Compare commits

..

12 Commits

Author SHA1 Message Date
DCFApixels
443a69615a up version to 0.9.17 2025-03-15 17:08:05 +08:00
DCFApixels
a0bec24fd2 defines refactoring 2025-03-15 15:10:16 +08:00
DCFApixels
0684b90584 fix 2025-03-15 15:09:11 +08:00
DCFApixels
f23f9692a2 defines refactoring 2025-03-14 16:53:33 +08:00
DCFApixels
99f6c30e2e fix 2025-03-14 15:00:53 +08:00
DCFApixels
4b4fb185eb add .md extension for LICENSE 2025-03-14 14:24:58 +08:00
DCFApixels
6a3b78026d Update AutoInjectSystem.cs 2025-03-13 20:48:22 +08:00
DCFApixels
1b2cf99a68 update the aspect auto-build 2025-03-13 13:38:58 +08:00
DCFApixels
ae49f52272 fix assignable types injection 2025-03-10 22:21:27 +08:00
DCFApixels
73c10e98ca add AutoInjectModule 2025-03-10 13:04:52 +08:00
DCFApixels
235b450f1a Update .gitignore 2025-01-06 10:50:46 +08:00
DCFApixels
889d02d1e2 code cleanup 2025-01-06 10:48:52 +08:00
14 changed files with 241 additions and 133 deletions

1
.gitignore vendored
View File

@ -35,6 +35,7 @@ ExportedObj/
*.csproj *.csproj
*.unityproj *.unityproj
*.sln *.sln
*.sln.meta
*.suo *.suo
*.tmp *.tmp
*.user *.user

View File

View File

