enumindex with custom get/set

Feb 8, 2011 at 7:30am

enumindex with custom get/set

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

#54846
Feb 8, 2011 at 9:19am

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.

#197506
Feb 8, 2011 at 11:14am

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

- Luigi

#197507
Feb 8, 2011 at 4:49pm

Hello Luigi Castelli,

i did something like that ; maybe have a look in the sources of my [november] external ;
sorry don’t have time to make a cleaner example ;-)

HTH

EDIT : oops / not ENUMINDEX in my code but ENUM …

Attachments:
  1. november.c
#197508
Feb 8, 2011 at 4:56pm

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;
}

#197509
Feb 9, 2011 at 2:44am

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
#197510
Feb 9, 2011 at 7:27am

Hello Luigi,

problem comes from if (alloc) statement in you code :

if (alloc) {
atom_setlong(*argv, x->state);
}

as EJ said ;-)

atom_setlong(*argv, x->state);

IMHO, you don’t need to test alloc as if memory have been passed you get zero, but you still need to set the atom passed ; that seems to happen in your method ; so you get bad number error when you query attributes with the inlet popup window …

expert opinion ?

#197511
Feb 9, 2011 at 9:31am

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.

#197512
Feb 9, 2011 at 11:41am

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

#197513

You must be logged in to reply to this topic.