Fixes for enums and dictionaries
This commit is contained in:
parent
1c181442e8
commit
5637e82dbe
|
@ -0,0 +1,72 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace PorygonSharp.EvalValues
|
||||
{
|
||||
public class DictionaryEvalValue
|
||||
{
|
||||
private readonly IDictionary _dictionary;
|
||||
private readonly Type _keyType;
|
||||
private readonly Type _valueType;
|
||||
|
||||
private delegate IntPtr GetterDelegate(IntPtr parent, IntPtr index);
|
||||
private delegate void SetterDelegate(IntPtr parent, IntPtr index, IntPtr value);
|
||||
private delegate IntPtr GetIteratorDelegate(IntPtr parent);
|
||||
private delegate int GetLengthDelegate(IntPtr parent);
|
||||
|
||||
// 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 GetterPtr;
|
||||
public readonly IntPtr SetterPtr;
|
||||
public readonly IntPtr GetIteratorPtr;
|
||||
public readonly IntPtr GetLengthPtr;
|
||||
|
||||
public DictionaryEvalValue(IDictionary dictionary, Type t)
|
||||
{
|
||||
_dictionary = dictionary;
|
||||
var genericTypes = t.GetGenericArguments();
|
||||
_keyType = genericTypes[0];
|
||||
_valueType = genericTypes[1];
|
||||
|
||||
_getter = Getter;
|
||||
_setter = Setter;
|
||||
_getIterator = GetIterator;
|
||||
_getLength = GetLength;
|
||||
|
||||
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).GetObjectValue();
|
||||
return EvalValueCreator.CreateValue(_dictionary[val]).GetPointer();
|
||||
}
|
||||
|
||||
private void Setter(IntPtr parent, IntPtr index, IntPtr value)
|
||||
{
|
||||
var key = new EvalValue(index).GetObjectValue();
|
||||
var val = new EvalValue(value).GetObjectValue();
|
||||
_dictionary[key] = Convert.ChangeType(val, _valueType);
|
||||
}
|
||||
|
||||
private IntPtr GetIterator(IntPtr parent)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
private int GetLength(IntPtr parent)
|
||||
{
|
||||
return _dictionary.Count;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -14,9 +14,6 @@ namespace PorygonSharp.EvalValues
|
|||
var type = o.GetType();
|
||||
if (type.IsEnum && !type.IsGenericParameter)
|
||||
{
|
||||
var typeHash = UserDataHandler.GetTypeId(type);
|
||||
var ptr = ObjectEvalValueHandler.GetObjectPtr(o);
|
||||
return new EvalValue(CreateUserDataEvalValue(typeHash, ptr));
|
||||
}
|
||||
var typeCode = Type.GetTypeCode(type);
|
||||
switch (typeCode)
|
||||
|
@ -42,6 +39,8 @@ namespace PorygonSharp.EvalValues
|
|||
case TypeCode.Object:
|
||||
if (typeof(IList).IsAssignableFrom(type))
|
||||
return CreateListEvalValue((IList)o, type);
|
||||
if (typeof(IDictionary).IsAssignableFrom(type))
|
||||
return CreateDictionaryEvalValue((IDictionary) o, type);
|
||||
if (typeof(Delegate).IsAssignableFrom(type))
|
||||
{
|
||||
return CreateDelegateEvalValue((Delegate) o);
|
||||
|
@ -71,6 +70,14 @@ namespace PorygonSharp.EvalValues
|
|||
return new EvalValue(ptr);
|
||||
}
|
||||
|
||||
private static EvalValue CreateDictionaryEvalValue(IDictionary dictionary, Type t)
|
||||
{
|
||||
var helper = new DictionaryEvalValue(dictionary, t);
|
||||
var ptr = CreateCollectionValue(IntPtr.Zero, IntPtr.Zero, helper.GetterPtr, helper.SetterPtr,
|
||||
helper.GetIteratorPtr, helper.GetLengthPtr);
|
||||
return new EvalValue(ptr);
|
||||
}
|
||||
|
||||
private static EvalValue CreateDelegateEvalValue(Delegate del)
|
||||
{
|
||||
var val = new DelegateEvalValue(del);
|
||||
|
@ -88,7 +95,7 @@ namespace PorygonSharp.EvalValues
|
|||
[DllImport("PorygonLang", EntryPoint = "CreateStringEvalValue",CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern IntPtr CreateStringEvalValue([MarshalAs(UnmanagedType.LPWStr)]string s);
|
||||
[DllImport("PorygonLang", EntryPoint = "CreateUserDataEvalValue",CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern IntPtr CreateUserDataEvalValue(uint typeHash, IntPtr obj);
|
||||
internal static extern IntPtr CreateUserDataEvalValue(uint typeHash, IntPtr obj);
|
||||
|
||||
[DllImport("PorygonLang", EntryPoint = "CreateFunctionEvalValue",CallingConvention = CallingConvention.Cdecl)]
|
||||
internal static extern IntPtr CreateFunctionEvalValue(IntPtr func, IntPtr parent);
|
||||
|
|
|
@ -2,6 +2,7 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using PorygonSharp.EvalValues;
|
||||
using PorygonSharp.UserData;
|
||||
using PorygonSharp.Utilities;
|
||||
|
||||
namespace PorygonSharp
|
||||
|
@ -21,6 +22,25 @@ namespace PorygonSharp
|
|||
RegisterStaticVariable(hash, scriptType.Value, value.GetPointer());
|
||||
}
|
||||
|
||||
public static void RegisterStaticEnum(string name, Type type)
|
||||
{
|
||||
UserDataHandler.RegisterEnumType(name, type);
|
||||
var typeHash = UserDataHandler.GetTypeId(type);
|
||||
var scriptType = ScriptType.ScriptTypeHandler.GetScriptType(type);
|
||||
if (!scriptType.HasValue)
|
||||
return;
|
||||
var ptr = ObjectEvalValueHandler.GetObjectPtr(Activator.CreateInstance(type));
|
||||
var val = new EvalValue(EvalValueCreator.CreateUserDataEvalValue(typeHash, ptr));
|
||||
StaticScope.RegisterStaticVariable(name, scriptType.Value, val);
|
||||
}
|
||||
|
||||
public static void RegisterStaticVariable(string name, IntPtr type, EvalValue val)
|
||||
{
|
||||
var hash = name.ScriptHash();
|
||||
RegisterStaticVariable(hash, type, val.GetPointer());
|
||||
}
|
||||
|
||||
|
||||
[DllImport("PorygonLang", EntryPoint = "RegisterStaticVariable", CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern void RegisterStaticVariable(uint hashId, IntPtr scriptType, IntPtr value);
|
||||
}
|
||||
|
|
|
@ -27,8 +27,7 @@ namespace PorygonSharp.UserData
|
|||
var enumAttr = type.GetCustomAttribute<PorygonEnumAttribute>();
|
||||
if (enumAttr != null)
|
||||
{
|
||||
RegisterEnumType(enumAttr.Name, type);
|
||||
StaticScope.RegisterStaticVariable(enumAttr.Name, Activator.CreateInstance(type));
|
||||
StaticScope.RegisterStaticEnum(enumAttr.Name, type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,8 +15,7 @@ namespace PorygonSharpTests
|
|||
[Test]
|
||||
public void AbleToAccessStaticEnumVariable()
|
||||
{
|
||||
UserDataHandler.RegisterEnumType("testEnum", typeof(testEnum));
|
||||
StaticScope.RegisterStaticVariable("testEnum", testEnum.One);
|
||||
StaticScope.RegisterStaticEnum("testEnum", typeof(testEnum));
|
||||
using (var script = new Script(@"
|
||||
return type(testEnum)
|
||||
"))
|
||||
|
@ -34,8 +33,7 @@ namespace PorygonSharpTests
|
|||
[Test]
|
||||
public void AbleToUseStaticEnumVariable()
|
||||
{
|
||||
UserDataHandler.RegisterEnumType("testEnum", typeof(testEnum));
|
||||
StaticScope.RegisterStaticVariable("testEnum", testEnum.One);
|
||||
StaticScope.RegisterStaticEnum("testEnum", typeof(testEnum));
|
||||
using (var script = new Script(@"
|
||||
return testEnum.Three + 2
|
||||
"))
|
||||
|
|
Loading…
Reference in New Issue