@ -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.16", "version": "0.9.17",
"repository": { "repository": {
"type": "git", "type": "git",
"url": "https://github.com/DCFApixels/DragonECS-AutoInjections.git" "url": "https://github.com/DCFApixels/DragonECS-AutoInjections.git"

View File

@ -1,5 +1,10 @@
using DCFApixels.DragonECS.AutoInjections.Internal; #if DISABLE_DEBUG
#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
@ -8,7 +13,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) { }
@ -16,90 +21,117 @@ namespace DCFApixels.DragonECS
internal static class EcsAspectAutoHelper internal static class EcsAspectAutoHelper
{ {
public static void Fill(EcsAspect s, EcsAspect.Builder b) private static readonly MethodInfo _incluedMethod;
private static readonly MethodInfo _excludeMethod;
private static readonly MethodInfo _optionalMethod;
private static readonly MethodInfo _includeImplicitMethod;
private static readonly MethodInfo _excludeImplicitMethod;
private static readonly MethodInfo _combineMethod;
static EcsAspectAutoHelper()
{ {
Type builderType = b.GetType(); const BindingFlags REFL_FLAGS = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
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);
Type aspectType = s.GetType(); Type builderType = typeof(EcsAspect.Builder);
foreach (var attribute in aspectType.GetCustomAttributes<ImplicitInjectAttribute>())//TODO убрать дублирование кода - вынести в отедльный метод _incluedMethod = builderType.GetMethod("IncludePool", REFL_FLAGS);
_excludeMethod = builderType.GetMethod("ExcludePool", REFL_FLAGS);
_optionalMethod = builderType.GetMethod("OptionalPool", REFL_FLAGS);
_includeImplicitMethod = builderType.GetMethod("IncludeImplicit", REFL_FLAGS);
_excludeImplicitMethod = builderType.GetMethod("ExcludeImplicit", REFL_FLAGS);
_combineMethod = builderType.GetMethod("Combine", REFL_FLAGS);
}
public static void FillMaskFields(object aspect, EcsMask mask)
{
const BindingFlags REFL_FLAGS = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
foreach (FieldInfo fieldInfo in aspect.GetType().GetFields(REFL_FLAGS))
{ {
if (attribute is IncImplicitAttribute incImplicit) if (fieldInfo.GetCustomAttribute<MaskAttribute>() == null)
{ {
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))
{ {
if (excImplicit.isPool) fieldInfo.SetValue(aspect, mask);
excludeMethod.MakeGenericMethod(excImplicit.type).Invoke(b, null);
else
excludeImplicitMethod.Invoke(b, new object[] { excImplicit.type });
continue;
} }
}//TODO КОНЕЦ убрать дублирование кода - вынести в отедльный метод else if (fieldInfo.FieldType == typeof(EcsStaticMask))
{
fieldInfo.SetValue(aspect, mask.ToStatic());
}
}
}
public static void FillFields(object aspect, EcsAspect.Builder builder)
{
const BindingFlags REFL_FLAGS = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
FieldInfo[] fieldInfos = aspectType.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); Type aspectType = aspect.GetType();
var implicitInjectAttributes = (IEnumerable<ImplicitInjectAttribute>)aspectType.GetCustomAttributes<ImplicitInjectAttribute>();
FieldInfo[] fieldInfos = aspectType.GetFields(REFL_FLAGS);
foreach (FieldInfo fieldInfo in fieldInfos) foreach (FieldInfo fieldInfo in fieldInfos)
{ {
Type fieldType = fieldInfo.FieldType; Type fieldType = fieldInfo.FieldType;
foreach (var attribute in fieldInfo.GetCustomAttributes<ImplicitInjectAttribute>())//TODO убрать дублирование кода - вынести в отедльный метод implicitInjectAttributes = implicitInjectAttributes.Concat(fieldInfo.GetCustomAttributes<ImplicitInjectAttribute>());
{
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)) if (fieldInfo.TryGetCustomAttribute(out InjectAspectMemberAttribute injectAttribute) == false)
{ {
continue; continue;
} }
if (injectAttribute is IncAttribute) switch (injectAttribute)
{ {
fieldInfo.SetValue(s, incluedMethod.MakeGenericMethod(fieldType).Invoke(b, null)); case IncAttribute atr:
var x1 = _incluedMethod;
fieldInfo.SetValue(aspect, _incluedMethod.MakeGenericMethod(fieldType).Invoke(builder, null));
break;
case ExcAttribute atr:
var x2 = _excludeMethod;
fieldInfo.SetValue(aspect, _excludeMethod.MakeGenericMethod(fieldType).Invoke(builder, null));
break;
case OptAttribute atr:
var x3 = _optionalMethod;
fieldInfo.SetValue(aspect, _optionalMethod.MakeGenericMethod(fieldType).Invoke(builder, null));
break;
case CombineAttribute atr:
var x4 = _combineMethod;
fieldInfo.SetValue(aspect, _combineMethod.MakeGenericMethod(fieldType).Invoke(builder, new object[] { atr.Order }));
break;
default:
break;
}
}
void Inject(ImplicitInjectAttribute atr_, MethodInfo method_, MethodInfo implicitMethod_)
{
if (atr_.IsPool)
{
method_.MakeGenericMethod(atr_.Type).Invoke(builder, null);
}
else
{
implicitMethod_.Invoke(builder, new object[] { atr_.Type });
}
}
foreach (var attribute in implicitInjectAttributes)
{
if (attribute is IncImplicitAttribute incImplicit)
{
Inject(incImplicit, _incluedMethod, _includeImplicitMethod);
continue; continue;
} }
if (injectAttribute is ExcAttribute) if (attribute is ExcImplicitAttribute excImplicit)
{ {
fieldInfo.SetValue(s, excludeMethod.MakeGenericMethod(fieldType).Invoke(b, null)); Inject(excImplicit, _excludeMethod, _excludeImplicitMethod);
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;
} }
} }
} }
} }
} }

View File

