aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/list_accum-help.pd27
-rw-r--r--src/list_accum.c139
2 files changed, 166 insertions, 0 deletions
diff --git a/src/list_accum-help.pd b/src/list_accum-help.pd
new file mode 100644
index 0000000..e7795ba
--- /dev/null
+++ b/src/list_accum-help.pd
@@ -0,0 +1,27 @@
+#N canvas 1298 133 478 349 10;
+#X obj 56 223 tof/list_accum;
+#X msg 77 158 1 2 3 4 5 6;
+#X obj 55 86 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1
+-1;
+#X obj 54 288 print;
+#X floatatom 69 131 5 0 0 0 - - -;
+#X msg 159 158 a b c d;
+#X obj 171 194 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144
+-1 -1;
+#X obj 140 256 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144
+-1 -1;
+#X text 35 36 Tags: lists;
+#X text 36 5 Description: Accumulates incomming atoms into one big
+list;
+#X text 113 135 Inlet 1 \, anything: Accumulate atoms;
+#X text 192 194 Inlet 2 \, bang: Clear accumulated atoms;
+#X text 76 85 Inlet 1 \, bang: Output and clear accumulated atoms;
+#X text 160 254 Outlet 2 \, bang: Nothing accumulated (empty);
+#X text 93 288 Outlet 1 \, list: Accumulated atoms;
+#X connect 0 0 3 0;
+#X connect 0 1 7 0;
+#X connect 1 0 0 0;
+#X connect 2 0 0 0;
+#X connect 4 0 0 0;
+#X connect 5 0 0 0;
+#X connect 6 0 0 1;
diff --git a/src/list_accum.c b/src/list_accum.c
new file mode 100644
index 0000000..48e3e7a
--- /dev/null
+++ b/src/list_accum.c
@@ -0,0 +1,139 @@
+#include "m_pd.h"
+//#include <string.h>
+#define IS_A_SYMBOL(atom,index) ((atom+index)->a_type == A_SYMBOL)
+#define IS_A_FLOAT(atom,index) ((atom+index)->a_type == A_FLOAT)
+
+// The maxsize should match the maximum value of an int (2147483647)
+#define MAXSIZE 2147483647
+//#define MAXSIZE 20
+
+
+
+
+static t_class *list_accum_class;
+
+typedef struct _list_accum {
+ t_object x_obj;
+ int got_data;
+ t_outlet* outlet1;
+ t_outlet* outlet2;
+ int mem_size;
+ int ac;
+ t_atom* av;
+} t_list_accum;
+
+
+
+
+// Bang: output accumulated list
+static void list_accum_bang(t_list_accum *x)
+{
+
+ if ( x->got_data) {
+ x->got_data = 0;
+ outlet_list(x->outlet1,&s_list,x->ac,x->av);
+ } else {
+ outlet_bang(x->outlet2);
+ }
+
+
+}
+
+void list_accum_clear(t_list_accum *x) {
+ x->got_data = 0;
+
+}
+
+
+void list_accum_anything(t_list_accum *x, t_symbol* s, int ac, t_atom* av)
+{
+ // COPY
+
+ if ( !x->got_data ) x->ac =0;
+ x->got_data = 1;
+
+
+ int do_selector = ( s != &s_list && s != &s_float && s != &s_symbol );
+ int ac_prev = x->ac;
+ unsigned int ac_new = x->ac + ac + do_selector; //One more for the selector
+
+
+ if ( ac_new < MAXSIZE ) {
+
+
+ x->ac = ac_new;
+
+ // Resize memory if required and add 10 atoms just in case
+ if(x->ac > x->mem_size) {
+ x->av = resizebytes(x->av, x->mem_size * sizeof(*(x->av)),
+ (10 + x->ac) * sizeof(*(x->av)));
+ x->mem_size = 10 + x->ac;
+ }
+
+ t_atom* dst = x->av + ac_prev; //Offset destination by current size
+
+ // Copy selector
+ if ( do_selector ) {
+ SETSYMBOL(dst, s);
+ dst++;
+ }
+ // Copy atoms
+ while(ac--) *dst++ = *av++;
+
+ } else {
+ pd_error(x, "[list_accum]: Input was ignored because maximum size(%d) would be exceeded.", MAXSIZE);
+ }
+
+}
+
+
+static void list_accum_free(t_list_accum *x)
+{
+ freebytes(x->av, x->mem_size * sizeof(*(x->av)));
+}
+
+void *list_accum_new(t_symbol *s, int argc, t_atom *argv)
+{
+ t_list_accum *x = (t_list_accum *)pd_new(list_accum_class);
+
+ //x->iterating = 0;
+ /*
+ x->mode = 0;
+
+
+ if (argc && IS_A_SYMBOL(argv,0) ) {
+ t_symbol* type = atom_getsymbol(argv);
+ if (type->s_name == gensym("prepend") ) {
+ x->mode = 1;
+ }
+ }
+ */
+
+ // Initialize memory
+ x->mem_size = 10;
+ x->ac = 0;
+ x->av = getbytes(x->mem_size * sizeof(*(x->av)));
+
+ x->outlet1 = outlet_new(&x->x_obj, &s_list);
+ x->outlet2 = outlet_new(&x->x_obj, &s_bang);
+
+
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("bang"), gensym("clear"));
+
+ return (void *)x;
+}
+
+void list_accum_setup(void) {
+ list_accum_class = class_new(gensym("list_accum"),
+ (t_newmethod)list_accum_new,
+ (t_method)list_accum_free, sizeof(t_list_accum),
+ CLASS_DEFAULT,
+ A_GIMME, 0);
+
+ class_addbang (list_accum_class, list_accum_bang);
+ class_addmethod(list_accum_class, (t_method)list_accum_clear, gensym("clear"),0);
+ class_addanything (list_accum_class, list_accum_anything);
+
+ //class_addlist (list_accum_class, list_accum_list);
+
+}