From c8fdbe3013f1ac6c7e5bca00ec57aff59d8354fd Mon Sep 17 00:00:00 2001 From: Thomas O Fredericks Date: Sat, 24 Oct 2009 20:51:11 +0000 Subject: Added onlyone as a replacement for destroysend svn path=/trunk/externals/tof/; revision=12664 --- help/onlyone-help.pd | 66 ++++++++++++++++++ src/onlyone.c | 188 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/param.h | 17 +---- 3 files changed, 257 insertions(+), 14 deletions(-) create mode 100644 help/onlyone-help.pd create mode 100644 src/onlyone.c diff --git a/help/onlyone-help.pd b/help/onlyone-help.pd new file mode 100644 index 0000000..e76eea4 --- /dev/null +++ b/help/onlyone-help.pd @@ -0,0 +1,66 @@ +#N canvas 1079 120 620 485 10; +#X obj 63 213 loadbang; +#X msg 123 213 set a; +#X msg 165 214 set b; +#X msg 208 215 set; +#X obj 280 215 loadbang; +#X msg 340 215 set a; +#X msg 383 217 set b; +#X msg 425 217 set; +#X msg 297 306 1; +#X msg 370 303 0; +#X msg 66 299 1; +#X msg 139 296 0; +#X obj 67 274 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 +-1; +#X obj 138 271 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 +-1 -1; +#X obj 296 280 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 +-1 -1; +#X obj 367 278 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 +-1 -1; +#X obj 62 244 tof/onlyone a; +#X obj 294 251 tof/onlyone b; +#X obj 39 33 cnv 15 400 100 empty empty empty 20 12 0 14 -249661 -66577 +0; +#X text 44 84 author: mrtoftrash@gmail.com; +#X text 44 64 tags: initialization control; +#X text 44 105 version: 2009-10-24; +#X text 44 33 description: makes sure it is the first or only [onlyone] +to use that name.; +#X text 77 399 Outlet 1: bangs if it is the first or only one to use +that name.; +#X text 79 431 Outlet 2: bangs if it not the the first and not the +only one to use that name.; +#X text 62 139 Try to "set" the name of each [onlyone] to the same +name and than to different names.; +#X obj 82 358 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 +-1; +#X obj 81 329 metro 500; +#X obj 330 340 metro 500; +#X obj 336 368 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 +-1 -1; +#X text 65 171 If both [onlyone] have the same name \, only one metro +will be active.; +#X connect 0 0 16 0; +#X connect 1 0 16 0; +#X connect 2 0 16 0; +#X connect 3 0 16 0; +#X connect 4 0 17 0; +#X connect 5 0 17 0; +#X connect 6 0 17 0; +#X connect 7 0 17 0; +#X connect 8 0 28 0; +#X connect 9 0 28 0; +#X connect 10 0 27 0; +#X connect 11 0 27 0; +#X connect 12 0 10 0; +#X connect 13 0 11 0; +#X connect 14 0 8 0; +#X connect 15 0 9 0; +#X connect 16 0 12 0; +#X connect 16 1 13 0; +#X connect 17 0 14 0; +#X connect 17 1 15 0; +#X connect 27 0 26 0; +#X connect 28 0 29 0; diff --git a/src/onlyone.c b/src/onlyone.c new file mode 100644 index 0000000..60287b0 --- /dev/null +++ b/src/onlyone.c @@ -0,0 +1,188 @@ + +#include "m_pd.h" + +struct _onlyone; + +typedef struct _oo { + struct _onlyone* x; + //t_symbol* name; + struct _oo* next; + struct _oo* previous; +} t_oo; + +static t_oo* oos = NULL; + +static t_class *onlyone_class; + +typedef struct _onlyone { + t_object x_obj; + t_outlet* outlet; + t_outlet* outlet2; + t_symbol* name; + int iamtheone; + t_symbol* s_empty; + //t_sample f_common; + //t_common* pg; + //t_sample f; +} t_onlyone; + + +static void onlyone_bang( t_onlyone *x) { + if (x->iamtheone) { + outlet_bang(x->outlet); + } else { + outlet_bang(x->outlet2); + } +} + + +static void onlyone_register(t_onlyone* x) { + + + t_oo* oo = oos; + + int outputme = 1; + + + t_oo* new_oo = getbytes(sizeof(*new_oo)); + new_oo->x = x; + + if ( oo != NULL) { + //post("oo is not null"); + if (outputme && (oo->x->name == x->name)) outputme = 0; + // Get the last oo + while (oo->next) { + oo = oo->next; + } + } + + // Append + + new_oo->previous = oo; + new_oo->next = NULL; + if (oo != NULL) { + oo->next = new_oo; + } else { + //post("Adding the first"); + oos = new_oo; + } + + x->iamtheone = outputme; + +} + + +static void onlyone_unregister(t_onlyone* x) { + + t_oo* oo = oos; + + t_onlyone* theotherone = NULL; + t_oo* deleteone = NULL; + + if ( oo != NULL) { + // Get the mathching oo and the x to output to + while ( oo ) { + if ( oo->x == x ) { + //post("Found oo to delete"); + deleteone = oo; + } else if (x->iamtheone && theotherone==NULL && (oo->x->name == x->name) ) { + theotherone = oo->x; + } + if ( deleteone && theotherone) break; + oo = oo->next; + } + + + + // Delete the oo matching the x that called this function + if (deleteone) { + + if (deleteone->previous) { + deleteone->previous->next = deleteone->next; + if (deleteone->next) deleteone->next->previous = deleteone->previous; + + } else { + oos = deleteone->next; + if ( deleteone->next != NULL) deleteone->next->previous = NULL; + } + + freebytes(deleteone,sizeof(*deleteone)); + x->iamtheone = 0; + x->name = NULL; + } else { + post("Hum, did not find oo to delete!"); + } + + // Output the bang to the other one + if (theotherone) { + theotherone->iamtheone = 1; + onlyone_bang(theotherone); + } + + } else { + post("Weird, the list is empty..."); + } + + // if (oos==NULL) post("this is the end"); + +} + + +static void onlyone_free( t_onlyone *x) { + + if ( x->name) onlyone_unregister(x); +} + +static void onlyone_set( t_onlyone *x, t_symbol *s) { + if ( s == x->s_empty) { + if ( x->name) { + onlyone_unregister(x); + //onlyone_bang(x); + } + } else if ( x->name && s != x->name) { + onlyone_unregister(x); + x->name = s; + onlyone_register(x); + //onlyone_bang(x); + } else if ( x->name == NULL) { + x->name = s; + onlyone_register(x); + //onlyone_bang(x); + } + onlyone_bang(x); +} + + + + +static void *onlyone_new(t_symbol* s) +{ + t_onlyone *x = (t_onlyone *)pd_new(onlyone_class); + + x->s_empty = gensym(""); + x->iamtheone = 0; + x->name = NULL; + + if ( s != x->s_empty) x->name = s; + + x->outlet = outlet_new(&x->x_obj, &s_bang); + + if ( x->name) onlyone_register(x); + + + x->outlet2 = outlet_new(&x->x_obj, &s_bang); + + return (void *)x; +} + +void onlyone_setup(void) { + onlyone_class = class_new(gensym("onlyone"), + (t_newmethod)onlyone_new, + (t_method)onlyone_free, sizeof(t_onlyone), + 0, A_DEFSYMBOL, 0); + + class_addbang(onlyone_class, onlyone_bang); + + class_addmethod(onlyone_class, (t_method)onlyone_set, gensym("set"),A_DEFSYMBOL,0); + +} diff --git a/src/param.h b/src/param.h index dfe8588..1c0b3a5 100644 --- a/src/param.h +++ b/src/param.h @@ -308,28 +308,17 @@ static void param_unregister(t_param* p) { if ( paramlist) { - //p->users = p->users - 1; - //if ( p->users == 0 ) { - // Remove param - //post("Removing last param of this name"); + if (p->previous) { p->previous->next = p->next; if (p->next) p->next->previous = p->previous; - /* - if (p->next == NULL) { - p->previous->next = NULL; - } else { - p->previous->next = p->next; - } - */ + } else { paramlist = p->next; if ( p->next != NULL) p->next->previous = NULL; } - //freebytes(p->av, p->alloc * sizeof *(p->av) ); - //freebytes(p->av_g, p->ac_g * sizeof *(p->av_g) ); + freebytes(p, sizeof *p); - //} // Update the params for that root if (paramlist == NULL) { -- cgit v1.2.1