diff --git a/PorygonSharp/EvalValues/EvalValueCreator.cs b/PorygonSharp/EvalValues/EvalValueCreator.cs index 41edf71..b29d4f3 100644 --- a/PorygonSharp/EvalValues/EvalValueCreator.cs +++ b/PorygonSharp/EvalValues/EvalValueCreator.cs @@ -63,8 +63,8 @@ namespace PorygonSharp.EvalValues 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); + var ptr = CreateCollectionValue(IntPtr.Zero, helper.ParentCollectionPtr, helper.GetterPtr, helper.SetterPtr, + helper.GetIteratorPtr, helper.GetLengthPtr); return new EvalValue(ptr); } @@ -86,6 +86,6 @@ namespace PorygonSharp.EvalValues [DllImport("PorygonLang", EntryPoint = "CreateCollectionValue", CallingConvention = CallingConvention.Cdecl)] private static extern IntPtr CreateCollectionValue(IntPtr type, IntPtr parent, IntPtr getter, IntPtr setter, - IntPtr iterator); + IntPtr iterator, IntPtr size); } } \ No newline at end of file diff --git a/PorygonSharp/EvalValues/ListEvalValue.cs b/PorygonSharp/EvalValues/ListEvalValue.cs index 50905f6..267d3a8 100644 --- a/PorygonSharp/EvalValues/ListEvalValue.cs +++ b/PorygonSharp/EvalValues/ListEvalValue.cs @@ -6,36 +6,69 @@ namespace PorygonSharp.EvalValues { internal class ListEvalValue { + private readonly IList _list; + private readonly Type _valueType; + private delegate IntPtr GetterDelegate(IntPtr parent, IntPtr index); private delegate void SetterDelegate(IntPtr parent, IntPtr index, IntPtr value); - public delegate IntPtr GetIteratorDelegate(IntPtr parent); + private delegate IntPtr GetIteratorDelegate(IntPtr parent); + private delegate int GetLengthDelegate(IntPtr parent); - public readonly IntPtr ParentCollection; - public readonly IntPtr Getter; - public readonly IntPtr Setter; - public readonly IntPtr GetIterator; + // ReSharper disable PrivateFieldCanBeConvertedToLocalVariable + private readonly GetterDelegate _getter; + private readonly SetterDelegate _setter; + private readonly GetIteratorDelegate _getIterator; + private readonly GetLengthDelegate _getLength; + // ReSharper restore PrivateFieldCanBeConvertedToLocalVariable + + public readonly IntPtr ParentCollectionPtr; + public readonly IntPtr GetterPtr; + public readonly IntPtr SetterPtr; + public readonly IntPtr GetIteratorPtr; + public readonly IntPtr GetLengthPtr; + public ListEvalValue(IList list, Type type) { - var valueType = type.IsArray ? type.GetElementType() : type.GetGenericArguments()[0]; - if (valueType == null) + _list = list; + _valueType = type.IsArray ? type.GetElementType() : type.GetGenericArguments()[0]; + if (_valueType == null) throw new ArgumentNullException(); - ParentCollection = ObjectEvalValueHandler.GetObjectPtr(list); - 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))); + ParentCollectionPtr = IntPtr.Zero; + _getter = Getter; + _setter = Setter; + _getIterator = GetIterator; + _getLength = GetLength; + + GetterPtr = Marshal.GetFunctionPointerForDelegate(_getter); + GetterPtr = Marshal.GetFunctionPointerForDelegate(_getter); + SetterPtr = Marshal.GetFunctionPointerForDelegate(_setter); + GetIteratorPtr = Marshal.GetFunctionPointerForDelegate(_getIterator); + GetLengthPtr = Marshal.GetFunctionPointerForDelegate(_getLength); + } + + private IntPtr Getter(IntPtr parent, IntPtr index) + { + var val = new EvalValue(index).EvaluateInteger(); + 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); + } + + private IntPtr GetIterator(IntPtr parent) + { + return ListIterator.CreateListIterator(_list); + } + + private int GetLength(IntPtr parent) + { + return _list.Count; } } } \ No newline at end of file diff --git a/PorygonSharp/libPorygonLang.so b/PorygonSharp/libPorygonLang.so index f0fcddf..8df6851 100755 Binary files a/PorygonSharp/libPorygonLang.so and b/PorygonSharp/libPorygonLang.so differ