DragonECS-AutoInjections/src/AutoInjectSystem.cs

101 lines
2.9 KiB
C#
Raw Normal View History

2023-03-29 16:43:06 +08:00
using System;
using System.Collections.Generic;
using System.Reflection;
namespace DCFApixels.DragonECS
{
internal class AutoInjectionMap
{
2023-03-30 05:33:55 +08:00
private readonly EcsPipeline _source;
2023-03-29 16:43:06 +08:00
private Dictionary<Type, List<FiledRecord>> _systems;
2023-03-30 05:33:55 +08:00
public AutoInjectionMap(EcsPipeline source)
2023-03-29 16:43:06 +08:00
{
_source = source;
var allsystems = _source.AllSystems;
_systems = new Dictionary<Type, List<FiledRecord>>();
foreach (var system in allsystems)
{
Type systemType = system.GetType();
foreach (var field in systemType.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic))
{
if(field.GetCustomAttribute<AutoInjectAttribute>() != null)
{
Type fieldType = field.FieldType;
List<FiledRecord> list;
if (!_systems.TryGetValue(fieldType, out list))
{
list = new List<FiledRecord>();
_systems.Add(fieldType, list);
}
list.Add(new FiledRecord(system, field));
}
}
}
}
public void Inject(object obj)
{
Type objectType = obj.GetType();
if(_systems.TryGetValue(objectType, out List<FiledRecord> list))
{
foreach (var item in list)
{
item.field.SetValue(item.target, obj);
}
}
}
private readonly struct FiledRecord
{
public readonly IEcsSystem target;
public readonly FieldInfo field;
public FiledRecord(IEcsSystem target, FieldInfo field)
{
this.target = target;
this.field = field;
}
}
}
[DebugHide, DebugColor(DebugColor.Gray)]
public class AutoInjectSystem : IEcsPreInitSystem, IEcsPreInject
{
2023-03-30 05:33:55 +08:00
private EcsPipeline _pipeline;
2023-03-29 16:43:06 +08:00
private List<object> _injectQueue = new List<object>();
private AutoInjectionMap _autoInjectionMap;
public void PreInject(object obj)
{
2023-03-30 05:33:55 +08:00
if(_pipeline == null)
2023-03-29 16:43:06 +08:00
{
_injectQueue.Add(obj);
return;
}
AutoInject(obj);
}
2023-03-30 05:33:55 +08:00
public void PreInit(EcsPipeline pipeline)
2023-03-29 16:43:06 +08:00
{
2023-03-30 05:33:55 +08:00
_pipeline = pipeline;
_autoInjectionMap = new AutoInjectionMap(_pipeline);
2023-03-29 16:43:06 +08:00
foreach (var obj in _injectQueue)
{
AutoInject(obj);
}
_injectQueue.Clear();
_injectQueue = null;
}
private void AutoInject(object obj)
{
_autoInjectionMap.Inject(obj);
}
}
}