Various changes and tweaks to run better

This commit is contained in:
2018-12-08 16:18:38 +01:00
parent f6947194b9
commit 43d9360145
15 changed files with 142 additions and 75 deletions

View File

@@ -5,10 +5,10 @@ namespace Upsilon.BaseTypes.UserData
{
internal sealed class GenericUserData : ScriptType, IUserData
{
public GenericUserData(object dictionary)
public GenericUserData(object obj)
{
Value = dictionary;
_typeInfo = UserDataTypeHandler.GetTypeInfo(dictionary.GetType());
Value = obj;
_typeInfo = UserDataTypeHandler.GetTypeInfo(obj.GetType());
}
public override Type Type => Type.UserData;

View File

@@ -0,0 +1,9 @@
using System;
namespace Upsilon.BaseTypes.UserData
{
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property | AttributeTargets.Method)]
public class UpsilonHiddenAttribute : Attribute
{
}
}

View File

@@ -2,7 +2,8 @@ using System;
namespace Upsilon.BaseTypes.UserData
{
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Enum, AllowMultiple = false, Inherited = true)]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Enum | AttributeTargets.Interface,
AllowMultiple = false, Inherited = true)]
public class UpsilonUserDataAttribute : Attribute
{
public UpsilonUserDataAttribute(string name)

View File

@@ -38,6 +38,8 @@ namespace Upsilon.BaseTypes.UserData
public UserDataMethodParameter(ParameterInfo info)
{
Type = info.ParameterType;
if (Type.IsGenericType)
Type = Type.GetGenericTypeDefinition();
IsOptional = info.IsOptional;
}
@@ -89,6 +91,7 @@ namespace Upsilon.BaseTypes.UserData
break;
}
var parameter = parameterTypes[index];
if (parameter.IsGenericType) parameter = parameter.GetGenericTypeDefinition();
if (userDataMethodParameter.Type != parameter &&
!userDataMethodParameter.Type.IsAssignableFrom(parameter))
{

View File

@@ -10,12 +10,20 @@ namespace Upsilon.BaseTypes.UserData
{
public UserDataType(System.Type type)
{
if (type.IsGenericType)
{
type = type.GetGenericTypeDefinition();
}
Type = type;
Variables = type.GetFields().ToDictionary(x => x.Name.ToLowerInvariant(), x => x);
Properties = type.GetProperties().ToDictionary(x => x.Name.ToLowerInvariant(), x => x);
Methods = new Dictionary<string, UserDataMethod>();
foreach (var methodInfo in type.GetMethods())
{
var hiddenAttribute = methodInfo.GetCustomAttribute(typeof(UpsilonHiddenAttribute));
if (hiddenAttribute != null)
continue;
var commonName = methodInfo.Name.ToLowerInvariant();
var attribute = methodInfo.GetCustomAttribute(typeof(ScriptFunctionAttribute));
if (attribute is ScriptFunctionAttribute sfa )
@@ -43,7 +51,10 @@ namespace Upsilon.BaseTypes.UserData
public (ScriptType Type, bool Failed, string Error) Get(object value, string member)
{
if (value.GetType() != Type)
var valueType = value.GetType();
if (valueType.IsGenericType)
valueType = valueType.GetGenericTypeDefinition();
if (valueType != Type)
return (null, true, "Invalid Type");
member = member.ToLowerInvariant();
if (Variables.TryGetValue(member, out var info))
@@ -93,6 +104,12 @@ namespace Upsilon.BaseTypes.UserData
return (new ScriptNull(), true);
}
// HACK: Ugly solution for generic methods
if (method.ContainsGenericParameters)
{
method = value.GetType().GetMethod(method.Name, new[] {par1.GetCSharpType(), par2.GetCSharpType()});
}
return (method.Invoke(value, new[] {par1.ToCSharpObject(), par2.ToCSharpObject()}).ToScriptType(), false);
}
public (ScriptType Type, bool Failed) UnaryOperator(object value, ScriptType par1, OperatorType op)
@@ -103,6 +120,12 @@ namespace Upsilon.BaseTypes.UserData
return (new ScriptNull(), true);
}
// HACK: Ugly solution for generic methods
if (method.ContainsGenericParameters)
{
method = value.GetType().GetMethod(method.Name, new[] {par1.GetCSharpType()});
}
return (method.Invoke(value, new[] {par1.ToCSharpObject()}).ToScriptType(), false);
}
}

View File

@@ -1,19 +1,23 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Reflection;
using Upsilon.BoundTypes;
using Upsilon.Exceptions;
using Upsilon.StandardLibraries;
using Upsilon.Text;
namespace Upsilon.BaseTypes.UserData
{
public static class UserDataTypeHandler
{
private static readonly Dictionary<System.Type, UserDataType> Types = new Dictionary<System.Type, UserDataType>();
private static readonly ConcurrentDictionary<System.Type, UserDataType> Types
= new ConcurrentDictionary<System.Type, UserDataType>();
public static void LoadType(System.Type t, string name)
{
var info = new UserDataType(t);
Types.Add(t, info);
Types.AddOrUpdate(t, info, (type, dataType) => dataType);
UserDataBoundTypeDefinition boundType;
if (t.IsEnum)
{
@@ -55,7 +59,14 @@ namespace Upsilon.BaseTypes.UserData
internal static UserDataType GetTypeInfo(System.Type t)
{
return Types[t];
if (t.IsGenericType)
t = t.GetGenericTypeDefinition();
if (Types.TryGetValue(t, out var result))
return result;
else
{
throw new Exception($"Can't use type '{t.FullName}' as script type, it's not registered for use.");
}
}
}
}

View File

@@ -86,6 +86,9 @@ namespace Upsilon.BaseTypes.UserData
{
return null;
}
if (t1.IsGenericType) t1 = t1.GetGenericTypeDefinition();
if (t2.IsGenericType) t2 = t2.GetGenericTypeDefinition();
foreach (var operatorMethod in m)
{