aboutsummaryrefslogtreecommitdiff
path: root/PureData/PureData.cs
diff options
context:
space:
mode:
Diffstat (limited to 'PureData/PureData.cs')
-rw-r--r--PureData/PureData.cs666
1 files changed, 547 insertions, 119 deletions
diff --git a/PureData/PureData.cs b/PureData/PureData.cs
index 4df716e..0174317 100644
--- a/PureData/PureData.cs
+++ b/PureData/PureData.cs
@@ -1,203 +1,637 @@
using System;
using System.Runtime.CompilerServices; // for extern import
using System.Runtime.InteropServices; // for structures
+using System.Reflection;
+using System.Collections;
namespace PureData
{
+ [StructLayout(LayoutKind.Sequential)]
+ internal struct ClassPtr
+ {
+ private IntPtr ptr;
+
+ public void Clear() { ptr = IntPtr.Zero; }
+ public bool Valid() { return ptr != IntPtr.Zero; }
+
+ public override string ToString() { return ptr.ToString(); }
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ internal struct ExternalPtr
+ {
+ private IntPtr ptr;
+
+ public void Clear() { ptr = IntPtr.Zero; }
+ public bool Valid() { return ptr != IntPtr.Zero; }
+
+ public override string ToString() { return ptr.ToString(); }
+ }
+
+ // data passed from/to native side
+ [StructLayout(LayoutKind.Sequential)]
+ internal class PassedData
+ {
+ public Class klass;
+ public External ext;
+ public object obj;
+ }
+
// PD core functions
- public unsafe class Internal
+ public class Internal
{
- [MethodImplAttribute (MethodImplOptions.InternalCall)]
- internal extern static void *SymGen(string sym);
+ // the ExternalPtr when initializing an External instance
+ internal static ExternalPtr extptr;
- [MethodImplAttribute (MethodImplOptions.InternalCall)]
- internal extern static string SymEval(void *sym);
+ internal static PassedData pass;
// --------------------------------------------------------------------------
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ internal extern static Symbol SymGen(string sym);
+
[MethodImplAttribute (MethodImplOptions.InternalCall)]
- internal extern static void AddInlet(void *obj,Symbol sel,Symbol to_sel);
+ internal extern static string SymEval(Symbol sym);
+
+ // --------------------------------------------------------------------------
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ internal extern static void AddInlet(ExternalPtr obj, Symbol sel, Symbol to_sel);
// map to data member
- [MethodImplAttribute (MethodImplOptions.InternalCall)]
- internal extern static void AddInlet(void *obj,ref float f);
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ internal extern static void AddInlet(ExternalPtr obj, ref float f);
// map to data member
- [MethodImplAttribute (MethodImplOptions.InternalCall)]
- internal extern static void AddInlet(void *obj,ref Symbol s);
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ internal extern static void AddInlet(ExternalPtr obj, ref Symbol s);
// map to data member
-// [MethodImplAttribute (MethodImplOptions.InternalCall)]
-// internal extern static void AddInlet(void *obj,ref Pointer f);
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ internal extern static void AddInlet(ExternalPtr obj,ref Pointer f);
- [MethodImplAttribute (MethodImplOptions.InternalCall)]
- internal extern static void AddInlet(void *obj,Symbol type); // create proxy inlet (typed)
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ internal extern static void AddInlet(ExternalPtr 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 AddInlet(ExternalPtr obj); // create proxy inlet (anything)
// --------------------------------------------------------------------------
- [MethodImplAttribute (MethodImplOptions.InternalCall)]
- internal extern static void AddOutlet(void *obj,Symbol type);
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ internal extern static void AddOutlet(ExternalPtr 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(ExternalPtr obj, int n);
[MethodImplAttribute (MethodImplOptions.InternalCall)]
- internal extern static void Outlet(void *obj,int n,Symbol s);
+ internal extern static void Outlet(ExternalPtr obj, int n, float f);
[MethodImplAttribute (MethodImplOptions.InternalCall)]
- internal extern static void Outlet(void *obj,int n,Pointer p);
+ internal extern static void Outlet(ExternalPtr obj, int n, Symbol s);
[MethodImplAttribute (MethodImplOptions.InternalCall)]
- internal extern static void Outlet(void *obj,int n,Atom a);
+ internal extern static void Outlet(ExternalPtr obj, int n, Pointer p);
[MethodImplAttribute (MethodImplOptions.InternalCall)]
- internal extern static void Outlet(void *obj,int n,Symbol s,AtomList l);
+ internal extern static void Outlet(ExternalPtr obj, int n, Atom a);
[MethodImplAttribute (MethodImplOptions.InternalCall)]
- internal extern static void Outlet(void *obj,int n,Symbol s,Atom[] l);
+ internal extern static void Outlet(ExternalPtr obj, int n, Symbol s, Atom[] l);
[MethodImplAttribute (MethodImplOptions.InternalCall)]
- internal extern static void OutletEx(void *obj,int n,object o);
+ internal extern static void OutletEx(ExternalPtr obj, int n, object o);
// --------------------------------------------------------------------------
[MethodImplAttribute (MethodImplOptions.InternalCall)]
- internal extern static void Bind(void *obj,Symbol dst);
+ internal extern static void Bind(ExternalPtr obj, Symbol dst);
[MethodImplAttribute (MethodImplOptions.InternalCall)]
- internal extern static void Unbind(void *obj,Symbol dst);
+ internal extern static void Unbind(ExternalPtr obj, Symbol dst);
}
-
- // This is the base class for a PD/CLR external
- public unsafe abstract class External
- {
- // PD object pointer
- private readonly void *ptr;
+
+ public abstract class Public
+ : Internal
+ {
// to be returned by Setup function
- protected enum ClassType { Default = 0,PD = 1,GObj = 2,Patchable = 3,NoInlet = 8 }
+ protected enum ClassType { Default = 0, PD = 1, GObj = 2, Patchable = 3, NoInlet = 8 }
// --------------------------------------------------------------------------
- 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");
+ public delegate void MethodBang();
+ public delegate void MethodFloat(float f);
+ public delegate void MethodSymbol(Symbol s);
+ public delegate void MethodPointer(Pointer p);
+ public delegate void MethodList(Atom[] lst);
+ public delegate void MethodAnything(int inlet, Symbol tag, Atom[] lst);
+ public delegate void MethodObject(int inlet, object o);
// --------------------------------------------------------------------------
- [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);
-
- 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(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)); }
+ public readonly static Symbol _ = new Symbol("");
+ public readonly static Symbol _bang = new Symbol("bang");
+ public readonly static Symbol _float = new Symbol("float");
+ public readonly static Symbol _symbol = new Symbol("symbol");
+ public readonly static Symbol _pointer = new Symbol("pointer");
+ public readonly static Symbol _list = new Symbol("list");
// --------------------------------------------------------------------------
- protected delegate void Method();
- protected delegate void MethodFloat(float f);
- protected delegate void MethodSymbol(Symbol s);
- protected delegate void MethodPointer(Pointer p);
- protected delegate void MethodList(AtomList lst);
- protected delegate void MethodAnything(int inlet,Symbol tag,AtomList lst);
- protected delegate void MethodObject(int inlet,object o);
+ [MethodImplAttribute (MethodImplOptions.InternalCall)]
+ public extern static void Post(string message);
- // --------------------------------------------------------------------------
+ public static void Post(string format, object arg0) { Post(String.Format(format, arg0)); }
+ public static void Post(string format, object arg0, object arg1) { Post(String.Format(format, arg0, arg1)); }
+ public static void Post(string format, object arg0, object arg1, object arg2) { Post(String.Format(format, arg0, arg1, arg2)); }
+ public static void Post(string format, params object[] args) { Post(String.Format(format, args)); }
[MethodImplAttribute (MethodImplOptions.InternalCall)]
- protected extern static void AddMethod(int inlet,Method m);
+ public extern static void PostError(string message);
- [MethodImplAttribute (MethodImplOptions.InternalCall)]
- protected extern static void AddMethod(int inlet,MethodFloat m);
+ public static void PostError(string format, object arg0) { PostError(String.Format(format, arg0)); }
+ public static void PostError(string format, object arg0, object arg1) { PostError(String.Format(format, arg0, arg1)); }
+ public static void PostError(string format, object arg0, object arg1, object arg2) { PostError(String.Format(format, arg0, arg1, arg2)); }
+ public static void PostError(string format, params object[] args) { PostError(String.Format(format, args)); }
[MethodImplAttribute (MethodImplOptions.InternalCall)]
- protected extern static void AddMethod(int inlet,MethodSymbol m);
+ public extern static void PostVerbose(int lvl, string message);
- [MethodImplAttribute (MethodImplOptions.InternalCall)]
- protected extern static void AddMethod(int inlet,MethodPointer m);
+ public static void PostVerbose(int lvl, string format, object arg0) { PostVerbose(lvl, String.Format(format, arg0)); }
+ public static void PostVerbose(int lvl, string format, object arg0, object arg1) { PostVerbose(lvl, String.Format(format, arg0, arg1)); }
+ public static void PostVerbose(int lvl, string format, object arg0, object arg1, object arg2) { PostVerbose(lvl, String.Format(format, arg0, arg1, arg2)); }
+ public static void PostVerbose(int lvl, string format, params object[] args) { PostVerbose(lvl, String.Format(format, args)); }
- [MethodImplAttribute (MethodImplOptions.InternalCall)]
- protected extern static void AddMethod(int inlet,MethodList m);
+ // --------------------------------------------------------------------------
- [MethodImplAttribute (MethodImplOptions.InternalCall)]
- protected extern static void AddMethod(int inlet,MethodAnything m);
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ public extern static string SearchPath(string file);
+ }
- [MethodImplAttribute (MethodImplOptions.InternalCall)]
- protected extern static void AddMethod(int inlet,Symbol sel,Method m);
- [MethodImplAttribute (MethodImplOptions.InternalCall)]
- protected extern static void AddMethod(int inlet,Symbol sel,MethodFloat m);
+ public sealed class Class
+ : Public
+ {
+ // PD class pointer
+ private readonly ClassPtr ptr;
+
+ // class type
+ private Type extclass;
+
+ // --------------------------------------------------------------------------
+
+ // simple methods for inlet 0
+ private DynamicMethodBang m_bang = null;
+ private DynamicMethodFloat m_float = null;
+ private DynamicMethodSymbol m_symbol = null;
+ private DynamicMethodPointer m_pointer = null;
+ private DynamicMethodList m_list = null;
+ private DynamicMethodAnything m_anything = null;
+ private DynamicMethodObject m_object = null;
+
+ // --------------------------------------------------------------------------
+
+ private static void ResizeArray(ref Hashtable[] oldArray, int newSize)
+ {
+ int oldSize = oldArray.Length;
+ System.Type elementType = oldArray.GetType().GetElementType();
+ Hashtable[] newArray = (Hashtable[])System.Array.CreateInstance(elementType, newSize);
+ int preserveLength = System.Math.Min(oldSize, newSize);
+ if (preserveLength > 0)
+ System.Array.Copy(oldArray, newArray, preserveLength);
+ oldArray = newArray;
+ }
+
+ private struct MapValue
+ {
+ public MapValue(Kind k,Delegate d) { this.k = k; this.d = d; }
+
+ public Kind k;
+ public Delegate d;
+ }
+
+ private Hashtable[] m_map = new Hashtable[0];
+
+ // --------------------------------------------------------------------------
+
+ public override string ToString()
+ {
+ return extclass.Name;
+ }
+
+ // --------------------------------------------------------------------------
+
+ private enum Kind { k_bang, k_float, k_symbol, k_pointer, k_list, k_anything, k_object }
+
+ private enum MethodFlags { f_none = 0,f_bang = 0x01, f_float = 0x02, f_symbol = 0x04, f_pointer = 0x08, f_list = 0x10, f_anything = 0x20 }
+
+ private static MethodFlags methodflags;
+
+
+ // --------------------------------------------------------------------------
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ private extern static bool RegisterClass(ClassPtr ptr, Symbol sym, ClassType cflags, MethodFlags mflags);
+
+ private void AddMethodIntern(int inlet, Symbol sel, Kind k, Delegate d)
+ {
+ // add to map
+ if (m_map.Length <= inlet) ResizeArray(ref m_map, inlet + 1);
+ Hashtable h = m_map[inlet];
+ if(h == null) m_map[inlet] = h = new Hashtable();
+ h[sel] = new MapValue(k, d);
+
+ methodflags |= MethodFlags.f_anything;
+ }
+
+ public void AddMethod(int inlet, Symbol sel, MethodBang d)
+ {
+ DynamicMethodBang dyn = DynamicMethods.Create(d);
+ if (inlet == 0 && sel == _bang)
+ {
+ m_bang = dyn;
+ methodflags |= MethodFlags.f_bang;
+ }
+ else
+ AddMethodIntern(inlet, sel, Kind.k_bang, dyn);
+ }
+
+ public void AddMethod(int inlet, Symbol sel, MethodFloat d)
+ {
+ DynamicMethodFloat dyn = DynamicMethods.Create(d);
+ if (inlet == 0 && sel == _float)
+ {
+ m_float = dyn;
+ methodflags |= MethodFlags.f_float;
+ }
+ else
+ AddMethodIntern(inlet, sel, Kind.k_float, dyn);
+ }
+
+ public void AddMethod(int inlet, Symbol sel, MethodSymbol d)
+ {
+ DynamicMethodSymbol dyn = DynamicMethods.Create(d);
+ if (inlet == 0 && sel == _symbol)
+ {
+ m_symbol = dyn;
+ methodflags |= MethodFlags.f_symbol;
+ }
+ else
+ AddMethodIntern(inlet, sel, Kind.k_symbol, dyn);
+ }
+
+ public void AddMethod(int inlet, Symbol sel, MethodPointer d)
+ {
+ DynamicMethodPointer dyn = DynamicMethods.Create(d);
+ if (inlet == 0 && sel == _pointer)
+ {
+ m_pointer = dyn;
+ methodflags |= MethodFlags.f_pointer;
+ }
+ else
+ AddMethodIntern(inlet, sel, Kind.k_pointer, dyn);
+ }
+
+ public void AddMethod(int inlet, Symbol sel, MethodList d)
+ {
+ DynamicMethodList dyn = DynamicMethods.Create(d);
+ if (inlet == 0 && sel == _list)
+ {
+ m_list = dyn;
+ methodflags |= MethodFlags.f_list;
+ }
+ else
+ AddMethodIntern(inlet, sel, Kind.k_list, dyn);
+ }
+
+ public void AddMethod(int inlet, Symbol sel, MethodAnything d)
+ {
+ DynamicMethodAnything dyn = DynamicMethods.Create(d);
+ if (inlet == 0 && sel == _)
+ {
+ m_anything = dyn;
+ methodflags |= MethodFlags.f_anything;
+ }
+ else
+ AddMethodIntern(inlet, sel, Kind.k_anything, dyn);
+ }
+
+ public void AddMethod(int inlet, MethodObject d)
+ {
+ DynamicMethodObject dyn = DynamicMethods.Create(d);
+ m_object = dyn;
+ methodflags |= MethodFlags.f_anything;
+ }
+
+ // --------------------------------------------------------------------------
+
+ private Class(ClassPtr p,Type c)
+ {
+ ptr = p;
+ extclass = c;
+ }
+
+ private delegate void DelegateClass(ClassPtr ptr, Symbol sym);
+ private static void NewClass(ClassPtr ptr, Symbol sym)
+ {
+ Internal.pass.klass = null;
+
+ try
+ {
+ string name = sym.ToString();
+
+ // load assembly according to name
+ string file = SearchPath(name + ".dll");
+ if (file.Length == 0) return; // throw new ArgumentException("Assembly file " + name + " not found");
+ Assembly assembly = Assembly.LoadFile(file);
+ if (assembly == null) return; // throw new ArgumentException("Assembly " + name + " could not be loaded");
+ Type exttp = assembly.GetType(name);
+ if (exttp == null) throw new ArgumentException("Class " + name + " could not be found");
+
+ Class klass = new Class(ptr, exttp);
+
+ // create dummy external
+ ConstructorInfo ctor = exttp.GetConstructor(System.Type.EmptyTypes);
+ if (ctor == null) throw new MissingMethodException("External class must have a default constructor");
+
+ Internal.pass.klass = klass;
+ Internal.extptr.Clear();
+
+ External dummy = (External)ctor.Invoke(null);
+
+ // reset flags
+ methodflags = MethodFlags.f_none;
+
+ // call Setup method
+ MethodInfo setup = exttp.GetMethod("Setup",BindingFlags.NonPublic|BindingFlags.Static,null, new Type[1] { exttp },null);
+ if (setup == null) throw new MissingMethodException("External class must have a Setup function");
+
+ object ret = setup.Invoke(exttp, new object[1] { dummy });
+ ClassType classflags;
+ try { classflags = (ClassType)ret; }
+ catch { classflags = ClassType.Default; }
+
+ // set callbacks
+ RegisterClass(ptr, sym, classflags, methodflags);
+ }
+ catch (Exception exc)
+ {
+ Internal.pass.klass = null;
+ PostError(exc.ToString());
+ }
+ }
+
+ private delegate void DelegateNew(ExternalPtr ptr,AtomList args);
+ private static void NewInstance(ExternalPtr ptr,AtomList args)
+ {
+ External instance;
+
+ Class cl = Internal.pass.klass; // set by native side
+ Internal.extptr = ptr;
+
+// Post("CLASS-NEW {0}",cl);
+ try
+ {
+ // TODO: create dynamic delegate for that....
+ System.Reflection.ConstructorInfo m = cl.extclass.GetConstructor(new Type[1] { typeof(Atom[]) });
+ if (m != null)
+ instance = (External)m.Invoke(new object[1] { (Atom[])args });
+ else
+ {
+ // search for the argument-less constructor... it must exist, we searched before
+ m = cl.extclass.GetConstructor(System.Type.EmptyTypes);
+ instance = (External)m.Invoke(null);
+ }
+ }
+ catch (Exception exc)
+ {
+ instance = null;
+ PostError(exc.ToString());
+ }
+
+#if DEBUG
+ Internal.extptr.Clear();
+#endif
+
+ Internal.pass.ext = instance; // back to native
+ }
+
+ private delegate void DelegateBang();
+ private static void CallBang()
+ {
+ External e = Internal.pass.ext;
+ try { e.klass.m_bang(e); }
+ catch (Exception exc) { PostError(exc.ToString()); }
+ }
+
+ private delegate void DelegateFloat(float f);
+ private static void CallFloat(float f)
+ {
+ External e = Internal.pass.ext;
+ try { e.klass.m_float(e, f); }
+ catch (Exception exc) { PostError(exc.ToString()); }
+ }
+
+ private delegate void DelegateSymbol(Symbol s);
+ private static void CallSymbol(Symbol s)
+ {
+ External e = Internal.pass.ext;
+ try { e.klass.m_symbol(e, s); }
+ catch (Exception exc) { PostError(exc.ToString()); }
+ }
+
+ private delegate void DelegatePointer(Pointer p);
+ private static void CallPointer(Pointer p)
+ {
+ External e = Internal.pass.ext;
+ try { e.klass.m_pointer(e, p); }
+ catch (Exception exc) { PostError(exc.ToString()); }
+ }
+
+ private delegate void DelegateList(AtomList l);
+ private static void CallList(AtomList l)
+ {
+ External e = Internal.pass.ext;
+ try { e.klass.m_list(e, (Atom[])l); }
+ catch (Exception exc) { PostError(exc.ToString()); }
+ }
+
+ private delegate void DelegateAnything(int inlet, Symbol s, AtomList l);
+ private static void CallAnything(int inlet, Symbol s, AtomList l)
+ {
+// Post("CLASS-ANYTHING {0}->{1}:{2}", inlet,s,l);
+
+ try {
+ External e = Internal.pass.ext;
+ Class c = e.klass;
+
+ Hashtable h;
+ try { h = (Hashtable)c.m_map[inlet]; }
+ catch (IndexOutOfRangeException) { h = null; }
+
+ if(h != null)
+ {
+ object fnd = h[s];
+ if (fnd != null)
+ {
+ MapValue mv = (MapValue)fnd;
+ switch(mv.k)
+ {
+ case Kind.k_bang:
+ {
+ ((DynamicMethodBang)mv.d)(e);
+ return;
+ }
+ case Kind.k_float:
+ {
+ float f = l.Count > 0 ? (float)l[0] : 0;
+ ((DynamicMethodFloat)mv.d)(e, f);
+ return;
+ }
+ case Kind.k_symbol:
+ {
+ Symbol sym = l.Count > 0 ? (Symbol)l[0] : _;
+ ((DynamicMethodSymbol)mv.d)(e, sym);
+ return;
+ }
+ case Kind.k_pointer:
+ {
+ Pointer p = l.Count > 0 ? (Pointer)l[0] : new Pointer();
+ ((DynamicMethodPointer)mv.d)(e, p);
+ return;
+ }
+ case Kind.k_list:
+ ((DynamicMethodList)mv.d)(e,(Atom[])l);
+ return;
+ case Kind.k_anything:
+ ((DynamicMethodAnything)mv.d)(e,inlet,s,(Atom[])l);
+ return;
+ default:
+ throw new NotImplementedException("Selector " + s.ToString() + " not handled");
+ }
+ }
+ }
+
+ // no explicit method found...
+ c.m_anything(e, inlet, s, (Atom[])l);
+ }
+ catch (Exception exc) { PostError(exc.ToString()); }
+ }
+
+ private delegate void DelegateObject(int inlet);
+ private static void CallObject(int inlet)
+ {
+// Post("CLASS-OBJECT {0}", inlet);
+
+ External e = Internal.pass.ext;
+ try { e.klass.m_object(e, inlet, Internal.pass.obj); }
+ catch (Exception exc) { PostError(exc.ToString()); }
+ }
+
+ // --------------------------------------------------------------------------
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ private extern static void Register(DelegateClass d_class, DelegateNew d_new, DelegateBang d_bang, DelegateFloat d_float, DelegateSymbol d_symbol, DelegatePointer d_pointer, DelegateList d_list, DelegateAnything d_anything, DelegateObject d_object);
+
+ private static void Setup()
+ {
+ try
+ {
+ Internal.pass = new PassedData();
+
+ Register(
+ new DelegateClass(NewClass),
+ new DelegateNew(NewInstance),
+ new DelegateBang(CallBang),
+ new DelegateFloat(CallFloat),
+ new DelegateSymbol(CallSymbol),
+ new DelegatePointer(CallPointer),
+ new DelegateList(CallList),
+ new DelegateAnything(CallAnything),
+ new DelegateObject(CallObject)
+ );
+ }
+ catch (Exception exc) { PostError(exc.ToString()); }
+ }
+ }
- [MethodImplAttribute (MethodImplOptions.InternalCall)]
- protected extern static void AddMethod(int inlet,Symbol sel,MethodSymbol m);
+
+ // This is the base class for a PD/CLR external
+ public abstract class External
+ : Public
+ {
+ // PD object pointer
+ internal readonly ExternalPtr ptr;
+ // Class
+ internal readonly Class klass;
- [MethodImplAttribute (MethodImplOptions.InternalCall)]
- protected extern static void AddMethod(int inlet,Symbol sel,MethodPointer m);
+ // --------------------------------------------------------------------------
- [MethodImplAttribute (MethodImplOptions.InternalCall)]
- protected extern static void AddMethod(int inlet,Symbol sel,MethodList m);
+ protected External()
+ {
+ ptr = Internal.extptr;
+ klass = Internal.pass.klass;
+ }
- [MethodImplAttribute (MethodImplOptions.InternalCall)]
- protected extern static void AddMethod(int inlet,Symbol sel,MethodAnything m);
+ public override string ToString()
+ {
+ return ptr.Valid()?klass.ToString():"???";
+ }
- protected static void AddMethod(int inlet,string sel,Method m) { AddMethod(inlet,new Symbol(sel),m); }
- protected static void AddMethod(int inlet,string sel,MethodFloat m) { AddMethod(inlet,new Symbol(sel),m); }
- protected static void AddMethod(int inlet,string sel,MethodSymbol m) { AddMethod(inlet,new Symbol(sel),m); }
- protected static void AddMethod(int inlet,string sel,MethodPointer m) { AddMethod(inlet,new Symbol(sel),m); }
- protected static void AddMethod(int inlet,string sel,MethodList m) { AddMethod(inlet,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 AddMethod(int inlet,MethodObject m);
+ protected static void AddMethod(int inlet, Symbol sel, MethodBang m) { ((External)m.Target).klass.AddMethod(inlet, sel, m); }
+ protected static void AddMethod(int inlet, Symbol sel, MethodFloat m) { ((External)m.Target).klass.AddMethod(inlet, sel, m); }
+ protected static void AddMethod(int inlet, Symbol sel, MethodSymbol m) { ((External)m.Target).klass.AddMethod(inlet, sel, m); }
+ protected static void AddMethod(int inlet, Symbol sel, MethodPointer m) { ((External)m.Target).klass.AddMethod(inlet, sel, m); }
+ protected static void AddMethod(int inlet, Symbol sel, MethodList m) { ((External)m.Target).klass.AddMethod(inlet, sel, m); }
+ protected static void AddMethod(int inlet, Symbol sel, MethodAnything m) { ((External)m.Target).klass.AddMethod(inlet, sel, m); }
+ protected static void AddMethod(int inlet, MethodObject m) { ((External)m.Target).klass.AddMethod(inlet, m); }
+
+ protected static void AddMethod(int inlet, MethodBang m) { AddMethod(inlet, _bang, m); }
+ protected static void AddMethod(int inlet, MethodFloat m) { AddMethod(inlet, _float, m); }
+ protected static void AddMethod(int inlet, MethodSymbol m) { AddMethod(inlet, _symbol, m); }
+ protected static void AddMethod(int inlet, MethodPointer m) { AddMethod(inlet, _pointer, m); }
+ protected static void AddMethod(int inlet, MethodList m) { AddMethod(inlet, _list, m); }
+ protected static void AddMethod(int inlet, MethodAnything m) { AddMethod(inlet, _, m); }
+
+ protected static void AddMethod(MethodBang m) { AddMethod(0, m); }
+ protected static void AddMethod(MethodFloat m) { AddMethod(0, m); }
+ protected static void AddMethod(MethodSymbol m) { AddMethod(0, m); }
+ protected static void AddMethod(MethodPointer m) { AddMethod(0, m); }
+ protected static void AddMethod(MethodList m) { AddMethod(0, m); }
+ protected static void AddMethod(MethodAnything m) { AddMethod(0, m); }
+ protected static void AddMethod(MethodObject m) { AddMethod(0, m); }
+
+ protected static void AddMethod(int inlet, string sel, MethodBang m) { AddMethod(inlet, new Symbol(sel), m); }
+ protected static void AddMethod(int inlet, string sel, MethodFloat m) { AddMethod(inlet, new Symbol(sel), m); }
+ protected static void AddMethod(int inlet, string sel, MethodSymbol m) { AddMethod(inlet, new Symbol(sel), m); }
+ protected static void AddMethod(int inlet, string sel, MethodPointer m) { AddMethod(inlet, new Symbol(sel), m); }
+ protected static void AddMethod(int inlet, string sel, MethodList m) { AddMethod(inlet, new Symbol(sel), m); }
+ protected static void AddMethod(int inlet, string sel, MethodAnything m) { AddMethod(inlet, new Symbol(sel), m); }
// --------------------------------------------------------------------------
- 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(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(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 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 AddOutlet(Symbol type) { Internal.AddOutlet(ptr, type); }
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); }
+ protected void AddOutletAnything() { AddOutlet(_); }
// --------------------------------------------------------------------------
@@ -206,9 +640,7 @@ 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,_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); }
protected void OutletEx(int n,object o) { Internal.OutletEx(ptr,n,o); }
@@ -223,17 +655,13 @@ namespace PureData
[MethodImplAttribute (MethodImplOptions.InternalCall)]
protected extern static void Send(Symbol sym,Atom a);
- protected static void Send(Symbol sym) { Send(sym,_bang,null); }
+ protected static void Send(Symbol sym) { Send(sym,_bang,new Atom[0]); }
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,_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);
-
- [MethodImplAttribute (MethodImplOptions.InternalCall)]
protected extern static void Send(Symbol sym,Symbol s,Atom[] l);
[MethodImplAttribute (MethodImplOptions.InternalCall)]