pvar-like

Jan 26, 2011 at 10:36pm

pvar-like

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

#54625
Jan 27, 2011 at 6:36am

Hello klaus filip,

- Sheep / Shepherd new example in last SDK
- Timothy Place blog : http://74objects.com : (Custom Data-Types series) !

HTH.

Post Scriptum :

http://cycling74.com/forums/topic.php?id=27185 … for my [talkie] [walkie] example : now best to use t_dictionnary Sheep / Shepherd trick ;-)

#196702
Jan 27, 2011 at 7:17am

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

#196703
Jan 27, 2011 at 10:52am

Hi Klaus,

if, after reading Timothy’s blog you decide to go the globalsymbol way, you might find helpful this thread as well: http://cycling74.com/forums/topic.php?id=29886

Bests,
Ádám

#196704
Jan 29, 2011 at 5:36pm

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);
	ll_pvar_connect(x);
	return (x);
}

 void ll_pvar_float(t_ll_pvar *x, double f)
{
	switch (proxy_getinlet((t_object *)x)) {
		case 0:
			post("later");
			break;
		case 1:
			outlet_float(x->ob.o_outlet,f) ;
			break;
	}
}

void ll_pvar_int(t_ll_pvar *x, long i)
{
	switch (proxy_getinlet((t_object *)x)) {
		case 0:
			post("later");
			break;
		case 1:
			outlet_int(x->ob.o_outlet,i) ;
			break;
	}
}

void ll_pvar_anything(t_ll_pvar *x, t_symbol *s, long ac, t_atom *av)
{

	switch (proxy_getinlet((t_object *)x)) {
		case 0:
			post("later");
			break;
		case 1:
			outlet_anything(x->ob.o_outlet,s,ac,av) ;
			break;
	}

}

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);

}
#196705
Jan 30, 2011 at 12:39am

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 http://cycling74.com/forums/topic.php?id=25883 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
`

#196706
Jan 30, 2011 at 3:21pm

Hello klaus filip,

(perhaps you have already done it but) have a look on iterator and iterate2 examples in the SDK …

#196707
Jan 30, 2011 at 7:16pm

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

#196708
Jan 30, 2011 at 10:15pm

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

#196709
Jan 30, 2011 at 11:54pm

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

#196710
Jan 31, 2011 at 8:00am

@klaus: I’ll mail it to you

#196711
Jan 31, 2011 at 12:44pm

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

aa

#196712

You must be logged in to reply to this topic.