;;; along with this program. If not, see <http://www.gnu.org/licenses/>.
-;;; World of Mob
-
-(in-package :gacela)
-
-(defmacro makemob (name variables &rest methods)
- `(lambda ,
-
-(defmacro defmob (name variables &key init logic render)
- `(let ((make-name ',(intern (concatenate 'string "MAKE-" (string name)))))
- (setf (symbol-function make-name)
- (makemob ,variables :init ,init :logic ,logic :render ,render))
- make-name))
-
-;(defmacro makemob (variables &key init logic render)
-; `(lambda
-; ,(if (null variables) () (cons '&key variables))
-; (mob-structure ,variables ,init ,logic ,render)))
-
-(defmacro mob-structure (variables init logic render)
- `(list
- :init (lambda () ,init)
- :logic (lambda () ,logic)
- :render (lambda () ,render)
- :context (lambda ()
- ,(if variables
- `(mapcar #'list
- ',(mapcar #'car+ variables)
- (multiple-value-list
- (values-list ,(cons 'list (mapcar #'car+ variables)))))
- nil))))
-
-(defun init-mob (mob)
- (funcall (getf mob :init)))
-
-(defun logic-mob (mob)
- (funcall (getf mob :logic)))
-
-(defun render-mob (mob)
- (funcall (getf mob :render)))
+(eval-when (compile load eval)
+ (when (not (find-package 'gacela)) (make-package 'gacela :nicknames '(gg) :use '(lisp)))
+ (in-package 'gacela :nicknames '(gg) :use '(lisp)))
+
+
+;;; Mob Factory
+
+(defmacro makemob (name &rest methods)
+ `(defun ,name (&rest args &aux (option (car args)))
+ ,(union
+ `(case option
+ (:on (mob-on ',name))
+ (:off (mob-off ',name)))
+ (labels ((options (m &aux (option (car m)) (body (cadr m)))
+ (cond ((null m) nil)
+ (t (cons (list option `(apply ,body (cdr args))) (options (cddr m)))))))
+ (options methods)))))
+
(let (running-mobs mobs-to-add mobs-to-quit)
(defun mob-on (mob)
(push mob mobs-to-add))
+ (defun run-mobs (option &key args function)
+ (dolist (mob running-mobs)
+ (cond (function (funcall function)))
+ (secure-block nil (apply (symbol-function mob) (cons option args)))))
+
(defun mob-off (mob)
- (push mob mobs-to-quit)))
+ (push mob mobs-to-quit))
+
+ (defun refresh-running-mobs ()
+ (do ((mob (pop mobs-to-add) (pop mobs-to-add))) ((null mob))
+ (push mob running-mobs)
+ (secure-block nil (funcall (symbol-function mob) :init)))
+ (setq running-mobs (reverse (set-difference running-mobs mobs-to-quit)))
+ (setq mobs-to-quit nil))
+
+ (defun quit-all-mobs ()
+ (setq running-mobs nil mobs-to-add nil mobs-to-quit nil)))
+
+
+(defun logic-mobs ()
+ (run-mobs :logic))
+
+(defun render-mobs ()
+ (run-mobs :render :function (lambda () (glLoadIdentity))))