I hope I am not too annoyingly, ..., but writing route I encountered some problems:
feature of my route:
- routing first number of lists: output rest of list
- routing numbers, output bang on matched numbers
- routing strings (which are in fact symbols),
with bang and list output
- mixing routing strings and numbers
(which does not work in max)
solution:
- adding methods for each string
(class_addmethod(route_class,route_symbol,
es->e_atom.a_w.w_symbol,A_GIMME,0);
- adding class_addanything(...) for not parsed strings,messages
problem:
if a a string is for example "int", a used symbol, than route_symbol(...) seg_faults, because pd_float is used for calling route_symbol(..) with wrong arguments, because the route_symbol(...) is registered as c_floatmethod.
So the string "int" or "float" matches all numbers. Lists, which in fact are lists beginning with numbers not strings, are handled correctly. Lists with beginning strings are handled as methods --- is this correct ?
So the my idea of route (to be compatible in future with real route) could be that "float", "int" routes all integers and floats, which are not in a list,
(route should be fast, since, in my experience with max, it is often used for sending synthesis parameters and has to handle high data-rates)
mfg winfried.
PS.:my route as source: ---- snip --- /* -------------------------- route ------------------------------ */ static t_class *route_class;
typedef struct _routeelement { t_atom e_atom; t_outlet *e_outlet; } t_routeelement;
typedef struct _route { t_object x_obj; t_int x_nelement; t_routeelement *x_vec; t_int x_nsymbols; t_routeelement *x_vecsymbols; t_outlet *x_rejectout; } t_route;
static void route_list(t_route *x, t_symbol *sel, int argc, t_atom *argv) { t_routeelement *e; int nelement, n; union word a_w;
if (!argc) return;
a_w = argv->a_w;
for (nelement = x->x_nelement, e = x->x_vec; nelement--; e++){
/* dont know how excatly to compare atomes since
strncmp is slow for a 8Byte long,
and i am not sure all types ar the same length (w_int, w_float,...)
so I have to test on atom type */
switch(argv->a_type){
case A_FLOAT:
if(e->e_atom.a_type == A_FLOAT && e->e_atom.a_w.w_float == a_w.w_float)
{
if(argc <= 1) outlet_bang(e->e_outlet);
else outlet_list(e->e_outlet, 0, argc-1, argv+1);
return;
}
break;
case A_INT :
if(e->e_atom.a_type == A_INT && e->e_atom.a_w.w_int == a_w.w_int)
{
if(argc <= 1) outlet_bang(e->e_outlet);
else outlet_list(e->e_outlet, 0, argc-1, argv+1);
return;
}
break;
}
}; outlet_list(x->x_rejectout, sel, argc, argv); return; }
static void route_symbol(t_route *x, t_symbol *sel, int argc, t_atom *argv) { t_routeelement *e; int nelement;
for (nelement = x->x_nsymbols, e = x->x_vecsymbols; nelement--; e++) if(/* e->e_atom.a_type == A_SYMBOL &&*/ e->e_atom.a_w.w_symbol == sel){
if(argc<=0) outlet_bang(e->e_outlet);
else outlet_list(e->e_outlet, 0, argc, argv);
return;
}
/* never reach this, but... */ outlet_anything(x->x_rejectout, sel, argc, argv); return; }
static void route_anything(t_route *x, t_symbol *sel, int argc, t_atom *argv) { outlet_anything(x->x_rejectout, sel, argc, argv); return; }
static void route_free(t_route *x) { freebytes(x->x_vec, x->x_nelement * sizeof(*x->x_vec)); }
static void *route_new(t_symbol *s, int argc, t_atom *argv) { int n; t_routeelement *ee, *es; t_route *x = (t_route *)pd_new(route_class);
x->x_nelement = x->x_nsymbols = 0; /* count from top */ x->x_vec = (t_routeelement *)getbytes(argc * sizeof(*x->x_vec)); x->x_rejectout = outlet_new(&x->x_obj, &s_list);
for (n = argc, ee = x->x_vec, es=x->x_vec+argc; n--;){
if(argv[n].a_type == A_SYMBOL){
es--;x->x_nsymbols++; /* count from top */
es->e_outlet = outlet_new(&x->x_obj, &s_list);
es->e_atom.a_type = argv[n].a_type;
es->e_atom.a_w = argv[n].a_w;
post("new_symbol: new symbol at %lx name %s",
argv[n].a_w.w_symbol,argv[n].a_w.w_symbol->s_name);
class_addmethod(route_class,route_symbol,
es->e_atom.a_w.w_symbol,A_GIMME,0);
}
else{ /* element */
ee->e_outlet = outlet_new(&x->x_obj, &s_list);
ee->e_atom.a_type = argv[n].a_type;
ee->e_atom.a_w = argv[n].a_w;
ee++;x->x_nelement++;/* count from bottom */
}
};
x->x_vecsymbols = es;
return (x); }
void route_setup(void) { route_class = class_new(gensym("route"), route_new, route_free, sizeof(t_route), 0, A_GIMME, 0);
class_addlist(route_class, route_list);
/* symbols which are not matched and so no messages */
class_addanything(route_class, route_anything);
} ---- snip ---