FTS does have a String abstraction which is distinct from symbols. Opcode Max, ISPW Max, and Pd have only symbols. Someday I might work on adding a true string feature to Pd but don't hold your breath... The trouble with symbols is that their storage space is never freed, so you shouldn't go around generating thousands of different symbols.
cheers Miller
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 ---