aboutsummaryrefslogtreecommitdiff
path: root/src/listUnfold.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/listUnfold.c')
-rw-r--r--src/listUnfold.c126
1 files changed, 95 insertions, 31 deletions
diff --git a/src/listUnfold.c b/src/listUnfold.c
index 579f645..60f5ec4 100644
--- a/src/listUnfold.c
+++ b/src/listUnfold.c
@@ -1,61 +1,114 @@
#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)
+/* Mode 0: unfold all the list till its end or when banged.
+ * Mode 1: unfold each element of the list at each bang.
+ * Mode 0 is by default. Mode 1 is activated when listUnfold is
+ * created with "wait" or "manually" as only argument.
+ */
static t_class *listUnfold_class;
typedef struct _listUnfold {
- t_object x_obj;
-
- //t_float start;
- //t_float step;
- t_int iterating;
- t_outlet* outlet1;
- t_outlet* outlet2;
+ t_object x_obj;
+ t_int iterating;
+ t_outlet* outlet1;
+ t_outlet* outlet2;
+ t_int mode;
+ int memSize;
+ int ac;
+ t_atom* av;
} t_listUnfold;
+
+
+
void listUnfold_bang(t_listUnfold *x)
{
//x->i_count = x->i_down;
- x->iterating = 0;
+ if ( x->mode == 0) {
+ x->iterating = 0;
+ } else {
+ if ( x->iterating < x->ac ) {
+ outlet_float(x->outlet2,x->iterating);
+ if ( IS_A_FLOAT(x->av,x->iterating) ) {
+ outlet_float(x->outlet1,atom_getfloat(x->av + x->iterating));
+ } else {
+ outlet_symbol(x->outlet1,atom_getsymbol(x->av + x->iterating));
+ }
+ x->iterating++;
+ }
+ }
}
void listUnfold_anything(t_listUnfold *x, t_symbol* s, int ac, t_atom* av)
{
- int i = 0;
- int count = 0;
- x->iterating = 1;
-
- if ( s != &s_list && s != &s_float && s != &s_symbol ) {
- outlet_float(x->outlet2,0);
- outlet_symbol(x->outlet1,s);
- count++;
- }
- for ( ; i < ac; i++ ) {
- if ( !(x->iterating) ) break;
- outlet_float(x->outlet2,count);
- count++;
- if ( IS_A_FLOAT(av,i) ) {
- outlet_float(x->outlet1,atom_getfloat(av+i));
- } else {
- outlet_symbol(x->outlet1,atom_getsymbol(av+i));
+
+
+ if ( x->mode == 0) {
+
+ // Output all
+
+ int i =0;
+ int offset =0;
+ x->iterating = 1;
+
+ if ( s != &s_list && s != &s_float && s != &s_symbol ) {
+ outlet_float(x->outlet2,0);
+ outlet_symbol(x->outlet1,s);
+ offset=1;
+ }
+
+ for ( ; i < ac && x->iterating; i++ ) {
+ outlet_float(x->outlet2,i+offset);
+ if ( IS_A_FLOAT(av,0) ) {
+ outlet_float(x->outlet1,atom_getfloat(av));
+ } else {
+ outlet_symbol(x->outlet1,atom_getsymbol(av));
+ }
+ av++;
}
+ } else {
+
+ x->iterating = 0;
+
+ // Copy and wait for bangs to output
+
+
+ int do_selector = ( s != &s_list && s != &s_float && s != &s_symbol );
+ x->ac = ac + do_selector; //One more for the selector
+
+ // Resize memory if required and add 3 atoms just in case
+ if(x->ac > x->memSize) {
+ x->av = resizebytes(x->av, x->memSize * sizeof(*(x->av)),
+ (3 + x->ac) * sizeof(*(x->av)));
+ x->memSize = 3 + x->ac;
+ }
+ t_atom* dst = x->av;
+
+ // Copy selector
+ if ( do_selector ) {
+ SETSYMBOL(dst, s);
+ dst++;
+ }
+ // Copy atoms
+ while(ac--) *dst++ = *av++;
- }
+ }
}
static void listUnfold_free(t_listUnfold *x)
{
-
-
+ freebytes(x->av, x->memSize * sizeof(*(x->av)));
}
void *listUnfold_new(t_symbol *s, int argc, t_atom *argv)
@@ -64,9 +117,20 @@ void *listUnfold_new(t_symbol *s, int argc, t_atom *argv)
x->iterating = 0;
-
- //floatinlet_new(&x->x_obj, &x->start);
- //floatinlet_new(&x->x_obj, &x->step);
+ x->mode = 0;
+
+ if (argc && IS_A_SYMBOL(argv,0) ) {
+ t_symbol* type = atom_getsymbol(argv);
+ if (strcmp(type->s_name,"wait")==0 || strcmp(type->s_name,"manually")==0) {
+ x->mode = 1;
+ }
+ }
+
+ // Initialize memory
+ x->memSize = 10;
+ x->ac = 0;
+ x->av = getbytes(x->memSize * sizeof(*(x->av)));
+
x->outlet1 = outlet_new(&x->x_obj, &s_list);
x->outlet2 = outlet_new(&x->x_obj, &s_float);