diff --git a/src/ECS/Relations/ILinkRelation.cs b/src/ECS/Relations/ILinkRelation.cs index 1cd3c929..2b3e14c3 100644 --- a/src/ECS/Relations/ILinkRelation.cs +++ b/src/ECS/Relations/ILinkRelation.cs @@ -14,7 +14,7 @@ namespace Friflo.Engine.ECS; /// Add multiple link relations to an entity using . /// /// -/// Return all links of an entity to other entities using . +/// Return all links of an entity to other entities using . /// /// /// Remove a specific link to another entity with . diff --git a/src/ECS/Relations/IRelation.cs b/src/ECS/Relations/IRelation.cs index 75012129..623bf1ae 100644 --- a/src/ECS/Relations/IRelation.cs +++ b/src/ECS/Relations/IRelation.cs @@ -7,32 +7,32 @@ namespace Friflo.Engine.ECS; public interface IRelation { } /// -/// A relation component enables adding multiple components of the same type to an entity.
+/// A relation enables adding multiple components of the same type to an entity.
/// The components added to a single entity build a set of components using the relation as unique identifier. ///
-/// The key defining a unique relation component. +/// The key defining a unique relation. /// -/// A relation component enables: +/// A relation enables: /// /// -/// Add multiple relation components to an entity using . +/// Add multiple relations to an entity using . /// /// -/// Return all relation components of an entity using . +/// Return all relations of an entity using . /// /// -/// Return a specific relation by key using
-/// or . +/// Return a specific relation by key using
+/// or . ///
/// -/// Remove a specific relation component by key using . +/// Remove a specific relation by key using . /// ///
///
public interface IRelation : IRelation { /// - /// Returns the key of a unique relation component. + /// Returns the key of a unique relation. /// TKey GetRelationKey(); } \ No newline at end of file diff --git a/src/ECS/Relations/Internal/EntityRelations.cs b/src/ECS/Relations/Internal/EntityRelations.cs index 8c0330f9..026439e0 100644 --- a/src/ECS/Relations/Internal/EntityRelations.cs +++ b/src/ECS/Relations/Internal/EntityRelations.cs @@ -24,7 +24,7 @@ internal abstract class EntityRelations /// Single stored in the . internal readonly StructHeap heap; - /// map: entity id -> relation component positions in + /// map: entity id -> relation positions in internal readonly Dictionary positionMap = new(); internal readonly EntityStore store; @@ -47,9 +47,9 @@ internal EntityRelations(ComponentType componentType, Archetype archetype, Struc relationBit = (int)types.bitSet.l0; } - internal abstract bool AddComponent (int id, in TComponent component) where TComponent : struct, IRelation; + internal abstract bool AddComponent (int id, in TRelation component) where TRelation : struct, IRelation; internal abstract IRelation GetRelationAt (int id, int index); - internal virtual ref TComponent GetEntityRelation(int id, int target) where TComponent : struct => throw new InvalidOperationException($"type: {GetType().Name}"); + internal virtual ref TRelation GetEntityRelation(int id, int target) where TRelation : struct => throw new InvalidOperationException($"type: {GetType().Name}"); internal virtual void AddIncomingRelations (int target, List result) => throw new InvalidOperationException($"type: {GetType().Name}"); internal virtual void RemoveLinksWithTarget (int targetId) => throw new InvalidOperationException($"type: {GetType().Name}"); @@ -72,7 +72,7 @@ internal static EntityRelations GetEntityRelations(EntityStoreBase store, int st var archetype = new Archetype(config, heap); var obj = Activator.CreateInstance(componentType.RelationType, componentType, archetype, heap); return relationsMap[structIndex] = (EntityRelations)obj; - // return store.relationsMap[structIndex] = new RelationArchetype(archetype, heap); + // return store.relationsMap[structIndex] = new RelationArchetype(archetype, heap); } private static EntityRelations[] CreateRelationsMap() { @@ -87,38 +87,38 @@ internal int GetRelationCount(Entity entity) { return positions.count; } - internal static Relations GetRelations(EntityStore store, int id) - where TComponent : struct, IRelation + internal static Relations GetRelations(EntityStore store, int id) + where TRelation : struct, IRelation { - var relations = store.extension.relationsMap?[StructInfo.Index]; + var relations = store.extension.relationsMap?[StructInfo.Index]; if (relations == null) { return default; } relations.positionMap.TryGetValue(id, out var positions); int count = positions.count; - var components = ((StructHeap)relations.heap).components; + var components = ((StructHeap)relations.heap).components; switch (count) { - case 0: return new Relations(); - case 1: return new Relations(components, positions.start); + case 0: return new Relations(); + case 1: return new Relations(components, positions.start); } var poolPositions = IdArrayPool.GetIds(count, relations.idHeap); - return new Relations(components, poolPositions, positions.start, positions.count); + return new Relations(components, poolPositions, positions.start, positions.count); } - internal static ref TComponent GetRelation(EntityStore store, int id, TKey key) - where TComponent : struct, IRelation + internal static ref TRelation GetRelation(EntityStore store, int id, TKey key) + where TRelation : struct, IRelation { - var relations = (EntityRelations)store.extension.relationsMap?[StructInfo.Index]; + var relations = (EntityRelations)store.extension.relationsMap?[StructInfo.Index]; if (relations == null) { throw KeyNotFoundException(id, key); } - return ref relations.GetRelation(id, key); + return ref relations.GetRelation(id, key); } - internal static bool TryGetRelation(EntityStore store, int id, TKey key, out TComponent value) - where TComponent : struct, IRelation + internal static bool TryGetRelation(EntityStore store, int id, TKey key, out TRelation value) + where TRelation : struct, IRelation { - var relations = (EntityRelations)store.extension.relationsMap?[StructInfo.Index]; + var relations = (EntityRelations)store.extension.relationsMap?[StructInfo.Index]; if (relations == null) { value = default; return false; @@ -126,10 +126,10 @@ internal static bool TryGetRelation(EntityStore store, int id, return relations.TryGetRelation(id, key, out value); } - internal void ForAllEntityRelations(ForEachEntity lambda) - where TComponent : struct, IRelation + internal void ForAllEntityRelations(ForEachEntity lambda) + where TRelation : struct, IRelation { - var components = ((StructHeap)heap).components; + var components = ((StructHeap)heap).components; int count = archetype.Count; var ids = archetype.entityIds; var entityStore = store; @@ -138,13 +138,13 @@ internal void ForAllEntityRelations(ForEachEntity lambda } } - internal (Entities entities, Chunk relations) GetAllEntityRelations() - where TComponent : struct, IRelation + internal (Entities entities, Chunk relations) GetAllEntityRelations() + where TRelation : struct, IRelation { int count = archetype.Count; var entities = new Entities(store, archetype.entityIds, 0, count); - var components = ((StructHeap)heap).components; - var chunk = new Chunk(components, count, 0); + var components = ((StructHeap)heap).components; + var chunk = new Chunk(components, count, 0); return (entities, chunk); } @@ -166,17 +166,17 @@ internal int CountIncomingLinkRelations(int target) #endregion #region mutation - internal static bool AddRelation(EntityStoreBase store, int id, in TComponent component) - where TComponent : struct, IRelation + internal static bool AddRelation(EntityStoreBase store, int id, in TRelation component) + where TRelation : struct, IRelation { - var relations = GetEntityRelations(store, StructInfo.Index); + var relations = GetEntityRelations(store, StructInfo.Index); return relations.AddComponent(id, component); } - internal static bool RemoveRelation(EntityStoreBase store, int id, TKey key) - where TComponent : struct, IRelation + internal static bool RemoveRelation(EntityStoreBase store, int id, TKey key) + where TRelation : struct, IRelation { - var relations = (EntityRelations)GetEntityRelations(store, StructInfo.Index); + var relations = (EntityRelations)GetEntityRelations(store, StructInfo.Index); return relations.RemoveRelation(id, key); } diff --git a/src/ECS/Relations/Internal/EntityRelations.generic.cs b/src/ECS/Relations/Internal/EntityRelations.generic.cs index ae52b71f..fc858d53 100644 --- a/src/ECS/Relations/Internal/EntityRelations.generic.cs +++ b/src/ECS/Relations/Internal/EntityRelations.generic.cs @@ -56,22 +56,22 @@ internal override IRelation GetRelationAt(int id, int index) return components[poolPositions[start + index]]; } - internal ref TComponent GetRelation(int id, TKey key) - where TComponent : struct, IRelation + internal ref T GetRelation(int id, TKey key) + where T : struct, IRelation { var position = FindRelationPosition(id, key, out _, out _); if (position >= 0) { - return ref ((StructHeap)heap).components[position]; + return ref ((StructHeap)heap).components[position]; } throw KeyNotFoundException(id, key); } - internal bool TryGetRelation(int id, TKey key, out TComponent value) - where TComponent : struct, IRelation + internal bool TryGetRelation(int id, TKey key, out T value) + where T : struct, IRelation { var position = FindRelationPosition(id, key, out _, out _); if (position >= 0) { - value = ((StructHeap)heap).components[position]; + value = ((StructHeap)heap).components[position]; return true; } value = default; @@ -82,9 +82,9 @@ internal bool TryGetRelation(int id, TKey key, out TComponent value) #region mutation /// true - component is newly added to the entity.
false - component is updated.
- internal override bool AddComponent(int id, in TComponent component) + internal override bool AddComponent(int id, in T component) { - var relationKey = RelationUtils.GetRelationKey(component); + var relationKey = RelationUtils.GetRelationKey(component); // var relationKey = ((IRelation)component).GetRelationKey(); // boxing version var added = true; var position = FindRelationPosition(id, relationKey, out var positions, out _); @@ -94,7 +94,7 @@ internal override bool AddComponent(int id, in TComponent component) } position = AddEntityRelation(id, positions); AssignComponent: - ((StructHeap)heap).components[position] = component; + ((StructHeap)heap).components[position] = component; return added; } diff --git a/src/ECS/Relations/Internal/RelationUtils.cs b/src/ECS/Relations/Internal/RelationUtils.cs index b8fdd191..49b24a68 100644 --- a/src/ECS/Relations/Internal/RelationUtils.cs +++ b/src/ECS/Relations/Internal/RelationUtils.cs @@ -11,34 +11,34 @@ namespace Friflo.Engine.ECS.Relations; internal static class RelationUtils { [UnconditionalSuppressMessage("ReflectionAnalysis", "IL3050", Justification = "TODO")] // TODO - internal static GetRelationKey CreateGetRelationKey() - where TComponent : struct, IRelation + internal static GetRelationKey CreateGetRelationKey() + where TRelation : struct, IRelation { const BindingFlags flags = BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.InvokeMethod; var method = typeof(RelationUtils).GetMethod(nameof(GetRelationKey), flags); - var genericMethod = method!.MakeGenericMethod(typeof(TComponent), typeof(TKey)); + var genericMethod = method!.MakeGenericMethod(typeof(TRelation), typeof(TKey)); - var genericDelegate = Delegate.CreateDelegate(typeof(GetRelationKey), genericMethod); - return (GetRelationKey)genericDelegate; + var genericDelegate = Delegate.CreateDelegate(typeof(GetRelationKey), genericMethod); + return (GetRelationKey)genericDelegate; } - private static TKey GetRelationKey(in TComponent component) - where TComponent : struct, IRelation + private static TKey GetRelationKey(in TRelation component) + where TRelation : struct, IRelation { return component.GetRelationKey(); } } -internal static class RelationUtils - where TComponent : struct, IRelation +internal static class RelationUtils + where TRelation : struct, IRelation { /// Returns the component value without boxing. - internal static readonly GetRelationKey GetRelationKey; + internal static readonly GetRelationKey GetRelationKey; static RelationUtils() { - GetRelationKey = RelationUtils.CreateGetRelationKey(); + GetRelationKey = RelationUtils.CreateGetRelationKey(); } } -internal delegate TKey GetRelationKey(in TComponent component) - where TComponent : struct, IRelation; +internal delegate TKey GetRelationKey(in TRelation component) + where TRelation : struct, IRelation; diff --git a/src/ECS/Relations/Links/EntityRelationLinks.cs b/src/ECS/Relations/Links/EntityRelationLinks.cs index 56162b40..ee8182d9 100644 --- a/src/ECS/Relations/Links/EntityRelationLinks.cs +++ b/src/ECS/Relations/Links/EntityRelationLinks.cs @@ -24,11 +24,11 @@ public EntityRelationLinks(ComponentType componentType, Archetype archetype, Str } /// Expect: component is present - internal override ref TComponent GetEntityRelation(int id, int targetId) + internal override ref T GetEntityRelation(int id, int targetId) { Entity target = new Entity(store, targetId); int position = FindRelationPosition(id, target, out _, out _); - return ref ((StructHeap)heap).components[position]; + return ref ((StructHeap)heap).components[position]; } internal override void AddIncomingRelations(int target, List result) @@ -47,9 +47,9 @@ internal override void AddIncomingRelations(int target, List result) #region mutation /// true - component is newly added to the entity.
false - component is updated.
- internal override bool AddComponent(int id, in TComponent component) + internal override bool AddComponent(int id, in T component) { - Entity target = RelationUtils.GetRelationKey(component); + Entity target = RelationUtils.GetRelationKey(component); bool added = true; int position = FindRelationPosition(id, target, out var positions, out _); if (position >= 0) { @@ -59,7 +59,7 @@ internal override bool AddComponent(int id, in TComponent component) position = AddEntityRelation(id, positions); LinkRelationUtils.AddComponentValue(id, target.Id, this); AssignComponent: - ((StructHeap)heap).components[position] = component; + ((StructHeap)heap).components[position] = component; return added; } diff --git a/src/ECS/Relations/RelationExtensions.cs b/src/ECS/Relations/RelationExtensions.cs index fd30b3e2..c86942d1 100644 --- a/src/ECS/Relations/RelationExtensions.cs +++ b/src/ECS/Relations/RelationExtensions.cs @@ -18,11 +18,11 @@ public static class RelationExtensions /// /// The relation is not found at the passed entity. /// If the entity is null. - public static ref TComponent GetRelation(this Entity entity, TKey key) - where TComponent : struct, IRelation + public static ref TRelation GetRelation(this Entity entity, TKey key) + where TRelation : struct, IRelation { if (entity.IsNull) throw EntityStoreBase.EntityNullException(entity); - return ref EntityRelations.GetRelation(entity.store, entity.Id, key); + return ref EntityRelations.GetRelation(entity.store, entity.Id, key); } /// @@ -30,49 +30,49 @@ public static ref TComponent GetRelation(this Entity entity, T /// Executes in O(N) N: number of entity relations. /// /// If the entity is null. - public static bool TryGetRelation(this Entity entity, TKey key, out TComponent value) - where TComponent : struct, IRelation + public static bool TryGetRelation(this Entity entity, TKey key, out TRelation value) + where TRelation : struct, IRelation { if (entity.IsNull) throw EntityStoreBase.EntityNullException(entity); return EntityRelations.TryGetRelation(entity.store, entity.Id, key, out value); } /// - /// Returns all unique relation components of the passed .
- /// Executes in O(1). In case is a it returns all linked entities. + /// Returns all unique relations of the passed .
+ /// Executes in O(1). In case is a it returns all linked entities. ///
/// If the entity is null. - public static Relations GetRelations(this Entity entity) - where TComponent : struct, IRelation + public static Relations GetRelations(this Entity entity) + where TRelation : struct, IRelation { if (entity.IsNull) throw EntityStoreBase.EntityNullException(entity); - return EntityRelations.GetRelations(entity.store, entity.Id); + return EntityRelations.GetRelations(entity.store, entity.Id); } /// - /// Add the relation component with the specified type to the entity.
+ /// Add the relation with the specified type to the entity.
/// Executes in O(1) ///
/// If the entity is null. /// true - relation is newly added to the entity.
false - relation is updated.
- public static bool AddRelation(this Entity entity, in TComponent component) - where TComponent : struct, IRelation + public static bool AddRelation(this Entity entity, in TRelation component) + where TRelation : struct, IRelation { if (entity.IsNull) throw EntityStoreBase.EntityNullException(entity); return EntityRelations.AddRelation(entity.store, entity.Id, component); } /// - /// Removes the relation component with the specified from an entity.
+ /// Removes the relation with the specified from an entity.
/// Executes in O(N) N: number of relations of the specific entity. ///
/// If the entity is null. /// true if the entity contained a relation of the given type before. - public static bool RemoveRelation(this Entity entity, TKey key) - where TComponent : struct, IRelation + public static bool RemoveRelation(this Entity entity, TKey key) + where TRelation : struct, IRelation { if (entity.IsNull) throw EntityStoreBase.EntityNullException(entity); - return EntityRelations.RemoveRelation(entity.store, entity.Id, key); + return EntityRelations.RemoveRelation(entity.store, entity.Id, key); } /// @@ -81,11 +81,11 @@ public static bool RemoveRelation(this Entity entity, TKey key /// /// If the entity is null. /// true if the entity contained a link relation of the given type before. - public static bool RemoveRelation(this Entity entity, Entity target) - where TComponent : struct, ILinkRelation + public static bool RemoveRelation(this Entity entity, Entity target) + where TRelation : struct, ILinkRelation { if (entity.IsNull) throw EntityStoreBase.EntityNullException(entity); - return EntityRelations.RemoveRelation(entity.store, entity.Id, target); + return EntityRelations.RemoveRelation(entity.store, entity.Id, target); } /// @@ -93,18 +93,18 @@ public static bool RemoveRelation(this Entity entity, Entity target) /// Executes in O(1). /// /// If the entity is null. - public static EntityLinks GetIncomingLinks(this Entity target) - where TComponent: struct, ILinkRelation + public static EntityLinks GetIncomingLinks(this Entity target) + where TRelation: struct, ILinkRelation { if (target.IsNull) throw EntityStoreBase.EntityNullException(target); - var entities = EntityRelations.GetIncomingLinkRelations(target.store, target.Id, StructInfo.Index, out var relations); - return new EntityLinks(target, entities, relations); + var entities = EntityRelations.GetIncomingLinkRelations(target.store, target.Id, StructInfo.Index, out var relations); + return new EntityLinks(target, entities, relations); } #endregion #region EntityStore /// - /// Returns a collection of entities having one or more relations of the specified type.
+ /// Returns a collection of entities having one or more relations of the specified type.
/// Executes in O(1). ///
/// @@ -114,42 +114,42 @@ public static EntityLinks GetIncomingLinks(this Entity t ///
/// /// To get all entities including their relations (the cartesian product aka CROSS JOIN) use
- /// + /// ///
/// /// - public static EntityReadOnlyCollection GetAllEntitiesWithRelations(this EntityStore store) - where TComponent : struct, IRelation + public static EntityReadOnlyCollection GetAllEntitiesWithRelations(this EntityStore store) + where TRelation : struct, IRelation { - var relations = EntityRelations.GetEntityRelations(store, StructInfo.Index); + var relations = EntityRelations.GetEntityRelations(store, StructInfo.Index); return new EntityReadOnlyCollection(store, relations.positionMap.Keys); } /// - /// Iterates all entity relations of the specified type.
+ /// Iterates all entity relations of the specified type.
/// Executes in O(N) N: number of all entity relations. ///
- public static void ForAllEntityRelations(this EntityStore store, ForEachEntity lambda) - where TComponent : struct, IRelation + public static void ForAllEntityRelations(this EntityStore store, ForEachEntity lambda) + where TRelation : struct, IRelation { - var relations = EntityRelations.GetEntityRelations(store, StructInfo.Index); + var relations = EntityRelations.GetEntityRelations(store, StructInfo.Index); relations.ForAllEntityRelations(lambda); } /// - /// Return all entity relations of the specified type.
+ /// Return all entity relations of the specified type.
/// Executes in O(1). Most efficient way to iterate all entity relations. ///
- public static (Entities entities, Chunk relations) GetAllEntityRelations(this EntityStore store) - where TComponent : struct, IRelation + public static (Entities entities, Chunk relations) GetAllEntityRelations(this EntityStore store) + where TRelation : struct, IRelation { - var entityRelations = EntityRelations.GetEntityRelations(store, StructInfo.Index); - return entityRelations.GetAllEntityRelations(); + var entityRelations = EntityRelations.GetEntityRelations(store, StructInfo.Index); + return entityRelations.GetAllEntityRelations(); } [ExcludeFromCodeCoverage] - public static IReadOnlyCollection GetAllLinkedEntities(this EntityStore store) - where TComponent: struct, IRelation + public static IReadOnlyCollection GetAllLinkedEntities(this EntityStore store) + where TRelation: struct, IRelation { throw new NotImplementedException(); } diff --git a/src/ECS/Relations/Relations.cs b/src/ECS/Relations/Relations.cs index 9a98b378..6c61d3be 100644 --- a/src/ECS/Relations/Relations.cs +++ b/src/ECS/Relations/Relations.cs @@ -13,23 +13,23 @@ namespace Friflo.Engine.ECS; /// -/// Contains the relation components of a specific entity returned by . +/// Contains the relations of a specific entity returned by . /// -public readonly struct Relations : IEnumerable - where TComponent : struct +public readonly struct Relations : IEnumerable + where TRelation : struct { - public override string ToString() => $"Relations<{typeof(TComponent).Name}>[{Length}]"; + public override string ToString() => $"Relations<{typeof(TRelation).Name}>[{Length}]"; /// - /// Return the number of relation components.
+ /// Return the number of relations.
/// Executes in O(1). ///
public readonly int Length; // 4 internal readonly int start; // 4 internal readonly int[] positions; // 8 - internal readonly TComponent[] components; // 8 + internal readonly TRelation[] components; // 8 internal readonly int position; // 4 - internal Relations(TComponent[] components, int[] positions, int start, int length) + internal Relations(TRelation[] components, int[] positions, int start, int length) { this.components = components; this.positions = positions; @@ -37,7 +37,7 @@ internal Relations(TComponent[] components, int[] positions, int start, int leng Length = length; } - internal Relations(TComponent[] components, int position) { + internal Relations(TRelation[] components, int position) { this.components = components; this.position = position; Length = 1; @@ -50,7 +50,7 @@ internal Relations(TComponent[] components, int position) { [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2090", Justification = "Only for debugging")] private static MethodInfo MakeGetRelationKey(out bool isEntity) { - var methodInfo = typeof(TComponent).GetMethod("GetRelationKey")!; + var methodInfo = typeof(TRelation).GetMethod("GetRelationKey")!; isEntity = methodInfo.ReturnType == typeof(Entity); return methodInfo; } @@ -78,34 +78,34 @@ public string Debug() /// - /// Return the relation component at the given .
+ /// Return the relation at the given .
/// Executes in O(1). ///
- public TComponent this[int index] => components[positions != null ? positions[index] : position]; + public TRelation this[int index] => components[positions != null ? positions[index] : position]; // --- IEnumerable<> - IEnumerator IEnumerable.GetEnumerator() => new RelationsEnumerator(this); + IEnumerator IEnumerable.GetEnumerator() => new RelationsEnumerator(this); // --- IEnumerable - IEnumerator IEnumerable.GetEnumerator() => new RelationsEnumerator(this); + IEnumerator IEnumerable.GetEnumerator() => new RelationsEnumerator(this); // --- new - public RelationsEnumerator GetEnumerator() => new RelationsEnumerator(this); + public RelationsEnumerator GetEnumerator() => new RelationsEnumerator(this); } -public struct RelationsEnumerator : IEnumerator - where TComponent : struct +public struct RelationsEnumerator : IEnumerator + where TRelation : struct { private readonly int[] positions; private readonly int position; - private readonly TComponent[] components; + private readonly TRelation[] components; private readonly int start; private readonly int last; private int index; - internal RelationsEnumerator(in Relations relations) { + internal RelationsEnumerator(in Relations relations) { positions = relations.positions; position = relations.position; components = relations.components; @@ -115,7 +115,7 @@ internal RelationsEnumerator(in Relations relations) { } // --- IEnumerator<> - public readonly TComponent Current => components[positions != null ? positions[index] : position]; + public readonly TRelation Current => components[positions != null ? positions[index] : position]; // --- IEnumerator public bool MoveNext() { diff --git a/src/Tests/ECS/Examples/Component_Types.cs b/src/Tests/ECS/Examples/Component_Types.cs index e473c177..1cd2054c 100644 --- a/src/Tests/ECS/Examples/Component_Types.cs +++ b/src/Tests/ECS/Examples/Component_Types.cs @@ -110,7 +110,7 @@ public static void LinkRelations() #endregion -#region relation component +#region relation [Test] public static void Relation_Snippets()