From d5a39ff6469f8762218c00a34f4b0a120a56332b Mon Sep 17 00:00:00 2001 From: "N.N." Date: Wed, 8 Dec 2004 15:40:14 +0000 Subject: various bug-fixes, maxmode, toxy .#args svn path=/trunk/externals/miXed/; revision=2360 --- cyclone/hammer/prepend.c | 255 ++++++++++++++++++++++++++++++++--------------- 1 file changed, 176 insertions(+), 79 deletions(-) (limited to 'cyclone/hammer/prepend.c') 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); } -- cgit v1.2.1