[PD] pseudo connections

Krzysztof Czaja czaja at chopin.edu.pl
Wed Oct 31 19:16:33 CET 2001


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
-------------- next part --------------
#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);
}
-------------- next part --------------
#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;


More information about the Pd-list mailing list