aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xCounter/Counter.cs38
-rw-r--r--PureData/PureData.cs99
-rwxr-xr-xclr.cpp416
-rwxr-xr-xtest-clr.pd17
4 files changed, 367 insertions, 203 deletions
diff --git a/Counter/Counter.cs b/Counter/Counter.cs
index 13688e5..4cd1564 100755
--- a/Counter/Counter.cs
+++ b/Counter/Counter.cs
@@ -17,8 +17,10 @@ public class Counter:
// that's the way to store args (don't just copy an AtomList instance!!)
this.args = (PureData.Atom[])args;
- AddInlet(s_list,new PureData.Symbol("list2"));
+// AddInlet(s_list,new PureData.Symbol("list2"));
+ AddInlet();
AddInlet(ref farg);
+ AddInlet();
AddOutletBang();
}
@@ -26,13 +28,15 @@ public class Counter:
// returns void or ClassType
private static ClassType Setup(Counter obj)
{
- Add(new MethodBang(obj.MyBang));
- Add(new MethodFloat(obj.MyFloat));
- 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));
+ AddMethod(0,new MethodBang(obj.MyBang));
+ AddMethod(0,new MethodFloat(obj.MyFloat));
+ AddMethod(0,new MethodSymbol(obj.MySymbol));
+ AddMethod(0,new MethodList(obj.MyList));
+ AddMethod(0,"set",new MethodAnything(obj.MySet));
+ AddMethod(0,"send",new MethodAnything(obj.MySend));
+ AddMethod(0,new MethodAnything(obj.MyAnything));
+ AddMethod(1,new MethodFloat(obj.MyFloat1));
+ AddMethod(1,new MethodAnything(obj.MyAny1));
Post("Count.Main");
return ClassType.Default;
@@ -50,6 +54,16 @@ public class Counter:
Outlet(0,f);
}
+ protected virtual void MyFloat1(float f)
+ {
+ Post("Count-FLOAT1 "+f.ToString());
+ }
+
+ protected virtual void MyAny1(int ix,PureData.Symbol s,PureData.AtomList l)
+ {
+ Post(ix.ToString()+": Count-ANY1 "+l.ToString());
+ }
+
protected virtual void MySymbol(PureData.Symbol s)
{
Post("Count-SYMBOL "+s.ToString());
@@ -62,21 +76,21 @@ public class Counter:
Outlet(0,l);
}
- protected virtual void MySet(PureData.AtomList l)
+ protected virtual void MySet(int ix,PureData.Symbol s,PureData.AtomList l)
{
Post("Count-SET "+l.ToString());
Outlet(0,new PureData.Symbol("set"),l);
}
- protected virtual void MySend(PureData.AtomList l)
+ protected virtual void MySend(int ix,PureData.Symbol s,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)
+ protected virtual void MyAnything(int ix,PureData.Symbol s,PureData.AtomList l)
{
- Post("Count-("+s.ToString()+") "+l.ToString());
+ Post(ix.ToString()+": Count-("+s.ToString()+") "+l.ToString());
Outlet(0,s,l);
}
/*
diff --git a/PureData/PureData.cs b/PureData/PureData.cs
index 8dbac5b..ea0042b 100644
--- a/PureData/PureData.cs
+++ b/PureData/PureData.cs
@@ -13,30 +13,36 @@ 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
+ internal extern static void AddInlet(void *obj,Symbol type); // create proxy inlet (typed)
+
+ [MethodImplAttribute (MethodImplOptions.InternalCall)]
+ internal extern static void AddInlet(void *obj); // create proxy inlet (anything)
+
+ // --------------------------------------------------------------------------
[MethodImplAttribute (MethodImplOptions.InternalCall)]
internal extern static void AddOutlet(void *obj,Symbol type);
+ // --------------------------------------------------------------------------
+
[MethodImplAttribute (MethodImplOptions.InternalCall)]
internal extern static void Outlet(void *obj,int n);
@@ -58,6 +64,8 @@ namespace PureData
[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);
@@ -76,27 +84,39 @@ 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");
+ protected readonly static Symbol _ = new Symbol("");
+ protected readonly static Symbol _bang = new Symbol("bang");
+ protected readonly static Symbol _float = new Symbol("float");
+ protected readonly static Symbol _symbol = new Symbol("symbol");
+ protected readonly static Symbol _pointer = new Symbol("pointer");
+ protected readonly static Symbol _list = new Symbol("list");
+ protected readonly static Symbol _anything = new Symbol("anything");
// --------------------------------------------------------------------------
[MethodImplAttribute (MethodImplOptions.InternalCall)]
protected extern static void Post(string message);
+ protected static void Post(string format,object arg0) { Post(String.Format(format,arg0)); }
+ protected static void Post(string format,object arg0,object arg1) { Post(String.Format(format,arg0,arg1)); }
+ protected static void Post(string format,object arg0,object arg1,object arg2) { Post(String.Format(format,arg0,arg1,arg2)); }
+ protected static void Post(string format,params object[] args) { Post(String.Format(format,args)); }
+
[MethodImplAttribute (MethodImplOptions.InternalCall)]
protected extern static void PostError(string message);
- [MethodImplAttribute (MethodImplOptions.InternalCall)]
- protected extern static void PostBug(string message);
+ protected static void PostError(string format,object arg0) { PostError(String.Format(format,arg0)); }
+ protected static void PostError(string format,object arg0,object arg1) { PostError(String.Format(format,arg0,arg1)); }
+ protected static void PostError(string format,object arg0,object arg1,object arg2) { PostError(String.Format(format,arg0,arg1,arg2)); }
+ protected static void PostError(string format,params object[] args) { PostError(String.Format(format,args)); }
[MethodImplAttribute (MethodImplOptions.InternalCall)]
- protected extern static void PostVerbose(string message);
+ protected extern static void PostVerbose(int lvl,string message);
+
+ protected static void PostVerbose(int lvl,string format,object arg0) { PostVerbose(lvl,String.Format(format,arg0)); }
+ protected static void PostVerbose(int lvl,string format,object arg0,object arg1) { PostVerbose(lvl,String.Format(format,arg0,arg1)); }
+ protected static void PostVerbose(int lvl,string format,object arg0,object arg1,object arg2) { PostVerbose(lvl,String.Format(format,arg0,arg1,arg2)); }
+ protected static void PostVerbose(int lvl,string format,params object[] args) { PostVerbose(lvl,String.Format(format,args)); }
// --------------------------------------------------------------------------
@@ -105,49 +125,52 @@ namespace PureData
protected delegate void MethodSymbol(Symbol s);
protected delegate void MethodPointer(Pointer p);
protected delegate void MethodList(AtomList lst);
- protected delegate void MethodAnything(Symbol tag,AtomList lst);
+ protected delegate void MethodAnything(int inlet,Symbol tag,AtomList lst);
+
+ // --------------------------------------------------------------------------
[MethodImplAttribute (MethodImplOptions.InternalCall)]
- protected extern static void Add(MethodBang m);
+ protected extern static void AddMethod(int inlet,MethodBang m);
[MethodImplAttribute (MethodImplOptions.InternalCall)]
- protected extern static void Add(MethodFloat m);
+ protected extern static void AddMethod(int inlet,MethodFloat m);
[MethodImplAttribute (MethodImplOptions.InternalCall)]
- protected extern static void Add(MethodSymbol m);
+ protected extern static void AddMethod(int inlet,MethodSymbol m);
[MethodImplAttribute (MethodImplOptions.InternalCall)]
- protected extern static void Add(MethodPointer m);
+ protected extern static void AddMethod(int inlet,MethodPointer m);
[MethodImplAttribute (MethodImplOptions.InternalCall)]
- protected extern static void Add(MethodList m);
+ protected extern static void AddMethod(int inlet,MethodList m);
[MethodImplAttribute (MethodImplOptions.InternalCall)]
- protected extern static void Add(Symbol sel,MethodList m);
+ protected extern static void AddMethod(int inlet,Symbol sel,MethodAnything m);
- protected static void Add(string sel,MethodList m) { Add(new Symbol(sel),m); }
+ protected static void AddMethod(int inlet,string sel,MethodAnything m) { AddMethod(inlet,new Symbol(sel),m); }
[MethodImplAttribute (MethodImplOptions.InternalCall)]
- protected extern static void Add(MethodAnything m);
+ protected extern static void AddMethod(int inlet,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 float f) { Internal.AddInlet(ptr,ref f); } // map to data member
+ protected void AddInlet(ref Symbol s) { Internal.AddInlet(ptr,ref s); } // map to data member
// 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 AddInlet(Symbol type) { Internal.AddInlet(ptr,type); } // create typed inlet
+ protected void AddInlet() { Internal.AddInlet(ptr); } // create inlet responding to any message
+ protected void AddInlet(Symbol sel,Symbol to_sel) { Internal.AddInlet(ptr,sel,to_sel); } // redirect messages to defined selector
// --------------------------------------------------------------------------
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 AddOutletBang() { AddOutlet(_bang); }
+ protected void AddOutletFloat() { AddOutlet(_float); }
+ protected void AddOutletSymbol() { AddOutlet(_symbol); }
+ protected void AddOutletPointer() { AddOutlet(_pointer); }
+ protected void AddOutletList() { AddOutlet(_list); }
+ protected void AddOutletAnything() { AddOutlet(_anything); }
// --------------------------------------------------------------------------
@@ -156,8 +179,8 @@ namespace PureData
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,AtomList l) { Internal.Outlet(ptr,n,_list,l); }
+ protected void Outlet(int n,Atom[] l) { Internal.Outlet(ptr,n,_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); }
@@ -171,12 +194,12 @@ namespace PureData
[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) { Send(sym,_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); }
+ protected static void Send(Symbol sym,AtomList l) { Send(sym,_list,l); }
+ protected static void Send(Symbol sym,Atom[] l) { Send(sym,_list,l); }
[MethodImplAttribute (MethodImplOptions.InternalCall)]
protected extern static void Send(Symbol sym,Symbol s,AtomList l);
diff --git a/clr.cpp b/clr.cpp
index 656a5f8..eb4fd14 100755
--- a/clr.cpp
+++ b/clr.cpp
@@ -27,6 +27,7 @@ extern "C" {
#include <map>
#include <vector>
+#include <list>
#define CORELIB "PureData"
#define DLLEXT "dll"
@@ -51,25 +52,87 @@ struct AtomList
// temporary workspace items
-static MonoArray *clr_objarr_1,*clr_objarr_2;
-static MonoObject *clr_obj_single,*clr_obj_symbol,*clr_obj_pointer,*clr_obj_atomlist;
+static MonoArray *clr_objarr_1,*clr_objarr_3;
+static MonoObject *clr_obj_int,*clr_obj_single,*clr_obj_symbol,*clr_obj_pointer,*clr_obj_atomlist;
+static int *clr_val_int;
static float *clr_val_single;
static t_symbol **clr_val_symbol;
static void **clr_val_pointer;
static AtomList *clr_val_atomlist;
+struct t_clr;
struct Delegate
{
- operator bool() const { return methodinfo != NULL; }
+ enum Kind { k_bang,k_float,k_symbol,k_pointer,k_list,k_anything };
+
+ inline operator bool() const { return methodinfo != NULL; }
MonoObject *methodinfo;
MonoMethod *virtmethod;
+ Kind kind;
+
+ inline void init(MonoObject *method,Kind k)
+ {
+ methodinfo = mono_property_get_value(clr_prop_method,method,NULL,NULL);
+ virtmethod = mono_object_get_virtual_method(methodinfo,clr_meth_invoke);
+ kind = k;
+ }
+
+ inline MonoObject *operator()(MonoObject *obj,void *arg = NULL) const
+ {
+ gpointer args[2] = {obj,arg};
+ assert(methodinfo);
+ MonoObject *exc;
+ mono_runtime_invoke(virtmethod,methodinfo,args,&exc);
+ return exc;
+ }
+
+ inline MonoObject *invokeatom(MonoObject *obj,MonoObject *atom) const
+ {
+ mono_array_set(clr_objarr_1,void*,0,atom);
+ return operator()(obj,clr_objarr_1);
+ }
+
+ inline MonoObject *operator()(MonoObject *obj,float f) const
+ {
+ *clr_val_single = f;
+ return invokeatom(obj,clr_obj_single);
+ }
+
+ inline MonoObject *operator()(MonoObject *obj,t_symbol *s) const
+ {
+ *clr_val_symbol = s;
+ return invokeatom(obj,clr_obj_symbol);
+ }
+
+ inline MonoObject *operator()(MonoObject *obj,t_gpointer *p) const
+ {
+ *clr_val_pointer = p;
+ return invokeatom(obj,clr_obj_pointer);
+ }
+
+ inline MonoObject *operator()(MonoObject *obj,int argc,t_atom *argv) const
+ {
+ clr_val_atomlist->Set(argc,argv);
+ return invokeatom(obj,clr_obj_atomlist);
+ }
+
+ inline MonoObject *operator()(MonoObject *obj,int inlet,t_symbol *s,int argc,t_atom *argv) const
+ {
+ *clr_val_int = inlet;
+ *clr_val_symbol = s;
+ clr_val_atomlist->Set(argc,argv);
+ mono_array_set(clr_objarr_3,void*,0,clr_obj_int);
+ mono_array_set(clr_objarr_3,void*,1,clr_obj_symbol);
+ mono_array_set(clr_objarr_3,void*,2,clr_obj_atomlist);
+ return operator()(obj,clr_objarr_3);
+ }
};
typedef std::map<t_symbol *,Delegate> ClrMethodMap;
-
+typedef std::vector<ClrMethodMap *> ClrMethods;
// this is the class structure
// holding the pd and mono class
@@ -82,7 +145,16 @@ struct t_clr_class
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
+ ClrMethods *methods; // explicit method selectors
+};
+
+static t_class *proxy_class;
+
+struct t_proxy
+{
+ t_object pd_obj; // myself
+ t_clr *parent; // parent object
+ int inlet;
};
typedef std::map<t_symbol *,t_clr_class *> ClrMap;
@@ -90,10 +162,14 @@ typedef std::map<t_symbol *,t_clr_class *> ClrMap;
static ClrMap clr_map;
typedef std::vector<t_outlet *> OutletArr;
+typedef std::list<t_proxy *> ProxyList;
// this is the class to be setup (while we are in the CLR static Main method)
static t_clr_class *clr_setup_class = NULL;
+// inlet index... must start with 0 every time a new object is made
+static int clr_inlet;
+
// this is the class instance object structure
struct t_clr
{
@@ -101,6 +177,7 @@ struct t_clr
t_clr_class *clr_clss; // pointer to our class structure
MonoObject *mono_obj; // the mono class instance
OutletArr *outlets;
+ ProxyList *proxies;
};
@@ -121,138 +198,117 @@ static void error_exc(char *txt,char *cname,MonoObject *exc)
static void clr_method_bang(t_clr *x)
{
assert(x && x->clr_clss);
-
- const Delegate &d = x->clr_clss->method_bang;
- assert(d);
-
- gpointer args[2] = {x->mono_obj,NULL};
- MonoObject *exc;
- mono_runtime_invoke(d.virtmethod,d.methodinfo,args,&exc);
+ MonoObject *exc = x->clr_clss->method_bang(x->mono_obj);
if(exc) error_exc("Exception raised",x->clr_clss->name->s_name,exc);
}
static void clr_method_float(t_clr *x,t_float f)
{
assert(x && x->clr_clss);
-
- const Delegate &d = x->clr_clss->method_float;
- assert(d);
-
- *clr_val_single = f;
- mono_array_set(clr_objarr_1,void*,0,clr_obj_single);
-
- gpointer args[2] = {x->mono_obj,clr_objarr_1};
- MonoObject *exc;
- mono_runtime_invoke(d.virtmethod,d.methodinfo,args,&exc);
+ MonoObject *exc = x->clr_clss->method_float(x->mono_obj,f);
if(exc) error_exc("Exception raised",x->clr_clss->name->s_name,exc);
}
static void clr_method_symbol(t_clr *x,t_symbol *s)
{
assert(x && x->clr_clss);
-
- const Delegate &d = x->clr_clss->method_symbol;
- assert(d);
-
- *clr_val_symbol = s;
- mono_array_set(clr_objarr_1,void*,0,clr_obj_symbol);
-
- gpointer args[2] = {x->mono_obj,clr_objarr_1};
- MonoObject *exc;
- mono_runtime_invoke(d.virtmethod,d.methodinfo,args,&exc);
+ MonoObject *exc = x->clr_clss->method_symbol(x->mono_obj,s);
if(exc) error_exc("Exception raised",x->clr_clss->name->s_name,exc);
}
static void clr_method_pointer(t_clr *x,t_gpointer *p)
{
assert(x && x->clr_clss);
-
- const Delegate &d = x->clr_clss->method_pointer;
- assert(d);
-
- *clr_val_pointer = p;
- mono_array_set(clr_objarr_1,void*,0,clr_obj_pointer);
-
- gpointer args[2] = {x->mono_obj,clr_objarr_1};
- MonoObject *exc;
- mono_runtime_invoke(d.virtmethod,d.methodinfo,args,&exc);
+ MonoObject *exc = x->clr_clss->method_pointer(x->mono_obj,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)
+static void clr_method_list(t_clr *x,t_symbol *,int argc,t_atom *argv)
{
assert(x && x->clr_clss);
-
- const Delegate &d = x->clr_clss->method_list;
- assert(d);
-
- clr_val_atomlist->Set(argc,argv);
- mono_array_set(clr_objarr_1,void*,0,clr_obj_atomlist);
-
- gpointer args[2] = {x->mono_obj,clr_objarr_1};
- MonoObject *exc;
- mono_runtime_invoke(d.virtmethod,d.methodinfo,args,&exc);
+ MonoObject *exc = x->clr_clss->method_symbol(x->mono_obj,argc,argv);
if(exc) error_exc("Exception raised",x->clr_clss->name->s_name,exc);
}
-static void clr_method_anything(t_clr *x,t_symbol *s,int argc,t_atom *argv)
+static void call_anything(t_clr *x,int inlet,t_symbol *s,int argc,t_atom *argv)
{
assert(x && x->clr_clss);
- const Delegate *d = NULL;
- ClrMethodMap *methods = x->clr_clss->methods;
- if(methods) {
- ClrMethodMap::iterator it = methods->find(s);
- if(it != methods->end()) d = &it->second;
+ const Delegate *d;
+
+ ClrMethods *methods = x->clr_clss->methods;
+ if(methods && inlet < (int)methods->size()) {
+ ClrMethodMap *methmap = (*methods)[inlet];
+ if(methmap) {
+ ClrMethodMap::iterator it = methmap->find(s);
+ if(it != methmap->end()) {
+ d = &it->second;
+ goto found;
+ }
+
+ if(inlet) {
+ // search for NULL symbol pointer
+ it = methmap->find(NULL);
+ if(it != methmap->end()) {
+ d = &it->second;
+ goto found;
+ }
+ }
+ }
}
- gpointer args[2];
- args[0] = x->mono_obj;
+ // no selectors: general method
+ d = &x->clr_clss->method_anything;
- if(d) {
- // explicit selector
+ found:
- clr_val_atomlist->Set(argc,argv);
- mono_array_set(clr_objarr_1,void*,0,clr_obj_atomlist);
- args[1] = clr_objarr_1;
- }
- else {
- // general method
-
- d = &x->clr_clss->method_anything;
- assert(d);
+ // we must have found something....
+ assert(d);
- *clr_val_symbol = s;
- clr_val_atomlist->Set(argc,argv);
- mono_array_set(clr_objarr_2,void*,0,clr_obj_symbol);
- mono_array_set(clr_objarr_2,void*,1,clr_obj_atomlist);
- args[1] = clr_objarr_2;
+ MonoObject *exc;
+ switch(d->kind) {
+ case Delegate::k_bang:
+ assert(argc == 0);
+ exc = (*d)(x->mono_obj);
+ break;
+ case Delegate::k_float:
+ assert(argc == 1 && argv[0].a_type == A_FLOAT);
+ exc = (*d)(x->mono_obj,argv[0].a_w.w_float);
+ break;
+ case Delegate::k_symbol:
+ assert(argc == 1 && argv[0].a_type == A_SYMBOL);
+ exc = (*d)(x->mono_obj,argv[0].a_w.w_symbol);
+ break;
+ case Delegate::k_pointer:
+ assert(argc == 1 && argv[0].a_type == A_POINTER);
+ exc = (*d)(x->mono_obj,argv[0].a_w.w_gpointer);
+ break;
+ case Delegate::k_list:
+ exc = (*d)(x->mono_obj,argc,argv);
+ break;
+ case Delegate::k_anything:
+ exc = (*d)(x->mono_obj,inlet,s,argc,argv);
+ break;
+ default:
+ assert(false);
}
- MonoObject *exc;
- mono_runtime_invoke(d->virtmethod,d->methodinfo,args,&exc);
if(exc) error_exc("Exception raised",x->clr_clss->name->s_name,exc);
}
-// this function is called by mono when it wants post messages to pd
+static void clr_method_anything(t_clr *x,t_symbol *s,int argc,t_atom *argv) { call_anything(x,0,s,argc,argv); }
+static void clr_method_proxy(t_proxy *x,t_symbol *s,int argc,t_atom *argv) { call_anything(x->parent,x->inlet,s,argc,argv); }
+
static void PD_Post(MonoString *str)
{
post("%s",mono_string_to_utf8(str));
}
-// this function is called by mono when it wants post messages to pd
static void PD_PostError(MonoString *str)
{
error("%s",mono_string_to_utf8(str));
}
-// this function is called by mono when it wants post messages to pd
-static void PD_PostBug(MonoString *str)
-{
- bug("%s",mono_string_to_utf8(str));
-}
-
-// this function is called by mono when it wants post messages to pd
static void PD_PostVerbose(int lvl,MonoString *str)
{
verbose(lvl,"%s",mono_string_to_utf8(str));
@@ -270,70 +326,100 @@ static MonoString *PD_SymEval(t_symbol *sym)
return mono_string_new(monodomain,sym->s_name);
}
-static void PD_AddBang(MonoObject *method)
+static void PD_AddMethodHandler(int inlet,t_symbol *sym,MonoObject *method,Delegate::Kind kind)
{
assert(clr_setup_class);
- Delegate &d = clr_setup_class->method_bang;
+ Delegate d;
d.methodinfo = mono_property_get_value(clr_prop_method,method,NULL,NULL);
d.virtmethod = mono_object_get_virtual_method(d.methodinfo,clr_meth_invoke);
+ d.kind = kind;
+
+ ClrMethods *ms = clr_setup_class->methods;
+ if(!ms)
+ clr_setup_class->methods = ms = new ClrMethods;
+
+ ClrMethodMap *m;
+ if(inlet >= (int)ms->size()) {
+ ms->resize(inlet+1,NULL);
+ (*ms)[inlet] = m = new ClrMethodMap;
+ }
+ else
+ m = (*ms)[inlet];
+ assert(m);
+
+ // add tag to map
+ (*m)[sym] = d;
}
-static void PD_AddFloat(MonoObject *method)
+static void PD_AddMethodSelector(int inlet,t_symbol *sym,MonoObject *method)
{
- assert(clr_setup_class);
- Delegate &d = clr_setup_class->method_float;
- d.methodinfo = mono_property_get_value(clr_prop_method,method,NULL,NULL);
- d.virtmethod = mono_object_get_virtual_method(d.methodinfo,clr_meth_invoke);
+ PD_AddMethodHandler(inlet,sym,method,Delegate::k_anything);
}
-static void PD_AddSymbol(MonoObject *method)
+static void PD_AddMethodBang(int inlet,MonoObject *method)
{
- assert(clr_setup_class);
- Delegate &d = clr_setup_class->method_symbol;
- d.methodinfo = mono_property_get_value(clr_prop_method,method,NULL,NULL);
- d.virtmethod = mono_object_get_virtual_method(d.methodinfo,clr_meth_invoke);
+ if(inlet)
+ PD_AddMethodHandler(inlet,&s_bang,method,Delegate::k_bang);
+ else {
+ assert(clr_setup_class);
+ clr_setup_class->method_bang.init(method,Delegate::k_bang);
+ }
}
-static void PD_AddPointer(MonoObject *method)
+static void PD_AddMethodFloat(int inlet,MonoObject *method)
{
- assert(clr_setup_class);
- Delegate &d = clr_setup_class->method_pointer;
- d.methodinfo = mono_property_get_value(clr_prop_method,method,NULL,NULL);
- d.virtmethod = mono_object_get_virtual_method(d.methodinfo,clr_meth_invoke);
+ if(inlet)
+ PD_AddMethodHandler(inlet,&s_float,method,Delegate::k_float);
+ else {
+ assert(clr_setup_class);
+ clr_setup_class->method_float.init(method,Delegate::k_float);
+ }
}
-static void PD_AddList(MonoObject *method)
+static void PD_AddMethodSymbol(int inlet,MonoObject *method)
{
- assert(clr_setup_class);
- Delegate &d = clr_setup_class->method_list;
- d.methodinfo = mono_property_get_value(clr_prop_method,method,NULL,NULL);
- d.virtmethod = mono_object_get_virtual_method(d.methodinfo,clr_meth_invoke);
+ if(inlet)
+ PD_AddMethodHandler(inlet,&s_symbol,method,Delegate::k_symbol);
+ else {
+ assert(clr_setup_class);
+ clr_setup_class->method_symbol.init(method,Delegate::k_symbol);
+ }
}
-static void PD_AddSelector(t_symbol *sym,MonoObject *method)
+static void PD_AddMethodPointer(int inlet,MonoObject *method)
{
- assert(clr_setup_class);
- Delegate d;
- d.methodinfo = mono_property_get_value(clr_prop_method,method,NULL,NULL);
- d.virtmethod = mono_object_get_virtual_method(d.methodinfo,clr_meth_invoke);
+ if(inlet)
+ PD_AddMethodHandler(inlet,&s_pointer,method,Delegate::k_pointer);
+ else {
+ assert(clr_setup_class);
+ clr_setup_class->method_pointer.init(method,Delegate::k_pointer);
+ }
+}
- if(!clr_setup_class->methods)
- clr_setup_class->methods = new ClrMethodMap;
- // add tag to map
- (*clr_setup_class->methods)[sym] = d;
+static void PD_AddMethodList(int inlet,MonoObject *method)
+{
+ if(inlet)
+ PD_AddMethodHandler(inlet,&s_list,method,Delegate::k_list);
+ else {
+ assert(clr_setup_class);
+ clr_setup_class->method_list.init(method,Delegate::k_list);
+ }
}
-static void PD_AddAnything(MonoObject *method)
+static void PD_AddMethodAnything(int inlet,MonoObject *method)
{
- assert(clr_setup_class);
- Delegate &d = clr_setup_class->method_anything;
- d.methodinfo = mono_property_get_value(clr_prop_method,method,NULL,NULL);
- d.virtmethod = mono_object_get_virtual_method(d.methodinfo,clr_meth_invoke);
+ if(inlet)
+ PD_AddMethodHandler(inlet,NULL,method,Delegate::k_anything);
+ else {
+ assert(clr_setup_class);
+ clr_setup_class->method_anything.init(method,Delegate::k_anything);
+ }
}
-static void PD_AddInlet(t_clr *obj,t_symbol *sel,t_symbol *to_sel)
+static void PD_AddInletAlias(t_clr *obj,t_symbol *sel,t_symbol *to_sel)
{
+ ++clr_inlet;
assert(obj);
t_inlet *in = inlet_new(&obj->pd_obj,&obj->pd_obj.ob_pd,sel,to_sel);
assert(in);
@@ -341,6 +427,7 @@ static void PD_AddInlet(t_clr *obj,t_symbol *sel,t_symbol *to_sel)
static void PD_AddInletFloat(t_clr *obj,float *f)
{
+ ++clr_inlet;
assert(obj);
t_inlet *in = floatinlet_new(&obj->pd_obj,f);
assert(in);
@@ -348,6 +435,7 @@ static void PD_AddInletFloat(t_clr *obj,float *f)
static void PD_AddInletSymbol(t_clr *obj,t_symbol **s)
{
+ ++clr_inlet;
assert(obj);
t_inlet *in = symbolinlet_new(&obj->pd_obj,s);
assert(in);
@@ -356,18 +444,28 @@ static void PD_AddInletSymbol(t_clr *obj,t_symbol **s)
/*
static void PD_AddInletPointer(t_clr *obj,t_gpointer *p)
{
+ ++clr_inlet;
assert(obj);
t_inlet *in = pointerinlet_new(&obj->pd_obj,p);
assert(in);
}
*/
-static void PD_AddInletProxy(t_clr *obj)
+static void PD_AddInletProxyTyped(t_clr *obj,t_symbol *type)
{
assert(obj);
- // TODO implement
+ t_proxy *p = (t_proxy *)pd_new(proxy_class);
+ p->parent = obj;
+ p->inlet = ++clr_inlet;
+ if(!obj->proxies) obj->proxies = new ProxyList;
+ obj->proxies->push_back(p);
+ t_inlet *in = inlet_new(&obj->pd_obj,&p->pd_obj.ob_pd,type,type);
+ assert(in);
}
+static void PD_AddInletProxy(t_clr *obj) { PD_AddInletProxyTyped(obj,NULL); }
+
+
static void PD_AddOutlet(t_clr *obj,t_symbol *type)
{
assert(obj);
@@ -381,7 +479,7 @@ static void PD_OutletBang(t_clr *obj,int n)
{
assert(obj);
assert(obj->outlets);
- assert(n >= 0 && n < obj->outlets->size());
+ assert(n >= 0 && n < (int)obj->outlets->size());
outlet_bang((*obj->outlets)[n]);
}
@@ -389,7 +487,7 @@ static void PD_OutletFloat(t_clr *obj,int n,float f)
{
assert(obj);
assert(obj->outlets);
- assert(n >= 0 && n < obj->outlets->size());
+ assert(n >= 0 && n < (int)obj->outlets->size());
outlet_float((*obj->outlets)[n],f);
}
@@ -397,7 +495,7 @@ static void PD_OutletSymbol(t_clr *obj,int n,t_symbol *s)
{
assert(obj);
assert(obj->outlets);
- assert(n >= 0 && n < obj->outlets->size());
+ assert(n >= 0 && n < (int)obj->outlets->size());
outlet_symbol((*obj->outlets)[n],s);
}
@@ -405,7 +503,7 @@ static void PD_OutletPointer(t_clr *obj,int n,t_gpointer *p)
{
assert(obj);
assert(obj->outlets);
- assert(n >= 0 && n < obj->outlets->size());
+ assert(n >= 0 && n < (int)obj->outlets->size());
outlet_pointer((*obj->outlets)[n],p);
}
@@ -413,7 +511,7 @@ static void PD_OutletAtom(t_clr *obj,int n,t_atom l)
{
assert(obj);
assert(obj->outlets);
- assert(n >= 0 && n < obj->outlets->size());
+ assert(n >= 0 && n < (int)obj->outlets->size());
t_outlet *out = (*obj->outlets)[n];
switch(l.a_type) {
case A_FLOAT: outlet_float(out,l.a_w.w_float); break;
@@ -428,7 +526,7 @@ static void PD_OutletAnything(t_clr *obj,int n,t_symbol *s,AtomList l)
{
assert(obj);
assert(obj->outlets);
- assert(n >= 0 && n < obj->outlets->size());
+ assert(n >= 0 && n < (int)obj->outlets->size());
outlet_anything((*obj->outlets)[n],s,l.argc,l.argv);
}
@@ -436,7 +534,7 @@ static void PD_OutletAnything2(t_clr *obj,int n,t_symbol *s,MonoArray *l)
{
assert(obj);
assert(obj->outlets);
- assert(n >= 0 && n < obj->outlets->size());
+ assert(n >= 0 && n < (int)obj->outlets->size());
// 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));
}
@@ -463,6 +561,7 @@ static void PD_SendAnything2(t_symbol *dst,t_symbol *s,MonoArray *l)
void *clr_new(t_symbol *classname, int argc, t_atom *argv)
{
// find class name in map
+
ClrMap::iterator it = clr_map.find(classname);
if(it == clr_map.end()) {
error("CLR class %s not found",classname->s_name);
@@ -488,10 +587,14 @@ void *clr_new(t_symbol *classname, int argc, t_atom *argv)
mono_field_set_value(x->mono_obj,clss->obj_field,x);
x->outlets = NULL;
+ x->proxies = NULL;
// ok, we have an object - look for constructor
if(clss->mono_ctor) {
- AtomList al;
+ // reset inlet index
+ clr_inlet = 0;
+
+ AtomList al;
al.Set(argc,argv);
gpointer args = &al;
@@ -511,9 +614,14 @@ void *clr_new(t_symbol *classname, int argc, t_atom *argv)
return x;
}
-void clr_free(t_clr *x)
+void clr_free(t_clr *obj)
{
- if(x->outlets) delete x->outlets;
+ if(obj->outlets) delete obj->outlets;
+
+ if(obj->proxies) {
+ for(ProxyList::iterator it = obj->proxies->begin(); it != obj->proxies->end(); ++it) pd_free((t_pd *)*it);
+ delete obj->proxies;
+ }
}
static int classloader(char *dirname, char *classname)
@@ -613,7 +721,7 @@ static int classloader(char *dirname, char *classname)
// make pd class
clr_class->pd_class = class_new(classsym,(t_newmethod)clr_new,(t_method)clr_free, sizeof(t_clr), flags, A_GIMME, A_NULL);
- // find && register methods
+ // register methods
if(clr_class->method_bang)
class_addbang(clr_class->pd_class,clr_method_bang);
if(clr_class->method_float)
@@ -698,21 +806,21 @@ void clr_setup(void)
mono_add_internal_call("PureData.External::Post(string)",(const void *)PD_Post);
mono_add_internal_call("PureData.External::PostError(string)",(const void *)PD_PostError);
- mono_add_internal_call("PureData.External::PostBug(string)",(const void *)PD_PostBug);
- mono_add_internal_call("PureData.External::PostVerbose(string)",(const void *)PD_PostVerbose);
-
- mono_add_internal_call("PureData.External::Add(PureData.External/MethodBang)", (const void *)PD_AddBang);
- mono_add_internal_call("PureData.External::Add(PureData.External/MethodFloat)", (const void *)PD_AddFloat);
- mono_add_internal_call("PureData.External::Add(PureData.External/MethodSymbol)", (const void *)PD_AddSymbol);
- mono_add_internal_call("PureData.External::Add(PureData.External/MethodPointer)", (const void *)PD_AddPointer);
- mono_add_internal_call("PureData.External::Add(PureData.External/MethodList)", (const void *)PD_AddList);
- 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.External::PostVerbose(int,string)",(const void *)PD_PostVerbose);
+
+ mono_add_internal_call("PureData.External::AddMethod(int,PureData.External/MethodBang)", (const void *)PD_AddMethodBang);
+ mono_add_internal_call("PureData.External::AddMethod(int,PureData.External/MethodFloat)", (const void *)PD_AddMethodFloat);
+ mono_add_internal_call("PureData.External::AddMethod(int,PureData.External/MethodSymbol)", (const void *)PD_AddMethodSymbol);
+ mono_add_internal_call("PureData.External::AddMethod(int,PureData.External/MethodPointer)", (const void *)PD_AddMethodPointer);
+ mono_add_internal_call("PureData.External::AddMethod(int,PureData.External/MethodList)", (const void *)PD_AddMethodList);
+ mono_add_internal_call("PureData.External::AddMethod(int,PureData.Symbol,PureData.External/MethodAnything)", (const void *)PD_AddMethodSelector);
+ mono_add_internal_call("PureData.External::AddMethod(int,PureData.External/MethodAnything)", (const void *)PD_AddMethodAnything);
+
+ mono_add_internal_call("PureData.Internal::AddInlet(void*,PureData.Symbol,PureData.Symbol)", (const void *)PD_AddInletAlias);
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*,PureData.Symbol)", (const void *)PD_AddInletTyped);
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);
@@ -759,17 +867,23 @@ void clr_setup(void)
// static objects to avoid allocation at method call time
clr_objarr_1 = mono_array_new(monodomain,mono_get_object_class(),1);
- clr_objarr_2 = mono_array_new(monodomain,mono_get_object_class(),2);
+ clr_objarr_3 = mono_array_new(monodomain,mono_get_object_class(),3);
+ clr_obj_int = mono_object_new(monodomain,mono_get_int32_class());
clr_obj_single = mono_object_new(monodomain,mono_get_single_class());
clr_obj_symbol = mono_object_new(monodomain,clr_symbol);
clr_obj_pointer = mono_object_new(monodomain,clr_pointer);
clr_obj_atomlist = mono_object_new(monodomain,clr_atomlist);
// unboxed addresses
+ clr_val_int = (int *)mono_object_unbox(clr_obj_int);
clr_val_single = (float *)mono_object_unbox(clr_obj_single);
clr_val_symbol = (t_symbol **)mono_object_unbox(clr_obj_symbol);
clr_val_pointer = (void **)mono_object_unbox(clr_obj_pointer);
clr_val_atomlist = (AtomList *)mono_object_unbox(clr_obj_atomlist);
+ // make proxy class
+ proxy_class = class_new(gensym("clr proxy"),NULL,NULL,sizeof(t_proxy),CLASS_PD|CLASS_NOINLET,A_NULL);
+ class_addanything(proxy_class,clr_method_proxy);
+
// install loader hook
sys_loader(classloader);
diff --git a/test-clr.pd b/test-clr.pd
index 75721bc..653f984 100755
--- a/test-clr.pd
+++ b/test-clr.pd
@@ -1,4 +1,4 @@
-#N canvas 617 153 818 585 12;
+#N canvas 617 153 842 609 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;
@@ -23,7 +23,14 @@
#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 floatatom 526 362 5 0 0 0 - - -;
+#X symbolatom 578 364 10 0 0 0 - - -;
+#X text 585 318 passive - bang to see;
+#X text 676 366 active;
+#X msg 526 386 1 2 3;
+#X floatatom 528 275 5 0 0 0 - - -;
+#X msg 589 386 turalu;
+#X msg 578 274 heyho;
#X connect 0 0 3 0;
#X connect 1 0 3 0;
#X connect 2 0 3 0;
@@ -44,3 +51,9 @@
#X connect 18 0 3 0;
#X connect 20 0 19 0;
#X connect 21 0 22 0;
+#X connect 23 0 3 3;
+#X connect 24 0 3 3;
+#X connect 27 0 3 3;
+#X connect 28 0 3 1;
+#X connect 29 0 3 3;
+#X connect 30 0 3 1;