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/universal.c | 167 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 167 insertions(+) create mode 100644 cyclone/hammer/universal.c (limited to 'cyclone/hammer/universal.c') diff --git a/cyclone/hammer/universal.c b/cyclone/hammer/universal.c new file mode 100644 index 0000000..b1731d8 --- /dev/null +++ b/cyclone/hammer/universal.c @@ -0,0 +1,167 @@ +/* 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 "m_pd.h" +#include "g_canvas.h" +#include "unstable/pd_imp.h" +#include "common/loud.h" + +/* LATER fragilize */ + +typedef struct _universal +{ + t_object x_ob; + t_glist *x_glist; + t_int x_descend; +} t_universal; + +static t_class *universal_class; + +static void universal_dobang(t_glist *glist, int descend, t_symbol *cname) +{ + t_gobj *g; + for (g = glist->gl_list; g; g = g->g_next) + if (pd_class(&g->g_pd)->c_name == cname) /* LATER rethink */ + pd_bang(&g->g_pd); + if (descend) + for (g = glist->gl_list; g; g = g->g_next) + if (pd_class(&g->g_pd) == canvas_class) /* LATER rethink */ + universal_dobang((t_glist *)g, descend, cname); +} + +static void universal_dofloat(t_glist *glist, int descend, t_symbol *cname, + t_float f) +{ + t_gobj *g; + for (g = glist->gl_list; g; g = g->g_next) + if (pd_class(&g->g_pd)->c_name == cname) /* LATER rethink */ + pd_float(&g->g_pd, f); + if (descend) + for (g = glist->gl_list; g; g = g->g_next) + if (pd_class(&g->g_pd) == canvas_class) /* LATER rethink */ + universal_dofloat((t_glist *)g, descend, cname, f); +} + +static void universal_dosymbol(t_glist *glist, int descend, t_symbol *cname, + t_symbol *s) +{ + t_gobj *g; + for (g = glist->gl_list; g; g = g->g_next) + if (pd_class(&g->g_pd)->c_name == cname) /* LATER rethink */ + pd_symbol(&g->g_pd, s); + if (descend) + for (g = glist->gl_list; g; g = g->g_next) + if (pd_class(&g->g_pd) == canvas_class) /* LATER rethink */ + universal_dosymbol((t_glist *)g, descend, cname, s); +} + +static void universal_dopointer(t_glist *glist, int descend, t_symbol *cname, + t_gpointer *gp) +{ + t_gobj *g; + for (g = glist->gl_list; g; g = g->g_next) + if (pd_class(&g->g_pd)->c_name == cname) /* LATER rethink */ + pd_pointer(&g->g_pd, gp); + if (descend) + for (g = glist->gl_list; g; g = g->g_next) + if (pd_class(&g->g_pd) == canvas_class) /* LATER rethink */ + universal_dopointer((t_glist *)g, descend, cname, gp); +} + +static void universal_dolist(t_glist *glist, int descend, t_symbol *cname, + int ac, t_atom *av) +{ + t_gobj *g; + for (g = glist->gl_list; g; g = g->g_next) + if (pd_class(&g->g_pd)->c_name == cname) /* LATER rethink */ + pd_list(&g->g_pd, &s_list, ac, av); + if (descend) + for (g = glist->gl_list; g; g = g->g_next) + if (pd_class(&g->g_pd) == canvas_class) /* LATER rethink */ + universal_dolist((t_glist *)g, descend, cname, ac, av); +} + +static void universal_doanything(t_glist *glist, int descend, t_symbol *cname, + t_symbol *s, int ac, t_atom *av) +{ + t_gobj *g; + for (g = glist->gl_list; g; g = g->g_next) + if (pd_class(&g->g_pd)->c_name == cname) /* LATER rethink */ + typedmess(&g->g_pd, s, ac, av); + if (descend) + for (g = glist->gl_list; g; g = g->g_next) + if (pd_class(&g->g_pd) == canvas_class) /* LATER rethink */ + universal_doanything((t_glist *)g, descend, cname, s, ac, av); +} + +/* LATER rethink type-checking -- it is borrowed from typedmess(). + Anyway, do it once, before traversal, bypassing the generic mechanism + performed for every object. */ +static void universal_anything(t_universal *x, t_symbol *s, int ac, t_atom *av) +{ + /* CHECKED selector without arguments ignored with no complaints */ + if (x->x_glist && s && ac) + { + if (av->a_type == A_FLOAT) + { + if (ac > 1) + universal_dolist(x->x_glist, x->x_descend, s, ac, av); + else + universal_dofloat(x->x_glist, x->x_descend, s, av->a_w.w_float); + } + else if (av->a_type == A_SYMBOL) + { + if (av->a_w.w_symbol == &s_bang) + universal_dobang(x->x_glist, x->x_descend, s); + else if (av->a_w.w_symbol == &s_float) + { + if (ac == 1) + universal_dofloat(x->x_glist, x->x_descend, s, 0.); + else if (av[1].a_type == A_FLOAT) + universal_dofloat(x->x_glist, x->x_descend, s, + av[1].a_w.w_float); + else + loud_error((t_pd *)x, "Bad argument for message 'float'"); + } + else if (av->a_w.w_symbol == &s_symbol) + universal_dosymbol(x->x_glist, x->x_descend, s, + (ac > 1 && av[1].a_type == A_SYMBOL ? + av[1].a_w.w_symbol : &s_)); + else if (av->a_w.w_symbol == &s_list) + universal_dolist(x->x_glist, x->x_descend, s, ac - 1, av + 1); + else + universal_doanything(x->x_glist, x->x_descend, s, + av->a_w.w_symbol, ac - 1, av + 1); + } + if (av->a_type == A_POINTER) + universal_dopointer(x->x_glist, x->x_descend, s, + av->a_w.w_gpointer); + } +} + +static void universal_send(t_universal *x, t_symbol *s, int ac, t_atom *av) +{ + if (ac && av->a_type == A_SYMBOL) + universal_anything(x, av->a_w.w_symbol, ac - 1, av + 1); + /* CHECKED: else ignored without complaints */ +} + +static void *universal_new(t_floatarg f) +{ + t_universal *x = (t_universal *)pd_new(universal_class); + x->x_glist = canvas_getcurrent(); + x->x_descend = ((int)f != 0); /* CHECKED */ + return (x); +} + +void universal_setup(void) +{ + universal_class = class_new(gensym("universal"), + (t_newmethod)universal_new, 0, + sizeof(t_universal), 0, A_DEFFLOAT, 0); + class_addanything(universal_class, universal_anything); + /* CHECKED: 'send', not 'sendmessage' */ + class_addmethod(universal_class, (t_method)universal_send, + gensym("send"), A_GIMME, 0); +} -- cgit v1.2.1