aboutsummaryrefslogtreecommitdiff
path: root/src/canvasconnections.c
diff options
context:
space:
mode:
authorIOhannes m zmölnig <zmoelnig@users.sourceforge.net>2008-09-18 12:03:49 +0000
committerIOhannes m zmölnig <zmoelnig@users.sourceforge.net>2008-09-18 12:03:49 +0000
commitedece44e516be164bfbfc09bf8743228bfa910d9 (patch)
treee43443e490c4e472426a8e65f5febb3b74334233 /src/canvasconnections.c
parent491fbf15d2eaa60959da1d0d602ec7ad9040a1c5 (diff)
more querying
svn path=/trunk/externals/iem/iemguts/; revision=10298
Diffstat (limited to 'src/canvasconnections.c')
-rw-r--r--src/canvasconnections.c255
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);
}