(suspend) and (resume) pointer conversion (for #3)
This commit is contained in:
parent
74d2cdc890
commit
b3a6fd3f78
|
@ -11,6 +11,7 @@
|
||||||
((:module "wh-engine"
|
((:module "wh-engine"
|
||||||
:components ((:file "package")
|
:components ((:file "package")
|
||||||
(:file "main")
|
(:file "main")
|
||||||
|
(:file "serialization")
|
||||||
(:file "actor")
|
(:file "actor")
|
||||||
(:file "component")
|
(:file "component")
|
||||||
(:file "scene")
|
(:file "scene")
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
:initform "")
|
:initform "")
|
||||||
(scene :documentation "The scene containing this actor."
|
(scene :documentation "The scene containing this actor."
|
||||||
:reader scene
|
:reader scene
|
||||||
:type (or weak-pointer null)
|
:type pointer
|
||||||
:initform nil)
|
:initform nil)
|
||||||
(tags :documentation "This actor's tags."
|
(tags :documentation "This actor's tags."
|
||||||
:reader tags
|
:reader tags
|
||||||
|
@ -30,12 +30,12 @@
|
||||||
:initform nil)
|
:initform nil)
|
||||||
(parent :documentation "This actor's parent."
|
(parent :documentation "This actor's parent."
|
||||||
:reader parent
|
:reader parent
|
||||||
:type (or weak-pointer null)
|
:type pointer
|
||||||
:initarg :parent
|
:initarg :parent
|
||||||
:initform nil)
|
:initform nil)
|
||||||
(children :documentation "The actors this actor is a parent of."
|
(children :documentation "The actors this actor is a parent of."
|
||||||
:reader children
|
:reader children
|
||||||
:type (proper-list weak-pointer)
|
:type (proper-list pointer)
|
||||||
:initform nil)
|
:initform nil)
|
||||||
(components :documentation "The components attached to this actor."
|
(components :documentation "The components attached to this actor."
|
||||||
:reader components
|
:reader components
|
||||||
|
@ -181,6 +181,30 @@
|
||||||
(loop for component in [this components]
|
(loop for component in [this components]
|
||||||
do [component (parent-activated this)]))
|
do [component (parent-activated this)]))
|
||||||
|
|
||||||
|
(defmethod resume ((this actor))
|
||||||
|
"Initialize or restore this actor's state."
|
||||||
|
; Restore self
|
||||||
|
(resume-setf [this :slot scene])
|
||||||
|
(resume-setf [this :slot parent])
|
||||||
|
(loop for entry on [this :slot children]
|
||||||
|
when (typep (car entry) 'id-ref)
|
||||||
|
do (rplaca entry (resume-ptr (car entry))))
|
||||||
|
; Restore components
|
||||||
|
(loop for component in [this components]
|
||||||
|
do [component (resume)]))
|
||||||
|
|
||||||
|
(defmethod suspend ((this actor))
|
||||||
|
"Prepare this actor for serialization."
|
||||||
|
; Suspend components
|
||||||
|
(loop for component in [this components]
|
||||||
|
do [component (suspend)])
|
||||||
|
; Suspend self
|
||||||
|
(loop for entry on [this :slot children]
|
||||||
|
when (typep (car entry) 'weak-pointer)
|
||||||
|
do (rplaca entry (suspend-ptr (car entry))))
|
||||||
|
(suspend-setf [this :slot scene])
|
||||||
|
(suspend-setf [this :slot parent]))
|
||||||
|
|
||||||
(defmethod update ((this actor))
|
(defmethod update ((this actor))
|
||||||
"Update this actor's components."
|
"Update this actor's components."
|
||||||
(loop for component in [this components]
|
(loop for component in [this components]
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
(defclass component ()
|
(defclass component ()
|
||||||
((actor :documentation "The actor this component belongs to."
|
((actor :documentation "The actor this component belongs to."
|
||||||
:reader actor
|
:reader actor
|
||||||
:type (or weak-pointer null)
|
:type pointer
|
||||||
:initform nil)
|
:initform nil)
|
||||||
(active-p :documentation "Whether or not this component is active."
|
(active-p :documentation "Whether or not this component is active."
|
||||||
:reader active-p
|
:reader active-p
|
||||||
|
@ -54,8 +54,28 @@
|
||||||
"Activate this component."
|
"Activate this component."
|
||||||
(setf [this :slot active-p] t))
|
(setf [this :slot active-p] t))
|
||||||
|
|
||||||
|
(defmethod resume ((this component))
|
||||||
|
"Initialize or restore this component's state."
|
||||||
|
(loop for slot in (sb-mop:class-slots (class-of this))
|
||||||
|
for slot-name = (sb-mop:slot-definition-name slot)
|
||||||
|
when (slot-boundp this slot-name)
|
||||||
|
do (let ((value (slot-value this slot-name)))
|
||||||
|
(when (typep value id-ref)
|
||||||
|
(setf (slot-value this slot-name) (resume-ptr value))))
|
||||||
|
))
|
||||||
|
|
||||||
|
(defmethod suspend ((this component))
|
||||||
|
"Prepare this component for serialization."
|
||||||
|
(loop for slot in (sb-mop:class-slots (class-of this))
|
||||||
|
for slot-name = (sb-mop:slot-definition-name slot)
|
||||||
|
when (slot-boundp this slot-name)
|
||||||
|
do (let ((value (slot-value this slot-name)))
|
||||||
|
(when (typep value weak-pointer)
|
||||||
|
(setf (slot-value this slot-name) (suspend-ptr value))))
|
||||||
|
))
|
||||||
|
|
||||||
(defmethod start ((this component))
|
(defmethod start ((this component))
|
||||||
"Called before on-update the first time this component is processed."
|
"Called before (update) the first time this component is processed."
|
||||||
(setf [this :slot started-p] t))
|
(setf [this :slot started-p] t))
|
||||||
|
|
||||||
(defmethod update ((this component))
|
(defmethod update ((this component))
|
||||||
|
|
|
@ -183,15 +183,15 @@
|
||||||
(update-all-scenes)
|
(update-all-scenes)
|
||||||
(gl:clear :color-buffer)
|
(gl:clear :color-buffer)
|
||||||
(let ((render-pass nil))
|
(let ((render-pass nil))
|
||||||
(loop for view-ptr in *world-views*
|
(loop for view-ptr in *world-views*
|
||||||
for view = (ensure-live (weak-pointer-value view-ptr))
|
for view = (ensure-live (weak-pointer-value view-ptr))
|
||||||
when (and [view active-p] [view actor tree-active-p])
|
when (and [view active-p] [view actor tree-active-p])
|
||||||
do (progn
|
do (progn
|
||||||
(unless (eq [view render-pass] render-pass)
|
(unless (eq [view render-pass] render-pass)
|
||||||
(setf render-pass [view render-pass])
|
(setf render-pass [view render-pass])
|
||||||
(gl:clear :depth-buffer)
|
(gl:clear :depth-buffer)
|
||||||
)
|
)
|
||||||
[view (render-view *world-drawables*)])))
|
[view (render-view *world-drawables*)])))
|
||||||
(gl:flush)
|
(gl:flush)
|
||||||
(sdl2:gl-swap-window win)))
|
(sdl2:gl-swap-window win)))
|
||||||
))))
|
))))
|
||||||
|
|
|
@ -18,6 +18,12 @@
|
||||||
register-test-scene
|
register-test-scene
|
||||||
run
|
run
|
||||||
|
|
||||||
|
;; serialization.lisp
|
||||||
|
id-ref make-id-ref
|
||||||
|
pointer
|
||||||
|
suspend-ptr resume-ptr
|
||||||
|
suspend-setf resume-setf
|
||||||
|
|
||||||
;; actor.lisp
|
;; actor.lisp
|
||||||
actor
|
actor
|
||||||
; properties
|
; properties
|
||||||
|
@ -33,6 +39,7 @@
|
||||||
has-tag add-tag remove-tag
|
has-tag add-tag remove-tag
|
||||||
parent-deactivated parent-activated parent-changed
|
parent-deactivated parent-activated parent-changed
|
||||||
deactivate activate
|
deactivate activate
|
||||||
|
resume suspend
|
||||||
update
|
update
|
||||||
destroy
|
destroy
|
||||||
transform-point world-point local-point
|
transform-point world-point local-point
|
||||||
|
@ -49,6 +56,7 @@
|
||||||
attach
|
attach
|
||||||
parent-deactivated parent-activated parent-changed
|
parent-deactivated parent-activated parent-changed
|
||||||
deactivate activate
|
deactivate activate
|
||||||
|
resume suspend
|
||||||
start update
|
start update
|
||||||
destroy
|
destroy
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
;;;; wh-engine/serialization.lisp
|
||||||
|
(in-package wh-engine)
|
||||||
|
|
||||||
|
(defstruct id-ref
|
||||||
|
(scene 0 :type fixnum)
|
||||||
|
(actor nil :type (or fixnum null))
|
||||||
|
(component nil :type (or symbol null)))
|
||||||
|
|
||||||
|
(deftype pointer () '(or id-ref weak-pointer null))
|
||||||
|
|
||||||
|
(defun suspend-ptr (ptr)
|
||||||
|
"Convert weak-pointer ptr to an id-ref."
|
||||||
|
(declare (type weak-pointer ptr))
|
||||||
|
|
||||||
|
(let (target (weak-pointer-value ptr))
|
||||||
|
(cond
|
||||||
|
((typep target 'scene)
|
||||||
|
(make-id-ref :scene [target id]))
|
||||||
|
((typep target 'actor)
|
||||||
|
(make-id-ref :scene [target scene id]
|
||||||
|
:actor [target id]))
|
||||||
|
((typep target 'component)
|
||||||
|
(make-id-ref :scene [target scene id]
|
||||||
|
:actor [target actor id]
|
||||||
|
:component (class-name (class-of target))))
|
||||||
|
(t ptr))))
|
||||||
|
|
||||||
|
(defun resume-ptr (ref)
|
||||||
|
"Convert id-ref ref to a weak-pointer."
|
||||||
|
(declare (type id-ref ref))
|
||||||
|
|
||||||
|
(let ((scene (get-scene (id-ref-scene ref))) actor component)
|
||||||
|
(if (setf actor [scene (get-actor (id-ref-actor ref))])
|
||||||
|
(if (setf component [actor (get-component (find-class (id-ref-component ref)))])
|
||||||
|
(make-weak-pointer component)
|
||||||
|
(make-weak-pointer actor))
|
||||||
|
(make-weak-pointer scene))))
|
||||||
|
|
||||||
|
(defmacro suspend-setf (place)
|
||||||
|
`(when (typep ,place 'weak-pointer)
|
||||||
|
(setf ,place (suspend-ptr ,place))))
|
||||||
|
(defmacro resume-setf (place)
|
||||||
|
`(when (typep ,place 'id-ref)
|
||||||
|
(setf ,place (resume-ptr ,place))))
|
Loading…
Reference in New Issue