diff --git a/wh-engine/actor.lisp b/wh-engine/actor.lisp index cc1334b..a3b58d5 100644 --- a/wh-engine/actor.lisp +++ b/wh-engine/actor.lisp @@ -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)))) diff --git a/wh-engine/package.lisp b/wh-engine/package.lisp index f1d2327..6d0d703 100644 --- a/wh-engine/package.lisp +++ b/wh-engine/package.lisp @@ -26,6 +26,7 @@ referize-setf pointerize-setf generate-load-forms dump-scene dump-actors + load-resume-scene load-resume-actors ;; actor.lisp actor diff --git a/wh-engine/serialization.lisp b/wh-engine/serialization.lisp index 2080157..cfe3c43 100644 --- a/wh-engine/serialization.lisp +++ b/wh-engine/serialization.lisp @@ -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)))