Work on separate handling for userdata collection types

This commit is contained in:
Deukhoofd 2019-09-28 12:03:06 +02:00
parent 415f03efc3
commit 30627a650f
Signed by: Deukhoofd
GPG Key ID: ADF2E9256009EDCE
5 changed files with 52 additions and 13 deletions

View File

@ -64,6 +64,12 @@ namespace PorygonSharp.EvalValues
var ptr = EvaluateUserDataObj(Handle); var ptr = EvaluateUserDataObj(Handle);
return GCHandle.FromIntPtr(ptr).Target; return GCHandle.FromIntPtr(ptr).Target;
} }
private object EvaluateUserdataCollection()
{
var listHelper = ListEvalValue.Fetch(Handle);
return listHelper.List;
}
public object GetObjectValue() public object GetObjectValue()
{ {
@ -74,7 +80,7 @@ namespace PorygonSharp.EvalValues
case TypeClass.Nil: case TypeClass.Nil:
return null; return null;
case TypeClass.Number: case TypeClass.Number:
if (IsNumericValueFloat(Handle) == 1) if (IsNumericValueFloat())
return EvaluateFloat(); return EvaluateFloat();
else else
return EvaluateInteger(); return EvaluateInteger();
@ -84,6 +90,8 @@ namespace PorygonSharp.EvalValues
return EvaluateString(); return EvaluateString();
case TypeClass.UserData: case TypeClass.UserData:
return EvaluateGenericObject(); return EvaluateGenericObject();
case TypeClass.UserdataCollection:
return EvaluateUserdataCollection();
case TypeClass.Table: case TypeClass.Table:
var val = new TableEvalValue(Handle); var val = new TableEvalValue(Handle);
return val.EvaluateNumericalTable(); return val.EvaluateNumericalTable();
@ -97,6 +105,11 @@ namespace PorygonSharp.EvalValues
return Handle; return Handle;
} }
public bool IsNumericValueFloat()
{
return IsNumericValueFloat(Handle) == 1;
}
[DllImport("PorygonLang", EntryPoint = "GetEvalValueTypeClass", CallingConvention = CallingConvention.Cdecl)] [DllImport("PorygonLang", EntryPoint = "GetEvalValueTypeClass", CallingConvention = CallingConvention.Cdecl)]
private static extern int GetTypeClass(IntPtr ptr); private static extern int GetTypeClass(IntPtr ptr);
[DllImport("PorygonLang", EntryPoint = "GetEvalValueType", CallingConvention = CallingConvention.Cdecl)] [DllImport("PorygonLang", EntryPoint = "GetEvalValueType", CallingConvention = CallingConvention.Cdecl)]

View File

@ -64,9 +64,7 @@ namespace PorygonSharp.EvalValues
private static EvalValue CreateListEvalValue(IList collection, Type type) private static EvalValue CreateListEvalValue(IList collection, Type type)
{ {
var helper = new ListEvalValue(collection, type); var ptr = ListEvalValue.Create(collection, type);
var ptr = CreateCollectionValue(IntPtr.Zero, helper.ParentCollectionPtr, helper.GetterPtr, helper.SetterPtr,
helper.GetIteratorPtr, helper.GetLengthPtr);
return new EvalValue(ptr); return new EvalValue(ptr);
} }
@ -100,7 +98,7 @@ namespace PorygonSharp.EvalValues
internal static extern IntPtr CreateFunctionEvalValue(IntPtr func, IntPtr parent); internal static extern IntPtr CreateFunctionEvalValue(IntPtr func, IntPtr parent);
[DllImport("PorygonLang", EntryPoint = "CreateCollectionValue", CallingConvention = CallingConvention.Cdecl)] [DllImport("PorygonLang", EntryPoint = "CreateCollectionValue", CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr CreateCollectionValue(IntPtr type, IntPtr parent, IntPtr getter, IntPtr setter, internal static extern IntPtr CreateCollectionValue(IntPtr type, IntPtr parent, IntPtr getter, IntPtr setter,
IntPtr iterator, IntPtr size); IntPtr iterator, IntPtr size);
} }
} }

View File

