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();
|
var type = o.GetType();
|
||||||
if (type.IsEnum && !type.IsGenericParameter)
|
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);
|
var typeCode = Type.GetTypeCode(type);
|
||||||
switch (typeCode)
|
switch (typeCode)
|
||||||
|
@ -42,6 +39,8 @@ namespace PorygonSharp.EvalValues
|
||||||
case TypeCode.Object:
|
case TypeCode.Object:
|
||||||
if (typeof(IList).IsAssignableFrom(type))
|
if (typeof(IList).IsAssignableFrom(type))
|
||||||
return CreateListEvalValue((IList)o, type);
|
return CreateListEvalValue((IList)o, type);
|
||||||
|
if (typeof(IDictionary).IsAssignableFrom(type))
|
||||||
|
return CreateDictionaryEvalValue((IDictionary) o, type);
|
||||||
if (typeof(Delegate).IsAssignableFrom(type))
|
if (typeof(Delegate).IsAssignableFrom(type))
|
||||||
{
|
{
|
||||||
return CreateDelegateEvalValue((Delegate) o);
|
return CreateDelegateEvalValue((Delegate) o);
|
||||||
|
@ -71,6 +70,14 @@ namespace PorygonSharp.EvalValues
|
||||||
return new EvalValue(ptr);
|
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)
|
private static EvalValue CreateDelegateEvalValue(Delegate del)
|
||||||
{
|
{
|
||||||
var val = new DelegateEvalValue(del);
|
var val = new DelegateEvalValue(del);
|
||||||
|
@ -88,7 +95,7 @@ namespace PorygonSharp.EvalValues
|
||||||
[DllImport("PorygonLang", EntryPoint = "CreateStringEvalValue",CallingConvention = CallingConvention.Cdecl)]
|
[DllImport("PorygonLang", EntryPoint = "CreateStringEvalValue",CallingConvention = CallingConvention.Cdecl)]
|
||||||
private static extern IntPtr CreateStringEvalValue([MarshalAs(UnmanagedType.LPWStr)]string s);
|
private static extern IntPtr CreateStringEvalValue([MarshalAs(UnmanagedType.LPWStr)]string s);
|
||||||
[DllImport("PorygonLang", EntryPoint = "CreateUserDataEvalValue",CallingConvention = CallingConvention.Cdecl)]
|
[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)]
|
[DllImport("PorygonLang", EntryPoint = "CreateFunctionEvalValue",CallingConvention = CallingConvention.Cdecl)]
|
||||||
internal static extern IntPtr CreateFunctionEvalValue(IntPtr func, IntPtr parent);
|
internal static extern IntPtr CreateFunctionEvalValue(IntPtr func, IntPtr parent);
|
||||||
|
|
|
@ -2,6 +2,7 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using PorygonSharp.EvalValues;
|
using PorygonSharp.EvalValues;
|
||||||
|
using PorygonSharp.UserData;
|
||||||
using PorygonSharp.Utilities;
|
using PorygonSharp.Utilities;
|
||||||
|
|
||||||
namespace PorygonSharp
|
namespace PorygonSharp
|
||||||
|
@ -20,6 +21,25 @@ namespace PorygonSharp
|
||||||
_variables.Add(o);
|
_variables.Add(o);
|
||||||
RegisterStaticVariable(hash, scriptType.Value, value.GetPointer());
|
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)]
|
[DllImport("PorygonLang", EntryPoint = "RegisterStaticVariable", CallingConvention = CallingConvention.Cdecl)]
|
||||||
private static extern void RegisterStaticVariable(uint hashId, IntPtr scriptType, IntPtr value);
|
private static extern void RegisterStaticVariable(uint hashId, IntPtr scriptType, IntPtr value);
|
||||||
|
|
|
@ -27,8 +27,7 @@ namespace PorygonSharp.UserData
|
||||||
var enumAttr = type.GetCustomAttribute<PorygonEnumAttribute>();
|
var enumAttr = type.GetCustomAttribute<PorygonEnumAttribute>();
|
||||||
if (enumAttr != null)
|
if (enumAttr != null)
|
||||||
{
|
{
|
||||||
RegisterEnumType(enumAttr.Name, type);
|
StaticScope.RegisterStaticEnum(enumAttr.Name, type);
|
||||||
StaticScope.RegisterStaticVariable(enumAttr.Name, Activator.CreateInstance(type));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,8 +15,7 @@ namespace PorygonSharpTests
|
||||||
[Test]
|
[Test]
|
||||||
public void AbleToAccessStaticEnumVariable()
|
public void AbleToAccessStaticEnumVariable()
|
||||||
{
|
{
|
||||||
UserDataHandler.RegisterEnumType("testEnum", typeof(testEnum));
|
StaticScope.RegisterStaticEnum("testEnum", typeof(testEnum));
|
||||||
StaticScope.RegisterStaticVariable("testEnum", testEnum.One);
|
|
||||||
using (var script = new Script(@"
|
using (var script = new Script(@"
|
||||||
return type(testEnum)
|
return type(testEnum)
|
||||||
"))
|
"))
|
||||||
|
@ -34,8 +33,7 @@ namespace PorygonSharpTests
|
||||||
[Test]
|
[Test]
|
||||||
public void AbleToUseStaticEnumVariable()
|
public void AbleToUseStaticEnumVariable()
|
||||||
{
|
{
|
||||||
UserDataHandler.RegisterEnumType("testEnum", typeof(testEnum));
|
StaticScope.RegisterStaticEnum("testEnum", typeof(testEnum));
|
||||||
StaticScope.RegisterStaticVariable("testEnum", testEnum.One);
|
|
||||||
using (var script = new Script(@"
|
using (var script = new Script(@"
|
||||||
return testEnum.Three + 2
|
return testEnum.Three + 2
|
||||||
"))
|
"))
|
||||||
|
|
Loading…
Reference in New Issue