more garbage optimization
							parent
							
								
									2f46af30fb
								
							
						
					
					
						commit
						93ed5c8dd2
					
				| 
						 | 
				
			
			@ -52,7 +52,7 @@ namespace MoonTools.ECS
 | 
			
		|||
			return ComponentDepot.GetSingletonEntity<TComponent>();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		protected IEnumerable<(Entity, Entity, TRelationKind)> Relations<TRelationKind>() where TRelationKind : unmanaged
 | 
			
		||||
		protected ReverseSpanEnumerator<(Entity, Entity)> Relations<TRelationKind>() where TRelationKind : unmanaged
 | 
			
		||||
		{
 | 
			
		||||
			return RelationDepot.Relations<TRelationKind>();
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -64,7 +64,7 @@ namespace MoonTools.ECS
 | 
			
		|||
 | 
			
		||||
		protected TRelationKind GetRelationData<TRelationKind>(in Entity a, in Entity b) where TRelationKind : unmanaged
 | 
			
		||||
		{
 | 
			
		||||
			return RelationDepot.Get<TRelationKind>(new Relation(a.ID, b.ID));
 | 
			
		||||
			return RelationDepot.Get<TRelationKind>(a, b);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// relations go A->B, so given A, will give all entities in outgoing relations of this kind.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,31 +0,0 @@
 | 
			
		|||
using System;
 | 
			
		||||
 | 
			
		||||
namespace MoonTools.ECS
 | 
			
		||||
{
 | 
			
		||||
	internal struct Relation : IEquatable<Relation>
 | 
			
		||||
	{
 | 
			
		||||
		public Entity A { get; }
 | 
			
		||||
		public Entity B { get; }
 | 
			
		||||
 | 
			
		||||
		internal Relation(Entity entityA, Entity entityB)
 | 
			
		||||
		{
 | 
			
		||||
			A = entityA;
 | 
			
		||||
			B = entityB;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public override bool Equals(object? obj)
 | 
			
		||||
		{
 | 
			
		||||
			return obj is Relation relation && Equals(relation);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public bool Equals(Relation other)
 | 
			
		||||
		{
 | 
			
		||||
			return A.ID == other.A.ID && B.ID == other.B.ID;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public override int GetHashCode()
 | 
			
		||||
		{
 | 
			
		||||
			return HashCode.Combine(A.ID, B.ID);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -36,19 +36,19 @@ namespace MoonTools.ECS
 | 
			
		|||
			return (RelationStorage<TRelationKind>) storages[storageIndex];
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public void Set<TRelationKind>(Relation relation, TRelationKind relationData) where TRelationKind : unmanaged
 | 
			
		||||
		public void Set<TRelationKind>(in Entity entityA, in Entity entityB, TRelationKind relationData) where TRelationKind : unmanaged
 | 
			
		||||
		{
 | 
			
		||||
			Lookup<TRelationKind>().Set(relation, relationData);
 | 
			
		||||
			Lookup<TRelationKind>().Set(entityA, entityB, relationData);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public TRelationKind Get<TRelationKind>(Relation relation) where TRelationKind : unmanaged
 | 
			
		||||
		public TRelationKind Get<TRelationKind>(in Entity entityA, in Entity entityB) where TRelationKind : unmanaged
 | 
			
		||||
		{
 | 
			
		||||
			return Lookup<TRelationKind>().Get(relation);
 | 
			
		||||
			return Lookup<TRelationKind>().Get(entityA, entityB);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public (bool, bool) Remove<TRelationKind>(Relation relation) where TRelationKind : unmanaged
 | 
			
		||||
		public (bool, bool) Remove<TRelationKind>(in Entity entityA, in Entity entityB) where TRelationKind : unmanaged
 | 
			
		||||
		{
 | 
			
		||||
			return Lookup<TRelationKind>().Remove(relation);
 | 
			
		||||
			return Lookup<TRelationKind>().Remove(entityA, entityB);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public void UnrelateAll<TRelationKind>(int entityID) where TRelationKind : unmanaged
 | 
			
		||||
| 
						 | 
				
			
			@ -56,14 +56,14 @@ namespace MoonTools.ECS
 | 
			
		|||
			Lookup<TRelationKind>().UnrelateAll(entityID);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public IEnumerable<(Entity, Entity, TRelationKind)> Relations<TRelationKind>() where TRelationKind : unmanaged
 | 
			
		||||
		public ReverseSpanEnumerator<(Entity, Entity)> Relations<TRelationKind>() where TRelationKind : unmanaged
 | 
			
		||||
		{
 | 
			
		||||
			return Lookup<TRelationKind>().All();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public bool Related<TRelationKind>(int idA, int idB) where TRelationKind : unmanaged
 | 
			
		||||
		{
 | 
			
		||||
			return Lookup<TRelationKind>().Has(new Relation(idA, idB));
 | 
			
		||||
			return Lookup<TRelationKind>().Has((idA, idB));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public ReverseSpanEnumerator<Entity> OutRelations<TRelationKind>(int entityID) where TRelationKind : unmanaged
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -19,32 +19,30 @@ namespace MoonTools.ECS
 | 
			
		|||
	internal class RelationStorage<TRelation> : RelationStorage where TRelation : unmanaged
 | 
			
		||||
	{
 | 
			
		||||
		private int count = 0;
 | 
			
		||||
		private Dictionary<Relation, int> indices = new Dictionary<Relation, int>(16);
 | 
			
		||||
		private Relation[] relations = new Relation[16];
 | 
			
		||||
		private Dictionary<(Entity, Entity), int> indices = new Dictionary<(Entity, Entity), int>(16);
 | 
			
		||||
		private (Entity, Entity)[] relations = new (Entity, Entity)[16];
 | 
			
		||||
		private TRelation[] relationDatas = new TRelation[16];
 | 
			
		||||
		private Dictionary<int, IndexableSet<Entity>> outRelations = new Dictionary<int, IndexableSet<Entity>>(16);
 | 
			
		||||
		private Dictionary<int, IndexableSet<Entity>> inRelations = new Dictionary<int, IndexableSet<Entity>>(16);
 | 
			
		||||
		private Stack<IndexableSet<Entity>> listPool = new Stack<IndexableSet<Entity>>();
 | 
			
		||||
 | 
			
		||||
		public IEnumerable<(Entity, Entity, TRelation)> All()
 | 
			
		||||
		public ReverseSpanEnumerator<(Entity, Entity)> All()
 | 
			
		||||
		{
 | 
			
		||||
			for (var i = 0; i < count; i += 1)
 | 
			
		||||
			{
 | 
			
		||||
				var relation = relations[i];
 | 
			
		||||
				yield return (relation.A, relation.B, relationDatas[i]);
 | 
			
		||||
			}
 | 
			
		||||
			return new ReverseSpanEnumerator<(Entity, Entity)>(new Span<(Entity, Entity)>(relations, 0, count));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public void Set(Relation relation, TRelation relationData)
 | 
			
		||||
		public void Set(in Entity entityA, in Entity entityB, TRelation relationData)
 | 
			
		||||
		{
 | 
			
		||||
			var relation = (entityA, entityB);
 | 
			
		||||
 | 
			
		||||
			if (indices.TryGetValue(relation, out var index))
 | 
			
		||||
			{
 | 
			
		||||
				relationDatas[index] = relationData;
 | 
			
		||||
				return;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			var idA = relation.A.ID;
 | 
			
		||||
			var idB = relation.B.ID;
 | 
			
		||||
			var idA = entityA.ID;
 | 
			
		||||
			var idB = entityB.ID;
 | 
			
		||||
 | 
			
		||||
			if (!outRelations.ContainsKey(idA))
 | 
			
		||||
			{
 | 
			
		||||
| 
						 | 
				
			
			@ -70,12 +68,12 @@ namespace MoonTools.ECS
 | 
			
		|||
			count += 1;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public TRelation Get(Relation relation)
 | 
			
		||||
		public TRelation Get(in Entity entityA, in Entity entityB)
 | 
			
		||||
		{
 | 
			
		||||
			return relationDatas[indices[relation]];
 | 
			
		||||
			return relationDatas[indices[(entityA, entityB)]];
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public bool Has(Relation relation)
 | 
			
		||||
		public bool Has((Entity, Entity) relation)
 | 
			
		||||
		{
 | 
			
		||||
			return indices.ContainsKey(relation);
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -147,24 +145,25 @@ namespace MoonTools.ECS
 | 
			
		|||
			return inRelations.TryGetValue(entityID, out var entityInRelations) ? entityInRelations.Count : 0;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public (bool, bool) Remove(Relation relation)
 | 
			
		||||
		public (bool, bool) Remove(in Entity entityA, in Entity entityB)
 | 
			
		||||
		{
 | 
			
		||||
			var aEmpty = false;
 | 
			
		||||
			var bEmpty = false;
 | 
			
		||||
			var relation = (entityA, entityB);
 | 
			
		||||
 | 
			
		||||
			if (outRelations.TryGetValue(relation.A.ID, out var entityOutRelations))
 | 
			
		||||
			if (outRelations.TryGetValue(entityA.ID, out var entityOutRelations))
 | 
			
		||||
			{
 | 
			
		||||
				entityOutRelations.Remove(relation.B.ID);
 | 
			
		||||
				if (outRelations[relation.A.ID].Count == 0)
 | 
			
		||||
				entityOutRelations.Remove(entityB.ID);
 | 
			
		||||
				if (outRelations[entityA.ID].Count == 0)
 | 
			
		||||
				{
 | 
			
		||||
					aEmpty = true;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if (inRelations.TryGetValue(relation.B.ID, out var entityInRelations))
 | 
			
		||||
			if (inRelations.TryGetValue(entityB.ID, out var entityInRelations))
 | 
			
		||||
			{
 | 
			
		||||
				entityInRelations.Remove(relation.A.ID);
 | 
			
		||||
				if (inRelations[relation.B.ID].Count == 0)
 | 
			
		||||
				entityInRelations.Remove(entityA.ID);
 | 
			
		||||
				if (inRelations[entityB.ID].Count == 0)
 | 
			
		||||
				{
 | 
			
		||||
					bEmpty = true;
 | 
			
		||||
				}
 | 
			
		||||
| 
						 | 
				
			
			@ -210,12 +209,12 @@ namespace MoonTools.ECS
 | 
			
		|||
 | 
			
		||||
		public override unsafe void Set(int entityA, int entityB, void* relationData)
 | 
			
		||||
		{
 | 
			
		||||
			Set(new Relation(entityA, entityB), *((TRelation*) relationData));
 | 
			
		||||
			Set(entityA, entityB, *((TRelation*) relationData));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public override int GetStorageIndex(int entityA, int entityB)
 | 
			
		||||
		{
 | 
			
		||||
			return indices[new Relation(entityA, entityB)];
 | 
			
		||||
			return indices[(entityA, entityB)];
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public override unsafe void* Get(int relationStorageIndex)
 | 
			
		||||
| 
						 | 
				
			
			@ -232,7 +231,7 @@ namespace MoonTools.ECS
 | 
			
		|||
			{
 | 
			
		||||
				foreach (var entityB in entityOutRelations)
 | 
			
		||||
				{
 | 
			
		||||
					Remove(new Relation(entityID, entityB));
 | 
			
		||||
					Remove(entityID, entityB);
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				ReturnHashSetToPool(entityOutRelations);
 | 
			
		||||
| 
						 | 
				
			
			@ -243,7 +242,7 @@ namespace MoonTools.ECS
 | 
			
		|||
			{
 | 
			
		||||
				foreach (var entityA in entityInRelations)
 | 
			
		||||
				{
 | 
			
		||||
					Remove(new Relation(entityA, entityID));
 | 
			
		||||
					Remove(entityA, entityID);
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				ReturnHashSetToPool(entityInRelations);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -70,7 +70,7 @@ namespace MoonTools.ECS
 | 
			
		|||
 | 
			
		||||
		protected void Relate<TRelationKind>(in Entity entityA, in Entity entityB, TRelationKind relationData) where TRelationKind : unmanaged
 | 
			
		||||
		{
 | 
			
		||||
			RelationDepot.Set<TRelationKind>(new Relation(entityA, entityB), relationData);
 | 
			
		||||
			RelationDepot.Set(entityA, entityB, relationData);
 | 
			
		||||
			var relationTypeIndex = RelationTypeIndices.GetIndex<TRelationKind>();
 | 
			
		||||
			EntityStorage.AddRelationKind(entityA.ID, relationTypeIndex);
 | 
			
		||||
			EntityStorage.AddRelationKind(entityB.ID, relationTypeIndex);
 | 
			
		||||
| 
						 | 
				
			
			@ -78,7 +78,7 @@ namespace MoonTools.ECS
 | 
			
		|||
 | 
			
		||||
		protected void Unrelate<TRelationKind>(in Entity entityA, in Entity entityB) where TRelationKind : unmanaged
 | 
			
		||||
		{
 | 
			
		||||
			var (aEmpty, bEmpty) = RelationDepot.Remove<TRelationKind>(new Relation(entityA, entityB));
 | 
			
		||||
			var (aEmpty, bEmpty) = RelationDepot.Remove<TRelationKind>(entityA, entityB);
 | 
			
		||||
 | 
			
		||||
			if (aEmpty)
 | 
			
		||||
			{
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,4 +1,4 @@
 | 
			
		|||
using System.Collections.Generic;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
 | 
			
		||||
namespace MoonTools.ECS
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -19,7 +19,7 @@ namespace MoonTools.ECS
 | 
			
		|||
			return TemplateToComponentTypeIndices[templateID].Add(componentTypeIndex);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public IEnumerable<int> ComponentTypeIndices(int templateID)
 | 
			
		||||
		public HashSet<int> ComponentTypeIndices(int templateID)
 | 
			
		||||
		{
 | 
			
		||||
			return TemplateToComponentTypeIndices[templateID];
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue