@@ -143,7 +143,7 @@ namespace Svelto.ECS | |||
if (baseType.IsGenericTypeEx()) | |||
{ | |||
var genericArguments = baseType.GetGenericArguments(); | |||
var genericArguments = baseType.GetGenericArgumentsEx(); | |||
AddEngine(engine as IHandleEntityViewEngine, genericArguments, _entityViewEngines); | |||
#if EXPERIMENTAL | |||
var activableEngine = engine as IHandleActivableEntityEngine; | |||
@@ -132,7 +132,7 @@ namespace Svelto.ECS.Internal | |||
Type[] interfaces; | |||
if (_cachedTypes.TryGetValue(type, out interfaces) == false) | |||
interfaces = _cachedTypes[type] = type.GetInterfaces(); | |||
interfaces = _cachedTypes[type] = type.GetInterfacesEx(); | |||
for (int iindex = 0; iindex < interfaces.Length; iindex++) | |||
{ | |||
@@ -161,7 +161,7 @@ namespace Svelto.ECS.Internal | |||
//Very efficent way to collect the fields of every EntityViewType | |||
KeyValuePair<Type, Action<EntityView, object>>[] setters = | |||
FasterList<KeyValuePair<Type, Action<EntityView, object>>>.NoVirt.ToArrayFast(entityView.EntityViewBlazingFastReflection, out count); | |||
FasterList<KeyValuePair<Type, Action<EntityView, object>>>.NoVirt.ToArrayFast(entityView.entityViewBlazingFastReflection, out count); | |||
var removeEntityComponentType = typeof(IRemoveEntityComponent); | |||
@@ -16,11 +16,11 @@ namespace Svelto.ECS | |||
new int ID { set; } | |||
} | |||
public abstract class EntityView : IEntityView | |||
public class EntityView : IEntityView | |||
{ | |||
public int ID { get { return _ID; } } | |||
internal FasterList<KeyValuePair<Type, Action<EntityView, object>>> EntityViewBlazingFastReflection; | |||
internal FasterList<KeyValuePair<Type, Action<EntityView, object>>> entityViewBlazingFastReflection; | |||
internal int _ID; | |||
} | |||
@@ -39,13 +39,13 @@ namespace Svelto.ECS | |||
{ | |||
var field = fields[i]; | |||
Action<EntityView, object> setter = FastInvoke<EntityView>.MakeSetter(field); | |||
Action<EntityView, object> setter = FastInvoke<T>.MakeSetter<EntityView>(field); | |||
FieldCache<T>.list.Add(new KeyValuePair<Type, Action<EntityView, object>>(field.FieldType, setter)); | |||
} | |||
} | |||
return new T { _ID = ID, EntityViewBlazingFastReflection = FieldCache<T>.list }; | |||
return new T { _ID = ID, entityViewBlazingFastReflection = FieldCache<T>.list }; | |||
} | |||
static class FieldCache<W> where W:T | |||
@@ -1,6 +1,7 @@ | |||
using System; | |||
using System.Reflection; | |||
using System.Reflection.Emit; | |||
using System.Linq.Expressions; | |||
namespace Svelto.Utilities | |||
{ | |||
@@ -8,9 +9,20 @@ namespace Svelto.Utilities | |||
public static class FastInvoke<T> where T : class | |||
{ | |||
public static Action<T, object> MakeSetter(FieldInfo field) | |||
#if ENABLE_IL2CPP | |||
public static Action<CastedType, object> MakeSetter<CastedType>(FieldInfo field) | |||
{ | |||
if (field.FieldType.IsInterface == true && field.FieldType.IsValueType == false) | |||
{ | |||
return new Action<CastedType, object>((target, value) => field.SetValue(target, value)); | |||
} | |||
throw new ArgumentException("<color=orange>Svelto.ECS</color> unsupported EntityView field (must be an interface and a class)"); | |||
} | |||
#elif !NETFX_CORE | |||
public static Action<CastedType, object> MakeSetter<CastedType>(FieldInfo field) | |||
{ | |||
if (field.FieldType.IsInterfaceEx() == true && field.FieldType.IsValueTypeEx() == false) | |||
{ | |||
DynamicMethod m = new DynamicMethod("setter", typeof(void), new Type[] { typeof(T), typeof(object) }); | |||
ILGenerator cg = m.GetILGenerator(); | |||
@@ -21,10 +33,29 @@ namespace Svelto.Utilities | |||
cg.Emit(OpCodes.Stfld, field); | |||
cg.Emit(OpCodes.Ret); | |||
return (Action<T, object>)m.CreateDelegate(typeof(Action<T, object>)); | |||
return new Action<CastedType, object>((target, value) => m.CreateDelegate(typeof(Action<T, object>)).DynamicInvoke(target, value)); | |||
} | |||
throw new ArgumentException("<color=orange>Svelto.ECS</color> unsupported EntityView field (must be an interface and a class)"); | |||
} | |||
#else | |||
public static Action<CastedType, object> MakeSetter<CastedType>(FieldInfo field) | |||
{ | |||
if (field.FieldType.IsInterfaceEx() == true && field.FieldType.IsValueTypeEx() == false) | |||
{ | |||
ParameterExpression targetExp = Expression.Parameter(typeof(T), "target"); | |||
ParameterExpression valueExp = Expression.Parameter(field.FieldType, "value"); | |||
MemberExpression fieldExp = Expression.Field(targetExp, field); | |||
BinaryExpression assignExp = Expression.Assign(fieldExp, valueExp); | |||
var setter = Expression.Lambda(assignExp, targetExp, valueExp).Compile(); | |||
return new Action<CastedType, object>((target, value) => setter.DynamicInvoke(target, value)); | |||
} | |||
throw new ArgumentException("<color=orange>Svelto.ECS</color> unsupported EntityView field (must be an interface and a class)"); | |||
} | |||
#endif | |||
} | |||
} |
@@ -4,11 +4,18 @@ using System.Reflection; | |||
using System.Runtime.CompilerServices; | |||
using Svelto.DataStructures; | |||
namespace Svelto.Utilities | |||
{ | |||
public static class NetFXCoreWrappers | |||
{ | |||
public static MethodInfo GetMethodInfoEx(this Delegate delegateEx) | |||
public static Type GetDeclaringType(this MethodInfo methodInfo) | |||
{ | |||
#if NETFX_CORE | |||
return methodInfo.DeclaringType; | |||
#else | |||
return methodInfo.ReflectedType; | |||
#endif | |||
} | |||
public static MethodInfo GetMethodInfoEx(this Delegate delegateEx) | |||
{ | |||
#if NETFX_CORE | |||
var method = delegateEx.GetMethodInfo(); | |||
@@ -18,6 +25,33 @@ namespace Svelto.Utilities | |||
return method; | |||
} | |||
public static Type[] GetInterfacesEx(this Type type) | |||
{ | |||
#if NETFX_CORE | |||
return type.GetInterfaces(); | |||
#else | |||
return type.GetInterfaces(); | |||
#endif | |||
} | |||
public static bool IsInterfaceEx(this Type type) | |||
{ | |||
#if NETFX_CORE | |||
return type.GetTypeInfo().IsInterface; | |||
#else | |||
return type.IsInterface; | |||
#endif | |||
} | |||
public static bool IsValueTypeEx(this Type type) | |||
{ | |||
#if NETFX_CORE | |||
return type.GetTypeInfo().IsValueType; | |||
#else | |||
return type.IsValueType; | |||
#endif | |||
} | |||
public static Type GetDeclaringType(this MemberInfo memberInfo) | |||
{ | |||
#if NETFX_CORE | |||
@@ -30,7 +64,7 @@ namespace Svelto.Utilities | |||
public static Type GetBaseType(this Type type) | |||
{ | |||
#if NETFX_CORE | |||
return type.BaseType(); | |||
return type.GetTypeInfo().BaseType; | |||
#else | |||
return type.BaseType; | |||
#endif | |||
@@ -63,7 +97,19 @@ namespace Svelto.Utilities | |||
#endif | |||
} | |||
public static MemberInfo[] FindWritablePropertiesWithCustomAttribute(this Type contract, | |||
public static Type[] GetGenericArgumentsEx(this Type type) | |||
{ | |||
#if !NETFX_CORE | |||
return type.GetGenericArguments(); | |||
#else | |||
var typeinfo = type.GetTypeInfo(); | |||
return typeinfo.IsGenericTypeDefinition | |||
? typeinfo.GenericTypeParameters | |||
: typeinfo.GenericTypeArguments; | |||
#endif | |||
} | |||
public static MemberInfo[] FindWritablePropertiesWithCustomAttribute(this Type contract, | |||
Type customAttributeType) | |||
{ | |||
FasterList<MemberInfo> propertyList = new FasterList<MemberInfo>(8); | |||
@@ -121,4 +167,4 @@ namespace Svelto.Utilities | |||
static readonly Type _compilerType = typeof(CompilerGeneratedAttribute); | |||
} | |||
} | |||
@@ -1,24 +0,0 @@ | |||
using System; | |||
using System.Reflection; | |||
public static class NetFXCoreWrappers | |||
{ | |||
public static MethodInfo GetMethodInfoEx(this Delegate delegateEx) | |||
{ | |||
#if NETFX_CORE | |||
var method = delegateEx.GetMethodInfo(); | |||
#else | |||
var method = delegateEx.Method; | |||
#endif | |||
return method; | |||
} | |||
public static Type GetDeclaringType(this MethodInfo methodInfo) | |||
{ | |||
#if NETFX_CORE | |||
return methodInfo.DeclaringType; | |||
#else | |||
return methodInfo.ReflectedType; | |||
#endif | |||
} | |||
} |