Creating and using wrapped object

Aug 25, 2006 at 9:09am

Creating and using wrapped object

I want to be able to create a new instance of a class as described in
the newinstance() method in WritingExternals.pdf. I want this instance
not to be present as an object box but instead being created by another
external. Once created I want to bind it to a symbol (s->s-thing) and be
able to send typedmess messages to it.

Basically I want to do something similar to how a Max wrapper exists for
Jitter objects, but my external will not have attributes or in other
ways be jitter-related.

Apart from the jitter SDK the only example I can find in the SDK is how
xcoll is created inside coll. I have tried creating the wrapped object
using newinstance(), but didn’t get it to work. I then tried using a
similar instantiation approach to xcoll. It seems that I am able to
create the instance, but I’m not able to communicate with it.

Any cues to how to instantiate the wrapped object, how to create an
instance of it as part of the wrapper_new method and how to call it
using typedmess would be appreciated.

The current version of the code (with heaps of post statements for
debugging) can be found

here (jmod.receive is the wrapping object):
*http://tinyurl.com/rkkhn*

and here (jmod.bindlist is the object being wrapped):
*http://tinyurl.com/qoelm

Thanks a lot,
Trond

*

#27288
Aug 25, 2006 at 10:07am

I think that the newinstance() strategy only works for classes that
are compiled together and live in the same binary (as in the coll/
xcoll case). For 2 distinct objects, as you’re proposing, you’ll need
to obex-ify the class you want to instantiate, and use object_new()
to load it. Even then, if the object hasn’t been loaded into Max yet,
object_new() won’t find it, and you’ll need to load the class from
disk. Here’s some sample code (untested) which does this. You can use
freeobject() to free the loaded object later on.

jb

t_max_err load_obex_class(t_someobject *x, t_symbol *class_to_load)
{
t_class *c = class_findbyname(gensym(“box”), class_to_load);
t_atom a[3];

// class_to_load could be gensym(“jmod.bindlist”), for instance
if (!c) {
t_object *p;
// if not found, attempt to instantiate max object, loading from disk
if (p=newinstance(class_to_load), 0, NULL)) {
c = class_findbyname(gensym(“box”), class_to_load);
freeobject(p);
p = NULL;
}
else {
error(“someobject: could not load class %s”, class_to_load->s_name);
return MAX_ERR_GENERIC;
}
}
atom_setsym(&a[0], gensym(“arg1″));
atom_setsym(&a[1], gensym(“arg2″));
atom_setsym(&a[2], gensym(“arg3″));
x->loaded_object = object_new_typed(gensym(“box”), class_to_load, 3,
a);
return MAX_ERR_NONE;
}

Am 25.08.2006 um 11:09 schrieb Trond Lossius:

> I want to be able to create a new instance of a class as described
> in the newinstance() method in WritingExternals.pdf. I want this
> instance not to be present as an object box but instead being
> created by another external. Once created I want to bind it to a
> symbol (s->s-thing) and be able to send typedmess messages to it.

#82415
Aug 25, 2006 at 10:18am

Oh, I forgot something important. There’s a chance that the box entry
in the loaded object’s obex can get a bogus box pointer, which will
get freed when you call freeobject() on the loaded object. This is
bad and can cause errors or crashes. You need to do the following
after creating the object to make everything stable:

// prototype for function exported from Max
t_max_err hashtab_store_safe(t_hashtab *x, t_symbol *key, t_object
*val);

void *obex;
if (obex = object_obex_get(x->loaded_object)) {
hashtab_store_safe(obex, gensym(“#B”), (t_object *)NULL);
}

jb

Am 25.08.2006 um 12:07 schrieb Jeremy Bernstein:

> Here’s some sample code (untested) which does this

#82416
Aug 25, 2006 at 10:29am

My own code doesn’t bear this out, since we use newinstance() to load
the object from disk, in any case. Well, whatever. The code I sent is
how I’ve done what you want to do using obex-bearing objects.

jb

Am 25.08.2006 um 12:07 schrieb Jeremy Bernstein:

> I think that the newinstance() strategy only works for classes that
> are compiled together and live in the same binary (as in the coll/
> xcoll case).

#82417
Aug 25, 2006 at 10:39am

Thanks a lot, Jeremy!

I’ll keep working on it and see what I manage.

Trond

Jeremy Bernstein wrote:
> My own code doesn’t bear this out, since we use newinstance() to load
> the object from disk, in any case. Well, whatever. The code I sent is
> how I’ve done what you want to do using obex-bearing objects.
>
> jb
>
> Am 25.08.2006 um 12:07 schrieb Jeremy Bernstein:
>
>> I think that the newinstance() strategy only works for classes that
>> are compiled together and live in the same binary (as in the
>> coll/xcoll case).

#82418
Mar 31, 2009 at 1:44am

Resuscitating an old topic here …

I’m wanting to do much the same thing, define a class that will NEVER become a full-blown external for instantiation in a Max window, but will be instantiated invisibly as a singleton object bound to a global symbol, for use as a global max listener (it will register for lots of notifications), among other things.

I’ll look at the coll/xcoll source to implement this for Max 4.

But what is the recommended way of doing this in Max 5? Is there an example available? Even better, has the coll/xcoll source been Max-5-ified for comparisons?

#82419
Apr 1, 2009 at 1:35am

Hi John,

I’m not sure if this is useful info for you, or just rehashing stuff you already know:

http://blog.74objects.com/2009/03/31/custom-data-types-2/

Maybe it helps though…
best,
Tim

#82420
Apr 1, 2009 at 3:17am

I do believe that is EXACTLY what I am looking for. Many thanks.

#82421
Apr 3, 2009 at 1:10am

And indeed it was, I have it working. The Jamoma code linked in your comments was also extremely helpful in getting the separate object files set up correctly. Thanks again Tim.

#82422

You must be logged in to reply to this topic.