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);
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)]

View File

@ -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);
}
}

View File

@ -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;
}
}
}

View File

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

Binary file not shown.