mirror of
https://github.com/DCFApixels/DragonECS-Graphs.git
synced 2025-09-17 19:24:36 +08:00
rework api
This commit is contained in:
parent
a747b5043c
commit
691484b429
@ -1,63 +1,51 @@
|
|||||||
using DCFApixels.DragonECS.Core;
|
using DCFApixels.DragonECS.Graphs.Internal;
|
||||||
using DCFApixels.DragonECS.Graphs.Internal;
|
|
||||||
|
|
||||||
namespace DCFApixels.DragonECS
|
namespace DCFApixels.DragonECS
|
||||||
{
|
{
|
||||||
public static class GraphQueriesExtensions
|
public static class GraphQueriesExtensions
|
||||||
{
|
{
|
||||||
#region JoinToGraph Empty
|
private struct JoinExecutorsManager : IEcsWorldComponent<JoinExecutorsManager>
|
||||||
public static SubGraphMap Join(this EcsWorld entities, JoinMode mode = JoinMode.Start)
|
|
||||||
{
|
{
|
||||||
entities.GetQueryCache(out JoinExecutor executor, out EmptyAspect _);
|
const int N = 32;
|
||||||
return executor.Execute(mode);
|
private JoinExecutor[] _joinExecutorsQueue;
|
||||||
|
private int _increment;
|
||||||
|
void IEcsWorldComponent<JoinExecutorsManager>.Init(ref JoinExecutorsManager component, EcsWorld graphWorld)
|
||||||
|
{
|
||||||
|
if (graphWorld.IsGraphWorld() == false)
|
||||||
|
{
|
||||||
|
Throw.Exception($"The {nameof(Join)} query can only be used for EntityGraph.GraphWorld or a collection of that _graphWorld.");
|
||||||
}
|
}
|
||||||
#endregion
|
component._joinExecutorsQueue = new JoinExecutor[N];
|
||||||
|
for (int i = 0; i < N; i++)
|
||||||
#region JoinToGraph Mask
|
{
|
||||||
public static SubGraphMap Join<TCollection>(this TCollection entities, IComponentMask mask, JoinMode mode = JoinMode.Start)
|
component._joinExecutorsQueue[i] = new JoinExecutor(graphWorld);
|
||||||
|
}
|
||||||
|
_increment = 0;
|
||||||
|
}
|
||||||
|
void IEcsWorldComponent<JoinExecutorsManager>.OnDestroy(ref JoinExecutorsManager component, EcsWorld graphWorld)
|
||||||
|
{
|
||||||
|
_joinExecutorsQueue = null;
|
||||||
|
}
|
||||||
|
public JoinExecutor GetExecutor()
|
||||||
|
{
|
||||||
|
_increment = ++_increment % N;
|
||||||
|
return _joinExecutorsQueue[_increment];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static SubGraphMap Join<TCollection>(this TCollection entities, JoinMode mode = JoinMode.Start)
|
||||||
where TCollection : IEntityStorage
|
where TCollection : IEntityStorage
|
||||||
{
|
{
|
||||||
if (ReferenceEquals(entities, entities.World))
|
var executor = entities.World.Get<JoinExecutorsManager>().GetExecutor();
|
||||||
{
|
return entities.ToSpan().Join(mode);
|
||||||
var executor = entities.World.GetExecutorForMask<JoinExecutor>(mask);
|
|
||||||
return executor.Execute();
|
|
||||||
}
|
}
|
||||||
return entities.ToSpan().JoinSubGraph(mask, mode);
|
public static SubGraphMap Join(this EcsReadonlyGroup group, JoinMode mode = JoinMode.Start)
|
||||||
}
|
|
||||||
public static SubGraphMap Join(this EcsReadonlyGroup group, IComponentMask mask, JoinMode mode = JoinMode.Start)
|
|
||||||
{
|
{
|
||||||
return group.ToSpan().JoinSubGraph(mask, mode);
|
return group.ToSpan().Join(mode);
|
||||||
}
|
}
|
||||||
public static SubGraphMap JoinSubGraph(this EcsSpan span, IComponentMask mask, JoinMode mode = JoinMode.Start)
|
public static SubGraphMap Join(this EcsSpan span, JoinMode mode = JoinMode.Start)
|
||||||
{
|
{
|
||||||
var executor = span.World.GetExecutorForMask<JoinExecutor>(mask);
|
var executor = span.World.Get<JoinExecutorsManager>().GetExecutor();
|
||||||
return executor.ExecuteFor(span, mode);
|
return executor.ExecuteFor(span, mode);
|
||||||
}
|
}
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region JoinToGraph
|
|
||||||
public static SubGraphMap Join<TCollection, TAspect>(this TCollection entities, out TAspect aspect, JoinMode mode = JoinMode.Start)
|
|
||||||
where TAspect : EcsAspect, new()
|
|
||||||
where TCollection : IEntityStorage
|
|
||||||
{
|
|
||||||
if (ReferenceEquals(entities, entities.World))
|
|
||||||
{
|
|
||||||
entities.World.GetQueryCache(out JoinExecutor executor, out aspect);
|
|
||||||
return executor.Execute();
|
|
||||||
}
|
|
||||||
return entities.ToSpan().Join(out aspect, mode);
|
|
||||||
}
|
|
||||||
public static SubGraphMap JoinSubGraph<TAspect>(this EcsReadonlyGroup group, out TAspect aspect, JoinMode mode = JoinMode.Start)
|
|
||||||
where TAspect : EcsAspect, new()
|
|
||||||
{
|
|
||||||
return group.ToSpan().Join(out aspect, mode);
|
|
||||||
}
|
|
||||||
public static SubGraphMap Join<TAspect>(this EcsSpan span, out TAspect aspect, JoinMode mode = JoinMode.Start)
|
|
||||||
where TAspect : EcsAspect, new()
|
|
||||||
{
|
|
||||||
span.World.GetQueryCache(out JoinExecutor executor, out aspect);
|
|
||||||
return executor.ExecuteFor(span, mode);
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
using DCFApixels.DragonECS.Core;
|
using DCFApixels.DragonECS.Graphs.Internal;
|
||||||
using DCFApixels.DragonECS.Graphs.Internal;
|
|
||||||
using DCFApixels.DragonECS.UncheckedCore;
|
using DCFApixels.DragonECS.UncheckedCore;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
@ -9,21 +8,12 @@ using LinkedList = DCFApixels.DragonECS.Graphs.Internal.OnlyAppendHeadLinkedList
|
|||||||
|
|
||||||
namespace DCFApixels.DragonECS.Graphs.Internal
|
namespace DCFApixels.DragonECS.Graphs.Internal
|
||||||
{
|
{
|
||||||
internal sealed class JoinExecutor : MaskQueryExecutor, IEcsWorldEventListener
|
internal sealed class JoinExecutor : IEcsWorldEventListener
|
||||||
{
|
{
|
||||||
|
private EcsWorld _graphWorld;
|
||||||
private EntityGraph _graph;
|
private EntityGraph _graph;
|
||||||
private EcsMaskIterator _iterator;
|
|
||||||
|
|
||||||
private int[] _filteredAllEntities = new int[32];
|
|
||||||
private int _filteredAllEntitiesCount = 0;
|
|
||||||
private int[] _filteredEntities = null;
|
|
||||||
private int _filteredEntitiesCount = 0;
|
|
||||||
|
|
||||||
private int[] _currentFilteredEntities = null;
|
|
||||||
private int _currentFilteredEntitiesCount = 0;
|
|
||||||
|
|
||||||
private long _version;
|
private long _version;
|
||||||
private WorldStateVersionsChecker _versionsChecker;
|
|
||||||
|
|
||||||
private LinkedList _linkedList;
|
private LinkedList _linkedList;
|
||||||
private LinkedListHead[] _linkedListSourceHeads;
|
private LinkedListHead[] _linkedListSourceHeads;
|
||||||
@ -36,9 +26,8 @@ namespace DCFApixels.DragonECS.Graphs.Internal
|
|||||||
|
|
||||||
public bool _isDestroyed = false;
|
public bool _isDestroyed = false;
|
||||||
|
|
||||||
|
|
||||||
#region Properties
|
#region Properties
|
||||||
public sealed override long Version
|
public long Version
|
||||||
{
|
{
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
get { return _version; }
|
get { return _version; }
|
||||||
@ -48,133 +37,39 @@ namespace DCFApixels.DragonECS.Graphs.Internal
|
|||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
get { return _graph; }
|
get { return _graph; }
|
||||||
}
|
}
|
||||||
public sealed override bool IsCached
|
|
||||||
{
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
get { return _versionsChecker.Check(); }
|
|
||||||
}
|
|
||||||
public sealed override int LastCachedCount
|
|
||||||
{
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
get { return _filteredAllEntitiesCount; }
|
|
||||||
}
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region OnInitialize/OnDestroy
|
#region Constructors/OnDestroy
|
||||||
protected override void OnInitialize()
|
public JoinExecutor(EcsWorld world)
|
||||||
{
|
{
|
||||||
if (World.IsGraphWorld() == false)
|
_graphWorld = world;
|
||||||
{
|
_linkedList = new OnlyAppendHeadLinkedList(_graphWorld.Capacity);
|
||||||
Throw.Exception("The JounSubGraph query can only be used for EntityGraph.GraphWorld or a collection of that world.");
|
_linkedListSourceHeads = new LinkedListHead[_graphWorld.Capacity];
|
||||||
|
_sourceEntities = new int[_graphWorld.Capacity * 2];
|
||||||
|
_graphWorld.AddListener(this);
|
||||||
|
_graph = _graphWorld.GetGraph();
|
||||||
}
|
}
|
||||||
|
public void Destroy()
|
||||||
_versionsChecker = new WorldStateVersionsChecker(Mask);
|
|
||||||
_linkedList = new OnlyAppendHeadLinkedList(World.Capacity);
|
|
||||||
_linkedListSourceHeads = new LinkedListHead[World.Capacity];
|
|
||||||
_sourceEntities = new int[World.Capacity * 2];
|
|
||||||
World.AddListener(this);
|
|
||||||
_graph = World.GetGraph();
|
|
||||||
_iterator = Mask.GetIterator();
|
|
||||||
}
|
|
||||||
protected override void OnDestroy()
|
|
||||||
{
|
{
|
||||||
if (_isDestroyed) { return; }
|
if (_isDestroyed) { return; }
|
||||||
_isDestroyed = true;
|
_isDestroyed = true;
|
||||||
World.RemoveListener(this);
|
_graphWorld.RemoveListener(this);
|
||||||
_versionsChecker.Dispose();
|
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Execute
|
#region Execute
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
private SubGraphMap Execute_Internal(JoinMode mode)
|
|
||||||
{
|
|
||||||
//_executeMarker.Begin();
|
|
||||||
|
|
||||||
World.ReleaseDelEntityBufferAllAuto();
|
|
||||||
|
|
||||||
if (Mask.IsEmpty || _versionsChecker.CheckAndNext() == false)
|
|
||||||
{
|
|
||||||
_filteredAllEntitiesCount = _iterator.IterateTo(World.Entities, ref _filteredAllEntities);
|
|
||||||
if (_sourceEntities.Length < _graph.World.Capacity * 2)
|
|
||||||
{
|
|
||||||
_sourceEntities = new int[_graph.World.Capacity * 2];
|
|
||||||
}
|
|
||||||
//Подготовка массивов
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//установка текущего массива
|
|
||||||
_currentFilteredEntities = _filteredAllEntities;
|
|
||||||
_currentFilteredEntitiesCount = _filteredAllEntitiesCount;
|
|
||||||
|
|
||||||
//Подготовка массивов
|
|
||||||
if (_targetWorldCapacity < _graph.World.Capacity)
|
|
||||||
{
|
|
||||||
_targetWorldCapacity = _graph.World.Capacity;
|
|
||||||
_linkedListSourceHeads = new LinkedListHead[_targetWorldCapacity];
|
|
||||||
//_startEntities = new int[_targetWorldCapacity];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//ArrayUtility.Fill(_linkedListSourceHeads, default); //TODO оптимизировать, сделав не полную отчистку а только по элементов с прошлого раза
|
|
||||||
for (int i = 0; i < _sourceEntitiesCount; i++)
|
|
||||||
{
|
|
||||||
_linkedListSourceHeads[_sourceEntities[i]] = default;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_sourceEntitiesCount = 0;
|
|
||||||
_linkedList.Clear();
|
|
||||||
|
|
||||||
//Заполнение массивов
|
|
||||||
if ((mode & JoinMode.Start) != 0)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < _filteredAllEntitiesCount; i++)
|
|
||||||
{
|
|
||||||
AddStart(_filteredAllEntities[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ((mode & JoinMode.End) != 0)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < _filteredAllEntitiesCount; i++)
|
|
||||||
{
|
|
||||||
AddEnd(_filteredAllEntities[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
_version++;
|
|
||||||
|
|
||||||
//_executeMarker.End();
|
|
||||||
return new SubGraphMap(this);
|
|
||||||
}
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
private SubGraphMap ExecuteFor_Internal(EcsSpan span, JoinMode mode)
|
private SubGraphMap ExecuteFor_Internal(EcsSpan span, JoinMode mode)
|
||||||
{
|
{
|
||||||
//_executeMarker.Begin();
|
//_executeMarker.Begin();
|
||||||
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
|
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
|
||||||
if (span.IsNull) { /*_executeMarker.End();*/ Throw.ArgumentNull(nameof(span)); }
|
if (span.IsNull) { /*_executeMarker.End();*/ Throw.ArgumentNull(nameof(span)); }
|
||||||
if (span.WorldID != World.ID) { /*_executeMarker.End();*/ Throw.Quiery_ArgumentDifferentWorldsException(); }
|
if (span.WorldID != _graphWorld.ID) { /*_executeMarker.End();*/ Throw.Quiery_ArgumentDifferentWorldsException(); }
|
||||||
#endif
|
#endif
|
||||||
if (_filteredEntities == null)
|
|
||||||
{
|
|
||||||
_filteredEntities = new int[32];
|
|
||||||
}
|
|
||||||
_filteredEntitiesCount = _iterator.IterateTo(span, ref _filteredEntities);
|
|
||||||
if (_sourceEntities.Length < _filteredEntitiesCount * 2)
|
|
||||||
{
|
|
||||||
_sourceEntities = new int[_filteredEntitiesCount * 2];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//установка текущего массива
|
|
||||||
_currentFilteredEntities = _filteredEntities;
|
|
||||||
_currentFilteredEntitiesCount = _filteredEntitiesCount;
|
|
||||||
|
|
||||||
//Подготовка массивов
|
//Подготовка массивов
|
||||||
if (_targetWorldCapacity < World.Capacity)
|
if (_targetWorldCapacity < _graphWorld.Capacity)
|
||||||
{
|
{
|
||||||
_targetWorldCapacity = World.Capacity;
|
_targetWorldCapacity = _graphWorld.Capacity;
|
||||||
_linkedListSourceHeads = new LinkedListHead[_targetWorldCapacity];
|
_linkedListSourceHeads = new LinkedListHead[_targetWorldCapacity];
|
||||||
//_startEntities = new int[_targetWorldCapacity];
|
//_startEntities = new int[_targetWorldCapacity];
|
||||||
}
|
}
|
||||||
@ -192,28 +87,22 @@ namespace DCFApixels.DragonECS.Graphs.Internal
|
|||||||
//Заполнение массивов
|
//Заполнение массивов
|
||||||
if ((mode & JoinMode.Start) != 0)
|
if ((mode & JoinMode.Start) != 0)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < _filteredEntitiesCount; i++)
|
for (int i = 0, iMax = span.Count; i < iMax; i++)
|
||||||
{
|
{
|
||||||
AddStart(_filteredEntities[i]);
|
AddStart(span[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((mode & JoinMode.End) != 0)
|
if ((mode & JoinMode.End) != 0)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < _filteredEntitiesCount; i++)
|
for (int i = 0, iMax = span.Count; i < iMax; i++)
|
||||||
{
|
{
|
||||||
AddEnd(_filteredEntities[i]);
|
AddEnd(span[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//_executeMarker.End();
|
//_executeMarker.End();
|
||||||
return new SubGraphMap(this);
|
return new SubGraphMap(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public SubGraphMap Execute(JoinMode mode = JoinMode.Start)
|
|
||||||
{
|
|
||||||
return Execute_Internal(mode);
|
|
||||||
}
|
|
||||||
public SubGraphMap ExecuteFor(EcsSpan span, JoinMode mode = JoinMode.Start)
|
public SubGraphMap ExecuteFor(EcsSpan span, JoinMode mode = JoinMode.Start)
|
||||||
{
|
{
|
||||||
return ExecuteFor_Internal(span, mode);
|
return ExecuteFor_Internal(span, mode);
|
||||||
@ -299,11 +188,7 @@ namespace DCFApixels.DragonECS.Graphs.Internal
|
|||||||
#region GetEntites
|
#region GetEntites
|
||||||
internal EcsSpan GetNodeEntities()
|
internal EcsSpan GetNodeEntities()
|
||||||
{
|
{
|
||||||
return UncheckedCoreUtility.CreateSpan(WorldID, _sourceEntities, _sourceEntitiesCount);
|
return UncheckedCoreUtility.CreateSpan(_graphWorld.ID, _sourceEntities, _sourceEntitiesCount);
|
||||||
}
|
|
||||||
internal EcsSpan GetRelEntities()
|
|
||||||
{
|
|
||||||
return UncheckedCoreUtility.CreateSpan(WorldID, _currentFilteredEntities, _currentFilteredEntitiesCount);
|
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
@ -327,39 +212,15 @@ namespace DCFApixels.DragonECS
|
|||||||
{
|
{
|
||||||
get { return _executer.Graph; }
|
get { return _executer.Graph; }
|
||||||
}
|
}
|
||||||
|
public EcsSpan Nodes
|
||||||
|
{
|
||||||
|
get { return _executer.GetNodeEntities(); }
|
||||||
|
}
|
||||||
|
|
||||||
internal SubGraphMap(JoinExecutor executer)
|
internal SubGraphMap(JoinExecutor executer)
|
||||||
{
|
{
|
||||||
_executer = executer;
|
_executer = executer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public EcsSpan WhereNodes<TAspect>(out TAspect a)
|
|
||||||
where TAspect : EcsAspect, new()
|
|
||||||
{
|
|
||||||
return _executer.GetNodeEntities().Where(out a);
|
|
||||||
}
|
|
||||||
public EcsSpan WhereNodes<TAspect>(IComponentMask mask)
|
|
||||||
{
|
|
||||||
return _executer.GetNodeEntities().Where(mask);
|
|
||||||
}
|
|
||||||
public EcsSpan WhereNodes<TAspect>(out TAspect a, Comparison<int> comparison)
|
|
||||||
where TAspect : EcsAspect, new()
|
|
||||||
{
|
|
||||||
return _executer.GetNodeEntities().Where(out a, comparison);
|
|
||||||
}
|
|
||||||
public EcsSpan WhereNodes<TAspect>(IComponentMask mask, Comparison<int> comparison)
|
|
||||||
{
|
|
||||||
return _executer.GetNodeEntities().Where(mask, comparison);
|
|
||||||
}
|
|
||||||
|
|
||||||
public EcsSpan GetNodes()
|
|
||||||
{
|
|
||||||
return _executer.GetNodeEntities();
|
|
||||||
}
|
|
||||||
public EcsSpan GetAllRelations()
|
|
||||||
{
|
|
||||||
return _executer.GetRelEntities();
|
|
||||||
}
|
|
||||||
|
|
||||||
public NodeInfo GetRelations(int nodeEntityID)
|
public NodeInfo GetRelations(int nodeEntityID)
|
||||||
{
|
{
|
||||||
return _executer.GetRelations_Internal(nodeEntityID);
|
return _executer.GetRelations_Internal(nodeEntityID);
|
||||||
|
Loading…
Reference in New Issue
Block a user