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) !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; return casted;
} }

View File

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

View File

@ -27,11 +27,13 @@ namespace ln.types.reflection
{ {
Owner = propertyInfo.DeclaringType; Owner = propertyInfo.DeclaringType;
IsPublic = propertyInfo.GetGetMethod().IsPublic; IsPublic = propertyInfo.GetGetMethod().IsPublic;
IsReadonly = !(propertyInfo.CanWrite && propertyInfo.GetSetMethod().IsPublic); IsReadonly = !(propertyInfo.CanWrite && propertyInfo.GetSetMethod(true).IsPublic);
AttributeName = propertyInfo.Name; AttributeName = propertyInfo.Name;
AttributeType = propertyInfo.PropertyType; AttributeType = propertyInfo.PropertyType;
SetAction = propertyInfo.SetValue; if (propertyInfo.CanWrite)
SetAction = propertyInfo.SetValue;
GetFunc = propertyInfo.GetValue; GetFunc = propertyInfo.GetValue;
} }
public AttributeDescriptor(FieldInfo fieldInfo) public AttributeDescriptor(FieldInfo fieldInfo)
@ -42,13 +44,18 @@ namespace ln.types.reflection
AttributeName = fieldInfo.Name; AttributeName = fieldInfo.Name;
AttributeType = fieldInfo.FieldType; AttributeType = fieldInfo.FieldType;
SetAction = fieldInfo.SetValue; if (!fieldInfo.IsInitOnly)
SetAction = fieldInfo.SetValue;
GetFunc = fieldInfo.GetValue; GetFunc = fieldInfo.GetValue;
} }
public TypeDescriptor TypeDescriptor => TypeDescriptor.GetDescriptor(Owner); public TypeDescriptor TypeDescriptor => TypeDescriptor.GetDescriptor(Owner);
public object GetValue(object instance) => GetFunc(instance); 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 System;
using ln.types.btree; using ln.types.btree;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
namespace ln.types.reflection namespace ln.types.reflection
{ {
public class ObjectPool public class ObjectPool
@ -24,10 +25,22 @@ namespace ln.types.reflection
getIdentity = getIdentityDelegate; getIdentity = getIdentityDelegate;
} }
public IEnumerable<object> Identities => objects.Keys; public IEnumerable<object> Identities => objects.Keys.Concat(derivedTypes.SelectMany((op)=>op.Identities));
public IEnumerable<object> Instances => objects.Values; 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 Add(object o) => objects.Add(GetIdentity(o), o);
public void Remove(object identity) => objects.Remove(identity); 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[string typeName] => objectPools[typeName];
public ObjectPool this[Type type] => objectPools[type.Name]; 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) => AddType(type, null);
public ObjectPoolContainer AddType(Type type,String identityAttribute) public ObjectPoolContainer AddType(Type type,String identityAttribute)
{ {
@ -44,7 +46,17 @@ namespace ln.types.reflection
public void SetupDerivedTypes(Type type) 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) public TypeDescriptor(Type type)
{ {
Type = type;
typeDescriptors[type] = this; typeDescriptors[type] = this;
foreach (FieldInfo fieldInfo in type.GetFields(BindingFlags.Instance | BindingFlags.Public)) 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<string> AttributeNames => attributeDescriptors.Keys;
public IEnumerable<AttributeDescriptor> AttributeDescriptors => attributeDescriptors.Values;
public AttributeDescriptor GetAttributeDescriptor(string attributeName) => attributeDescriptors[attributeName]; public AttributeDescriptor GetAttributeDescriptor(string attributeName) => attributeDescriptors[attributeName];
public bool ContainsAttribute(string attributeName) => attributeDescriptors.ContainsKey(attributeName); public bool ContainsAttribute(string attributeName) => attributeDescriptors.ContainsKey(attributeName);
static Dictionary<Type, TypeDescriptor> typeDescriptors = new Dictionary<Type, TypeDescriptor>(); static Dictionary<Type, TypeDescriptor> typeDescriptors = new Dictionary<Type, TypeDescriptor>();
public static TypeDescriptor GetDescriptor(Type type) 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 new TypeDescriptor(type);
return typeDescriptor; 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 = new Pool(nThreads);
ThreadPool.Start(); ThreadPool.Start();
schedulerThread = new Thread(scheduler); lock (this)
schedulerThread.Start(); {
schedulerThread = new Thread(scheduler);
schedulerThread.Start();
Monitor.Wait(this);
}
} }
void scheduler() void scheduler()
{ {
while (true) lock (this)
{ {
lock (this) Monitor.PulseAll(this);
while (true)
{ {
double now = DateTime.Now.ToUnixTimeMilliseconds(); double now = DateTime.Now.ToUnixTimeMilliseconds();
if (schedule.Empty) if (schedule.Empty)