1 (in-package :lisp-on-lines
)
4 ;;;; A description is an object which is used
5 ;;;; to describe another object.
8 ;;; Since i'm not using deflayer, ensure-layer etc,
9 ;;; There are a few places where contextl gets confused
10 ;;; trying to locate my description layers.
12 ;;; TODO: investigate switching to deflayer!
14 (defun contextl::prepare-layer
(layer)
16 (if (eq (symbol-package layer
)
17 (find-package :description-definers
))
19 (contextl::defining-layer layer
))
23 (defmethod find-layer-class :around
((layer symbol
) &optional errorp environment
)
24 (if (eq (symbol-package layer
)
25 (find-package :description-definers
))
30 ;;; I'm having some 'issues' with
31 ;;; compiled code and my initialization.
32 ;;; So this hack initializes the world.
33 (eval-when (:compile-toplevel
:load-toplevel
:execute
)
34 (defparameter *defined-descriptions
* nil
))
36 (define-layered-class description-access-class
(standard-layer-class contextl
::special-layered-access-class
)
37 ((defined-in-descriptions :initarg
:in-description
)
38 (mixin-class-p :initarg
:mixinp
)))
40 (defmethod direct-slot-definition-class
41 ((class description-access-class
) &key
&allow-other-keys
)
42 (find-class 'direct-attribute-definition-class
))
44 (defmethod effective-slot-definition-class
45 ((class description-access-class
) &key
&allow-other-keys
)
46 (find-class 'effective-attribute-definition-class
))
48 (defmethod compute-effective-slot-definition
49 ((class description-access-class
) name direct-slot-definitions
)
50 (declare (ignore name
))
51 (let ((attribute (call-next-method)))
52 (setf (attribute-direct-attributes attribute
) direct-slot-definitions
)
53 (setf (attribute-object-initargs attribute
)
54 ;; This plist will be used to init the attribute object
55 ;; Once the description itself is properly initiated.
57 'effective-attribute attribute
))
60 (defmethod slot-value-using-class ((class description-access-class
) object slotd
)
62 (eq (slot-definition-name slotd
) 'described-object
)
63 (not (slot-boundp slotd
'attribute-object
)))
65 (slot-definition-attribute-object slotd
)))
68 (defclass standard-description-class
(description-access-class layered-class
)
70 (:default-initargs
:defining-metaclass
'description-access-class
))
72 (defmethod validate-superclass
73 ((class standard-description-class
)
74 (superclass standard-class
))
77 (define-layered-class standard-description-object
(standard-layer-object)
78 ((described-object :accessor described-object
81 (defun description-class-name (description-class)
82 (read-from-string (symbol-name (class-name description-class
))))
84 (defun initialize-description-class (class)
86 ;;; HACK: initialization does not happ en properly
87 ;;; when compiling and loading or something like that.
88 ;;; Obviously i'm not sure why.
89 ;;; So we're going to explicitly initialize things.
92 (pushnew class
*defined-descriptions
*)
96 (let* ((description (find-layer class
))
100 (let* ((*init-time-description
* description
)
101 (attribute (apply #'make-instance
103 :description description
104 (attribute-object-initargs slot
))))
107 (setf (slot-definition-attribute-object slot
) attribute
)))
108 (remove 'described-object
(class-slots (class-of description
))
109 :key
#'slot-definition-name
)))
110 (defining-classes (partial-class-defining-classes (class-of description
))))
114 :on defining-classes
:by
#'cddr
115 :do
(funcall-with-layer-context
116 (adjoin-layer (find-layer layer
) (current-layer-context))
118 (loop :for direct-slot
:in
(class-direct-slots class
)
120 (find (slot-definition-name direct-slot
)
122 :key
#'attribute-name
)))
124 (prepare-initargs attribute
(direct-attribute-properties direct-slot
))))
126 (apply #'reinitialize-instance attribute
128 (when (not (eq (find-class (attribute-class attribute
))
129 (class-of attribute
)))
131 (apply #'change-class attribute
(attribute-class attribute
)
137 ;;;; HACK: run this at startup till we figure things out.
138 (defun initialize-descriptions ()
139 (map nil
#'initialize-description-class
140 (setf *defined-descriptions
*
141 (remove-duplicates *defined-descriptions
*))))
143 (defmethod initialize-instance :around
((class standard-description-class
) &rest initargs
&key
(direct-superclasses '()))
144 (declare (dynamic-extent initargs
))
146 (if (loop for direct-superclass in direct-superclasses
147 thereis
(ignore-errors (subtypep direct-superclass
'standard-description-object
)))
149 (apply #'call-next-method
152 (append direct-superclasses
153 (list (find-class 'standard-description-object
)))
155 (initialize-description-class class
)))
158 (defmethod reinitialize-instance :around
((class standard-description-class
) &rest initargs
&key
(direct-superclasses '() direct-superclasses-p
))
159 (declare (dynamic-extent initargs
))
160 ; (warn "CLASS ~A ARGS ~A:" class initargs)
162 (if (or (not direct-superclasses-p
)
163 (loop for direct-superclass in direct-superclasses
164 thereis
(ignore-errors (subtypep direct-superclass
'standard-description-object
))))
166 (apply #'call-next-method
169 (append direct-superclasses
170 (list (find-class 'standard-description-object
)))
172 (initialize-description-class class
)))
175 (defmethod print-object ((object standard-description-object
) stream
)
176 (print-unreadable-object (object stream
:type nil
:identity t
)
177 (format stream
"DESCRIPTION ~A" (ignore-errors (description-print-name object
)))))
179 (defmethod print-object ((object standard-description-class
) stream
)
180 (print-unreadable-object (object stream
:type t
:identity t
)
181 (princ (ignore-errors (description-print-name (find-layer object
))) stream
)))
183 (defun find-description (name)
184 (find-layer (find-class (defining-description name
))))