Forums > Dev

object registration interaction

February 7, 2007 | 2:59 am

I had a chance to look at the object registration stuff for passing
messages from jitter to the max wrapper. I’ve copied the details from
jit.notify, and everything seems to work in this regard – I can pass
information through.

however, I have two objects, one of which looks up the other by name:

[jit.foo @name foo]
[jit.bar @fooname foo]

jit.bar calls jit_object_findregistered(x->fooname) to get a pointer
to the jit.foo instance.

when I add the following code to the max wrapper for jit.foo, jit.bar
can no longer find jit.foo by name:

max_jit_foo_new(t_symbol *s, long argc, t_atom *argv) {
// ..

max_jit_attr_args(x, argc, argv); // process attribute arguments

x->servername = jit_symbol_unique();
jit_object_method(jit_ob, _jit_sym_register, x->servername);
jit_object_attach(x->servername, x);

// ..
}

presumably this is because jit.foo is now being named after x-
>servername, instead of the @name attribute. if I send ‘getname’ to
jit.foo, it correctly returns ‘foo’, which is the name supplied by
the constructor attribute and not jit_sym_unique().

I tried setting the x->servername to the name attribute, rather than
jit_symbol_unique(), but that crashed max when the object loaded. I
assumed that the attributes would be ready after calling
max_jit_attr_args, but perhaps that isn’t the case?

am I approaching this incorrectly? how does the x->servername in the
max wrapper get updated when the name is updated? does it even need
to be? I’m ever so confused.

best,

r.


February 7, 2007 | 6:25 am

On 07-02-06, at 1859, ritchie argue wrote:
>
> I tried setting the x->servername to the name attribute, rather
> than jit_symbol_unique(), but that crashed max when the object
> loaded. I assumed that the attributes would be ready after calling
> max_jit_attr_args, but perhaps that isn’t the case?
>
here’s one for the archives – I was getting the name attribute
incorrectly. note to self: it’s easier to figure things out after
eating dinner.

x->servername = jit_attr_getsym(jit_ob, _jit_sym_name);
if (x->servername == _jit_sym_nothing) {
x->servername = jit_symbol_unique();
jit_object_method(jit_ob, _jit_sym_register, x->servername);
}
jit_object_attach(x->servername, x);

this approach still falls apart if the name is changed after the
object is created. if I watch the notifications I receive, I see a
‘free’ message for the first name change, but no mention of the new
name. what is the correct way to keep the max wrapper in sync with
the jitter object in this case?

thanks,

r.


February 7, 2007 | 8:46 am

On Feb 6, 2007, at 10:25 PM, ritchie argue wrote:

>
> this approach still falls apart if the name is changed after the
> object is created. if I watch the notifications I receive, I see a
> ‘free’ message for the first name change, but no mention of the new
> name. what is the correct way to keep the max wrapper in sync with
> the jitter object in this case?

I believe the notify method will let you know about such reassignment
of named servers, though I could be mistaken. You could always notify
your clients about the name change using object_notify if it doesn’t
off the bat.

FWIW, you can also use the loadbang message, qelems, or lazy polling
for resolving servers after patch load or "when you need to". This is
what we typically do in Jitter for this sort of thing.

Hope this helps.

-Joshua


February 7, 2007 | 4:18 pm

On 07-02-07, at 0046, Joshua Kit Clayton wrote:
>
> I believe the notify method will let you know about such
> reassignment of named servers, though I could be mistaken.
>
from what I can tell, it doesn’t. it would be nice if this came
through as an attr_modified message like all the others. can I add a
feature request? =)

> You could always notify your clients about the name change using
> object_notify if it doesn’t off the bat.
>
I think this involves overriding the default name getter/setter/
storage provided by the obex. if I create my own storage, will the
obex suffer? do I need to figure out how to wrap the setter, and then
continue to use the obex as storage?

> FWIW, you can also use the loadbang message, qelems, or lazy
> polling for resolving servers after patch load or "when you need
> to". This is what we typically do in Jitter for this sort of thing.
>
I’m using this approach for my inter-object servers, and it works
great. the problem is updating the max wrapper client, as I have (as
far as I can tell) no means of independently telling it the new name
of the internal jitter object.

make sense?

r.


February 8, 2007 | 11:19 pm

On Feb 7, 2007, at 8:18 AM, ritchie argue wrote:

