[PEAK] Using peak.model as an observer subject

Phillip J. Eby pje at telecommunity.com
Wed Sep 1 21:10:54 EDT 2004


At 07:17 PM 9/1/04 -0500, Doug Quale wrote:
>"Phillip J. Eby" <pje at telecommunity.com> writes:
>
> > At 11:08 AM 9/1/04 -0500, Doug Quale wrote:
> > >I want to use peak.model as the model in MVC so I need notification of
> > >updates.
> >
> > Currently, you need to override the '_onLink'/'_onUnlink' methods of
> > the features involved in order to do anything like this.
> >
> > The long-term plan is that peak.storage will provide some kind of
> > event support, but for right now this is the only way to do it.
>
>Thanks for your instantaneous reply and your patience with my
>elementary questions.  I had to take some time to try this out.
>
>I have never used the method exporter facilities of peak.model but it
>seems like they might be useful here.  Is this a workable approach?
>Simple is OK because I don't need a very featureful observer pattern.

Looks pretty good to me.  Personally, I'd use peak.events "event source" 
objects such as
'events.Broadcaster' instances rather than creating a new callback 
facility.  This would eliminate the need for the _callbacks dictionary and 
a fair bit of logic; i.e. something like:

     class ObservableAttr(model.Attribute):
         newVerbs = [('get_event', '%(singularName)sEvent')]

         def get_event(feature, element):
             key = feature.attrName+'__event'
             try:
                 return feature.__dict__[key]
             except KeyError:
                 return feature.__dict__.setdefault(key,events.Broadcaster)

         def _onLink(feature, element, item, posn=None):
             feature.get_event(element).send(...)

Then, to subscribe to a feature, you'd do:

     anElement.someFeatureNameEvent().addCallback(callback)

Of course, this only calls 'callback' once; you'd probably use:

     source = anElement.someFeatureNameEvent()
     unsubscribe = events.subscribe(source, callback)

which handles weak referencing for you, and automatically re-adds the 
callback each time the event fires.

In addition to saving you from writing all the callback management code 
yourself, this approach in principle lets you use events.Task 
"pseudothreads" to manage asynchronous, event-driven tasks.  For example, 
you can model GUI constraint resolution (e.g. "this field = that field * 
the other field") as continuously-looping 'events.Task' procedures that 
wait for the appropriate events.  It might be overkill for simple GUI's, 
though.




More information about the PEAK mailing list