mirror of
https://github.com/DCFApixels/DragonECS-AutoInjections.git
synced 2025-09-18 21:35:07 +08:00
Compare commits
No commits in common. "main" and "0.9.16" have entirely different histories.
1
.gitignore
vendored
1
.gitignore
vendored
@ -35,7 +35,6 @@ ExportedObj/
|
|||||||
*.csproj
|
*.csproj
|
||||||
*.unityproj
|
*.unityproj
|
||||||
*.sln
|
*.sln
|
||||||
*.sln.meta
|
|
||||||
*.suo
|
*.suo
|
||||||
*.tmp
|
*.tmp
|
||||||
*.user
|
*.user
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
"displayName": "DragonECS-AutoInjections",
|
"displayName": "DragonECS-AutoInjections",
|
||||||
"description": "Auto Injections for DragonECS",
|
"description": "Auto Injections for DragonECS",
|
||||||
"unity": "2020.3",
|
"unity": "2020.3",
|
||||||
"version": "0.9.18",
|
"version": "0.9.16",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/DCFApixels/DragonECS-AutoInjections.git"
|
"url": "https://github.com/DCFApixels/DragonECS-AutoInjections.git"
|
||||||
|
@ -1,10 +1,5 @@
|
|||||||
#if DISABLE_DEBUG
|
using DCFApixels.DragonECS.AutoInjections.Internal;
|
||||||
#undef DEBUG
|
|
||||||
#endif
|
|
||||||
using DCFApixels.DragonECS.AutoInjections.Internal;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
|
||||||
namespace DCFApixels.DragonECS
|
namespace DCFApixels.DragonECS
|
||||||
@ -13,7 +8,7 @@ namespace DCFApixels.DragonECS
|
|||||||
{
|
{
|
||||||
protected sealed override void Init(Builder b)
|
protected sealed override void Init(Builder b)
|
||||||
{
|
{
|
||||||
//EcsAspectAutoHelper.Fill(this, b);
|
EcsAspectAutoHelper.Fill(this, b);
|
||||||
InitAfterDI(b);
|
InitAfterDI(b);
|
||||||
}
|
}
|
||||||
protected virtual void InitAfterDI(Builder b) { }
|
protected virtual void InitAfterDI(Builder b) { }
|
||||||
@ -21,119 +16,90 @@ namespace DCFApixels.DragonECS
|
|||||||
|
|
||||||
internal static class EcsAspectAutoHelper
|
internal static class EcsAspectAutoHelper
|
||||||
{
|
{
|
||||||
private static readonly MethodInfo _incluedMethod;
|
public static void Fill(EcsAspect s, EcsAspect.Builder b)
|
||||||
private static readonly MethodInfo _excludeMethod;
|
|
||||||
private static readonly MethodInfo _optionalMethod;
|
|
||||||
private static readonly MethodInfo _combineMethod;
|
|
||||||
private const BindingFlags REFL_FLAGS = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
|
|
||||||
static EcsAspectAutoHelper()
|
|
||||||
{
|
{
|
||||||
Type builderType = typeof(EcsAspect.Builder);
|
Type builderType = b.GetType();
|
||||||
|
MethodInfo incluedMethod = builderType.GetMethod("IncludePool", BindingFlags.Instance | BindingFlags.Public);
|
||||||
|
MethodInfo excludeMethod = builderType.GetMethod("ExcludePool", BindingFlags.Instance | BindingFlags.Public);
|
||||||
|
MethodInfo optionalMethod = builderType.GetMethod("OptionalPool", BindingFlags.Instance | BindingFlags.Public);
|
||||||
|
MethodInfo includeImplicitMethod = builderType.GetMethod("IncludeImplicit", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
|
||||||
|
MethodInfo excludeImplicitMethod = builderType.GetMethod("ExcludeImplicit", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
|
||||||
|
MethodInfo combineMethod = builderType.GetMethod("Combine", BindingFlags.Instance | BindingFlags.Public);
|
||||||
|
|
||||||
_incluedMethod = builderType.GetMethod("IncludePool", REFL_FLAGS);
|
Type aspectType = s.GetType();
|
||||||
_excludeMethod = builderType.GetMethod("ExcludePool", REFL_FLAGS);
|
|
||||||
_optionalMethod = builderType.GetMethod("OptionalPool", REFL_FLAGS);
|
foreach (var attribute in aspectType.GetCustomAttributes<ImplicitInjectAttribute>())//TODO убрать дублирование кода - вынести в отедльный метод
|
||||||
_combineMethod = builderType.GetMethod("Combine", REFL_FLAGS);
|
|
||||||
}
|
|
||||||
public static void FillMaskFields(object aspect, EcsMask mask)
|
|
||||||
{
|
|
||||||
foreach (FieldInfo fieldInfo in aspect.GetType().GetFields(REFL_FLAGS))
|
|
||||||
{
|
{
|
||||||
if (fieldInfo.GetCustomAttribute<MaskAttribute>() == null)
|
if (attribute is IncImplicitAttribute incImplicit)
|
||||||
{
|
{
|
||||||
|
if (incImplicit.isPool)
|
||||||
|
incluedMethod.MakeGenericMethod(incImplicit.type).Invoke(b, null);
|
||||||
|
else
|
||||||
|
includeImplicitMethod.Invoke(b, new object[] { incImplicit.type });
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (attribute is ExcImplicitAttribute excImplicit)
|
||||||
if (fieldInfo.FieldType == typeof(EcsMask))
|
|
||||||
{
|
{
|
||||||
fieldInfo.SetValue(aspect, mask);
|
if (excImplicit.isPool)
|
||||||
|
excludeMethod.MakeGenericMethod(excImplicit.type).Invoke(b, null);
|
||||||
|
else
|
||||||
|
excludeImplicitMethod.Invoke(b, new object[] { excImplicit.type });
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
else if (fieldInfo.FieldType == typeof(EcsStaticMask))
|
}//TODO КОНЕЦ убрать дублирование кода - вынести в отедльный метод
|
||||||
{
|
|
||||||
fieldInfo.SetValue(aspect, mask.ToStatic());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public static void FillFields(object aspect, EcsAspect.Builder builder)
|
|
||||||
{
|
|
||||||
Type aspectType = aspect.GetType();
|
|
||||||
|
|
||||||
var implicitInjectAttributes = (IEnumerable<ImplicitInjectAttribute>)aspectType.GetCustomAttributes<ImplicitInjectAttribute>();
|
|
||||||
|
|
||||||
FieldInfo[] fieldInfos = aspectType.GetFields(REFL_FLAGS);
|
FieldInfo[] fieldInfos = aspectType.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
|
||||||
foreach (FieldInfo fieldInfo in fieldInfos)
|
foreach (FieldInfo fieldInfo in fieldInfos)
|
||||||
{
|
{
|
||||||
Type fieldType = fieldInfo.FieldType;
|
Type fieldType = fieldInfo.FieldType;
|
||||||
|
|
||||||
implicitInjectAttributes = implicitInjectAttributes.Concat(fieldInfo.GetCustomAttributes<ImplicitInjectAttribute>());
|
foreach (var attribute in fieldInfo.GetCustomAttributes<ImplicitInjectAttribute>())//TODO убрать дублирование кода - вынести в отедльный метод
|
||||||
|
{
|
||||||
|
if (attribute is IncImplicitAttribute incImplicit)
|
||||||
|
{
|
||||||
|
if (incImplicit.isPool)
|
||||||
|
incluedMethod.MakeGenericMethod(incImplicit.type).Invoke(b, null);
|
||||||
|
else
|
||||||
|
includeImplicitMethod.Invoke(b, new object[] { incImplicit.type });
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (attribute is ExcImplicitAttribute excImplicit)
|
||||||
|
{
|
||||||
|
if (excImplicit.isPool)
|
||||||
|
excludeMethod.MakeGenericMethod(excImplicit.type).Invoke(b, null);
|
||||||
|
else
|
||||||
|
excludeImplicitMethod.Invoke(b, new object[] { excImplicit.type });
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}//TODO КОНЕЦ убрать дублирование кода - вынести в отедльный метод
|
||||||
|
|
||||||
if (fieldInfo.TryGetCustomAttribute(out InjectAspectMemberAttribute injectAttribute) == false)
|
if (!fieldInfo.TryGetCustomAttribute(out InjectAspectMemberAttribute injectAttribute))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
IEcsPool pool;
|
|
||||||
switch (injectAttribute)
|
|
||||||
{
|
|
||||||
case IncAttribute incAtr:
|
|
||||||
if (builder.World.TryFindPoolInstance(fieldType, out pool))
|
|
||||||
{
|
|
||||||
builder.SetMaskInclude(fieldType);
|
|
||||||
fieldInfo.SetValue(aspect, pool);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
pool = (IEcsPool)_incluedMethod.MakeGenericMethod(fieldType).Invoke(builder, null);
|
|
||||||
}
|
|
||||||
fieldInfo.SetValue(aspect, pool);
|
|
||||||
break;
|
|
||||||
case ExcAttribute extAtr:
|
|
||||||
if (builder.World.TryFindPoolInstance(fieldType, out pool))
|
|
||||||
{
|
|
||||||
builder.SetMaskExclude(fieldType);
|
|
||||||
fieldInfo.SetValue(aspect, pool);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
pool = (IEcsPool)_excludeMethod.MakeGenericMethod(fieldType).Invoke(builder, null);
|
|
||||||
}
|
|
||||||
fieldInfo.SetValue(aspect, pool);
|
|
||||||
break;
|
|
||||||
case OptAttribute optAtr:
|
|
||||||
if (builder.World.TryFindPoolInstance(fieldType, out pool))
|
|
||||||
{
|
|
||||||
fieldInfo.SetValue(aspect, pool);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
pool = (IEcsPool)_optionalMethod.MakeGenericMethod(fieldType).Invoke(builder, null);
|
|
||||||
}
|
|
||||||
fieldInfo.SetValue(aspect, pool);
|
|
||||||
break;
|
|
||||||
case CombineAttribute combineAtr:
|
|
||||||
pool = builder.World.FindPoolInstance(fieldType);
|
|
||||||
fieldInfo.SetValue(aspect, _combineMethod.MakeGenericMethod(fieldType).Invoke(builder, new object[] { combineAtr.Order }));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (injectAttribute is IncAttribute)
|
||||||
foreach (var attribute in implicitInjectAttributes)
|
|
||||||
{
|
|
||||||
if (attribute is IncImplicitAttribute incImplicitAtr)
|
|
||||||
{
|
{
|
||||||
builder.SetMaskInclude(incImplicitAtr.ComponentType);
|
fieldInfo.SetValue(s, incluedMethod.MakeGenericMethod(fieldType).Invoke(b, null));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (attribute is ExcImplicitAttribute excImplicitAtr)
|
if (injectAttribute is ExcAttribute)
|
||||||
{
|
{
|
||||||
builder.SetMaskExclude(excImplicitAtr.ComponentType);
|
fieldInfo.SetValue(s, excludeMethod.MakeGenericMethod(fieldType).Invoke(b, null));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (injectAttribute is OptAttribute)
|
||||||
|
{
|
||||||
|
fieldInfo.SetValue(s, optionalMethod.MakeGenericMethod(fieldType).Invoke(b, null));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (injectAttribute is CombineAttribute combAttribute)
|
||||||
|
{
|
||||||
|
fieldInfo.SetValue(s, combineMethod.MakeGenericMethod(fieldType).Invoke(b, new object[] { combAttribute.order }));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,4 @@
|
|||||||
#if DISABLE_DEBUG
|
using DCFApixels.DragonECS.PoolsCore;
|
||||||
#undef DEBUG
|
|
||||||
#endif
|
|
||||||
using DCFApixels.DragonECS.PoolsCore;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
@ -17,30 +14,32 @@ namespace DCFApixels.DragonECS
|
|||||||
[AttributeUsage(AttributeTargets.Field, Inherited = false, AllowMultiple = false)]
|
[AttributeUsage(AttributeTargets.Field, Inherited = false, AllowMultiple = false)]
|
||||||
public sealed class CombineAttribute : InjectAspectMemberAttribute
|
public sealed class CombineAttribute : InjectAspectMemberAttribute
|
||||||
{
|
{
|
||||||
public readonly int Order = 0;
|
public readonly int order = 0;
|
||||||
public CombineAttribute(int order = 0) { Order = order; }
|
public CombineAttribute(int order = 0) { this.order = order; }
|
||||||
}
|
}
|
||||||
[AttributeUsage(AttributeTargets.Field, Inherited = false, AllowMultiple = false)]
|
|
||||||
public sealed class MaskAttribute : InjectAspectMemberAttribute { }
|
|
||||||
|
|
||||||
|
public abstract class ImplicitInjectAttribute : Attribute { }
|
||||||
public abstract class ImplicitInjectAttribute : Attribute
|
|
||||||
{
|
|
||||||
public readonly Type ComponentType;
|
|
||||||
public ImplicitInjectAttribute(Type componentType)
|
|
||||||
{
|
|
||||||
ComponentType = componentType;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Class, Inherited = false, AllowMultiple = true)]
|
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Class, Inherited = false, AllowMultiple = true)]
|
||||||
public sealed class IncImplicitAttribute : ImplicitInjectAttribute
|
public sealed class IncImplicitAttribute : ImplicitInjectAttribute
|
||||||
{
|
{
|
||||||
public IncImplicitAttribute(Type type) : base(type) { }
|
public readonly Type type;
|
||||||
|
public readonly bool isPool;
|
||||||
|
public IncImplicitAttribute(Type type)
|
||||||
|
{
|
||||||
|
this.type = type;
|
||||||
|
isPool = type.GetInterfaces().Any(o => o == typeof(IEcsPoolImplementation));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Class, Inherited = false, AllowMultiple = true)]
|
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Class, Inherited = false, AllowMultiple = true)]
|
||||||
public sealed class ExcImplicitAttribute : ImplicitInjectAttribute
|
public sealed class ExcImplicitAttribute : ImplicitInjectAttribute
|
||||||
{
|
{
|
||||||
public ExcImplicitAttribute(Type type) : base(type) { }
|
public readonly Type type;
|
||||||
|
public readonly bool isPool;
|
||||||
|
public ExcImplicitAttribute(Type type)
|
||||||
|
{
|
||||||
|
this.type = type;
|
||||||
|
isPool = type.GetInterfaces().Any(o => o == typeof(IEcsPoolImplementation));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,4 @@
|
|||||||
#if DISABLE_DEBUG
|
using System;
|
||||||
#undef DEBUG
|
|
||||||
#endif
|
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace DCFApixels.DragonECS
|
namespace DCFApixels.DragonECS
|
||||||
{
|
{
|
||||||
|
@ -1,6 +1,3 @@
|
|||||||
#if DISABLE_DEBUG
|
|
||||||
#undef DEBUG
|
|
||||||
#endif
|
|
||||||
using DCFApixels.DragonECS.AutoInjections;
|
using DCFApixels.DragonECS.AutoInjections;
|
||||||
using DCFApixels.DragonECS.AutoInjections.Internal;
|
using DCFApixels.DragonECS.AutoInjections.Internal;
|
||||||
using System;
|
using System;
|
||||||
@ -13,8 +10,8 @@ namespace DCFApixels.DragonECS
|
|||||||
internal class AutoInjectionMap
|
internal class AutoInjectionMap
|
||||||
{
|
{
|
||||||
private readonly EcsPipeline _source;
|
private readonly EcsPipeline _source;
|
||||||
private Dictionary<Type, List<InjectedPropertyRecord>> _injectedTypeToPropertiesMap = new Dictionary<Type, List<InjectedPropertyRecord>>();
|
private Dictionary<Type, List<InjectedPropertyRecord>> _systemProperties;
|
||||||
private HashSet<Type> _notInjected = new HashSet<Type>();
|
private HashSet<Type> _notInjected;
|
||||||
private bool _isDummyInjected = false;
|
private bool _isDummyInjected = false;
|
||||||
|
|
||||||
private bool _isPreInitInjectionComplete = false;
|
private bool _isPreInitInjectionComplete = false;
|
||||||
@ -23,19 +20,20 @@ namespace DCFApixels.DragonECS
|
|||||||
{
|
{
|
||||||
_source = source;
|
_source = source;
|
||||||
var allsystems = _source.AllSystems;
|
var allsystems = _source.AllSystems;
|
||||||
|
_systemProperties = new Dictionary<Type, List<InjectedPropertyRecord>>();
|
||||||
|
_notInjected = new HashSet<Type>();
|
||||||
foreach (var system in allsystems)
|
foreach (var system in allsystems)
|
||||||
{
|
{
|
||||||
Type systemType = system.GetType();
|
Type systemType = system.GetType();
|
||||||
if (systemType == typeof(AutoInjectSystem)) { continue; }
|
if (systemType == typeof(AutoInjectSystem)) { continue; }
|
||||||
|
|
||||||
foreach (var property in GetAllPropertiesFor(systemType, isAgressiveInjection))
|
foreach (var property in GetAllPropertiesFor(systemType, isAgressiveInjection))
|
||||||
{
|
{
|
||||||
Type propertType = property.PropertyType;
|
Type propertType = property.PropertyType;
|
||||||
List<InjectedPropertyRecord> list;
|
List<InjectedPropertyRecord> list;
|
||||||
if (_injectedTypeToPropertiesMap.TryGetValue(propertType, out list) == false)
|
if (!_systemProperties.TryGetValue(propertType, out list))
|
||||||
{
|
{
|
||||||
list = new List<InjectedPropertyRecord>();
|
list = new List<InjectedPropertyRecord>();
|
||||||
_injectedTypeToPropertiesMap.Add(propertType, list);
|
_systemProperties.Add(propertType, list);
|
||||||
}
|
}
|
||||||
list.Add(new InjectedPropertyRecord(system, property));
|
list.Add(new InjectedPropertyRecord(system, property));
|
||||||
if (property.GetAutoInjectAttribute() != DIAttribute.Dummy)
|
if (property.GetAutoInjectAttribute() != DIAttribute.Dummy)
|
||||||
@ -45,100 +43,87 @@ namespace DCFApixels.DragonECS
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private static List<IInjectedProperty> GetAllPropertiesFor(Type type, bool isAgressiveInjection)
|
|
||||||
{
|
|
||||||
List<IInjectedProperty> result = new List<IInjectedProperty>();
|
|
||||||
GetAllPropertiesFor(type, isAgressiveInjection, result);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
private static void GetAllPropertiesFor(Type type, bool isAgressiveInjection, List<IInjectedProperty> result)
|
|
||||||
{
|
|
||||||
const BindingFlags REFL_FLAGS = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
|
|
||||||
|
|
||||||
result.AddRange(type.GetFields(REFL_FLAGS)
|
private static void Do(Type type, List<IInjectedProperty> result, bool isAgressiveInjection)
|
||||||
.Where(o => isAgressiveInjection || o.HasAttribute<DIAttribute>())
|
{
|
||||||
|
const BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
|
||||||
|
result.AddRange(type.GetFields(bindingFlags)
|
||||||
|
.Where(o => isAgressiveInjection || o.GetCustomAttribute<DIAttribute>() != null)
|
||||||
.Select(o => new InjectedField(o)));
|
.Select(o => new InjectedField(o)));
|
||||||
|
result.AddRange(type.GetProperties(bindingFlags)
|
||||||
result.AddRange(type.GetProperties(REFL_FLAGS)
|
|
||||||
.Where(o =>
|
.Where(o =>
|
||||||
{
|
{
|
||||||
if (!isAgressiveInjection && o.HasAttribute<DIAttribute>() == false)
|
if (!isAgressiveInjection && o.GetCustomAttribute<DIAttribute>() == null)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#if DEBUG
|
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
|
||||||
if (!isAgressiveInjection && o.CanWrite == false) { Throw.PropertyIsCantWrite(o); }
|
if (!isAgressiveInjection && o.CanWrite == false) { Throw.PropertyIsCantWrite(o); }
|
||||||
#endif
|
#endif
|
||||||
return o.CanWrite;
|
return o.CanWrite == false;
|
||||||
})
|
})
|
||||||
.Select(o => new InjectedProperty(o)));
|
.Select(o => new InjectedProperty(o)));
|
||||||
|
result.AddRange(type.GetMethods(bindingFlags)
|
||||||
result.AddRange(type.GetMethods(REFL_FLAGS)
|
|
||||||
.Where(o =>
|
.Where(o =>
|
||||||
{
|
{
|
||||||
if (!isAgressiveInjection && o.HasAttribute<DIAttribute>() == false)
|
if (!isAgressiveInjection && o.GetCustomAttribute<DIAttribute>() == null)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
var parameters = o.GetParameters();
|
var parameters = o.GetParameters();
|
||||||
|
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
|
||||||
if (!isAgressiveInjection)
|
if (!isAgressiveInjection)
|
||||||
{
|
{
|
||||||
#if DEBUG
|
|
||||||
if (o.IsGenericMethod) { Throw.MethodIsGeneric(o); }
|
if (o.IsGenericMethod) { Throw.MethodIsGeneric(o); }
|
||||||
if (parameters.Length != 1) { Throw.MethodArgumentsGreater1(o); }
|
if (parameters.Length != 1) { Throw.MethodArgumentsGreater1(o); }
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
return o.IsGenericMethod == false && parameters.Length == 1;
|
return o.IsGenericMethod == false && parameters.Length == 1;
|
||||||
})
|
})
|
||||||
.Select(o => new InjectedMethod(o)));
|
.Select(o => new InjectedMethod(o)));
|
||||||
|
|
||||||
if (type.BaseType != null)
|
if (type.BaseType != null)
|
||||||
{
|
{
|
||||||
GetAllPropertiesFor(type.BaseType, isAgressiveInjection, result);
|
Do(type.BaseType, result, isAgressiveInjection);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Type[] _relatedTypesBuffer;
|
private static List<IInjectedProperty> GetAllPropertiesFor(Type type, bool isAgressiveInjection)
|
||||||
|
{
|
||||||
|
List<IInjectedProperty> result = new List<IInjectedProperty>();
|
||||||
|
Do(type, result, isAgressiveInjection);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
public void Inject(Type fieldType, object obj)
|
public void Inject(Type fieldType, object obj)
|
||||||
{
|
{
|
||||||
|
if (!_isPreInitInjectionComplete)
|
||||||
if (_relatedTypesBuffer == null || _relatedTypesBuffer.Length < _injectedTypeToPropertiesMap.Count)
|
|
||||||
{
|
{
|
||||||
_relatedTypesBuffer = new Type[_injectedTypeToPropertiesMap.Count];
|
_notInjected.Remove(fieldType);
|
||||||
}
|
}
|
||||||
int relatedTypesCount = 0;
|
|
||||||
foreach (var pair in _injectedTypeToPropertiesMap)
|
if (_systemProperties.TryGetValue(fieldType, out List<InjectedPropertyRecord> list))
|
||||||
{
|
{
|
||||||
if (pair.Key == fieldType || pair.Key.IsAssignableFrom(fieldType))
|
string name = string.Empty;
|
||||||
|
if(obj is INamedMember named)
|
||||||
{
|
{
|
||||||
_relatedTypesBuffer[relatedTypesCount++] = pair.Key;
|
name = named.Name;
|
||||||
}
|
}
|
||||||
}
|
foreach (var item in list)
|
||||||
|
|
||||||
foreach (var type in new ReadOnlySpan<Type>(_relatedTypesBuffer, 0, relatedTypesCount))
|
|
||||||
{
|
|
||||||
if (_injectedTypeToPropertiesMap.TryGetValue(type, out List<InjectedPropertyRecord> list))
|
|
||||||
{
|
{
|
||||||
string name = string.Empty;
|
string propertyName = item.Attribute.NamedInjection;
|
||||||
if (obj is INamedMember named)
|
if (string.IsNullOrEmpty(propertyName) || propertyName == name)
|
||||||
{
|
{
|
||||||
name = named.Name;
|
item.property.Inject(item.target, obj);
|
||||||
}
|
|
||||||
foreach (var item in list)
|
|
||||||
{
|
|
||||||
string propertyName = item.Attribute.NamedInjection;
|
|
||||||
if (string.IsNullOrEmpty(propertyName) || propertyName == name)
|
|
||||||
{
|
|
||||||
if (_isPreInitInjectionComplete == false)
|
|
||||||
{
|
|
||||||
_notInjected.Remove(item.property.PropertyType);
|
|
||||||
}
|
|
||||||
item.property.Inject(item.target, obj);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Type baseType = fieldType.BaseType;
|
||||||
|
if (baseType != null)
|
||||||
|
{
|
||||||
|
Inject(baseType, obj);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void InjectDummy()
|
public void InjectDummy()
|
||||||
@ -148,7 +133,7 @@ namespace DCFApixels.DragonECS
|
|||||||
_isDummyInjected = true;
|
_isDummyInjected = true;
|
||||||
foreach (var notInjectedItem in _notInjected)
|
foreach (var notInjectedItem in _notInjected)
|
||||||
{
|
{
|
||||||
foreach (var systemRecord in _injectedTypeToPropertiesMap[notInjectedItem])
|
foreach (var systemRecord in _systemProperties[notInjectedItem])
|
||||||
{
|
{
|
||||||
if (systemRecord.Attribute.NotNullDummyType == null)
|
if (systemRecord.Attribute.NotNullDummyType == null)
|
||||||
continue;
|
continue;
|
||||||
@ -172,7 +157,7 @@ namespace DCFApixels.DragonECS
|
|||||||
#if DEBUG
|
#if DEBUG
|
||||||
foreach (var item in _notInjected)
|
foreach (var item in _notInjected)
|
||||||
{
|
{
|
||||||
foreach (var systemRecord in _injectedTypeToPropertiesMap[item])
|
foreach (var systemRecord in _systemProperties[item])
|
||||||
{
|
{
|
||||||
EcsDebug.PrintWarning($"in system {EcsDebugUtility.GetGenericTypeFullName(systemRecord.target.GetType(), 1)} is missing an injection of {EcsDebugUtility.GetGenericTypeFullName(item, 1)}.");
|
EcsDebug.PrintWarning($"in system {EcsDebugUtility.GetGenericTypeFullName(systemRecord.target.GetType(), 1)} is missing an injection of {EcsDebugUtility.GetGenericTypeFullName(item, 1)}.");
|
||||||
}
|
}
|
||||||
@ -202,33 +187,15 @@ namespace DCFApixels.DragonECS
|
|||||||
[MetaColor(MetaColor.Gray)]
|
[MetaColor(MetaColor.Gray)]
|
||||||
[MetaGroup(EcsAutoInjectionsConsts.PACK_GROUP, EcsConsts.DI_GROUP)]
|
[MetaGroup(EcsAutoInjectionsConsts.PACK_GROUP, EcsConsts.DI_GROUP)]
|
||||||
[MetaDescription(EcsConsts.AUTHOR, "The system responsible for the processing of automatic injections. The .AutoInject() method adds an AutoInjectSystem to the systems pipelines.")]
|
[MetaDescription(EcsConsts.AUTHOR, "The system responsible for the processing of automatic injections. The .AutoInject() method adds an AutoInjectSystem to the systems pipelines.")]
|
||||||
public class AutoInjectSystem : IEcsInject<object>, IEcsPipelineMember, IOnInitInjectionComplete, IEcsDefaultAddParams
|
public class AutoInjectSystem : IEcsInject<object>, IEcsPipelineMember, IOnInitInjectionComplete
|
||||||
{
|
{
|
||||||
public AddParams AddParams => new AddParams(layerName: EcsConsts.PRE_BEGIN_LAYER, isUnique: true);
|
|
||||||
|
|
||||||
private EcsPipeline _pipeline;
|
private EcsPipeline _pipeline;
|
||||||
|
EcsPipeline IEcsPipelineMember.Pipeline { get => _pipeline; set => _pipeline = value; }
|
||||||
private List<object> _delayedInjects = new List<object>();
|
private List<object> _delayedInjects = new List<object>();
|
||||||
private AutoInjectionMap _autoInjectionMap;
|
private AutoInjectionMap _autoInjectionMap;
|
||||||
private bool _isInitInjectionCompleted;
|
private bool _isInitInjectionCompleted;
|
||||||
private bool _isAgressiveInjection;
|
private bool _isAgressiveInjection;
|
||||||
|
|
||||||
static AutoInjectSystem()
|
|
||||||
{
|
|
||||||
EcsAspect.OnInit -= EcsAspect_OnInit;
|
|
||||||
EcsAspect.OnInit += EcsAspect_OnInit;
|
|
||||||
EcsAspect.OnAfterInit -= EcsAspect_OnBuild;
|
|
||||||
EcsAspect.OnAfterInit += EcsAspect_OnBuild;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void EcsAspect_OnInit(object aspect, EcsAspect.Builder builder)
|
|
||||||
{
|
|
||||||
EcsAspectAutoHelper.FillFields(aspect, builder);
|
|
||||||
}
|
|
||||||
private static void EcsAspect_OnBuild(object aspect, EcsMask mask)
|
|
||||||
{
|
|
||||||
EcsAspectAutoHelper.FillMaskFields(aspect, mask);
|
|
||||||
}
|
|
||||||
|
|
||||||
public AutoInjectSystem(bool isAgressiveInjection = false)
|
public AutoInjectSystem(bool isAgressiveInjection = false)
|
||||||
{
|
{
|
||||||
_isAgressiveInjection = isAgressiveInjection;
|
_isAgressiveInjection = isAgressiveInjection;
|
||||||
@ -246,7 +213,6 @@ namespace DCFApixels.DragonECS
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnBeforeInitInjection() { }
|
|
||||||
public void OnInitInjectionComplete()
|
public void OnInitInjectionComplete()
|
||||||
{
|
{
|
||||||
_autoInjectionMap = new AutoInjectionMap(_pipeline, _isAgressiveInjection);
|
_autoInjectionMap = new AutoInjectionMap(_pipeline, _isAgressiveInjection);
|
||||||
@ -263,8 +229,6 @@ namespace DCFApixels.DragonECS
|
|||||||
_delayedInjects = null;
|
_delayedInjects = null;
|
||||||
GC.Collect(0);
|
GC.Collect(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
EcsPipeline IEcsPipelineMember.Pipeline { get => _pipeline; set => _pipeline = value; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Utils
|
#region Utils
|
||||||
|
@ -1,23 +1,10 @@
|
|||||||
#if DISABLE_DEBUG
|
namespace DCFApixels.DragonECS
|
||||||
#undef DEBUG
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace DCFApixels.DragonECS
|
|
||||||
{
|
{
|
||||||
public static class AutoInjectSystemExtensions
|
public static class AutoInjectSystemExtensions
|
||||||
{
|
{
|
||||||
[MetaColor(MetaColor.DragonCyan)]
|
|
||||||
public class AutoInjectModule : IEcsModule
|
|
||||||
{
|
|
||||||
public bool isAgressiveInjection;
|
|
||||||
public void Import(EcsPipeline.Builder b)
|
|
||||||
{
|
|
||||||
b.AddUnique(new AutoInjectSystem(isAgressiveInjection));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public static EcsPipeline.Builder AutoInject(this EcsPipeline.Builder self, bool isAgressiveInjection = false)
|
public static EcsPipeline.Builder AutoInject(this EcsPipeline.Builder self, bool isAgressiveInjection = false)
|
||||||
{
|
{
|
||||||
self.AddUnique(new AutoInjectSystem(isAgressiveInjection));
|
self.Add(new AutoInjectSystem(isAgressiveInjection));
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,4 @@
|
|||||||
#if DISABLE_DEBUG
|
using System;
|
||||||
#undef DEBUG
|
|
||||||
#endif
|
|
||||||
using System;
|
|
||||||
|
|
||||||
[AttributeUsage(AttributeTargets.Interface, Inherited = false, AllowMultiple = false)]
|
[AttributeUsage(AttributeTargets.Interface, Inherited = false, AllowMultiple = false)]
|
||||||
public sealed class BindWithRunnerAttribute : Attribute
|
public sealed class BindWithRunnerAttribute : Attribute
|
||||||
{
|
{
|
||||||
|
@ -1,7 +1,4 @@
|
|||||||
#if DISABLE_DEBUG
|
using DCFApixels.DragonECS.AutoInjections.Internal;
|
||||||
#undef DEBUG
|
|
||||||
#endif
|
|
||||||
using DCFApixels.DragonECS.AutoInjections.Internal;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
|
||||||
|
@ -1,7 +1,4 @@
|
|||||||
#if DISABLE_DEBUG
|
using System;
|
||||||
#undef DEBUG
|
|
||||||
#endif
|
|
||||||
using System;
|
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
|
||||||
namespace DCFApixels.DragonECS
|
namespace DCFApixels.DragonECS
|
||||||
|
@ -1,7 +1,4 @@
|
|||||||
#if DISABLE_DEBUG
|
using System;
|
||||||
#undef DEBUG
|
|
||||||
#endif
|
|
||||||
using System;
|
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
|
@ -1,7 +1,4 @@
|
|||||||
#if DISABLE_DEBUG
|
using System;
|
||||||
#undef DEBUG
|
|
||||||
#endif
|
|
||||||
using System;
|
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
@ -21,10 +18,5 @@ namespace DCFApixels.DragonECS.AutoInjections.Internal
|
|||||||
attribute = self.GetCustomAttribute<T>();
|
attribute = self.GetCustomAttribute<T>();
|
||||||
return attribute != null;
|
return attribute != null;
|
||||||
}
|
}
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static bool HasAttribute<T>(this MemberInfo self) where T : Attribute
|
|
||||||
{
|
|
||||||
return self.GetCustomAttribute<T>() != null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user