@ -1,12 +1,17 @@
using System; using System;
using System.Collections; using System.Collections;
using System.Collections.Concurrent;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using PorygonSharp.Utilities;
namespace PorygonSharp.EvalValues namespace PorygonSharp.EvalValues
{ {
internal class ListEvalValue internal class ListEvalValue
{ {
private readonly IList _list; private static readonly ConcurrentDictionary<IntPtr, WeakReference<ListEvalValue>> _cache
= new ConcurrentDictionary<IntPtr, WeakReference<ListEvalValue>>();
public IList List { get; }
private readonly Type _valueType; private readonly Type _valueType;
private delegate IntPtr GetterDelegate(IntPtr parent, IntPtr index); private delegate IntPtr GetterDelegate(IntPtr parent, IntPtr index);
@ -28,9 +33,9 @@ namespace PorygonSharp.EvalValues
public readonly IntPtr GetLengthPtr; public readonly IntPtr GetLengthPtr;
public ListEvalValue(IList list, Type type) private ListEvalValue(IList list, Type type)
{ {
_list = list; List = list;
_valueType = type.IsArray ? type.GetElementType() : type.GetGenericArguments()[0]; _valueType = type.IsArray ? type.GetElementType() : type.GetGenericArguments()[0];
if (_valueType == null) if (_valueType == null)
throw new ArgumentNullException(); throw new ArgumentNullException();
@ -46,29 +51,51 @@ namespace PorygonSharp.EvalValues
SetterPtr = Marshal.GetFunctionPointerForDelegate(_setter); SetterPtr = Marshal.GetFunctionPointerForDelegate(_setter);
GetIteratorPtr = Marshal.GetFunctionPointerForDelegate(_getIterator); GetIteratorPtr = Marshal.GetFunctionPointerForDelegate(_getIterator);
GetLengthPtr = Marshal.GetFunctionPointerForDelegate(_getLength); GetLengthPtr = Marshal.GetFunctionPointerForDelegate(_getLength);
}
public static IntPtr Create(IList list, Type type)
{
var v = new ListEvalValue(list, type);
var ptr = EvalValueCreator.CreateCollectionValue(IntPtr.Zero, v.ParentCollectionPtr, v.GetterPtr,
v.SetterPtr, v.GetIteratorPtr, v.GetLengthPtr);
_cache.TryAdd(ptr, new WeakReference<ListEvalValue>(v));
return ptr;
}
internal static ListEvalValue Fetch(IntPtr ptr)
{
if (_cache.TryGetValue(ptr, out var r))
{
if (r.TryGetTarget(out var v))
{
return v;
}
}
throw new Exception("Can't get list eval value.");
} }
private IntPtr Getter(IntPtr parent, IntPtr index) private IntPtr Getter(IntPtr parent, IntPtr index)
{ {
var val = new EvalValue(index).EvaluateInteger(); var val = new EvalValue(index).EvaluateInteger();
return EvalValueCreator.CreateValue(_list[(int) val - 1]).GetPointer(); return EvalValueCreator.CreateValue(List[(int) val - 1]).GetPointer();
} }
private void Setter(IntPtr parent, IntPtr index, IntPtr value) private void Setter(IntPtr parent, IntPtr index, IntPtr value)
{ {
var key = new EvalValue(index).EvaluateInteger(); var key = new EvalValue(index).EvaluateInteger();
var val = new EvalValue(value).GetObjectValue(); var val = new EvalValue(value);
_list[(int) key - 1] = Convert.ChangeType(val, _valueType); List[(int) key - 1] = Caster.Cast(val, _valueType);
} }
private IntPtr GetIterator(IntPtr parent) private IntPtr GetIterator(IntPtr parent)
{ {
return ListIterator.CreateListIterator(_list); return ListIterator.CreateListIterator(List);
} }
private int GetLength(IntPtr parent) private int GetLength(IntPtr parent)
{ {
return _list.Count; return List.Count;
} }
} }
} }

View File

@ -9,6 +9,7 @@ namespace PorygonSharp
String, String,
Function, Function,
UserData, UserData,
UserdataCollection,
Table, Table,
Any Any
} }

Binary file not shown.