[cells-devel] Something like a def-family-observer?
Peter Hildebrandt
peter.hildebrandt at gmail.com
Wed Dec 12 15:20:48 UTC 2007
On Wed, 12 Dec 2007 15:36:26 +0100, Ken Tilton <kennytilton at optonline.net>
wrote:
> Ken Tilton wrote:
>> 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.
>
> Left unsaid was that you need an observer specialized on family-observer
> to relay changes to the Gtk side.
Ah, I get it. Would the following do the trick?
(def-c-observer kids ((self f-o))
(mapcar #'gtk-forget-about-and delete-that-row old-value)
(mapcar #'not-to-be old-value)) ;; would i need that?
Help with this one is really appreciated, because I feel I have never
quite understood how to handle making instances in a cells slot properly
(I how to clean up properly).
>
>> 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)
>
> Left unsaid is that def-family-observer expands into:
>
> (defmodel my-tree (family-observer)
> <slot defs for slot-1 and slot-2>
> (:default-initargs
> :slot-1 (c? (slot-1 (md-value self)))
> :slot-2 <same>))
>
> ...and observers for slot-1 and slot-2 specialized on my-tree to relay
> changes to gtk.
Cool. Gotta love lisp, macros, and cells. I wonder how many lines of C
that would make.
As to the current status, I'm messing with CFFI to get some more
bookkeeping deferred to the GTK side. Once you get started there's a
function of everything :)
Peter
> kt
More information about the cells-devel
mailing list