aboutsummaryrefslogtreecommitdiff
path: root/shared/unstable/fragile.c
diff options
context:
space:
mode:
authorN.N. <krzyszcz@users.sourceforge.net>2005-01-27 14:42:55 +0000
committerN.N. <krzyszcz@users.sourceforge.net>2005-01-27 14:42:55 +0000
commitbfb359fd22e61faaca3a6e49ad3b7a81f2d71551 (patch)
treed070071515c7e7f53073da32046b24855e8307c8 /shared/unstable/fragile.c
parent6435314717c5fb8fa062eb682c72c8df095b1be3 (diff)
cyclone alpha52 and toxy alpha15 (see notes.txt for cyclone, toxy and shared)
svn path=/trunk/externals/miXed/; revision=2550
Diffstat (limited to 'shared/unstable/fragile.c')
-rw-r--r--shared/unstable/fragile.c174
1 files changed, 173 insertions, 1 deletions
diff --git a/shared/unstable/fragile.c b/shared/unstable/fragile.c
index cd92b72..aed4d83 100644
--- a/shared/unstable/fragile.c
+++ b/shared/unstable/fragile.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 1997-2003 Miller Puckette, krzYszcz, and others.
+/* Copyright (c) 1997-2005 Miller Puckette, krzYszcz, and others.
* For information on usage and redistribution, and for a DISCLAIMER OF ALL
* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
@@ -15,6 +15,178 @@ int fragile_class_count(void)
return (pd_objectmaker->c_nmethod);
}
+/* Raising and voluntary mutation is a method of resolving name clashes.
+ A raised class hides other equivocal candidates. A simpler method,
+ raising and lowering, works only in global scope, because, currently, Pd
+ has only one visibility stack. Until this is changed, abstraction scope
+ will involve some kind of a hack for overriding global visibility stack. */
+
+void fragile_class_raise(t_symbol *cname, t_newmethod thiscall)
+{
+ t_methodentry *mp = pd_objectmaker->c_methods, *topmp = 0;
+ int count = pd_objectmaker->c_nmethod;
+ while (count--)
+ {
+ if (mp->me_name == cname)
+ {
+ if (mp->me_fun == (t_gotfn)thiscall)
+ {
+ if (topmp)
+ {
+ t_methodentry auxmp;
+ /* no linkage there, but anyway... */
+ loud_warning(0, 0, "%s is raising itself...",
+ cname->s_name);
+ memcpy(&auxmp, mp, sizeof(t_methodentry));
+ memcpy(mp, topmp, sizeof(t_methodentry));
+ memcpy(topmp, &auxmp, sizeof(t_methodentry));
+ }
+ return;
+ }
+ else if (!topmp)
+ topmp = mp;
+ }
+ mp++;
+ }
+ loudbug_bug("fragile_class_raise");
+}
+
+t_pd *fragile_class_mutate(t_symbol *cname, t_newmethod thiscall,
+ int ac, t_atom *av)
+{
+ t_newmethod fn;
+ t_atomtype *argtypes;
+ if (fn = fragile_class_getalien(cname, thiscall, &argtypes))
+ {
+ t_pd *z;
+ loud_warning(0, 0, "%s is mutating now...", cname->s_name);
+ if (z = fragile_class_createobject(cname, fn, argtypes, ac, av))
+ {
+ post("...succeeded");
+ return (z);
+ }
+ else post("...failed");
+ }
+ return (0);
+}
+
+t_newmethod fragile_class_getalien(t_symbol *cname, t_newmethod thiscall,
+ t_atomtype **argtypesp)
+{
+ t_methodentry *mp = pd_objectmaker->c_methods;
+ int count = pd_objectmaker->c_nmethod;
+ while (count--)
+ {
+ if (mp->me_name == cname && mp->me_fun != (t_gotfn)thiscall)
+ {
+ *argtypesp = mp->me_arg;
+ return ((t_newmethod)mp->me_fun);
+ }
+ mp++;
+ }
+ return (0);
+}
+
+/* A specialized copy of pd_typedmess() from m_class.c,
+ somewhat simplified for readability. */
+
+typedef t_pd *(*t_newgimme)(t_symbol *s, int ac, t_atom *av);
+typedef t_pd *(*t_new0)(
+ t_floatarg, t_floatarg, t_floatarg, t_floatarg, t_floatarg);
+typedef t_pd *(*t_new1)(
+ t_symbol*,
+ t_floatarg, t_floatarg, t_floatarg, t_floatarg, t_floatarg);
+typedef t_pd *(*t_new2)(
+ t_symbol*, t_symbol*,
+ t_floatarg, t_floatarg, t_floatarg, t_floatarg, t_floatarg);
+typedef t_pd *(*t_new3)(
+ t_symbol*, t_symbol*, t_symbol*,
+ t_floatarg, t_floatarg, t_floatarg, t_floatarg, t_floatarg);
+typedef t_pd *(*t_new4)(
+ t_symbol*, t_symbol*, t_symbol*, t_symbol*,
+ t_floatarg, t_floatarg, t_floatarg, t_floatarg, t_floatarg);
+typedef t_pd *(*t_new5)(
+ t_symbol*, t_symbol*, t_symbol*, t_symbol*, t_symbol*,
+ t_floatarg, t_floatarg, t_floatarg, t_floatarg, t_floatarg);
+typedef t_pd *(*t_new6)(
+ t_symbol*, t_symbol*, t_symbol*, t_symbol*, t_symbol*, t_symbol*,
+ t_floatarg, t_floatarg, t_floatarg, t_floatarg, t_floatarg);
+
+t_pd *fragile_class_createobject(t_symbol *cname, t_newmethod callthis,
+ t_atomtype *argtypes, int ac, t_atom *av)
+{
+ t_floatarg ff[MAXPDARG+1], *fp = ff;
+ t_symbol *ss[MAXPDARG+1], **sp = ss;
+ int nsymbols = 0;
+ t_atomtype wanttype;
+ if (*argtypes == A_GIMME)
+ return ((*((t_newgimme)(callthis)))(cname, ac, av));
+ if (ac > MAXPDARG)
+ ac = MAXPDARG;
+ while (wanttype = *argtypes++)
+ {
+ switch (wanttype)
+ {
+ case A_POINTER:
+ goto badarg;
+ case A_FLOAT:
+ if (!ac) goto badarg;
+ case A_DEFFLOAT:
+ if (!ac) *fp = 0;
+ else
+ {
+ if (av->a_type == A_FLOAT)
+ *fp = av->a_w.w_float;
+ else goto badarg;
+ ac--; av++;
+ }
+ fp++;
+ break;
+ case A_SYMBOL:
+ if (!ac) goto badarg;
+ case A_DEFSYM:
+ if (!ac) *sp = &s_;
+ else
+ {
+ if (av->a_type == A_SYMBOL)
+ *sp = av->a_w.w_symbol;
+ else if (av->a_type == A_FLOAT && av->a_w.w_float == 0)
+ *sp = &s_;
+ else goto badarg;
+ ac--; av++;
+ }
+ nsymbols++;
+ sp++;
+ }
+ }
+ switch (nsymbols)
+ {
+ case 0: return ((*(t_new0)(callthis))
+ (ff[0], ff[1], ff[2], ff[3], ff[4]));
+ case 1: return ((*(t_new1)(callthis))
+ (ss[0],
+ ff[0], ff[1], ff[2], ff[3], ff[4]));
+ case 2: return ((*(t_new2)(callthis))
+ (ss[0], ss[1],
+ ff[0], ff[1], ff[2], ff[3], ff[4]));
+ case 3: return ((*(t_new3)(callthis))
+ (ss[0], ss[1], ss[2],
+ ff[0], ff[1], ff[2], ff[3], ff[4]));
+ case 4: return ((*(t_new4)(callthis))
+ (ss[0], ss[1], ss[2], ss[3],
+ ff[0], ff[1], ff[2], ff[3], ff[4]));
+ case 5: return ((*(t_new5)(callthis))
+ (ss[0], ss[1], ss[2], ss[3], ss[4],
+ ff[0], ff[1], ff[2], ff[3], ff[4]));
+ case 6: return ((*(t_new6)(callthis))
+ (ss[0], ss[1], ss[2], ss[3], ss[4], ss[5],
+ ff[0], ff[1], ff[2], ff[3], ff[4]));
+ }
+badarg:
+ loud_error(0, "bad creation arguments for class '%s'", cname->s_name);
+ return (0);
+}
+
void fragile_class_printnames(char *msg, int firstndx, int lastndx)
{
t_methodentry *mp = pd_objectmaker->c_methods;