diff --git a/.idea/.idea.PorygonSharp/.idea/projectSettingsUpdater.xml b/.idea/.idea.PorygonSharp/.idea/projectSettingsUpdater.xml
new file mode 100644
index 0000000..7515e76
--- /dev/null
+++ b/.idea/.idea.PorygonSharp/.idea/projectSettingsUpdater.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/PorygonSharp/Attributes/PorygonEnumAttribute.cs b/PorygonSharp/Attributes/PorygonEnumAttribute.cs
new file mode 100644
index 0000000..b1a1725
--- /dev/null
+++ b/PorygonSharp/Attributes/PorygonEnumAttribute.cs
@@ -0,0 +1,14 @@
+using System;
+
+namespace PorygonSharp.Attributes
+{
+ public class PorygonEnumAttribute : Attribute
+ {
+ public string Name { get; }
+
+ public PorygonEnumAttribute(string name)
+ {
+ Name = name;
+ }
+ }
+}
\ No newline at end of file
diff --git a/PorygonSharp/Attributes/PorygonUserdataAttribute.cs b/PorygonSharp/Attributes/PorygonUserdataAttribute.cs
new file mode 100644
index 0000000..29d896d
--- /dev/null
+++ b/PorygonSharp/Attributes/PorygonUserdataAttribute.cs
@@ -0,0 +1,13 @@
+using System;
+
+namespace PorygonSharp.Attributes
+{
+ public class PorygonUserdataAttribute : Attribute
+ {
+ public string Identifier { get; }
+ public PorygonUserdataAttribute(string identifier)
+ {
+ Identifier = identifier;
+ }
+ }
+}
\ No newline at end of file
diff --git a/PorygonSharp/EvalValues/EvalValueCreator.cs b/PorygonSharp/EvalValues/EvalValueCreator.cs
index 559d9fd..43eb1d9 100644
--- a/PorygonSharp/EvalValues/EvalValueCreator.cs
+++ b/PorygonSharp/EvalValues/EvalValueCreator.cs
@@ -11,6 +11,12 @@ namespace PorygonSharp.EvalValues
public static EvalValue CreateValue(object o)
{
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);
switch (typeCode)
{
@@ -57,7 +63,7 @@ namespace PorygonSharp.EvalValues
}
[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)]
private static extern IntPtr CreateFloatEvalValue(double d);
[DllImport("libPorygonLang", EntryPoint = "CreateBoolEvalValue",CallingConvention = CallingConvention.Cdecl)]
diff --git a/PorygonSharp/ScriptType/ScriptType.cs b/PorygonSharp/ScriptType/ScriptType.cs
index f5dd1d8..cb83ac5 100644
--- a/PorygonSharp/ScriptType/ScriptType.cs
+++ b/PorygonSharp/ScriptType/ScriptType.cs
@@ -11,6 +11,10 @@ namespace PorygonSharp.ScriptType
{
internal static IntPtr GetScriptType(Type t)
{
+ if (t.IsEnum)
+ {
+ return UserDataHandler.CreateUserDataType(t);
+ }
var typeCode = Type.GetTypeCode(t);
switch (typeCode)
{
@@ -95,7 +99,7 @@ namespace PorygonSharp.ScriptType
private static extern IntPtr CreateScriptType(TypeClass t);
[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)]
private static extern IntPtr CreateStringScriptType(bool knownAtBind, uint hash);
diff --git a/PorygonSharp/StaticScope.cs b/PorygonSharp/StaticScope.cs
new file mode 100644
index 0000000..7a56698
--- /dev/null
+++ b/PorygonSharp/StaticScope.cs
@@ -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);
+ }
+}
\ No newline at end of file
diff --git a/PorygonSharp/UserData/UserDataHandler.cs b/PorygonSharp/UserData/UserDataHandler.cs
index e0c7e3c..e032298 100644
--- a/PorygonSharp/UserData/UserDataHandler.cs
+++ b/PorygonSharp/UserData/UserDataHandler.cs
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
+using PorygonSharp.Attributes;
using PorygonSharp.EvalValues;
using PorygonSharp.Utilities;
@@ -17,6 +18,25 @@ namespace PorygonSharp.UserData
private delegate IntPtr CallerDelegate(IntPtr parent, IntPtr scriptOption,
[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();
+ if (attr != null)
+ {
+ RegisterType(attr.Identifier, type);
+ }
+
+ var enumAttr = type.GetCustomAttribute();
+ if (enumAttr != null)
+ {
+ RegisterEnumType(enumAttr.Name, type);
+ StaticScope.RegisterStaticVariable(enumAttr.Name, Activator.CreateInstance(type));
+ }
+ }
+ }
+
public static void RegisterType(string name, Type type)
{
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)
{
var getter = new GetterDelegate(ptr =>
diff --git a/PorygonSharp/libPorygonLang.so b/PorygonSharp/libPorygonLang.so
index e4471f5..d1bec0f 100755
Binary files a/PorygonSharp/libPorygonLang.so and b/PorygonSharp/libPorygonLang.so differ
diff --git a/PorygonSharpTests/EnumUserdataTest.cs b/PorygonSharpTests/EnumUserdataTest.cs
new file mode 100644
index 0000000..9b8fc35
--- /dev/null
+++ b/PorygonSharpTests/EnumUserdataTest.cs
@@ -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());
+ }
+ }
+
+ }
+}
\ No newline at end of file