From 5031853e91f45ba8ae050e715d378090b9e478bf Mon Sep 17 00:00:00 2001 From: DCFApixels <99481254+DCFApixels@users.noreply.github.com> Date: Tue, 3 Jun 2025 00:22:56 +0800 Subject: [PATCH 1/9] update entlong.TryUnpack --- src/Utils/Exceptions.cs | 5 ++ src/entlong.cs | 132 ++++++++++++++++++++++++++-------------- 2 files changed, 93 insertions(+), 44 deletions(-) diff --git a/src/Utils/Exceptions.cs b/src/Utils/Exceptions.cs index 7245b3b..04fa33a 100644 --- a/src/Utils/Exceptions.cs +++ b/src/Utils/Exceptions.cs @@ -141,6 +141,11 @@ namespace DCFApixels.DragonECS.Core.Internal { throw new ArgumentException("The groups belong to different worlds."); } + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ArgumentDifferentWorldsException() + { + throw new ArgumentException("The groups belong to different worlds."); + } [MethodImpl(MethodImplOptions.NoInlining)] diff --git a/src/entlong.cs b/src/entlong.cs index d8f38b2..b93a608 100644 --- a/src/entlong.cs +++ b/src/entlong.cs @@ -136,7 +136,7 @@ namespace DCFApixels.DragonECS } #endregion - #region Unpacking + #region Unpacking Try [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool TryGetID(out int id) { @@ -156,6 +156,90 @@ namespace DCFApixels.DragonECS return IsAlive; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool TryUnpack(out int id) + { + id = _id; + return IsAlive; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool TryUnpack(out int id, out EcsWorld world) + { + world = GetWorld_Internal(); + id = _id; + return IsAlive; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool TryUnpack(out int id, out short gen, out EcsWorld world) + { + world = GetWorld_Internal(); + gen = _gen; + id = _id; + return IsAlive; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool TryUnpack(out int id, out short worldID) + { + worldID = _world; + id = _id; + return IsAlive; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool TryUnpack(out int id, out short gen, out short worldID) + { + worldID = _world; + gen = _gen; + id = _id; + return IsAlive; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool TryUnpack(EcsWorld world, out int id) + { + if (world.ID != _world) { Throw.ArgumentDifferentWorldsException(); } + id = _id; + return world.IsAlive(_id, _gen); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool TryUnpack(EcsWorld world, out int id, out short gen) + { + if (world.ID != _world) { Throw.ArgumentDifferentWorldsException(); } + gen = _gen; + id = _id; + return world.IsAlive(_id, _gen); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool TryUnpack(EcsMask mask, out int id) + { + if (mask.WorldID != _world) { Throw.ArgumentDifferentWorldsException(); } + id = _id; + return mask.World.IsAlive(_id, _gen); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool TryUnpack(EcsMask mask, out int id, out short gen) + { + if (mask.WorldID != _world) { Throw.ArgumentDifferentWorldsException(); } + gen = _gen; + id = _id; + return mask.World.IsAlive(_id, _gen); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool TryUnpack(EcsAspect aspect, out int id) + { + if (aspect.World.ID != _world) { Throw.ArgumentDifferentWorldsException(); } + id = _id; + return aspect.World.IsAlive(_id, _gen); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool TryUnpack(EcsAspect aspect, out int id, out short gen) + { + if (aspect.World.ID != _world) { Throw.ArgumentDifferentWorldsException(); } + gen = _gen; + id = _id; + return aspect.World.IsAlive(_id, _gen); + } + #endregion + + #region Unpacking/Deconstruct [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Unpack(out int id) { @@ -238,46 +322,13 @@ namespace DCFApixels.DragonECS gen = _gen; id = _id; } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool TryUnpack(out int id) - { - id = _id; - return IsAlive; - } + public void Deconstruct(out int id, out short gen, out short worldID) { Unpack(out id, out gen, out worldID); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool TryUnpack(out int id, out EcsWorld world) - { - world = GetWorld_Internal(); - id = _id; - return IsAlive; - } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool TryUnpack(out int id, out short gen, out EcsWorld world) - { - world = GetWorld_Internal(); - gen = _gen; - id = _id; - return IsAlive; - } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool TryUnpack(out int id, out short worldID) - { - worldID = _world; - id = _id; - return IsAlive; - } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool TryUnpack(out int id, out short gen, out short worldID) - { - worldID = _world; - gen = _gen; - id = _id; - return IsAlive; - } + public void Deconstruct(out int id, out EcsWorld world) { Unpack(out id, out world); } #endregion - #region Unpacking + #region Unpacking Unchecked [MethodImpl(MethodImplOptions.AggressiveInlining)] public int GetIDUnchecked() { @@ -352,13 +403,6 @@ namespace DCFApixels.DragonECS public static explicit operator int(entlong a) { return a.ID; } #endregion - #region Deconstruct - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Deconstruct(out int id, out short gen, out short worldID) { Unpack(out id, out gen, out worldID); } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Deconstruct(out int id, out EcsWorld world) { Unpack(out id, out world); } - #endregion - #region Other [MethodImpl(MethodImplOptions.AggressiveInlining)] private EcsWorld GetWorld_Internal() From a016763824662dea5dd7e9de0126e33289f0f2bb Mon Sep 17 00:00:00 2001 From: DCFApixels <99481254+DCFApixels@users.noreply.github.com> Date: Tue, 3 Jun 2025 09:49:08 +0800 Subject: [PATCH 2/9] Update entlong.cs --- src/entlong.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/entlong.cs b/src/entlong.cs index b93a608..d5ab1ac 100644 --- a/src/entlong.cs +++ b/src/entlong.cs @@ -212,7 +212,7 @@ namespace DCFApixels.DragonECS { if (mask.WorldID != _world) { Throw.ArgumentDifferentWorldsException(); } id = _id; - return mask.World.IsAlive(_id, _gen); + return mask.World.IsAlive(_id, _gen) && mask.World.IsMatchesMask(mask, _id); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool TryUnpack(EcsMask mask, out int id, out short gen) @@ -220,14 +220,14 @@ namespace DCFApixels.DragonECS if (mask.WorldID != _world) { Throw.ArgumentDifferentWorldsException(); } gen = _gen; id = _id; - return mask.World.IsAlive(_id, _gen); + return mask.World.IsAlive(_id, _gen) && mask.World.IsMatchesMask(mask, _id); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool TryUnpack(EcsAspect aspect, out int id) { if (aspect.World.ID != _world) { Throw.ArgumentDifferentWorldsException(); } id = _id; - return aspect.World.IsAlive(_id, _gen); + return aspect.World.IsAlive(_id, _gen) && aspect.IsMatches(_id); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool TryUnpack(EcsAspect aspect, out int id, out short gen) @@ -235,7 +235,7 @@ namespace DCFApixels.DragonECS if (aspect.World.ID != _world) { Throw.ArgumentDifferentWorldsException(); } gen = _gen; id = _id; - return aspect.World.IsAlive(_id, _gen); + return aspect.World.IsAlive(_id, _gen) && aspect.IsMatches(_id); } #endregion From 68118dc5810c245b80a5479d81e26ba39b010837 Mon Sep 17 00:00:00 2001 From: DCFApixels <99481254+DCFApixels@users.noreply.github.com> Date: Tue, 3 Jun 2025 23:13:28 +0800 Subject: [PATCH 3/9] add static EcsAspect.GetMask --- src/EcsAspect.cs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/EcsAspect.cs b/src/EcsAspect.cs index 3c35c3d..5474f08 100644 --- a/src/EcsAspect.cs +++ b/src/EcsAspect.cs @@ -87,6 +87,10 @@ namespace DCFApixels.DragonECS { get { return EcsAspect.CurrentBuilder.Opt; } } + public static EcsMask.Builder GetMask() + { + return EcsAspect.CurrentBuilder.GetMask(); + } } public abstract class EcsAspect : IEcsAspect, ITemplateNode, IComponentMask { @@ -130,6 +134,10 @@ namespace DCFApixels.DragonECS { get { return B.Singleton; } } + protected static EcsMask.Builder GetMask() + { + return B.GetMask(); + } #endregion //Инициализация аспектов проходит в синхронизированном состоянии, поэтому использование _staticMaskCache потоко безопасно. @@ -277,6 +285,10 @@ namespace DCFApixels.DragonECS #endregion #region Include/Exclude/Optional/Combine/Except + public EcsMask.Builder GetMask() + { + return EcsMask.New(_world); + } public Singleton Get() where T : struct { return new Singleton(_world.ID); From 9a88fff7a720f755a55468ac7c0a2e97d91454d5 Mon Sep 17 00:00:00 2001 From: DCFApixels <99481254+DCFApixels@users.noreply.github.com> Date: Wed, 4 Jun 2025 18:45:24 +0800 Subject: [PATCH 4/9] remove static EcsAspect.GetMask --- src/EcsAspect.cs | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/src/EcsAspect.cs b/src/EcsAspect.cs index 5474f08..75a3be2 100644 --- a/src/EcsAspect.cs +++ b/src/EcsAspect.cs @@ -30,7 +30,7 @@ namespace DCFApixels.DragonECS } public interface IEcsAspect { - EcsMask Mask { get; set; } + EcsMask Mask { get; } } #region IEcsAspectExtensions tmp @@ -87,10 +87,6 @@ namespace DCFApixels.DragonECS { get { return EcsAspect.CurrentBuilder.Opt; } } - public static EcsMask.Builder GetMask() - { - return EcsAspect.CurrentBuilder.GetMask(); - } } public abstract class EcsAspect : IEcsAspect, ITemplateNode, IComponentMask { @@ -134,10 +130,6 @@ namespace DCFApixels.DragonECS { get { return B.Singleton; } } - protected static EcsMask.Builder GetMask() - { - return B.GetMask(); - } #endregion //Инициализация аспектов проходит в синхронизированном состоянии, поэтому использование _staticMaskCache потоко безопасно. @@ -151,7 +143,6 @@ namespace DCFApixels.DragonECS public EcsMask Mask { get { return _mask; } - set { } } public EcsWorld World { @@ -285,10 +276,6 @@ namespace DCFApixels.DragonECS #endregion #region Include/Exclude/Optional/Combine/Except - public EcsMask.Builder GetMask() - { - return EcsMask.New(_world); - } public Singleton Get() where T : struct { return new Singleton(_world.ID); From 4db3b1c32d17511406bb0d6c135d43515f939815 Mon Sep 17 00:00:00 2001 From: DCFApixels <99481254+DCFApixels@users.noreply.github.com> Date: Wed, 4 Jun 2025 19:19:49 +0800 Subject: [PATCH 5/9] up version to 0.9.15 --- DragonECS.csproj | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/DragonECS.csproj b/DragonECS.csproj index 71a9d1d..00afd14 100644 --- a/DragonECS.csproj +++ b/DragonECS.csproj @@ -10,7 +10,7 @@ DCFApixels.DragonECS DragonECS - 0.9.14 + 0.9.15 DCFApixels ECS Framework for Game Engines with C# and .Net Platform DCFApixels diff --git a/package.json b/package.json index eccc952..22b9220 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "displayName": "DragonECS", "description": "C# Entity Component System Framework", "unity": "2020.3", - "version": "0.9.14", + "version": "0.9.15", "repository": { "type": "git", "url": "https://github.com/DCFApixels/DragonECS.git" From 0c7f743f1ea2d3a145006a2f600e01b690057e3f Mon Sep 17 00:00:00 2001 From: DCFApixels <99481254+DCFApixels@users.noreply.github.com> Date: Mon, 14 Jul 2025 16:20:11 +0800 Subject: [PATCH 6/9] Squashed commit of the following: commit 5f92f544f39679f8bcc508c17b5572ae789e7ab8 Author: DCFApixels <99481254+DCFApixels@users.noreply.github.com> Date: Mon Jul 14 16:19:58 2025 +0800 Update LayersMap.cs commit 27e7fddb40f697c5a5b21d140267e2c49e1f46f6 Author: DCFApixels <99481254+DCFApixels@users.noreply.github.com> Date: Mon Jul 14 16:13:49 2025 +0800 update commit f118605bea25abe11b196074fdd6c6baeb9124ba Author: DCFApixels <99481254+DCFApixels@users.noreply.github.com> Date: Mon Jul 14 15:49:52 2025 +0800 update pipeline building, rework/refactoring injector commit 52af6142d09a4e89f6298a9baffd378d9f77f52d Author: DCFApixels <99481254+DCFApixels@users.noreply.github.com> Date: Sat Jul 12 01:32:51 2025 +0800 Update EcsPipeline.Builder.cs commit b3571e3ed866741b4b928b8b23654916a51c23ad Author: DCFApixels <99481254+DCFApixels@users.noreply.github.com> Date: Sat Jul 12 01:28:24 2025 +0800 update commit ab50dcb7e358ca1a1098aedfee84573f5736671d Author: DCFApixels <99481254+DCFApixels@users.noreply.github.com> Date: Fri Jul 11 23:37:48 2025 +0800 update commit c23aa1b2234c678bb52178aab4bd895a92bf8f11 Author: DCFApixels <99481254+DCFApixels@users.noreply.github.com> Date: Fri Jul 11 17:38:45 2025 +0800 update StructList --- src/EcsPipeline.Builder.cs | 64 ++++- src/EcsPipeline.cs | 20 +- src/EcsWorld.static.cs | 2 +- src/Injections/EcsPipelineExtensions.cs | 2 +- src/Injections/Graph/InjectionBranch.cs | 41 +-- src/Injections/Graph/InjectionNode.cs | 2 - src/Injections/Injector.cs | 330 ++++++++++++++---------- src/Internal/ReflectionUtility.cs | 4 + src/Internal/StructList.cs | 103 +++++++- src/Utils/Exceptions.cs | 6 +- src/Utils/LayersMap.cs | 32 +-- 11 files changed, 395 insertions(+), 211 deletions(-) diff --git a/src/EcsPipeline.Builder.cs b/src/EcsPipeline.Builder.cs index fec1c9a..3d3b04c 100644 --- a/src/EcsPipeline.Builder.cs +++ b/src/EcsPipeline.Builder.cs @@ -34,16 +34,55 @@ namespace DCFApixels.DragonECS private int _freeNodesCount = 0; private readonly Dictionary _layerLists = new Dictionary(8); - private readonly List _initDeclaredRunners = new List(4); + private readonly StructList _initDeclaredRunners = new StructList(4); public readonly LayersMap Layers; - public readonly Injector.Builder Injector; + public readonly InitInjectionList Injections; public readonly Configurator Configs; private AddParams _defaultAddParams = new AddParams(BASIC_LAYER, 0, false); private HashSet _uniqueSystemsSet = new HashSet(); + + #region InitInjector + public readonly struct InitInjectionList + { + private readonly Builder _pipelineBuilder; + public readonly Injector.InjectionList Instance; + public InitInjectionList(Injector.InjectionList instance, Builder pipelineBuilder) + { + Instance = instance; + _pipelineBuilder = pipelineBuilder; + } + public Builder AddNode() + { + Instance.AddNode(); + return _pipelineBuilder; + } + public Builder Inject(T obj) + { + Instance.Inject(obj); + return _pipelineBuilder; + } + public Builder Extract(ref T obj) + { + Instance.Extract(ref obj); + return _pipelineBuilder; + } + public Builder Merge(Injector.InjectionList other) + { + Instance.MergeWith(other); + return _pipelineBuilder; + } + public Builder Merge(InitInjectionList other) + { + Instance.MergeWith(other.Instance); + return _pipelineBuilder; + } + } + #endregion + #region Properties //private ReadOnlySpan SystemRecords //{ @@ -57,11 +96,12 @@ namespace DCFApixels.DragonECS if (config == null) { config = new ConfigContainer(); } Configs = new Configurator(config, this); - Injector = new Injector.Builder(this); - Injector.AddNode(); - Injector.AddNode(); - Injector.AddNode(); - Injector.AddNode(); + var injectorBuilder = new Injector.InjectionList(); + Injections = new InitInjectionList(injectorBuilder, this); + Injections.AddNode(); + Injections.AddNode(); + Injections.AddNode(); + Injections.AddNode(); var graph = new DependencyGraph(BASIC_LAYER); Layers = new LayersMap(graph, this, PRE_BEGIN_LAYER, BEGIN_LAYER, BASIC_LAYER, END_LAYER, POST_END_LAYER); @@ -201,7 +241,7 @@ namespace DCFApixels.DragonECS _defaultAddParams = oldDefaultAddParams; } - Injector.Inject(module); + Injections.Inject(module); return this; } #endregion @@ -351,7 +391,7 @@ namespace DCFApixels.DragonECS //} } - + IEcsProcess[] allSystems = new IEcsProcess[allSystemsLength]; { int i = 0; @@ -368,7 +408,7 @@ namespace DCFApixels.DragonECS } } - EcsPipeline pipeline = new EcsPipeline(Configs.Instance.GetContainer(), Injector, allSystems); + EcsPipeline pipeline = new EcsPipeline(allSystems, Configs.Instance.GetContainer(), Injections.Instance); foreach (var item in _initDeclaredRunners) { item.Declare(pipeline); @@ -395,7 +435,7 @@ namespace DCFApixels.DragonECS #endregion #region Configurator - public class Configurator + public readonly struct Configurator { private readonly IConfigContainerWriter _configs; private readonly Builder _builder; @@ -564,6 +604,8 @@ namespace DCFApixels.DragonECS #endregion #region Obsolete + [Obsolete("Use " + nameof(Injections))] + public readonly InitInjectionList Injector; [Obsolete("Use LayersMap")] public class LayerList : LayersMap { diff --git a/src/EcsPipeline.cs b/src/EcsPipeline.cs index cb73cbc..788a127 100644 --- a/src/EcsPipeline.cs +++ b/src/EcsPipeline.cs @@ -78,11 +78,21 @@ namespace DCFApixels.DragonECS #endregion #region Constructors - private EcsPipeline(IConfigContainer configs, Injector.Builder injectorBuilder, IEcsProcess[] systems) + public EcsPipeline(IEnumerable systems, IConfigContainer configs = null, Injector.InjectionList injectionList = null) { + if(systems == null) { Throw.ArgumentNull(nameof(systems)); } + + if(configs == null) + { + configs = new ConfigContainer(); + } + if(injectionList == null) + { + injectionList = Injector.InjectionList._Empty_Internal; + } + _configs = configs; - _allSystems = systems; - injectorBuilder.Inject(this); + _allSystems = systems.ToArray(); var members = GetProcess(); for (int i = 0; i < members.Length; i++) @@ -90,8 +100,10 @@ namespace DCFApixels.DragonECS members[i].Pipeline = this; } - _injector = injectorBuilder.Build(this); + _injector = new Injector(this); + injectionList.InitInjectTo(_injector, this); } + ~EcsPipeline() { if (_isDestoryed) { return; } diff --git a/src/EcsWorld.static.cs b/src/EcsWorld.static.cs index 95be601..9d85021 100644 --- a/src/EcsWorld.static.cs +++ b/src/EcsWorld.static.cs @@ -114,7 +114,7 @@ namespace DCFApixels.DragonECS } public ReadOnlySpan GetAllWorldComponents() { - return _worldComponentPools.ToReadOnlySpan(); + return _worldComponentPools.AsReadOnlySpan(); } public abstract class WorldComponentPoolAbstract { diff --git a/src/Injections/EcsPipelineExtensions.cs b/src/Injections/EcsPipelineExtensions.cs index 95a9fad..7b8d23e 100644 --- a/src/Injections/EcsPipelineExtensions.cs +++ b/src/Injections/EcsPipelineExtensions.cs @@ -10,7 +10,7 @@ namespace DCFApixels.DragonECS public static EcsPipeline.Builder Inject(this EcsPipeline.Builder self, T data) { if (data == null) { Throw.ArgumentNull(); } - self.Injector.Inject(data); + self.Injections.Inject(data); if (data is IEcsModule module) { self.AddModule(module); diff --git a/src/Injections/Graph/InjectionBranch.cs b/src/Injections/Graph/InjectionBranch.cs index eaf1a29..477a7e0 100644 --- a/src/Injections/Graph/InjectionBranch.cs +++ b/src/Injections/Graph/InjectionBranch.cs @@ -8,11 +8,8 @@ namespace DCFApixels.DragonECS.Core.Internal { internal class InjectionBranch { - private readonly Injector _source; private readonly Type _type; - private InjectionNodeBase[] _nodes = new InjectionNodeBase[4]; - private int _nodesCount = 0; - + private StructList _nodes = new StructList(4); public Type Type { [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -21,45 +18,15 @@ namespace DCFApixels.DragonECS.Core.Internal public ReadOnlySpan Nodes { [MethodImpl(MethodImplOptions.AggressiveInlining)] - get { return new ReadOnlySpan(_nodes, 0, _nodesCount); } + get { return _nodes.AsReadOnlySpan(); } } - public InjectionBranch(Injector source, Type type) + public InjectionBranch(Type type) { - _source = source; _type = type; } - public void Inject(object obj) - { - for (int i = 0; i < _nodesCount; i++) - { - _nodes[i].Inject(obj); - } - if (obj is IInjectionBlock block) - { - block.InjectTo(_source); - } - } public void AddNode(InjectionNodeBase node) { - if (_nodesCount >= _nodes.Length) - { - Array.Resize(ref _nodes, (_nodes.Length << 1) + 1); - } - _nodes[_nodesCount++] = node; - } - public void Trim() - { - if (_nodesCount <= 0) - { - _nodes = Array.Empty(); - return; - } - - InjectionNodeBase[] newNodes = new InjectionNodeBase[_nodesCount]; - for (int i = 0; i < newNodes.Length; i++) - { - newNodes[i] = _nodes[i]; - } + _nodes.Add(node); } } } diff --git a/src/Injections/Graph/InjectionNode.cs b/src/Injections/Graph/InjectionNode.cs index a933d1b..e849493 100644 --- a/src/Injections/Graph/InjectionNode.cs +++ b/src/Injections/Graph/InjectionNode.cs @@ -60,8 +60,6 @@ namespace DCFApixels.DragonECS.Core.Internal } private void ExtractTo_Internal(object target) { - var type = target.GetType(); - var intrfs = type.GetInterfaces(); if (target is IEcsInject intrf) { intrf.Inject(_currentInjectedDependency); diff --git a/src/Injections/Injector.cs b/src/Injections/Injector.cs index a722962..8786867 100644 --- a/src/Injections/Injector.cs +++ b/src/Injections/Injector.cs @@ -11,14 +11,59 @@ namespace DCFApixels.DragonECS { public class Injector : IInjector { - private EcsPipeline _pipeline; - private Dictionary _branches = new Dictionary(32); - private Dictionary _nodes = new Dictionary(32); - private bool _isInit = false; + private readonly EcsPipeline _pipeline; + private readonly Dictionary _branches = new Dictionary(32); + private readonly Dictionary _nodes = new Dictionary(32); + private ReadOnlySpan GetNodes(Type type) + { + if(_branches.TryGetValue(type, out InjectionBranch branch)) + { + return branch.Nodes; + } + return Array.Empty(); + } -#if DEBUG - private HashSet _requiredInjectionTypes = new HashSet(); -#endif + #region InjectionTempHistory + private StructList _injectionTempHistory = new StructList(32); + private int _injectionTempHistoryReadersCount = 0; + private int StartReadHistory_Internal() + { + _injectionTempHistoryReadersCount++; + return _injectionTempHistory.Count; + } + private ReadOnlySpan EndReadHistory_Internal(int startIndex) + { + _injectionTempHistoryReadersCount--; + if(_injectionTempHistoryReadersCount < 0) + { + Throw.OpeningClosingMethodsBalanceError(); + } + var result = _injectionTempHistory.AsReadOnlySpan().Slice(startIndex); + if (_injectionTempHistoryReadersCount == 0) + { + _injectionTempHistory.Recreate(); + } + return result; + } + public readonly struct InjectionHistorySpanReader + { + private readonly Injector _injector; + private readonly int _startIndex; + public InjectionHistorySpanReader(Injector injector) + { + _injector = injector; + _startIndex = _injector.StartReadHistory_Internal(); + } + public ReadOnlySpan StopReadAndGetHistorySpan() + { + return _injector.EndReadHistory_Internal(_startIndex); + } + } + public InjectionHistorySpanReader StartReadHistory() + { + return new InjectionHistorySpanReader(this); + } + #endregion public EcsPipeline Pipelie { @@ -26,12 +71,14 @@ namespace DCFApixels.DragonECS get { return _pipeline; } } - private Injector() { } + public Injector(EcsPipeline pipeline) + { + _pipeline = pipeline; + } #region Inject/Extract/AddNode public void Inject(T obj) { - object raw = obj; Type tType = typeof(T); Type objType = obj.GetType(); if (_branches.TryGetValue(objType, out InjectionBranch branch) == false) @@ -40,30 +87,31 @@ namespace DCFApixels.DragonECS { InitNode(new InjectionNode()); } - bool hasNode = _nodes.ContainsKey(objType); - if (hasNode == false && obj is IInjectionUnit unit) + bool hasObjTypeNode = _nodes.ContainsKey(objType); + if (hasObjTypeNode == false && obj is IInjectionUnit unit) { unit.InitInjectionNode(new InjectionGraph(this)); - hasNode = _nodes.ContainsKey(objType); + hasObjTypeNode = _nodes.ContainsKey(objType); } - branch = new InjectionBranch(this, objType); + branch = new InjectionBranch(objType); InitBranch(branch); - -#if DEBUG - foreach (var requiredInjectionType in _requiredInjectionTypes) - { - if (requiredInjectionType.IsAssignableFrom(objType)) - { - if (_nodes.ContainsKey(requiredInjectionType) == false) - { - throw new InjectionException($"A systems in the pipeline implements IEcsInject<{requiredInjectionType.Name}> interface, but no suitable injection node was found in the Injector. To create a node, use Injector.AddNode<{requiredInjectionType.Name}>() or implement the IInjectionUnit interface for type {objType.Name}."); - } - } - } -#endif } - branch.Inject(raw); + + + var branchNodes = branch.Nodes; + for (int i = 0; i < branchNodes.Length; i++) + { + branchNodes[i].Inject(obj); + } + if (_injectionTempHistoryReadersCount > 0) + { + _injectionTempHistory.Add(obj); + } + if (obj is IInjectionBlock block) + { + block.InjectTo(this); + } } public void ExtractAllTo(object target) { @@ -86,12 +134,11 @@ namespace DCFApixels.DragonECS } throw new InjectionException($"The injection graph is missing a node for {type.Name} type. To create a node, use the Injector.AddNode<{type.Name}>() method directly in the injector or in the implementation of the IInjectionUnit for {type.Name}."); } - public void AddNode() + public bool AddNode() { - if (_nodes.ContainsKey(typeof(T)) == false) - { - InitNode(new InjectionNode()); - } + if (_nodes.ContainsKey(typeof(T))) { return false; } + InitNode(new InjectionNode()); + return true; } #endregion @@ -126,71 +173,121 @@ namespace DCFApixels.DragonECS } } } - private bool IsCanInstantiated(Type type) - { - return !type.IsAbstract && !type.IsInterface; - } #endregion - #region Build - private void Init(EcsPipeline pipeline) + #region InjectionList + public class InjectionList : IInjector { - if (_isInit) { Throw.Exception("Already initialized"); } + public static readonly InjectionList _Empty_Internal = new InjectionList(); - _pipeline = pipeline; - foreach (var pair in _nodes) + private StructList _injections = new StructList(32); + private StructList _nodes = new StructList(32); + private EcsWorld _monoWorld; + public void AddNode() { - pair.Value.Init(pipeline); + _nodes.Add(new Node()); } - _isInit = true; - -#if DEBUG - var systems = _pipeline.AllSystems; - var injectType = typeof(IEcsInject<>); - foreach (var system in systems) + public void Inject(T obj) { - var type = system.GetType(); - foreach (var requiredInjectionType in type.GetInterfaces().Where(o => o.IsGenericType && o.GetGenericTypeDefinition() == injectType).Select(o => o.GenericTypeArguments[0])) + FindMonoWorld(obj); + _injections.Add(new Injection(obj)); + } + public void Extract(ref T obj) // TODO проверить + { + Type type = typeof(T); + for (int i = _injections.Count - 1; i >= 0; i--) { - _requiredInjectionTypes.Add(requiredInjectionType); + var item = _injections[i]; + if (type.IsAssignableFrom(item.Type)) + { + obj = (T)item.Raw; + return; + } + } + Throw.UndefinedException(); + } + public void MergeWith(InjectionList other) + { + foreach (var item in other._injections) + { + FindMonoWorld(item); + _injections.Add(item); + } + foreach (var item in other._nodes) + { + _nodes.Add(item); } } -#endif - } - private bool TryDeclare() - { - Type type = typeof(T); - if (_nodes.ContainsKey(type)) + public void InitInjectTo(Injector injector, EcsPipeline pipeline) { - return false; - } - InitNode(new InjectionNode()); -#if !REFLECTION_DISABLED - if (IsCanInstantiated(type)) +#if DEBUG + HashSet requiredInjectionTypes = new HashSet(); + var systems = pipeline.AllSystems; + var injectType = typeof(IEcsInject<>); + foreach (var system in systems) + { + var type = system.GetType(); + foreach (var requiredInjectionType in type.GetInterfaces().Where(o => o.IsGenericType && o.GetGenericTypeDefinition() == injectType).Select(o => o.GenericTypeArguments[0])) + { + requiredInjectionTypes.Add(requiredInjectionType); + } + } + var reader = injector.StartReadHistory(); #endif - { - InitBranch(new InjectionBranch(this, type)); - } - return true; - } - public class Builder : IInjector - { - private EcsPipeline.Builder _source; - private Injector _instance; - private List _initInjections = new List(16); - private EcsWorld _monoWorld; - internal Builder(EcsPipeline.Builder source) - { - _source = source; - _instance = new Injector(); + + var initInjectionCallbacks = pipeline.GetProcess(); + foreach (var system in initInjectionCallbacks) + { + system.OnBeforeInitInjection(); + } + + injector.Inject(pipeline); + injector.AddNode(); + InjectTo(injector, pipeline); + + foreach (var system in initInjectionCallbacks) + { + system.OnInitInjectionComplete(); + } + + +#if DEBUG + var injectionHistory = reader.StopReadAndGetHistorySpan(); + foreach (var injection in injectionHistory) + { + foreach (var node in injector.GetNodes(injection.GetType())) + { + requiredInjectionTypes.Remove(node.Type); + } + } + if (requiredInjectionTypes.Count > 0) + { + foreach (var requiredInjectionType in requiredInjectionTypes) + { + throw new InjectionException($"A systems in the pipeline implements IEcsInject<{requiredInjectionType.Name}> interface, but no suitable injection node was found in the Injector. To create a node, use Injector.AddNode<{requiredInjectionType.Name}>() or implement the IInjectionUnit interface for the type being injected."); + } + } +#endif } - public EcsPipeline.Builder AddNode() + public void InjectTo(Injector injector, EcsPipeline pipeline) { - _instance.TryDeclare(); - return _source; + var monoWorldProcess = pipeline.GetProcess(); // TODO Проверить IMonoWorldInject + foreach (var monoWorldSystem in monoWorldProcess) + { + monoWorldSystem.World = _monoWorld; + } + foreach (var item in _nodes) + { + item.AddNodeTo(injector); + } + foreach (var item in _injections) + { + item.InjectTo(injector); + } } - public EcsPipeline.Builder Inject(T obj) + + private void FindMonoWorld(object obj) { if (obj is EcsWorld objWorld) { @@ -216,55 +313,6 @@ namespace DCFApixels.DragonECS } } } - _initInjections.Add(new InitInject(obj)); - return _source; - } - public EcsPipeline.Builder Extract(ref T obj) // TODO проверить - { - Type type = typeof(T); - for (int i = _initInjections.Count - 1; i >= 0; i--) - { - var item = _initInjections[i]; - if (type.IsAssignableFrom(item.Type)) - { - obj = (T)item.Raw; - return _source; - } - } - Throw.UndefinedException(); - return default; - } - public Injector Build(EcsPipeline pipeline) - { - var monoWorldProcess = pipeline.GetProcess(); // TODO Проверить IMonoWorldInject - foreach (var monoWorldSystem in monoWorldProcess) - { - monoWorldSystem.World = _monoWorld; - } - - - var initInjectionCallbacks = pipeline.GetProcess(); - foreach (var system in initInjectionCallbacks) - { - system.OnBeforeInitInjection(); - } - _instance.Init(pipeline); - foreach (var item in _initInjections) - { - item.InjectTo(_instance); - } - foreach (var system in initInjectionCallbacks) - { - system.OnInitInjectionComplete(); - } - return _instance; - } - public void Add(Builder other) - { - foreach (var item in other._initInjections) - { - _initInjections.Add(item); - } } void IInjector.Inject(T obj) { Inject(obj); } @@ -275,24 +323,38 @@ namespace DCFApixels.DragonECS return result; } - private abstract class InitInjectBase + private abstract class NodeBase + { + public abstract Type Type { get; } + public abstract void AddNodeTo(Injector instance); + } + private sealed class Node : NodeBase + { + public override Type Type { get { return typeof(T); } } + public override void AddNodeTo(Injector instance) + { + instance.AddNode(); + } + } + + private abstract class InjectionBase { public abstract Type Type { get; } public abstract object Raw { get; } public abstract void InjectTo(Injector instance); } - private sealed class InitInject : InitInjectBase + private sealed class Injection : InjectionBase { private T _injectedData; public override Type Type { get { return typeof(T); } } public override object Raw { get { return _injectedData; } } - public InitInject(T injectedData) + public Injection(T injectedData) { _injectedData = injectedData; } public override void InjectTo(Injector instance) { - instance.Inject(_injectedData); + instance.Inject(_injectedData); } } } diff --git a/src/Internal/ReflectionUtility.cs b/src/Internal/ReflectionUtility.cs index 46ed351..cc15e5f 100644 --- a/src/Internal/ReflectionUtility.cs +++ b/src/Internal/ReflectionUtility.cs @@ -31,5 +31,9 @@ namespace DCFApixels.DragonECS.Core.Internal { return self.GetCustomAttribute(inherit) != null; } + public static bool IsCanInstantiated(this Type type) + { + return !type.IsAbstract && !type.IsInterface; + } } } diff --git a/src/Internal/StructList.cs b/src/Internal/StructList.cs index 1d6ad02..4331c09 100644 --- a/src/Internal/StructList.cs +++ b/src/Internal/StructList.cs @@ -12,8 +12,12 @@ namespace DCFApixels.DragonECS.Core.Internal [DebuggerDisplay("Count: {Count}")] internal struct StructList { + internal readonly static bool _IsManaged = RuntimeHelpers.IsReferenceOrContainsReferences(); + internal T[] _items; internal int _count; + + #region Properties public int Count { [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -30,6 +34,11 @@ namespace DCFApixels.DragonECS.Core.Internal Array.Resize(ref _items, value); } } + public bool IsNull + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get { return _items == null; } + } public T this[int index] { [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -49,13 +58,16 @@ namespace DCFApixels.DragonECS.Core.Internal _items[index] = value; } } + #endregion + #region Constructors [MethodImpl(MethodImplOptions.AggressiveInlining)] public StructList(int capacity) { _items = new T[ArrayUtility.NextPow2(capacity)]; _count = 0; } + #endregion [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Add(T item) @@ -64,6 +76,11 @@ namespace DCFApixels.DragonECS.Core.Internal { Array.Resize(ref _items, _items.Length << 1); } + AddFixed(item); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AddFixed(T item) + { _items[_count++] = item; } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -72,6 +89,11 @@ namespace DCFApixels.DragonECS.Core.Internal return Array.IndexOf(_items, item, 0, _count); } [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool Contains(T item) + { + return _count != 0 && IndexOf(item) >= 0; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void SwapAt(int idnex1, int idnex2) { T tmp = _items[idnex1]; @@ -93,7 +115,10 @@ namespace DCFApixels.DragonECS.Core.Internal if (index < 0 || index >= _count) { Throw.ArgumentOutOfRange(); } #endif _items[index] = _items[--_count]; - _items[_count] = default; + if (_IsManaged) + { + _items[_count] = default; + } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void RemoveAtWithOrder(int index) @@ -128,6 +153,56 @@ namespace DCFApixels.DragonECS.Core.Internal } return false; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public T Peek() + { +#if DEBUG + if (_count <= 0) { Throw.EmptyStack(); } +#endif + return _items[_count - 1]; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool TryPeek(out T result) + { + if (_count <= 0) + { + result = default; + return false; + } + result = _items[_count - 1]; + return true; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public T Pop() + { +#if DEBUG + if (_count <= 0) { Throw.EmptyStack(); } +#endif + + T result = _items[--_count]; + if (_IsManaged) + { + _items[_count] = default; + } + return result; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool TryPop(out T result) + { + if (_count <= 0) + { + result = default; + return false; + } + result = _items[--_count]; + if (_IsManaged) + { + _items[_count] = default; + } + return true; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void FastClear() { @@ -136,19 +211,31 @@ namespace DCFApixels.DragonECS.Core.Internal [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Clear() { - for (int i = 0; i < _count; i++) + if (_IsManaged) { - _items[i] = default; + Array.Clear(_items, 0, _count); } _count = 0; } [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Recreate() + { + _items = new T[_items.Length]; + _count = 0; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Recreate(int newSize) + { + _items = new T[ArrayUtility.NextPow2(newSize)]; + _count = 0; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public ReadOnlySpan.Enumerator GetEnumerator() { return new ReadOnlySpan(_items, 0, _count).GetEnumerator(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public ReadOnlySpan ToReadOnlySpan() + public ReadOnlySpan AsReadOnlySpan() { return new ReadOnlySpan(_items, 0, _count); } @@ -157,5 +244,13 @@ namespace DCFApixels.DragonECS.Core.Internal { return _items.Take(_count); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public T[] ToArray() + { + if (_count <= 0) { return Array.Empty(); } + T[] result = new T[_count]; + Array.Copy(_items, result, _count); + return result; + } } } \ No newline at end of file diff --git a/src/Utils/Exceptions.cs b/src/Utils/Exceptions.cs index 04fa33a..832c41d 100644 --- a/src/Utils/Exceptions.cs +++ b/src/Utils/Exceptions.cs @@ -147,7 +147,11 @@ namespace DCFApixels.DragonECS.Core.Internal throw new ArgumentException("The groups belong to different worlds."); } - + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void EmptyStack() + { + throw new InvalidOperationException("Invalid Operation Empty Stack."); + } [MethodImpl(MethodImplOptions.NoInlining)] internal static void ArgumentNull() { diff --git a/src/Utils/LayersMap.cs b/src/Utils/LayersMap.cs index 8ee47a8..4a27d4c 100644 --- a/src/Utils/LayersMap.cs +++ b/src/Utils/LayersMap.cs @@ -19,7 +19,7 @@ namespace DCFApixels.DragonECS.Core private readonly IDependencyGraph _graph; private readonly EcsPipeline.Builder _pipelineBuilder; - private readonly string _preBeginLayer; + //private readonly string _preBeginLayer; #region Properties public EcsPipeline.Builder Back @@ -209,21 +209,21 @@ namespace DCFApixels.DragonECS.Core { var enumerator = other.GetEnumerator(); string prev = null; - if (_preBeginLayer != null) - { - while (enumerator.MoveNext()) - { - var layer = enumerator.Current; - if (layer == _preBeginLayer) { break; } - - Add(layer); - if (prev != null) - { - Move(prev).Before(layer); - } - prev = layer; - } - } + //if (_preBeginLayer != null) + //{ + // while (enumerator.MoveNext()) + // { + // var layer = enumerator.Current; + // if (layer == _preBeginLayer) { break; } + // + // Add(layer); + // if (prev != null) + // { + // Move(prev).Before(layer); + // } + // prev = layer; + // } + //} while (enumerator.MoveNext()) { var layer = enumerator.Current; From cfc1ffe9a6f48997a55a7a9f69510179e26531de Mon Sep 17 00:00:00 2001 From: DCFApixels <99481254+DCFApixels@users.noreply.github.com> Date: Mon, 14 Jul 2025 20:55:09 +0800 Subject: [PATCH 7/9] impl EcsPipeline.Builder.MergeWith --- src/EcsPipeline.Builder.cs | 108 ++++++++++++++++++------------------- 1 file changed, 53 insertions(+), 55 deletions(-) diff --git a/src/EcsPipeline.Builder.cs b/src/EcsPipeline.Builder.cs index 3d3b04c..34e1efe 100644 --- a/src/EcsPipeline.Builder.cs +++ b/src/EcsPipeline.Builder.cs @@ -44,45 +44,6 @@ namespace DCFApixels.DragonECS private HashSet _uniqueSystemsSet = new HashSet(); - - #region InitInjector - public readonly struct InitInjectionList - { - private readonly Builder _pipelineBuilder; - public readonly Injector.InjectionList Instance; - public InitInjectionList(Injector.InjectionList instance, Builder pipelineBuilder) - { - Instance = instance; - _pipelineBuilder = pipelineBuilder; - } - public Builder AddNode() - { - Instance.AddNode(); - return _pipelineBuilder; - } - public Builder Inject(T obj) - { - Instance.Inject(obj); - return _pipelineBuilder; - } - public Builder Extract(ref T obj) - { - Instance.Extract(ref obj); - return _pipelineBuilder; - } - public Builder Merge(Injector.InjectionList other) - { - Instance.MergeWith(other); - return _pipelineBuilder; - } - public Builder Merge(InitInjectionList other) - { - Instance.MergeWith(other.Instance); - return _pipelineBuilder; - } - } - #endregion - #region Properties //private ReadOnlySpan SystemRecords //{ @@ -274,22 +235,21 @@ namespace DCFApixels.DragonECS } private void MergeWith(Builder other) { - throw new NotImplementedException(); - //Injector.Add(other.Injector); - //foreach (var declaredRunners in other._initDeclaredRunners) - //{ - // _initDeclaredRunners.Add(declaredRunners); - //} - //foreach (var config in other.Configs.Instance.GetAllConfigs()) - //{ - // Configs.Instance.Set(config.Key, config.Value); - //} - //Layers.MergeWith(other.Layers); - // - //foreach (ref readonly SystemNode otherRecord in new LinkedListCountIterator(_systemNodes, _systemNodesCount, _startIndex)) - //{ - // AddNode_Internal(otherRecord.system, otherRecord.layerName, otherRecord.sortOrder, otherRecord.isUnique); - //} + Injections.MergeWith(other.Injections); + foreach (var declaredRunners in other._initDeclaredRunners) + { + _initDeclaredRunners.Add(declaredRunners); + } + foreach (var config in other.Configs.Instance.GetAllConfigs()) + { + Configs.Instance.Set(config.Key, config.Value); + } + Layers.MergeWith(other.Layers); + + foreach (ref readonly SystemNode otherRecord in new LinkedListCountIterator(_systemNodes, _systemNodesCount, _startIndex)) + { + AddNode_Internal(otherRecord.system, otherRecord.layerName, otherRecord.sortOrder, otherRecord.isUnique); + } } #endregion @@ -434,6 +394,44 @@ namespace DCFApixels.DragonECS } #endregion + #region InitInjector + public readonly struct InitInjectionList + { + private readonly Builder _pipelineBuilder; + public readonly Injector.InjectionList Instance; + public InitInjectionList(Injector.InjectionList instance, Builder pipelineBuilder) + { + Instance = instance; + _pipelineBuilder = pipelineBuilder; + } + public Builder AddNode() + { + Instance.AddNode(); + return _pipelineBuilder; + } + public Builder Inject(T obj) + { + Instance.Inject(obj); + return _pipelineBuilder; + } + public Builder Extract(ref T obj) + { + Instance.Extract(ref obj); + return _pipelineBuilder; + } + public Builder Merge(Injector.InjectionList other) + { + Instance.MergeWith(other); + return _pipelineBuilder; + } + public Builder MergeWith(InitInjectionList other) + { + Instance.MergeWith(other.Instance); + return _pipelineBuilder; + } + } + #endregion + #region Configurator public readonly struct Configurator { From e4dc76e0372accc5a5c44733e587992428e22d98 Mon Sep 17 00:00:00 2001 From: DCFApixels <99481254+DCFApixels@users.noreply.github.com> Date: Mon, 14 Jul 2025 21:10:57 +0800 Subject: [PATCH 8/9] update --- src/EcsPipeline.Builder.cs | 2 +- src/EcsPipeline.cs | 17 ++++++++++------- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/EcsPipeline.Builder.cs b/src/EcsPipeline.Builder.cs index 34e1efe..64b6309 100644 --- a/src/EcsPipeline.Builder.cs +++ b/src/EcsPipeline.Builder.cs @@ -368,7 +368,7 @@ namespace DCFApixels.DragonECS } } - EcsPipeline pipeline = new EcsPipeline(allSystems, Configs.Instance.GetContainer(), Injections.Instance); + EcsPipeline pipeline = new EcsPipeline((ReadOnlySpan)allSystems, Configs.Instance.GetContainer(), Injections.Instance); foreach (var item in _initDeclaredRunners) { item.Declare(pipeline); diff --git a/src/EcsPipeline.cs b/src/EcsPipeline.cs index 788a127..a8ca5d0 100644 --- a/src/EcsPipeline.cs +++ b/src/EcsPipeline.cs @@ -78,21 +78,25 @@ namespace DCFApixels.DragonECS #endregion #region Constructors - public EcsPipeline(IEnumerable systems, IConfigContainer configs = null, Injector.InjectionList injectionList = null) + public EcsPipeline(ReadOnlySpan systems, IConfigContainer configs = null, Injector.InjectionList injectionList = null) : + this(systems.ToArray(), configs, injectionList) + { } + public EcsPipeline(IEnumerable systems, IConfigContainer configs = null, Injector.InjectionList injectionList = null) : + this(systems.ToArray(), configs, injectionList) + { } + private EcsPipeline(IEcsProcess[] systems, IConfigContainer configs, Injector.InjectionList injectionList) { - if(systems == null) { Throw.ArgumentNull(nameof(systems)); } - - if(configs == null) + if (configs == null) { configs = new ConfigContainer(); } - if(injectionList == null) + if (injectionList == null) { injectionList = Injector.InjectionList._Empty_Internal; } _configs = configs; - _allSystems = systems.ToArray(); + _allSystems = systems; var members = GetProcess(); for (int i = 0; i < members.Length; i++) @@ -103,7 +107,6 @@ namespace DCFApixels.DragonECS _injector = new Injector(this); injectionList.InitInjectTo(_injector, this); } - ~EcsPipeline() { if (_isDestoryed) { return; } From 007ef493a83e94db6fe3de70204da7e1cfdd857e Mon Sep 17 00:00:00 2001 From: DCFApixels <99481254+DCFApixels@users.noreply.github.com> Date: Tue, 15 Jul 2025 13:57:53 +0800 Subject: [PATCH 9/9] up version to 0.9.16 --- DragonECS.csproj | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/DragonECS.csproj b/DragonECS.csproj index 00afd14..ec34c10 100644 --- a/DragonECS.csproj +++ b/DragonECS.csproj @@ -10,7 +10,7 @@ DCFApixels.DragonECS DragonECS - 0.9.15 + 0.9.16 DCFApixels ECS Framework for Game Engines with C# and .Net Platform DCFApixels diff --git a/package.json b/package.json index 22b9220..a376ddc 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "displayName": "DragonECS", "description": "C# Entity Component System Framework", "unity": "2020.3", - "version": "0.9.15", + "version": "0.9.16", "repository": { "type": "git", "url": "https://github.com/DCFApixels/DragonECS.git"