[cells-devel] Something like a def-family-observer?

Ken Tilton kennytilton at optonline.net
Wed Dec 12 14:36:26 UTC 2007


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.

> 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.

kt



More information about the cells-devel mailing list