Jan 26 2011 | 10:36 pm
    i am tapping in the dark with finding the right method to grab an objects outlet. i would like to bind to an object the same way pvar does. any hints are highly welcome. klaus

    • Jan 27 2011 | 7:17 am
      how would you like to use it?
      basic way how we do it: - connect a named receive object to the object you would like to grab - create a grab with the nummer of outlets you need (probably the same as the object you would like to monitor, so say [grab 4 namedcoll] - send messages to the grab (kinda like the 'blue' example from the helpfile)
      notes: - names of receives and grabs can be set dynamically - make sure there is only 1 receive with that name - if the object you are grabbing behaves asynchronously, this method will fail
      [edit] I failed to see that your post was in Dev, so my answer might be a bit too basic. I made my own datacontainer, a mix between pvar pv send and receive which can be easily voiced and I use a nobox class with the object_attach , object_findregistered and notification methods, this doesn't communicate between different kinds of objects though
    • Jan 27 2011 | 10:52 am
      Hi Klaus,
      if, after reading Timothy's blog you decide to go the globalsymbol way, you might find helpful this thread as well: https://cycling74.com/forums/globalsymboling-issues
      Bests, Ádám
    • Jan 29 2011 | 5:36 pm
      hi there, so here is how far i came (see code below). the thing is, i want to start having an object that does *exactly* what pvar does as a starting point. so i don't want any custom notify routines whatsoever.
      i assumed, that pvar has kind of proxy inlets, that are not visible. and simply connects via an extra hidden patchcord to that invisible inlet. so thats my main question, is this right, or are there other concepts living in pvar?
      then my try opened a few other questions: - how do i get the jbox of my object, if its not a UI? - how can i tell my object, that a new object was created in the patcher, or somebody added a scripting name to one of the objects? - obviously making the connection to my object in the *new function is too early. can i get a notification, when the box of myobject is drawn?
      thanks for any help klaus
      #include "ext.h"							// standard Max include, always required
      #include "ext_obex.h"						// required for new style Max object
      #include "jpatcher_api.h"
      ////////////////////////// object struct
      typedef struct _ll_pvar
      	t_object					ob;			// the object itself (must be first)
      	t_symbol	*prepend;
      	long		prp;
      	t_symbol *the;
      	t_symbol *llist;
      	long m_in;
      	void *m_proxy;
      	t_symbol	*thename;
      } t_ll_pvar;
      void *ll_pvar_new(t_symbol *s, long argc, t_atom *argv);
      void ll_pvar_free(t_ll_pvar *x);
      void ll_pvar_anything(t_ll_pvar *x, t_symbol *s, long ac, t_atom *av);
      void ll_pvar_connect(t_ll_pvar *x);
      void ll_pvar_float(t_ll_pvar *x, double f);
      void ll_pvar_int(t_ll_pvar *x, long i);
      void *ll_pvar_class;
      int main(void)
      	t_class *c;
      	c = class_new("ll_pvar", (method)ll_pvar_new, (method)ll_pvar_free, (long)sizeof(t_ll_pvar),
      				  0L /* leave NULL!! */, A_GIMME, 0);
      	class_addmethod(c, (method)ll_pvar_connect,		"connect", 0);
      	class_addmethod(c, (method)ll_pvar_anything,	"anything", A_GIMME, 0);
      	class_addmethod(c, (method)ll_pvar_float, "float", A_FLOAT, 0);
      	class_addmethod(c, (method)ll_pvar_int, "int", A_LONG, 0);
      	class_register(CLASS_BOX, c); /* CLASS_NOBOX */
      	ll_pvar_class = c;
      	return 0;
      void ll_pvar_free(t_ll_pvar *x)
      void *ll_pvar_new(t_symbol *s, long argc, t_atom *argv)
      	t_ll_pvar *x = NULL;
          long i;
      	if (x = (t_ll_pvar *)object_alloc(ll_pvar_class)) {
              for (i = 0; i < argc; i++) {
                  if ((argv + i)->a_type == A_SYM) {
      				x->thename = atom_getsym(argv+i);
      				object_post((t_object *)x, "looking for %s", x->thename->s_name);
                  } else {
                      object_error((t_object *)x, "forbidden argument");
      	outlet_new((t_object *)x,NULL);
      	x->m_proxy = proxy_new((t_object *)x, 1, &x->m_in);
      	return (x);
       void ll_pvar_float(t_ll_pvar *x, double f)
      	switch (proxy_getinlet((t_object *)x)) {
      		case 0:
      		case 1:
      			outlet_float(x->ob.o_outlet,f) ;
      void ll_pvar_int(t_ll_pvar *x, long i)
      	switch (proxy_getinlet((t_object *)x)) {
      		case 0:
      		case 1:
      			outlet_int(x->ob.o_outlet,i) ;
      void ll_pvar_anything(t_ll_pvar *x, t_symbol *s, long ac, t_atom *av)
      	switch (proxy_getinlet((t_object *)x)) {
      		case 0:
      		case 1:
      			outlet_anything(x->ob.o_outlet,s,ac,av) ;
      void ll_pvar_connect(t_ll_pvar *x)
      	t_object *patcher = NULL, *box, *obj;
      	t_symbol *sn;
      	t_atom msg[4], ret;
      	object_obex_lookup(x, gensym("#P"), &patcher);
      	for (box = jpatcher_get_firstobject(patcher); box; box = jbox_get_nextobject(box)) {
      		obj = jbox_get_object(box);
      		if (obj){
      			sn = object_attr_getsym(box, gensym("varname"));
      			//post("%s %s",object_classname(obj)->s_name, sn->s_name);
      			if (sn == x->thename) atom_setobj(msg, box);
      			if (object_classname(obj) == gensym("ll_pvar")) atom_setobj(msg + 2, box);
      		} else
      			post("box with NULL object");
      	atom_setlong(msg + 1, 0);
      	atom_setlong(msg + 3, 1);
      	object_method_typed(patcher, gensym("connect"), 4, msg, &ret);
    • Jan 30 2011 | 12:39 am
      Hi Klaus.
      If I'm not mistaken (browser coding...) you should be able to get your jbox with
      t_object *box=NULL;
      object_obex_lookup((t_object *)x,gensym("#B"),&box);
      with x being your object, as usual Here https://cycling74.com/forums/request-jbox_get_arguments-or-such you can find more info.
      To watch the patcher for editing, you should attach it to your object with object_attach_byptr_register, and then give your object a notify method (see the scripto example). I'm not sure whether you get a notification from the patcher also for changing the scripting name of an object, but it's the first thing I would try. If you don't, I don't really know... Attaching your object to _all the objects in the patcher looks quite brutal... probably others may give you better advice than me!
      As for your third question, I'd defer_low the connection from the new method of your object. It should be enough.
      hth aa `
    • Jan 30 2011 | 7:16 pm
      thanks to all, this definitely helps a lot, and i am able now to do nearly everything i want. except having this invisible connection between the tracked object and my object. i am still hoping, that somebody from cycling can bring some light into that.
      @timo rozenthal: your are saying above: "I made my own datacontainer, a mix between pvar pv send and receive which can be easily voiced" this sounds very close to my project. are you sharing this object somewhere?
      cheers klaus
    • Jan 30 2011 | 10:15 pm
      and please please. i tried to avoid this question, and tried hard to find the answer in other threads of this forum::
      - how can i receive a message that is sent via typedmess() respectively a message that is sent via the max send object?
      if you may, please give me a simple code example of how i can get hold of the stuff, that is sent via an object [s there] elsewhere in max.
      many thanks klaus
    • Jan 30 2011 | 11:54 pm
      oups and yet another Q: is there any chance to create an inlet *after* the *new function?
      so dynamically call proxy_new() if i need more?
      best klaus
    • Jan 31 2011 | 8:00 am
      @klaus: I'll mail it to you
    • Jan 31 2011 | 12:44 pm
      Hi Klaus typedmess is, under the hood, how max objects communicate with each other even through patch cords. It simply means "call the msg method of the x object, with av arguments". So, just implement the method you want your object to respond to. But how will you be able to have [send] sending to a non [receive] object?
      and no, inlets are only created at instance creation time - unless there is some arcana that's hidden from our mortal eyes ;) but of course what you can do (don't know if it's relevant) is setting the number of inlets according to a typed-in argument