Creating and using wrapped object


    Aug 25 2006 | 9:09 am
    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
    *

    • Aug 25 2006 | 10:07 am
      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.
    • Aug 25 2006 | 10:18 am
      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
    • Aug 25 2006 | 10:29 am
      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).
    • Aug 25 2006 | 10:39 am
      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).
    • Mar 31 2009 | 1:44 am
      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?
    • Apr 01 2009 | 1:35 am
      Hi John,
      I'm not sure if this is useful info for you, or just rehashing stuff you already know:
      Maybe it helps though... best, Tim
    • Apr 01 2009 | 3:17 am
      I do believe that is EXACTLY what I am looking for. Many thanks.
    • Apr 03 2009 | 1:10 am
      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.