From 158905493c8371724641de3dd20e86637378a0ec Mon Sep 17 00:00:00 2001 From: Ivica Ico Bukvic <ico@vt.edu> Date: Sat, 3 Aug 2013 21:49:44 -0400 Subject: [PATCH] added [list cat] object --- pd/src/x_list.c | 125 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 124 insertions(+), 1 deletion(-) diff --git a/pd/src/x_list.c b/pd/src/x_list.c index 9f9c739f3..3142b381b 100644 --- a/pd/src/x_list.c +++ b/pd/src/x_list.c @@ -27,6 +27,7 @@ extern t_pd *newest; list split - first n elements to first outlet, rest to second outlet list trim - trim off "list" selector list length - output number of items in list + list cat - build a list by accumulating elements Need to think more about: list foreach - spit out elements of a list one by one (also in reverse?) @@ -34,7 +35,6 @@ Need to think more about: list reverse - permute elements of a list back to front list pack - synonym for 'pack' list unpack - synonym for 'unpack' - list cat - build a list by accumulating elements Probably don't need: list first - output first n elements. @@ -247,6 +247,124 @@ static void list_append_setup(void) class_sethelpsymbol(list_append_class, &s_list); } +/* ------------- list cat --------------------- */ + +t_class *list_cat_class; +t_class *list_cat_proxy_class; + +typedef struct _list_cat_proxy +{ + t_pd l_pd; + void *parent; +} t_list_cat_proxy; + +typedef struct _list_cat +{ + t_object x_obj; + t_alist x_alist; + t_list_cat_proxy x_pxy; +} t_list_cat; + +static void list_cat_clear(t_list_cat *x); + +static void list_cat_proxy_init(t_list_cat_proxy *x, t_list_cat *p) +{ + x->l_pd = list_cat_proxy_class; + x->parent = (void *)p; +} + +static void list_cat_proxy_clear(t_list_cat_proxy *x) +{ + t_list_cat *p = (t_list_cat *)x->parent; + list_cat_clear(p); +} + +static void *list_cat_new( void) +{ + t_list_cat *x = (t_list_cat *)pd_new(list_cat_class); + alist_init(&x->x_alist); + outlet_new(&x->x_obj, &s_list); + list_cat_proxy_init(&x->x_pxy, x); + inlet_new(&x->x_obj, &x->x_pxy.l_pd, 0, 0); + return (x); +} + +static void list_cat_list(t_list_cat *x, t_symbol *s, + int argc, t_atom *argv) +{ + t_atom *outv; + int n, outc = x->x_alist.l_n + argc; + XL_ATOMS_ALLOCA(outv, outc); + atoms_copy(argc, argv, outv + x->x_alist.l_n); + if (x->x_alist.l_npointer) + { + t_alist y; + alist_clone(&x->x_alist, &y); + alist_toatoms(&y, outv); + outlet_list(x->x_obj.ob_outlet, &s_list, outc, outv); + alist_clear(&y); + } + else + { + alist_toatoms(&x->x_alist, outv); + outlet_list(x->x_obj.ob_outlet, &s_list, outc, outv); + } + alist_list(&x->x_alist, s, outc, outv); + XL_ATOMS_FREEA(outv, outc); +} + +static void list_cat_anything(t_list_cat *x, t_symbol *s, + int argc, t_atom *argv) +{ + t_atom *outv; + int n, outc = x->x_alist.l_n + argc + 1; + XL_ATOMS_ALLOCA(outv, outc); + SETSYMBOL(outv + x->x_alist.l_n, s); + atoms_copy(argc, argv, outv + x->x_alist.l_n + 1); + if (x->x_alist.l_npointer) + { + t_alist y; + alist_clone(&x->x_alist, &y); + alist_toatoms(&y, outv); + outlet_list(x->x_obj.ob_outlet, &s_list, outc, outv); + alist_clear(&y); + } + else + { + alist_toatoms(&x->x_alist, outv); + outlet_list(x->x_obj.ob_outlet, &s_list, outc, outv); + } + if (x->x_alist.l_n <= 1) + alist_anything(&x->x_alist, s, outc, outv); + else + alist_list(&x->x_alist, s, outc, outv); + XL_ATOMS_FREEA(outv, outc); +} + +static void list_cat_clear(t_list_cat *x) +{ + alist_clear(&x->x_alist); +} + +static void list_cat_free(t_list_cat *x) +{ + alist_clear(&x->x_alist); +} + +static void list_cat_setup(void) +{ + list_cat_class = class_new(gensym("list cat"), + (t_newmethod)list_cat_new, (t_method)list_cat_free, + sizeof(t_list_cat), 0, 0); + class_addlist(list_cat_class, list_cat_list); + class_addanything(list_cat_class, list_cat_anything); + class_sethelpsymbol(list_cat_class, &s_list); + + list_cat_proxy_class = class_new(gensym("list cat pxy"), 0, 0, + sizeof(t_list_cat_proxy), 0, 0); + class_addmethod(list_cat_proxy_class, (t_method)list_cat_proxy_clear, gensym("clear"), 0); +} + /* ------------- list prepend --------------------- */ t_class *list_prepend_class; @@ -329,6 +447,8 @@ static void list_prepend_setup(void) class_addlist(list_prepend_class, list_prepend_list); class_addanything(list_prepend_class, list_prepend_anything); class_sethelpsymbol(list_prepend_class, &s_list); + + } /* ------------- list split --------------------- */ @@ -480,6 +600,8 @@ static void *list_new(t_pd *dummy, t_symbol *s, int argc, t_atom *argv) t_symbol *s2 = argv[0].a_w.w_symbol; if (s2 == gensym("append")) newest = list_append_new(s, argc-1, argv+1); + else if (s2 == gensym("cat")) + newest = list_cat_new(); else if (s2 == gensym("prepend")) newest = list_prepend_new(s, argc-1, argv+1); else if (s2 == gensym("split")) @@ -501,6 +623,7 @@ void x_list_setup(void) { alist_setup(); list_append_setup(); + list_cat_setup(); list_prepend_setup(); list_split_setup(); list_trim_setup(); -- GitLab