mirror of
https://github.com/DCFApixels/DragonECS-AutoInjections.git
synced 2025-09-18 05:04:35 +08:00
fix assignable types injection
This commit is contained in:
parent
73c10e98ca
commit
ae49f52272
@ -10,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>> _systemProperties;
|
private Dictionary<Type, List<InjectedPropertyRecord>> _systemProperties = 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,17 +20,16 @@ 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 (_systemProperties.TryGetValue(propertType, out list) == false)
|
||||||
{
|
{
|
||||||
list = new List<InjectedPropertyRecord>();
|
list = new List<InjectedPropertyRecord>();
|
||||||
_systemProperties.Add(propertType, list);
|
_systemProperties.Add(propertType, list);
|
||||||
@ -43,17 +42,24 @@ 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;
|
||||||
}
|
}
|
||||||
@ -63,10 +69,11 @@ namespace DCFApixels.DragonECS
|
|||||||
return o.CanWrite == false;
|
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.GetCustomAttribute<DIAttribute>() == null)
|
if (!isAgressiveInjection && o.HasAttribute<DIAttribute>() == false)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -81,26 +88,36 @@ namespace DCFApixels.DragonECS
|
|||||||
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 < _systemProperties.Count)
|
||||||
|
{
|
||||||
|
_relatedTypesBuffer = new Type[_systemProperties.Count];
|
||||||
|
}
|
||||||
|
int relatedTypesCount = 0;
|
||||||
|
foreach (var pair in _systemProperties)
|
||||||
|
{
|
||||||
|
if (pair.Key == fieldType || pair.Key.IsAssignableFrom(fieldType))
|
||||||
|
{
|
||||||
|
_relatedTypesBuffer[relatedTypesCount++] = pair.Key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (_systemProperties.TryGetValue(fieldType, out List<InjectedPropertyRecord> list))
|
foreach (var type in new ReadOnlySpan<Type>(_relatedTypesBuffer, 0, relatedTypesCount))
|
||||||
|
{
|
||||||
|
if (_systemProperties.TryGetValue(type, out List<InjectedPropertyRecord> list))
|
||||||
{
|
{
|
||||||
string name = string.Empty;
|
string name = string.Empty;
|
||||||
if (obj is INamedMember named)
|
if (obj is INamedMember named)
|
||||||
@ -116,14 +133,8 @@ namespace DCFApixels.DragonECS
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Type baseType = fieldType.BaseType;
|
|
||||||
if (baseType != null)
|
|
||||||
{
|
|
||||||
Inject(baseType, obj);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void InjectDummy()
|
public void InjectDummy()
|
||||||
|
@ -18,5 +18,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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user