;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Animates ;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; Classes ;;; The class of all animated objects, they can hold things. ;;; This is a superclass, and should never be instantiated. Rather ;;; the subclasses of will be instantiated. (defclass ( ) ;; by convention if gender is #t then the animate is female ;; when gender is #f then the animate is male (gender :type :accessor gender :initarg :gender :initvalue #f) (maxload :type :accessor maxload :initarg :maxload :initvalue 40)) ;;; Has a plan - which is what do-something will do. (defclass () (plan :type :accessor plan :initarg :plan :initvalue (lambda (a) #f))) ; do nothing by default ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; Interface ;;; A predicate for animates. ;;; (define (character? x) ...) ;;; The time that the animate should have it's first do-something. (defgeneric (start-time (a ))) ;;; This generic is what is used to do what the character is doing. The ;;; return value is a number that is the delay until the next call ;;; event. (defgeneric (do-something animate)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; Implementation ;;; A predicate for animates. (define (animate? x) (instance-of? x )) (defmethod (destroy (a )) (for-each (lambda (o) (transfer o a (start-place o))) (contents a)) (call-next-method)) ;;; Characters start doing something immediately, and run their plan. (defmethod (start-time (a )) 0) ;;; This specialize the way that objects are created - adding ;;; the initial do-something event automatically. (defmethod (initialize (a ) initargs) (define (character-loop) ;; this will do-something and insert the next event if the result is ;; a number. (let ((n (do-something a))) (when (and (number? n) (not (eq? (location a) *null-place*))) (insert-event n character-loop)))) (call-next-method) ; must call this (let ((start (start-time a))) (when (number? start) ; add 1st event if got a number (insert-first-event start character-loop)))) (defmethod (do-something (a )) ((plan a) a))