Fixes support for newer version, added support for userdata collections
This commit is contained in:
		| @@ -27,7 +27,7 @@ namespace PorygonSharp | ||||
|             Print(message); | ||||
|         } | ||||
|          | ||||
|         [DllImport("libPorygonLang", EntryPoint = "SetPrintFunc", CallingConvention = CallingConvention.Cdecl)] | ||||
|         [DllImport("libPorygonLang", EntryPoint = "SetDefaultPrintFunc", CallingConvention = CallingConvention.Cdecl)] | ||||
|         private static extern double InternalSetPrintFunc(IntPtr ptr); | ||||
|     } | ||||
| } | ||||
| @@ -1,9 +1,8 @@ | ||||
| using System; | ||||
| using System.Runtime.InteropServices; | ||||
| using System.Text; | ||||
| using PorygonSharp.UserData; | ||||
| 
 | ||||
| namespace PorygonSharp | ||||
| namespace PorygonSharp.EvalValues | ||||
| { | ||||
|     public class EvalValue : IDisposable | ||||
|     { | ||||
| @@ -14,48 +13,7 @@ namespace PorygonSharp | ||||
|             _handle = handle; | ||||
|         } | ||||
| 
 | ||||
|         public static EvalValue CreateValue(object o) | ||||
|         { | ||||
|             var type     = o.GetType(); | ||||
|             var typeCode = Type.GetTypeCode(type); | ||||
|             switch (typeCode) | ||||
|             { | ||||
|                 case TypeCode.Boolean: | ||||
|                     return new EvalValue(CreateBoolEvalValue((bool)o)); | ||||
|                 case TypeCode.Byte: | ||||
|                 case TypeCode.SByte: | ||||
|                 case TypeCode.Int16: | ||||
|                 case TypeCode.Int32: | ||||
|                 case TypeCode.Int64: | ||||
|                 case TypeCode.UInt16: | ||||
|                 case TypeCode.UInt32: | ||||
|                 case TypeCode.UInt64: | ||||
|                     return new EvalValue(CreateIntegerEvalValue(Convert.ToInt64(o))); | ||||
|                 case TypeCode.Char: | ||||
|                 case TypeCode.String: | ||||
|                     return new EvalValue(CreateStringEvalValue(o.ToString())); | ||||
|                 case TypeCode.Decimal: | ||||
|                 case TypeCode.Double: | ||||
|                 case TypeCode.Single: | ||||
|                     return new EvalValue(CreateFloatEvalValue(Convert.ToDouble(o))); | ||||
|                 case TypeCode.Object: | ||||
|                     var typeHash = UserDataHandler.GetTypeId(type); | ||||
|                     var handle   = GCHandle.Alloc(o, GCHandleType.WeakTrackResurrection); | ||||
|                     return new EvalValue(CreateUserDataEvalValue(typeHash, GCHandle.ToIntPtr(handle))); | ||||
|                 case TypeCode.DateTime: | ||||
|                 case TypeCode.DBNull: | ||||
|                 case TypeCode.Empty: | ||||
|                 default: | ||||
|                     throw new Exception($"Type {type} is not currently available as EvalValue"); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public static EvalValue FunctionEvalValue(IntPtr func, IntPtr parent) | ||||
|         { | ||||
|             return new EvalValue(CreateFunctionEvalValue(func, parent)); | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
|          | ||||
|         public void Dispose() | ||||
|         { | ||||
|             if (_handle != IntPtr.Zero) | ||||
| @@ -119,9 +77,6 @@ namespace PorygonSharp | ||||
|                     return EvaluateString(); | ||||
|                 case TypeClass.UserData: | ||||
|                     return EvaluateGenericObject(); | ||||
|                 case TypeClass.Function: | ||||
|                 case TypeClass.Table: | ||||
|                 case TypeClass.Error: | ||||
|                 default: | ||||
|                     throw new ArgumentOutOfRangeException(); | ||||
|             } | ||||
| @@ -150,19 +105,5 @@ namespace PorygonSharp | ||||
|         [DllImport("libPorygonLang", EntryPoint = "EvaluateUserDataObj",CallingConvention = CallingConvention.Cdecl)] | ||||
|         private static extern IntPtr EvaluateUserDataObj(IntPtr ptr); | ||||
| 
 | ||||
|         [DllImport("libPorygonLang", EntryPoint = "CreateIntegerEvalValue",CallingConvention = CallingConvention.Cdecl)] | ||||
|         private static extern IntPtr CreateIntegerEvalValue(long l); | ||||
|         [DllImport("libPorygonLang", EntryPoint = "CreateFloatEvalValue",CallingConvention = CallingConvention.Cdecl)] | ||||
|         private static extern IntPtr CreateFloatEvalValue(double d); | ||||
|         [DllImport("libPorygonLang", EntryPoint = "CreateBoolEvalValue",CallingConvention = CallingConvention.Cdecl)] | ||||
|         private static extern IntPtr CreateBoolEvalValue(bool b); | ||||
|         [DllImport("libPorygonLang", EntryPoint = "CreateStringEvalValue",CallingConvention = CallingConvention.Cdecl)] | ||||
|         private static extern IntPtr CreateStringEvalValue(string s); | ||||
|         [DllImport("libPorygonLang", EntryPoint = "CreateUserDataEvalValue",CallingConvention = CallingConvention.Cdecl)] | ||||
|         private static extern IntPtr CreateUserDataEvalValue(uint typeHash, IntPtr obj); | ||||
| 
 | ||||
|         [DllImport("libPorygonLang", EntryPoint = "CreateFunctionEvalValue",CallingConvention = CallingConvention.Cdecl)] | ||||
|         private static extern IntPtr CreateFunctionEvalValue(IntPtr func, IntPtr parent); | ||||
| 
 | ||||
|     } | ||||
| } | ||||
							
								
								
									
										77
									
								
								PorygonSharp/EvalValues/EvalValueCreator.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								PorygonSharp/EvalValues/EvalValueCreator.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,77 @@ | ||||
| using System; | ||||
| using System.Collections; | ||||
| using System.Collections.Generic; | ||||
| using System.Runtime.InteropServices; | ||||
| using PorygonSharp.UserData; | ||||
|  | ||||
| namespace PorygonSharp.EvalValues | ||||
| { | ||||
|     public static class EvalValueCreator | ||||
|     { | ||||
|         public static EvalValue CreateValue(object o) | ||||
|         { | ||||
|             var type     = o.GetType(); | ||||
|             var typeCode = Type.GetTypeCode(type); | ||||
|             switch (typeCode) | ||||
|             { | ||||
|                 case TypeCode.Boolean: | ||||
|                     return new EvalValue(CreateBoolEvalValue((bool)o)); | ||||
|                 case TypeCode.Byte: | ||||
|                 case TypeCode.SByte: | ||||
|                 case TypeCode.Int16: | ||||
|                 case TypeCode.Int32: | ||||
|                 case TypeCode.Int64: | ||||
|                 case TypeCode.UInt16: | ||||
|                 case TypeCode.UInt32: | ||||
|                 case TypeCode.UInt64: | ||||
|                     return new EvalValue(CreateIntegerEvalValue(Convert.ToInt64(o))); | ||||
|                 case TypeCode.Char: | ||||
|                 case TypeCode.String: | ||||
|                     return new EvalValue(CreateStringEvalValue(o.ToString())); | ||||
|                 case TypeCode.Decimal: | ||||
|                 case TypeCode.Double: | ||||
|                 case TypeCode.Single: | ||||
|                     return new EvalValue(CreateFloatEvalValue(Convert.ToDouble(o))); | ||||
|                 case TypeCode.Object: | ||||
|                     if (typeof(IList).IsAssignableFrom(type)) | ||||
|                         return CreateListEvalValue((IList)o, type); | ||||
|                     var typeHash = UserDataHandler.GetTypeId(type); | ||||
|                     var handle   = GCHandle.Alloc(o, GCHandleType.WeakTrackResurrection); | ||||
|                     return new EvalValue(CreateUserDataEvalValue(typeHash, GCHandle.ToIntPtr(handle))); | ||||
|                 default: | ||||
|                     throw new Exception($"Type {type} is not currently available as EvalValue"); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         public static EvalValue FunctionEvalValue(IntPtr func, IntPtr parent) | ||||
|         { | ||||
|             return new EvalValue(CreateFunctionEvalValue(func, parent)); | ||||
|         } | ||||
|  | ||||
|         private static EvalValue CreateListEvalValue(IList collection, Type type) | ||||
|         { | ||||
|             var helper = new ListEvalValue(collection, type); | ||||
|             var ptr = CreateCollectionValue(IntPtr.Zero, helper.ParentCollection, helper.Getter, helper.Setter, | ||||
|                 helper.GetIterator); | ||||
|             return new EvalValue(ptr); | ||||
|         } | ||||
|          | ||||
|         [DllImport("libPorygonLang", EntryPoint = "CreateIntegerEvalValue",CallingConvention = CallingConvention.Cdecl)] | ||||
|         private static extern IntPtr CreateIntegerEvalValue(long l); | ||||
|         [DllImport("libPorygonLang", EntryPoint = "CreateFloatEvalValue",CallingConvention = CallingConvention.Cdecl)] | ||||
|         private static extern IntPtr CreateFloatEvalValue(double d); | ||||
|         [DllImport("libPorygonLang", EntryPoint = "CreateBoolEvalValue",CallingConvention = CallingConvention.Cdecl)] | ||||
|         private static extern IntPtr CreateBoolEvalValue(bool b); | ||||
|         [DllImport("libPorygonLang", EntryPoint = "CreateStringEvalValue",CallingConvention = CallingConvention.Cdecl)] | ||||
|         private static extern IntPtr CreateStringEvalValue(string s); | ||||
|         [DllImport("libPorygonLang", EntryPoint = "CreateUserDataEvalValue",CallingConvention = CallingConvention.Cdecl)] | ||||
|         private static extern IntPtr CreateUserDataEvalValue(uint typeHash, IntPtr obj); | ||||
|  | ||||
|         [DllImport("libPorygonLang", EntryPoint = "CreateFunctionEvalValue",CallingConvention = CallingConvention.Cdecl)] | ||||
|         private static extern IntPtr CreateFunctionEvalValue(IntPtr func, IntPtr parent); | ||||
|  | ||||
|         [DllImport("libPorygonLang", EntryPoint = "CreateCollectionValue", CallingConvention = CallingConvention.Cdecl)] | ||||
|         private static extern IntPtr CreateCollectionValue(IntPtr type, IntPtr parent, IntPtr getter, IntPtr setter, | ||||
|             IntPtr iterator); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										43
									
								
								PorygonSharp/EvalValues/ListEvalValue.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								PorygonSharp/EvalValues/ListEvalValue.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,43 @@ | ||||
| using System; | ||||
| using System.Collections; | ||||
| using System.Diagnostics; | ||||
| using System.Runtime.InteropServices; | ||||
|  | ||||
| namespace PorygonSharp.EvalValues | ||||
| { | ||||
|     internal class ListEvalValue | ||||
|     { | ||||
|         private delegate IntPtr GetterDelegate(IntPtr parent, IntPtr index); | ||||
|         private delegate void SetterDelegate(IntPtr parent, IntPtr index, IntPtr value); | ||||
|         public delegate IntPtr GetIteratorDelegate(IntPtr parent); | ||||
|  | ||||
|         public readonly IntPtr ParentCollection; | ||||
|         public readonly IntPtr Getter; | ||||
|         public readonly IntPtr Setter; | ||||
|         public readonly IntPtr GetIterator; | ||||
|          | ||||
|         public ListEvalValue(IList list, Type type) | ||||
|         { | ||||
|             var valueType = type.IsArray ? type.GetElementType() : type.GetGenericArguments()[0]; | ||||
|             if (valueType == null) | ||||
|                 throw new ArgumentNullException(); | ||||
|              | ||||
|             var parentHandle = GCHandle.Alloc(list, GCHandleType.WeakTrackResurrection); | ||||
|             ParentCollection = GCHandle.ToIntPtr(parentHandle); | ||||
|             Getter = Marshal.GetFunctionPointerForDelegate(new GetterDelegate((parent, index) => | ||||
|             { | ||||
|                 var val = new EvalValue(index).EvaluateInteger(); | ||||
|                 return EvalValueCreator.CreateValue(list[(int) val - 1]).GetPointer(); | ||||
|             })); | ||||
|             Setter = Marshal.GetFunctionPointerForDelegate(new SetterDelegate((parent, index, value) => | ||||
|             { | ||||
|                 var key = new EvalValue(index).EvaluateInteger(); | ||||
|                 var val = new EvalValue(value).GetObjectValue(); | ||||
|                 list[(int) key - 1] = Convert.ChangeType(val, valueType); | ||||
|             })); | ||||
|             GetIterator = | ||||
|                 Marshal.GetFunctionPointerForDelegate(new GetIteratorDelegate(parent => | ||||
|                     ListIterator.CreateListIterator(list))); | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										17
									
								
								PorygonSharp/EvalValues/ListIterator.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								PorygonSharp/EvalValues/ListIterator.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,17 @@ | ||||
| using System; | ||||
| using System.Collections; | ||||
| using System.Runtime.InteropServices; | ||||
|  | ||||
| namespace PorygonSharp.EvalValues | ||||
| { | ||||
|     public static class ListIterator | ||||
|     { | ||||
|         public static IntPtr CreateListIterator(IList list) | ||||
|         { | ||||
|             return CreateCollectionRangeIterator(0, list.Count); | ||||
|         } | ||||
|          | ||||
|         [DllImport("libPorygonLang", EntryPoint = "CreateCollectionRangeIterator", CallingConvention = CallingConvention.Cdecl)] | ||||
|         private static extern IntPtr CreateCollectionRangeIterator(int start, int end); | ||||
|     } | ||||
| } | ||||
| @@ -1,5 +1,6 @@ | ||||
| using System; | ||||
| using System.Runtime.InteropServices; | ||||
| using PorygonSharp.EvalValues; | ||||
|  | ||||
| namespace PorygonSharp | ||||
| { | ||||
| @@ -9,7 +10,7 @@ namespace PorygonSharp | ||||
|         private struct EvaluateResultInternal | ||||
|         { | ||||
|             public readonly IntPtr Value; | ||||
|             public readonly byte Result; | ||||
|             public readonly bool Result; | ||||
|         } | ||||
|  | ||||
|         private readonly IntPtr _ptr; | ||||
| @@ -22,12 +23,12 @@ namespace PorygonSharp | ||||
|  | ||||
|         public EvalValue GetValue() | ||||
|         { | ||||
|             return !IsSuccess() ? null : new EvalValue(_internal.Value); | ||||
|             return new EvalValue(_internal.Value); | ||||
|         } | ||||
|  | ||||
|         public bool IsSuccess() | ||||
|         { | ||||
|             return _internal.Result == 0; | ||||
|             return !_internal.Result; | ||||
|         } | ||||
|  | ||||
|         public string GetError() | ||||
|   | ||||
| @@ -5,4 +5,10 @@ | ||||
|         <AllowUnsafeBlocks>true</AllowUnsafeBlocks> | ||||
|     </PropertyGroup> | ||||
|  | ||||
|     <ItemGroup> | ||||
|       <None Update="libPorygonLang.so"> | ||||
|         <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> | ||||
|       </None> | ||||
|     </ItemGroup> | ||||
|  | ||||
| </Project> | ||||
|   | ||||
| @@ -1,10 +1,9 @@ | ||||
| using System; | ||||
| using System.Linq; | ||||
| using System.Runtime.CompilerServices; | ||||
| using System.Runtime.ExceptionServices; | ||||
| using System.Runtime.InteropServices; | ||||
| using System.Security; | ||||
| using PorygonSharp.DiagnosticHandling; | ||||
| using PorygonSharp.EvalValues; | ||||
|  | ||||
| namespace PorygonSharp | ||||
| { | ||||
| @@ -13,8 +12,10 @@ namespace PorygonSharp | ||||
|     { | ||||
|         private readonly IntPtr _evaluator; | ||||
|         private readonly IntPtr _scriptVariables; | ||||
|         private readonly IntPtr _scriptTypes; | ||||
|         private readonly SharedPointer<object> _boundScript; | ||||
|         private readonly SharedPointer<object> _returnType; | ||||
|         private readonly IntPtr _scriptOptions; | ||||
|         internal readonly SharedPointer<Diagnostics> Diagnostics; | ||||
|     } | ||||
|  | ||||
| @@ -43,12 +44,12 @@ namespace PorygonSharp | ||||
|         private Diagnostics _diagnostics; | ||||
|         public Diagnostics Diagnostics => _diagnostics ?? (_diagnostics = new Diagnostics(_internalScript.Diagnostics)); | ||||
|  | ||||
|         private static readonly RuntimeTypeHandle _setupHandle = typeof(CoreSetup).TypeHandle;  | ||||
|         private static readonly RuntimeTypeHandle SetupHandle = typeof(CoreSetup).TypeHandle;  | ||||
|  | ||||
|         public Script(string s) | ||||
|         { | ||||
|             // Ensure core setup has been called | ||||
|             RuntimeHelpers.RunClassConstructor(_setupHandle); | ||||
|             RuntimeHelpers.RunClassConstructor(SetupHandle); | ||||
|              | ||||
|             _internalScriptHandle = Create(s); | ||||
|             _internalScript       = Marshal.PtrToStructure<InternalScript>(_internalScriptHandle); | ||||
| @@ -90,9 +91,20 @@ namespace PorygonSharp | ||||
|  | ||||
|         public EvalValue CallFunction(string key, params object[] parameters) | ||||
|         { | ||||
|             var scriptParameters = parameters.Select(x => EvalValue.CreateValue(x).GetPointer()).ToArray(); | ||||
|             var scriptParameters = parameters.Select(x => EvalValueCreator.CreateValue(x).GetPointer()).ToArray(); | ||||
|             var ptr = CallFunction(_internalScriptHandle, key, scriptParameters, scriptParameters.Length); | ||||
|             return new EvalValue(ptr); | ||||
|             foreach (var parameter in scriptParameters) | ||||
|             { | ||||
|                 Marshal.FreeHGlobal(parameter); | ||||
|             } | ||||
|             using (var result = new EvaluateResult(ptr)) | ||||
|             { | ||||
|                 if (result.IsSuccess()) | ||||
|                 { | ||||
|                     return result.GetValue(); | ||||
|                 } | ||||
|                 throw new EvaluationException(result.GetError()); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         [DllImport("libPorygonLang", EntryPoint = "CreateScript", CallingConvention = CallingConvention.Cdecl)] | ||||
| @@ -106,8 +118,10 @@ namespace PorygonSharp | ||||
|  | ||||
|         [DllImport("libPorygonLang", EntryPoint = "HasFunction", CallingConvention = CallingConvention.Cdecl)] | ||||
|         private static extern bool HasFunction(IntPtr script, [MarshalAs(UnmanagedType.LPWStr)]string key); | ||||
|          | ||||
|         [DllImport("libPorygonLang", EntryPoint = "CallFunction", CallingConvention = CallingConvention.Cdecl)] | ||||
|         private static extern IntPtr CallFunction(IntPtr script, [MarshalAs(UnmanagedType.LPWStr)]string key, IntPtr[] parameters, int parameterCount); | ||||
|         private static extern IntPtr CallFunction(IntPtr script, [MarshalAs(UnmanagedType.LPWStr)]string key,  | ||||
|             IntPtr[] parameters, int parameterCount); | ||||
|  | ||||
|     } | ||||
| } | ||||
| @@ -1,6 +1,9 @@ | ||||
| using System; | ||||
| using System.Collections; | ||||
| using System.Collections.Generic; | ||||
| using System.Reflection; | ||||
| using System.Runtime.InteropServices; | ||||
| using PorygonSharp.UserData; | ||||
|  | ||||
| namespace PorygonSharp.ScriptType | ||||
| { | ||||
| @@ -34,6 +37,18 @@ namespace PorygonSharp.ScriptType | ||||
|                     { | ||||
|                         return CreateScriptType(TypeClass.Nil); | ||||
|                     } | ||||
|                     if (UserDataHandler.IsTypeRegistered(t)) | ||||
|                     { | ||||
|                         return UserDataHandler.CreateUserDataType(t); | ||||
|                     } | ||||
|                     if (typeof(IList).IsAssignableFrom(t)) | ||||
|                     { | ||||
|                         return CreateUserDataListType(t); | ||||
|                     } | ||||
|                     if (typeof(IDictionary<,>).IsAssignableFrom(t)) | ||||
|                     { | ||||
|                         return CreateUserDataDictionaryType(t); | ||||
|                     } | ||||
|                     goto default; | ||||
|                 default: | ||||
|                     throw new ArgumentOutOfRangeException(t.FullName); | ||||
| @@ -61,6 +76,21 @@ namespace PorygonSharp.ScriptType | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         private static IntPtr CreateUserDataListType(Type t) | ||||
|         { | ||||
|             var keyType = CreateNumericScriptType(true, false); | ||||
|             var valType = t.IsArray ? t.GetElementType() : t.GenericTypeArguments[0]; | ||||
|             var valueType = GetScriptType(valType); | ||||
|             return CreateCollectionType(keyType, valueType); | ||||
|         } | ||||
|          | ||||
|         private static IntPtr CreateUserDataDictionaryType(Type t) | ||||
|         { | ||||
|             var keyType = GetScriptType(t.GenericTypeArguments[0]); | ||||
|             var valueType = GetScriptType(t.GenericTypeArguments[1]); | ||||
|             return CreateCollectionType(keyType, valueType); | ||||
|         } | ||||
|  | ||||
|         [DllImport("libPorygonLang", EntryPoint = "CreateScriptType", CallingConvention = CallingConvention.Cdecl)] | ||||
|         private static extern IntPtr CreateScriptType(TypeClass t); | ||||
|  | ||||
| @@ -72,5 +102,8 @@ namespace PorygonSharp.ScriptType | ||||
|  | ||||
|         [DllImport("libPorygonLang", EntryPoint = "CreateUserDataFunctionScriptType", CallingConvention = CallingConvention.Cdecl)] | ||||
|         private static extern IntPtr CreateUserDataFunctionScriptType(IntPtr returnType, IntPtr[] parameters, int parameterCount); | ||||
|          | ||||
|         [DllImport("libPorygonLang", EntryPoint = "CreateCollectionType", CallingConvention = CallingConvention.Cdecl)] | ||||
|         private static extern IntPtr CreateCollectionType(IntPtr keyType, IntPtr valueType); | ||||
|     } | ||||
| } | ||||
| @@ -3,6 +3,7 @@ using System.Collections.Generic; | ||||
| using System.Linq; | ||||
| using System.Reflection; | ||||
| using System.Runtime.InteropServices; | ||||
| using PorygonSharp.EvalValues; | ||||
| using PorygonSharp.Utilities; | ||||
|  | ||||
| namespace PorygonSharp.UserData | ||||
| @@ -13,8 +14,8 @@ namespace PorygonSharp.UserData | ||||
|  | ||||
|         private delegate IntPtr GetterDelegate(IntPtr ptr); | ||||
|         private delegate void SetterDelegate(IntPtr ptr, IntPtr val); | ||||
|         private delegate IntPtr CallerDelegate(IntPtr parent, | ||||
|             [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)]IntPtr[] parameters, int size); | ||||
|         private delegate IntPtr CallerDelegate(IntPtr parent, IntPtr scriptOption, | ||||
|             [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)]IntPtr[] parameters, int size); | ||||
|  | ||||
|         public static void RegisterType(string name, Type type) | ||||
|         { | ||||
| @@ -51,7 +52,7 @@ namespace PorygonSharp.UserData | ||||
|             { | ||||
|                 var obj   = GCHandle.FromIntPtr(ptr).Target; | ||||
|                 var value = field.GetValue(obj); | ||||
|                 return EvalValue.CreateValue(value).GetPointer(); | ||||
|                 return EvalValueCreator.CreateValue(value).GetPointer(); | ||||
|             }); | ||||
|  | ||||
|             var setterPtr = IntPtr.Zero; | ||||
| @@ -82,7 +83,7 @@ namespace PorygonSharp.UserData | ||||
|                 { | ||||
|                     var obj   = GCHandle.FromIntPtr(ptr).Target; | ||||
|                     var value = property.GetValue(obj); | ||||
|                     return EvalValue.CreateValue(value).GetPointer(); | ||||
|                     return EvalValueCreator.CreateValue(value).GetPointer(); | ||||
|                 }); | ||||
|                 getterPtr = Marshal.GetFunctionPointerForDelegate(getter); | ||||
|             } | ||||
| @@ -110,7 +111,7 @@ namespace PorygonSharp.UserData | ||||
|  | ||||
|             var getter = new GetterDelegate(ptr => | ||||
|             { | ||||
|                 var func = new CallerDelegate((parent, parameters, size) => | ||||
|                 var func = new CallerDelegate((parent, scriptOptions, parameters, size) => | ||||
|                 { | ||||
|  | ||||
|                     var evaluatedParameters = new object[size]; | ||||
| @@ -124,10 +125,10 @@ namespace PorygonSharp.UserData | ||||
|  | ||||
|                     var parentObj = GCHandle.FromIntPtr(parent).Target; | ||||
|                     var result = method.Invoke(parentObj, evaluatedParameters); | ||||
|                     return EvalValue.CreateValue(result).GetPointer(); | ||||
|                     return EvalValueCreator.CreateValue(result).GetPointer(); | ||||
|                 }); | ||||
|                 var funcPtr = Marshal.GetFunctionPointerForDelegate(func); | ||||
|                 return EvalValue.FunctionEvalValue(funcPtr, ptr).GetPointer(); | ||||
|                 return EvalValueCreator.FunctionEvalValue(funcPtr, ptr).GetPointer(); | ||||
|             }); | ||||
|             var getterPtr = Marshal.GetFunctionPointerForDelegate(getter); | ||||
|             var type = ScriptType.ScriptType.GetFunctionScriptType(method); | ||||
| @@ -144,12 +145,23 @@ namespace PorygonSharp.UserData | ||||
|             return UserDataLookup[t]; | ||||
|         } | ||||
|  | ||||
|         public static bool IsTypeRegistered(Type t) | ||||
|         { | ||||
|             return UserDataLookup.ContainsKey(t); | ||||
|         } | ||||
|  | ||||
|         public static int GetUserDataFieldCount(Type t) | ||||
|         { | ||||
|             var hash = GetTypeId(t); | ||||
|             return GetUserDataFieldCount(hash); | ||||
|         } | ||||
|  | ||||
|         internal static IntPtr CreateUserDataType(Type t) | ||||
|         { | ||||
|             var hash = GetTypeId(t); | ||||
|             return CreateUserDataType(hash); | ||||
|         } | ||||
|  | ||||
|         [DllImport("libPorygonLang", EntryPoint = "RegisterUserDataType", CallingConvention = CallingConvention.Cdecl)] | ||||
|         private static extern void RegisterUserDataType(uint hashId); | ||||
|  | ||||
| @@ -161,6 +173,9 @@ namespace PorygonSharp.UserData | ||||
|  | ||||
|         [DllImport("libPorygonLang", EntryPoint = "GetUserDataFieldCount", CallingConvention = CallingConvention.Cdecl)] | ||||
|         private static extern int GetUserDataFieldCount(uint hashId); | ||||
|          | ||||
|         [DllImport("libPorygonLang", EntryPoint = "CreateUserDataType", CallingConvention = CallingConvention.Cdecl)] | ||||
|         private static extern IntPtr CreateUserDataType(uint hashId); | ||||
|  | ||||
|     } | ||||
| } | ||||
							
								
								
									
										
											BIN
										
									
								
								PorygonSharp/libPorygonLang.so
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								PorygonSharp/libPorygonLang.so
									
									
									
									
									
										Executable file
									
								
							
										
											Binary file not shown.
										
									
								
							| @@ -16,6 +16,8 @@ namespace PorygonSharpTests | ||||
|             public int GetOnly { get; } = 865; | ||||
|             public readonly int ReadOnly = 684; | ||||
|  | ||||
|             public int[] IntArray = {55, 60, 846, 346846}; | ||||
|  | ||||
|             public int TestFunc() | ||||
|             { | ||||
|                 return 345435; | ||||
| @@ -210,5 +212,104 @@ end | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         [Test] | ||||
|         public void CanGetFromArray() | ||||
|         { | ||||
|             UserDataHandler.RegisterType("testObject", typeof(UserDataTestObject)); | ||||
|             using (var script = new Script(@" | ||||
| function test(testObject v) | ||||
|     return v.IntArray[3] | ||||
| end | ||||
| ")) | ||||
|             { | ||||
|                 var diags = script.Diagnostics.GetDiagnostics(); | ||||
|                 foreach (var diag in diags) | ||||
|                 { | ||||
|                     throw new Exception(script.Diagnostics.GetFullDiagnosticMessage(diag)); | ||||
|                 } | ||||
|  | ||||
|                 script.Evaluate(); | ||||
|                 var parameter = new UserDataTestObject(); | ||||
|                 var result = script.CallFunction("test", parameter); | ||||
|                 Assert.AreEqual(846, result.EvaluateInteger()); | ||||
|             } | ||||
|         } | ||||
|          | ||||
|         [Test] | ||||
|         public void CanSetToArray() | ||||
|         { | ||||
|             UserDataHandler.RegisterType("testObject", typeof(UserDataTestObject)); | ||||
|             using (var script = new Script(@" | ||||
| function test(testObject v) | ||||
|     v.IntArray[2] = 256 | ||||
| end | ||||
| ")) | ||||
|             { | ||||
|                 var diags = script.Diagnostics.GetDiagnostics(); | ||||
|                 foreach (var diag in diags) | ||||
|                 { | ||||
|                     throw new Exception(script.Diagnostics.GetFullDiagnosticMessage(diag)); | ||||
|                 } | ||||
|  | ||||
|                 script.Evaluate(); | ||||
|                 var parameter = new UserDataTestObject(); | ||||
|                 script.CallFunction("test", parameter); | ||||
|                 Assert.AreEqual(256, parameter.IntArray[1]); | ||||
|             } | ||||
|         } | ||||
|          | ||||
|         [Test] | ||||
|         public void CanIterateOverArrayKeys() | ||||
|         { | ||||
|             UserDataHandler.RegisterType("testObject", typeof(UserDataTestObject)); | ||||
|             using (var script = new Script(@" | ||||
| function test(testObject v) | ||||
|     value = 0 | ||||
|     for i in v.IntArray do | ||||
|         value = value + i | ||||
|     end | ||||
|     return value | ||||
| end | ||||
| ")) | ||||
|             { | ||||
|                 var diags = script.Diagnostics.GetDiagnostics(); | ||||
|                 foreach (var diag in diags) | ||||
|                 { | ||||
|                     throw new Exception(script.Diagnostics.GetFullDiagnosticMessage(diag)); | ||||
|                 } | ||||
|  | ||||
|                 script.Evaluate(); | ||||
|                 var parameter = new UserDataTestObject(); | ||||
|                 var result = script.CallFunction("test", parameter); | ||||
|                 Assert.AreEqual(10, result.EvaluateInteger()); | ||||
|             } | ||||
|         } | ||||
|          | ||||
|         [Test] | ||||
|         public void CanIterateOverArrayValues() | ||||
|         { | ||||
|             UserDataHandler.RegisterType("testObject", typeof(UserDataTestObject)); | ||||
|             using (var script = new Script(@" | ||||
| function test(testObject v) | ||||
|     value = 0 | ||||
|     for i, j in v.IntArray do | ||||
|         value = value + j | ||||
|     end | ||||
|     return value | ||||
| end | ||||
| ")) | ||||
|             { | ||||
|                 var diags = script.Diagnostics.GetDiagnostics(); | ||||
|                 foreach (var diag in diags) | ||||
|                 { | ||||
|                     throw new Exception(script.Diagnostics.GetFullDiagnosticMessage(diag)); | ||||
|                 } | ||||
|  | ||||
|                 script.Evaluate(); | ||||
|                 var parameter = new UserDataTestObject(); | ||||
|                 var result = script.CallFunction("test", parameter); | ||||
|                 Assert.AreEqual(347807, result.EvaluateInteger()); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
										
											Binary file not shown.
										
									
								
							
		Reference in New Issue
	
	Block a user