Rewrite modules functions as macro

This let us recompile initialize/finalize/update functions during
runtime without having to register them once again.
This commit is contained in:
Renaud Casenave-Péré 2014-11-14 20:29:39 +09:00
parent 6b2c2df3bf
commit 9faa777972
6 changed files with 58 additions and 37 deletions

View file

@ -7,7 +7,9 @@
(defpackage stoe.debug (defpackage stoe.debug
(:nicknames :debug) (:nicknames :debug)
(:use :cl (:use :cl
:utils)) :utils)
(:import-from :modules
:defmodule))
(in-package :stoe.debug) (in-package :stoe.debug)
(defvar *swank-server-port* 4006) (defvar *swank-server-port* 4006)
@ -46,6 +48,4 @@ start the swank server to accept remote connection."
(setf time-counter 0.0) (setf time-counter 0.0)
(setf frames-counter 0)))) (setf frames-counter 0))))
(modules:register-initialize-fun #'initialize) (defmodule debug)
(modules:register-finalize-fun #'finalize)
(modules:register-update-fun #'update)

View file

@ -8,7 +8,9 @@
(:use :cl) (:use :cl)
(:nicknames :game) (:nicknames :game)
(:export :get-world-origin (:export :get-world-origin
:get-current-camera)) :get-current-camera)
(:import-from :modules
:defmodule))
(in-package :stoe.game) (in-package :stoe.game)
(defconstant +loop-step-time+ 16000.0 (defconstant +loop-step-time+ 16000.0
@ -51,9 +53,7 @@ Advance the world by `delta-time', +loop-step-time+ at a time."
(decf delta-time +loop-step-time+))) (decf delta-time +loop-step-time+)))
(setf *last-frame-remaining-time* delta-time)) (setf *last-frame-remaining-time* delta-time))
(modules:register-initialize-fun #'initialize) (defmodule game)
(modules:register-finalize-fun #'finalize)
(modules:register-update-fun #'update)
(defun get-world-origin () *world-origin*) (defun get-world-origin () *world-origin*)
(defun get-current-camera () *current-camera*) (defun get-current-camera () *current-camera*)

View file

@ -14,7 +14,9 @@
:job-result :job-result
:push-job :push-job
:wait-for-job :wait-for-job
:cancel-job)) :cancel-job)
(:import-from :modules
:defmodule))
(in-package :stoe.jobs) (in-package :stoe.jobs)
(defstruct job (defstruct job
@ -82,9 +84,7 @@ If a thread is available, assign a new job to it."
(if (not (thread-alive-p (thread-thread thread))) (if (not (thread-alive-p (thread-thread thread)))
(finalize-thread thread)))))) (finalize-thread thread))))))
(modules:register-initialize-fun #'initialize) (defmodule jobs)
(modules:register-finalize-fun #'finalize)
(modules:register-update-fun #'update)
(defun push-job (fun args) (defun push-job (fun args)
"Create a new job using `fun' and `data' and push it into the job-list." "Create a new job using `fun' and `data' and push it into the job-list."

View file

@ -8,8 +8,10 @@
(:nicknames :modules) (:nicknames :modules)
(:use :cl (:use :cl
:utils) :utils)
(:export :register-initialize-fun :register-finalize-fun :register-update-fun (:export :initialize :finalize :update
:initialize :finalize :update)) :defmodule)
(:import-from :alexandria
:once-only))
(in-package :stoe.modules) (in-package :stoe.modules)
(defparameter *initialize-hook* nil (defparameter *initialize-hook* nil
@ -25,25 +27,32 @@ the program argv.")
Functions attached to this hook should expect an argument containing the time Functions attached to this hook should expect an argument containing the time
since last frame.") since last frame.")
(defun initialize (&optional argv) (defmacro initialize (&optional argv)
"Perform the engine and subsystems initialization process." "Perform the engine and subsystems initialization process."
(format t "Initialize...~%") `(progn
(run-hook *initialize-hook* argv)) (format t "Initialize...~%")
,@(loop for fun in *initialize-hook*
collect (list fun argv))))
(defun finalize () (defmacro finalize ()
"Perform the engine and subsystems finalization process." "Perform the engine and subsystems finalization process."
(format t "Finalize...~%") `(progn
(run-hook *finalize-hook*)) (format t "Finalize...~%")
,@(loop for fun in *finalize-hook*
collect (list fun))))
(defun update (delta-time) (defmacro update (delta-time)
"Update the modules each loop." "Update the modules each loop."
(run-hook *update-hook* delta-time)) `(progn
,@(loop for fun in *update-hook*
collect (list fun delta-time))))
(defun register-initialize-fun (fun) (defmacro defmodule (module)
(add-hook *initialize-hook* fun 'append)) "Register a new module.
The module is expected to have at least `initialize', `update', and `finalize' functions.
(defun register-finalize-fun (fun) `initialize' accepts an optional `argv' argument,
(add-hook *finalize-hook* fun)) `update' accepts a delta-time argument."
`(progn
(defun register-update-fun (fun) (setf *initialize-hook* (append *initialize-hook* (list (intern "INITIALIZE" ',module))))
(add-hook *update-hook* fun 'append)) (push (intern "FINALIZE" ',module) *finalize-hook*)
(setf *update-hook* (append *update-hook* (list (intern "UPDATE" ',module))))))

View file

@ -8,7 +8,9 @@
(:nicknames :render) (:nicknames :render)
(:use :cl (:use :cl
:utils) :utils)
(:export :poll-events)) (:export :poll-events)
(:import-from :modules
:defmodule))
(in-package :stoe.render) (in-package :stoe.render)
(defvar *window* nil) (defvar *window* nil)
@ -60,9 +62,7 @@ Render a frame and swap buffers."
(render-scene (game:get-world-origin)) (render-scene (game:get-world-origin))
(glop:swap-buffers *window*)) (glop:swap-buffers *window*))
(modules:register-initialize-fun #'initialize) (defmodule render)
(modules:register-finalize-fun #'finalize)
(modules:register-update-fun #'update)
(defun poll-events () (defun poll-events ()
"Poll events from the window manager. "Poll events from the window manager.

View file

@ -22,7 +22,7 @@ continue unless `unprotected' is t."
(update-current-time) (update-current-time)
(update-clock clock (get-delta-time)) (update-clock clock (get-delta-time))
(render:poll-events) (render:poll-events)
(modules:update (clock-delta clock)))))) (update (clock-delta clock))))))
(defun quit () (defun quit ()
"Quit the main loop." "Quit the main loop."
@ -55,11 +55,23 @@ continue unless `unprotected' is t."
(go:attach (go:make-object :mesh (with-input-from-string (s f) (go:attach (go:make-object :mesh (with-input-from-string (s f)
(mesh:make-mesh (read s)))) (game:get-world-origin)))) (mesh:make-mesh (read s)))) (game:get-world-origin))))
(defun initialize (&optional argv)
"Initialize all the modules passing the optional argv"
(modules:initialize argv))
(defun finalize ()
"Finalize all the modules"
(modules:finalize))
(defun update (delta-time)
"Update all the modules passing the delta time since the last frame"
(modules:update delta-time))
(defun main (&optional argv) (defun main (&optional argv)
"Run the program." "Run the program."
(modules:initialize argv) (initialize argv)
(unwind-protect (unwind-protect
(progn (progn
(game-start) (game-start)
(main-loop)) (main-loop))
(modules:finalize))) (finalize)))