Fixes support for newer version, added support for userdata collections
This commit is contained in:
parent
4a42254b62
commit
d2cc82dc21
|
@ -27,7 +27,7 @@ namespace PorygonSharp
|
||||||
Print(message);
|
Print(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
[DllImport("libPorygonLang", EntryPoint = "SetPrintFunc", CallingConvention = CallingConvention.Cdecl)]
|
[DllImport("libPorygonLang", EntryPoint = "SetDefaultPrintFunc", CallingConvention = CallingConvention.Cdecl)]
|
||||||
private static extern double InternalSetPrintFunc(IntPtr ptr);
|
private static extern double InternalSetPrintFunc(IntPtr ptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,9 +1,8 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using PorygonSharp.UserData;
|
|
||||||
|
|
||||||
namespace PorygonSharp
|
namespace PorygonSharp.EvalValues
|
||||||
{
|
{
|
||||||
public class EvalValue : IDisposable
|
public class EvalValue : IDisposable
|
||||||
{
|
{
|
||||||
|
@ -14,47 +13,6 @@ namespace PorygonSharp
|
||||||
_handle = handle;
|
_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()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
|
@ -119,9 +77,6 @@ namespace PorygonSharp
|
||||||
return EvaluateString();
|
return EvaluateString();
|
||||||
case TypeClass.UserData:
|
case TypeClass.UserData:
|
||||||
return EvaluateGenericObject();
|
return EvaluateGenericObject();
|
||||||
case TypeClass.Function:
|
|
||||||
case TypeClass.Table:
|
|
||||||
case TypeClass.Error:
|
|
||||||
default:
|
default:
|
||||||
throw new ArgumentOutOfRangeException();
|
throw new ArgumentOutOfRangeException();
|
||||||
}
|
}
|
||||||
|
@ -150,19 +105,5 @@ namespace PorygonSharp
|
||||||
[DllImport("libPorygonLang", EntryPoint = "EvaluateUserDataObj",CallingConvention = CallingConvention.Cdecl)]
|
[DllImport("libPorygonLang", EntryPoint = "EvaluateUserDataObj",CallingConvention = CallingConvention.Cdecl)]
|
||||||
private static extern IntPtr EvaluateUserDataObj(IntPtr ptr);
|
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);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
using PorygonSharp.EvalValues;
|
||||||
|
|
||||||
namespace PorygonSharp
|
namespace PorygonSharp
|
||||||
{
|
{
|
||||||
|
@ -9,7 +10,7 @@ namespace PorygonSharp
|
||||||
private struct EvaluateResultInternal
|
private struct EvaluateResultInternal
|
||||||
{
|
{
|
||||||
public readonly IntPtr Value;
|
public readonly IntPtr Value;
|
||||||
public readonly byte Result;
|
public readonly bool Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly IntPtr _ptr;
|
private readonly IntPtr _ptr;
|
||||||
|
@ -22,12 +23,12 @@ namespace PorygonSharp
|
||||||
|
|
||||||
public EvalValue GetValue()
|
public EvalValue GetValue()
|
||||||
{
|
{
|
||||||
return !IsSuccess() ? null : new EvalValue(_internal.Value);
|
return new EvalValue(_internal.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsSuccess()
|
public bool IsSuccess()
|
||||||
{
|
{
|
||||||
return _internal.Result == 0;
|
return !_internal.Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GetError()
|
public string GetError()
|
||||||
|
|
|
@ -5,4 +5,10 @@
|
||||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<None Update="libPorygonLang.so">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Runtime.ExceptionServices;
|
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Security;
|
|
||||||
using PorygonSharp.DiagnosticHandling;
|
using PorygonSharp.DiagnosticHandling;
|
||||||
|
using PorygonSharp.EvalValues;
|
||||||
|
|
||||||
namespace PorygonSharp
|
namespace PorygonSharp
|
||||||
{
|
{
|
||||||
|
@ -13,8 +12,10 @@ namespace PorygonSharp
|
||||||
{
|
{
|
||||||
private readonly IntPtr _evaluator;
|
private readonly IntPtr _evaluator;
|
||||||
private readonly IntPtr _scriptVariables;
|
private readonly IntPtr _scriptVariables;
|
||||||
|
private readonly IntPtr _scriptTypes;
|
||||||
private readonly SharedPointer<object> _boundScript;
|
private readonly SharedPointer<object> _boundScript;
|
||||||
private readonly SharedPointer<object> _returnType;
|
private readonly SharedPointer<object> _returnType;
|
||||||
|
private readonly IntPtr _scriptOptions;
|
||||||
internal readonly SharedPointer<Diagnostics> Diagnostics;
|
internal readonly SharedPointer<Diagnostics> Diagnostics;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,12 +44,12 @@ namespace PorygonSharp
|
||||||
private Diagnostics _diagnostics;
|
private Diagnostics _diagnostics;
|
||||||
public Diagnostics Diagnostics => _diagnostics ?? (_diagnostics = new Diagnostics(_internalScript.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)
|
public Script(string s)
|
||||||
{
|
{
|
||||||
// Ensure core setup has been called
|
// Ensure core setup has been called
|
||||||
RuntimeHelpers.RunClassConstructor(_setupHandle);
|
RuntimeHelpers.RunClassConstructor(SetupHandle);
|
||||||
|
|
||||||
_internalScriptHandle = Create(s);
|
_internalScriptHandle = Create(s);
|
||||||
_internalScript = Marshal.PtrToStructure<InternalScript>(_internalScriptHandle);
|
_internalScript = Marshal.PtrToStructure<InternalScript>(_internalScriptHandle);
|
||||||
|
@ -90,9 +91,20 @@ namespace PorygonSharp
|
||||||
|
|
||||||
public EvalValue CallFunction(string key, params object[] parameters)
|
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);
|
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)]
|
[DllImport("libPorygonLang", EntryPoint = "CreateScript", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
@ -106,8 +118,10 @@ namespace PorygonSharp
|
||||||
|
|
||||||
[DllImport("libPorygonLang", EntryPoint = "HasFunction", CallingConvention = CallingConvention.Cdecl)]
|
[DllImport("libPorygonLang", EntryPoint = "HasFunction", CallingConvention = CallingConvention.Cdecl)]
|
||||||
private static extern bool HasFunction(IntPtr script, [MarshalAs(UnmanagedType.LPWStr)]string key);
|
private static extern bool HasFunction(IntPtr script, [MarshalAs(UnmanagedType.LPWStr)]string key);
|
||||||
|
|
||||||
[DllImport("libPorygonLang", EntryPoint = "CallFunction", CallingConvention = CallingConvention.Cdecl)]
|
[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;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
using PorygonSharp.UserData;
|
||||||
|
|
||||||
namespace PorygonSharp.ScriptType
|
namespace PorygonSharp.ScriptType
|
||||||
{
|
{
|
||||||
|
@ -34,6 +37,18 @@ namespace PorygonSharp.ScriptType
|
||||||
{
|
{
|
||||||
return CreateScriptType(TypeClass.Nil);
|
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;
|
goto default;
|
||||||
default:
|
default:
|
||||||
throw new ArgumentOutOfRangeException(t.FullName);
|
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)]
|
[DllImport("libPorygonLang", EntryPoint = "CreateScriptType", CallingConvention = CallingConvention.Cdecl)]
|
||||||
private static extern IntPtr CreateScriptType(TypeClass t);
|
private static extern IntPtr CreateScriptType(TypeClass t);
|
||||||
|
|
||||||
|
@ -72,5 +102,8 @@ namespace PorygonSharp.ScriptType
|
||||||
|
|
||||||
[DllImport("libPorygonLang", EntryPoint = "CreateUserDataFunctionScriptType", CallingConvention = CallingConvention.Cdecl)]
|
[DllImport("libPorygonLang", EntryPoint = "CreateUserDataFunctionScriptType", CallingConvention = CallingConvention.Cdecl)]
|
||||||
private static extern IntPtr CreateUserDataFunctionScriptType(IntPtr returnType, IntPtr[] parameters, int parameterCount);
|
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.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
using PorygonSharp.EvalValues;
|
||||||
using PorygonSharp.Utilities;
|
using PorygonSharp.Utilities;
|
||||||
|
|
||||||
namespace PorygonSharp.UserData
|
namespace PorygonSharp.UserData
|
||||||
|
@ -13,8 +14,8 @@ namespace PorygonSharp.UserData
|
||||||
|
|
||||||
private delegate IntPtr GetterDelegate(IntPtr ptr);
|
private delegate IntPtr GetterDelegate(IntPtr ptr);
|
||||||
private delegate void SetterDelegate(IntPtr ptr, IntPtr val);
|
private delegate void SetterDelegate(IntPtr ptr, IntPtr val);
|
||||||
private delegate IntPtr CallerDelegate(IntPtr parent,
|
private delegate IntPtr CallerDelegate(IntPtr parent, IntPtr scriptOption,
|
||||||
[MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)]IntPtr[] parameters, int size);
|
[MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)]IntPtr[] parameters, int size);
|
||||||
|
|
||||||
public static void RegisterType(string name, Type type)
|
public static void RegisterType(string name, Type type)
|
||||||
{
|
{
|
||||||
|
@ -51,7 +52,7 @@ namespace PorygonSharp.UserData
|
||||||
{
|
{
|
||||||
var obj = GCHandle.FromIntPtr(ptr).Target;
|
var obj = GCHandle.FromIntPtr(ptr).Target;
|
||||||
var value = field.GetValue(obj);
|
var value = field.GetValue(obj);
|
||||||
return EvalValue.CreateValue(value).GetPointer();
|
return EvalValueCreator.CreateValue(value).GetPointer();
|
||||||
});
|
});
|
||||||
|
|
||||||
var setterPtr = IntPtr.Zero;
|
var setterPtr = IntPtr.Zero;
|
||||||
|
@ -82,7 +83,7 @@ namespace PorygonSharp.UserData
|
||||||
{
|
{
|
||||||
var obj = GCHandle.FromIntPtr(ptr).Target;
|
var obj = GCHandle.FromIntPtr(ptr).Target;
|
||||||
var value = property.GetValue(obj);
|
var value = property.GetValue(obj);
|
||||||
return EvalValue.CreateValue(value).GetPointer();
|
return EvalValueCreator.CreateValue(value).GetPointer();
|
||||||
});
|
});
|
||||||
getterPtr = Marshal.GetFunctionPointerForDelegate(getter);
|
getterPtr = Marshal.GetFunctionPointerForDelegate(getter);
|
||||||
}
|
}
|
||||||
|
@ -110,7 +111,7 @@ namespace PorygonSharp.UserData
|
||||||
|
|
||||||
var getter = new GetterDelegate(ptr =>
|
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];
|
var evaluatedParameters = new object[size];
|
||||||
|
@ -124,10 +125,10 @@ namespace PorygonSharp.UserData
|
||||||
|
|
||||||
var parentObj = GCHandle.FromIntPtr(parent).Target;
|
var parentObj = GCHandle.FromIntPtr(parent).Target;
|
||||||
var result = method.Invoke(parentObj, evaluatedParameters);
|
var result = method.Invoke(parentObj, evaluatedParameters);
|
||||||
return EvalValue.CreateValue(result).GetPointer();
|
return EvalValueCreator.CreateValue(result).GetPointer();
|
||||||
});
|
});
|
||||||
var funcPtr = Marshal.GetFunctionPointerForDelegate(func);
|
var funcPtr = Marshal.GetFunctionPointerForDelegate(func);
|
||||||
return EvalValue.FunctionEvalValue(funcPtr, ptr).GetPointer();
|
return EvalValueCreator.FunctionEvalValue(funcPtr, ptr).GetPointer();
|
||||||
});
|
});
|
||||||
var getterPtr = Marshal.GetFunctionPointerForDelegate(getter);
|
var getterPtr = Marshal.GetFunctionPointerForDelegate(getter);
|
||||||
var type = ScriptType.ScriptType.GetFunctionScriptType(method);
|
var type = ScriptType.ScriptType.GetFunctionScriptType(method);
|
||||||
|
@ -144,12 +145,23 @@ namespace PorygonSharp.UserData
|
||||||
return UserDataLookup[t];
|
return UserDataLookup[t];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static bool IsTypeRegistered(Type t)
|
||||||
|
{
|
||||||
|
return UserDataLookup.ContainsKey(t);
|
||||||
|
}
|
||||||
|
|
||||||
public static int GetUserDataFieldCount(Type t)
|
public static int GetUserDataFieldCount(Type t)
|
||||||
{
|
{
|
||||||
var hash = GetTypeId(t);
|
var hash = GetTypeId(t);
|
||||||
return GetUserDataFieldCount(hash);
|
return GetUserDataFieldCount(hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal static IntPtr CreateUserDataType(Type t)
|
||||||
|
{
|
||||||
|
var hash = GetTypeId(t);
|
||||||
|
return CreateUserDataType(hash);
|
||||||
|
}
|
||||||
|
|
||||||
[DllImport("libPorygonLang", EntryPoint = "RegisterUserDataType", CallingConvention = CallingConvention.Cdecl)]
|
[DllImport("libPorygonLang", EntryPoint = "RegisterUserDataType", CallingConvention = CallingConvention.Cdecl)]
|
||||||
private static extern void RegisterUserDataType(uint hashId);
|
private static extern void RegisterUserDataType(uint hashId);
|
||||||
|
|
||||||
|
@ -162,5 +174,8 @@ namespace PorygonSharp.UserData
|
||||||
[DllImport("libPorygonLang", EntryPoint = "GetUserDataFieldCount", CallingConvention = CallingConvention.Cdecl)]
|
[DllImport("libPorygonLang", EntryPoint = "GetUserDataFieldCount", CallingConvention = CallingConvention.Cdecl)]
|
||||||
private static extern int GetUserDataFieldCount(uint hashId);
|
private static extern int GetUserDataFieldCount(uint hashId);
|
||||||
|
|
||||||
|
[DllImport("libPorygonLang", EntryPoint = "CreateUserDataType", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
private static extern IntPtr CreateUserDataType(uint hashId);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
Binary file not shown.
|
@ -16,6 +16,8 @@ namespace PorygonSharpTests
|
||||||
public int GetOnly { get; } = 865;
|
public int GetOnly { get; } = 865;
|
||||||
public readonly int ReadOnly = 684;
|
public readonly int ReadOnly = 684;
|
||||||
|
|
||||||
|
public int[] IntArray = {55, 60, 846, 346846};
|
||||||
|
|
||||||
public int TestFunc()
|
public int TestFunc()
|
||||||
{
|
{
|
||||||
return 345435;
|
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.
Loading…
Reference in New Issue