Support for enums, and adding static variables
This commit is contained in:
parent
d2cc82dc21
commit
6ecbfe2074
|
@ -0,0 +1,6 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="RiderProjectSettingsUpdater">
|
||||||
|
<option name="vcsConfiguration" value="1" />
|
||||||
|
</component>
|
||||||
|
</project>
|
|
@ -0,0 +1,14 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace PorygonSharp.Attributes
|
||||||
|
{
|
||||||
|
public class PorygonEnumAttribute : Attribute
|
||||||
|
{
|
||||||
|
public string Name { get; }
|
||||||
|
|
||||||
|
public PorygonEnumAttribute(string name)
|
||||||
|
{
|
||||||
|
Name = name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace PorygonSharp.Attributes
|
||||||
|
{
|
||||||
|
public class PorygonUserdataAttribute : Attribute
|
||||||
|
{
|
||||||
|
public string Identifier { get; }
|
||||||
|
public PorygonUserdataAttribute(string identifier)
|
||||||
|
{
|
||||||
|
Identifier = identifier;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -11,6 +11,12 @@ namespace PorygonSharp.EvalValues
|
||||||
public static EvalValue CreateValue(object o)
|
public static EvalValue CreateValue(object o)
|
||||||
{
|
{
|
||||||
var type = o.GetType();
|
var type = o.GetType();
|
||||||
|
if (type.IsEnum)
|
||||||
|
{
|
||||||
|
var typeHash = UserDataHandler.GetTypeId(type);
|
||||||
|
var handle = GCHandle.Alloc(o, GCHandleType.WeakTrackResurrection);
|
||||||
|
return new EvalValue(CreateUserDataEvalValue(typeHash, GCHandle.ToIntPtr(handle)));
|
||||||
|
}
|
||||||
var typeCode = Type.GetTypeCode(type);
|
var typeCode = Type.GetTypeCode(type);
|
||||||
switch (typeCode)
|
switch (typeCode)
|
||||||
{
|
{
|
||||||
|
@ -57,7 +63,7 @@ namespace PorygonSharp.EvalValues
|
||||||
}
|
}
|
||||||
|
|
||||||
[DllImport("libPorygonLang", EntryPoint = "CreateIntegerEvalValue",CallingConvention = CallingConvention.Cdecl)]
|
[DllImport("libPorygonLang", EntryPoint = "CreateIntegerEvalValue",CallingConvention = CallingConvention.Cdecl)]
|
||||||
private static extern IntPtr CreateIntegerEvalValue(long l);
|
internal static extern IntPtr CreateIntegerEvalValue(long l);
|
||||||
[DllImport("libPorygonLang", EntryPoint = "CreateFloatEvalValue",CallingConvention = CallingConvention.Cdecl)]
|
[DllImport("libPorygonLang", EntryPoint = "CreateFloatEvalValue",CallingConvention = CallingConvention.Cdecl)]
|
||||||
private static extern IntPtr CreateFloatEvalValue(double d);
|
private static extern IntPtr CreateFloatEvalValue(double d);
|
||||||
[DllImport("libPorygonLang", EntryPoint = "CreateBoolEvalValue",CallingConvention = CallingConvention.Cdecl)]
|
[DllImport("libPorygonLang", EntryPoint = "CreateBoolEvalValue",CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
|
|
@ -11,6 +11,10 @@ namespace PorygonSharp.ScriptType
|
||||||
{
|
{
|
||||||
internal static IntPtr GetScriptType(Type t)
|
internal static IntPtr GetScriptType(Type t)
|
||||||
{
|
{
|
||||||
|
if (t.IsEnum)
|
||||||
|
{
|
||||||
|
return UserDataHandler.CreateUserDataType(t);
|
||||||
|
}
|
||||||
var typeCode = Type.GetTypeCode(t);
|
var typeCode = Type.GetTypeCode(t);
|
||||||
switch (typeCode)
|
switch (typeCode)
|
||||||
{
|
{
|
||||||
|
@ -95,7 +99,7 @@ namespace PorygonSharp.ScriptType
|
||||||
private static extern IntPtr CreateScriptType(TypeClass t);
|
private static extern IntPtr CreateScriptType(TypeClass t);
|
||||||
|
|
||||||
[DllImport("libPorygonLang", EntryPoint = "CreateNumericScriptType", CallingConvention = CallingConvention.Cdecl)]
|
[DllImport("libPorygonLang", EntryPoint = "CreateNumericScriptType", CallingConvention = CallingConvention.Cdecl)]
|
||||||
private static extern IntPtr CreateNumericScriptType(bool isAware, bool isFloat);
|
internal static extern IntPtr CreateNumericScriptType(bool isAware, bool isFloat);
|
||||||
|
|
||||||
[DllImport("libPorygonLang", EntryPoint = "CreateStringScriptType", CallingConvention = CallingConvention.Cdecl)]
|
[DllImport("libPorygonLang", EntryPoint = "CreateStringScriptType", CallingConvention = CallingConvention.Cdecl)]
|
||||||
private static extern IntPtr CreateStringScriptType(bool knownAtBind, uint hash);
|
private static extern IntPtr CreateStringScriptType(bool knownAtBind, uint hash);
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
using System;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using PorygonSharp.EvalValues;
|
||||||
|
using PorygonSharp.Utilities;
|
||||||
|
|
||||||
|
namespace PorygonSharp
|
||||||
|
{
|
||||||
|
public static class StaticScope
|
||||||
|
{
|
||||||
|
public static void RegisterStaticVariable(string name, object o)
|
||||||
|
{
|
||||||
|
var type = o.GetType();
|
||||||
|
var scriptType = ScriptType.ScriptType.GetScriptType(type);
|
||||||
|
var hash = name.ScriptHash();
|
||||||
|
var value = EvalValueCreator.CreateValue(o);
|
||||||
|
RegisterStaticVariable(hash, scriptType, value.GetPointer());
|
||||||
|
}
|
||||||
|
|
||||||
|
[DllImport("libPorygonLang", EntryPoint = "RegisterStaticVariable", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
private static extern void RegisterStaticVariable(uint hashId, IntPtr scriptType, IntPtr value);
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
using PorygonSharp.Attributes;
|
||||||
using PorygonSharp.EvalValues;
|
using PorygonSharp.EvalValues;
|
||||||
using PorygonSharp.Utilities;
|
using PorygonSharp.Utilities;
|
||||||
|
|
||||||
|
@ -17,6 +18,25 @@ namespace PorygonSharp.UserData
|
||||||
private delegate IntPtr CallerDelegate(IntPtr parent, IntPtr scriptOption,
|
private delegate IntPtr CallerDelegate(IntPtr parent, IntPtr scriptOption,
|
||||||
[MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)]IntPtr[] parameters, int size);
|
[MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)]IntPtr[] parameters, int size);
|
||||||
|
|
||||||
|
public static void RegisterAssembly(Assembly assembly)
|
||||||
|
{
|
||||||
|
foreach (var type in assembly.GetTypes())
|
||||||
|
{
|
||||||
|
var attr = type.GetCustomAttribute<PorygonUserdataAttribute>();
|
||||||
|
if (attr != null)
|
||||||
|
{
|
||||||
|
RegisterType(attr.Identifier, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
var enumAttr = type.GetCustomAttribute<PorygonEnumAttribute>();
|
||||||
|
if (enumAttr != null)
|
||||||
|
{
|
||||||
|
RegisterEnumType(enumAttr.Name, type);
|
||||||
|
StaticScope.RegisterStaticVariable(enumAttr.Name, Activator.CreateInstance(type));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void RegisterType(string name, Type type)
|
public static void RegisterType(string name, Type type)
|
||||||
{
|
{
|
||||||
var hash = name.ScriptHash();
|
var hash = name.ScriptHash();
|
||||||
|
@ -46,6 +66,26 @@ namespace PorygonSharp.UserData
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void RegisterEnumType(string name, Type type)
|
||||||
|
{
|
||||||
|
var hash = name.ScriptHash();
|
||||||
|
RegisterUserDataType(hash);
|
||||||
|
if (UserDataLookup.ContainsKey(type))
|
||||||
|
return;
|
||||||
|
UserDataLookup.Add(type, hash);
|
||||||
|
var values = Enum.GetValues(type);
|
||||||
|
foreach (var value in values)
|
||||||
|
{
|
||||||
|
var getter = new GetterDelegate(ptr => EvalValueCreator.CreateIntegerEvalValue(Convert.ToInt64(value)));
|
||||||
|
var valueName = Enum.GetName(type, value);
|
||||||
|
var fieldName = valueName.ScriptHash();
|
||||||
|
var t = ScriptType.ScriptType.CreateNumericScriptType(true, false);
|
||||||
|
RegisterUserDataField(hash, fieldName,
|
||||||
|
CreateUserDataField(t, Marshal.GetFunctionPointerForDelegate(getter), IntPtr.Zero));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
private static void RegisterField(FieldInfo field, uint typeHash)
|
private static void RegisterField(FieldInfo field, uint typeHash)
|
||||||
{
|
{
|
||||||
var getter = new GetterDelegate(ptr =>
|
var getter = new GetterDelegate(ptr =>
|
||||||
|
|
Binary file not shown.
|
@ -0,0 +1,54 @@
|
||||||
|
using System;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using PorygonSharp;
|
||||||
|
using PorygonSharp.UserData;
|
||||||
|
|
||||||
|
namespace PorygonSharpTests
|
||||||
|
{
|
||||||
|
public class EnumUserdataTest
|
||||||
|
{
|
||||||
|
private enum testEnum
|
||||||
|
{
|
||||||
|
One, Two, Three, Foo, Bar
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void AbleToAccessStaticEnumVariable()
|
||||||
|
{
|
||||||
|
UserDataHandler.RegisterEnumType("testEnum", typeof(testEnum));
|
||||||
|
StaticScope.RegisterStaticVariable("testEnum", testEnum.One);
|
||||||
|
using (var script = new Script(@"
|
||||||
|
return type(testEnum)
|
||||||
|
"))
|
||||||
|
{
|
||||||
|
var diags = script.Diagnostics.GetDiagnostics();
|
||||||
|
foreach (var diag in diags)
|
||||||
|
{
|
||||||
|
throw new Exception(script.Diagnostics.GetFullDiagnosticMessage(diag));
|
||||||
|
}
|
||||||
|
var result = script.Evaluate();
|
||||||
|
Assert.AreEqual("userdata", result.EvaluateString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void AbleToUseStaticEnumVariable()
|
||||||
|
{
|
||||||
|
UserDataHandler.RegisterEnumType("testEnum", typeof(testEnum));
|
||||||
|
StaticScope.RegisterStaticVariable("testEnum", testEnum.One);
|
||||||
|
using (var script = new Script(@"
|
||||||
|
return testEnum.Three + 2
|
||||||
|
"))
|
||||||
|
{
|
||||||
|
var diags = script.Diagnostics.GetDiagnostics();
|
||||||
|
foreach (var diag in diags)
|
||||||
|
{
|
||||||
|
throw new Exception(script.Diagnostics.GetFullDiagnosticMessage(diag));
|
||||||
|
}
|
||||||
|
var result = script.Evaluate();
|
||||||
|
Assert.AreEqual(4, result.EvaluateInteger());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue