more untyped storage granularity
							parent
							
								
									9bc6822f38
								
							
						
					
					
						commit
						8d1274cba0
					
				|  | @ -1,4 +1,5 @@ | |||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Runtime.CompilerServices; | ||||
| 
 | ||||
| namespace MoonTools.ECS | ||||
|  | @ -57,8 +58,6 @@ namespace MoonTools.ECS | |||
| 			Lookup<TComponent>().Set(entityID, component); | ||||
| 		} | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 		public Entity GetSingletonEntity<TComponent>() where TComponent : unmanaged | ||||
| 		{ | ||||
| 			return Lookup<TComponent>().FirstEntity(); | ||||
|  | @ -92,14 +91,12 @@ namespace MoonTools.ECS | |||
| 
 | ||||
| 		// these methods used to implement snapshots, templates, and debugging | ||||
| 
 | ||||
| 		// FIXME: use unsafe pointers instead of object | ||||
| 		internal object UntypedGet(int entityID, int componentTypeIndex) | ||||
| 		internal unsafe void* UntypedGet(int entityID, int componentTypeIndex) | ||||
| 		{ | ||||
| 			return storages[componentTypeIndex].UntypedGet(entityID); | ||||
| 		} | ||||
| 
 | ||||
| 		// FIXME: use unsafe pointers instead of object | ||||
| 		internal void Set(int entityID, int componentTypeIndex, object component) | ||||
| 		internal unsafe void Set(int entityID, int componentTypeIndex, void* component) | ||||
| 		{ | ||||
| 			storages[componentTypeIndex].Set(entityID, component); | ||||
| 		} | ||||
|  | @ -114,5 +111,19 @@ namespace MoonTools.ECS | |||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		// this method is used to iterate components of an entity, only for use with a debug inspector | ||||
| 
 | ||||
| #if DEBUG | ||||
| 		public object Debug_Get(int entityID, int componentTypeIndex) | ||||
| 		{ | ||||
| 			return storages[componentTypeIndex].Debug_Get(entityID); | ||||
| 		} | ||||
| 
 | ||||
| 		public IEnumerable<int> Debug_GetEntityIDs(int componentTypeIndex) | ||||
| 		{ | ||||
| 			return storages[componentTypeIndex].Debug_GetEntityIDs(); | ||||
| 		} | ||||
| #endif | ||||
| 	} | ||||
| } | ||||
|  |  | |||
|  | @ -1,19 +1,22 @@ | |||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Runtime.InteropServices; | ||||
| 
 | ||||
| namespace MoonTools.ECS | ||||
| { | ||||
| 	internal abstract class ComponentStorage | ||||
| 	{ | ||||
| 		internal abstract void Set(int entityID, object component); | ||||
| 		internal abstract unsafe void Set(int entityID, void* component); | ||||
| 		public abstract bool Remove(int entityID); | ||||
| 		public abstract void Clear(); | ||||
| 
 | ||||
| 		// used for debugging and template instantiation | ||||
| 		internal abstract object UntypedGet(int entityID); | ||||
| 		internal abstract unsafe void* UntypedGet(int entityID); | ||||
| 		// used to create correctly typed storage on snapshot | ||||
| 		public abstract ComponentStorage CreateStorage(); | ||||
| #if DEBUG | ||||
| 		internal abstract object Debug_Get(int entityID); | ||||
| 		internal abstract IEnumerable<int> Debug_GetEntityIDs(); | ||||
| #endif | ||||
| 	} | ||||
| 
 | ||||
| 	internal class ComponentStorage<TComponent> : ComponentStorage where TComponent : unmanaged | ||||
|  | @ -33,9 +36,12 @@ namespace MoonTools.ECS | |||
| 			return ref components[entityIDToStorageIndex[entityID]]; | ||||
| 		} | ||||
| 
 | ||||
