Work on separate handling for userdata collection types
This commit is contained in:
parent
415f03efc3
commit
30627a650f
|
@ -64,6 +64,12 @@ namespace PorygonSharp.EvalValues
|
|||
var ptr = EvaluateUserDataObj(Handle);
|
||||
return GCHandle.FromIntPtr(ptr).Target;
|
||||
}
|
||||
|
||||
private object EvaluateUserdataCollection()
|
||||
{
|
||||
var listHelper = ListEvalValue.Fetch(Handle);
|
||||
return listHelper.List;
|
||||
}
|
||||
|
||||
public object GetObjectValue()
|
||||
{
|
||||
|
@ -74,7 +80,7 @@ namespace PorygonSharp.EvalValues
|
|||
case TypeClass.Nil:
|
||||
return null;
|
||||
case TypeClass.Number:
|
||||
if (IsNumericValueFloat(Handle) == 1)
|
||||
if (IsNumericValueFloat())
|
||||
return EvaluateFloat();
|
||||
else
|
||||
return EvaluateInteger();
|
||||
|
@ -84,6 +90,8 @@ namespace PorygonSharp.EvalValues
|
|||
return EvaluateString();
|
||||
case TypeClass.UserData:
|
||||
return EvaluateGenericObject();
|
||||
case TypeClass.UserdataCollection:
|
||||
return EvaluateUserdataCollection();
|
||||
case TypeClass.Table:
|
||||
var val = new TableEvalValue(Handle);
|
||||
return val.EvaluateNumericalTable();
|
||||
|
@ -97,6 +105,11 @@ namespace PorygonSharp.EvalValues
|
|||
return Handle;
|
||||
}
|
||||
|
||||
public bool IsNumericValueFloat()
|
||||
{
|
||||
return IsNumericValueFloat(Handle) == 1;
|
||||
}
|
||||
|
||||
[DllImport("PorygonLang", EntryPoint = "GetEvalValueTypeClass", CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern int GetTypeClass(IntPtr ptr);
|
||||
[DllImport("PorygonLang", EntryPoint = "GetEvalValueType", CallingConvention = CallingConvention.Cdecl)]
|
||||
|
|
|
@ -64,9 +64,7 @@ namespace PorygonSharp.EvalValues
|
|||
|
||||
private static EvalValue CreateListEvalValue(IList collection, Type type)
|
||||
{
|
||||
var helper = new ListEvalValue(collection, type);
|
||||
var ptr = CreateCollectionValue(IntPtr.Zero, helper.ParentCollectionPtr, helper.GetterPtr, helper.SetterPtr,
|
||||
helper.GetIteratorPtr, helper.GetLengthPtr);
|
||||
var ptr = ListEvalValue.Create(collection, type);
|
||||
return new EvalValue(ptr);
|
||||
}
|
||||
|
||||
|
@ -100,7 +98,7 @@ namespace PorygonSharp.EvalValues
|
|||
internal static extern IntPtr CreateFunctionEvalValue(IntPtr func, IntPtr parent);
|
||||
|
||||
[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);
|
||||
}
|
||||
}
|
|
@ -1,12 +1,17 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Runtime.InteropServices;
|
||||
using PorygonSharp.Utilities;
|
||||
|
||||
namespace PorygonSharp.EvalValues
|
||||
{
|
||||
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 delegate IntPtr GetterDelegate(IntPtr parent, IntPtr index);
|
||||
|
@ -28,9 +33,9 @@ namespace PorygonSharp.EvalValues
|
|||
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];
|
||||
if (_valueType == null)
|
||||
throw new ArgumentNullException();
|
||||
|
@ -46,29 +51,51 @@ namespace PorygonSharp.EvalValues
|
|||
SetterPtr = Marshal.GetFunctionPointerForDelegate(_setter);
|
||||
GetIteratorPtr = Marshal.GetFunctionPointerForDelegate(_getIterator);
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
var key = new EvalValue(index).EvaluateInteger();
|
||||
var val = new EvalValue(value).GetObjectValue();
|
||||
_list[(int) key - 1] = Convert.ChangeType(val, _valueType);
|
||||
var val = new EvalValue(value);
|
||||
List[(int) key - 1] = Caster.Cast(val, _valueType);
|
||||
}
|
||||
|
||||
private IntPtr GetIterator(IntPtr parent)
|
||||
{
|
||||
return ListIterator.CreateListIterator(_list);
|
||||
return ListIterator.CreateListIterator(List);
|
||||
}
|
||||
|
||||
private int GetLength(IntPtr parent)
|
||||
{
|
||||
return _list.Count;
|
||||
return List.Count;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -9,6 +9,7 @@ namespace PorygonSharp
|
|||
String,
|
||||
Function,
|
||||
UserData,
|
||||
UserdataCollection,
|
||||
Table,
|
||||
Any
|
||||
}
|
||||
|
|
Binary file not shown.
Loading…
Reference in New Issue