mirror of
https://github.com/DCFApixels/DragonECS-AutoInjections.git
synced 2025-09-18 05:04:35 +08:00
add notnull dummy
This commit is contained in:
parent
540d341778
commit
1a2bd2bea2
@ -5,7 +5,12 @@ namespace DCFApixels.DragonECS
|
|||||||
[AttributeUsage(AttributeTargets.Field, Inherited = false, AllowMultiple = false)]
|
[AttributeUsage(AttributeTargets.Field, Inherited = false, AllowMultiple = false)]
|
||||||
public sealed class AutoInjectAttribute : Attribute
|
public sealed class AutoInjectAttribute : Attribute
|
||||||
{
|
{
|
||||||
|
public readonly Type notNullDummyType;
|
||||||
|
|
||||||
|
public AutoInjectAttribute(Type notNullDummyType = null)
|
||||||
|
{
|
||||||
|
this.notNullDummyType = notNullDummyType;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,25 +4,35 @@ using System.Reflection;
|
|||||||
|
|
||||||
namespace DCFApixels.DragonECS
|
namespace DCFApixels.DragonECS
|
||||||
{
|
{
|
||||||
|
internal static class DummyInstance<T>
|
||||||
|
{
|
||||||
|
public static T intsance = (T)Activator.CreateInstance(typeof(T));
|
||||||
|
}
|
||||||
internal class AutoInjectionMap
|
internal class AutoInjectionMap
|
||||||
{
|
{
|
||||||
private readonly EcsPipeline _source;
|
private readonly EcsPipeline _source;
|
||||||
|
|
||||||
private Dictionary<Type, List<FiledRecord>> _systems;
|
private Dictionary<Type, List<FiledRecord>> _systems;
|
||||||
|
private HashSet<Type> _notInjected;
|
||||||
|
|
||||||
|
private Type dummyInstance = typeof(DummyInstance<>);
|
||||||
|
|
||||||
|
private bool _isDummyInjected = false;
|
||||||
|
|
||||||
public AutoInjectionMap(EcsPipeline source)
|
public AutoInjectionMap(EcsPipeline source)
|
||||||
{
|
{
|
||||||
_source = source;
|
_source = source;
|
||||||
var allsystems = _source.AllSystems;
|
var allsystems = _source.AllSystems;
|
||||||
_systems = new Dictionary<Type, List<FiledRecord>>();
|
_systems = new Dictionary<Type, List<FiledRecord>>();
|
||||||
|
_notInjected = new HashSet<Type>();
|
||||||
foreach (var system in allsystems)
|
foreach (var system in allsystems)
|
||||||
{
|
{
|
||||||
Type systemType = system.GetType();
|
Type systemType = system.GetType();
|
||||||
foreach (var field in systemType.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic))
|
foreach (var field in systemType.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic))
|
||||||
{
|
{
|
||||||
if(field.GetCustomAttribute<AutoInjectAttribute>() != null)
|
AutoInjectAttribute autoInjectAttribute = field.GetCustomAttribute<AutoInjectAttribute>();
|
||||||
|
if (autoInjectAttribute != null)
|
||||||
{
|
{
|
||||||
|
|
||||||
Type fieldType = field.FieldType;
|
Type fieldType = field.FieldType;
|
||||||
List<FiledRecord> list;
|
List<FiledRecord> list;
|
||||||
if (!_systems.TryGetValue(fieldType, out list))
|
if (!_systems.TryGetValue(fieldType, out list))
|
||||||
@ -31,16 +41,19 @@ namespace DCFApixels.DragonECS
|
|||||||
_systems.Add(fieldType, list);
|
_systems.Add(fieldType, list);
|
||||||
}
|
}
|
||||||
|
|
||||||
list.Add(new FiledRecord(system, field));
|
list.Add(new FiledRecord(system, field, autoInjectAttribute));
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
foreach (var item in _systems.Keys)
|
||||||
|
{
|
||||||
|
_notInjected.Add(item);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Inject(object obj)
|
public void Inject(object obj)
|
||||||
{
|
{
|
||||||
|
_notInjected.Remove(obj.GetType());
|
||||||
Type objectType = obj.GetType();
|
Type objectType = obj.GetType();
|
||||||
if(_systems.TryGetValue(objectType, out List<FiledRecord> list))
|
if(_systems.TryGetValue(objectType, out List<FiledRecord> list))
|
||||||
{
|
{
|
||||||
@ -51,26 +64,59 @@ namespace DCFApixels.DragonECS
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void InjectDummy()
|
||||||
|
{
|
||||||
|
if (_isDummyInjected)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_isDummyInjected = true;
|
||||||
|
foreach (var notInjectedItem in _notInjected)
|
||||||
|
{
|
||||||
|
foreach (var systemRecord in _systems[notInjectedItem])
|
||||||
|
{
|
||||||
|
if (systemRecord.attribute.notNullDummyType == null)
|
||||||
|
continue;
|
||||||
|
if (systemRecord.field.GetValue(systemRecord.target) != null)
|
||||||
|
continue;
|
||||||
|
if (systemRecord.field.FieldType.IsAssignableFrom(systemRecord.attribute.notNullDummyType) == false)
|
||||||
|
{
|
||||||
|
EcsDebug.Print(EcsConsts.DEBUG_ERROR_TAG, $"The {systemRecord.attribute.notNullDummyType} dummy cannot be assigned to the {systemRecord.field.FieldType.Name} field");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
systemRecord.field.SetValue(systemRecord.target,
|
||||||
|
dummyInstance.MakeGenericType(systemRecord.attribute.notNullDummyType).GetField("intsance", BindingFlags.Static | BindingFlags.Public).GetValue(null));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_notInjected.Clear();
|
||||||
|
_notInjected= null;
|
||||||
|
}
|
||||||
|
|
||||||
private readonly struct FiledRecord
|
private readonly struct FiledRecord
|
||||||
{
|
{
|
||||||
public readonly IEcsSystem target;
|
public readonly IEcsSystem target;
|
||||||
public readonly FieldInfo field;
|
public readonly FieldInfo field;
|
||||||
public FiledRecord(IEcsSystem target, FieldInfo field)
|
public readonly AutoInjectAttribute attribute;
|
||||||
|
public FiledRecord(IEcsSystem target, FieldInfo field, AutoInjectAttribute attribute)
|
||||||
{
|
{
|
||||||
this.target = target;
|
this.target = target;
|
||||||
this.field = field;
|
this.field = field;
|
||||||
|
this.attribute = attribute;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[DebugHide, DebugColor(DebugColor.Gray)]
|
[DebugHide, DebugColor(DebugColor.Gray)]
|
||||||
public class AutoInjectSystem : IEcsPreInitSystem, IEcsPreInject
|
public class AutoInjectSystem : IEcsPreInitSystem, IEcsPreInject, IEcsPreInitInjectCallbacks
|
||||||
{
|
{
|
||||||
private EcsPipeline _pipeline;
|
private EcsPipeline _pipeline;
|
||||||
private List<object> _injectQueue = new List<object>();
|
private List<object> _injectQueue = new List<object>();
|
||||||
|
|
||||||
private AutoInjectionMap _autoInjectionMap;
|
private AutoInjectionMap _autoInjectionMap;
|
||||||
|
|
||||||
|
private bool _isPreInjectionComplete = false;
|
||||||
|
|
||||||
public void PreInject(object obj)
|
public void PreInject(object obj)
|
||||||
{
|
{
|
||||||
if(_pipeline == null)
|
if(_pipeline == null)
|
||||||
@ -91,11 +137,25 @@ namespace DCFApixels.DragonECS
|
|||||||
}
|
}
|
||||||
_injectQueue.Clear();
|
_injectQueue.Clear();
|
||||||
_injectQueue = null;
|
_injectQueue = null;
|
||||||
|
if (_isPreInjectionComplete)
|
||||||
|
{
|
||||||
|
_autoInjectionMap.InjectDummy();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AutoInject(object obj)
|
private void AutoInject(object obj)
|
||||||
{
|
{
|
||||||
_autoInjectionMap.Inject(obj);
|
_autoInjectionMap.Inject(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void OnPreInitInjectionBefore() { }
|
||||||
|
public void OnPreInitInjectionAfter()
|
||||||
|
{
|
||||||
|
_isPreInjectionComplete = true;
|
||||||
|
if (_autoInjectionMap != null)
|
||||||
|
{
|
||||||
|
_autoInjectionMap.InjectDummy();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user