mirror of
https://github.com/DCFApixels/DragonECS.git
synced 2025-09-17 17:34:36 +08:00
Compare commits
10 Commits
5c6c440db6
...
7fa63ef7e3
Author | SHA1 | Date | |
---|---|---|---|
![]() |
7fa63ef7e3 | ||
![]() |
007ef493a8 | ||
![]() |
e4dc76e037 | ||
![]() |
cfc1ffe9a6 | ||
![]() |
0c7f743f1e | ||
![]() |
4db3b1c32d | ||
![]() |
9a88fff7a7 | ||
![]() |
68118dc581 | ||
![]() |
a016763824 | ||
![]() |
5031853e91 |
@ -10,7 +10,7 @@
|
|||||||
<RootNamespace>DCFApixels.DragonECS</RootNamespace>
|
<RootNamespace>DCFApixels.DragonECS</RootNamespace>
|
||||||
|
|
||||||
<Title>DragonECS</Title>
|
<Title>DragonECS</Title>
|
||||||
<Version>0.9.14</Version>
|
<Version>0.9.16</Version>
|
||||||
<Authors>DCFApixels</Authors>
|
<Authors>DCFApixels</Authors>
|
||||||
<Description>ECS Framework for Game Engines with C# and .Net Platform</Description>
|
<Description>ECS Framework for Game Engines with C# and .Net Platform</Description>
|
||||||
<Copyright>DCFApixels</Copyright>
|
<Copyright>DCFApixels</Copyright>
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
"displayName": "DragonECS",
|
"displayName": "DragonECS",
|
||||||
"description": "C# Entity Component System Framework",
|
"description": "C# Entity Component System Framework",
|
||||||
"unity": "2020.3",
|
"unity": "2020.3",
|
||||||
"version": "0.9.14",
|
"version": "0.9.16",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/DCFApixels/DragonECS.git"
|
"url": "https://github.com/DCFApixels/DragonECS.git"
|
||||||
|
@ -30,7 +30,7 @@ namespace DCFApixels.DragonECS
|
|||||||
}
|
}
|
||||||
public interface IEcsAspect
|
public interface IEcsAspect
|
||||||
{
|
{
|
||||||
EcsMask Mask { get; set; }
|
EcsMask Mask { get; }
|
||||||
}
|
}
|
||||||
|
|
||||||
#region IEcsAspectExtensions tmp
|
#region IEcsAspectExtensions tmp
|
||||||
@ -143,7 +143,6 @@ namespace DCFApixels.DragonECS
|
|||||||
public EcsMask Mask
|
public EcsMask Mask
|
||||||
{
|
{
|
||||||
get { return _mask; }
|
get { return _mask; }
|
||||||
set { }
|
|
||||||
}
|
}
|
||||||
public EcsWorld World
|
public EcsWorld World
|
||||||
{
|
{
|
||||||
|
@ -34,10 +34,10 @@ namespace DCFApixels.DragonECS
|
|||||||
private int _freeNodesCount = 0;
|
private int _freeNodesCount = 0;
|
||||||
|
|
||||||
private readonly Dictionary<string, LayerSystemsList> _layerLists = new Dictionary<string, LayerSystemsList>(8);
|
private readonly Dictionary<string, LayerSystemsList> _layerLists = new Dictionary<string, LayerSystemsList>(8);
|
||||||
private readonly List<InitDeclaredRunner> _initDeclaredRunners = new List<InitDeclaredRunner>(4);
|
private readonly StructList<InitDeclaredRunner> _initDeclaredRunners = new StructList<InitDeclaredRunner>(4);
|
||||||
|
|
||||||
public readonly LayersMap Layers;
|
public readonly LayersMap Layers;
|
||||||
public readonly Injector.Builder Injector;
|
public readonly InitInjectionList Injections;
|
||||||
public readonly Configurator Configs;
|
public readonly Configurator Configs;
|
||||||
|
|
||||||
private AddParams _defaultAddParams = new AddParams(BASIC_LAYER, 0, false);
|
private AddParams _defaultAddParams = new AddParams(BASIC_LAYER, 0, false);
|
||||||
@ -57,11 +57,12 @@ namespace DCFApixels.DragonECS
|
|||||||
if (config == null) { config = new ConfigContainer(); }
|
if (config == null) { config = new ConfigContainer(); }
|
||||||
Configs = new Configurator(config, this);
|
Configs = new Configurator(config, this);
|
||||||
|
|
||||||
Injector = new Injector.Builder(this);
|
var injectorBuilder = new Injector.InjectionList();
|
||||||
Injector.AddNode<object>();
|
Injections = new InitInjectionList(injectorBuilder, this);
|
||||||
Injector.AddNode<EcsWorld>();
|
Injections.AddNode<object>();
|
||||||
Injector.AddNode<EcsAspect>();
|
Injections.AddNode<EcsWorld>();
|
||||||
Injector.AddNode<EcsPipeline>();
|
Injections.AddNode<EcsAspect>();
|
||||||
|
Injections.AddNode<EcsPipeline>();
|
||||||
|
|
||||||
var graph = new DependencyGraph<string>(BASIC_LAYER);
|
var graph = new DependencyGraph<string>(BASIC_LAYER);
|
||||||
Layers = new LayersMap(graph, this, PRE_BEGIN_LAYER, BEGIN_LAYER, BASIC_LAYER, END_LAYER, POST_END_LAYER);
|
Layers = new LayersMap(graph, this, PRE_BEGIN_LAYER, BEGIN_LAYER, BASIC_LAYER, END_LAYER, POST_END_LAYER);
|
||||||
@ -201,7 +202,7 @@ namespace DCFApixels.DragonECS
|
|||||||
_defaultAddParams = oldDefaultAddParams;
|
_defaultAddParams = oldDefaultAddParams;
|
||||||
}
|
}
|
||||||
|
|
||||||
Injector.Inject(module);
|
Injections.Inject(module);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
@ -234,22 +235,21 @@ namespace DCFApixels.DragonECS
|
|||||||
}
|
}
|
||||||
private void MergeWith(Builder other)
|
private void MergeWith(Builder other)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
Injections.MergeWith(other.Injections);
|
||||||
//Injector.Add(other.Injector);
|
foreach (var declaredRunners in other._initDeclaredRunners)
|
||||||
//foreach (var declaredRunners in other._initDeclaredRunners)
|
{
|
||||||
//{
|
_initDeclaredRunners.Add(declaredRunners);
|
||||||
// _initDeclaredRunners.Add(declaredRunners);
|
}
|
||||||
//}
|
foreach (var config in other.Configs.Instance.GetAllConfigs())
|
||||||
//foreach (var config in other.Configs.Instance.GetAllConfigs())
|
{
|
||||||
//{
|
Configs.Instance.Set(config.Key, config.Value);
|
||||||
// Configs.Instance.Set(config.Key, config.Value);
|
}
|
||||||
//}
|
Layers.MergeWith(other.Layers);
|
||||||
//Layers.MergeWith(other.Layers);
|
|
||||||
//
|
foreach (ref readonly SystemNode otherRecord in new LinkedListCountIterator<SystemNode>(_systemNodes, _systemNodesCount, _startIndex))
|
||||||
//foreach (ref readonly SystemNode otherRecord in new LinkedListCountIterator<SystemNode>(_systemNodes, _systemNodesCount, _startIndex))
|
{
|
||||||
//{
|
AddNode_Internal(otherRecord.system, otherRecord.layerName, otherRecord.sortOrder, otherRecord.isUnique);
|
||||||
// AddNode_Internal(otherRecord.system, otherRecord.layerName, otherRecord.sortOrder, otherRecord.isUnique);
|
}
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
@ -351,7 +351,7 @@ namespace DCFApixels.DragonECS
|
|||||||
//}
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
IEcsProcess[] allSystems = new IEcsProcess[allSystemsLength];
|
IEcsProcess[] allSystems = new IEcsProcess[allSystemsLength];
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
@ -368,7 +368,7 @@ namespace DCFApixels.DragonECS
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
EcsPipeline pipeline = new EcsPipeline(Configs.Instance.GetContainer(), Injector, allSystems);
|
EcsPipeline pipeline = new EcsPipeline((ReadOnlySpan<IEcsProcess>)allSystems, Configs.Instance.GetContainer(), Injections.Instance);
|
||||||
foreach (var item in _initDeclaredRunners)
|
foreach (var item in _initDeclaredRunners)
|
||||||
{
|
{
|
||||||
item.Declare(pipeline);
|
item.Declare(pipeline);
|
||||||
@ -394,8 +394,46 @@ namespace DCFApixels.DragonECS
|
|||||||
}
|
}
|
||||||
#endregion
|
#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<T>()
|
||||||
|
{
|
||||||
|
Instance.AddNode<T>();
|
||||||
|
return _pipelineBuilder;
|
||||||
|
}
|
||||||
|
public Builder Inject<T>(T obj)
|
||||||
|
{
|
||||||
|
Instance.Inject(obj);
|
||||||
|
return _pipelineBuilder;
|
||||||
|
}
|
||||||
|
public Builder Extract<T>(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
|
#region Configurator
|
||||||
public class Configurator
|
public readonly struct Configurator
|
||||||
{
|
{
|
||||||
private readonly IConfigContainerWriter _configs;
|
private readonly IConfigContainerWriter _configs;
|
||||||
private readonly Builder _builder;
|
private readonly Builder _builder;
|
||||||
@ -564,6 +602,8 @@ namespace DCFApixels.DragonECS
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Obsolete
|
#region Obsolete
|
||||||
|
[Obsolete("Use " + nameof(Injections))]
|
||||||
|
public readonly InitInjectionList Injector;
|
||||||
[Obsolete("Use LayersMap")]
|
[Obsolete("Use LayersMap")]
|
||||||
public class LayerList : LayersMap
|
public class LayerList : LayersMap
|
||||||
{
|
{
|
||||||
|
@ -78,11 +78,25 @@ namespace DCFApixels.DragonECS
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Constructors
|
#region Constructors
|
||||||
private EcsPipeline(IConfigContainer configs, Injector.Builder injectorBuilder, IEcsProcess[] systems)
|
public EcsPipeline(ReadOnlySpan<IEcsProcess> systems, IConfigContainer configs = null, Injector.InjectionList injectionList = null) :
|
||||||
|
this(systems.ToArray(), configs, injectionList)
|
||||||
|
{ }
|
||||||
|
public EcsPipeline(IEnumerable<IEcsProcess> systems, IConfigContainer configs = null, Injector.InjectionList injectionList = null) :
|
||||||
|
this(systems.ToArray(), configs, injectionList)
|
||||||
|
{ }
|
||||||
|
private EcsPipeline(IEcsProcess[] systems, IConfigContainer configs, Injector.InjectionList injectionList)
|
||||||
{
|
{
|
||||||
|
if (configs == null)
|
||||||
|
{
|
||||||
|
configs = new ConfigContainer();
|
||||||
|
}
|
||||||
|
if (injectionList == null)
|
||||||
|
{
|
||||||
|
injectionList = Injector.InjectionList._Empty_Internal;
|
||||||
|
}
|
||||||
|
|
||||||
_configs = configs;
|
_configs = configs;
|
||||||
_allSystems = systems;
|
_allSystems = systems;
|
||||||
injectorBuilder.Inject(this);
|
|
||||||
|
|
||||||
var members = GetProcess<IEcsPipelineMember>();
|
var members = GetProcess<IEcsPipelineMember>();
|
||||||
for (int i = 0; i < members.Length; i++)
|
for (int i = 0; i < members.Length; i++)
|
||||||
@ -90,7 +104,8 @@ namespace DCFApixels.DragonECS
|
|||||||
members[i].Pipeline = this;
|
members[i].Pipeline = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
_injector = injectorBuilder.Build(this);
|
_injector = new Injector(this);
|
||||||
|
injectionList.InitInjectTo(_injector, this);
|
||||||
}
|
}
|
||||||
~EcsPipeline()
|
~EcsPipeline()
|
||||||
{
|
{
|
||||||
|
@ -114,7 +114,7 @@ namespace DCFApixels.DragonECS
|
|||||||
}
|
}
|
||||||
public ReadOnlySpan<WorldComponentPoolAbstract> GetAllWorldComponents()
|
public ReadOnlySpan<WorldComponentPoolAbstract> GetAllWorldComponents()
|
||||||
{
|
{
|
||||||
return _worldComponentPools.ToReadOnlySpan();
|
return _worldComponentPools.AsReadOnlySpan();
|
||||||
}
|
}
|
||||||
public abstract class WorldComponentPoolAbstract
|
public abstract class WorldComponentPoolAbstract
|
||||||
{
|
{
|
||||||
|
@ -10,7 +10,7 @@ namespace DCFApixels.DragonECS
|
|||||||
public static EcsPipeline.Builder Inject<T>(this EcsPipeline.Builder self, T data)
|
public static EcsPipeline.Builder Inject<T>(this EcsPipeline.Builder self, T data)
|
||||||
{
|
{
|
||||||
if (data == null) { Throw.ArgumentNull(); }
|
if (data == null) { Throw.ArgumentNull(); }
|
||||||
self.Injector.Inject(data);
|
self.Injections.Inject(data);
|
||||||
if (data is IEcsModule module)
|
if (data is IEcsModule module)
|
||||||
{
|
{
|
||||||
self.AddModule(module);
|
self.AddModule(module);
|
||||||
|
@ -8,11 +8,8 @@ namespace DCFApixels.DragonECS.Core.Internal
|
|||||||
{
|
{
|
||||||
internal class InjectionBranch
|
internal class InjectionBranch
|
||||||
{
|
{
|
||||||
private readonly Injector _source;
|
|
||||||
private readonly Type _type;
|
private readonly Type _type;
|
||||||
private InjectionNodeBase[] _nodes = new InjectionNodeBase[4];
|
private StructList<InjectionNodeBase> _nodes = new StructList<InjectionNodeBase>(4);
|
||||||
private int _nodesCount = 0;
|
|
||||||
|
|
||||||
public Type Type
|
public Type Type
|
||||||
{
|
{
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
@ -21,45 +18,15 @@ namespace DCFApixels.DragonECS.Core.Internal
|
|||||||
public ReadOnlySpan<InjectionNodeBase> Nodes
|
public ReadOnlySpan<InjectionNodeBase> Nodes
|
||||||
{
|
{
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
get { return new ReadOnlySpan<InjectionNodeBase>(_nodes, 0, _nodesCount); }
|
get { return _nodes.AsReadOnlySpan(); }
|
||||||
}
|
}
|
||||||
public InjectionBranch(Injector source, Type type)
|
public InjectionBranch(Type type)
|
||||||
{
|
{
|
||||||
_source = source;
|
|
||||||
_type = type;
|
_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)
|
public void AddNode(InjectionNodeBase node)
|
||||||
{
|
{
|
||||||
if (_nodesCount >= _nodes.Length)
|
_nodes.Add(node);
|
||||||
{
|
|
||||||
Array.Resize(ref _nodes, (_nodes.Length << 1) + 1);
|
|
||||||
}
|
|
||||||
_nodes[_nodesCount++] = node;
|
|
||||||
}
|
|
||||||
public void Trim()
|
|
||||||
{
|
|
||||||
if (_nodesCount <= 0)
|
|
||||||
{
|
|
||||||
_nodes = Array.Empty<InjectionNodeBase>();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
InjectionNodeBase[] newNodes = new InjectionNodeBase[_nodesCount];
|
|
||||||
for (int i = 0; i < newNodes.Length; i++)
|
|
||||||
{
|
|
||||||
newNodes[i] = _nodes[i];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -60,8 +60,6 @@ namespace DCFApixels.DragonECS.Core.Internal
|
|||||||
}
|
}
|
||||||
private void ExtractTo_Internal(object target)
|
private void ExtractTo_Internal(object target)
|
||||||
{
|
{
|
||||||
var type = target.GetType();
|
|
||||||
var intrfs = type.GetInterfaces();
|
|
||||||
if (target is IEcsInject<T> intrf)
|
if (target is IEcsInject<T> intrf)
|
||||||
{
|
{
|
||||||
intrf.Inject(_currentInjectedDependency);
|
intrf.Inject(_currentInjectedDependency);
|
||||||
|
@ -11,14 +11,59 @@ namespace DCFApixels.DragonECS
|
|||||||
{
|
{
|
||||||
public class Injector : IInjector
|
public class Injector : IInjector
|
||||||
{
|
{
|
||||||
private EcsPipeline _pipeline;
|
private readonly EcsPipeline _pipeline;
|
||||||
private Dictionary<Type, InjectionBranch> _branches = new Dictionary<Type, InjectionBranch>(32);
|
private readonly Dictionary<Type, InjectionBranch> _branches = new Dictionary<Type, InjectionBranch>(32);
|
||||||
private Dictionary<Type, InjectionNodeBase> _nodes = new Dictionary<Type, InjectionNodeBase>(32);
|
private readonly Dictionary<Type, InjectionNodeBase> _nodes = new Dictionary<Type, InjectionNodeBase>(32);
|
||||||
private bool _isInit = false;
|
private ReadOnlySpan<InjectionNodeBase> GetNodes(Type type)
|
||||||
|
{
|
||||||
|
if(_branches.TryGetValue(type, out InjectionBranch branch))
|
||||||
|
{
|
||||||
|
return branch.Nodes;
|
||||||
|
}
|
||||||
|
return Array.Empty<InjectionNodeBase>();
|
||||||
|
}
|
||||||
|
|
||||||
#if DEBUG
|
#region InjectionTempHistory
|
||||||
private HashSet<Type> _requiredInjectionTypes = new HashSet<Type>();
|
private StructList<object> _injectionTempHistory = new StructList<object>(32);
|
||||||
#endif
|
private int _injectionTempHistoryReadersCount = 0;
|
||||||
|
private int StartReadHistory_Internal()
|
||||||
|
{
|
||||||
|
_injectionTempHistoryReadersCount++;
|
||||||
|
return _injectionTempHistory.Count;
|
||||||
|
}
|
||||||
|
private ReadOnlySpan<object> 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<object> StopReadAndGetHistorySpan()
|
||||||
|
{
|
||||||
|
return _injector.EndReadHistory_Internal(_startIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public InjectionHistorySpanReader StartReadHistory()
|
||||||
|
{
|
||||||
|
return new InjectionHistorySpanReader(this);
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
public EcsPipeline Pipelie
|
public EcsPipeline Pipelie
|
||||||
{
|
{
|
||||||
@ -26,12 +71,14 @@ namespace DCFApixels.DragonECS
|
|||||||
get { return _pipeline; }
|
get { return _pipeline; }
|
||||||
}
|
}
|
||||||
|
|
||||||
private Injector() { }
|
public Injector(EcsPipeline pipeline)
|
||||||
|
{
|
||||||
|
_pipeline = pipeline;
|
||||||
|
}
|
||||||
|
|
||||||
#region Inject/Extract/AddNode
|
#region Inject/Extract/AddNode
|
||||||
public void Inject<T>(T obj)
|
public void Inject<T>(T obj)
|
||||||
{
|
{
|
||||||
object raw = obj;
|
|
||||||
Type tType = typeof(T);
|
Type tType = typeof(T);
|
||||||
Type objType = obj.GetType();
|
Type objType = obj.GetType();
|
||||||
if (_branches.TryGetValue(objType, out InjectionBranch branch) == false)
|
if (_branches.TryGetValue(objType, out InjectionBranch branch) == false)
|
||||||
@ -40,30 +87,31 @@ namespace DCFApixels.DragonECS
|
|||||||
{
|
{
|
||||||
InitNode(new InjectionNode<T>());
|
InitNode(new InjectionNode<T>());
|
||||||
}
|
}
|
||||||
bool hasNode = _nodes.ContainsKey(objType);
|
bool hasObjTypeNode = _nodes.ContainsKey(objType);
|
||||||
if (hasNode == false && obj is IInjectionUnit unit)
|
if (hasObjTypeNode == false && obj is IInjectionUnit unit)
|
||||||
{
|
{
|
||||||
unit.InitInjectionNode(new InjectionGraph(this));
|
unit.InitInjectionNode(new InjectionGraph(this));
|
||||||
hasNode = _nodes.ContainsKey(objType);
|
hasObjTypeNode = _nodes.ContainsKey(objType);
|
||||||
}
|
}
|
||||||
|
|
||||||
branch = new InjectionBranch(this, objType);
|
branch = new InjectionBranch(objType);
|
||||||
InitBranch(branch);
|
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)
|
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}.");
|
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<T>()
|
public bool AddNode<T>()
|
||||||
{
|
{
|
||||||
if (_nodes.ContainsKey(typeof(T)) == false)
|
if (_nodes.ContainsKey(typeof(T))) { return false; }
|
||||||
{
|
InitNode(new InjectionNode<T>());
|
||||||
InitNode(new InjectionNode<T>());
|
return true;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
@ -126,71 +173,121 @@ namespace DCFApixels.DragonECS
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private bool IsCanInstantiated(Type type)
|
|
||||||
{
|
|
||||||
return !type.IsAbstract && !type.IsInterface;
|
|
||||||
}
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Build
|
#region InjectionList
|
||||||
private void Init(EcsPipeline pipeline)
|
public class InjectionList : IInjector
|
||||||
{
|
{
|
||||||
if (_isInit) { Throw.Exception("Already initialized"); }
|
public static readonly InjectionList _Empty_Internal = new InjectionList();
|
||||||
|
|
||||||
_pipeline = pipeline;
|
private StructList<InjectionBase> _injections = new StructList<InjectionBase>(32);
|
||||||
foreach (var pair in _nodes)
|
private StructList<NodeBase> _nodes = new StructList<NodeBase>(32);
|
||||||
|
private EcsWorld _monoWorld;
|
||||||
|
public void AddNode<T>()
|
||||||
{
|
{
|
||||||
pair.Value.Init(pipeline);
|
_nodes.Add(new Node<T>());
|
||||||
}
|
}
|
||||||
_isInit = true;
|
public void Inject<T>(T obj)
|
||||||
|
|
||||||
#if DEBUG
|
|
||||||
var systems = _pipeline.AllSystems;
|
|
||||||
var injectType = typeof(IEcsInject<>);
|
|
||||||
foreach (var system in systems)
|
|
||||||
{
|
{
|
||||||
var type = system.GetType();
|
FindMonoWorld(obj);
|
||||||
foreach (var requiredInjectionType in type.GetInterfaces().Where(o => o.IsGenericType && o.GetGenericTypeDefinition() == injectType).Select(o => o.GenericTypeArguments[0]))
|
_injections.Add(new Injection<T>(obj));
|
||||||
|
}
|
||||||
|
public void Extract<T>(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
|
public void InitInjectTo(Injector injector, EcsPipeline pipeline)
|
||||||
}
|
|
||||||
private bool TryDeclare<T>()
|
|
||||||
{
|
|
||||||
Type type = typeof(T);
|
|
||||||
if (_nodes.ContainsKey(type))
|
|
||||||
{
|
{
|
||||||
return false;
|
#if DEBUG
|
||||||
}
|
HashSet<Type> requiredInjectionTypes = new HashSet<Type>();
|
||||||
InitNode(new InjectionNode<T>());
|
var systems = pipeline.AllSystems;
|
||||||
#if !REFLECTION_DISABLED
|
var injectType = typeof(IEcsInject<>);
|
||||||
if (IsCanInstantiated(type))
|
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
|
#endif
|
||||||
{
|
|
||||||
InitBranch(new InjectionBranch(this, type));
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public class Builder : IInjector
|
|
||||||
{
|
var initInjectionCallbacks = pipeline.GetProcess<IOnInitInjectionComplete>();
|
||||||
private EcsPipeline.Builder _source;
|
foreach (var system in initInjectionCallbacks)
|
||||||
private Injector _instance;
|
{
|
||||||
private List<InitInjectBase> _initInjections = new List<InitInjectBase>(16);
|
system.OnBeforeInitInjection();
|
||||||
private EcsWorld _monoWorld;
|
}
|
||||||
internal Builder(EcsPipeline.Builder source)
|
|
||||||
{
|
injector.Inject(pipeline);
|
||||||
_source = source;
|
injector.AddNode<object>();
|
||||||
_instance = new Injector();
|
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<T>()
|
public void InjectTo(Injector injector, EcsPipeline pipeline)
|
||||||
{
|
{
|
||||||
_instance.TryDeclare<T>();
|
var monoWorldProcess = pipeline.GetProcess<IMonoWorldInject>(); // TODO Проверить IMonoWorldInject
|
||||||
return _source;
|
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>(T obj)
|
|
||||||
|
private void FindMonoWorld(object obj)
|
||||||
{
|
{
|
||||||
if (obj is EcsWorld objWorld)
|
if (obj is EcsWorld objWorld)
|
||||||
{
|
{
|
||||||
@ -216,55 +313,6 @@ namespace DCFApixels.DragonECS
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_initInjections.Add(new InitInject<T>(obj));
|
|
||||||
return _source;
|
|
||||||
}
|
|
||||||
public EcsPipeline.Builder Extract<T>(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<IMonoWorldInject>(); // TODO Проверить IMonoWorldInject
|
|
||||||
foreach (var monoWorldSystem in monoWorldProcess)
|
|
||||||
{
|
|
||||||
monoWorldSystem.World = _monoWorld;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
var initInjectionCallbacks = pipeline.GetProcess<IOnInitInjectionComplete>();
|
|
||||||
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>(T obj) { Inject(obj); }
|
void IInjector.Inject<T>(T obj) { Inject(obj); }
|
||||||
@ -275,24 +323,38 @@ namespace DCFApixels.DragonECS
|
|||||||
return result;
|
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<T> : NodeBase
|
||||||
|
{
|
||||||
|
public override Type Type { get { return typeof(T); } }
|
||||||
|
public override void AddNodeTo(Injector instance)
|
||||||
|
{
|
||||||
|
instance.AddNode<T>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private abstract class InjectionBase
|
||||||
{
|
{
|
||||||
public abstract Type Type { get; }
|
public abstract Type Type { get; }
|
||||||
public abstract object Raw { get; }
|
public abstract object Raw { get; }
|
||||||
public abstract void InjectTo(Injector instance);
|
public abstract void InjectTo(Injector instance);
|
||||||
}
|
}
|
||||||
private sealed class InitInject<T> : InitInjectBase
|
private sealed class Injection<T> : InjectionBase
|
||||||
{
|
{
|
||||||
private T _injectedData;
|
private T _injectedData;
|
||||||
public override Type Type { get { return typeof(T); } }
|
public override Type Type { get { return typeof(T); } }
|
||||||
public override object Raw { get { return _injectedData; } }
|
public override object Raw { get { return _injectedData; } }
|
||||||
public InitInject(T injectedData)
|
public Injection(T injectedData)
|
||||||
{
|
{
|
||||||
_injectedData = injectedData;
|
_injectedData = injectedData;
|
||||||
}
|
}
|
||||||
public override void InjectTo(Injector instance)
|
public override void InjectTo(Injector instance)
|
||||||
{
|
{
|
||||||
instance.Inject<T>(_injectedData);
|
instance.Inject(_injectedData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,5 +31,9 @@ namespace DCFApixels.DragonECS.Core.Internal
|
|||||||
{
|
{
|
||||||
return self.GetCustomAttribute<T>(inherit) != null;
|
return self.GetCustomAttribute<T>(inherit) != null;
|
||||||
}
|
}
|
||||||
|
public static bool IsCanInstantiated(this Type type)
|
||||||
|
{
|
||||||
|
return !type.IsAbstract && !type.IsInterface;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,8 +12,12 @@ namespace DCFApixels.DragonECS.Core.Internal
|
|||||||
[DebuggerDisplay("Count: {Count}")]
|
[DebuggerDisplay("Count: {Count}")]
|
||||||
internal struct StructList<T>
|
internal struct StructList<T>
|
||||||
{
|
{
|
||||||
|
internal readonly static bool _IsManaged = RuntimeHelpers.IsReferenceOrContainsReferences<T>();
|
||||||
|
|
||||||
internal T[] _items;
|
internal T[] _items;
|
||||||
internal int _count;
|
internal int _count;
|
||||||
|
|
||||||
|
#region Properties
|
||||||
public int Count
|
public int Count
|
||||||
{
|
{
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
@ -30,6 +34,11 @@ namespace DCFApixels.DragonECS.Core.Internal
|
|||||||
Array.Resize(ref _items, value);
|
Array.Resize(ref _items, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
public bool IsNull
|
||||||
|
{
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
get { return _items == null; }
|
||||||
|
}
|
||||||
public T this[int index]
|
public T this[int index]
|
||||||
{
|
{
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
@ -49,13 +58,16 @@ namespace DCFApixels.DragonECS.Core.Internal
|
|||||||
_items[index] = value;
|
_items[index] = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Constructors
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public StructList(int capacity)
|
public StructList(int capacity)
|
||||||
{
|
{
|
||||||
_items = new T[ArrayUtility.NextPow2(capacity)];
|
_items = new T[ArrayUtility.NextPow2(capacity)];
|
||||||
_count = 0;
|
_count = 0;
|
||||||
}
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public void Add(T item)
|
public void Add(T item)
|
||||||
@ -64,6 +76,11 @@ namespace DCFApixels.DragonECS.Core.Internal
|
|||||||
{
|
{
|
||||||
Array.Resize(ref _items, _items.Length << 1);
|
Array.Resize(ref _items, _items.Length << 1);
|
||||||
}
|
}
|
||||||
|
AddFixed(item);
|
||||||
|
}
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public void AddFixed(T item)
|
||||||
|
{
|
||||||
_items[_count++] = item;
|
_items[_count++] = item;
|
||||||
}
|
}
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
@ -72,6 +89,11 @@ namespace DCFApixels.DragonECS.Core.Internal
|
|||||||
return Array.IndexOf(_items, item, 0, _count);
|
return Array.IndexOf(_items, item, 0, _count);
|
||||||
}
|
}
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public bool Contains(T item)
|
||||||
|
{
|
||||||
|
return _count != 0 && IndexOf(item) >= 0;
|
||||||
|
}
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public void SwapAt(int idnex1, int idnex2)
|
public void SwapAt(int idnex1, int idnex2)
|
||||||
{
|
{
|
||||||
T tmp = _items[idnex1];
|
T tmp = _items[idnex1];
|
||||||
@ -93,7 +115,10 @@ namespace DCFApixels.DragonECS.Core.Internal
|
|||||||
if (index < 0 || index >= _count) { Throw.ArgumentOutOfRange(); }
|
if (index < 0 || index >= _count) { Throw.ArgumentOutOfRange(); }
|
||||||
#endif
|
#endif
|
||||||
_items[index] = _items[--_count];
|
_items[index] = _items[--_count];
|
||||||
_items[_count] = default;
|
if (_IsManaged)
|
||||||
|
{
|
||||||
|
_items[_count] = default;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public void RemoveAtWithOrder(int index)
|
public void RemoveAtWithOrder(int index)
|
||||||
@ -128,6 +153,56 @@ namespace DCFApixels.DragonECS.Core.Internal
|
|||||||
}
|
}
|
||||||
return false;
|
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)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public void FastClear()
|
public void FastClear()
|
||||||
{
|
{
|
||||||
@ -136,19 +211,31 @@ namespace DCFApixels.DragonECS.Core.Internal
|
|||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public void Clear()
|
public void Clear()
|
||||||
{
|
{
|
||||||
for (int i = 0; i < _count; i++)
|
if (_IsManaged)
|
||||||
{
|
{
|
||||||
_items[i] = default;
|
Array.Clear(_items, 0, _count);
|
||||||
}
|
}
|
||||||
_count = 0;
|
_count = 0;
|
||||||
}
|
}
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[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<T>.Enumerator GetEnumerator()
|
public ReadOnlySpan<T>.Enumerator GetEnumerator()
|
||||||
{
|
{
|
||||||
return new ReadOnlySpan<T>(_items, 0, _count).GetEnumerator();
|
return new ReadOnlySpan<T>(_items, 0, _count).GetEnumerator();
|
||||||
}
|
}
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public ReadOnlySpan<T> ToReadOnlySpan()
|
public ReadOnlySpan<T> AsReadOnlySpan()
|
||||||
{
|
{
|
||||||
return new ReadOnlySpan<T>(_items, 0, _count);
|
return new ReadOnlySpan<T>(_items, 0, _count);
|
||||||
}
|
}
|
||||||
@ -157,5 +244,13 @@ namespace DCFApixels.DragonECS.Core.Internal
|
|||||||
{
|
{
|
||||||
return _items.Take(_count);
|
return _items.Take(_count);
|
||||||
}
|
}
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public T[] ToArray()
|
||||||
|
{
|
||||||
|
if (_count <= 0) { return Array.Empty<T>(); }
|
||||||
|
T[] result = new T[_count];
|
||||||
|
Array.Copy(_items, result, _count);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -141,8 +141,17 @@ namespace DCFApixels.DragonECS.Core.Internal
|
|||||||
{
|
{
|
||||||
throw new ArgumentException("The groups belong to different worlds.");
|
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)]
|
||||||
|
internal static void EmptyStack()
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("Invalid Operation Empty Stack.");
|
||||||
|
}
|
||||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||||
internal static void ArgumentNull()
|
internal static void ArgumentNull()
|
||||||
{
|
{
|
||||||
|
@ -19,7 +19,7 @@ namespace DCFApixels.DragonECS.Core
|
|||||||
|
|
||||||
private readonly IDependencyGraph<string> _graph;
|
private readonly IDependencyGraph<string> _graph;
|
||||||
private readonly EcsPipeline.Builder _pipelineBuilder;
|
private readonly EcsPipeline.Builder _pipelineBuilder;
|
||||||
private readonly string _preBeginLayer;
|
//private readonly string _preBeginLayer;
|
||||||
|
|
||||||
#region Properties
|
#region Properties
|
||||||
public EcsPipeline.Builder Back
|
public EcsPipeline.Builder Back
|
||||||
@ -209,21 +209,21 @@ namespace DCFApixels.DragonECS.Core
|
|||||||
{
|
{
|
||||||
var enumerator = other.GetEnumerator();
|
var enumerator = other.GetEnumerator();
|
||||||
string prev = null;
|
string prev = null;
|
||||||
if (_preBeginLayer != null)
|
//if (_preBeginLayer != null)
|
||||||
{
|
//{
|
||||||
while (enumerator.MoveNext())
|
// while (enumerator.MoveNext())
|
||||||
{
|
// {
|
||||||
var layer = enumerator.Current;
|
// var layer = enumerator.Current;
|
||||||
if (layer == _preBeginLayer) { break; }
|
// if (layer == _preBeginLayer) { break; }
|
||||||
|
//
|
||||||
Add(layer);
|
// Add(layer);
|
||||||
if (prev != null)
|
// if (prev != null)
|
||||||
{
|
// {
|
||||||
Move(prev).Before(layer);
|
// Move(prev).Before(layer);
|
||||||
}
|
// }
|
||||||
prev = layer;
|
// prev = layer;
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
while (enumerator.MoveNext())
|
while (enumerator.MoveNext())
|
||||||
{
|
{
|
||||||
var layer = enumerator.Current;
|
var layer = enumerator.Current;
|
||||||
|
132
src/entlong.cs
132
src/entlong.cs
@ -136,7 +136,7 @@ namespace DCFApixels.DragonECS
|
|||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Unpacking
|
#region Unpacking Try
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public bool TryGetID(out int id)
|
public bool TryGetID(out int id)
|
||||||
{
|
{
|
||||||
@ -156,6 +156,90 @@ namespace DCFApixels.DragonECS
|
|||||||
return IsAlive;
|
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) && mask.World.IsMatchesMask(mask, _id);
|
||||||
|
}
|
||||||
|
[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) && 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) && aspect.IsMatches(_id);
|
||||||
|
}
|
||||||
|
[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) && aspect.IsMatches(_id);
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Unpacking/Deconstruct
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public void Unpack(out int id)
|
public void Unpack(out int id)
|
||||||
{
|
{
|
||||||
@ -238,46 +322,13 @@ namespace DCFApixels.DragonECS
|
|||||||
gen = _gen;
|
gen = _gen;
|
||||||
id = _id;
|
id = _id;
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public bool TryUnpack(out int id)
|
public void Deconstruct(out int id, out short gen, out short worldID) { Unpack(out id, out gen, out worldID); }
|
||||||
{
|
|
||||||
id = _id;
|
|
||||||
return IsAlive;
|
|
||||||
}
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public bool TryUnpack(out int id, out EcsWorld world)
|
public void Deconstruct(out int id, out EcsWorld world) { Unpack(out id, out 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;
|
|
||||||
}
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Unpacking
|
#region Unpacking Unchecked
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public int GetIDUnchecked()
|
public int GetIDUnchecked()
|
||||||
{
|
{
|
||||||
@ -352,13 +403,6 @@ namespace DCFApixels.DragonECS
|
|||||||
public static explicit operator int(entlong a) { return a.ID; }
|
public static explicit operator int(entlong a) { return a.ID; }
|
||||||
#endregion
|
#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
|
#region Other
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
private EcsWorld GetWorld_Internal()
|
private EcsWorld GetWorld_Internal()
|
||||||
|
Loading…
Reference in New Issue
Block a user