diff --git a/src/ECS/Relations/EntityRelations.cs b/src/ECS/Relations/EntityRelations.cs new file mode 100644 index 00000000..a131c89c --- /dev/null +++ b/src/ECS/Relations/EntityRelations.cs @@ -0,0 +1,37 @@ +using Friflo.Engine.ECS.Relations; + +// ReSharper disable once CheckNamespace +namespace Friflo.Engine.ECS; + +public readonly struct EntityRelations + where TRelation : struct, IRelation +{ + private readonly AbstractEntityRelations relations; + + internal EntityRelations(AbstractEntityRelations relations) { + this.relations = relations; + } + + /// + /// Returns a collection of entities having one or more relations of the specified type.
+ /// Executes in O(1). + ///
+ /// + /// + /// + /// The returned collection changes when relations are updated, removed or added. + /// + /// + /// To get all entities including their relations (the cartesian product aka CROSS JOIN) use
+ /// + ///
+ ///
+ ///
+ public EntityReadOnlyCollection Entities => new EntityReadOnlyCollection(relations.store, relations.positionMap.Keys); + + /// + /// Iterates all entity relations of the specified type.
+ /// Executes in O(N) N: number of all entity relations. + ///
+ public void For(ForEachEntity lambda) => relations.ForAllEntityRelations(lambda); +} diff --git a/src/ECS/Relations/RelationExtensions.cs b/src/ECS/Relations/RelationExtensions.cs index d079c079..8e9e2726 100644 --- a/src/ECS/Relations/RelationExtensions.cs +++ b/src/ECS/Relations/RelationExtensions.cs @@ -3,7 +3,6 @@ using System; using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; using Friflo.Engine.ECS.Relations; // ReSharper disable once CheckNamespace @@ -103,7 +102,15 @@ public static EntityLinks GetIncomingLinks(this Entity tar #endregion #region EntityStore + public static EntityRelations EntityRelations(this EntityStore store) + where TRelation : struct, IRelation + { + var relations = AbstractEntityRelations.GetEntityRelations(store, StructInfo.Index); + return new EntityRelations(relations); + } + /// + /// Obsolete: Use
/// Returns a collection of entities having one or more relations of the specified type.
/// Executes in O(1). ///
@@ -118,6 +125,7 @@ public static EntityLinks GetIncomingLinks(this Entity tar /// /// /// + [Obsolete("replace with property: EntityRelations().Entities")] public static EntityReadOnlyCollection GetAllEntitiesWithRelations(this EntityStore store) where TRelation : struct, IRelation { @@ -126,9 +134,11 @@ public static EntityReadOnlyCollection GetAllEntitiesWithRelations(th } /// + /// Obsolete: Use
/// Iterates all entity relations of the specified type.
/// Executes in O(N) N: number of all entity relations. ///
+ [Obsolete("replace with method: EntityRelations().For()")] public static void ForAllEntityRelations(this EntityStore store, ForEachEntity lambda) where TRelation : struct, IRelation { @@ -146,12 +156,5 @@ public static (Entities entities, Chunk relations) GetAllEntityRelati var entityRelations = AbstractEntityRelations.GetEntityRelations(store, StructInfo.Index); return entityRelations.GetAllEntityRelations(); } - - [ExcludeFromCodeCoverage] - public static IReadOnlyCollection GetAllLinkedEntities(this EntityStore store) - where TRelation: struct, IRelation - { - throw new NotImplementedException(); - } #endregion } \ No newline at end of file diff --git a/src/Tests/ECS/Relations/Test_Relations.cs b/src/Tests/ECS/Relations/Test_Relations.cs index b5a9a462..a8fd2a02 100644 --- a/src/Tests/ECS/Relations/Test_Relations.cs +++ b/src/Tests/ECS/Relations/Test_Relations.cs @@ -227,7 +227,7 @@ public static void Test_Relations_Enumerator() public static void Test_Relations_EntityReadOnlyCollection() { var store = new EntityStore(); - var entities = store.GetAllEntitiesWithRelations(); + var entities = store.EntityRelations().Entities; var entity1 = store.CreateEntity(1); var entity2 = store.CreateEntity(2); diff --git a/src/Tests/ECS/Relations/Test_Relations_Delete.cs b/src/Tests/ECS/Relations/Test_Relations_Delete.cs index 7430f4fd..830c12a6 100644 --- a/src/Tests/ECS/Relations/Test_Relations_Delete.cs +++ b/src/Tests/ECS/Relations/Test_Relations_Delete.cs @@ -12,7 +12,7 @@ public static class Test_Relations_Delete public static void Test_Relations_Delete_int_relations() { var store = new EntityStore(); - var allEntities = store.GetAllEntitiesWithRelations(); + var allEntities = store.EntityRelations().Entities; AreEqual("{ }", allEntities.Debug()); var entity1 = store.CreateEntity(1); @@ -29,7 +29,7 @@ public static void Test_Relations_Delete_int_relations() int count = 0; // --- version: iterate all entity relations in O(N) - store.ForAllEntityRelations((ref IntRelation relation, Entity entity) => { + store.EntityRelations().For((ref IntRelation relation, Entity entity) => { switch (count++) { case 0: AreEqual(1, entity.Id); AreEqual(10, relation.value); break; case 1: AreEqual(1, entity.Id); AreEqual(20, relation.value); break; @@ -54,7 +54,7 @@ public static void Test_Relations_Delete_int_relations() public static void Test_Relations_Delete_Entity_relations() { var store = new EntityStore(); - var sourceNodes = store.GetAllEntitiesWithRelations(); + var sourceNodes = store.EntityRelations().Entities; AreEqual("{ }", sourceNodes.Debug()); var target10 = store.CreateEntity(10); @@ -76,7 +76,7 @@ public static void Test_Relations_Delete_Entity_relations() int count = 0; // --- version: iterate all entity relations in O(N) - store.ForAllEntityRelations((ref AttackRelation relation, Entity entity) => { + store.EntityRelations().For((ref AttackRelation relation, Entity entity) => { switch (count++) { case 0: AreEqual(1, entity.Id); AreEqual(10, relation.target.Id); break; case 1: AreEqual(1, entity.Id); AreEqual(11, relation.target.Id); break; diff --git a/src/Tests/ECS/Relations/Test_Relations_Query.cs b/src/Tests/ECS/Relations/Test_Relations_Query.cs index b6398dc8..e6e3d121 100644 --- a/src/Tests/ECS/Relations/Test_Relations_Query.cs +++ b/src/Tests/ECS/Relations/Test_Relations_Query.cs @@ -197,7 +197,7 @@ public static void Test_Relations_ForAllEntityRelations_Perf() int count = 0; var sw = new Stopwatch(); sw.Start(); - store.ForAllEntityRelations((ref IntRelation relation, Entity entity) => { + store.EntityRelations().For((ref IntRelation relation, Entity entity) => { count++; }); AreEqual(entityCount * relationsPerEntity, count);