Resume scene/actor from serialized state (for #3, revealed #6)

This commit is contained in:
~keith 2021-12-17 15:24:32 +00:00
parent bafd505145
commit 372044fc20
Signed by: keith
GPG Key ID: 5BEBEEAB2C73D520
3 changed files with 44 additions and 16 deletions

View File

@ -187,30 +187,38 @@
(defmethod resume ((this actor))
"Initialize or restore this actor's state."
; Restore self
(pointerize-setf [this :slot scene])
(pointerize-setf [this :slot parent])
;; Restore self
(when (typep [this :slot scene] 'id-ref)
;; relink to scene
(let ((scene (get-scene (id-ref-scene [this :slot scene]))))
(setf [this :slot scene] nil)
[scene (add-actor this)]))
(when (typep [this :slot parent] 'id-ref)
;; relink to parent
(let ((parent [this scene (get-actor (id-ref-actor [this :slot parent]))]))
(setf [this :slot parent] nil)
[parent (add-child this)]))
(loop for entry on [this :slot children]
when (typep (car entry) 'id-ref)
do (rplaca entry (pointerize (car entry))))
; Restore components
;; Restore components
(loop for component in [this components]
do [component (resume)])
; Restore children
;; Restore children
(loop for child-ptr in [this children]
for child = (weak-pointer-value child-ptr)
do [child (resume)]))
(defmethod suspend ((this actor))
"Prepare this actor for serialization."
; Suspend children
;; Suspend children
(loop for child-ptr in [this children]
for child = (weak-pointer-value child-ptr)
do [child (suspend)])
; Suspend components
;; Suspend components
(loop for component in [this components]
do [component (suspend)])
; Suspend self
;; Suspend self
(loop for child-cell on [this :slot children]
when (typep (car child-cell) 'weak-pointer)
do (rplaca child-cell (referize (car child-cell))))

View File

@ -26,6 +26,7 @@
referize-setf pointerize-setf
generate-load-forms
dump-scene dump-actors
load-resume-scene load-resume-actors
;; actor.lisp
actor

View File

@ -14,11 +14,10 @@
(declare (type pointer val))
(etypecase val
(weak-pointer (weak-pointer-value val))
(id-ref (warn "dereferencing sus pointer:~%~S" val)
(id-ref (warn "dereferencing sus pointer ~S" val)
(weak-pointer-value (pointerize val)))
(null nil)))
(defun referize (ptr)
"Convert weak-pointer ptr into an id-ref."
(declare (type weak-pointer ptr))
@ -28,11 +27,17 @@
(scene
(make-id-ref :scene [target id]))
(actor
(make-id-ref :scene [target scene id]
(make-id-ref :scene (etypecase [target :slot scene]
(weak-pointer [target scene id])
(id-ref (id-ref-scene [target :slot scene])))
:actor [target id]))
(component
(make-id-ref :scene [target scene id]
:actor [target actor id]
(make-id-ref :scene (etypecase [target :slot actor]
(weak-pointer [target scene id])
(id-ref (id-ref-scene [target :slot actor])))
:actor (etypecase [target :slot actor]
(weak-pointer [target actor id])
(id-ref (id-ref-actor [target :slot actor])))
:component (class-name (class-of target))))
)))
@ -201,9 +206,8 @@
(declare (type boolean destroy-after prune nice-syms))
;; Collect children so we serialize them as well
(let ((all-actors (append actors
(loop for actor in actors
nconc (collect-descendents actor)))))
(let ((all-actors (loop for actor in actors
nconc (collect-descendents actor))))
;; Suspend
(loop for actor in actors
do [actor (suspend)])
@ -216,3 +220,18 @@
(loop for actor in actors do [actor (destroy)])
(loop for actor in actors do [actor (resume)])))
))
(defun load-resume-scene (scene-form)
"Load and resume the scene saved in scene-form."
(let ((scene (eval scene-form)))
(add-scene scene)
[scene (resume)]
scene))
(defun load-resume-actors (actor-forms)
"Load and resume the actors saved in actor-forms."
(let ((actors (loop for actor-form in actor-forms
collect (eval actor-form))))
(loop for actor in actors
do [actor (resume)]
collect actor)))