Forums > Dev

enumindex with custom get/set


Feb 08 2011 | 7:30 am

Hi there,

I have declared an attribute as such:

CLASS_ATTR_LONG(c,      	"myattr", 	0, t_myobj, myattr);
CLASS_ATTR_ACCESSORS(c,		"myattr",    	(method)myobj_myattr_get, (method)myobj_myattr_set);
CLASS_ATTR_ENUMINDEX(c,		"myattr",	0, "Left Center Right");
CLASS_ATTR_DEFAULT_SAVE_PAINT(c,"myattr",    	0, "0");

The custom getter and setter:

t_max_err myobj_myattr_get(t_myobj *x, t_object *attr, long *argc, t_atom **argv)
{
    char alloc;

    if (argc && argv) {
	if (atom_alloc(argc, argv, &alloc)) {
            return MAX_ERR_OUT_OF_MEM;
        }
        if (alloc) {
            atom_setlong(*argv, x->myattr);
	}
    }
    return MAX_ERR_NONE;
}

t_max_err myobj_myattr_set(t_myobj *x, t_object *attr, long argc, t_atom *argv)
{
    if (argc && argv) {
        x->myattr = atom_getlong(argv);
    }
    return MAX_ERR_NONE;
}

Pretty straightforward, however I have one problem:
if I understand everything clearly, the CLASS_ATTR_ENUMINDEX macro creates an "enumindex" attribute, which becomes an attribute of the "myattr" attribute.
However it seems I am having problems updating the "enumindex" attribute when I use a custom getter and setter.

In other words, when the user clicks on an inlet of my object and the quickref menu gets displayed, the string portion of "myattr" always says "Left" even though the numeric value associated with "myattr" might change. I also see a ‘bad number’ error in the Max window.

So I am guessing that there must be a way to update the "enumindex" attribute after changing the value of myattr in order for the two to be synced together.
Probably I need to do it manually since I defeat the internal setter and getter. But how ???

Any suggestions ?

Thanks.

– Luigi

Feb 08 2011 | 9:19 am

Unless I didn’t read properly, you shouldn’t need to have a custom gettr, so the following should work.

CLASS_ATTR_ACCESSORS(c,		"myattr",    	(method)NULL, (method)myobj_myattr_set);

In this case it uses the standard gettr method.

Feb 08 2011 | 11:14 am

I know, but I do need a custom getter…
how do I make it work with a custom getter ?

– Luigi

Feb 08 2011 | 4:56 pm

it should be something like this. alloc doesn’t return anything really interesting in this case.


t_max_err myobj_myattr_get(t_myobj *x, t_object *attr, long *argc, t_atom **argv)
{
    char alloc;

    if (argc && argv) {
	if (atom_alloc(argc, argv, &alloc)) {
            return MAX_ERR_GENERIC;
        }
        atom_setlong(*argv, x->myattr);
    }
    return MAX_ERR_NONE;
}

Feb 09 2011 | 2:44 am

yes, that’s what I would think too…

However the above custom getter produces an "enumindex: bad number" error in the Max window and fails to update the symbol portion of the attribute.

Curiously enough, if the same attribute is declared as ENUM (with a symbol datatype) everything works fine.

To better illustrate the problem I wrote a simple UI external with just one attribute defined as ENUMINDEX with custom getter and setter.

If you compile it and then open the help file you will find instructions to reproduce the problem exactly as it appears to me.

Please, let me know what you guys think…

Thanks a lot.

– Luigi

Attachments:
  1. myenum.maxpat
Feb 09 2011 | 9:31 am

tha alloc is true only when atom_alloc allocates the memory. But if ac && av that you pass as argument of the method are non NULL, atom_alloc will not allocate memory and use the already allocated memory instead. What you really want to look at to see if the memory is valid is the return value of atom_alloc, if the t_max_err value returned is MAX_ERR_NONE you’re god to go.

Feb 09 2011 | 11:41 am

Of course…. sorry for my silliness…. it was late at night….
Problem is solved exactly like you guys said.

Emmanuel and Vanille, thank you so much for your help.

– Luigi

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

Forums > Dev