From 724d36db0c42dfb7e4ac24cdd8d47bb17be2e592 Mon Sep 17 00:00:00 2001 From: Ullrich Praetz Date: Sun, 1 Dec 2024 10:57:27 +0100 Subject: [PATCH] add LinkComponentIndex<> - made IndexExtensions.GetAllLinkedEntities() obsolete --- src/ECS/Index/ComponentIndex.cs | 22 +--------------- src/ECS/Index/ILinkComponent.cs | 2 +- src/ECS/Index/IndexExtensions.cs | 14 ++++++++++- src/ECS/Index/LinkComponentIndex.cs | 39 +++++++++++++++++++++++++++++ src/Tests/ECS/Index/Test_Index.cs | 6 ++++- 5 files changed, 59 insertions(+), 24 deletions(-) create mode 100644 src/ECS/Index/LinkComponentIndex.cs diff --git a/src/ECS/Index/ComponentIndex.cs b/src/ECS/Index/ComponentIndex.cs index 412c2cbc9..1f2658501 100644 --- a/src/ECS/Index/ComponentIndex.cs +++ b/src/ECS/Index/ComponentIndex.cs @@ -39,25 +39,5 @@ internal ComponentIndex(AbstractComponentIndex index) { /// public IReadOnlyCollection Values => index.IndexedComponentValues; - /// - /// Returns all entities linked by the specified type.
- /// Executes in O(1). Each entity in the returned list is unique. See remarks for additional infos. - ///
- /// - /// - /// - /// The returned collection changes when component link values are updated, removed or added. - /// - /// - /// To get the entities linking a specific entity use .
- ///
- /// - /// The method is a specialized version of
- /// using TIndexedComponent = ILinkComponent and TValue = Entity. - ///
- ///
- ///
- public IReadOnlyCollection LinkedEntities => ((AbstractComponentIndex)(object)index).IndexedComponentValues; - public override string ToString() => $"Count: {Values.Count}"; -} \ No newline at end of file +} diff --git a/src/ECS/Index/ILinkComponent.cs b/src/ECS/Index/ILinkComponent.cs index b377290c0..2f87ecb0d 100644 --- a/src/ECS/Index/ILinkComponent.cs +++ b/src/ECS/Index/ILinkComponent.cs @@ -20,7 +20,7 @@ namespace Friflo.Engine.ECS; /// /// /// Return all entities linked by a specific type.
-/// See +/// See ///
/// /// Filter entities in a query having a to a specific entity.
diff --git a/src/ECS/Index/IndexExtensions.cs b/src/ECS/Index/IndexExtensions.cs index c5b0da969..80ee04ac5 100644 --- a/src/ECS/Index/IndexExtensions.cs +++ b/src/ECS/Index/IndexExtensions.cs @@ -40,6 +40,17 @@ public static ComponentIndex ComponentIndex)StoreIndex.GetIndex(store, StructInfo.Index); return new ComponentIndex(index); } + + /// + /// Returns the index for link components to search entities with a specific entity in O(1).
+ /// Executes in O(1). + ///
+ public static LinkComponentIndex LinkComponentIndex(this EntityStore store) + where TLinkComponent: struct, ILinkComponent + { + var index = (AbstractComponentIndex)StoreIndex.GetIndex(store, StructInfo.Index); + return new LinkComponentIndex(index); + } /// /// Obsolete: Use
@@ -82,7 +93,7 @@ public static IReadOnlyCollection GetAllIndexedComponentValues - /// Obsolete: Use
+ /// Obsolete: Use
/// Returns all entities linked by the specified type.
/// Executes in O(1). Each entity in the returned list is unique. See remarks for additional infos. ///
@@ -100,6 +111,7 @@ public static IReadOnlyCollection GetAllIndexedComponentValues /// /// + [Obsolete("replace with property: LinkComponentIndex().Values")] public static IReadOnlyCollection GetAllLinkedEntities(this EntityStore store) where TComponent: struct, ILinkComponent { diff --git a/src/ECS/Index/LinkComponentIndex.cs b/src/ECS/Index/LinkComponentIndex.cs new file mode 100644 index 000000000..fed82b593 --- /dev/null +++ b/src/ECS/Index/LinkComponentIndex.cs @@ -0,0 +1,39 @@ +using System.Collections.Generic; +using Friflo.Engine.ECS.Index; + +// ReSharper disable once CheckNamespace +namespace Friflo.Engine.ECS; + +public readonly struct LinkComponentIndex + where TLinkComponent: struct, ILinkComponent +{ + private readonly AbstractComponentIndex index; + + internal LinkComponentIndex(AbstractComponentIndex index) { + this.index = index; + } + + /// + /// Return the entities having a link component with the passed component value.
+ /// Executes in O(1) with default index. + ///
+ public Entities this[Entity value] => index.GetHasValueEntities(value); + + /// + /// Returns all indexed link component values of the passed type.
+ /// Executes in O(1). Each value in the returned list is unique. See remarks for additional infos. + ///
+ /// + /// + /// + /// The returned collection changes when indexed component values are updated, removed or added. + /// + /// + /// To get the entities having a specific component value use . + /// + /// + /// + public IReadOnlyCollection Values => index.IndexedComponentValues; + + public override string ToString() => $"Count: {Values.Count}"; +} \ No newline at end of file diff --git a/src/Tests/ECS/Index/Test_Index.cs b/src/Tests/ECS/Index/Test_Index.cs index 62c85affc..9c6138039 100644 --- a/src/Tests/ECS/Index/Test_Index.cs +++ b/src/Tests/ECS/Index/Test_Index.cs @@ -105,6 +105,7 @@ public static void Test_Index_Component_Update() public static void Test_Index_indexed_Entity() { var store = new EntityStore(); + var index = store.LinkComponentIndex(); var entity1 = store.CreateEntity(1); var entity2 = store.CreateEntity(2); var entity3 = store.CreateEntity(3); @@ -113,11 +114,14 @@ public static void Test_Index_indexed_Entity() var target5 = store.CreateEntity(5); var target6 = store.CreateEntity(6); - var values = store.GetAllLinkedEntities(); + var values = index.Values; entity1.AddComponent(new LinkComponent { entity = target4 }); AreEqual(1, values.Count); entity2.AddComponent(new LinkComponent { entity = target5 }); AreEqual(2, values.Count); entity3.AddComponent(new LinkComponent { entity = target5 }); AreEqual(2, values.Count); + + AreEqual(1, index[target4].Count); + AreEqual(2, index[target5].Count); int count = 0; foreach (var entity in values) {