Hi list, i plan to program an external object which should be able to find out which objects are connected to its inlets and outlets. How can i retrieve the adresses of the respective object structures?
thanks in advance, Thomas
Hi all,
If you happen to be able to write methods for the connected objects, just send them some kind of "probe" message that causes them to announce themselves to you. But if you're wanting to find out what among all possible Pd objects you're connected to, you'll have to go adding code to m_obj.c to chase the links down...
cheers Miller
On Mon, Oct 29, 2001 at 11:21:17PM +0100, Thomas Grill wrote:
Hi list, i plan to program an external object which should be able to find out which objects are connected to its inlets and outlets. How can i retrieve the adresses of the respective object structures?
thanks in advance, Thomas
hi,
since customizing m_obj.c makes upgrading hard...
Miller Puckette wrote: ...
if you're wanting to find out what among all possible Pd objects you're connected to, you'll have to go adding code to m_obj.c to chase the links down...
... maybe a slightly different approach could be worth trying -- there is a simple (although inefficient) way for sink-object to find its source-objects, as shown in demo external defined in whofeedsme.c attachment.
Miller Puckette wrote: ...
If you happen to be able to write methods for the connected objects, just send them some kind of "probe" message that causes them to announce themselves to you.
Plugging new methods into any existing class is easy, once a pointer to that class is available. The [whofeedsme] external uses this to infect its feeders.
Now, my question is: how to spread such a virus? I mean, how to get hold of a pointer to a canvas from within a method other then constructor?
Krzysztof
#include "m_imp.h" #include "g_canvas.h"
typedef struct _whofeedsme { t_object x_ob; t_glist *x_glist; } t_whofeedsme;
static t_class *whofeedsme_class;
static void *whofeedsme_new(void) { t_whofeedsme *x = (t_whofeedsme *)pd_new(whofeedsme_class); x->x_glist = (t_glist *)canvas_getcurrent(); return (x); }
static void whofeedsme_whofeedsme(t_whofeedsme *x) { t_gobj *y; t_object *src; t_symbol *mname = gensym("whofeedsme"); if (*(t_pd *)x == whofeedsme_class) y = x->x_glist->gl_list; else { t_glist *gl = (t_glist *)canvas_getcurrent(); if (gl) y = gl->gl_list; else { post("gosh, is it immune?"); return; } /* the stack is empty... */ } for (; y; y = y->g_next) { if (src = pd_checkobject(&y->g_pd)) { t_object *dest; t_outconnect *oc; t_outlet *op; t_inlet *ip; int outno = obj_noutlets(src); int inno; t_class *sclass = *(t_pd *)src; char *sname = class_getname(sclass); post("[%s]", sname); while (outno--) { oc = obj_starttraverseoutlet(src, &op, outno); while (oc) { oc = obj_nexttraverseoutlet(oc, &dest, &ip, &inno); post("\t-> [%s]", class_getname(*(t_pd *)dest)); if (dest == (t_object *)x) { int i = sclass->c_nmethod; t_methodentry *m = sclass->c_methods; startpost("*\there I am, [%s] is my feeder ", sname); while (i--) if (m++->me_name == mname) break; if (i >= 0) post("-- already infected..."); else { class_addmethod(sclass, (t_method)whofeedsme_whofeedsme, mname, 0); post("-- got infected!"); } } } } } } }
void whofeedsme_setup(void) { whofeedsme_class = class_new(gensym("whofeedsme"), (t_newmethod)whofeedsme_new, 0, sizeof(t_whofeedsme), 0, 0); class_addmethod(whofeedsme_class, (t_method)whofeedsme_whofeedsme, gensym("whofeedsme"), 0); }
#N canvas 0 0 450 300 12; #X msg 39 108 whofeedsme; #X obj 39 156 t anything; #X obj 39 207 whofeedsme; #X obj 39 58 loadbang; #X obj 149 58 loadbang; #X connect 0 0 1 0; #X connect 1 0 2 0; #X connect 3 0 0 0; #X connect 4 0 0 0;
Hi list, thanks very much for all your help. I realized that i can use the _outlet and _outconnect structures to get the successors of an object. As the struct definitions are hidden in a *.c-file and not publicly declared in a header file: can they be subject to severe changes in a future version of pd? For the moment i'm quite satisfied with this solution - i only need top-down signal flow (for spectral data, btw.), so i do not need to know the predecessors of an object.
greetings, Thomas
hi,
it does not matter, if definitions change, as long as you are using obj_noutlets() and obj_{start,next}traverseoutlet() -- take a look at my example (it is cluttered somewhat with the viral code, sorry)...
Krzysztof
Thomas Grill wrote: ...
thanks very much for all your help. I realized that i can use the _outlet and _outconnect structures to get the successors of an object. As the struct definitions are hidden in a *.c-file and not publicly declared in a header file: can they be subject to severe changes in a future version of pd?