aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Grill <xovo@users.sourceforge.net>2006-03-08 16:48:29 +0000
committerThomas Grill <xovo@users.sourceforge.net>2006-03-08 16:48:29 +0000
commit0028a036b1823c364b8a3984bd6b836a15ab7b6f (patch)
tree09da3bd31d17d96aec2ebca84c838a15052156db
parent91a94f0946561a6343f6169b63e538776dca867b (diff)
added inlet and outlet functions
added send functions practically ready to work with! svn path=/trunk/externals/clr/; revision=4658
-rwxr-xr-xCounter/Counter.cs22
-rw-r--r--PureData/PureData.cs115
-rwxr-xr-xclr.cpp169
-rwxr-xr-xtest-clr.pd27
4 files changed, 314 insertions, 19 deletions
diff --git a/Counter/Counter.cs b/Counter/Counter.cs
index 9cb4801..b59945e 100755
--- a/Counter/Counter.cs
+++ b/Counter/Counter.cs
@@ -8,6 +8,8 @@ public class Counter:
{
PureData.Atom[] args;
+ float farg;
+
public Counter(PureData.AtomList args)
{
Post("Count.ctor "+args.ToString());
@@ -15,8 +17,9 @@ public class Counter:
// that's the way to store args (don't just copy an AtomList instance!!)
this.args = (PureData.Atom[])args;
-// pd.AddInlet(x, "init", ParametersType.Float);
-// pd.AddOutlet(x, ParametersType.Float);
+ AddInlet(s_list,new PureData.Symbol("list2"));
+ AddInlet(ref farg);
+ AddOutletBang();
}
// this function MUST exist
@@ -27,6 +30,7 @@ public class Counter:
Add(new MethodSymbol(obj.MySymbol));
Add(new MethodList(obj.MyList));
Add("set",new MethodList(obj.MySet));
+ Add("send",new MethodList(obj.MySend));
Add(new MethodAnything(obj.MyAnything));
Post("Count.Main");
@@ -34,32 +38,44 @@ public class Counter:
protected virtual void MyBang()
{
- Post("Count-BANG");
+ Post("Count-BANG "+farg.ToString());
+ Outlet(0);
}
protected virtual void MyFloat(float f)
{
Post("Count-FLOAT "+f.ToString());
+ Outlet(0,f);
}
protected virtual void MySymbol(PureData.Symbol s)
{
Post("Count-SYMBOL "+s.ToString());
+ Outlet(0,s);
}
protected virtual void MyList(PureData.AtomList l)
{
Post("Count-LIST "+l.ToString());
+ Outlet(0,l);
}
protected virtual void MySet(PureData.AtomList l)
{
Post("Count-SET "+l.ToString());
+ Outlet(0,new PureData.Symbol("set"),l);
+ }
+
+ protected virtual void MySend(PureData.AtomList l)
+ {
+ Send(new PureData.Symbol("receiver"),l);
+ Send(new PureData.Symbol("receiver2"),(PureData.Atom[])l);
}
protected virtual void MyAnything(PureData.Symbol s,PureData.AtomList l)
{
Post("Count-("+s.ToString()+") "+l.ToString());
+ Outlet(0,s,l);
}
/*
public void SendOut()
diff --git a/PureData/PureData.cs b/PureData/PureData.cs
index 6e55693..ebbc319 100644
--- a/PureData/PureData.cs
+++ b/PureData/PureData.cs
@@ -12,6 +12,57 @@ namespace PureData
[MethodImplAttribute (MethodImplOptions.InternalCall)]
internal extern static string SymEval(void *sym);
+
+ [MethodImplAttribute (MethodImplOptions.InternalCall)]
+ internal extern static void AddInlet(void *obj,Symbol sel,Symbol to_sel);
+
+ // map to data member
+ // \NOTE don't know if this is really safe since f must stay at its place (but it should, no?)
+ [MethodImplAttribute (MethodImplOptions.InternalCall)]
+ internal extern static void AddInlet(void *obj,ref float f);
+
+ // map to data member
+ // \NOTE don't know if this is really safe since s must stay at its place (but it should, no?)
+ [MethodImplAttribute (MethodImplOptions.InternalCall)]
+ internal extern static void AddInlet(void *obj,ref Symbol s);
+
+ // map to data member
+ // \NOTE don't know if this is really safe since s must stay at its place (but it should, no?)
+// [MethodImplAttribute (MethodImplOptions.InternalCall)]
+// internal extern static void AddInlet(void *obj,ref Pointer f);
+
+ [MethodImplAttribute (MethodImplOptions.InternalCall)]
+ internal extern static void AddInlet(void *obj); // create proxy inlet
+
+ [MethodImplAttribute (MethodImplOptions.InternalCall)]
+ internal extern static void AddOutlet(void *obj,Symbol type);
+
+ [MethodImplAttribute (MethodImplOptions.InternalCall)]
+ internal extern static void Outlet(void *obj,int n);
+
+ [MethodImplAttribute (MethodImplOptions.InternalCall)]
+ internal extern static void Outlet(void *obj,int n,float f);
+
+ [MethodImplAttribute (MethodImplOptions.InternalCall)]
+ internal extern static void Outlet(void *obj,int n,Symbol s);
+
+ [MethodImplAttribute (MethodImplOptions.InternalCall)]
+ internal extern static void Outlet(void *obj,int n,Pointer p);
+
+ [MethodImplAttribute (MethodImplOptions.InternalCall)]
+ internal extern static void Outlet(void *obj,int n,Atom a);
+
+ [MethodImplAttribute (MethodImplOptions.InternalCall)]
+ internal extern static void Outlet(void *obj,int n,Symbol s,AtomList l);
+
+ [MethodImplAttribute (MethodImplOptions.InternalCall)]
+ internal extern static void Outlet(void *obj,int n,Symbol s,Atom[] l);
+
+ [MethodImplAttribute (MethodImplOptions.InternalCall)]
+ internal extern static void Bind(void *obj,Symbol dst);
+
+ [MethodImplAttribute (MethodImplOptions.InternalCall)]
+ internal extern static void Unbind(void *obj,Symbol dst);
}
// This is the base class for a PD/CLR external
@@ -22,6 +73,16 @@ namespace PureData
// --------------------------------------------------------------------------
+ protected readonly static Symbol s__ = new Symbol("");
+ protected readonly static Symbol s_bang = new Symbol("bang");
+ protected readonly static Symbol s_float = new Symbol("float");
+ protected readonly static Symbol s_symbol = new Symbol("symbol");
+ protected readonly static Symbol s_pointer = new Symbol("pointer");
+ protected readonly static Symbol s_list = new Symbol("list");
+ protected readonly static Symbol s_anything = new Symbol("anything");
+
+ // --------------------------------------------------------------------------
+
[MethodImplAttribute (MethodImplOptions.InternalCall)]
protected extern static void Post(string message);
@@ -65,5 +126,59 @@ namespace PureData
[MethodImplAttribute (MethodImplOptions.InternalCall)]
protected extern static void Add(MethodAnything m);
+
+ // --------------------------------------------------------------------------
+
+ protected void AddInlet(Symbol sel,Symbol to_sel) { Internal.AddInlet(ptr,sel,to_sel); }
+ protected void AddInlet(ref float f) { Internal.AddInlet(ptr,ref f); }
+ protected void AddInlet(ref Symbol s) { Internal.AddInlet(ptr,ref s); }
+// protected void AddInlet(ref Pointer p) { Internal.AddInlet(ptr,ref p); } // map to data member
+ protected void AddInlet() { Internal.AddInlet(ptr); } // create proxy inlet
+
+ // --------------------------------------------------------------------------
+
+ protected void AddOutlet(Symbol type) { Internal.AddOutlet(ptr,type); }
+
+ protected void AddOutletBang() { AddOutlet(s_bang); }
+ protected void AddOutletFloat() { AddOutlet(s_float); }
+ protected void AddOutletSymbol() { AddOutlet(s_symbol); }
+ protected void AddOutletPointer() { AddOutlet(s_pointer); }
+ protected void AddOutletList() { AddOutlet(s_list); }
+ protected void AddOutletAnything() { AddOutlet(s_anything); }
+
+ // --------------------------------------------------------------------------
+
+ protected void Outlet(int n) { Internal.Outlet(ptr,n); }
+ protected void Outlet(int n,float f) { Internal.Outlet(ptr,n,f); }
+ protected void Outlet(int n,Symbol s) { Internal.Outlet(ptr,n,s); }
+ protected void Outlet(int n,Pointer p) { Internal.Outlet(ptr,n,p); }
+ protected void Outlet(int n,Atom a) { Internal.Outlet(ptr,n,a); }
+ protected void Outlet(int n,AtomList l) { Internal.Outlet(ptr,n,s_list,l); }
+ protected void Outlet(int n,Atom[] l) { Internal.Outlet(ptr,n,s_list,l); }
+ protected void Outlet(int n,Symbol s,AtomList l) { Internal.Outlet(ptr,n,s,l); }
+ protected void Outlet(int n,Symbol s,Atom[] l) { Internal.Outlet(ptr,n,s,l); }
+
+ // --------------------------------------------------------------------------
+
+ // bind to symbol
+ protected void Bind(Symbol sym) { Internal.Bind(ptr,sym); }
+ protected void Unbind(Symbol sym) { Internal.Unbind(ptr,sym); }
+
+ // send to receiver symbol
+ [MethodImplAttribute (MethodImplOptions.InternalCall)]
+ protected extern static void Send(Symbol sym,Atom a);
+
+ protected static void Send(Symbol sym) { Send(sym,s_bang,null); }
+ protected static void Send(Symbol sym,float f) { Send(sym,new Atom(f)); }
+ protected static void Send(Symbol sym,Symbol s) { Send(sym,new Atom(s)); }
+ protected static void Send(Symbol sym,Pointer p) { Send(sym,new Atom(p)); }
+ protected static void Send(Symbol sym,AtomList l) { Send(sym,s_list,l); }
+ protected static void Send(Symbol sym,Atom[] l) { Send(sym,s_list,l); }
+
+ [MethodImplAttribute (MethodImplOptions.InternalCall)]
+ protected extern static void Send(Symbol sym,Symbol s,AtomList l);
+
+ [MethodImplAttribute (MethodImplOptions.InternalCall)]
+ protected extern static void Send(Symbol sym,Symbol s,Atom[] l);
}
}
diff --git a/clr.cpp b/clr.cpp
index e8aed95..7a5af73 100755
--- a/clr.cpp
+++ b/clr.cpp
@@ -26,6 +26,7 @@ extern "C" {
#endif
#include <map>
+#include <vector>
#define CORELIB "PureData"
#define DLLEXT "dll"
@@ -39,7 +40,6 @@ static MonoMethodDesc *clr_desc_tostring,*clr_desc_ctor;
static MonoMethod *clr_meth_invoke;
static MonoProperty *clr_prop_method;
-
struct AtomList
{
int argc;
@@ -78,8 +78,8 @@ struct t_clr_class
{
t_class *pd_class;
MonoClass *mono_class;
- MonoClassField *mono_obj_field;
MonoMethod *mono_ctor;
+ MonoClassField *obj_field; // ptr field in PureData.External
t_symbol *name;
Delegate method_bang,method_float,method_symbol,method_pointer,method_list,method_anything;
ClrMethodMap *methods; // explicit method selectors
@@ -89,6 +89,8 @@ typedef std::map<t_symbol *,t_clr_class *> ClrMap;
// this holds the class name to class structure association
static ClrMap clr_map;
+typedef std::vector<t_outlet *> OutletArr;
+
// this is the class to be setup (while we are in the CLR static Main method)
static t_clr_class *clr_setup_class = NULL;
@@ -98,6 +100,7 @@ struct t_clr
t_object pd_obj; // myself
t_clr_class *clr_clss; // pointer to our class structure
MonoObject *mono_obj; // the mono class instance
+ OutletArr *outlets;
};
@@ -176,7 +179,6 @@ static void clr_method_pointer(t_clr *x,t_gpointer *p)
if(exc) error_exc("Exception raised",x->clr_clss->name->s_name,exc);
}
-
static void clr_method_list(t_clr *x,t_symbol *l, int argc, t_atom *argv)
{
assert(x && x->clr_clss);
@@ -330,6 +332,127 @@ static void PD_AddAnything(MonoObject *method)
}
+static void PD_AddInlet(t_clr *obj,t_symbol *sel,t_symbol *to_sel)
+{
+ assert(obj);
+ t_inlet *in = inlet_new(&obj->pd_obj,&obj->pd_obj.ob_pd,sel,to_sel);
+ assert(in);
+}
+
+static void PD_AddInletFloat(t_clr *obj,float *f)
+{
+ assert(obj);
+ t_inlet *in = floatinlet_new(&obj->pd_obj,f);
+ assert(in);
+}
+
+static void PD_AddInletSymbol(t_clr *obj,t_symbol **s)
+{
+ assert(obj);
+ t_inlet *in = symbolinlet_new(&obj->pd_obj,s);
+ assert(in);
+}
+
+/*
+static void PD_AddInletPointer(t_clr *obj,t_gpointer *p)
+{
+ assert(obj);
+ t_inlet *in = pointerinlet_new(&obj->pd_obj,p);
+ assert(in);
+}
+*/
+
+static void PD_AddInletProxy(t_clr *obj)
+{
+ assert(obj);
+ // TODO implement
+}
+
+static void PD_AddOutlet(t_clr *obj,t_symbol *type)
+{
+ assert(obj);
+ t_outlet *out = outlet_new(&obj->pd_obj,type);
+ assert(out);
+ if(!obj->outlets) obj->outlets = new OutletArr;
+ obj->outlets->push_back(out);
+}
+
+static void PD_OutletBang(t_clr *obj,int n)
+{
+ assert(obj);
+ assert(obj->outlets);
+ outlet_bang((*obj->outlets)[n]);
+}
+
+static void PD_OutletFloat(t_clr *obj,int n,float f)
+{
+ assert(obj);
+ assert(obj->outlets);
+ outlet_float((*obj->outlets)[n],f);
+}
+
+static void PD_OutletSymbol(t_clr *obj,int n,t_symbol *s)
+{
+ assert(obj);
+ assert(obj->outlets);
+ outlet_symbol((*obj->outlets)[n],s);
+}
+
+static void PD_OutletPointer(t_clr *obj,int n,t_gpointer *p)
+{
+ assert(obj);
+ assert(obj->outlets);
+ outlet_pointer((*obj->outlets)[n],p);
+}
+
+static void PD_OutletAtom(t_clr *obj,int n,t_atom l)
+{
+ assert(obj);
+ assert(obj->outlets);
+ t_outlet *out = (*obj->outlets)[n];
+ switch(l.a_type) {
+ case A_FLOAT: outlet_float(out,l.a_w.w_float); break;
+ case A_SYMBOL: outlet_symbol(out,l.a_w.w_symbol); break;
+ case A_POINTER: outlet_pointer(out,l.a_w.w_gpointer); break;
+ default:
+ error("CLR - internal error in file " __FILE__ ", line %i",__LINE__);
+ }
+}
+
+static void PD_OutletAnything(t_clr *obj,int n,t_symbol *s,AtomList l)
+{
+ assert(obj);
+ assert(obj->outlets);
+ outlet_anything((*obj->outlets)[n],s,l.argc,l.argv);
+}
+
+static void PD_OutletAnything2(t_clr *obj,int n,t_symbol *s,MonoArray *l)
+{
+ assert(obj);
+ assert(obj->outlets);
+// assert(mono_object_get_class(&l->obj) == clr_atom);
+ outlet_anything((*obj->outlets)[n],s,mono_array_length(l),mono_array_addr(l,t_atom,0));
+}
+
+static void PD_SendAtom(t_symbol *dst,t_atom a)
+{
+ void *cl = dst->s_thing;
+ if(cl) pd_forwardmess((t_class **)cl,1,&a);
+}
+
+static void PD_SendAnything(t_symbol *dst,t_symbol *s,AtomList l)
+{
+ void *cl = dst->s_thing;
+ if(cl) pd_typedmess((t_class **)cl,s,l.argc,l.argv);
+}
+
+static void PD_SendAnything2(t_symbol *dst,t_symbol *s,MonoArray *l)
+{
+ void *cl = dst->s_thing;
+// assert(mono_object_get_class(&l->obj) == clr_atom);
+ if(cl) pd_typedmess((t_class **)cl,s,mono_array_length(l),mono_array_addr(l,t_atom,0));
+}
+
void *clr_new(t_symbol *classname, int argc, t_atom *argv)
{
// find class name in map
@@ -355,7 +478,9 @@ void *clr_new(t_symbol *classname, int argc, t_atom *argv)
x->clr_clss->name = classname;
// store our object pointer in External::ptr member
- mono_field_set_value(x->mono_obj,clss->mono_obj_field,&x);
+ mono_field_set_value(x->mono_obj,clss->obj_field,x);
+
+ x->outlets = NULL;
// ok, we have an object - look for constructor
if(clss->mono_ctor) {
@@ -381,6 +506,7 @@ void *clr_new(t_symbol *classname, int argc, t_atom *argv)
void clr_free(t_clr *x)
{
+ if(x->outlets) delete x->outlets;
}
static int classloader(char *dirname, char *classname)
@@ -402,10 +528,9 @@ static int classloader(char *dirname, char *classname)
close(fd);
clr_class = (t_clr_class *)getbytes(sizeof(t_clr_class));
+ // set all struct members to 0
memset(clr_class,0,sizeof(*clr_class));
-// clr_class->methods = NULL;
-
// try to load assembly
strcat(dirbuf,"/");
strcat(dirbuf,classname);
@@ -428,13 +553,13 @@ static int classloader(char *dirname, char *classname)
goto bailout;
}
- clr_class->mono_obj_field = mono_class_get_field_from_name(clr_class->mono_class,"ptr");
- assert(clr_class->mono_obj_field);
-
// make new class (with classname)
classsym = gensym(classname);
clr_class->pd_class = class_new(classsym,(t_newmethod)clr_new,(t_method)clr_free, sizeof(t_clr), CLASS_DEFAULT, A_GIMME, 0);
+ clr_class->obj_field = mono_class_get_field_from_name(clr_class->mono_class,"ptr");
+ assert(clr_class->obj_field);
+
// find static Main method
MonoMethodDesc *clr_desc_main = mono_method_desc_new("::Setup",FALSE);
@@ -449,8 +574,7 @@ static int classloader(char *dirname, char *classname)
}
// store NULL in External::ptr member
- void *x = NULL;
- mono_field_set_value(obj,clr_class->mono_obj_field,&x);
+ mono_field_set_value(obj,clr_class->obj_field,NULL);
// set current class
clr_setup_class = clr_class;
@@ -570,6 +694,29 @@ void clr_setup(void)
mono_add_internal_call("PureData.External::Add(PureData.Symbol,PureData.External/MethodList)", (const void *)PD_AddSelector);
mono_add_internal_call("PureData.External::Add(PureData.External/MethodAnything)", (const void *)PD_AddAnything);
+ mono_add_internal_call("PureData.Internal::AddInlet(void*,PureData.Symbol,PureData.Symbol)", (const void *)PD_AddInlet);
+ mono_add_internal_call("PureData.Internal::AddInlet(void*,single&)", (const void *)PD_AddInletFloat);
+ mono_add_internal_call("PureData.Internal::AddInlet(void*,PureData.Symbol&)", (const void *)PD_AddInletSymbol);
+// mono_add_internal_call("PureData.Internal::AddInlet(void*,PureData.Pointer&)", (const void *)PD_AddInletPointer);
+ mono_add_internal_call("PureData.Internal::AddInlet(void*)", (const void *)PD_AddInletProxy);
+
+ mono_add_internal_call("PureData.Internal::AddOutlet(void*,PureData.Symbol)", (const void *)PD_AddOutlet);
+
+ mono_add_internal_call("PureData.Internal::Outlet(void*,int)", (const void *)PD_OutletBang);
+ mono_add_internal_call("PureData.Internal::Outlet(void*,int,single)", (const void *)PD_OutletFloat);
+ mono_add_internal_call("PureData.Internal::Outlet(void*,int,PureData.Symbol)", (const void *)PD_OutletSymbol);
+ mono_add_internal_call("PureData.Internal::Outlet(void*,int,PureData.Pointer)", (const void *)PD_OutletPointer);
+ mono_add_internal_call("PureData.Internal::Outlet(void*,int,PureData.Atom)", (const void *)PD_OutletAtom);
+ mono_add_internal_call("PureData.Internal::Outlet(void*,int,PureData.Symbol,PureData.AtomList)", (const void *)PD_OutletAnything);
+ mono_add_internal_call("PureData.Internal::Outlet(void*,int,PureData.Symbol,PureData.Atom[])", (const void *)PD_OutletAnything2);
+
+// mono_add_internal_call("PureData.Internal::Bind(void*,PureData.Symbol)", (const void *)PD_Bind);
+// mono_add_internal_call("PureData.Internal::Unbind(void*,PureData.Symbol)", (const void *)PD_Unbind);
+
+ mono_add_internal_call("PureData.External::Send(PureData.Symbol,PureData.Atom)", (const void *)PD_SendAtom);
+ mono_add_internal_call("PureData.External::Send(PureData.Symbol,PureData.Symbol,PureData.AtomList)", (const void *)PD_SendAnything);
+ mono_add_internal_call("PureData.External::Send(PureData.Symbol,PureData.Symbol,PureData.Atom[])", (const void *)PD_SendAnything2);
+
// load important classes
clr_symbol = mono_class_from_name(image,"PureData","Symbol");
assert(clr_symbol);
diff --git a/test-clr.pd b/test-clr.pd
index fc1e7b7..75721bc 100755
--- a/test-clr.pd
+++ b/test-clr.pd
@@ -1,8 +1,8 @@
-#N canvas 603 10 798 320 12;
+#N canvas 617 153 818 585 12;
#X floatatom 125 51 5 0 0 0 - - -;
#X symbolatom 320 81 10 0 0 0 - - -;
#X msg 536 45 msg one 2 three;
-#X obj 240 276 Counter a b 5;
+#X obj 151 443 Counter a b 5;
#X obj 22 24 loadbang;
#X floatatom 213 26 5 0 0 0 - - -;
#X msg 213 52 1 \$1 3;
@@ -11,12 +11,23 @@
#X obj 21 54 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
-1;
#X msg 535 82 set 1 7 8;
-#X msg 541 167 list;
-#X msg 540 196 list 1;
-#X msg 541 225 list abc;
+#X msg 533 135 list;
+#X msg 532 164 list 1;
+#X msg 533 193 list abc;
+#X msg 528 251 list s e c o n d;
+#X obj 152 495 print OUT;
+#X floatatom 530 321 5 0 0 0 - - -;
+#X floatatom 229 112 5 0 0 0 - - -;
+#X msg 228 136 send \$1 b c;
+#X obj 407 497 print RECV1;
+#X obj 406 463 r receiver;
+#X obj 554 465 r receiver2;
+#X obj 555 499 print RECV2;
+#X text 585 318 bang to see;
#X connect 0 0 3 0;
#X connect 1 0 3 0;
#X connect 2 0 3 0;
+#X connect 3 0 15 0;
#X connect 4 0 9 0;
#X connect 5 0 6 0;
#X connect 6 0 3 0;
@@ -27,3 +38,9 @@
#X connect 11 0 3 0;
#X connect 12 0 3 0;
#X connect 13 0 3 0;
+#X connect 14 0 3 1;
+#X connect 16 0 3 2;
+#X connect 17 0 18 0;
+#X connect 18 0 3 0;
+#X connect 20 0 19 0;
+#X connect 21 0 22 0;