diff options
author | Thomas Grill <xovo@users.sourceforge.net> | 2006-03-06 00:35:40 +0000 |
---|---|---|
committer | Thomas Grill <xovo@users.sourceforge.net> | 2006-03-06 00:35:40 +0000 |
commit | fa95cabd64b0c49a6c3c6ba1bfdae27ab28ca755 (patch) | |
tree | f42248bb71bd4bd89e680d694d262e72be7157b9 /pd | |
parent | 2147d5f788d36ebccb7981c427b7e430b1e4e8cd (diff) |
many improvements:
- efficient symbol and atom list handling
- better control over function arguments
svn path=/trunk/externals/clr/; revision=4648
Diffstat (limited to 'pd')
-rwxr-xr-x | pd/Atom.cs | 282 | ||||
-rw-r--r-- | pd/PureData.cs | 18 | ||||
-rwxr-xr-x | pd/pd.csproj | 210 |
3 files changed, 339 insertions, 171 deletions
@@ -1,104 +1,270 @@ using System; using System.Runtime.InteropServices; // for structures +using System.Collections; +#if NET_2_0 +using System.Collections.Generic; +#endif namespace PureData { - public enum AtomType {Null = 0, Float = 1, Symbol = 2, Pointer = 3}; - [StructLayout (LayoutKind.Sequential)] - sealed public class Symbol + public unsafe struct Symbol { - // this should NOT be public - readonly private IntPtr ptr; - - public Symbol(IntPtr p) - { - ptr = p; - } - - public Symbol(Symbol s) - { - ptr = s.ptr; - } + // this should NOT be public (or at least read only) + private readonly void *sym; public Symbol(string s) { - ptr = Core.GenSym(s); + sym = Core.SymGen(s); } - - override public string ToString() + + public override string ToString() { - return Core.EvalSym(this); + return Core.SymEval(sym); } } [StructLayout (LayoutKind.Sequential)] - sealed public class Pointer + public unsafe struct Pointer { - public IntPtr ptr; - } + private readonly void *ptr; - [StructLayout (LayoutKind.Explicit)] - public struct Word - { - [FieldOffset(0)] public float w_float; - [FieldOffset(0)] public Symbol w_symbol; - [FieldOffset(0)] public Pointer w_pointer; + public override string ToString() + { + if(sizeof(void *) == 4) + return ((int)ptr).ToString(); + else + return ((long)ptr).ToString(); + } } - //[StructLayout (LayoutKind.Explicit)] [StructLayout (LayoutKind.Sequential)] - sealed public class Atom + public unsafe struct Atom { - - public AtomType type; - public Word word; + private enum AtomType {Null = 0, Float = 1, Symbol = 2, Pointer = 3}; + + [StructLayout (LayoutKind.Explicit)] + private struct Word + { + [FieldOffset(0)] public float w_float; + [FieldOffset(0)] public Symbol w_sym; + [FieldOffset(0)] public Pointer w_ptr; + } + + private AtomType type; + private Word word; public Atom(float f) { type = AtomType.Float; + word = new Word(); word.w_float = f; } public Atom(int i) { type = AtomType.Float; + word = new Word(); word.w_float = (float)i; } public Atom(Symbol s) { type = AtomType.Symbol; - word.w_symbol = s; + word = new Word(); + word.w_sym = s; } public Atom(string s) { type = AtomType.Symbol; - word.w_symbol = new Symbol(s); + word = new Word(); + word.w_sym = new Symbol(s); } - } - + + public Atom(Pointer p) + { + type = AtomType.Pointer; + word = new Word(); + word.w_ptr = p; + } + + public bool IsFloat { get { return type == AtomType.Float; } } + public bool IsSymbol { get { return type == AtomType.Symbol; } } + public bool IsPointer { get { return type == AtomType.Pointer; } } + + public float ToFloat() + { + if(IsFloat) + return word.w_float; + else + throw new System.InvalidCastException("Can't be cast to float."); + } + + public Symbol ToSymbol() + { + if(IsSymbol) + return word.w_sym; + else + throw new System.InvalidCastException("Can't be cast to Symbol."); + } + + public Pointer ToPointer() + { + if(IsPointer) + return word.w_ptr; + else + throw new System.InvalidCastException("Can't be cast to Pointer."); + } + + override public string ToString() + { + if(IsFloat) + return word.w_float.ToString(); + else if(IsSymbol) + return word.w_sym.ToString(); + else if(IsPointer) + return word.w_ptr.ToString(); + else + // should never happen + throw new System.InvalidProgramException("Internal error."); + } + + public static explicit operator float(Atom a) + { + return a.ToFloat(); + } + + public static explicit operator Symbol(Atom a) + { + return a.ToSymbol(); + } + + public static explicit operator Pointer(Atom a) + { + return a.ToPointer(); + } + } - // this struct is relative to this c struct, see clr.c + public class AtomListEnum + : IEnumerator + { + public AtomList list; - /* - // simplyfied atom - typedef struct atom_simple atom_simple; - typedef enum - { - A_S_NULL=0, - A_S_FLOAT=1, - A_S_SYMBOL=2, - } t_atomtype_simple; - typedef struct atom_simple - { - t_atomtype_simple a_type; - union{ - float float_value; - MonoString *string_value; - } stuff; - }; - */ - -}
\ No newline at end of file + // Enumerators are positioned before the first element + // until the first MoveNext() call. + int position = -1; + + public AtomListEnum(AtomList l) + { + list = l; + } + + public bool MoveNext() + { + return ++position < list.Count; + } + + public void Reset() + { + position = -1; + } + + public object Current + { + get + { + try + { + return list[position]; + } + catch (IndexOutOfRangeException) + { + throw new InvalidOperationException(); + } + } + } + } + + + // attention: this is dangerous, because we could do the following + // AtomList l2 = l; + // with l also being an AtomList... the two private memebers will get copied, although atoms is only a temporary reference + + [StructLayout (LayoutKind.Sequential)] + unsafe public struct AtomList +#if NET_2_0 + : ICollection<Atom> +#else + : ICollection +#endif + { + private readonly int len; + private readonly Atom *atoms; + + public int Count { get { return len; } } +#if NET_2_0 + public bool IsReadOnly { get { return false; } } // member of generic.ICollection<Atom> (C# 2.0) +#endif + public bool IsSynchronized { get { return false; } } + public Object SyncRoot { get { return null; } } + + // protect this from being used + private AtomList(AtomList a) { len = 0; atoms = null; } + +#if NET_2_0 + public void CopyTo(Atom[] array,int start) +#else + public void CopyTo(Array array,int start) +#endif + { + if(len > array.GetUpperBound(0)+1-start) + throw new System.ArgumentException("Destination array is not long enough."); + int i; + for(i = 0; i < len-start; ++i) + array.SetValue(atoms[start+i],i); + } + + public IEnumerator GetEnumerator() + { + return new AtomListEnum(this); + } + + public Atom this[int i] + { + get + { + if(i < 0 || i >= len) + throw new System.IndexOutOfRangeException("Index outside array bounds."); + return atoms[i]; + } + set + { + if(i < 0 || i >= len) + throw new System.IndexOutOfRangeException("Index outside array bounds."); + atoms[i] = value; + } + } + +#if !NET_2_0 + public static explicit operator Atom[](AtomList l) + { + Atom[] ret = new Atom[l.Count]; + int i; + for(i = 0; i < l.Count; ++i) ret[i] = l.atoms[i]; + return ret; + } +#endif + + override public string ToString() + { + string n = "{"; + if(len > 0) { + int i; + for(i = 0; i < len-1; ++i) n += atoms[i].ToString()+","; + n += atoms[i].ToString(); + } + return n+"}"; + } + } +} diff --git a/pd/PureData.cs b/pd/PureData.cs index 2d6cf16..70f3d98 100644 --- a/pd/PureData.cs +++ b/pd/PureData.cs @@ -1,10 +1,11 @@ using System; using System.Runtime.CompilerServices; // for extern import +using System.Runtime.InteropServices; // for structures namespace PureData { // PD core functions - public class Core + public unsafe class Core { [MethodImplAttribute (MethodImplOptions.InternalCall)] public extern static void Post(string message); @@ -19,18 +20,19 @@ namespace PureData public extern static void PostVerbose(string message); [MethodImplAttribute (MethodImplOptions.InternalCall)] - public extern static IntPtr GenSym(string sym); + internal extern static void *SymGen(string sym); [MethodImplAttribute (MethodImplOptions.InternalCall)] - public extern static string EvalSym(Symbol sym); + internal extern static string SymEval(void *sym); } // This is the base class for a PD/CLR external - public class External + public unsafe class External : Core { - private readonly IntPtr ptr; - + // PD object pointer + private readonly void *ptr; + protected virtual void MethodBang() { Post("No bang handler"); } protected virtual void MethodFloat(float f) { Post("No float handler"); } @@ -39,8 +41,8 @@ namespace PureData protected virtual void MethodPointer(Pointer p) { Post("No pointer handler");} - protected virtual void MethodList(Atom[] lst) { Post("No list handler"); } + protected virtual void MethodList(AtomList lst) { Post("No list handler"); } - protected virtual void MethodAnything(Atom[] lst) { Post("No list handler"); } + protected virtual void MethodAnything(Symbol tag,AtomList lst) { Post("No anything handler"); } } } diff --git a/pd/pd.csproj b/pd/pd.csproj index 29dcf7d..8dd510d 100755 --- a/pd/pd.csproj +++ b/pd/pd.csproj @@ -1,105 +1,105 @@ -<VisualStudioProject>
- <CSHARP
- ProjectType = "Local"
- ProductVersion = "7.10.3077"
- SchemaVersion = "2.0"
- ProjectGuid = "{FFBC9D2E-1FB7-4E82-B5DC-46B31F8A58A2}"
- >
- <Build>
- <Settings
- ApplicationIcon = ""
- AssemblyKeyContainerName = ""
- AssemblyName = "PureData"
- AssemblyOriginatorKeyFile = ""
- DefaultClientScript = "JScript"
- DefaultHTMLPageLayout = "Grid"
- DefaultTargetSchema = "IE50"
- DelaySign = "false"
- OutputType = "Library"
- PreBuildEvent = ""
- PostBuildEvent = ""
- RootNamespace = "PureData"
- RunPostBuildEvent = "OnBuildSuccess"
- StartupObject = ""
- >
- <Config
- Name = "Debug"
- AllowUnsafeBlocks = "false"
- BaseAddress = "285212672"
- CheckForOverflowUnderflow = "false"
- ConfigurationOverrideFile = ""
- DefineConstants = "DEBUG;TRACE"
- DocumentationFile = ""
- DebugSymbols = "true"
- FileAlignment = "4096"
- IncrementalBuild = "false"
- NoStdLib = "false"
- NoWarn = ""
- Optimize = "false"
- OutputPath = "..\"
- RegisterForComInterop = "false"
- RemoveIntegerChecks = "false"
- TreatWarningsAsErrors = "false"
- WarningLevel = "4"
- />
- <Config
- Name = "Release"
- AllowUnsafeBlocks = "false"
- BaseAddress = "285212672"
- CheckForOverflowUnderflow = "false"
- ConfigurationOverrideFile = ""
- DefineConstants = "TRACE"
- DocumentationFile = ""
- DebugSymbols = "false"
- FileAlignment = "4096"
- IncrementalBuild = "false"
- NoStdLib = "false"
- NoWarn = ""
- Optimize = "true"
- OutputPath = "bin\Release\"
- RegisterForComInterop = "false"
- RemoveIntegerChecks = "false"
- TreatWarningsAsErrors = "false"
- WarningLevel = "4"
- />
- </Settings>
- <References>
- <Reference
- Name = "System"
- AssemblyName = "System"
- HintPath = "..\..\..\..\..\WINDOWS\Microsoft.NET\Framework\v1.1.4322\System.dll"
- />
- <Reference
- Name = "System.Data"
- AssemblyName = "System.Data"
- HintPath = "..\..\..\..\..\WINDOWS\Microsoft.NET\Framework\v1.1.4322\System.Data.dll"
- />
- <Reference
- Name = "System.XML"
- AssemblyName = "System.Xml"
- HintPath = "..\..\..\..\..\WINDOWS\Microsoft.NET\Framework\v1.1.4322\System.XML.dll"
- />
- </References>
- </Build>
- <Files>
- <Include>
- <File
- RelPath = "AssemblyInfo.cs"
- SubType = "Code"
- BuildAction = "Compile"
- />
- <File
- RelPath = "Atom.cs"
- SubType = "Code"
- BuildAction = "Compile"
- />
- <File
- RelPath = "PureData.cs"
- SubType = "Code"
- BuildAction = "Compile"
- />
- </Include>
- </Files>
- </CSHARP>
-</VisualStudioProject>
-
+<VisualStudioProject> + <CSHARP + ProjectType = "Local" + ProductVersion = "7.10.3077" + SchemaVersion = "2.0" + ProjectGuid = "{FFBC9D2E-1FB7-4E82-B5DC-46B31F8A58A2}" + > + <Build> + <Settings + ApplicationIcon = "" + AssemblyKeyContainerName = "" + AssemblyName = "PureData" + AssemblyOriginatorKeyFile = "" + DefaultClientScript = "JScript" + DefaultHTMLPageLayout = "Grid" + DefaultTargetSchema = "IE50" + DelaySign = "false" + OutputType = "Library" + PreBuildEvent = "" + PostBuildEvent = "" + RootNamespace = "PureData" + RunPostBuildEvent = "OnBuildSuccess" + StartupObject = "" + > + <Config + Name = "Debug" + AllowUnsafeBlocks = "true" + BaseAddress = "285212672" + CheckForOverflowUnderflow = "false" + ConfigurationOverrideFile = "" + DefineConstants = "DEBUG;TRACE" + DocumentationFile = "" + DebugSymbols = "true" + FileAlignment = "4096" + IncrementalBuild = "false" + NoStdLib = "false" + NoWarn = "" + Optimize = "false" + OutputPath = "..\" + RegisterForComInterop = "false" + RemoveIntegerChecks = "false" + TreatWarningsAsErrors = "false" + WarningLevel = "4" + /> + <Config + Name = "Release" + AllowUnsafeBlocks = "true" + BaseAddress = "285212672" + CheckForOverflowUnderflow = "false" + ConfigurationOverrideFile = "" + DefineConstants = "TRACE" + DocumentationFile = "" + DebugSymbols = "false" + FileAlignment = "4096" + IncrementalBuild = "false" + NoStdLib = "false" + NoWarn = "" + Optimize = "true" + OutputPath = "bin\Release\" + RegisterForComInterop = "false" + RemoveIntegerChecks = "false" + TreatWarningsAsErrors = "false" + WarningLevel = "4" + /> + </Settings> + <References> + <Reference + Name = "System" + AssemblyName = "System" + HintPath = "..\..\..\..\..\WINDOWS\Microsoft.NET\Framework\v1.1.4322\System.dll" + /> + <Reference + Name = "System.Data" + AssemblyName = "System.Data" + HintPath = "..\..\..\..\..\WINDOWS\Microsoft.NET\Framework\v1.1.4322\System.Data.dll" + /> + <Reference + Name = "System.XML" + AssemblyName = "System.Xml" + HintPath = "..\..\..\..\..\WINDOWS\Microsoft.NET\Framework\v1.1.4322\System.XML.dll" + /> + </References> + </Build> + <Files> + <Include> + <File + RelPath = "AssemblyInfo.cs" + SubType = "Code" + BuildAction = "Compile" + /> + <File + RelPath = "Atom.cs" + SubType = "Code" + BuildAction = "Compile" + /> + <File + RelPath = "PureData.cs" + SubType = "Code" + BuildAction = "Compile" + /> + </Include> + </Files> + </CSHARP> +</VisualStudioProject> + |