From ae49f5227263c9db7b700559cdd433bab32a6c1e Mon Sep 17 00:00:00 2001 From: DCFApixels <99481254+DCFApixels@users.noreply.github.com> Date: Mon, 10 Mar 2025 22:21:27 +0800 Subject: [PATCH] fix assignable types injection --- src/AutoInjectSystem.cs | 87 ++++++++++++++++++-------------- src/Utils/ReflectionExtenions.cs | 5 ++ 2 files changed, 54 insertions(+), 38 deletions(-) diff --git a/src/AutoInjectSystem.cs b/src/AutoInjectSystem.cs index 48ac746..4126113 100644 --- a/src/AutoInjectSystem.cs +++ b/src/AutoInjectSystem.cs @@ -10,8 +10,8 @@ namespace DCFApixels.DragonECS internal class AutoInjectionMap { private readonly EcsPipeline _source; - private Dictionary> _systemProperties; - private HashSet _notInjected; + private Dictionary> _systemProperties = new Dictionary>(); + private HashSet _notInjected = new HashSet(); private bool _isDummyInjected = false; private bool _isPreInitInjectionComplete = false; @@ -20,17 +20,16 @@ namespace DCFApixels.DragonECS { _source = source; var allsystems = _source.AllSystems; - _systemProperties = new Dictionary>(); - _notInjected = new HashSet(); foreach (var system in allsystems) { Type systemType = system.GetType(); if (systemType == typeof(AutoInjectSystem)) { continue; } + foreach (var property in GetAllPropertiesFor(systemType, isAgressiveInjection)) { Type propertType = property.PropertyType; List list; - if (!_systemProperties.TryGetValue(propertType, out list)) + if (_systemProperties.TryGetValue(propertType, out list) == false) { list = new List(); _systemProperties.Add(propertType, list); @@ -43,17 +42,24 @@ namespace DCFApixels.DragonECS } } } - - private static void Do(Type type, List result, bool isAgressiveInjection) + private static List GetAllPropertiesFor(Type type, bool isAgressiveInjection) { - const BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; - result.AddRange(type.GetFields(bindingFlags) - .Where(o => isAgressiveInjection || o.GetCustomAttribute() != null) + List result = new List(); + GetAllPropertiesFor(type, isAgressiveInjection, result); + return result; + } + private static void GetAllPropertiesFor(Type type, bool isAgressiveInjection, List result) + { + const BindingFlags REFL_FLAGS = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; + + result.AddRange(type.GetFields(REFL_FLAGS) + .Where(o => isAgressiveInjection || o.HasAttribute()) .Select(o => new InjectedField(o))); - result.AddRange(type.GetProperties(bindingFlags) + + result.AddRange(type.GetProperties(REFL_FLAGS) .Where(o => { - if (!isAgressiveInjection && o.GetCustomAttribute() == null) + if (!isAgressiveInjection && o.HasAttribute() == false) { return false; } @@ -63,10 +69,11 @@ namespace DCFApixels.DragonECS return o.CanWrite == false; }) .Select(o => new InjectedProperty(o))); - result.AddRange(type.GetMethods(bindingFlags) + + result.AddRange(type.GetMethods(REFL_FLAGS) .Where(o => { - if (!isAgressiveInjection && o.GetCustomAttribute() == null) + if (!isAgressiveInjection && o.HasAttribute() == false) { return false; } @@ -81,49 +88,53 @@ namespace DCFApixels.DragonECS return o.IsGenericMethod == false && parameters.Length == 1; }) .Select(o => new InjectedMethod(o))); + if (type.BaseType != null) { - Do(type.BaseType, result, isAgressiveInjection); + GetAllPropertiesFor(type.BaseType, isAgressiveInjection, result); } } - private static List GetAllPropertiesFor(Type type, bool isAgressiveInjection) - { - List result = new List(); - Do(type, result, isAgressiveInjection); - return result; - } + private Type[] _relatedTypesBuffer; public void Inject(Type fieldType, object obj) { - if (!_isPreInitInjectionComplete) + if (_isPreInitInjectionComplete == false) { _notInjected.Remove(fieldType); } - - if (_systemProperties.TryGetValue(fieldType, out List list)) + if (_relatedTypesBuffer == null || _relatedTypesBuffer.Length < _systemProperties.Count) { - string name = string.Empty; - if (obj is INamedMember named) + _relatedTypesBuffer = new Type[_systemProperties.Count]; + } + int relatedTypesCount = 0; + foreach (var pair in _systemProperties) + { + 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(_relatedTypesBuffer, 0, relatedTypesCount)) + { + if (_systemProperties.TryGetValue(type, out List list)) { - string propertyName = item.Attribute.NamedInjection; - if (string.IsNullOrEmpty(propertyName) || propertyName == name) + string name = string.Empty; + 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() diff --git a/src/Utils/ReflectionExtenions.cs b/src/Utils/ReflectionExtenions.cs index c66f155..a9949cd 100644 --- a/src/Utils/ReflectionExtenions.cs +++ b/src/Utils/ReflectionExtenions.cs @@ -18,5 +18,10 @@ namespace DCFApixels.DragonECS.AutoInjections.Internal attribute = self.GetCustomAttribute(); return attribute != null; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool HasAttribute(this MemberInfo self) where T : Attribute + { + return self.GetCustomAttribute() != null; + } } }