1 (in-package :lisp-on-lines
)
3 (define-layered-function display-using-description
(description object component
)
4 ; (:argument-precedence-order )
6 "Render the object in component,
7 using DESCRIPTION, which is an occurence, an attribute, or something else entirely."))
10 display-using-description
(d o c
)
11 (<:as-html
"default :" o
))
13 (defmethod find-layer-for-type (type)
17 (define-layered-function display
(component object
&rest args
)
19 "Displays OBJECT in COMPONENT."))
21 (define-layered-method display
((component t
) (object t
)
23 &key type
(line #'line-in
)
25 " The default display dispatch method
27 DISPLAY takes two required arguments,
28 COMPONENT : The component to display FROM (not neccesarily 'in')
29 OBJECT : The 'thing' we want to display... in this case it's the component
31 DISPLAY also takes keywords arguments which modify the DESCRIPTION,
32 that is to say the parameters that come together to create the output.
34 The default display calls out via FUNCALL-WITH-LAYERS to tche DISPLAY-USING-DESCRIPTION method."
36 (let* ((occurence (find-occurence object
))
37 (description (or (find-display-attribute
39 (setf type
(or type
(description.type occurence
))))
42 (dletf (((description.type occurence
) type
)
43 ((attributes description
) (or
44 (attributes description
)
45 (list-slots object
))))
46 ;; apply the default line to the description
47 (funcall-with-description
50 ;; apply the passed in arguments and call display-using-description
52 (funcall-with-description
55 #'display-using-description description object component
))))
56 (error "no description for ~A" object
))))
61 (defun funcall-with-description (description properties function
&rest args
)
64 (dletf* (((description.type description
) (or
65 (getf properties
:type
)
66 (description.type description
)))
68 ((description.layers description
) (append
69 (description.layers description
)
70 (getf properties
:layers
)))
71 ((description.properties description
) (append (description.properties description
) properties
)))
73 (description.layers description
)
75 (contextl::funcall-with-special-initargs
76 (list (cons description properties
))
78 (apply function args
))))))
79 (apply function args
)))
83 (defmacro with-description
((description &rest properties
) &body body
)
84 `(funcall-with-description ,description
(if ',(cdr properties
)
90 (defmacro do-attributes
((var description
&optional
(attributes `(attributes ,description
))) &body body
)
91 (with-unique-names (att properties type
)
92 `(dolist* (,att
,attributes
)
93 (let* ((,att
(ensure-list ,att
))
94 (,properties
(rest ,att
))
95 (,type
(getf ,properties
:type
))
96 (,var
(let ((a (find-attribute ,description
(first ,att
))))
98 (apply #'make-attribute
:name
(first ,att
) :type
,type
,properties
)
99 (if a a
(make-attribute :name
(first ,att
) :slot-name
(first ,att
)))))))
100 (funcall-with-description ,var
,properties
101 #'(lambda () ,@body
))))))
103 (defmacro with-component
((component) &body body
)
104 `(let ((self ,component
))
105 (declare (ignorable self
))
106 (flet ((display* (thing &rest args
)
107 (apply #'display
,component thing args
))
108 (display-attribute (attribute obj
&optional props
)
110 (funcall-with-description
112 #'display-using-description attribute obj
,component
)
113 (display-using-description attribute obj
,component
))))
114 (declare (ignorable #'display
* #'display-attribute
))
117 (defmacro defdisplay
(&body body
)
118 (loop with in-layerp
= (eq (car body
) :in-layer
)
119 with layer
= (if in-layerp
(cadr body
) 't
)
120 for tail on
(if in-layerp
(cddr body
) body
)
121 until
(listp (car tail
))
122 collect
(car tail
) into qualifiers
124 (when (member :in-layer qualifiers
)
125 (error "Incorrect occurrence of :in-layer in defdisplay. Must occur before qualifiers."))
127 (destructuring-bind (description &optional object component
) (car tail
)
128 (with-unique-names (d c
)
129 (let (standard-description-p)
130 `(define-layered-method
131 display-using-description
136 (setf object description
)
141 (setf d
(car description
))
145 (setf standard-description-p t
)
152 (setf c
(car component
))