@ -1,4 +1,7 @@
using DCFApixels.DragonECS.PoolsCore; #if DISABLE_DEBUG
#undef DEBUG
#endif
using DCFApixels.DragonECS.PoolsCore;
using System; using System;
using System.Linq; using System.Linq;
@ -14,32 +17,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) { this.order = order; } public CombineAttribute(int order = 0) { 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 Type;
public readonly bool IsPool;
public ImplicitInjectAttribute(Type type)
{
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 IncImplicitAttribute : ImplicitInjectAttribute public sealed class IncImplicitAttribute : ImplicitInjectAttribute
{ {
public readonly Type type; public IncImplicitAttribute(Type type) : base(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 readonly Type type; public ExcImplicitAttribute(Type type) : base(type) { }
public readonly bool isPool;
public ExcImplicitAttribute(Type type)
{
this.type = type;
isPool = type.GetInterfaces().Any(o => o == typeof(IEcsPoolImplementation));
}
} }
} }

View File

@ -1,4 +1,7 @@
using System; #if DISABLE_DEBUG
#undef DEBUG
#endif
using System;
namespace DCFApixels.DragonECS namespace DCFApixels.DragonECS
{ {

View File

@ -1,3 +1,6 @@
#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;
@ -10,8 +13,8 @@ namespace DCFApixels.DragonECS
internal class AutoInjectionMap internal class AutoInjectionMap
{ {
private readonly EcsPipeline _source; private readonly EcsPipeline _source;
private Dictionary<Type, List<InjectedPropertyRecord>> _systemProperties; private Dictionary<Type, List<InjectedPropertyRecord>> _injectedTypeToPropertiesMap = new Dictionary<Type, List<InjectedPropertyRecord>>();
private HashSet<Type> _notInjected; private HashSet<Type> _notInjected = new HashSet<Type>();
private bool _isDummyInjected = false; private bool _isDummyInjected = false;
private bool _isPreInitInjectionComplete = false; private bool _isPreInitInjectionComplete = false;
@ -20,20 +23,19 @@ 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 (!_systemProperties.TryGetValue(propertType, out list)) if (_injectedTypeToPropertiesMap.TryGetValue(propertType, out list) == false)
{ {
list = new List<InjectedPropertyRecord>(); list = new List<InjectedPropertyRecord>();
_systemProperties.Add(propertType, list); _injectedTypeToPropertiesMap.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)
@ -43,87 +45,99 @@ namespace DCFApixels.DragonECS
} }
} }
} }
private static List<IInjectedProperty> GetAllPropertiesFor(Type type, bool isAgressiveInjection)
private static void Do(Type type, List<IInjectedProperty> result, bool isAgressiveInjection)
{ {
const BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; List<IInjectedProperty> result = new List<IInjectedProperty>();
result.AddRange(type.GetFields(bindingFlags) GetAllPropertiesFor(type, isAgressiveInjection, result);
.Where(o => isAgressiveInjection || o.GetCustomAttribute<DIAttribute>() != null) 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)
.Where(o => isAgressiveInjection || o.HasAttribute<DIAttribute>())
.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.GetCustomAttribute<DIAttribute>() == null) if (!isAgressiveInjection && o.HasAttribute<DIAttribute>() == false)
{ {
return false; return false;
} }
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS #if DEBUG
if (!isAgressiveInjection && o.CanWrite == false) { Throw.PropertyIsCantWrite(o); } if (!isAgressiveInjection && o.CanWrite == false) { Throw.PropertyIsCantWrite(o); }
#endif #endif
return o.CanWrite == false; return o.CanWrite;
}) })
.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.GetCustomAttribute<DIAttribute>() == null) if (!isAgressiveInjection && o.HasAttribute<DIAttribute>() == false)
{ {
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)
{ {
Do(type.BaseType, result, isAgressiveInjection); GetAllPropertiesFor(type.BaseType, isAgressiveInjection, result);
} }
} }
private static List<IInjectedProperty> GetAllPropertiesFor(Type type, bool isAgressiveInjection) private Type[] _relatedTypesBuffer;
{
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 (_isPreInitInjectionComplete == false)
{ {
_notInjected.Remove(fieldType); _notInjected.Remove(fieldType);
} }
if (_relatedTypesBuffer == null || _relatedTypesBuffer.Length < _injectedTypeToPropertiesMap.Count)
if (_systemProperties.TryGetValue(fieldType, out List<InjectedPropertyRecord> list))
{ {
string name = string.Empty; _relatedTypesBuffer = new Type[_injectedTypeToPropertiesMap.Count];
if(obj is INamedMember named) }
int relatedTypesCount = 0;
foreach (var pair in _injectedTypeToPropertiesMap)
{
if (pair.Key == fieldType || pair.Key.IsAssignableFrom(fieldType))
{ {
name = named.Name; _relatedTypesBuffer[relatedTypesCount++] = pair.Key;
} }
foreach (var item in list) }
foreach (var type in new ReadOnlySpan<Type>(_relatedTypesBuffer, 0, relatedTypesCount))
{
if (_injectedTypeToPropertiesMap.TryGetValue(type, out List<InjectedPropertyRecord> list))
{ {
string propertyName = item.Attribute.NamedInjection; string name = string.Empty;
if (string.IsNullOrEmpty(propertyName) || propertyName == name) if (obj is INamedMember named)
{ {
item.property.Inject(item.target, obj); name = named.Name;
}
foreach (var item in list)
{
string propertyName = item.Attribute.NamedInjection;
if (string.IsNullOrEmpty(propertyName) || propertyName == name)
{
item.property.Inject(item.target, obj);
}
} }
} }
} }
Type baseType = fieldType.BaseType;
if (baseType != null)
{
Inject(baseType, obj);
}
} }
public void InjectDummy() public void InjectDummy()
@ -133,7 +147,7 @@ namespace DCFApixels.DragonECS
_isDummyInjected = true; _isDummyInjected = true;
foreach (var notInjectedItem in _notInjected) foreach (var notInjectedItem in _notInjected)
{ {
foreach (var systemRecord in _systemProperties[notInjectedItem]) foreach (var systemRecord in _injectedTypeToPropertiesMap[notInjectedItem])
{ {
if (systemRecord.Attribute.NotNullDummyType == null) if (systemRecord.Attribute.NotNullDummyType == null)
continue; continue;
@ -157,7 +171,7 @@ namespace DCFApixels.DragonECS
#if DEBUG #if DEBUG
foreach (var item in _notInjected) foreach (var item in _notInjected)
{ {
foreach (var systemRecord in _systemProperties[item]) foreach (var systemRecord in _injectedTypeToPropertiesMap[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)}.");
} }
@ -187,15 +201,33 @@ 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 public class AutoInjectSystem : IEcsInject<object>, IEcsPipelineMember, IOnInitInjectionComplete, IEcsDefaultAddParams
{ {
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;
@ -213,6 +245,7 @@ namespace DCFApixels.DragonECS
} }
} }
public void OnBeforeInitInjection() { }
public void OnInitInjectionComplete() public void OnInitInjectionComplete()
{ {
_autoInjectionMap = new AutoInjectionMap(_pipeline, _isAgressiveInjection); _autoInjectionMap = new AutoInjectionMap(_pipeline, _isAgressiveInjection);
@ -229,6 +262,8 @@ 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

View File

@ -1,10 +1,23 @@
namespace DCFApixels.DragonECS #if DISABLE_DEBUG
#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.Add(new AutoInjectSystem(isAgressiveInjection)); self.AddUnique(new AutoInjectSystem(isAgressiveInjection));
return self; return self;
} }
} }

View File

@ -1,4 +1,8 @@
using System; #if DISABLE_DEBUG
#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
{ {

View File

@ -1,4 +1,7 @@
using DCFApixels.DragonECS.AutoInjections.Internal; #if DISABLE_DEBUG
#undef DEBUG
#endif
using DCFApixels.DragonECS.AutoInjections.Internal;
using System; using System;
using System.Reflection; using System.Reflection;

View File

@ -1,4 +1,7 @@
using System; #if DISABLE_DEBUG
#undef DEBUG
#endif
using System;
using System.Reflection; using System.Reflection;
namespace DCFApixels.DragonECS namespace DCFApixels.DragonECS

View File

@ -1,4 +1,7 @@
using System; #if DISABLE_DEBUG
#undef DEBUG
#endif
using System;
using System.Reflection; using System.Reflection;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;

View File

@ -1,4 +1,7 @@
using System; #if DISABLE_DEBUG
#undef DEBUG
#endif
using System;
using System.Reflection; using System.Reflection;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
@ -18,5 +21,10 @@ 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;
}
} }
} }