Request: jbox_get_arguments or such

johnpitcairn's icon

This is how we're currently getting the arguments for a (non-bpatcher) patcher:

if(buf = (t_atombuf *)((t_jbox *)box)->b_binbuf) {
if(buf->a_argc) args = atomarray_new(buf->a_argc, buf->a_argv);
}

I don't much like that direct access to t_jbox struct members - can we perhaps have an official convenience method to avoid being dependent on t_jbox implementation details? Would be nice if it worked for bpatchers too, thanks.

Joshua Kit Clayton's icon

Patchers have an arguments attribute which you can use.

andrea agostini's icon

it's definitely there! but I can't read it... I tried to cast it to everything I could imagine it, but I had no luck...

merry xmas to everyone
aa

johnpitcairn's icon

+1. Joshua, you mean something like:

object_attr_getvalueof(box, gensym("args"), &argc, &argv);

This only works for bpatchers. I've also been using direct access access to jbox struct members for patchers.

Joshua Kit Clayton's icon

Hmmm. perhaps you are looking at the box and not the patcher itself. Something like the following might be of assistance (web browser coding, so apologies for any typos):

t_atom *av=NULL;
long ac = 0;
t_object *patcher=NULL;

object_obex_lookup((t_object *)x,gensym("#P"),&patcher);
if (patcher) {
    object_attr_getvalueof(patcher,gensym("arguments"),&ac,&av);
    if (ac&&av) {
        // do something with ac/av
        sysmem_freeptr(av);
    }
}

However, here's what patcherargs does (post patcher loadbang):

box = object_attr_getobj(x->parent, _sym_box); // x->parent is the parent patcher
if (!box)
    object_method(x->parent, _sym_getassoc, &box);    // this how we get a poly~ (as opposed to bpatcher or patcher)
box_classname = object_classname(box);

if(box_classname == gensym("bpatcher") || box_classname == gensym("poly~")) {
    object_attr_getvalueof(box, gensym("args"), &size, &pargv);
    argv = pargv; // save real pointer since newobj case increments argv -jkc
} else if(box_classname == gensym("newobj")){
    textfield = object_attr_getobj(box, gensym("textfield"));            // bpatcher -- textfield is null
    object_method(textfield, gensym("gettextptr"), &text, &textlen);
    atom_setparse(&size, &pargv, text);
    argv = pargv; // save real pointer since newobj case increments argv -jkc
    argv++;
    size--;
}

Hope this helps. Sorry I don't have time to test all this in various cases or get into further detail.

Happy holidays!

-Joshua

andrea agostini's icon

Thank you very much, this is perfect!

Just one question, to avoid future trouble: I must free the atoms I get from object_attr_getvalueof, right? (I guess this is why you save the real argv pointer...)

best
aa

Joshua Kit Clayton's icon

Yes. Same for atom_setparse().

These functions let you pass in memory if you don't want the function to allocate memory, but it is actually rarely done.

-Joshua