> from what I can tell, it doesn’t. it would be nice if this came
> through as an attr_modified message like all the others. can I add
> a feature request? =)

Will consider for future…

>> You could always notify your clients about the name change using
>> object_notify if it doesn’t off the bat.
>>
> I think this involves overriding the default name getter/setter/
> storage provided by the obex. if I create my own storage, will the
> obex suffer? do I need to figure out how to wrap the setter, and
> then continue to use the obex as storage?

Yes, you would need to add your own "name" setter for the ob3d (which
is where I presume you’re inheriting this attribute), and that’s
probably not a good idea. However, upon inspection of the ob3d name
setter, it automatically registers the max wrapper object (if one
exists), as a client when it has a new name. and after calling this
method the max wrapper object should receive the attr_modified
notification message with the new name attribute.

Let me know if I’m misunderstanding what you’re doing or if you
aren’t being notified of the attr name changed if you’re using this
with a max wrapper for an ob3d.

Code from the ob3d name setter below in case it helps you understand
better what we’re doing under the hood (though obviously it employs
data structures which we need to keep opaque).

-Joshua

t_jit_err jit_ob3d_name_set(t_jit_object *jit_ob, void *attr, long
argc, t_atom *argv)
{
t_jit_err result = JIT_ERR_NONE;
t_jit_ob3d *ob3d;
t_symbol *old_name, *new_name;
t_jit_object *o;

if (jit_ob && (ob3d = jit_ob3d_get(jit_ob)) && argc && argv)
{
old_name = ob3d->name;
new_name = jit_atom_getsym(argv);

if (new_name==old_name)
return result;

if (o=jit_object_findregistered(new_name))
{
error("name %s already in use. ob3d does not allow multiple
bindings", new_name->s_name);
result = JIT_ERR_GENERIC;
}
else
{
if (ob3d->max_obj)
jit_object_detach(old_name, ob3d->max_obj);
jit_object_unregister(jit_ob);
jit_ob = jit_object_method(jit_ob, _jit_sym_register, new_name);

// if registered ok under new name, attach max obj to new name.
if (jit_ob)
{
ob3d->name = new_name;
if (ob3d->max_obj)
{
jit_object_attach(new_name, ob3d->max_obj);
max_jit_obex_jitob_set(ob3d->max_obj, jit_ob);
}
}
else
result = JIT_ERR_GENERIC;
}
}
return result;
}


February 9, 2007 | 10:30 pm

On 07-02-08, at 1519, Joshua Kit Clayton wrote:
>
> Yes, you would need to add your own "name" setter for the ob3d
> (which is where I presume you’re inheriting this attribute), and
> that’s probably not a good idea. However, upon inspection of the
> ob3d name setter, it automatically registers the max wrapper object
> (if one exists), as a client when it has a new name. and after
> calling this method the max wrapper object should receive the
> attr_modified notification message with the new name attribute.
>
to follow up on this for the archives:

ob3d objects automatically have a notification mechanism provided
between the max wrapper and jitter object, I presume due to their
having a name attribute by default, unlike other jitter objects.

so, to receive notifications in the max wrapper for an ob3d object,
the extra work done in the jit.notify sample code is unnecessary.
here are the required parts:

int
main(void) {
//..

addmess((method)max_jit_gl_foo_notify, "notify", A_CANT, 0);

//..
}

void
max_jit_gl_foo_notify(t_max_jit_gl_foo *x, t_symbol *s, t_symbol
*msg, void *ob, void *data) {
// standard notification callback
}

void *
max_jit_gl_foo_new(t_symbol *s, long argc, t_atom *argv) {
//..

// attach the jit object’s ob3d to a new outlet for sending
drawing messages.
//max_jit_ob3d_attach(x, jit_ob, outlet_new(x, "jit_matrix"));
max_jit_ob3d_attach(x, jit_ob, NULL);
x->bangout = bangout(x);

//..
// no need to register for notifications here, handled by
max_jit_ob3d_attach
}

I had commented out max_jit_ob3d_attach(x, jit_ob, outlet_new(x,
"jit_matrix")); as I only wanted a bangout, not a matrix out. the
correct way to accomplish this is to pass NULL as the outlet
parameter. the ob3d handles all the notification registration, so
there is no need to keep track of the object name or unregister in
the free function.

thanks for all the help in tracking this down, joshua.

r.


Viewing 6 posts - 1 through 6 (of 6 total)