[cells-devel] Something like a def-family-observer?
Ken Tilton
kennytilton at optonline.net
Wed Dec 12 12:27:06 UTC 2007
Ken Tilton wrote:
> Peter Hildebrandt wrote:
>
> OK, now that I am up to speed, let's go back to your original query.
>
>>
>> Say, I have a model M that depends on the structure of a family tree.
>> One of M's slots is therefore depending on the root of the family
>> tree: (c? root). However, I want M to know about changes in the
>> family tree, like, say, when a child or grandchild is added.
>> Apparently cells (at least the cells_2.0 branch required by
>> cells-gtk) does not broadcast change messages to the parents of a
>> node (which I guess is the right thing in 99% of the cases).
>>
>> What's the best way to deal with that?
>>
>> (i) Is there some mechanism for this purpose present in cells? Or
>> (ii) Do I roll my own special case solution? Or
>> (iii) Is it worthwhile to build some general purpose solution to this
>> problem?
>>
>> My approach towards (ii) (I haven't coded anything yet, waiting for
>> you comments) would be something like building an observer tree each
>> node of which observes one node in the family tree. Something like
>> this:
>> - Design a tiny tree observer model ("tto"?), suited to observing one
>> family node
>> (defmodel tty (family) (observed observed-kids reports-to))
>>
>> - Every tto knows about the parent model (M from above) and does the
>> right thing when it sees a change (say, call a closure)
>> - If the observed nodes has kids, it instantiates tto kids of its own
>> to match the kids of the observed tree
>> (def-c-output observed ((self tto))
>> (make-tto :observed (c? new-value) :observed-kids (c? (kids
>> new-value)))
>> (setf (kids self) (mapcar (lambda (kid) (make-tto :observed (c?
>> kid) :observed-kids (c? (kids kid)))) (kids new-value)
>> ...)
>> (def-c-output observed-kids ((self tto))
>> ...)
>>
>> - Changing the root slot in M results in the instantiation of a tto
>> for the root
>>
>> I guess that would work ... but I feel there must be a more elegant
>> solution.
Roughly (cuz of rough recall of Cells2):
(defmodel family-observer (family)
;; we'll use the "md-value" slot for the observed
()
(:default-initargs
:kids (c? (the-kids
(bwhen (o (^md-value self)) ;; not sure why not
(loop for k in (^kids o) collecting
(let ((this-k k)) ;; loop is weird
(make-instance 'family-observer
:md-value this-k)))))))
That handles rows in/out. As for individual values, well, I guess you
generalize the handling of kids so it is just another slot-value.
Changes to kids add/remove rows, changes to other things set values
within a row.
You know you need the kids handled, so what you might build that in and
then have some macrology write the defmodel for custom subclasses of f-o:
(def-family-observer my-tree (<def options?>) slot-1 slot-2)
Expansion left as an exercise. :) It is not inconceivable to have f-o
link dynamically to any cell-mediated slot of the model instances, btw.
kt
More information about the cells-devel
mailing list