aboutsummaryrefslogtreecommitdiff
path: root/cyclone/hammer/prepend.c
diff options
context:
space:
mode:
authorN.N. <krzyszcz@users.sourceforge.net>2004-12-08 15:40:14 +0000
committerN.N. <krzyszcz@users.sourceforge.net>2004-12-08 15:40:14 +0000
commitd5a39ff6469f8762218c00a34f4b0a120a56332b (patch)
tree8b5d6f1008f1ce09daf3e2a63b71f9c142911e80 /cyclone/hammer/prepend.c
parentb88a64023a08ed9a0e520058ef8be200515d9639 (diff)
various bug-fixes, maxmode, toxy .#args
svn path=/trunk/externals/miXed/; revision=2360
Diffstat (limited to 'cyclone/hammer/prepend.c')
-rw-r--r--cyclone/hammer/prepend.c255
1 files changed, 176 insertions, 79 deletions
diff --git a/cyclone/hammer/prepend.c b/cyclone/hammer/prepend.c
index 052c8d6..1b3bd73 100644
--- a/cyclone/hammer/prepend.c
+++ b/cyclone/hammer/prepend.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2002-2003 krzYszcz and others.
+/* Copyright (c) 2002-2004 krzYszcz and others.
* For information on usage and redistribution, and for a DISCLAIMER OF ALL
* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
@@ -21,9 +21,17 @@ typedef struct _prepend
int x_entered;
int x_auxsize;
t_atom *x_auxbuf;
+ t_pd *x_proxy;
} t_prepend;
+typedef struct _prependxy
+{
+ t_pd xy_pd;
+ t_prepend *xy_owner;
+} t_prependxy;
+
static t_class *prepend_class;
+static t_class *prependxy_class;
/* Usually a preallocation method is used, except in special cases of:
1) reentrant output request, or 2) an output request which would cause
@@ -32,83 +40,86 @@ static t_class *prepend_class;
A separately preallocated output buffer is not used, thus avoiding
memcpying of the stored message (a small performance gain when the
preallocation method is chosen). Instead, self-invoked 'set'
- messages are postponed, using an auxiliary buffer.
-*/
+ messages are postponed, using an auxiliary buffer. */
-static void prepend_dooutput(t_prepend *x, t_symbol *s, int ac, t_atom *av)
+/* called only from prepend_doanything() */
+static void prepend_dooutput(t_prepend *x, int ac, t_atom *av)
{
- if (s == &s_float)
+ if (x->x_selector == &s_float)
{
if (ac > 1)
outlet_list(((t_object *)x)->ob_outlet, &s_list, ac, av);
else
outlet_float(((t_object *)x)->ob_outlet, av->a_w.w_float);
}
- else if (s == &s_list)
+ else if (x->x_selector == &s_list)
outlet_list(((t_object *)x)->ob_outlet, &s_list, ac, av);
- else if (s)
+ else /* x->x_selector guaranteed non-empty */
/* CHECKED: 'bang' is prepended -- we cannot do so...
('symbol' cannot be compatible too) */
- {
- outlet_anything(((t_object *)x)->ob_outlet, s, ac, av);
- }
+ outlet_anything(((t_object *)x)->ob_outlet, x->x_selector, ac, av);
}
-static void prepend_anything(t_prepend *x, t_symbol *s, int ac, t_atom *av)
+static void prepend_doanything(t_prepend *x, t_symbol *s, int ac, t_atom *av)
{
int reentered = x->x_entered;
- int prealloc = !reentered;
- int ntotal = x->x_natoms + ac;
- t_atom *buf;
x->x_entered = 1;
- if (s == &s_) s = 0;
- if (s)
- ntotal++;
- if (prealloc && ntotal > x->x_size)
- {
- if (ntotal > PREPEND_MAXSIZE)
- prealloc = 0;
- else
- {
- int nrequested = ntotal;
- x->x_message = grow_withdata(&nrequested, &x->x_natoms,
- &x->x_size, x->x_message,
- PREPEND_INISIZE, x->x_messini,
- sizeof(*x->x_message));
- prealloc = (nrequested == ntotal);
- }
- }
- if (prealloc)
+ if (s == &s_)
+ s = 0;
+ if (s || x->x_natoms)
{
- buf = x->x_message + x->x_natoms;
+ int prealloc = !reentered;
+ int ntotal = x->x_natoms + ac;
+ t_atom *buf;
if (s)
+ ntotal++;
+ if (prealloc && ntotal > x->x_size)
{
- SETSYMBOL(buf, s);
- buf++;
+ if (ntotal > PREPEND_MAXSIZE)
+ prealloc = 0;
+ else
+ {
+ int nrequested = ntotal;
+ x->x_message = grow_withdata(&nrequested, &x->x_natoms,
+ &x->x_size, x->x_message,
+ PREPEND_INISIZE, x->x_messini,
+ sizeof(*x->x_message));
+ prealloc = (nrequested == ntotal);
+ }
}
- if (ac)
- memcpy(buf, av, ac * sizeof(*buf));
- prepend_dooutput(x, x->x_selector, ntotal, x->x_message);
- }
- else
- {
- /* LATER consider using the stack if ntotal <= MAXSTACK */
- if (buf = getbytes(ntotal * sizeof(*buf)))
+ if (prealloc)
{
- t_atom *bp = buf + x->x_natoms;
- if (x->x_natoms)
- memcpy(buf, x->x_message, x->x_natoms * sizeof(*buf));
+ buf = x->x_message + x->x_natoms;
if (s)
{
- SETSYMBOL(bp, s);
- bp++;
+ SETSYMBOL(buf, s);
+ buf++;
}
if (ac)
- memcpy(bp, av, ac * sizeof(*bp));
- prepend_dooutput(x, x->x_selector, ntotal, buf);
- freebytes(buf, ntotal * sizeof(*buf));
+ memcpy(buf, av, ac * sizeof(*buf));
+ prepend_dooutput(x, ntotal, x->x_message);
+ }
+ else
+ {
+ /* LATER consider using the stack if ntotal <= MAXSTACK */
+ if (buf = getbytes(ntotal * sizeof(*buf)))
+ {
+ t_atom *bp = buf + x->x_natoms;
+ if (x->x_natoms)
+ memcpy(buf, x->x_message, x->x_natoms * sizeof(*buf));
+ if (s)
+ {
+ SETSYMBOL(bp, s);
+ bp++;
+ }
+ if (ac)
+ memcpy(bp, av, ac * sizeof(*bp));
+ prepend_dooutput(x, ntotal, buf);
+ freebytes(buf, ntotal * sizeof(*buf));
+ }
}
}
+ else prepend_dooutput(x, ac, av);
if (!reentered)
{
x->x_entered = 0;
@@ -136,51 +147,75 @@ static void prepend_anything(t_prepend *x, t_symbol *s, int ac, t_atom *av)
static void prepend_bang(t_prepend *x)
{
- t_atom at;
- SETSYMBOL(&at, &s_bang); /* CHECKED */
- prepend_anything(x, 0, 1, &at);
+ if (x->x_selector)
+ {
+ t_atom at;
+ SETSYMBOL(&at, &s_bang); /* CHECKED */
+ prepend_doanything(x, 0, 1, &at);
+ }
+ else outlet_bang(((t_object *)x)->ob_outlet);
}
static void prepend_float(t_prepend *x, t_float f)
{
- t_atom at;
- SETFLOAT(&at, f);
- prepend_anything(x, 0, 1, &at);
+ if (x->x_selector)
+ {
+ t_atom at;
+ SETFLOAT(&at, f);
+ prepend_doanything(x, 0, 1, &at);
+ }
+ else outlet_float(((t_object *)x)->ob_outlet, f);
}
static void prepend_symbol(t_prepend *x, t_symbol *s)
{
- t_atom at;
- SETSYMBOL(&at, s);
- prepend_anything(x, 0, 1, &at);
+ if (x->x_selector)
+ {
+ t_atom at;
+ SETSYMBOL(&at, s);
+ prepend_doanything(x, 0, 1, &at);
+ }
+ else outlet_symbol(((t_object *)x)->ob_outlet, s);
}
/* LATER gpointer */
static void prepend_list(t_prepend *x, t_symbol *s, int ac, t_atom *av)
{
- prepend_anything(x, 0, ac, av);
+ if (x->x_selector)
+ prepend_doanything(x, 0, ac, av);
+ else
+ outlet_list(((t_object *)x)->ob_outlet, s, ac, av);
}
-static void prepend_set(t_prepend *x, t_symbol *s, int ac, t_atom *av)
+static void prepend_anything(t_prepend *x, t_symbol *s, int ac, t_atom *av)
{
- if (ac)
+ if (x->x_selector)
+ prepend_doanything(x, s, ac, av);
+ else
+ outlet_anything(((t_object *)x)->ob_outlet, s, ac, av);
+}
+
+static void prepend_doset(t_prepend *x, t_symbol *s, int ac, t_atom *av)
+{
+ if (s)
+ x->x_selector = s;
+ else if (ac)
{
- int newsize;
- if (av->a_type == A_FLOAT)
- {
- if (ac > 1) x->x_selector = &s_list;
- else x->x_selector = &s_float;
- }
- else if (av->a_type == A_SYMBOL)
+ if (av->a_type == A_SYMBOL)
{
x->x_selector = av->a_w.w_symbol;
- ac--;
- av++;
+ ac--; av++;
}
+ else if (av->a_type == A_FLOAT)
+ x->x_selector = (ac > 1 ? &s_list : &s_float);
else
return; /* LATER rethink */
- newsize = ac * 2;
+ }
+ else x->x_selector = 0;
+ if (ac)
+ {
+ int newsize = ac * 2;
if (x->x_entered)
{
if (x->x_auxbuf)
@@ -212,12 +247,56 @@ static void prepend_set(t_prepend *x, t_symbol *s, int ac, t_atom *av)
while (ac--) *ap++ = *av++;
}
}
+ else x->x_natoms = 0;
+}
+
+static void prepend_set(t_prepend *x, t_symbol *s, int ac, t_atom *av)
+{
+ if (shared_getmaxcompatibility())
+ prepend_doset(x, 0, ac, av);
+ else
+ prepend_anything(x, s, ac, av);
+}
+
+static void prependxy_bang(t_prependxy *xy)
+{
+ prepend_doset(xy->xy_owner, 0, 0, 0); /* LATER rethink */
+}
+
+static void prependxy_float(t_prependxy *xy, t_float f)
+{
+ t_atom at;
+ SETFLOAT(&at, f);
+ prepend_doset(xy->xy_owner, &s_float, 1, &at);
+}
+
+static void prependxy_symbol(t_prependxy *xy, t_symbol *s)
+{
+ prepend_doset(xy->xy_owner,
+ (s && s != &s_ ? s : &s_symbol), 0, 0); /* LATER rethink */
+}
+
+static void prependxy_list(t_prependxy *xy, t_symbol *s, int ac, t_atom *av)
+{
+ prepend_doset(xy->xy_owner, &s_list, ac, av); /* LATER rethink */
+}
+
+static void prependxy_anything(t_prependxy *xy, t_symbol *s, int ac, t_atom *av)
+{
+ prepend_doset(xy->xy_owner, s, ac, av);
}
static void prepend_free(t_prepend *x)
{
if (x->x_message != x->x_messini)
freebytes(x->x_message, x->x_size * sizeof(*x->x_message));
+ if (x->x_auxbuf)
+ {
+ bug("prepend_free"); /* LATER rethink */
+ freebytes(x->x_auxbuf, x->x_auxsize * sizeof(*x->x_auxbuf));
+ }
+ if (x->x_proxy)
+ pd_free(x->x_proxy);
}
static void *prepend_new(t_symbol *s, int ac, t_atom *av)
@@ -229,15 +308,25 @@ static void *prepend_new(t_symbol *s, int ac, t_atom *av)
x->x_message = x->x_messini;
x->x_auxbuf = 0;
x->x_entered = 0;
- if (!ac)
+ shared_usecompatibility();
+ if (ac)
{
- loud_incompatible(prepend_class,
- "creating an object without an argument");
- /* CHECKED: this is not compatible -- in max an object without an outlet
- is created, and there is no warning if loading from a file. */
+ x->x_proxy = 0;
+ prepend_doset(x, 0, ac, av);
+ }
+ else
+ {
+ if (shared_getmaxcompatibility())
+ /* CHECKED: this is still not compatible -- in max an object
+ without an outlet is created, and there is no warning when
+ loading from a file. */
+ loud_incompatible(prepend_class,
+ "creating an object without an argument");
+ x->x_proxy = pd_new(prependxy_class);
+ ((t_prependxy *)x->x_proxy)->xy_owner = x;
+ inlet_new((t_object *)x, x->x_proxy, 0, 0);
}
outlet_new((t_object *)x, &s_anything);
- prepend_set(x, 0, ac, av);
return (x);
}
@@ -255,4 +344,12 @@ void prepend_setup(void)
class_addanything(prepend_class, prepend_anything);
class_addmethod(prepend_class, (t_method)prepend_set,
gensym("set"), A_GIMME, 0);
+
+ prependxy_class = class_new(gensym("prepend"), 0, 0, sizeof(t_prependxy),
+ CLASS_PD | CLASS_NOINLET, 0);
+ class_addbang(prependxy_class, prependxy_bang);
+ class_addfloat(prependxy_class, prependxy_float);
+ class_addsymbol(prependxy_class, prependxy_symbol);
+ class_addlist(prependxy_class, prependxy_list);
+ class_addanything(prependxy_class, prependxy_anything);
}