Support for easy loading assemblies, and instantly creating enums in the static scope

This commit is contained in:
Deukhoofd 2018-12-08 11:30:22 +01:00
parent 986d00b1a0
commit f6947194b9
No known key found for this signature in database
GPG Key ID: B4C087AC81641654
4 changed files with 57 additions and 14 deletions

View File

@ -0,0 +1,15 @@
using System;
namespace Upsilon.BaseTypes.UserData
{
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Enum, AllowMultiple = false, Inherited = true)]
public class UpsilonUserDataAttribute : Attribute
{
public UpsilonUserDataAttribute(string name)
{
Name = name;
}
public string Name { get; }
}
}

View File

@ -1,6 +1,8 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Reflection;
using Upsilon.BoundTypes; using Upsilon.BoundTypes;
using Upsilon.StandardLibraries;
namespace Upsilon.BaseTypes.UserData namespace Upsilon.BaseTypes.UserData
{ {
@ -8,25 +10,47 @@ namespace Upsilon.BaseTypes.UserData
{ {
private static readonly Dictionary<System.Type, UserDataType> Types = new Dictionary<System.Type, UserDataType>(); private static readonly Dictionary<System.Type, UserDataType> Types = new Dictionary<System.Type, UserDataType>();
public static void LoadType(System.Type t) public static void LoadType(System.Type t, string name)
{ {
var info = new UserDataType(t); var info = new UserDataType(t);
Types.Add(t, info); Types.Add(t, info);
UserDataBoundTypeDefinition boundType; UserDataBoundTypeDefinition boundType;
if (t.IsEnum) if (t.IsEnum)
{ {
boundType = new UserDataBoundEnumDefinition(t); boundType = new UserDataBoundEnumDefinition(t, name);
} }
else else
{ {
boundType = UserDataBoundTypeDefinition.Create(t); boundType = UserDataBoundTypeDefinition.Create(t, name);
} }
BoundTypeHandler.LoadUserDataTypeDefinition(boundType); BoundTypeHandler.LoadUserDataTypeDefinition(boundType);
} }
public static void LoadAssembly(Assembly assembly)
{
var types = assembly.GetTypes();
foreach (var type in types)
{
var attr = (UpsilonUserDataAttribute)type.GetCustomAttribute(typeof(UpsilonUserDataAttribute));
if (attr != null)
{
var name = attr.Name.ToLowerInvariant();
LoadType(type, name);
if (type.IsEnum)
{
var def = Activator.CreateInstance(type);
StaticScope.RegisterStaticVariable(attr.Name, def);
}
}
}
}
public static void LoadType<T>() public static void LoadType<T>()
{ {
LoadType(typeof(T)); var attr = (UpsilonUserDataAttribute)typeof(T).GetCustomAttribute(typeof(UpsilonUserDataAttribute));
var name = typeof(T).Name;
if (attr != null) name = attr.Name;
LoadType(typeof(T), name);
} }
internal static UserDataType GetTypeInfo(System.Type t) internal static UserDataType GetTypeInfo(System.Type t)

View File

@ -39,6 +39,7 @@ namespace Upsilon.BoundTypes
} }
return null; return null;
} }
public static BoundTypeDefinition GetTypeDefinition(System.Type type) public static BoundTypeDefinition GetTypeDefinition(System.Type type)
{ {
return _typeDefinitions.Values.FirstOrDefault(x => x.ValidInternalTypes.Contains(type)); return _typeDefinitions.Values.FirstOrDefault(x => x.ValidInternalTypes.Contains(type));

View File

@ -10,7 +10,7 @@ namespace Upsilon.BoundTypes
{ {
public class UserDataBoundTypeDefinition : BoundTypeDefinition public class UserDataBoundTypeDefinition : BoundTypeDefinition
{ {
public string Name { get; } public string Name { get; protected set; }
public Dictionary<string, UserDataBoundProperty> Properties { get; protected set; } public Dictionary<string, UserDataBoundProperty> Properties { get; protected set; }
internal UserDataBoundTypeDefinition(System.Type backingType) internal UserDataBoundTypeDefinition(System.Type backingType)
@ -28,11 +28,12 @@ namespace Upsilon.BoundTypes
public static UserDataBoundTypeDefinition Create(System.Type backingType) public static UserDataBoundTypeDefinition Create(System.Type backingType, string name)
{ {
var obj = new UserDataBoundTypeDefinition(backingType) var obj = new UserDataBoundTypeDefinition(backingType)
{ {
Properties = new Dictionary<string, UserDataBoundProperty>() Properties = new Dictionary<string, UserDataBoundProperty>(),
Name = name
}; };
var fields = backingType.GetFields().Select(x => new UserDataBoundProperty() var fields = backingType.GetFields().Select(x => new UserDataBoundProperty()
{ {
@ -60,15 +61,15 @@ namespace Upsilon.BoundTypes
{ {
if (backingMethod.IsSpecialName) if (backingMethod.IsSpecialName)
continue; continue;
var name = backingMethod.Name; var methodName = backingMethod.Name;
var attribute = backingMethod.GetCustomAttribute(typeof(ScriptFunctionAttribute)); var attribute = backingMethod.GetCustomAttribute(typeof(ScriptFunctionAttribute));
if (attribute is ScriptFunctionAttribute sfa ) if (attribute is ScriptFunctionAttribute sfa )
{ {
name = sfa.Name; methodName = sfa.Name;
} }
methods.Add(new UserDataBoundMethod() methods.Add(new UserDataBoundMethod()
{ {
Name = name, Name = methodName,
Type = Type.Function, Type = Type.Function,
ResultType = backingMethod.ReturnType.GetScriptType() ResultType = backingMethod.ReturnType.GetScriptType()
}); });
@ -88,7 +89,7 @@ namespace Upsilon.BoundTypes
public class UserDataBoundEnumDefinition : UserDataBoundTypeDefinition public class UserDataBoundEnumDefinition : UserDataBoundTypeDefinition
{ {
public UserDataBoundEnumDefinition(System.Type enumType) : base(enumType) public UserDataBoundEnumDefinition(System.Type enumType, string name) : base(enumType)
{ {
if (!enumType.IsEnum) if (!enumType.IsEnum)
throw new Exception("Trying to bind an enum with a type that's not an enum"); throw new Exception("Trying to bind an enum with a type that's not an enum");
@ -97,14 +98,16 @@ namespace Upsilon.BoundTypes
var enumUnderlyingType = Enum.GetUnderlyingType(enumType); var enumUnderlyingType = Enum.GetUnderlyingType(enumType);
var enumValues = Enum.GetValues(enumType); var enumValues = Enum.GetValues(enumType);
Name = name;
for (var i=0; i < enumValues.Length; i++) for (var i=0; i < enumValues.Length; i++)
{ {
var value = enumValues.GetValue(i); var value = enumValues.GetValue(i);
var name = value.ToString().ToLowerInvariant(); var valueName = value.ToString().ToLowerInvariant();
Properties.Add(name, new UserDataBoundProperty() Properties.Add(valueName, new UserDataBoundProperty()
{ {
Name = name, Name = valueName,
ActualType = enumUnderlyingType.ToString(), ActualType = enumUnderlyingType.ToString(),
Type = Type.Number Type = Type.Number
}); });