diff options
author | Thomas O Fredericks <mrtof@users.sourceforge.net> | 2009-10-24 20:51:11 +0000 |
---|---|---|
committer | Thomas O Fredericks <mrtof@users.sourceforge.net> | 2009-10-24 20:51:11 +0000 |
commit | c8fdbe3013f1ac6c7e5bca00ec57aff59d8354fd (patch) | |
tree | 53813bb68e0584da4afb8710c8478b75cbc2955a /src | |
parent | 7a8bdf66f6138b5e320732751a158a926dfcebb6 (diff) |
Added onlyone as a replacement for destroysend
svn path=/trunk/externals/tof/; revision=12664
Diffstat (limited to 'src')
-rw-r--r-- | src/onlyone.c | 188 | ||||
-rw-r--r-- | src/param.h | 17 |
2 files changed, 191 insertions, 14 deletions
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) { |