Update of /cvsroot/pure-data/pd/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv5231
Modified Files: Tag: devel_0_39 m_pd.h m_imp.h desire.c Log Message: simplified observables
Index: m_pd.h =================================================================== RCS file: /cvsroot/pure-data/pd/src/m_pd.h,v retrieving revision 1.4.4.11.2.9 retrieving revision 1.4.4.11.2.10 diff -C2 -d -r1.4.4.11.2.9 -r1.4.4.11.2.10 *** m_pd.h 6 Oct 2005 07:57:08 -0000 1.4.4.11.2.9 --- m_pd.h 21 Oct 2005 13:17:01 -0000 1.4.4.11.2.10 *************** *** 160,174 **** typedef t_class *t_pd; /* pure datum: nothing but a class pointer */ #ifdef DESIRE ! /* names of fields are stored in each t_class */ ! typedef struct _observable { ! struct _gobj *master;/* this struct belongs to a master (but in the tcl impl, it's _part_ of the master) */ struct _gobj *next; /* big hack. this is the donut hole as cut from _gobj */ /* actual observable */ - int dirty; /* bitfield of things we may have to confess (unknown=-1 like "(all)" in the client side) */ int nobs; /* number of spies */ struct _gobj **obs; /* I spy with my little I */ ! /* virtual func for observer (not observable... sorry, this is just C) */ ! void (*notice)(struct _gobj *x, struct _gobj *origin, int dirty); ! } t_observable; #endif
--- 160,178 ---- typedef t_class *t_pd; /* pure datum: nothing but a class pointer */ #ifdef DESIRE ! /* _gobj_appendix is made of the things that logically ought to be in _gobj but have ! been put in a separate memory space because this allows most externals to work ! unmodified on both DesireData and non-DesireData systems. ! The equivalent in the Tcl side is really part of every view object ! Note: The observer func ptr has been moved to the t_class. ! Note: names of fields are stored in each t_class. ! Note: as of 2005-10-18, this is no longer a delayed observer pattern as in Java, so no need for dirty-flags. ! */ ! typedef struct _gobj_appendix { ! struct _gobj *master; /* this is the thing that this appendix is an appendage of */ struct _gobj *next; /* big hack. this is the donut hole as cut from _gobj */ /* actual observable */ int nobs; /* number of spies */ struct _gobj **obs; /* I spy with my little I */ ! } t_appendix; #endif
*************** *** 178,183 **** #ifdef DESIRE /* g_next is moved out to keep ABI compat */ ! t_observable *g_obs; /* voyeurism */ ! #define g_next g_obs->next #else struct _gobj *g_next; /* next in list */ --- 182,187 ---- #ifdef DESIRE /* g_next is moved out to keep ABI compat */ ! t_appendix *g_adix; /* voyeurism (observable/observer/etc) */ ! #define g_next g_adix->next #else struct _gobj *g_next; /* next in list */ *************** *** 352,356 **** #define pd_class(x) (*(x))
! EXTERN void gobj_notice(t_gobj *x, t_gobj *origin, int dirty);
/* ----------------- pointers ---------------- */ --- 356,365 ---- #define pd_class(x) (*(x))
! #ifdef DESIRE ! EXTERN void gobj_subscribe (t_gobj *self, t_gobj *observer); ! EXTERN void gobj_unsubscribe (t_gobj *self, t_gobj *observer); ! EXTERN void gobj_changed (t_gobj *self, const char *k); ! EXTERN void gobj_changed2 (t_gobj *self, int argc, t_atom *argv); ! #endif
/* ----------------- pointers ---------------- */ *************** *** 446,450 **** class_domainsignalin(c, (char *)(&((type *)0)->field) - (char *)0)
! /* prototype for functions to save Pd's to a binbuf */ typedef void (*t_savefn)(t_gobj *x, t_binbuf *b); EXTERN void class_setsavefn(t_class *c, t_savefn f); --- 455,464 ---- class_domainsignalin(c, (char *)(&((type *)0)->field) - (char *)0)
! #ifdef DESIRE ! 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); ! #endif ! ! /* prototype for functions to save Pd's to a binbuf */ typedef void (*t_savefn)(t_gobj *x, t_binbuf *b); EXTERN void class_setsavefn(t_class *c, t_savefn f);
Index: m_imp.h =================================================================== RCS file: /cvsroot/pure-data/pd/src/m_imp.h,v retrieving revision 1.3.4.1.2.2 retrieving revision 1.3.4.1.2.3 diff -C2 -d -r1.3.4.1.2.2 -r1.3.4.1.2.3 *** m_imp.h 6 Oct 2005 06:58:45 -0000 1.3.4.1.2.2 --- m_imp.h 21 Oct 2005 13:17:01 -0000 1.3.4.1.2.3 *************** *** 54,62 **** char c_drawcommand; /* a drawing command for a template */ t_symbol *c_firsttip; t_symbol **c_fields; /* names of fields aka attributes. */ int c_nfields; /* ... and how many of them */ };
- /* m_obj.c */ EXTERN int obj_noutlets(t_object *x); --- 54,64 ---- char c_drawcommand; /* a drawing command for a template */ t_symbol *c_firsttip; + #ifdef DESIRE t_symbol **c_fields; /* names of fields aka attributes. */ int c_nfields; /* ... and how many of them */ + t_notice c_notice; /* observer method */ + #endif };
/* m_obj.c */ EXTERN int obj_noutlets(t_object *x);
Index: desire.c =================================================================== RCS file: /cvsroot/pure-data/pd/src/Attic/desire.c,v retrieving revision 1.1.2.32 retrieving revision 1.1.2.33 diff -C2 -d -r1.1.2.32 -r1.1.2.33 *** desire.c 6 Oct 2005 10:17:46 -0000 1.1.2.32 --- desire.c 21 Oct 2005 13:17:01 -0000 1.1.2.33 *************** *** 32,41 ****
//-------------------------------------------------------------------------- ! ! t_observable *observable_new (t_gobj *master) { ! t_observable *self = malloc(sizeof(t_observable)); self->master = master; self->next = 0; - self->dirty = 0; self->nobs = 0; self->obs = 0; --- 32,39 ----
//-------------------------------------------------------------------------- ! t_appendix *appendix_new (t_gobj *master) { ! t_appendix *self = malloc(sizeof(t_appendix)); self->master = master; self->next = 0; self->nobs = 0; self->obs = 0; *************** *** 44,75 ****
/* subscribing N spies takes N*N time, but I don't care in this case */ ! void observable_subscribe (t_observable *self, t_gobj *observer) { int i; ! for (i=0; i<self->nobs; i++) if (self->obs[i]) return; ! self->obs=realloc(self->obs,sizeof(t_gobj *)*(1+self->nobs)); ! self->obs[self->nobs++] = observer; }
! void observable_unsubscribe (t_observable *self, t_gobj *observer) { int i; ! for (i=0; i<self->nobs; i++) if (self->obs[i]) break; ! if (i==self->nobs) return; ! self->nobs--; ! for (; i<self->nobs-1; i++) self->obs[i] = self->obs[i+1]; }
// if !k then suppose all of the object might have changed. ! void observable_changed (t_observable *self, const char *k) { ! if (!k) self->dirty=-1; ! if (self->dirty<0) return; ! self->dirty |= 1 << class_getfieldindex(self->master->g_pd,k); }
! void observable_notify (t_observable *self) { int i; ! for (i=0; i<self->nobs; i++) { ! gobj_notice(self->obs[i],self->master,self->dirty); ! } ! self->dirty = 0; }
--- 42,74 ----
/* subscribing N spies takes N*N time, but I don't care in this case */ ! void gobj_subscribe (t_gobj *self, t_gobj *observer) { ! t_appendix *d = self->g_adix; int i; ! for (i=0; i<d->nobs; i++) if (d->obs[i]) return; ! d->obs=realloc(d->obs,sizeof(t_gobj *)*(1+d->nobs)); ! d->obs[d->nobs++] = observer; }
! void gobj_unsubscribe (t_gobj *self, t_gobj *observer) { ! t_appendix *d = self->g_adix; int i; ! for (i=0; i<d->nobs; i++) if (d->obs[i]) break; ! if (i==d->nobs) return; ! d->nobs--; ! for (; i<d->nobs-1; i++) d->obs[i] = d->obs[i+1]; }
// if !k then suppose all of the object might have changed. ! void gobj_changed (t_gobj *self, const char *k) { ! int dirty = k ? (1<<class_getfieldindex(self->g_pd,k)) : -1; ! t_atom argv[1]; ! SETFLOAT(argv,(float)dirty); ! gobj_changed2(self,1,argv); }
! void gobj_changed2 (t_gobj *self, int argc, t_atom *argv) { ! t_appendix *d = self->g_adix; int i; ! for (i=0; i<d->nobs; i++) self->g_pd->c_notice(d->obs[i],self,argc,argv); }
*************** *** 5215,5219 **** { t_object *ob; ! y->g_obs = observable_new(y); /* mb: i found no better place for initing this */ y->g_next = 0; if (!x->gl_list) x->gl_list = y; --- 5214,5219 ---- { t_object *ob; ! y->g_adix = appendix_new(y); /* mb: i found no better place for initing this */ ! gobj_subscribe(y,x); y->g_next = 0; if (!x->gl_list) x->gl_list = y;