diff options
author | IOhannes m zmölnig <zmoelnig@users.sourceforge.net> | 2008-09-18 12:03:49 +0000 |
---|---|---|
committer | IOhannes m zmölnig <zmoelnig@users.sourceforge.net> | 2008-09-18 12:03:49 +0000 |
commit | edece44e516be164bfbfc09bf8743228bfa910d9 (patch) | |
tree | e43443e490c4e472426a8e65f5febb3b74334233 | |
parent | 491fbf15d2eaa60959da1d0d602ec7ad9040a1c5 (diff) |
more querying
svn path=/trunk/externals/iem/iemguts/; revision=10298
-rw-r--r-- | src/canvasconnections.c | 255 |
1 files changed, 248 insertions, 7 deletions
diff --git a/src/canvasconnections.c b/src/canvasconnections.c index cebd085..85e01e9 100644 --- a/src/canvasconnections.c +++ b/src/canvasconnections.c @@ -26,6 +26,7 @@ #include "m_pd.h" #include "g_canvas.h" #include "m_imp.h" +#include <string.h> int glist_getindex(t_glist *x, t_gobj *y); @@ -41,19 +42,251 @@ typedef struct _canvasconnections t_outlet *x_out; } t_canvasconnections; -static void canvasconnections_outlets(t_canvasconnections *x) +typedef struct _intvec +{ + int num_elements; /* number of valid elements in the 'elements' vector */ + int*elements; /* elements */ + int size; /* private: the full length of the 'elements' vector */ +} t_intvec; + + +static t_intvec*intvec_new(int initial_size) +{ + t_intvec*res=(t_intvec*)getbytes(sizeof(t_intvec)); + if(initial_size<1) + initial_size=32; + + res->num_elements=0; + res->size=initial_size; + res->elements=(int*)getbytes(res->size*sizeof(int)); + + return res; +} + + +static void intvec_free(t_intvec*vec) +{ + if(NULL==vec)return; + if(vec->elements) + freebytes(vec->elements, sizeof(int)*vec->size); + vec->elements=NULL; + + vec->size=0; + vec->num_elements=0; + + freebytes(vec, sizeof(t_intvec)); +} + + +static t_intvec*intvec_add(t_intvec*vec, int element) +{ + /* ensure that vector is big enough */ + if(vec->size<=vec->num_elements) { + /* resize! */ + t_intvec*vec2=intvec_new(2*vec->num_elements); + memcpy(vec2->elements, vec->elements, vec->size); + vec2->num_elements=vec->size; + intvec_free(vec); + vec=vec2; + } + + /* add the new element to the end of the vector */ + vec->elements[vec->num_elements]=element; + vec->num_elements++; + + return vec; +} + +/* just for debugging... */ +static void intvec_post(t_intvec*vec) +{ + int i=0; + post("vec: 0x%X :: 0x%X holds %d/%d elements", vec, vec->elements, vec->num_elements, vec->size); + startpost("elements:"); + for(i=0; i<vec->num_elements; i++) { + startpost(" %02d", vec->elements[i]); + } + endpost(); +} + +static t_intvec**query_inletconnections(t_canvasconnections *x, int *num_inlets) { + int i=0; + t_intvec**invecs=NULL; + int ninlets=0; + int nin=0; + + t_gobj*y; + + if(0==x->x_object || 0==x->x_parent) + return 0; + + ninlets=obj_ninlets(x->x_object); + *num_inlets=ninlets; + + + // TODO....find objects connecting TO this object + /* as Pd does not have any information about connections to inlets, + * we have to find out ourselves + * this is done by traversing all objects in the canvas and try + * to find out, whether they are connected to us! + */ + + invecs=getbytes(sizeof(t_intvec*)*ninlets); + for(i=0; i<ninlets; i++)invecs[i]=intvec_new(0); + + for (y = x->x_parent->gl_list; y; y = y->g_next) /* traverse all objects in canvas */ + { + t_object*obj=(t_object*)y; + int obj_nout=obj_noutlets(obj); + int nout=0; + for(nout=0; nout<obj_nout; nout++) { /* traverse all outlets of each object */ + t_outlet*out=0; + t_inlet *in =0; + t_object*dest=0; + int sourcewhich=0; + + t_outconnect*conn=obj_starttraverseoutlet(obj, &out, nout); + + while(conn) { /* traverse all connections from each outlet */ + int which; + conn=obj_nexttraverseoutlet(conn, &dest, &in, &which); + if(dest==x->x_object) { // connected to us! + int connid = glist_getindex(x->x_parent, (t_gobj*)obj); + + // post("inlet from %d:%d to my:%d", connid, sourcewhich, which); + + /* add it to the inletconnectionlist */ + intvec_add(invecs[which], connid); + } + sourcewhich++; + } + } + } + return invecs; +} + +static void canvasconnections_queryinlets(t_canvasconnections *x) +{ + t_atom at; + int ninlets=0, i; + t_intvec**invecs=query_inletconnections(x, &ninlets); + + SETFLOAT(&at, (t_float)ninlets); + outlet_anything(x->x_out, gensym("inlets"), 1, &at); + + for(i=0; i<ninlets; i++){ + int size=invecs[i]->num_elements; + t_atom*ap=getbytes(sizeof(t_atom)*(size+1)); + int j=0; + SETFLOAT(ap, (t_float)i); + for(j=0; j<size; j++) + SETFLOAT(ap+j+1, ((t_float)invecs[i]->elements[j])); + + outlet_anything(x->x_out, gensym("inlet"), size+1, ap); + + intvec_free(invecs[i]); + freebytes(ap, sizeof(t_atom)*(size+1)); + } + if(invecs)freebytes(invecs, sizeof(t_intvec*)*ninlets); +} + +static int canvasconnections_inlets(t_canvasconnections *x) { - int noutlets=0; - int nout=0; t_atom at; + int ninlets=0; if(0==x->x_object || 0==x->x_parent) + return 0; + + ninlets=obj_ninlets(x->x_object); + + + ninlets=obj_ninlets(x->x_object); + SETFLOAT(&at, (t_float)ninlets); + outlet_anything(x->x_out, gensym("inlets"), 1, &at); + + return ninlets; +} + +static void canvasconnections_inlet(t_canvasconnections *x, t_floatarg f) +{ + int inlet=f; + t_atom at[4]; + int ninlets=0; + + t_intvec**inlets=query_inletconnections(x, &ninlets); + if(!inlets || inlet < 0 || inlet>ninlets) { + /* non-existing inlet! */ return; + } else { + post("TODO"); + + } +} + + +static int canvasconnections_outlets(t_canvasconnections *x) +{ + t_atom at; + int noutlets=0; + + if(0==x->x_object || 0==x->x_parent) + return 0; noutlets=obj_noutlets(x->x_object); SETFLOAT(&at, (t_float)noutlets); - outlet_anything(x->x_out, gensym("outlets"), 1, &at); + + return noutlets; +} + +static void canvasconnections_outlet(t_canvasconnections *x, t_floatarg f) +{ + int outlet=f; + t_atom at[4]; + int noutlets=0; + + if(0==x->x_object || 0==x->x_parent) + return; + + noutlets=obj_noutlets(x->x_object); + + if(outlet<0 || outlet>=noutlets) { + post("nonexisting outlet: %d", outlet); + /* non-existing outlet! */ + return; + } else { + t_outlet*out=0; + t_outconnect*conn=obj_starttraverseoutlet(x->x_object, &out, outlet); + t_object*dest=0; + t_inlet*in=0; + int count=0; + int id=glist_getindex(x->x_parent, (t_gobj*)x->x_object); + + conn=obj_starttraverseoutlet(x->x_object, &out, outlet); + while(conn) { + int destid=0; + int destwhich=0; + conn=obj_nexttraverseoutlet(conn, &dest, &in, &destwhich); + destid = glist_getindex(x->x_parent, (t_gobj*)dest); + + //post("connection from %d|%d to %d|%d", id, outlet, destid, destwhich); + SETFLOAT(at+0, (t_float)id); + SETFLOAT(at+1, (t_float)outlet); + SETFLOAT(at+2, (t_float)destid); + SETFLOAT(at+3, (t_float)destwhich); + + outlet_anything(x->x_out, gensym("outconnect"), 4, at); + } + } + +} + +static void canvasconnections_queryoutlets(t_canvasconnections *x) +{ + int noutlets=canvasconnections_outlets(x); + int nout=0; + t_atom at; for(nout=0; nout<noutlets; nout++) { t_outlet*out=0; t_outconnect*conn=obj_starttraverseoutlet(x->x_object, &out, nout); @@ -70,10 +303,11 @@ static void canvasconnections_outlets(t_canvasconnections *x) SETFLOAT(abuf, nout); conn=obj_starttraverseoutlet(x->x_object, &out, nout); while(conn) { - t_float connid=0; + int connid=0; conn=obj_nexttraverseoutlet(conn, &dest, &in, &which); connid = glist_getindex(x->x_parent, (t_gobj*)dest); - SETFLOAT(abuf+1+i, connid); + + SETFLOAT(abuf+1+i, (t_float)connid); i++; } outlet_anything(x->x_out, gensym("outlet"), count+1, abuf); @@ -83,7 +317,8 @@ static void canvasconnections_outlets(t_canvasconnections *x) static void canvasconnections_bang(t_canvasconnections *x) { - canvasconnections_outlets(x); + canvasconnections_queryinlets(x); + canvasconnections_queryoutlets(x); } @@ -127,4 +362,10 @@ void canvasconnections_setup(void) sizeof(t_canvasconnections), 0, A_DEFFLOAT, 0); class_addbang(canvasconnections_class, (t_method)canvasconnections_bang); + + class_addmethod(canvasconnections_class, (t_method)canvasconnections_outlets, gensym("outlets"), 0); + class_addmethod(canvasconnections_class, (t_method)canvasconnections_outlet, gensym("outlet"), A_FLOAT, 0); + + class_addmethod(canvasconnections_class, (t_method)canvasconnections_inlets, gensym("inlets"), 0); + class_addmethod(canvasconnections_class, (t_method)canvasconnections_inlet, gensym("inlet"), A_FLOAT, 0); } |