From a747b5043c1e091c481ad992e0dec0048b794935 Mon Sep 17 00:00:00 2001 From: DCFApixels <99481254+DCFApixels@users.noreply.github.com> Date: Fri, 22 Nov 2024 12:15:29 +0800 Subject: [PATCH] api polishing --- src/EntityGraph.cs | 2 +- src/EntityGraphExtensions.cs | 9 ++ src/Executors/GraphQueries.cs | 24 ++--- src/Executors/JoinToSubGraphExecutor.cs | 113 ++++++++++++++++-------- 4 files changed, 96 insertions(+), 52 deletions(-) diff --git a/src/EntityGraph.cs b/src/EntityGraph.cs index 705ca7e..55a8f7b 100644 --- a/src/EntityGraph.cs +++ b/src/EntityGraph.cs @@ -239,7 +239,7 @@ namespace DCFApixels.DragonECS SubGraphMap subGraph; EcsWorld graphWorld = _graph._graphWorld; - subGraph = graphWorld.JoinGraph(JoinMode.All); + subGraph = graphWorld.Join(JoinMode.All); foreach (var sourceE in delEntities) { var relEs = subGraph.GetRelations(sourceE); diff --git a/src/EntityGraphExtensions.cs b/src/EntityGraphExtensions.cs index d764839..c4bad67 100644 --- a/src/EntityGraphExtensions.cs +++ b/src/EntityGraphExtensions.cs @@ -71,6 +71,15 @@ namespace DCFApixels.DragonECS Throw.UndefinedException(); return null; } + public static EcsWorld GetGraphWorld(this EcsWorld self) + { + if (self.TryGetGraph(out EntityGraph graph)) + { + return graph.GraphWorld; + } + Throw.UndefinedException(); + return null; + } public static bool IsGraphWorld(this EcsWorld self) { diff --git a/src/Executors/GraphQueries.cs b/src/Executors/GraphQueries.cs index 1791c96..d6c494b 100644 --- a/src/Executors/GraphQueries.cs +++ b/src/Executors/GraphQueries.cs @@ -6,56 +6,56 @@ namespace DCFApixels.DragonECS public static class GraphQueriesExtensions { #region JoinToGraph Empty - public static SubGraphMap JoinGraph(this EcsWorld entities, JoinMode mode = JoinMode.Start) + public static SubGraphMap Join(this EcsWorld entities, JoinMode mode = JoinMode.Start) { - entities.GetQueryCache(out JoinToSubGraphExecutor executor, out EmptyAspect _); + entities.GetQueryCache(out JoinExecutor executor, out EmptyAspect _); return executor.Execute(mode); } #endregion #region JoinToGraph Mask - public static SubGraphMap JoinSubGraph(this TCollection entities, IComponentMask mask, JoinMode mode = JoinMode.Start) + public static SubGraphMap Join(this TCollection entities, IComponentMask mask, JoinMode mode = JoinMode.Start) where TCollection : IEntityStorage { if (ReferenceEquals(entities, entities.World)) { - var executor = entities.World.GetExecutorForMask(mask); + var executor = entities.World.GetExecutorForMask(mask); return executor.Execute(); } return entities.ToSpan().JoinSubGraph(mask, mode); } - public static SubGraphMap JoinSubGraph(this EcsReadonlyGroup group, IComponentMask mask, JoinMode mode = JoinMode.Start) + public static SubGraphMap Join(this EcsReadonlyGroup group, IComponentMask mask, JoinMode mode = JoinMode.Start) { return group.ToSpan().JoinSubGraph(mask, mode); } public static SubGraphMap JoinSubGraph(this EcsSpan span, IComponentMask mask, JoinMode mode = JoinMode.Start) { - var executor = span.World.GetExecutorForMask(mask); + var executor = span.World.GetExecutorForMask(mask); return executor.ExecuteFor(span, mode); } #endregion #region JoinToGraph - public static SubGraphMap JoinSubGraph(this TCollection entities, out TAspect aspect, JoinMode mode = JoinMode.Start) + public static SubGraphMap Join(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 JoinToSubGraphExecutor executor, out aspect); + entities.World.GetQueryCache(out JoinExecutor executor, out aspect); return executor.Execute(); } - return entities.ToSpan().JoinSubGraph(out aspect, mode); + return entities.ToSpan().Join(out aspect, mode); } public static SubGraphMap JoinSubGraph(this EcsReadonlyGroup group, out TAspect aspect, JoinMode mode = JoinMode.Start) where TAspect : EcsAspect, new() { - return group.ToSpan().JoinSubGraph(out aspect, mode); + return group.ToSpan().Join(out aspect, mode); } - public static SubGraphMap JoinSubGraph(this EcsSpan span, out TAspect aspect, JoinMode mode = JoinMode.Start) + public static SubGraphMap Join(this EcsSpan span, out TAspect aspect, JoinMode mode = JoinMode.Start) where TAspect : EcsAspect, new() { - span.World.GetQueryCache(out JoinToSubGraphExecutor executor, out aspect); + span.World.GetQueryCache(out JoinExecutor executor, out aspect); return executor.ExecuteFor(span, mode); } #endregion diff --git a/src/Executors/JoinToSubGraphExecutor.cs b/src/Executors/JoinToSubGraphExecutor.cs index d193260..7ad71b1 100644 --- a/src/Executors/JoinToSubGraphExecutor.cs +++ b/src/Executors/JoinToSubGraphExecutor.cs @@ -3,12 +3,13 @@ using DCFApixels.DragonECS.Graphs.Internal; using DCFApixels.DragonECS.UncheckedCore; using System; using System.Collections.Generic; +using System.Diagnostics; using System.Runtime.CompilerServices; using LinkedList = DCFApixels.DragonECS.Graphs.Internal.OnlyAppendHeadLinkedList; namespace DCFApixels.DragonECS.Graphs.Internal { - internal sealed class JoinToSubGraphExecutor : MaskQueryExecutor, IEcsWorldEventListener + internal sealed class JoinExecutor : MaskQueryExecutor, IEcsWorldEventListener { private EntityGraph _graph; private EcsMaskIterator _iterator; @@ -62,6 +63,11 @@ namespace DCFApixels.DragonECS.Graphs.Internal #region OnInitialize/OnDestroy protected override void OnInitialize() { + if (World.IsGraphWorld() == false) + { + Throw.Exception("The JounSubGraph query can only be used for EntityGraph.GraphWorld or a collection of that world."); + } + _versionsChecker = new WorldStateVersionsChecker(Mask); _linkedList = new OnlyAppendHeadLinkedList(World.Capacity); _linkedListSourceHeads = new LinkedListHead[World.Capacity]; @@ -246,10 +252,10 @@ namespace DCFApixels.DragonECS.Graphs.Internal #region Internal result methods [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal SubGraphMap.Node GetRelations_Internal(int sourceEntityID) + internal SubGraphMap.NodeInfo GetRelations_Internal(int sourceEntityID) { LinkedListHead basket = _linkedListSourceHeads[sourceEntityID]; - return new SubGraphMap.Node(_linkedList._nodes, basket.head, basket.count); + return new SubGraphMap.NodeInfo(_linkedList._nodes, basket.head, basket.count); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal int GetRelation_Internal(int sourceEntityID) @@ -291,7 +297,7 @@ namespace DCFApixels.DragonECS.Graphs.Internal #endregion #region GetEntites - internal EcsSpan GetSourceEntities() + internal EcsSpan GetNodeEntities() { return UncheckedCoreUtility.CreateSpan(WorldID, _sourceEntities, _sourceEntitiesCount); } @@ -313,47 +319,64 @@ namespace DCFApixels.DragonECS All = Start | End, } - #region SubGraphMap/SubGraphMapNode + #region SubGraphMap public readonly ref struct SubGraphMap { - private readonly JoinToSubGraphExecutor _executer; + private readonly JoinExecutor _executer; public EntityGraph Graph { get { return _executer.Graph; } } - internal SubGraphMap(JoinToSubGraphExecutor executer) + internal SubGraphMap(JoinExecutor executer) { _executer = executer; } - public EcsSpan GetSourceEntities() + + public EcsSpan WhereNodes(out TAspect a) + where TAspect : EcsAspect, new() { - return _executer.GetSourceEntities(); + return _executer.GetNodeEntities().Where(out a); } - public EcsSpan GetAllRelEntities() + public EcsSpan WhereNodes(IComponentMask mask) + { + return _executer.GetNodeEntities().Where(mask); + } + public EcsSpan WhereNodes(out TAspect a, Comparison comparison) + where TAspect : EcsAspect, new() + { + return _executer.GetNodeEntities().Where(out a, comparison); + } + public EcsSpan WhereNodes(IComponentMask mask, Comparison comparison) + { + return _executer.GetNodeEntities().Where(mask, comparison); + } + + public EcsSpan GetNodes() + { + return _executer.GetNodeEntities(); + } + public EcsSpan GetAllRelations() { return _executer.GetRelEntities(); } - public Node GetRelations(int startEntityID) + + public NodeInfo GetRelations(int nodeEntityID) { - return _executer.GetRelations_Internal(startEntityID); - } - public int GetRelation(int startEntityID) - { - return _executer.GetRelation_Internal(startEntityID); - } - public int GetRelationsCount(int startEntityID) - { - return _executer.GetRelationsCount_Internal(startEntityID); + return _executer.GetRelations_Internal(nodeEntityID); } - public readonly ref struct Node + public int GetRelation(int nodeEntityID) { - public static Node Empty - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get { return new Node(null, 0, 0); } - } + return _executer.GetRelation_Internal(nodeEntityID); + } + public int GetRelationsCount(int nodeEntityID) + { + return _executer.GetRelationsCount_Internal(nodeEntityID); + } + [DebuggerTypeProxy(typeof(DebuggerProxy))] + public readonly ref struct NodeInfo + { private readonly LinkedList.Node[] _nodes; private readonly LinkedList.NodeIndex _startNodeIndex; private readonly int _count; @@ -362,20 +385,8 @@ namespace DCFApixels.DragonECS [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return _count; } } - private IEnumerable E - { - get - { - List result = new List(); - foreach (var item in this) - { - result.Add(item); - } - return result; - } - } [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal Node(LinkedList.Node[] nodes, LinkedList.NodeIndex startNodeIndex, int count) + internal NodeInfo(LinkedList.Node[] nodes, LinkedList.NodeIndex startNodeIndex, int count) { _nodes = nodes; _startNodeIndex = startNodeIndex; @@ -414,6 +425,30 @@ namespace DCFApixels.DragonECS //return _count-- > 0; } } + private class DebuggerProxy + { + private readonly LinkedList.Node[] _nodes; + private readonly LinkedList.NodeIndex _startNodeIndex; + private readonly int _count; + private IEnumerable Entities + { + get + { + List result = new List(); + foreach (var item in new NodeInfo(_nodes, _startNodeIndex, _count)) + { + result.Add(item); + } + return result; + } + } + public DebuggerProxy(NodeInfo node) + { + _nodes = node._nodes; + _startNodeIndex = node._startNodeIndex; + _count = node._count; + } + } } } #endregion