From 6a4d702ea28829487554c25837e19ebd91db0db9 Mon Sep 17 00:00:00 2001 From: sebas77 Date: Wed, 27 Dec 2017 03:01:08 +0000 Subject: [PATCH] Improve compatibility across platforms --- ECS/EnginesRootEngines.cs | 2 +- ECS/EntityDescriptor.cs | 4 +- ECS/EntityView.cs | 10 ++--- Utilities/FastInvoke.cs | 35 ++++++++++++++++- Utilities/NetFXCoreWrappers.cs | 58 ++++++++++++++++++++++++++--- Utilities/PropertyInfoExtensions.cs | 24 ------------ 6 files changed, 93 insertions(+), 40 deletions(-) delete mode 100644 Utilities/PropertyInfoExtensions.cs diff --git a/ECS/EnginesRootEngines.cs b/ECS/EnginesRootEngines.cs index a74e26c..940c5b5 100644 --- a/ECS/EnginesRootEngines.cs +++ b/ECS/EnginesRootEngines.cs @@ -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; diff --git a/ECS/EntityDescriptor.cs b/ECS/EntityDescriptor.cs index 9f3a46f..880c2c2 100644 --- a/ECS/EntityDescriptor.cs +++ b/ECS/EntityDescriptor.cs @@ -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>[] setters = - FasterList>>.NoVirt.ToArrayFast(entityView.EntityViewBlazingFastReflection, out count); + FasterList>>.NoVirt.ToArrayFast(entityView.entityViewBlazingFastReflection, out count); var removeEntityComponentType = typeof(IRemoveEntityComponent); diff --git a/ECS/EntityView.cs b/ECS/EntityView.cs index 5891198..8add72c 100644 --- a/ECS/EntityView.cs +++ b/ECS/EntityView.cs @@ -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>> EntityViewBlazingFastReflection; + internal FasterList>> entityViewBlazingFastReflection; internal int _ID; } @@ -39,13 +39,13 @@ namespace Svelto.ECS { var field = fields[i]; - Action setter = FastInvoke.MakeSetter(field); - + Action setter = FastInvoke.MakeSetter(field); + FieldCache.list.Add(new KeyValuePair>(field.FieldType, setter)); } } - return new T { _ID = ID, EntityViewBlazingFastReflection = FieldCache.list }; + return new T { _ID = ID, entityViewBlazingFastReflection = FieldCache.list }; } static class FieldCache where W:T diff --git a/Utilities/FastInvoke.cs b/Utilities/FastInvoke.cs index c749c1d..b9a1aab 100644 --- a/Utilities/FastInvoke.cs +++ b/Utilities/FastInvoke.cs @@ -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 where T : class { - public static Action MakeSetter(FieldInfo field) +#if ENABLE_IL2CPP + public static Action MakeSetter(FieldInfo field) { if (field.FieldType.IsInterface == true && field.FieldType.IsValueType == false) + { + return new Action((target, value) => field.SetValue(target, value)); + } + + throw new ArgumentException("Svelto.ECS unsupported EntityView field (must be an interface and a class)"); + } +#elif !NETFX_CORE + public static Action MakeSetter(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)m.CreateDelegate(typeof(Action)); + return new Action((target, value) => m.CreateDelegate(typeof(Action)).DynamicInvoke(target, value)); + } + + throw new ArgumentException("Svelto.ECS unsupported EntityView field (must be an interface and a class)"); + } +#else + public static Action MakeSetter(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((target, value) => setter.DynamicInvoke(target, value)); } throw new ArgumentException("Svelto.ECS unsupported EntityView field (must be an interface and a class)"); } +#endif } } \ No newline at end of file diff --git a/Utilities/NetFXCoreWrappers.cs b/Utilities/NetFXCoreWrappers.cs index cde69f8..1fa798a 100644 --- a/Utilities/NetFXCoreWrappers.cs +++ b/Utilities/NetFXCoreWrappers.cs @@ -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 propertyList = new FasterList(8); @@ -121,4 +167,4 @@ namespace Svelto.Utilities static readonly Type _compilerType = typeof(CompilerGeneratedAttribute); } -} + diff --git a/Utilities/PropertyInfoExtensions.cs b/Utilities/PropertyInfoExtensions.cs deleted file mode 100644 index 87b18d8..0000000 --- a/Utilities/PropertyInfoExtensions.cs +++ /dev/null @@ -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 - } -}