diff options
Diffstat (limited to 'shared')
-rw-r--r-- | shared/common/Makefile.sources | 1 | ||||
-rw-r--r-- | shared/common/patchvalue.c | 265 | ||||
-rw-r--r-- | shared/common/patchvalue.h | 24 | ||||
-rw-r--r-- | shared/notes.txt | 6 | ||||
-rw-r--r-- | shared/toxy/scriptlet.c | 18 | ||||
-rw-r--r-- | shared/toxy/scriptlet.h | 9 | ||||
-rw-r--r-- | shared/unstable/fragile.c | 7 | ||||
-rw-r--r-- | shared/unstable/fragile.h | 2 |
8 files changed, 322 insertions, 10 deletions
diff --git a/shared/common/Makefile.sources b/shared/common/Makefile.sources index 76fd3cc..33bf597 100644 --- a/shared/common/Makefile.sources +++ b/shared/common/Makefile.sources @@ -8,6 +8,7 @@ lex.c \ loud.c \ mifi.c \ os.c \ +patchvalue.c \ port.c \ props.c \ qtree.c \ diff --git a/shared/common/patchvalue.c b/shared/common/patchvalue.c new file mode 100644 index 0000000..b75b565 --- /dev/null +++ b/shared/common/patchvalue.c @@ -0,0 +1,265 @@ +/* Copyright (c) 2005 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 <stdio.h> +#include <string.h> +#include "m_pd.h" +#include "g_canvas.h" +#include "patchvalue.h" + +#ifdef KRZYSZCZ +# include "loud.h" +# define PATCHVALUE_DEBUG +#else +# define loudbug_bug(msg) fprintf(stderr, "BUG: %s\n", msg), bug(msg) +#endif + +typedef struct _patchstorage +{ + t_glist *ps_glist; + t_patchvalue *ps_values; + struct _patchstorage *ps_next; +} t_patchstorage; + +typedef struct _patchboard +{ + t_pd pb_pd; + t_symbol *pb_category; + t_patchstorage *pb_contents; +} t_patchboard; + +static t_class *patchboard_class = 0; + +/* assuming there is no 'name' in the storage */ +static t_patchvalue *patchstorage_addvalue( + t_patchstorage *ps, t_patchvalue *prv, t_class *cls, t_symbol *name) +{ + t_patchvalue *pv = (t_patchvalue *)pd_new(cls); + pv->pv_name = name; + pv->pv_refcount = 0; + if (prv) + { + pv->pv_next = prv->pv_next; + prv->pv_next = pv; + } + else + { + pv->pv_next = ps->ps_values; + ps->ps_values = pv; + } + return (pv); +} + +/* assuming there is no 'glist' on the board */ +static t_patchstorage *patchboard_addstorage( + t_patchboard *pb, t_patchstorage *prv, t_glist *glist) +{ + t_patchstorage *ps = getbytes(sizeof(*ps)); + ps->ps_glist = glist; + ps->ps_values = 0; + if (prv) + { + ps->ps_next = prv->ps_next; + prv->ps_next = ps; + } + else + { + ps->ps_next = pb->pb_contents; + pb->pb_contents = ps; + } + return (ps); +} + +/* not used (LATER find a gc scheme) */ +static void patchstorage_removevalue( + t_patchstorage *ps, t_patchvalue *prv, t_patchvalue *pv, int force) +{ + if (force || pv->pv_refcount < 1) + { + if (prv) + prv->pv_next = pv->pv_next; + else + ps->ps_values = pv->pv_next; + pd_free((t_pd *)pv); + } +} + +/* not used (LATER find a gc scheme) */ +static void patchboard_removestorage( + t_patchboard *pb, t_patchstorage *prv, t_patchstorage *ps, int force) +{ + if (prv) + prv->ps_next = ps->ps_next; + else + pb->pb_contents = ps->ps_next; + if (force) + { + t_patchvalue *pv, *pvnext = ps->ps_values; + while (pv = pvnext) + { + pvnext = pv->pv_next; + pd_free((t_pd *)pv); + } + } + else if (ps->ps_values) + return; + freebytes(ps, sizeof(*ps)); +} + +static t_patchvalue *patchstorage_findvalue( + t_patchstorage *ps, t_symbol *name) +{ + t_patchvalue *pv; + for (pv = ps->ps_values; pv; pv = pv->pv_next) + if (pv->pv_name == name) + break; + return (pv); +} + +static t_patchstorage *patchboard_findstorage( + t_patchboard *pb, t_glist *glist) +{ + t_patchstorage *ps; + for (ps = pb->pb_contents; ps; ps = ps->ps_next) + if (ps->ps_glist == glist) + break; + return (ps); +} + +static t_patchboard *patchboard_find(t_symbol *category) +{ + if (!patchboard_class) + patchboard_class = + patchvalue_classnew(gensym("_patchboard"), sizeof(t_patchboard)); + return ((t_patchboard *)pd_findbyclass(category, patchboard_class)); +} + +static t_patchboard *patchboard_use(t_symbol *category) +{ + if (!patchboard_class) + patchboard_class = + patchvalue_classnew(gensym("_patchboard"), sizeof(t_patchboard)); + if (category && *category->s_name == '#') + { + t_patchboard *pb; + if (!(pb = (t_patchboard *)pd_findbyclass(category, patchboard_class))) + { + pb = (t_patchboard *)pd_new(patchboard_class); + pb->pb_category = category; + pd_bind((t_pd *)pb, category); /* never unbound */ + pb->pb_contents = 0; + } + return (pb); + } + else + { + loudbug_bug("patchboard_use"); + return (0); + } +} + +static t_patchstorage *patchstorage_use(t_symbol *category, t_glist *glist) +{ + t_patchboard *pb; + if (pb = patchboard_use(category)) + { + t_patchstorage *ps; + if (!(ps = patchboard_findstorage(pb, glist))) + ps = patchboard_addstorage(pb, 0, glist); + return (ps); + } + else return (0); +} + +/* The class might have been created by another dll... + This is public, because apart from the "_patchboard" class above, + it is called for the "_raftentry" class too. LATER rethink. */ +t_class *patchvalue_classnew(t_symbol *cname, size_t size) +{ + t_class *cls; + t_symbol *bindsym; + char buf[MAXPDSTRING]; + sprintf(buf, "#%s", cname->s_name); + bindsym = gensym(buf); + if (bindsym->s_thing) + { + t_pd *pd = bindsym->s_thing; + char *name = class_getname(*pd); + if (strcmp(name, cname->s_name)) + { + /* FIXME handle this properly... */ + loudbug_bug("patchvalue_classnew"); + } + else return (*pd); + } + cls = class_new(cname, 0, 0, size, CLASS_PD | CLASS_NOINLET, 0); + pd_bind(pd_new(cls), bindsym); /* never unbound */ + return (cls); +} + +t_patchvalue *patchvalue_use(t_symbol *category, t_glist *glist, + t_class *cls, t_symbol *name) +{ + t_patchstorage *ps; + if (ps = patchstorage_use(category, glist)) + { + t_patchvalue *pv; + if (pv = patchstorage_findvalue(ps, name)) + { + if (*(t_pd *)pv != cls) + { + loudbug_bug("patchvalue_use"); + return (0); + } + } + else pv = patchstorage_addvalue(ps, 0, cls, name); + return (pv); + } + else return (0); +} + +t_patchvalue *patchvalue_get(t_symbol *category, t_glist *glist, + t_class *cls, t_symbol *name) +{ + t_patchboard *pb; + t_patchstorage *ps; + t_patchvalue *pv; + if ((pb = patchboard_find(category)) && + (ps = patchboard_findstorage(pb, glist)) && + (pv = patchstorage_findvalue(ps, name))) + { + if (*(t_pd *)pv == cls) + return (pv); + else + loudbug_bug("patchvalue_get"); + } + return (0); +} + +t_patchvalue *patchvalue_resolve(t_symbol *category, t_glist *glist, + t_class *cls, t_symbol *name) +{ + t_patchboard *pb; + if (pb = patchboard_find(category)) + { + t_patchstorage *ps; + t_patchvalue *pv; + while (glist) + { + if ((ps = patchboard_findstorage(pb, glist)) && + (pv = patchstorage_findvalue(ps, name))) + { + if (*(t_pd *)pv == cls) + return (pv); + else + loudbug_bug("patchvalue_resolve"); + } + else if (canvas_isabstraction(glist)) + break; + else + glist = glist->gl_owner; + } + } + return (0); +} diff --git a/shared/common/patchvalue.h b/shared/common/patchvalue.h new file mode 100644 index 0000000..1a7bc79 --- /dev/null +++ b/shared/common/patchvalue.h @@ -0,0 +1,24 @@ +/* Copyright (c) 2005 krzYszcz and others. + * For information on usage and redistribution, and for a DISCLAIMER OF ALL + * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ + +#ifndef __PATCHVALUE_H__ +#define __PATCHVALUE_H__ + +typedef struct _patchvalue +{ + t_pd pv_pd; + t_symbol *pv_name; + int pv_refcount; + struct _patchvalue *pv_next; +} t_patchvalue; + +t_class *patchvalue_classnew(t_symbol *cname, size_t size); +t_patchvalue *patchvalue_use(t_symbol *category, t_glist *glist, + t_class *cls, t_symbol *name); +t_patchvalue *patchvalue_get(t_symbol *category, t_glist *glist, + t_class *cls, t_symbol *name); +t_patchvalue *patchvalue_resolve(t_symbol *category, t_glist *glist, + t_class *cls, t_symbol *name); + +#endif diff --git a/shared/notes.txt b/shared/notes.txt index 9f92507..3f35ae2 100644 --- a/shared/notes.txt +++ b/shared/notes.txt @@ -5,6 +5,12 @@ TODO for root and shared DONE for root and shared +with rafts prealpha1 + * new module: patchvalue + +with toxy alpha17 + * scriptlet: new call scriptlet_newalike() + with cyclone alpha54 and toxy alpha16 * props: . code cleanup diff --git a/shared/toxy/scriptlet.c b/shared/toxy/scriptlet.c index bf207c1..42e3c02 100644 --- a/shared/toxy/scriptlet.c +++ b/shared/toxy/scriptlet.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2003-2004 krzYszcz and others. +/* Copyright (c) 2003-2005 krzYszcz and others. * For information on usage and redistribution, and for a DISCLAIMER OF ALL * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ @@ -46,7 +46,7 @@ struct _scriptlet t_glist *s_glist; /* containing glist (empty allowed) */ t_symbol *s_rptarget; /* reply target */ t_symbol *s_cbtarget; /* callback target */ - t_symbol *s_item; + t_symbol *s_item; /* item's name (readable part of its path) */ t_scriptlet_cvfn s_cvfn; /* if empty, passing resolveall is a bug */ t_canvas *s_cv; /* as returned by cvfn */ int s_cvstate; @@ -1048,8 +1048,10 @@ void scriptlet_free(t_scriptlet *sp) /* The parameter 'gl' (null accepted) is necessary, because the 's_glist' field, if implicitly set, would be dangerous (after a glist is gone) and confusing (current directory used for i/o of a global scriptlet). */ -t_scriptlet *scriptlet_new(t_pd *owner, t_symbol *rptarget, t_symbol *cbtarget, - t_symbol *item, t_glist *gl, t_scriptlet_cvfn cvfn) +t_scriptlet *scriptlet_new(t_pd *owner, + t_symbol *rptarget, t_symbol *cbtarget, + t_symbol *item, t_glist *glist, + t_scriptlet_cvfn cvfn) { t_scriptlet *sp = getbytes(sizeof(*sp)); if (sp) @@ -1065,7 +1067,7 @@ t_scriptlet *scriptlet_new(t_pd *owner, t_symbol *rptarget, t_symbol *cbtarget, configured = 1; } sp->s_owner = owner; - sp->s_glist = gl; + sp->s_glist = glist; sp->s_rptarget = rptarget; sp->s_cbtarget = cbtarget; sp->s_item = item; @@ -1079,3 +1081,9 @@ t_scriptlet *scriptlet_new(t_pd *owner, t_symbol *rptarget, t_symbol *cbtarget, } return (sp); } + +t_scriptlet *scriptlet_newalike(t_scriptlet *sp) +{ + return (scriptlet_new(sp->s_owner, sp->s_rptarget, sp->s_cbtarget, + sp->s_item, sp->s_glist, sp->s_cvfn)); +} diff --git a/shared/toxy/scriptlet.h b/shared/toxy/scriptlet.h index c9411ae..5887950 100644 --- a/shared/toxy/scriptlet.h +++ b/shared/toxy/scriptlet.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2003-2004 krzYszcz and others. +/* Copyright (c) 2003-2005 krzYszcz and others. * For information on usage and redistribution, and for a DISCLAIMER OF ALL * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ @@ -41,7 +41,10 @@ void scriptlet_setowner(t_scriptlet *sp, t_pd *owner); void scriptlet_clone(t_scriptlet *to, t_scriptlet *from); void scriptlet_append(t_scriptlet *to, t_scriptlet *from); void scriptlet_free(t_scriptlet *sp); -t_scriptlet *scriptlet_new(t_pd *owner, t_symbol *rptarget, t_symbol *cbtarget, - t_symbol *item, t_glist *gl, t_scriptlet_cvfn cvfn); +t_scriptlet *scriptlet_new(t_pd *owner, + t_symbol *rptarget, t_symbol *cbtarget, + t_symbol *item, t_glist *glist, + t_scriptlet_cvfn cvfn); +t_scriptlet *scriptlet_newalike(t_scriptlet *sp); #endif diff --git a/shared/unstable/fragile.c b/shared/unstable/fragile.c index d91ea58..e65e6d4 100644 --- a/shared/unstable/fragile.c +++ b/shared/unstable/fragile.c @@ -15,15 +15,20 @@ int fragile_class_count(void) return (pd_objectmaker->c_nmethod); } -void fragile_class_getnames(t_atom *av) +int fragile_class_getnames(t_atom *av, int maxnames) { int ac = pd_objectmaker->c_nmethod; t_methodentry *mp = pd_objectmaker->c_methods; + if (ac > maxnames) + ac = maxnames; + else + maxnames = ac; while (ac--) { SETSYMBOL(av, mp->me_name); mp++; av++; } + return (maxnames); } /* Raising and voluntary mutation is a method of resolving name clashes. diff --git a/shared/unstable/fragile.h b/shared/unstable/fragile.h index b59bb14..1e2ea0e 100644 --- a/shared/unstable/fragile.h +++ b/shared/unstable/fragile.h @@ -6,7 +6,7 @@ #define __FRAGILE_H__ int fragile_class_count(void); -void fragile_class_getnames(t_atom *av); +int fragile_class_getnames(t_atom *av, int maxnames); void fragile_class_raise(t_symbol *cname, t_newmethod thiscall); t_pd *fragile_class_mutate(t_symbol *cname, t_newmethod thiscall, int ac, t_atom *av); |