| 		internal override object UntypedGet(int entityID) | ||||
| 		internal override unsafe void* UntypedGet(int entityID) | ||||
| 		{ | ||||
| 			return components[entityIDToStorageIndex[entityID]]; | ||||
| 			fixed (void* p = &components[entityIDToStorageIndex[entityID]]) | ||||
| 			{ | ||||
| 				return p; | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		public ref readonly TComponent GetFirst() | ||||
|  | @ -69,9 +75,9 @@ namespace MoonTools.ECS | |||
| 			components[entityIDToStorageIndex[entityID]] = component; | ||||
| 		} | ||||
| 
 | ||||
| 		internal override void Set(int entityID, object component) | ||||
| 		internal override unsafe void Set(int entityID, void* component) | ||||
| 		{ | ||||
| 			Set(entityID, (TComponent) component); | ||||
| 			Set(entityID, *((TComponent*) component)); | ||||
| 		} | ||||
| 
 | ||||
| 		// Returns true if the entity had this component. | ||||
|  | @ -127,5 +133,17 @@ namespace MoonTools.ECS | |||
| 		{ | ||||
| 			return new ComponentStorage<TComponent>(); | ||||
| 		} | ||||
| 
 | ||||
| #if DEBUG | ||||
| 		internal override object Debug_Get(int entityID) | ||||
| 		{ | ||||
| 			return components[entityIDToStorageIndex[entityID]]; | ||||
| 		} | ||||
| 
 | ||||
| 		internal override IEnumerable<int> Debug_GetEntityIDs() | ||||
| 		{ | ||||
| 			return entityIDToStorageIndex.Keys; | ||||
| 		} | ||||
| #endif | ||||
| 	} | ||||
| } | ||||
|  |  | |||
|  | @ -9,27 +9,24 @@ namespace MoonTools.ECS | |||
| { | ||||
| 	public abstract class DebugSystem : System | ||||
| 	{ | ||||
| 		private Dictionary<Type, Filter> singleComponentFilters = new Dictionary<Type, Filter>(); | ||||
| 
 | ||||
| 		protected DebugSystem(World world) : base(world) | ||||
| 		{ | ||||
| 		} | ||||
| 
 | ||||
| 		protected IEnumerable<object> Debug_GetAllComponents(Entity entity) | ||||
| 		protected IEnumerable<dynamic> Debug_GetAllComponents(Entity entity) | ||||
| 		{ | ||||
| 			foreach (var typeIndex in EntityStorage.ComponentTypeIndices(entity.ID)) | ||||
| 			{ | ||||
| 				yield return ComponentDepot.UntypedGet(entity.ID, typeIndex); | ||||
| 				yield return ComponentDepot.Debug_Get(entity.ID, typeIndex); | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		protected IEnumerable<Entity> Debug_GetEntities(Type componentType) | ||||
| 		{ | ||||
| 			if (!singleComponentFilters.ContainsKey(componentType)) | ||||
| 			foreach (var entityID in ComponentDepot.Debug_GetEntityIDs(ComponentTypeIndices.GetIndex(componentType))) | ||||
| 			{ | ||||
| 				singleComponentFilters.Add(componentType, new Filter(FilterStorage, new HashSet<int>(ComponentTypeIndices.GetIndex(componentType)), new HashSet<int>())); | ||||
| 				yield return new Entity(entityID); | ||||
| 			} | ||||
| 			return singleComponentFilters[componentType].Entities; | ||||
| 		} | ||||
| 
 | ||||
| 		protected IEnumerable<Type> Debug_SearchComponentType(string typeString) | ||||
|  |  | |||
|  | @ -103,24 +103,24 @@ namespace MoonTools.ECS | |||
| 
 | ||||
| 		// untyped methods used for destroying and snapshots | ||||
| 
 | ||||
| 		public void Set(int entityA, int entityB, int relationTypeIndex, object relationData) | ||||
| 		public unsafe void Set(int entityA, int entityB, int relationTypeIndex, void* relationData) | ||||
| 		{ | ||||
| 			storages[relationTypeIndex].Set(entityA, entityB, relationData); | ||||
| 		} | ||||
| 
 | ||||
| 		public unsafe void* Get(int relationTypeIndex, int relationStorageIndex) | ||||
| 		{ | ||||
| 			return storages[relationTypeIndex].Get(relationStorageIndex); | ||||
| 		} | ||||
| 
 | ||||
| 		public void UnrelateAll(int entityID, int relationTypeIndex) | ||||
| 		{ | ||||
| 			storages[relationTypeIndex].UnrelateAll(entityID); | ||||
| 		} | ||||
| 
 | ||||
| 		public IEnumerable<(int, object)> InRelations(int entityID, int relationTypeIndex) | ||||
| 		public IEnumerable<(int, int)> OutRelationIndices(int entityID, int relationTypeIndex) | ||||
| 		{ | ||||
| 			return storages[relationTypeIndex].UntypedInRelations(entityID); | ||||
| 		} | ||||
| 
 | ||||
| 		public IEnumerable<(int, object)> OutRelations(int entityID, int relationTypeIndex) | ||||
| 		{ | ||||
| 			return storages[relationTypeIndex].UntypedOutRelations(entityID); | ||||
| 			return storages[relationTypeIndex].OutRelationIndices(entityID); | ||||
| 		} | ||||
| 
 | ||||
| 		public void Clear() | ||||
|  |  | |||
|  | @ -5,11 +5,10 @@ namespace MoonTools.ECS | |||
| { | ||||
| 	internal abstract class RelationStorage | ||||
| 	{ | ||||
| 		public abstract void Set(int entityA, int entityB, object relationData); | ||||
| 		public abstract unsafe void Set(int entityA, int entityB, void* relationData); | ||||
| 		public abstract unsafe void* Get(int relationStorageIndex); | ||||
| 		public abstract void UnrelateAll(int entityID); | ||||
| 		public abstract IEnumerable<(int, object)> UntypedInRelations(int entityID); | ||||
| 		public abstract IEnumerable<(int, object)> UntypedOutRelations(int entityID); | ||||
| 		// used to create correctly typed storage on snapshot | ||||
| 		public abstract IEnumerable<(int, int)> OutRelationIndices(int entityID); | ||||
| 		public abstract RelationStorage CreateStorage(); | ||||
| 		public abstract void Clear(); | ||||
| 	} | ||||
|  | @ -208,9 +207,17 @@ namespace MoonTools.ECS | |||
| 
 | ||||
| 		// untyped methods used for internal implementation | ||||
| 
 | ||||
| 		public override void Set(int entityA, int entityB, object relationData) | ||||
| 		public override unsafe void Set(int entityA, int entityB, void* relationData) | ||||
| 		{ | ||||
| 			Set(new Relation(entityA, entityB), (TRelation) relationData); | ||||
| 			Set(new Relation(entityA, entityB), *((TRelation*) relationData)); | ||||
| 		} | ||||
| 
 | ||||
| 		public override unsafe void* Get(int relationStorageIndex) | ||||
| 		{ | ||||
| 			fixed (void* p = &relations[relationStorageIndex]) | ||||
| 			{ | ||||
| 				return p; | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		public override void UnrelateAll(int entityID) | ||||
|  | @ -238,19 +245,15 @@ namespace MoonTools.ECS | |||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		public override IEnumerable<(int, object)> UntypedInRelations(int entityID) | ||||
| 		public override IEnumerable<(int, int)> OutRelationIndices(int entityID) | ||||
| 		{ | ||||
| 			foreach (var (entity, relationData) in InRelations(entityID)) | ||||
| 			if (outRelations.ContainsKey(entityID)) | ||||
| 			{ | ||||
| 				yield return (entity.ID, relationData); | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		public override IEnumerable<(int, object)> UntypedOutRelations(int entityID) | ||||
| 		{ | ||||
| 			foreach (var (entity, relationData) in OutRelations(entityID)) | ||||
| 			{ | ||||
| 				yield return (entity.ID, relationData); | ||||
| 				foreach (var id in outRelations[entityID]) | ||||
| 				{ | ||||
| 					var relation = new Relation(entityID, id); | ||||
| 					yield return (id, indices[relation]); | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
|  |  | |||
|  | @ -23,7 +23,7 @@ namespace MoonTools.ECS | |||
| 			SnapshotRelationDepot = new RelationDepot(World.RelationTypeIndices); | ||||
| 		} | ||||
| 
 | ||||
| 		public void Take(Filter filter) | ||||
| 		public unsafe void Take(Filter filter) | ||||
| 		{ | ||||
| 			Clear(); | ||||
| 			Filter = filter; | ||||
|  | @ -50,7 +50,7 @@ namespace MoonTools.ECS | |||
| 				{ | ||||
| 					SnapshotEntityStorage.AddRelationKind(snapshotEntityID, relationTypeIndex); | ||||
| 
 | ||||
| 					foreach (var (otherEntityID, relationData) in World.RelationDepot.OutRelations(worldEntity.ID, relationTypeIndex)) | ||||
| 					foreach (var (otherEntityID, relationStorageIndex) in World.RelationDepot.OutRelationIndices(worldEntity.ID, relationTypeIndex)) | ||||
| 					{ | ||||
| #if DEBUG | ||||
| 						if (!World.FilterStorage.CheckSatisfied(otherEntityID, Filter.Signature)) | ||||
|  | @ -60,13 +60,13 @@ namespace MoonTools.ECS | |||
| #endif | ||||
| 						var otherSnapshotID = WorldToSnapshotID[otherEntityID]; | ||||
| 						SnapshotEntityStorage.AddRelationKind(otherSnapshotID, relationTypeIndex); | ||||
| 						SnapshotRelationDepot.Set(snapshotEntityID, otherSnapshotID, relationTypeIndex, relationData); | ||||
| 						SnapshotRelationDepot.Set(snapshotEntityID, otherSnapshotID, relationTypeIndex, World.RelationDepot.Get(relationTypeIndex, relationStorageIndex)); | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		public void Restore() | ||||
| 		public unsafe void Restore() | ||||
| 		{ | ||||
| 			if (Filter == null) | ||||
| 			{ | ||||
|  | @ -99,10 +99,10 @@ namespace MoonTools.ECS | |||
| 				{ | ||||
| 					World.EntityStorage.AddRelationKind(worldID, relationTypeIndex); | ||||
| 
 | ||||
| 					foreach (var (otherEntityID, relationData) in SnapshotRelationDepot.OutRelations(i, relationTypeIndex)) | ||||
| 					foreach (var (otherEntityID, relationStorageIndex) in SnapshotRelationDepot.OutRelationIndices(i, relationTypeIndex)) | ||||
| 					{ | ||||
| 						var otherEntityWorldID = SnapshotToWorldID[otherEntityID]; | ||||
| 						World.RelationDepot.Set(worldID, otherEntityWorldID, relationTypeIndex, relationData); | ||||
| 						World.RelationDepot.Set(worldID, otherEntityWorldID, relationTypeIndex, SnapshotRelationDepot.Get(relationTypeIndex, relationStorageIndex)); | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
|  |  | |||
|  | @ -59,7 +59,7 @@ namespace MoonTools.ECS | |||
| 			ComponentDepot.Register<TComponent>(componentTypeIndex); | ||||
| 		} | ||||
| 
 | ||||
| 		public Entity Instantiate(in Template template) | ||||
| 		public unsafe Entity Instantiate(in Template template) | ||||
| 		{ | ||||
| 			var entity = EntityStorage.Create(); | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue