aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cyclone/hammer/Table.c149
-rw-r--r--shared/common/port.c25
2 files changed, 141 insertions, 33 deletions
diff --git a/cyclone/hammer/Table.c b/cyclone/hammer/Table.c
index eb30d28..da19b9f 100644
--- a/cyclone/hammer/Table.c
+++ b/cyclone/hammer/Table.c
@@ -48,6 +48,9 @@ typedef struct _tablecommon
int *c_table;
int c_tableini[TABLE_INISIZE];
int c_cacheisfresh;
+ int c_cachesum;
+ int c_cachemin;
+ int c_cachemax;
int *c_cache;
int c_cacheini[TABLE_INISIZE];
t_symbol *c_filename;
@@ -77,6 +80,7 @@ static t_class *tablecommon_class;
static void tablecommon_modified(t_tablecommon *cc, int relocated)
{
+ cc->c_cacheisfresh = 0;
if (cc->c_increation)
return;
if (relocated)
@@ -94,23 +98,23 @@ static void tablecommon_modified(t_tablecommon *cc, int relocated)
static int tablecommon_getindex(t_tablecommon *cc, int ndx)
{
- int mx = cc->c_length - 1;
+ int nmx = cc->c_length - 1;
/* CHECKED ndx silently clipped */
- return (ndx < 0 ? 0 : (ndx > mx ? mx : ndx));
+ return (ndx < 0 ? 0 : (ndx > nmx ? nmx : ndx));
}
static int tablecommon_getvalue(t_tablecommon *cc, int ndx)
{
- int mx = cc->c_length - 1;
+ int nmx = cc->c_length - 1;
/* CHECKED ndx silently clipped */
- return (cc->c_table[ndx < 0 ? 0 : (ndx > mx ? mx : ndx)]);
+ return (cc->c_table[ndx < 0 ? 0 : (ndx > nmx ? nmx : ndx)]);
}
static void tablecommon_setvalue(t_tablecommon *cc, int ndx, int v)
{
- int mx = cc->c_length - 1;
+ int nmx = cc->c_length - 1;
/* CHECKED ndx silently clipped, value not clipped */
- cc->c_table[ndx < 0 ? 0 : (ndx > mx ? mx : ndx)] = v;
+ cc->c_table[ndx < 0 ? 0 : (ndx > nmx ? nmx : ndx)] = v;
tablecommon_modified(cc, 0);
}
@@ -138,10 +142,10 @@ static void tablecommon_setatoms(t_tablecommon *cc, int ndx, int ac, t_atom *av)
{
if (ac > 1 && av->a_type == A_FLOAT)
{
- /* CHECKME resizing */
+ /* CHECKED no resizing */
int last = tablecommon_getindex(cc, ndx + ac - 1);
int *ptr = cc->c_table + ndx;
- for (av++; ndx <= last; ndx++, av++)
+ for (; ndx <= last; ndx++, av++)
*ptr++ = (av->a_type == A_FLOAT ? (int)av->a_w.w_float : 0);
tablecommon_modified(cc, 0);
}
@@ -156,21 +160,65 @@ static void tablecommon_setlength(t_tablecommon *cc, int length)
length = TABLE_MAXLENGTH;
if (relocate = (length > cc->c_size))
{
- cc->c_table = grow_nodata(&length, &cc->c_size, cc->c_table,
- TABLE_INISIZE, cc->c_tableini,
- sizeof(*cc->c_table));
- /* FIXME cache */
+ int l = length;
+ /* CHECKED existing values are preserved */
+ cc->c_table = grow_withdata(&length, &cc->c_length,
+ &cc->c_size, cc->c_table,
+ TABLE_INISIZE, cc->c_tableini,
+ sizeof(*cc->c_table));
+ if (length == l)
+ cc->c_table = grow_nodata(&length, &cc->c_size, cc->c_cache,
+ TABLE_INISIZE, cc->c_cacheini,
+ sizeof(*cc->c_cache));
+ if (length != l)
+ {
+ if (cc->c_table != cc->c_tableini)
+ freebytes(cc->c_table, cc->c_size * sizeof(*cc->c_table));
+ if (cc->c_cache != cc->c_cacheini)
+ freebytes(cc->c_cache, cc->c_size * sizeof(*cc->c_cache));
+ cc->c_size = length = TABLE_INISIZE;
+ cc->c_table = cc->c_tableini;
+ cc->c_cache = cc->c_cacheini;
+ }
}
cc->c_length = length;
- tablecommon_setall(cc, 0); /* CHECKME */
- /* CHECKME head */
+ /* CHECKED values at common indices are preserved */
+ /* CHECKED rewinding neither head, nor loadndx, but a separate
+ condition of eot is preserved only for the head. */
tablecommon_modified(cc, relocate);
}
+static void tablecommon_cacheupdate(t_tablecommon *cc)
+{
+ int ndx = cc->c_length, sum = 0, mn, mx;
+ int *tptr = cc->c_table, *cptr = cc->c_cache;
+ mn = mx = *tptr;
+ while (ndx--)
+ {
+ int v = *tptr++;
+ *cptr++ = (sum += v);
+ if (mn > v)
+ mn = v;
+ else if (mx < v)
+ mx = v;
+ }
+ cc->c_cachesum = sum;
+ cc->c_cachemin = mn;
+ cc->c_cachemax = mx;
+ cc->c_cacheisfresh = 1;
+}
+
static int tablecommon_quantile(t_tablecommon *cc, float f)
{
- /* FIXME */
- return (0);
+ /* CHECKME */
+ float fv;
+ int ndx, *ptr, nmx = cc->c_length - 1;
+ if (!cc->c_cacheisfresh) tablecommon_cacheupdate(cc);
+ fv = f * cc->c_cachesum;
+ for (ndx = 0, ptr = cc->c_cache; ndx < nmx; ndx++, ptr++)
+ if (*ptr >= fv)
+ break;
+ return (ndx);
}
static void tablecommon_doread(t_tablecommon *cc, t_symbol *fn, t_canvas *cv)
@@ -251,6 +299,7 @@ static void *tablecommon_new(void)
cc->c_length = TABLE_DEFLENGTH;
cc->c_table = cc->c_tableini;
cc->c_cache = cc->c_cacheini;
+ cc->c_cacheisfresh = 0;
return (cc);
}
@@ -276,8 +325,6 @@ static void table_unbind(t_table *x)
if (!(cc->c_refs = x->x_next))
{
hammerfile_free(cc->c_filehandle);
- /* disable canvas dirty-flag handling, LATER rethink */
- cc->c_increation = 1;
tablecommon_free(cc);
if (x->x_name) pd_unbind(&cc->c_pd, x->x_name);
pd_free(&cc->c_pd);
@@ -493,6 +540,8 @@ static void table_goto(t_table *x, t_floatarg f)
x->x_head = tablecommon_getindex(x->x_common, (int)f);
}
+/* CHECKED 'send <target> length' works, but not max, min, sum... */
+/* CHECKED 'send <target> <ndx> <value>' writes the value (a bug?) */
static void table_send(t_table *x, t_symbol *s, t_floatarg f)
{
/* FIXME */
@@ -505,17 +554,23 @@ static void table_length(t_table *x)
static void table_sum(t_table *x)
{
- /* FIXME */
+ t_tablecommon *cc = x->x_common;
+ if (!cc->c_cacheisfresh) tablecommon_cacheupdate(cc);
+ outlet_float(((t_object *)x)->ob_outlet, (t_float)cc->c_cachesum);
}
static void table_min(t_table *x)
{
- /* FIXME */
+ t_tablecommon *cc = x->x_common;
+ if (!cc->c_cacheisfresh) tablecommon_cacheupdate(cc);
+ outlet_float(((t_object *)x)->ob_outlet, (t_float)cc->c_cachemin);
}
static void table_max(t_table *x)
{
- /* FIXME */
+ t_tablecommon *cc = x->x_common;
+ if (!cc->c_cacheisfresh) tablecommon_cacheupdate(cc);
+ outlet_float(((t_object *)x)->ob_outlet, (t_float)cc->c_cachemax);
}
static void table_getbits(t_table *x, t_floatarg f1,
@@ -532,7 +587,12 @@ static void table_setbits(t_table *x, t_floatarg f1,
static void table_inv(t_table *x, t_floatarg f)
{
- /* FIXME */
+ /* CHECKME none found, float */
+ int v = (int)f, ndx, *ptr, nmx = x->x_common->c_length - 1;
+ for (ndx = 0, ptr = x->x_common->c_table; ndx < nmx; ndx++, ptr++)
+ if (*ptr >= v)
+ break;
+ outlet_float(((t_object *)x)->ob_outlet, (t_float)ndx);
}
static void table_quantile(t_table *x, t_floatarg f)
@@ -550,19 +610,20 @@ static void table_fquantile(t_table *x, t_floatarg f)
(t_float)tablecommon_quantile(x->x_common, f));
}
+/* FIXME arguments (from, to) */
+/* CHECKED no remote dumping, symbol args bashed to 0 */
static void table_dump(t_table *x)
{
t_tablecommon *cc = x->x_common;
t_outlet *out = ((t_object *)x)->ob_outlet;
- int ndx = cc->c_length;
- int *ptr = cc->c_table;
- /* CHECKME */
- while (ndx--)
- {
- outlet_float(out, (t_float)*ptr++);
- /* FIXME ptr may be invalid after outlet_float()... consider calling
- tablecommon_getindex() rather than patching in selfmod tests */
- }
+ int ndx;
+ /* The usual way of traversing the table by incrementing a pointer is
+ not robust, because calling outlet_float() may invalidate the pointer.
+ The test below is simpler than generic selfmod detection ala coll,
+ but behaviour may be different. LATER revisit, consider asserting
+ invariance of cc->c_table and cc->c_length, instead. */
+ for (ndx = 0; ndx < cc->c_length; ndx++)
+ outlet_float(out, (t_float)cc->c_table[ndx]);
}
static void table_refer(t_table *x, t_symbol *s)
@@ -591,10 +652,34 @@ static void table_write(t_table *x, t_symbol *s)
hammerpanel_save(cc->c_filehandle, 0, 0); /* CHECKME default name */
}
+static int tablecommon_editorappend(t_tablecommon *cc,
+ int v, char *buf, int col)
+{
+ char *bp = buf;
+ int cnt = 0;
+ if (col > 0)
+ *bp++ = ' ', cnt++;
+ cnt += sprintf(bp, "%d", v);
+ if (col + cnt > 80)
+ buf[0] = '\n', col = cnt;
+ else
+ col += cnt;
+ hammereditor_append(cc->c_filehandle, buf);
+ return (col);
+}
+
static void table_open(t_table *x)
{
- t_tablecommon *cc = x->x_common;
/* FIXME */
+ t_tablecommon *cc = x->x_common;
+ char buf[MAXPDSTRING];
+ int *bp = cc->c_table;
+ int count = cc->c_length, col = 0;
+ /* LATER prepend "table: " */
+ hammereditor_open(cc->c_filehandle,
+ x->x_name ? x->x_name->s_name : "Untitled");
+ while (count--)
+ col = tablecommon_editorappend(cc, *bp++, buf, col);
}
static void table_wclose(t_table *x)
diff --git a/shared/common/port.c b/shared/common/port.c
index d09fa6f..9c08802 100644
--- a/shared/common/port.c
+++ b/shared/common/port.c
@@ -88,6 +88,7 @@ static t_symbol *portps_inlet;
static t_symbol *portps_outlet;
static t_symbol *portps_vtable;
static t_symbol *portps_coll;
+static t_symbol *portps_funbuff;
static t_symbol *portps_picture;
static t_int port_getint(t_port *x, int ndx)
@@ -500,6 +501,14 @@ static int imaction_N1_coll(t_port *x, char *arg)
return (PORT_NEXT);
}
+static int imaction_N1_funbuff(t_port *x, char *arg)
+{
+ import_emstart(x, portps_funbuff, &s_, 0);
+ import_emaddv(x, portps_funbuff, "si;", gensym("embed"),
+ port_getint(x, 2) != 0);
+ return (PORT_NEXT);
+}
+
static int imaction_N1_picture(t_port *x, char *arg)
{
import_emstart(x, portps_picture, 0, 0);
@@ -564,6 +573,16 @@ static int imaction_P6_coll(t_port *x, char *arg)
return (PORT_NEXT);
}
+static int imaction_P6_funbuff(t_port *x, char *arg)
+{
+ binbuf_addv(x->x_outbb, "ssffs;",
+ gensym("#X"), gensym("obj"),
+ port_getx(x, 2), port_gety(x, 3), portps_funbuff);
+ import_emflush(x, portps_funbuff, &s_);
+ x->x_nobj++;
+ return (PORT_NEXT);
+}
+
/* LATER use hammer replacements */
static int imaction_P6_pack(t_port *x, char *arg)
{
@@ -748,6 +767,7 @@ static int imaction_T1_flags(t_port *x, char *arg)
static int imaction_T1_set(t_port *x, char *arg)
{
+ /* FIXME funbuff */
if (import_emcopy(x, portps_vtable))
{
int count = port_getint(x, 2);
@@ -840,6 +860,7 @@ static t_portslot imslots__N[] =
{ "vpatcher", imaction_N1_vpatcher, 0, 0, 0 },
{ "vtable", imaction_N1_vtable, 0, 0, 0 },
{ "coll", imaction_N1_coll, 0, 0, 0 },
+ { "funbuff", imaction_N1_funbuff, 0, 0, 0 },
{ "picture", imaction_N1_picture, 0, 0, 0 }
};
static t_portnode imnode__N = { imslots__N, PORT_NSLOTS(imslots__N), 1 };
@@ -849,7 +870,8 @@ static t_portslot imslots_newobj[] =
{ "patcher", imaction_P6_patcher, 0, 0, 0 },
{ "p", imaction_P6_patcher, 0, 0, 0 },
{ "table", imaction_P6_table, 0, 0, 0 },
- { "coll", imaction_P6_coll, 0, 0, 0 }
+ { "coll", imaction_P6_coll, 0, 0, 0 },
+ { "funbuff", imaction_P6_funbuff, 0, 0, 0 }
};
static t_portnode imnode_newobj = { imslots_newobj,
PORT_NSLOTS(imslots_newobj), 6 };
@@ -1269,6 +1291,7 @@ static void port_checksetup(void)
portps_outlet = gensym("outlet");
portps_vtable = gensym("vtable");
portps_coll = gensym("coll");
+ portps_funbuff = gensym("funbuff");
portps_picture = gensym("picture");
if (zgetfn(&pd_objectmaker, portps_bogus) == 0)