[PD-dev] Re: Observable

Mathieu Bouchard matju at artengine.ca
Sat Oct 29 02:33:13 CEST 2005


Ok, back from Norway, and even almost back from the cold I caught in the 
plane. Here's an update (no pun intended) on Observables.



On Thu, 6 Oct 2005, Mathieu Bouchard wrote:

> I am implementing an observer/observable interface in t_gobj.
> typedef struct _observable {
> 	struct _gobj *master; /* pointer back to our t_gobj */
> 	struct _gobj *next; /* formerly in t_gobj */
> /* actual observable */
> 	int dirty;          /* bitset of fields */

I have removed this "dirty" thing, and then re-added it again.

First I figured out that t_observable was a misnomer, and instead should 
be called t_appendix. (it's separate from t_gobj for binary compatibility 
reasons, but isn't only about observables).

Then I figured out that whatever I had copied from Ruby's Observable had
been copied from java.util.Observable which itself is not used by anybody
at all, and for a reason.

I found out that the two-phase system of flagging an object as "changed" 
and then coming back later to notify-if-necessary is silly. There is a 
much bigger incentive to gather notices together in a central place so 
that we can figure out their chronology, save time, and manage things (uh) 
holistically. So instead,

> EXTERN void observable_changed (t_observable *self, const char *k);
> EXTERN void observable_notify (t_observable *self);

is only one function now,

  gobj_changed(t_gobj *self, const char *k);

> /* virtual func for observer */
> 	void (*notice)(struct _gobj *x, struct _gobj *origin, int dirty);

This has been moved to t_class, and you set it using the function:

  typedef void (*t_notice)(struct _gobj *x, struct _gobj *origin,
	int argc, t_atom *argv);
  EXTERN void class_setnotice(t_class *c, t_notice notice);

Also,

> EXTERN void   observable_subscribe (t_observable *self, t_gobj *observer);
> EXTERN void observable_unsubscribe (t_observable *self, t_gobj *observer);

is now considered part of the t_gobj API, just like gobj_changed:

  EXTERN void gobj_subscribe   (t_gobj *self, t_gobj *observer);
  EXTERN void gobj_unsubscribe (t_gobj *self, t_gobj *observer);

Then Carmen (and others) asked me why i hadn't already added support for
partial array updates. So then I added this (instead of adding partial
array updates):

  EXTERN void gobj_changed2 (void /*t_gobj*/ *self, int argc, t_atom *argv);

Which allows any list of atoms (but heap-allocated, unlike list-messages)  
to be a notice. I'm not too sure how we will really use it, but that
should allow us not only to have partial array updates, but also partial 
updates of any kind imaginable.

> Those two manage the relationships so that the observables know where to 
> forward their notifications.

Then I found out that I didn't have a function that could take care of the 
forwarding, and so did I add:

  EXTERN void gobj_changed3 (void /*t_gobj*/ *self, t_gobj *origin,
    int argc, t_atom *argv);

Where one specifies where the notice is coming from.

Then I figured out that I didn't have a hashtable class handy and didn't
want to write one now so I added "dirty" fields back into the t_gobj's,
except that now they belong to the t_manager, supposing each object has
only one t_manager. This won't be true forever though, so later this will
have to be replaced by hashtables.

The t_manager is the thing that manages a queue of objects that have to be
updated (uploaded), in chronological order, without duplicates. When
duplicates are encountered, the earliest one is kept. This establishes a
priority for updating objects client-side. This allows to introduce a
"bandwidth limiter" that gives equal chance to all objects that need to be
updated.

When partial updates start to be supported for real, duplicate notices
will be handled in smarter ways. They will be coalesced (merged). E.g.
bitmasks of dirty fields will be OR'ed together, and extra notice info
will be appended to each other or something.

____________________________________________________________________
Mathieu Bouchard - tél:+1.514.383.3801 - http://artengine.ca/matju
Freelance Digital Arts Engineer, Montréal QC Canada




More information about the Pd-dev mailing list