master
Harald Wolff 2020-03-03 17:11:52 +01:00
parent 52e63b40e0
commit 78f5e181cf
8 changed files with 101 additions and 13 deletions

25
Cast.cs
View File

@ -33,7 +33,30 @@ namespace ln.types
!Explicit(value, value.GetType(), targetType, out casted)
)
{
casted = Convert.ChangeType(value, targetType);
if (targetType.IsEnum)
{
if (value is string sValue)
{
casted = Enum.Parse(targetType, sValue);
} else
{
throw new NotSupportedException();
}
}
else if (targetType.IsArray)
{
Array array = value as Array;
Array castedArray = Array.CreateInstance(targetType.GetElementType(), array.Length);
for (int n = 0; n < array.Length; n++)
castedArray.SetValue(To(array.GetValue(n), targetType.GetElementType()), n);
casted = castedArray;
}
else
{
casted = Convert.ChangeType(value, targetType);
}
}
return casted;
}

View File

@ -148,6 +148,7 @@
<Compile Include="reflection\ObjectPool.cs" />
<Compile Include="attributes\IdentityAttribute.cs" />
<Compile Include="reflection\ObjectPoolValue.cs" />
<Compile Include="reflection\TypeExtensions.cs" />
</ItemGroup>
<ItemGroup>
<Folder Include="odb\" />

View File

@ -27,11 +27,13 @@ namespace ln.types.reflection
{
Owner = propertyInfo.DeclaringType;
IsPublic = propertyInfo.GetGetMethod().IsPublic;
IsReadonly = !(propertyInfo.CanWrite && propertyInfo.GetSetMethod().IsPublic);
IsReadonly = !(propertyInfo.CanWrite && propertyInfo.GetSetMethod(true).IsPublic);
AttributeName = propertyInfo.Name;
AttributeType = propertyInfo.PropertyType;
SetAction = propertyInfo.SetValue;
if (propertyInfo.CanWrite)
SetAction = propertyInfo.SetValue;
GetFunc = propertyInfo.GetValue;
}
public AttributeDescriptor(FieldInfo fieldInfo)
@ -42,13 +44,18 @@ namespace ln.types.reflection
AttributeName = fieldInfo.Name;
AttributeType = fieldInfo.FieldType;
SetAction = fieldInfo.SetValue;
if (!fieldInfo.IsInitOnly)
SetAction = fieldInfo.SetValue;
GetFunc = fieldInfo.GetValue;
}
public TypeDescriptor TypeDescriptor => TypeDescriptor.GetDescriptor(Owner);
public object GetValue(object instance) => GetFunc(instance);
public void SetValue(object instance, object value) => SetAction(instance, value);
public void SetValue(object instance, object value) {
if (SetAction != null)
SetAction(instance, value);
}
}
}

View File

@ -1,6 +1,7 @@
using System;
using ln.types.btree;
using System.Collections.Generic;
using System.Linq;
namespace ln.types.reflection
{
public class ObjectPool
@ -24,10 +25,22 @@ namespace ln.types.reflection
getIdentity = getIdentityDelegate;
}
public IEnumerable<object> Identities => objects.Keys;
public IEnumerable<object> Instances => objects.Values;
public IEnumerable<object> Identities => objects.Keys.Concat(derivedTypes.SelectMany((op)=>op.Identities));
public IEnumerable<object> Instances => objects.Values.Concat(derivedTypes.SelectMany((op) => op.Instances));
public IEnumerable<object> OwnInstances => objects.Values;
public object this[object identity] => objects[identity];
public object this[object identity]
{
get
{
if (objects.ContainsKey(identity))
return objects[identity];
foreach (ObjectPool derivedPool in derivedTypes)
if (derivedPool.objects.ContainsKey(identity))
return derivedPool.objects[identity];
throw new KeyNotFoundException();
}
}
public void Add(object o) => objects.Add(GetIdentity(o), o);
public void Remove(object identity) => objects.Remove(identity);

View File

@ -19,6 +19,8 @@ namespace ln.types.reflection
public ObjectPool this[string typeName] => objectPools[typeName];
public ObjectPool this[Type type] => objectPools[type.Name];
public bool KnowsType(Type type) => objectPools.ContainsKey(type.Name);
public ObjectPoolContainer AddType(Type type) => AddType(type, null);
public ObjectPoolContainer AddType(Type type,String identityAttribute)
{
@ -44,7 +46,17 @@ namespace ln.types.reflection
public void SetupDerivedTypes(Type type)
{
Type current = type.BaseType;
while (!object.Equals(current, typeof(object)))
{
if (objectPools.ContainsKey(current.Name))
{
objectPools[current.Name].AddDerivedTypePool(objectPools[type.Name]);
break;
}
current = current.BaseType;
}
}

View File

@ -20,6 +20,8 @@ namespace ln.types.reflection
public TypeDescriptor(Type type)
{
Type = type;
typeDescriptors[type] = this;
foreach (FieldInfo fieldInfo in type.GetFields(BindingFlags.Instance | BindingFlags.Public))
@ -31,13 +33,15 @@ namespace ln.types.reflection
}
public IEnumerable<string> AttributeNames => attributeDescriptors.Keys;
public IEnumerable<AttributeDescriptor> AttributeDescriptors => attributeDescriptors.Values;
public AttributeDescriptor GetAttributeDescriptor(string attributeName) => attributeDescriptors[attributeName];
public bool ContainsAttribute(string attributeName) => attributeDescriptors.ContainsKey(attributeName);
static Dictionary<Type, TypeDescriptor> typeDescriptors = new Dictionary<Type, TypeDescriptor>();
public static TypeDescriptor GetDescriptor(Type type)
{
if (typeDescriptors.TryGetValue(type, out TypeDescriptor typeDescriptor))
if (!typeDescriptors.TryGetValue(type, out TypeDescriptor typeDescriptor))
return new TypeDescriptor(type);
return typeDescriptor;
}

View File

@ -0,0 +1,21 @@
using System;
using System.Linq;
namespace ln.types.reflection
{
public static class TypeExtensions
{
public static bool HasGenericInterface<T>(this Type type) => HasGenericInterface(type, typeof(T).GetGenericTypeDefinition());
public static bool HasGenericInterface(this Type type, Type genericInterfaceType)
{
return type.GetInterfaces().Any(x => x.IsGenericType && x.GetGenericTypeDefinition() == genericInterfaceType);
}
public static Type GetGenericInterface<T>(this Type type) => GetGenericInterface(type, typeof(T).GetGenericTypeDefinition());
public static Type GetGenericInterface(this Type type, Type genericInterfaceType)
{
return type.GetInterfaces().First(x => x.IsGenericType && x.GetGenericTypeDefinition() == genericInterfaceType);
}
}
}

View File

@ -47,15 +47,22 @@ namespace ln.types.threads
ThreadPool = new Pool(nThreads);
ThreadPool.Start();
schedulerThread = new Thread(scheduler);
schedulerThread.Start();
lock (this)
{
schedulerThread = new Thread(scheduler);
schedulerThread.Start();
Monitor.Wait(this);
}
}
void scheduler()
{
while (true)
lock (this)
{
lock (this)
Monitor.PulseAll(this);
while (true)
{
double now = DateTime.Now.ToUnixTimeMilliseconds();
if (schedule.Empty)