45 lines
1.4 KiB
Common Lisp
45 lines
1.4 KiB
Common Lisp
;;;; 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))))
|