1 (in-package :lisp-on-lines
)
3 (define-layered-function display-using-description
(description object component
)
4 (:method-combination wrapping-standard
)
6 "Render the object in component,
7 using DESCRIPTION, which is an occurence, an attribute, or something else entirely."))
9 (defun make-display-function (component object
13 "returns a function that expects a 3 argument function as its argument
15 The function argument (which is usually display-using-description) will be called with the proper environment for display all set up nice n pretty like."
18 (let* ((description (find-occurence object
)))
20 (dletf (((attributes description
)
22 (attributes description
)
23 (list-attributes description
))))
24 ;; apply the default line to the description
25 (funcall-with-description
28 ;; apply the passed in arguments and call display-using-description
30 (funcall-with-description
33 function description object component
))))
34 (error "no description for ~A" object
)))))
36 (define-layered-function display
(component object
&rest args
)
38 "Displays OBJECT in COMPONENT."))
40 (define-layered-method display
((component t
) (object t
)
42 " The default display dispatch method
44 DISPLAY takes two required arguments,
45 COMPONENT : The component to display FROM (not neccesarily 'in')
46 OBJECT : The 'thing' we want to display... in this case it's the component
48 DISPLAY also takes keywords arguments which modify the DESCRIPTION,
49 that is to say the parameters that come together to create the output.
51 The default display calls out via FUNCALL-WITH-LAYERS to tche DISPLAY-USING-DESCRIPTION method."
52 (funcall (apply 'make-display-function component object properties
)
53 'display-using-description
))
57 (defun funcall-with-layers (layers thunk
)
58 (let ((context (current-layer-context)))
63 (+ (adjoin-layer layer context
))
64 (- (remove-layer layer context
)))))
65 (funcall-with-layer-context context thunk
)))
68 (defun funcall-with-description (description properties function
&rest args
)
70 (dletf* (((description-type description
)
72 (getf properties
:type
)
73 (description-type description
)))
75 ((description-layers description
)
77 (description-layers description
)
78 (getf properties
:layers
)))
79 ((description-properties description
) (append (description-properties description
) properties
)))
81 (description-layers description
)
83 (contextl::funcall-with-special-initargs
84 (list (cons description properties
))
86 (apply function args
))))))
87 (apply function args
)))
89 (defmacro with-description
((description &rest properties
) &body body
)
90 `(funcall-with-description ,description
(if ',(cdr properties
)
96 (define-layered-function find-do-attributes
(desc))
98 (define-layered-method find-do-attributes
((description description
))
102 :in
(attributes description
)
103 :collect
(let ((default (find (car (ensure-list att
))
104 (default-attributes description
)
108 (defmacro do-attributes
((var description
&optional
(attributes `(find-do-attributes ,description
))) &body body
)
109 (with-unique-names (att properties type
)
110 `(dolist* (,att
,attributes
)
111 (let* ((,att
(ensure-list ,att
))
112 (,properties
(rest ,att
))
113 (,type
(getf ,properties
:type
))
114 (,var
(let ((a (find-attribute ,description
(first ,att
))))
116 (apply #'make-attribute
:name
(first ,att
) :type
,type
,properties
)
117 (if a a
(make-attribute :name
(first ,att
) :slot-name
(first ,att
)))))))
118 (funcall-with-description ,var
,properties
122 (defmacro with-component
((component) &body body
)
123 `(let ((self ,component
))
124 (declare (ignorable self
))
125 (flet ((display* (thing &rest args
)
126 (apply #'display
,component thing args
))
127 (display-attribute (attribute obj
&rest
130 (funcall-with-description
132 #'display-using-description attribute obj
,component
)
133 (display-using-description attribute obj
,component
))))
134 (declare (ignorable #'display
* #'display-attribute
))