From faada59567f8cb252f4a909116595ce309ff5828 Mon Sep 17 00:00:00 2001 From: "N.N." Date: Fri, 23 May 2003 12:29:55 +0000 Subject: This commit was generated by cvs2svn to compensate for changes in r647, which included commits to RCS files with non-trunk default branches. svn path=/trunk/externals/miXed/; revision=648 --- cyclone/hammer/testmess.c | 245 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 245 insertions(+) create mode 100644 cyclone/hammer/testmess.c (limited to 'cyclone/hammer/testmess.c') diff --git a/cyclone/hammer/testmess.c b/cyclone/hammer/testmess.c new file mode 100644 index 0000000..a6e8fe4 --- /dev/null +++ b/cyclone/hammer/testmess.c @@ -0,0 +1,245 @@ +/* Copyright (c) 2002-2003 krzYszcz and others. + * For information on usage and redistribution, and for a DISCLAIMER OF ALL + * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ + +#include +#include "m_pd.h" + +#define TESTMESS_INISIZE 4 /* LATER rethink */ +#define TESTMESS_STACKSIZE 256 + +typedef struct _testmess +{ + t_object x_ob; + t_symbol *x_method; + void (*x_messfun)(struct _testmess *, t_symbol *s, int, t_atom *); + int x_appendmode; + int x_size; /* as allocated */ + int x_natoms; /* as used */ + int x_tailwise; /* data is moved to the end of a buffer */ + t_atom *x_message; + t_atom *x_messbuf; + t_atom x_messini[TESTMESS_INISIZE]; +} t_testmess; + +static t_class *testmess_class; + +static void testmess_setnatoms(t_testmess *x, int natoms) +{ + if (x->x_tailwise) + x->x_message = x->x_messbuf + x->x_size - natoms; + else + x->x_message = x->x_messbuf; + x->x_natoms = natoms; +} + +static int testmess_makeroom(t_testmess *x, int natoms, int preserve) +{ + if (x->x_size < natoms) + { + int newsize = x->x_size * 2; + while (newsize < natoms) newsize *= 2; + post("makeroom %s %d %d %d", x->x_method->s_name, + preserve, natoms, newsize); + if (x->x_messbuf == x->x_messini) + { + if (!(x->x_messbuf = + (t_atom *)getbytes(newsize * sizeof(*x->x_messbuf)))) + { + x->x_messbuf = x->x_messini; + testmess_setnatoms(x, preserve ? x->x_natoms : 0); + return (0); + } + x->x_size = newsize; + testmess_setnatoms(x, preserve ? x->x_natoms : 0); + if (x->x_natoms) + { + if (x->x_tailwise) + memcpy(x->x_message, + x->x_messini + TESTMESS_INISIZE - x->x_natoms, + x->x_natoms * sizeof(*x->x_message)); + else + memcpy(x->x_message, + x->x_messini, x->x_natoms * sizeof(*x->x_message)); + } + } + else + { + int oldsize = x->x_size; + if (!(x->x_messbuf = + (t_atom *)resizebytes(x->x_messbuf, + x->x_size * sizeof(*x->x_messbuf), + newsize * sizeof(*x->x_messbuf)))) + { + x->x_messbuf = x->x_messini; + x->x_size = TESTMESS_INISIZE; + testmess_setnatoms(x, 0); + return (0); + } + x->x_size = newsize; + testmess_setnatoms(x, preserve ? x->x_natoms : 0); + if (x->x_natoms && x->x_tailwise) + memmove(x->x_message, x->x_messbuf + oldsize - x->x_natoms, + x->x_natoms * sizeof(*x->x_message)); + } + } + return (1); +} + +static void testmess_stackmess(t_testmess *x, t_symbol *s, int ac, t_atom *av) +{ + t_atom buf[TESTMESS_STACKSIZE]; + int natoms = x->x_natoms; + if (x->x_appendmode) + { + int left = TESTMESS_STACKSIZE - ac; + if (left < 0) ac = TESTMESS_STACKSIZE, natoms = 0; + else if (natoms > left) natoms = left; + if (ac) + memcpy(buf, av, ac * sizeof(*buf)); + if (natoms) + memcpy(buf + ac, x->x_message, natoms * sizeof(*buf)); + } + else + { + int left = TESTMESS_STACKSIZE - natoms; + if (left < 0) natoms = TESTMESS_STACKSIZE, ac = 0; + else if (ac > left) ac = left; + if (natoms) + memcpy(buf, x->x_message, natoms * sizeof(*buf)); + if (ac) + memcpy(buf + natoms, av, ac * sizeof(*buf)); + } + outlet_anything(((t_object *)x)->ob_outlet, s, natoms + ac, buf); +} + +static void testmess_heapmess(t_testmess *x, t_symbol *s, int ac, t_atom *av) +{ + int ntotal = x->x_natoms + ac; + t_atom *buf = getbytes(ntotal * sizeof(*buf)); + if (buf) + { + if (x->x_appendmode) + { + if (ac) + memcpy(buf, av, ac * sizeof(*buf)); + if (x->x_natoms) + memcpy(buf + ac, x->x_message, x->x_natoms * sizeof(*buf)); + } + else + { + if (x->x_natoms) + memcpy(buf, x->x_message, x->x_natoms * sizeof(*buf)); + if (ac) + memcpy(buf + x->x_natoms, av, ac * sizeof(*buf)); + } + outlet_anything(((t_object *)x)->ob_outlet, s, ntotal, buf); + freebytes(buf, ntotal * sizeof(*buf)); + } +} + +static void testmess_premess(t_testmess *x, t_symbol *s, int ac, t_atom *av) +{ + int ntotal = x->x_natoms + ac; + if (testmess_makeroom(x, ntotal, 1)) + { + t_atom *buf; + if (x->x_appendmode) + { + buf = x->x_messbuf + x->x_size - ntotal; + if (ac) + memcpy(buf, av, ac * sizeof(*buf)); + } + else + { + buf = x->x_messbuf; + if (ac) + memcpy(buf + x->x_natoms, av, ac * sizeof(*buf)); + } + outlet_anything(((t_object *)x)->ob_outlet, s, ntotal, buf); + } +} + +static void testmess_bang(t_testmess *x) +{ + if (x->x_natoms) + x->x_messfun(x, &s_list, 0, 0); +} + +static void testmess_float(t_testmess *x, t_float f) +{ + t_atom at; + SETFLOAT(&at, f); + x->x_messfun(x, (x->x_natoms ? &s_list : &s_float), 1, &at); +} + +static void testmess_symbol(t_testmess *x, t_symbol *s) +{ + x->x_messfun(x, s, 0, 0); +} + +static void testmess_anything(t_testmess *x, t_symbol *s, int ac, t_atom *av) +{ + x->x_messfun(x, s, ac, av); +} + +static void testmess_set(t_testmess *x, t_floatarg f1, t_floatarg f2) +{ + int natoms = (int)f1; + if (natoms > 0 && testmess_makeroom(x, natoms * 2, 0)) + { + t_atom *ap; + int i = (int)f2;; + testmess_setnatoms(x, natoms); + ap = x->x_message; + while (natoms--) + { + SETFLOAT(ap, i); + i++; ap++; + } + } +} + +static void testmess_free(t_testmess *x) +{ + if (x->x_messbuf != x->x_messini) + freebytes(x->x_messbuf, x->x_size * sizeof(*x->x_messbuf)); +} + +static void *testmess_new(t_symbol *s, t_floatarg f) +{ + t_testmess *x = (t_testmess *)pd_new(testmess_class); + x->x_appendmode = 1; + x->x_tailwise = 0; + if (s == gensym("stack")) + x->x_method = s, x->x_messfun = testmess_stackmess; + else if (s == gensym("heap")) + x->x_method = s, x->x_messfun = testmess_heapmess; + else + { + x->x_method = gensym("prealloc"); + x->x_messfun = testmess_premess; + x->x_tailwise = x->x_appendmode; + } + x->x_size = TESTMESS_INISIZE; + x->x_messbuf = x->x_messini; + outlet_new((t_object *)x, &s_anything); + testmess_setnatoms(x, 0); + testmess_set(x, f, 0); + return (x); +} + +void testmess_setup(void) +{ + testmess_class = class_new(gensym("testmess"), + (t_newmethod)testmess_new, + (t_method)testmess_free, + sizeof(t_testmess), 0, + A_DEFFLOAT, A_DEFSYM, 0); + class_addbang(testmess_class, testmess_bang); + class_addfloat(testmess_class, testmess_float); + class_addsymbol(testmess_class, testmess_symbol); + class_addanything(testmess_class, testmess_anything); + class_addmethod(testmess_class, (t_method)testmess_set, + gensym("set"), A_FLOAT, A_DEFFLOAT, 0); +} -- cgit v1.2.1