Upsilon/Upsilon/BoundTypes/BoundTypeHandler.cs

87 lines
3.2 KiB
C#

using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using Upsilon.BaseTypes;
namespace Upsilon.BoundTypes
{
public static class BoundTypeHandler
{
private static void AddDefaults(ConcurrentDictionary<string, BoundTypeDefinition> dic)
{
dic.TryAdd("string", new BoundTypeDefinition(Type.String, typeof(string)));
dic.TryAdd("number", new BoundTypeDefinition(Type.Number,
new[] {typeof(int), typeof(long), typeof(float), typeof(double), typeof(byte)}));
dic.TryAdd("bool", new BoundTypeDefinition(Type.Boolean, typeof(bool)));
dic.TryAdd("table", new BoundTypeDefinition(Type.Table, typeof(IEnumerator)));
dic.TryAdd("function", new BoundTypeDefinition(Type.Function, new System.Type[0]));
}
private static readonly ConcurrentDictionary<System.Type, string> TypeLookup =
new ConcurrentDictionary<System.Type, string>();
private static readonly ConcurrentDictionary<string, BoundTypeDefinition> TypeDefinitions = Reset();
public static ConcurrentDictionary<string, BoundTypeDefinition> Reset()
{
var dic = new ConcurrentDictionary<string, BoundTypeDefinition>();
AddDefaults(dic);
foreach (var boundTypeDefinition in dic)
{
foreach (var valueValidInternalType in boundTypeDefinition.Value.ValidInternalTypes)
{
TypeLookup.TryAdd(valueValidInternalType, boundTypeDefinition.Key);
}
}
return dic;
}
public static BoundTypeDefinition GetTypeDefinition(string key)
{
var normalizedName = key.ToLowerInvariant();
if (TypeDefinitions.TryGetValue(normalizedName, out var bt))
{
return bt;
}
return null;
}
public static BoundTypeDefinition GetTypeDefinition(System.Type type)
{
return TypeDefinitions.Values.FirstOrDefault(x => x.ValidInternalTypes.Contains(type));
}
public static string GetTypeName(System.Type type)
{
if (type == null)
return null;
if (TypeLookup.TryGetValue(type, out var bDefKey))
{
return bDefKey;
}
var bDef = TypeDefinitions.FirstOrDefault(x =>
{
var first = x.Value.ValidInternalTypes.FirstOrDefault();
if (first == null)
return false;
return first.IsAssignableFrom(type);
});
if (!bDef.Equals(default(KeyValuePair<string, BoundTypeDefinition>)))
{
TypeLookup.TryAdd(type, bDef.Key);
}
return null;
}
public static void LoadUserDataTypeDefinition(UserDataBoundTypeDefinition def)
{
var key = def.Name.ToLowerInvariant();
TypeDefinitions.AddOrUpdate(key, def, (s, definition) => definition);
foreach (var valueValidInternalType in def.ValidInternalTypes)
{
TypeLookup.TryAdd(valueValidInternalType, key);
}
}
}
}