diff --git a/src/Builtin/InjectSystem.cs b/src/Builtin/InjectSystem.cs index b9ab4e1..2fe8a5e 100644 --- a/src/Builtin/InjectSystem.cs +++ b/src/Builtin/InjectSystem.cs @@ -5,6 +5,23 @@ using System.Linq; namespace DCFApixels.DragonECS { + public readonly struct Injector + { + private readonly EcsPipeline _pipeline; + public Injector(EcsPipeline pipeline) + { + _pipeline = pipeline; + } + public void Inject(T data) + { + _pipeline.Inject(data); + } + } + public interface IInjectionBlock + { + void InjectTo(Injector i); + } + [MetaName(nameof(PreInject))] [BindWithEcsRunner(typeof(EcsPreInjectRunner))] public interface IEcsPreInject : IEcsProcess @@ -56,7 +73,14 @@ namespace DCFApixels.DragonECS { void IEcsPreInject.PreInject(object obj) { - foreach (var item in targets) item.PreInject(obj); + if (obj is IInjectionBlock container) + { + container.InjectTo(new Injector(Pipeline)); + } + foreach (var item in targets) + { + item.PreInject(obj); + } } } [MetaTags(MetaTags.HIDDEN)] @@ -74,9 +98,9 @@ namespace DCFApixels.DragonECS { Type baseType = typeof(T).BaseType; if (baseType != typeof(object) && baseType != typeof(ValueType) && baseType != null) - _baseTypeInjectRunner = (EcsBaseTypeInjectRunner)Activator.CreateInstance(typeof(EcsBaseTypeInjectRunner<>).MakeGenericType(baseType), Source); + _baseTypeInjectRunner = (EcsBaseTypeInjectRunner)Activator.CreateInstance(typeof(EcsBaseTypeInjectRunner<>).MakeGenericType(baseType), Pipeline); else - _baseTypeInjectRunner = new EcsObjectTypePreInjectRunner(Source); + _baseTypeInjectRunner = new EcsObjectTypePreInjectRunner(Pipeline); } } internal abstract class EcsBaseTypeInjectRunner @@ -155,7 +179,10 @@ namespace DCFApixels.DragonECS public static partial class EcsPipelineExtensions { - public static void Inject(EcsPipeline self, T data) => self.GetRunner>().Inject(data); + public static void Inject(this EcsPipeline self, T data) + { + self.GetRunner>().Inject(data); + } } public static partial class EcsPipelineBuilderExtensions { @@ -167,33 +194,33 @@ namespace DCFApixels.DragonECS self.AddModule(module); return self; } - public static EcsPipeline.Builder Inject(this EcsPipeline.Builder self, A a, B b) + public static EcsPipeline.Builder Inject(this EcsPipeline.Builder self, T0 d0, T1 d1) { - return self.Inject(a).Inject(b); + return self.Inject(d0).Inject(d1); } - public static EcsPipeline.Builder Inject(this EcsPipeline.Builder self, A a, B b, C c) + public static EcsPipeline.Builder Inject(this EcsPipeline.Builder self, T0 d0, T1 d1, T2 d2) { - return self.Inject(a).Inject(b).Inject(c); + return self.Inject(d0).Inject(d1).Inject(d2); } - public static EcsPipeline.Builder Inject(this EcsPipeline.Builder self, A a, B b, C c, D d) + public static EcsPipeline.Builder Inject(this EcsPipeline.Builder self, T0 d0, T1 d1, T2 d2, T3 d3) { - return self.Inject(a).Inject(b).Inject(c).Inject(d); + return self.Inject(d0).Inject(d1).Inject(d2).Inject(d3); } - public static EcsPipeline.Builder Inject(this EcsPipeline.Builder self, A a, B b, C c, D d, E e) + public static EcsPipeline.Builder Inject(this EcsPipeline.Builder self, T0 d0, T1 d1, T2 d2, T3 d3, T4 d4) { - return self.Inject(a).Inject(b).Inject(c).Inject(d).Inject(e); + return self.Inject(d0).Inject(d1).Inject(d2).Inject(d3).Inject(d4); } - public static EcsPipeline.Builder Inject(this EcsPipeline.Builder self, A a, B b, C c, D d, E e, F f) + public static EcsPipeline.Builder Inject(this EcsPipeline.Builder self, T0 d0, T1 d1, T2 d2, T3 d3, T4 d4, T5 f) { - return self.Inject(a).Inject(b).Inject(c).Inject(d).Inject(e).Inject(f); + return self.Inject(d0).Inject(d1).Inject(d2).Inject(d3).Inject(d4).Inject(f); } - public static EcsPipeline.Builder Inject(this EcsPipeline.Builder self, A a, B b, C c, D d, E e, F f, G g) + public static EcsPipeline.Builder Inject(this EcsPipeline.Builder self, T0 d0, T1 d1, T2 d2, T3 d3, T4 d4, T5 f, T6 d6) { - return self.Inject(a).Inject(b).Inject(c).Inject(d).Inject(e).Inject(f).Inject(g); + return self.Inject(d0).Inject(d1).Inject(d2).Inject(d3).Inject(d4).Inject(f).Inject(d6); } - public static EcsPipeline.Builder Inject(this EcsPipeline.Builder self, A a, B b, C c, D d, E e, F f, G g, H h) + public static EcsPipeline.Builder Inject(this EcsPipeline.Builder self, T0 d0, T1 d1, T2 d2, T3 d3, T4 d4, T5 f, T6 d6, T7 d7) { - return self.Inject(a).Inject(b).Inject(c).Inject(d).Inject(e).Inject(f).Inject(g).Inject(h); + return self.Inject(d0).Inject(d1).Inject(d2).Inject(d3).Inject(d4).Inject(f).Inject(d6).Inject(d7); } } } diff --git a/src/EcsPipeline.cs b/src/EcsPipeline.cs index b77cccc..98ea570 100644 --- a/src/EcsPipeline.cs +++ b/src/EcsPipeline.cs @@ -38,16 +38,21 @@ namespace DCFApixels.DragonECS #endregion #region Runners + public T[] GetSystems() where T : IEcsProcess + { + return _allSystems.Where(o => o is T).Select(o => (T)o).ToArray(); + } public T GetRunner() where T : IEcsProcess { Type type = typeof(T); if (_runners.TryGetValue(type, out IEcsRunner result)) + { return (T)result; + } result = (IEcsRunner)EcsRunner.Instantiate(this); _runners.Add(type, result); return (T)result; } - internal void OnRunnerDestroy(IEcsRunner runner) { _runners.Remove(runner.Interface); diff --git a/src/EcsRunner.cs b/src/EcsRunner.cs index 46bdd3f..9a0dd8c 100644 --- a/src/EcsRunner.cs +++ b/src/EcsRunner.cs @@ -54,9 +54,9 @@ namespace DCFApixels.DragonECS { public interface IEcsRunner { - EcsPipeline Source { get; } + EcsPipeline Pipeline { get; } Type Interface { get; } - IList Targets { get; } + IList TargetsRaw { get; } object Filter { get; } bool IsHasFilter { get; } bool IsDestroyed { get; } @@ -203,9 +203,10 @@ namespace DCFApixels.DragonECS private bool _isDestroyed; #region Properties - public EcsPipeline Source => _source; + public EcsPipeline Pipeline => _source; public Type Interface => typeof(TInterface); - public IList Targets => _targetsSealed; + public IList TargetsRaw => _targetsSealed; + public ReadOnlySpan Targets => targets; public object Filter => _filter; public bool IsHasFilter => _isHasFilter; public bool IsDestroyed => _isDestroyed; @@ -225,9 +226,13 @@ namespace DCFApixels.DragonECS internal void Rebuild() { if (_isHasFilter) + { Set(_source, FilterSystems(_source.AllSystems), _isHasFilter, _filter); + } else + { Set(_source, FilterSystems(_source.AllSystems, _filter), _isHasFilter, _filter); + } } public void Destroy() {