From 03944a1765fcfc26dc11f25e659fbb7a2c1a03fa Mon Sep 17 00:00:00 2001 From: David Thompson Date: Thu, 15 Dec 2022 12:14:43 -0500 Subject: Break into modules. This will make adding ocapn easier. --- community-garden/actors.scm | 62 ++++++++++++++++ community-garden/garden-bed.scm | 74 +++++++++++++++++++ community-garden/plant.scm | 20 +++++ community-garden/view.scm | 159 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 315 insertions(+) create mode 100644 community-garden/actors.scm create mode 100644 community-garden/garden-bed.scm create mode 100644 community-garden/plant.scm create mode 100644 community-garden/view.scm (limited to 'community-garden') diff --git a/community-garden/actors.scm b/community-garden/actors.scm new file mode 100644 index 0000000..b34d1f8 --- /dev/null +++ b/community-garden/actors.scm @@ -0,0 +1,62 @@ +(define-module (community-garden actors) + #:use-module (community-garden garden-bed) + #:use-module (goblins) + #:use-module (goblins actor-lib methods) + #:use-module (goblins utils simple-sealers) + #:export (^botanist + ^garden-gate + ^garden + ^visitor + ^gardener)) + +(define (^botanist bcom) + (define-values (seal-plant unseal-plant approved-plant?) + (make-sealer-triplet)) + (methods + ((approve-plant plant) + (seal-plant plant)) + ((check-plant plant) + (if (approved-plant? plant) + (unseal-plant plant) + (error "plant is not allowed" plant))))) + +(define (^garden-gate bcom botanist) + (methods + ((check-plant plant) + ($ botanist 'check-plant plant)))) + +(define (^garden bcom name garden-bed garden-gate) + (define (ensure-empty x y) + (when (garden-bed-ref garden-bed x y) + (error "tile already has something planted in it" x y))) + (methods + ((get-name) name) + ((get-bed) garden-bed) + ((plant x y sealed-plant) + (ensure-empty x y) + (let* ((plant ($ garden-gate 'check-plant sealed-plant)) + (new-bed (garden-bed-set garden-bed x y plant))) + (bcom (^garden bcom name new-bed garden-gate)))) + ((dig-up x y) + (let ((new-bed (garden-bed-set garden-bed x y #f))) + (bcom (^garden bcom name new-bed garden-gate)))))) + +(define (^visitor bcom name garden) + (methods + ((get-name) name) + ((get-garden-name) + (<- garden 'get-name)) + ((inspect-garden) + (<- garden 'get-bed)))) + +(define (^gardener bcom name garden) + (methods + ((get-name) name) + ((get-garden-name) + (<- garden 'get-name)) + ((inspect-garden) + (<- garden 'get-bed)) + ((plant x y plant) + (<- garden 'plant x y plant)) + ((dig-up x y) + (<- garden 'dig-up x y)))) diff --git a/community-garden/garden-bed.scm b/community-garden/garden-bed.scm new file mode 100644 index 0000000..71cf6e6 --- /dev/null +++ b/community-garden/garden-bed.scm @@ -0,0 +1,74 @@ +(define-module (community-garden garden-bed) + #:use-module (community-garden plant) + #:use-module (ice-9 match) + #:use-module (srfi srfi-1) + #:use-module (srfi srfi-9) + #:export (make-garden-bed + garden-bed? + garden-bed-width + garden-bed-height + garden-bed-tiles + garden-bed-ref + garden-bed-set)) + +(define (list-replace lst i o) + (let loop ((j 0) + (lst lst)) + (match lst + ((head . rest) + (if (= i j) + (cons o rest) + (cons head (loop (+ j 1) rest))))))) + +(define (make-empty-row width) + (make-list width #f)) + +(define (make-empty-bed width height) + (list-tabulate height + (lambda (_i) + (make-empty-row width)))) + +(define (bed-ref bed x y) + (list-ref (list-ref bed y) x)) + +(define (bed-set bed x y o) + (list-replace bed y (list-replace (list-ref bed y) x o))) + +(define-record-type + (%make-garden-bed width height tiles) + garden-bed? + (width garden-bed-width) + (height garden-bed-height) + (tiles garden-bed-tiles)) + +(define (make-garden-bed width height) + (%make-garden-bed width height (make-empty-bed width height))) + +(define (bounds-check garden x y) + (unless (and (>= x 0) + (>= y 0) + (< x (garden-bed-width garden)) + (< y (garden-bed-height garden))) + (error "garden tile out of bounds" x y))) + +(define (garden-bed-ref garden x y) + (bounds-check garden x y) + (bed-ref (garden-bed-tiles garden) x y)) + +(define (garden-bed-set garden x y o) + (bounds-check garden x y) + (%make-garden-bed (garden-bed-width garden) + (garden-bed-height garden) + (bed-set (garden-bed-tiles garden) x y o))) + +(define (display-garden-bed garden) + (for-each (lambda (row) + (for-each (lambda (tile) + (display + (if (plant? tile) + (plant-char tile) + ".")) + (display " ")) + row) + (newline)) + (garden-bed-tiles garden))) diff --git a/community-garden/plant.scm b/community-garden/plant.scm new file mode 100644 index 0000000..3f034b8 --- /dev/null +++ b/community-garden/plant.scm @@ -0,0 +1,20 @@ +(define-module (community-garden plant) + #:use-module (srfi srfi-9) + #:export (make-plant + plant? + plant-name + plant-char + + sunflower + cabbage + winter-squash)) + +(define-record-type + (make-plant name char) + plant? + (name plant-name) + (char plant-char)) + +(define sunflower (make-plant "Sunflower" #\S)) +(define cabbage (make-plant "Cabbage" #\C)) +(define winter-squash (make-plant "Winter Squash" #\W)) diff --git a/community-garden/view.scm b/community-garden/view.scm new file mode 100644 index 0000000..e43617b --- /dev/null +++ b/community-garden/view.scm @@ -0,0 +1,159 @@ +(define-module (community-garden view) + #:use-module (catbird asset) + #:use-module (catbird node) + #:use-module (catbird node-2d) + #:use-module (chickadee config) + #:use-module (chickadee graphics color) + #:use-module (chickadee graphics path) + #:use-module (chickadee graphics text) + #:use-module (chickadee graphics texture) + #:use-module (chickadee math vector) + #:use-module (chickadee scripting) + #:use-module (community-garden garden-bed) + #:use-module (community-garden plant) + #:use-module (goblins) + #:use-module (ice-9 atomic) + #:use-module (ice-9 match) + #:use-module (oop goops) + #:use-module (srfi srfi-43) + #:export (%window-width + %window-height + )) + +;; Hack to fix broken version of this in catbird upstream. +(define-method (on-change (sprite ) slot-name old new) + (case slot-name + ((texture) + (let ((new (artifact (->asset new)))) + (set! (width sprite) (texture-width new)) + (set! (height sprite) (texture-height new)))))) + +(define %window-width 1024) +(define %window-height 768) +(define %tile-width 64.0) +(define %tile-height 64.0) +(define font-file (scope-datadir "fonts/Inconsolata-Regular.otf")) +(define-asset (title-font (f font-file)) + (load-font f 24)) +(define-asset (plant-tile-font (f font-file)) + (load-font f 32)) +(define-asset (sunflower-texture (f "assets/images/sunflower.png")) + (load-image f)) +(define-asset (cabbage-texture (f "assets/images/cabbage.png")) + (load-image f)) + +(define-class () + (vat #:getter vat #:init-keyword #:vat) + (visitor #:getter visitor #:init-keyword #:visitor) + (name-box #:getter name-box #:init-keyword #:name-box) + (garden-bed-box #:getter garden-bed-box #:init-keyword #:garden-bed-box) + (prev-garden #:accessor prev-garden #:init-value #f) + (tiles #:accessor tiles #:init-value #())) + +(define-method (garden-bed (garden )) + (atomic-box-ref (garden-bed-box garden))) + +(define-method (garden-name (garden )) + (atomic-box-ref (name-box garden))) + +(define-method (on-boot (garden )) + (define title + (make