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