From 17ec1deb74e2e934dc11fb4d9a2f8c6cef34c5a7 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Mon, 9 Jul 2007 20:45:58 +0000 Subject: This commit was generated by cvs2svn to compensate for changes in r7949, which included commits to RCS files with non-trunk default branches. svn path=/trunk/externals/moonlib/; revision=7950 --- slist.c | 233 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 233 insertions(+) create mode 100644 slist.c (limited to 'slist.c') diff --git a/slist.c b/slist.c new file mode 100644 index 0000000..6af28c6 --- /dev/null +++ b/slist.c @@ -0,0 +1,233 @@ +/* +Copyright (C) 2003 Antoine Rousseau + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +/* a shared symbol list, ala "value" .*/ + +#include +#include +#include + +static t_class *slist_class, *scommon_class; + +typedef struct _sitem t_sitem; + +struct _sitem +{ + t_sitem *next; + t_symbol *s; +}; + +typedef struct scommon +{ + t_pd c_pd; + t_symbol *c_sym; + int c_refcount; + t_sitem *first; +} t_scommon; + +typedef struct _slist +{ + t_object x_obj; + t_symbol *x_sym; + t_scommon *x_c; + t_outlet *x_symout; + t_outlet *x_lenout; +} t_slist; + + +static void sitem_delete(t_sitem **x) +{ + t_sitem *next=(*x)->next; + + //freebytes((*x)->name,strlen((*x)->name)+1); + freebytes(*x,sizeof(t_sitem)); + (*x)=next; +} + +static void sitem_add(t_sitem **x,t_symbol *s) +{ + t_int l; + t_sitem *newone=getbytes(sizeof(t_sitem)); + + //newone->name=getbytes(l=(strlen(s->s_name)+1)); + //strncpy(newone->name,s->s_name,l); + newone->s=s; + newone->next=0; + + while(*x) x=&((*x)->next); + + *x=newone; +} + +static void *scommon_new(t_symbol *s) +{ + t_scommon *x = (t_scommon *)pd_new(scommon_class); + + x->c_refcount = 0; + x->c_sym=s; + pd_bind((t_pd*)x, s); + + x->first=0; + + return (x); +} + +static int scommon_find(t_scommon *x, t_symbol *s) +{ + t_sitem *si=x->first; + t_int i=1; + + while(si) { + if(!strcmp(si->s->s_name,s->s_name)) return i; + si=si->next; + i++; + } + return 0; +} + +static void scommon_add(t_scommon *x, t_symbol *s) +{ + sitem_add(&x->first,s); +} + +static void scommon_reset(t_scommon *x) +{ + while(x->first) sitem_delete(&x->first); +} + +static void scommon_ff(t_scommon *x) +{ + scommon_reset(x); + pd_unbind((t_pd*)x, x->c_sym); +} + + + /* get a pointer to a named symbol list (a "scommon" object), + which is created if necessary. */ +t_scommon *slist_get(t_symbol *s) +{ + t_scommon *c = (t_scommon *)pd_findbyclass(s, scommon_class); + + if (!c) c = (t_scommon *)scommon_new(s); + c->c_refcount++; + return (c); +} + + /* release a variable. This only frees the "scommon" resource when the + last interested party releases it. */ +void slist_release(t_scommon *c) +{ + if (!--c->c_refcount) scommon_ff(c); +} + + +static void *slist_new(t_symbol *s) +{ + t_slist *x = (t_slist *)pd_new(slist_class); + x->x_sym = s; + x->x_c = slist_get(s); + outlet_new(&x->x_obj, &s_float); + x->x_symout=outlet_new(&x->x_obj, &s_symbol); + x->x_lenout=outlet_new(&x->x_obj, &s_float); + return (x); +} + +static void slist_ff(t_slist *x) +{ + slist_release(x->x_c); +} + +static void slist_print(t_slist *x) +{ + t_sitem *t=x->x_c->first; + int i=0; + + while(t){ + post("item %d: %s",++i,t->s->s_name); + t=t->next; + } +} + +static void slist_reset(t_slist *x) +{ + scommon_reset(x->x_c); +} + +static void slist_add(t_slist *x,t_symbol *s) +{ + scommon_add(x->x_c,s); +} + +static void slist_find(t_slist *x,t_symbol *s) +{ + outlet_float(x->x_obj.ob_outlet,scommon_find(x->x_c,s)); +} + +static void slist_setlist(t_slist *x,t_symbol *s) +{ + slist_release(x->x_c); + x->x_c = slist_get(s); +} + +static void slist_float(t_slist *x, t_float f) +{ + t_sitem *t=x->x_c->first; + int i=0; + + if(!f) return; + + while(t&&((++i)!=f)){ + t=t->next; + } + + if(t) outlet_symbol(x->x_symout,t->s); +} + +static void slist_len(t_slist *x) +{ + t_sitem *t=x->x_c->first; + int i=0; + + while(t){ + t=t->next; + i++; + } + + outlet_float(x->x_lenout,i); +} + + +void slist_setup(void) +{ + slist_class = class_new(gensym("slist"), (t_newmethod)slist_new, + (t_method)slist_ff, + sizeof(t_slist), 0, A_DEFSYM, 0); + + //class_addbang(slist_class, slist_bang); + class_addfloat(slist_class, slist_float); + class_addmethod(slist_class,(t_method)slist_add, gensym("add"),A_SYMBOL,0); + class_addmethod(slist_class,(t_method)slist_find, gensym("find"),A_SYMBOL,0); + class_addmethod(slist_class,(t_method)slist_setlist, gensym("setlist"),A_SYMBOL,0); + class_addmethod(slist_class,(t_method)slist_reset, gensym("reset"),0); + class_addmethod(slist_class,(t_method)slist_print, gensym("print"),0); + class_addmethod(slist_class,(t_method)slist_len, gensym("len"),0); + scommon_class = class_new(gensym("slist"), 0, 0, + sizeof(t_scommon), CLASS_PD, 0); +} + -- cgit v1.2.1