[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