/****************************************************** * * zexy - implementation file * * copyleft (c) IOhannes m zmölnig * * 1999:forum::für::umläute:2009 * * institute of electronic music and acoustics (iem) * ****************************************************** * * license: GNU General Public License v.2 * ******************************************************/ /* */ #include "zexy.h" /* -------------------------- multireceive ------------------------------ */ static t_class *multireceive_class=NULL; static t_class *multireceive_proxy_class=NULL; typedef struct _symlist { t_symbol*s; struct _symlist*next; } t_symlist; typedef struct _multireceive_proxy { t_object x_obj; struct _multireceive*x_parent; } t_multireceive_proxy; typedef struct _multireceive { t_object x_obj; t_multireceive_proxy*x_proxy; t_symlist*x_symlist; t_outlet *x_out; } t_multireceive; static void multireceive_any(t_multireceive_proxy *x, t_symbol*s, int argc, t_atom*argv) { outlet_anything(x->x_parent->x_out, s, argc, argv); } static void multireceive_add(t_multireceive *x, t_symbol*s) { t_symlist*sl=x->x_symlist; t_symlist*element=NULL; if(sl) { while(sl->next) { if(s==sl->s) { // already bound to this symbol return; } sl=sl->next; } } element=(t_symlist*)getbytes(sizeof(t_symlist)); element->s=s; element->next=NULL; pd_bind(&x->x_proxy->x_obj.ob_pd, s); if(sl) { sl->next=element; } else { x->x_symlist=element; } } static void multireceive_clear(t_multireceive *x) { t_symlist*sl=x->x_symlist; t_symlist*current=NULL; while(sl) { current=sl; sl=sl->next; pd_unbind(&x->x_proxy->x_obj.ob_pd, current->s); current->s=NULL; current->next=NULL; freebytes(current, sizeof(t_symlist)); } x->x_symlist=NULL; } static void multireceive_set(t_multireceive *x, t_symbol*s, int argc, t_atom*argv) { multireceive_clear(x); while(argc-->0) { t_symbol*s=atom_getsymbol(argv); if(A_SYMBOL==argv->a_type) { multireceive_add(x, s); } else { verbose(1, "[multireceive]: ignoring non-symbol receive name"); } argv++; } } static void multireceive_free(t_multireceive *x) { multireceive_clear(x); pd_free((t_pd *)x->x_proxy); outlet_free(x->x_out); x->x_out=NULL; } static void *multireceive_new(t_symbol *s, int argc, t_atom *argv) { t_multireceive *x = (t_multireceive *)pd_new(multireceive_class); x->x_proxy=(t_multireceive_proxy*)pd_new(multireceive_proxy_class); x->x_proxy->x_parent=x; x->x_symlist=NULL; x->x_out = outlet_new(&x->x_obj, 0); multireceive_set(x, 0, argc, argv); return (x); } void multireceive_setup(void) { multireceive_class = class_new(gensym("multireceive"), (t_newmethod)multireceive_new, (t_method)multireceive_free, sizeof(t_multireceive), 0, A_GIMME, 0); class_addmethod(multireceive_class, (t_method)multireceive_set, gensym("set"), A_GIMME, 0); class_addmethod(multireceive_class, (t_method)multireceive_add, gensym("add"), A_SYMBOL, 0); multireceive_proxy_class = class_new(gensym("multireceive proxy"), 0, 0, sizeof(t_multireceive_proxy), CLASS_PD | CLASS_NOINLET, 0); class_addanything(multireceive_proxy_class, multireceive_any); zexy_register("multireceive"); }