Skip to content

Commit

Permalink
- Add EntityRelations<>
Browse files Browse the repository at this point in the history
- replaced RelationExtensions.GetAllEntitiesWithRelations() -> EntityRelations<TRelation>().Entities
- replaced RelationExtensions.ForAllEntityRelations()       -> EntityRelations<TRelation>().For()
  • Loading branch information
friflo committed Dec 1, 2024
1 parent 803f0f9 commit e54388b
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 14 deletions.
37 changes: 37 additions & 0 deletions src/ECS/Relations/EntityRelations.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
using Friflo.Engine.ECS.Relations;

// ReSharper disable once CheckNamespace
namespace Friflo.Engine.ECS;

public readonly struct EntityRelations <TRelation>
where TRelation : struct, IRelation
{
private readonly AbstractEntityRelations relations;

internal EntityRelations(AbstractEntityRelations relations) {
this.relations = relations;
}

/// <summary>
/// Returns a collection of entities having one or more relations of the specified <typeparamref name="TRelation"/> type.<br/>
/// Executes in O(1).
/// </summary>
/// <remarks>
/// <list type="bullet">
/// <item>
/// The returned collection changes when relations are updated, removed or added.
/// </item>
/// <item>
/// To get all entities including their relations (the cartesian product aka CROSS JOIN) use<br/>
/// <see cref="RelationExtensions.GetAllEntityRelations{TRelation}"/>
/// </item>
/// </list>
/// </remarks>
public EntityReadOnlyCollection Entities => new EntityReadOnlyCollection(relations.store, relations.positionMap.Keys);

/// <summary>
/// Iterates all entity relations of the specified <typeparamref name="TRelation"/> type.<br/>
/// Executes in O(N) N: number of all entity relations.
/// </summary>
public void For(ForEachEntity<TRelation> lambda) => relations.ForAllEntityRelations(lambda);
}
19 changes: 11 additions & 8 deletions src/ECS/Relations/RelationExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using Friflo.Engine.ECS.Relations;

// ReSharper disable once CheckNamespace
Expand Down Expand Up @@ -103,7 +102,15 @@ public static EntityLinks<TRelation> GetIncomingLinks<TRelation>(this Entity tar
#endregion

#region EntityStore
public static EntityRelations<TRelation> EntityRelations<TRelation>(this EntityStore store)
where TRelation : struct, IRelation
{
var relations = AbstractEntityRelations.GetEntityRelations(store, StructInfo<TRelation>.Index);
return new EntityRelations<TRelation>(relations);
}

/// <summary>
/// Obsolete: Use <see cref="EntityRelations{TRelation}.Entities"/><br/>
/// Returns a collection of entities having one or more relations of the specified <typeparamref name="TRelation"/> type.<br/>
/// Executes in O(1).
/// </summary>
Expand All @@ -118,6 +125,7 @@ public static EntityLinks<TRelation> GetIncomingLinks<TRelation>(this Entity tar
/// </item>
/// </list>
/// </remarks>
[Obsolete("replace with property: EntityRelations<TRelation>().Entities")]
public static EntityReadOnlyCollection GetAllEntitiesWithRelations<TRelation>(this EntityStore store)
where TRelation : struct, IRelation
{
Expand All @@ -126,9 +134,11 @@ public static EntityReadOnlyCollection GetAllEntitiesWithRelations<TRelation>(th
}

/// <summary>
/// Obsolete: Use <see cref="EntityRelations{TRelation}.For"/><br/>
/// Iterates all entity relations of the specified <typeparamref name="TRelation"/> type.<br/>
/// Executes in O(N) N: number of all entity relations.
/// </summary>
[Obsolete("replace with method: EntityRelations<TRelation>().For()")]
public static void ForAllEntityRelations<TRelation>(this EntityStore store, ForEachEntity<TRelation> lambda)
where TRelation : struct, IRelation
{
Expand All @@ -146,12 +156,5 @@ public static (Entities entities, Chunk<TRelation> relations) GetAllEntityRelati
var entityRelations = AbstractEntityRelations.GetEntityRelations(store, StructInfo<TRelation>.Index);
return entityRelations.GetAllEntityRelations<TRelation>();
}

[ExcludeFromCodeCoverage]
public static IReadOnlyCollection<Entity> GetAllLinkedEntities<TRelation>(this EntityStore store)
where TRelation: struct, IRelation
{
throw new NotImplementedException();
}
#endregion
}
2 changes: 1 addition & 1 deletion src/Tests/ECS/Relations/Test_Relations.cs
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ public static void Test_Relations_Enumerator()
public static void Test_Relations_EntityReadOnlyCollection()
{
var store = new EntityStore();
var entities = store.GetAllEntitiesWithRelations<IntRelation>();
var entities = store.EntityRelations<IntRelation>().Entities;

var entity1 = store.CreateEntity(1);
var entity2 = store.CreateEntity(2);
Expand Down
8 changes: 4 additions & 4 deletions src/Tests/ECS/Relations/Test_Relations_Delete.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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<IntRelation>();
var allEntities = store.EntityRelations<IntRelation>().Entities;
AreEqual("{ }", allEntities.Debug());

var entity1 = store.CreateEntity(1);
Expand All @@ -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<IntRelation>().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;
Expand All @@ -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<AttackRelation>();
var sourceNodes = store.EntityRelations<AttackRelation>().Entities;
AreEqual("{ }", sourceNodes.Debug());

var target10 = store.CreateEntity(10);
Expand All @@ -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<AttackRelation>().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;
Expand Down
2 changes: 1 addition & 1 deletion src/Tests/ECS/Relations/Test_Relations_Query.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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<IntRelation>().For((ref IntRelation relation, Entity entity) => {
count++;
});
AreEqual(entityCount * relationsPerEntity, count);
Expand Down

0 comments on commit e54388b

Please sign in to comment.