internal storage using int ID instead of entity to avoid hash lookups

pull/5/head
Evan Hemsley 2019-12-23 18:45:49 -08:00
parent 7885c2e0f4
commit 47e1072c8d
14 changed files with 178 additions and 188 deletions

View File

@ -7,7 +7,7 @@ namespace Encompass
{ {
internal class ComponentBitSet internal class ComponentBitSet
{ {
Dictionary<Entity, BitSet512> entities = new Dictionary<Entity, BitSet512>(); Dictionary<int, BitSet512> entities = new Dictionary<int, BitSet512>();
Dictionary<Type, int> TypeToIndex { get; } Dictionary<Type, int> TypeToIndex { get; }
public ComponentBitSet(Dictionary<Type, int> typeToIndex) public ComponentBitSet(Dictionary<Type, int> typeToIndex)
@ -15,46 +15,41 @@ namespace Encompass
TypeToIndex = typeToIndex; TypeToIndex = typeToIndex;
} }
public void FinishRegistering()
{
}
public void Clear() public void Clear()
{ {
entities.Clear(); entities.Clear();
} }
public void AddEntity(Entity entity) public void AddEntity(int entityID)
{ {
entities.Add(entity, BitSet512Builder.Zeroes()); entities.Add(entityID, BitSet512Builder.Zeroes());
} }
public void Set<TComponent>(Entity entity) where TComponent : struct, IComponent public void Set<TComponent>(int entityID) where TComponent : struct, IComponent
{ {
if (!entities.ContainsKey(entity)) { AddEntity(entity); } if (!entities.ContainsKey(entityID)) { AddEntity(entityID); }
entities[entity] = entities[entity].Set(TypeToIndex[typeof(TComponent)]); entities[entityID] = entities[entityID].Set(TypeToIndex[typeof(TComponent)]);
} }
public void RemoveComponent<TComponent>(Entity entity) where TComponent : struct, IComponent public void RemoveComponent<TComponent>(int entityID) where TComponent : struct, IComponent
{ {
if (entities.ContainsKey(entity)) if (entities.ContainsKey(entityID))
{ {
entities[entity] = entities[entity].UnSet(TypeToIndex[typeof(TComponent)]); entities[entityID] = entities[entityID].UnSet(TypeToIndex[typeof(TComponent)]);
} }
} }
public void RemoveEntity(Entity entity) public void RemoveEntity(int entityID)
{ {
if (entities.ContainsKey(entity)) if (entities.ContainsKey(entityID))
{ {
entities.Remove(entity); entities.Remove(entityID);
} }
} }
public BitSet512 EntityBitArray(Entity entity) public BitSet512 EntityBitArray(int entityID)
{ {
return entities.ContainsKey(entity) ? entities[entity] : BitSet512Builder.Zeroes(); return entities.ContainsKey(entityID) ? entities[entityID] : BitSet512Builder.Zeroes();
} }
} }
} }

View File

@ -31,75 +31,70 @@ namespace Encompass
} }
} }
public void FinishRegistering()
{
ComponentBitSet.FinishRegistering();
}
private TypedComponentStore<TComponent> Lookup<TComponent>() where TComponent : struct, IComponent private TypedComponentStore<TComponent> Lookup<TComponent>() where TComponent : struct, IComponent
{ {
//RegisterComponentType<TComponent>(); //RegisterComponentType<TComponent>();
return Stores[typeof(TComponent)] as TypedComponentStore<TComponent>; return Stores[typeof(TComponent)] as TypedComponentStore<TComponent>;
} }
public bool Has<TComponent>(Entity entity) where TComponent : struct, IComponent public bool Has<TComponent>(int entityID) where TComponent : struct, IComponent
{ {
return Lookup<TComponent>().Has(entity); return Lookup<TComponent>().Has(entityID);
} }
public bool Has(Type type, Entity entity) public bool Has(Type type, int entityID)
{ {
return Stores.ContainsKey(type) && Stores[type].Has(entity); return Stores.ContainsKey(type) && Stores[type].Has(entityID);
} }
public BitSet512 EntityBitArray(Entity entity) public BitSet512 EntityBitArray(int entityID)
{ {
return ComponentBitSet.EntityBitArray(entity); return ComponentBitSet.EntityBitArray(entityID);
} }
public TComponent Get<TComponent>(Entity entity) where TComponent : struct, IComponent public TComponent Get<TComponent>(int entityID) where TComponent : struct, IComponent
{ {
return Lookup<TComponent>().Get(entity); return Lookup<TComponent>().Get(entityID);
} }
public void Set<TComponent>(Entity entity, TComponent component) where TComponent : struct, IComponent public void Set<TComponent>(int entityID, TComponent component) where TComponent : struct, IComponent
{ {
Lookup<TComponent>().Set(entity, component); Lookup<TComponent>().Set(entityID, component);
ComponentBitSet.Set<TComponent>(entity); ComponentBitSet.Set<TComponent>(entityID);
} }
public bool Set<TComponent>(Entity entity, TComponent component, int priority) where TComponent : struct, IComponent public bool Set<TComponent>(int entityID, TComponent component, int priority) where TComponent : struct, IComponent
{ {
if (Lookup<TComponent>().Set(entity, component, priority)) if (Lookup<TComponent>().Set(entityID, component, priority))
{ {
ComponentBitSet.Set<TComponent>(entity); ComponentBitSet.Set<TComponent>(entityID);
return true; return true;
} }
return false; return false;
} }
public bool Remove<TComponent>(Entity entity, int priority) where TComponent : struct, IComponent public bool Remove<TComponent>(int entityID, int priority) where TComponent : struct, IComponent
{ {
if (Lookup<TComponent>().Remove(entity, priority)) if (Lookup<TComponent>().Remove(entityID, priority))
{ {
ComponentBitSet.RemoveComponent<TComponent>(entity); ComponentBitSet.RemoveComponent<TComponent>(entityID);
return true; return true;
} }
return false; return false;
} }
public void ForceRemove<TComponent>(Entity entity) where TComponent : struct, IComponent public void ForceRemove<TComponent>(int entityID) where TComponent : struct, IComponent
{ {
Lookup<TComponent>().ForceRemove(entity); Lookup<TComponent>().ForceRemove(entityID);
} }
public void Remove(Entity entity) public void Remove(int entityID)
{ {
foreach (var entry in Stores.Values) foreach (var entry in Stores.Values)
{ {
entry.ForceRemove(entity); entry.ForceRemove(entityID);
} }
ComponentBitSet.RemoveEntity(entity); ComponentBitSet.RemoveEntity(entityID);
} }
public bool Any<TComponent>() where TComponent : struct, IComponent public bool Any<TComponent>() where TComponent : struct, IComponent
@ -107,7 +102,7 @@ namespace Encompass
return Lookup<TComponent>().Count > 0; return Lookup<TComponent>().Count > 0;
} }
public IEnumerable<(Entity, Type, IComponent)> AllInterfaceTyped() public IEnumerable<(int, Type, IComponent)> AllInterfaceTyped()
{ {
foreach (var store in Stores.Values) foreach (var store in Stores.Values)
{ {
@ -118,7 +113,7 @@ namespace Encompass
} }
} }
public IEnumerable<(TComponent, Entity)> All<TComponent>() where TComponent : struct, IComponent public IEnumerable<(TComponent, int)> All<TComponent>() where TComponent : struct, IComponent
{ {
return Lookup<TComponent>().All(); return Lookup<TComponent>().All();
} }

View File

@ -6,63 +6,64 @@ namespace Encompass
internal abstract class TypedComponentStore internal abstract class TypedComponentStore
{ {
public abstract int Count { get; } public abstract int Count { get; }
public abstract IEnumerable<(Entity, Type, IComponent)> AllInterfaceTyped(); public abstract IEnumerable<(int, Type, IComponent)> AllInterfaceTyped();
public abstract bool Has(Entity entity); public abstract bool Has(int entity);
public abstract bool Remove(Entity entity, int priority); public abstract bool Remove(int entity, int priority);
public abstract void ForceRemove(Entity entity); public abstract void ForceRemove(int entity);
public abstract void Clear(); public abstract void Clear();
} }
internal class TypedComponentStore<TComponent> : TypedComponentStore where TComponent : struct, IComponent internal class TypedComponentStore<TComponent> : TypedComponentStore where TComponent : struct, IComponent
{ {
private readonly Dictionary<Entity, TComponent> store = new Dictionary<Entity, TComponent>(128); private readonly Dictionary<int, TComponent> store = new Dictionary<int, TComponent>(128);
private readonly Dictionary<Entity, int> priorities = new Dictionary<Entity, int>(128); private readonly Dictionary<int, int> priorities = new Dictionary<int, int>(128);
public override int Count { get => store.Count; } public override int Count { get => store.Count; }
public TComponent Get(Entity entity) public TComponent Get(int entityID)
{ {
return store[entity]; return store[entityID];
} }
public void Set(Entity entity, TComponent component) public void Set(int entityID, TComponent component)
{ {
store[entity] = component; store[entityID] = component;
} }
public bool Set(Entity entity, TComponent component, int priority) public bool Set(int entityID, TComponent component, int priority)
{ {
if (!priorities.ContainsKey(entity) || priority < priorities[entity]) { if (!priorities.ContainsKey(entityID) || priority < priorities[entityID])
store[entity] = component;
priorities[entity] = priority;
return true;
}
return false;
}
public override bool Remove(Entity entity, int priority)
{
if (!priorities.ContainsKey(entity) || priority < priorities[entity])
{ {
priorities[entity] = priority; store[entityID] = component;
store.Remove(entity); priorities[entityID] = priority;
priorities.Remove(entity);
return true; return true;
} }
return false; return false;
} }
public override void ForceRemove(Entity entity) public override bool Remove(int entityID, int priority)
{ {
store.Remove(entity); if (!priorities.ContainsKey(entityID) || priority < priorities[entityID])
priorities.Remove(entity); {
priorities[entityID] = priority;
store.Remove(entityID);
priorities.Remove(entityID);
return true;
}
return false;
} }
public override bool Has(Entity entity) public override void ForceRemove(int entityID)
{ {
return store.ContainsKey(entity); store.Remove(entityID);
priorities.Remove(entityID);
}
public override bool Has(int entityID)
{
return store.ContainsKey(entityID);
} }
public override void Clear() public override void Clear()
@ -71,7 +72,7 @@ namespace Encompass
priorities.Clear(); priorities.Clear();
} }
public IEnumerable<(TComponent, Entity)> All() public IEnumerable<(TComponent, int)> All()
{ {
foreach (var kvp in store) foreach (var kvp in store)
{ {
@ -79,7 +80,7 @@ namespace Encompass
} }
} }
public override IEnumerable<(Entity, Type, IComponent)> AllInterfaceTyped() public override IEnumerable<(int, Type, IComponent)> AllInterfaceTyped()
{ {
foreach (var kvp in store) foreach (var kvp in store)
{ {

View File

@ -9,7 +9,7 @@ namespace Encompass
private readonly ComponentUpdateManager componentUpdateManager; private readonly ComponentUpdateManager componentUpdateManager;
private readonly ComponentStore componentStore; private readonly ComponentStore componentStore;
private readonly HashSet<Entity> entitiesMarkedForRemoval = new HashSet<Entity>(); private readonly HashSet<int> entitiesMarkedForRemoval = new HashSet<int>();
public ComponentManager(DrawLayerManager drawLayerManager, ComponentUpdateManager componentUpdateManager, Dictionary<Type, int> typeToIndex) public ComponentManager(DrawLayerManager drawLayerManager, ComponentUpdateManager componentUpdateManager, Dictionary<Type, int> typeToIndex)
{ {
@ -23,11 +23,6 @@ namespace Encompass
componentStore.RegisterComponentType<TComponent>(); componentStore.RegisterComponentType<TComponent>();
} }
public void FinishRegistering()
{
componentStore.FinishRegistering();
}
internal void SetComponentStore(ComponentStore componentStore) internal void SetComponentStore(ComponentStore componentStore)
{ {
this.componentStore.SwapWith(componentStore); this.componentStore.SwapWith(componentStore);
@ -35,12 +30,12 @@ namespace Encompass
internal void RegisterDrawableComponent<TComponent>(Entity entity, TComponent component, int layer) where TComponent : struct, IComponent internal void RegisterDrawableComponent<TComponent>(Entity entity, TComponent component, int layer) where TComponent : struct, IComponent
{ {
drawLayerManager.RegisterComponentWithLayer(entity, component, layer); drawLayerManager.RegisterComponentWithLayer(entity.ID, component, layer);
} }
internal void AddComponent<TComponent>(Entity entity, TComponent component) where TComponent : struct, IComponent internal void AddComponent<TComponent>(Entity entity, TComponent component) where TComponent : struct, IComponent
{ {
componentStore.Set(entity, component); componentStore.Set(entity.ID, component);
} }
internal void WriteComponents() internal void WriteComponents()
@ -48,7 +43,7 @@ namespace Encompass
componentStore.SwapWith(componentUpdateManager.UpToDateComponentStore); componentStore.SwapWith(componentUpdateManager.UpToDateComponentStore);
} }
internal IEnumerable<(TComponent, Entity)> GetComponentsIncludingEntity<TComponent>() where TComponent : struct, IComponent internal IEnumerable<(TComponent, int)> GetComponentsIncludingEntity<TComponent>() where TComponent : struct, IComponent
{ {
return componentStore.All<TComponent>(); return componentStore.All<TComponent>();
} }
@ -63,12 +58,12 @@ namespace Encompass
internal TComponent GetComponentByEntityAndType<TComponent>(Entity entity) where TComponent : struct, IComponent internal TComponent GetComponentByEntityAndType<TComponent>(Entity entity) where TComponent : struct, IComponent
{ {
return componentStore.Get<TComponent>(entity); return componentStore.Get<TComponent>(entity.ID);
} }
internal bool EntityHasComponentOfType<TComponent>(Entity entity) where TComponent : struct, IComponent internal bool EntityHasComponentOfType<TComponent>(Entity entity) where TComponent : struct, IComponent
{ {
return componentStore.Has<TComponent>(entity); return componentStore.Has<TComponent>(entity.ID);
} }
internal bool ComponentOfTypeExists<TComponent>() where TComponent : struct, IComponent internal bool ComponentOfTypeExists<TComponent>() where TComponent : struct, IComponent
@ -78,15 +73,15 @@ namespace Encompass
internal void MarkAllComponentsOnEntityForRemoval(Entity entity) internal void MarkAllComponentsOnEntityForRemoval(Entity entity)
{ {
entitiesMarkedForRemoval.Add(entity); entitiesMarkedForRemoval.Add(entity.ID);
} }
internal void RemoveMarkedComponents() internal void RemoveMarkedComponents()
{ {
foreach (var entity in entitiesMarkedForRemoval) foreach (var entityID in entitiesMarkedForRemoval)
{ {
componentStore.Remove(entity); componentStore.Remove(entityID);
drawLayerManager.UnRegisterEntityWithLayer(entity); drawLayerManager.UnRegisterEntityWithLayer(entityID);
} }
entitiesMarkedForRemoval.Clear(); entitiesMarkedForRemoval.Clear();
@ -96,7 +91,7 @@ namespace Encompass
{ {
if (componentUpdateManager.RemovePending<TComponent>(entity, priority)) if (componentUpdateManager.RemovePending<TComponent>(entity, priority))
{ {
drawLayerManager.UnRegisterComponentWithLayer<TComponent>(entity); drawLayerManager.UnRegisterComponentWithLayer<TComponent>(entity.ID);
return true; return true;
} }
return false; return false;
@ -106,7 +101,7 @@ namespace Encompass
{ {
if (componentUpdateManager.Remove<TComponent>(entity, priority)) if (componentUpdateManager.Remove<TComponent>(entity, priority))
{ {
drawLayerManager.UnRegisterComponentWithLayer<TComponent>(entity); drawLayerManager.UnRegisterComponentWithLayer<TComponent>(entity.ID);
return true; return true;
} }
return false; return false;

View File

@ -28,13 +28,6 @@ namespace Encompass
UpToDateComponentStore.RegisterComponentType<TComponent>(); UpToDateComponentStore.RegisterComponentType<TComponent>();
} }
public void FinishRegistering()
{
existingComponentStore.FinishRegistering();
pendingComponentStore.FinishRegistering();
UpToDateComponentStore.FinishRegistering();
}
internal void Clear() internal void Clear()
{ {
existingComponentStore.ClearAll(); existingComponentStore.ClearAll();
@ -56,12 +49,12 @@ namespace Encompass
{ {
RegisterExistingOrPendingComponentMessage(entity, component); RegisterExistingOrPendingComponentMessage(entity, component);
existingComponentStore.Set(entity, component); existingComponentStore.Set(entity.ID, component);
} }
internal bool AddPendingComponent<TComponent>(Entity entity, TComponent component, int priority) where TComponent : struct, IComponent internal bool AddPendingComponent<TComponent>(Entity entity, TComponent component, int priority) where TComponent : struct, IComponent
{ {
if (pendingComponentStore.Set(entity, component, priority)) if (pendingComponentStore.Set(entity.ID, component, priority))
{ {
RegisterExistingOrPendingComponentMessage(entity, component); RegisterExistingOrPendingComponentMessage(entity, component);
return true; return true;
@ -72,45 +65,45 @@ namespace Encompass
internal bool RemovePending<TComponent>(Entity entity, int priority) where TComponent : struct, IComponent internal bool RemovePending<TComponent>(Entity entity, int priority) where TComponent : struct, IComponent
{ {
UpToDateComponentStore.Remove<TComponent>(entity, priority); UpToDateComponentStore.Remove<TComponent>(entity.ID, priority);
return pendingComponentStore.Remove<TComponent>(entity, priority); return pendingComponentStore.Remove<TComponent>(entity.ID, priority);
} }
internal bool Remove<TComponent>(Entity entity, int priority) where TComponent : struct, IComponent internal bool Remove<TComponent>(Entity entity, int priority) where TComponent : struct, IComponent
{ {
return UpToDateComponentStore.Remove<TComponent>(entity, priority); return UpToDateComponentStore.Remove<TComponent>(entity.ID, priority);
} }
private void RegisterExistingOrPendingComponentMessage<TComponent>(Entity entity, TComponent component) where TComponent : struct, IComponent private void RegisterExistingOrPendingComponentMessage<TComponent>(Entity entity, TComponent component) where TComponent : struct, IComponent
{ {
UpToDateComponentStore.Set(entity, component); UpToDateComponentStore.Set(entity.ID, component);
} }
public bool UpdateComponent<TComponent>(Entity entity, TComponent component, int priority) where TComponent : struct, IComponent public bool UpdateComponent<TComponent>(Entity entity, TComponent component, int priority) where TComponent : struct, IComponent
{ {
return UpToDateComponentStore.Set<TComponent>(entity, component, priority); return UpToDateComponentStore.Set<TComponent>(entity.ID, component, priority);
} }
// general component reads by type // general component reads by type
internal IEnumerable<(TComponent, Entity)> ReadExistingAndPendingComponentsByType<TComponent>() where TComponent : struct, IComponent internal IEnumerable<(TComponent, int)> ReadExistingAndPendingComponentsByType<TComponent>() where TComponent : struct, IComponent
{ {
return UpToDateComponentStore.All<TComponent>(); return UpToDateComponentStore.All<TComponent>();
} }
internal IEnumerable<(TComponent, Entity)> ReadExistingComponentsByType<TComponent>() where TComponent : struct, IComponent internal IEnumerable<(TComponent, int)> ReadExistingComponentsByType<TComponent>() where TComponent : struct, IComponent
{ {
return existingComponentStore.All<TComponent>(); return existingComponentStore.All<TComponent>();
} }
internal IEnumerable<(TComponent, Entity)> ReadPendingComponentsByType<TComponent>() where TComponent : struct, IComponent internal IEnumerable<(TComponent, int)> ReadPendingComponentsByType<TComponent>() where TComponent : struct, IComponent
{ {
return pendingComponentStore.All<TComponent>(); return pendingComponentStore.All<TComponent>();
} }
// singular component reads by type // singular component reads by type
internal (TComponent, Entity) ReadFirstExistingOrPendingComponentByType<TComponent>() where TComponent : struct, IComponent internal (TComponent, int) ReadFirstExistingOrPendingComponentByType<TComponent>() where TComponent : struct, IComponent
{ {
if (!SomeExistingOrPendingComponent<TComponent>()) { throw new Exceptions.NoComponentOfTypeException($"No Component with type {typeof(TComponent)} exists"); } if (!SomeExistingOrPendingComponent<TComponent>()) { throw new Exceptions.NoComponentOfTypeException($"No Component with type {typeof(TComponent)} exists"); }
var enumerator = ReadExistingAndPendingComponentsByType<TComponent>().GetEnumerator(); var enumerator = ReadExistingAndPendingComponentsByType<TComponent>().GetEnumerator();
@ -118,7 +111,7 @@ namespace Encompass
return enumerator.Current; return enumerator.Current;
} }
internal (TComponent, Entity) ReadFirstExistingComponentByType<TComponent>() where TComponent : struct, IComponent internal (TComponent, int) ReadFirstExistingComponentByType<TComponent>() where TComponent : struct, IComponent
{ {
if (!SomeExistingComponent<TComponent>()) { throw new Exceptions.NoComponentOfTypeException($"No Component with type {typeof(TComponent)} exists"); } if (!SomeExistingComponent<TComponent>()) { throw new Exceptions.NoComponentOfTypeException($"No Component with type {typeof(TComponent)} exists"); }
var enumerator = ReadExistingComponentsByType<TComponent>().GetEnumerator(); var enumerator = ReadExistingComponentsByType<TComponent>().GetEnumerator();
@ -126,7 +119,7 @@ namespace Encompass
return enumerator.Current; return enumerator.Current;
} }
internal (TComponent, Entity) ReadFirstPendingComponentByType<TComponent>() where TComponent : struct, IComponent internal (TComponent, int) ReadFirstPendingComponentByType<TComponent>() where TComponent : struct, IComponent
{ {
if (!SomePendingComponent<TComponent>()) { throw new Exceptions.NoComponentOfTypeException($"No Component with type {typeof(TComponent)} exists"); } if (!SomePendingComponent<TComponent>()) { throw new Exceptions.NoComponentOfTypeException($"No Component with type {typeof(TComponent)} exists"); }
var enumerator = ReadPendingComponentsByType<TComponent>().GetEnumerator(); var enumerator = ReadPendingComponentsByType<TComponent>().GetEnumerator();
@ -155,47 +148,47 @@ namespace Encompass
internal TComponent ReadExistingComponentByEntityAndType<TComponent>(Entity entity) where TComponent : struct, IComponent internal TComponent ReadExistingComponentByEntityAndType<TComponent>(Entity entity) where TComponent : struct, IComponent
{ {
return existingComponentStore.Get<TComponent>(entity); return existingComponentStore.Get<TComponent>(entity.ID);
} }
internal TComponent ReadPendingComponentByEntityAndType<TComponent>(Entity entity) where TComponent : struct, IComponent internal TComponent ReadPendingComponentByEntityAndType<TComponent>(Entity entity) where TComponent : struct, IComponent
{ {
return pendingComponentStore.Get<TComponent>(entity); return pendingComponentStore.Get<TComponent>(entity.ID);
} }
// check if entity has component of type // check if entity has component of type
internal bool HasExistingOrPendingComponent<TComponent>(Entity entity) where TComponent : struct, IComponent internal bool HasExistingOrPendingComponent<TComponent>(Entity entity) where TComponent : struct, IComponent
{ {
return UpToDateComponentStore.Has<TComponent>(entity); return UpToDateComponentStore.Has<TComponent>(entity.ID);
} }
internal bool HasExistingOrPendingComponent(Entity entity, Type type) internal bool HasExistingOrPendingComponent(Entity entity, Type type)
{ {
return UpToDateComponentStore.Has(type, entity); return UpToDateComponentStore.Has(type, entity.ID);
} }
internal bool HasExistingComponent<TComponent>(Entity entity) where TComponent : struct, IComponent internal bool HasExistingComponent<TComponent>(Entity entity) where TComponent : struct, IComponent
{ {
return existingComponentStore.Has<TComponent>(entity); return existingComponentStore.Has<TComponent>(entity.ID);
} }
internal bool HasExistingComponent(Entity entity, Type type) internal bool HasExistingComponent(Entity entity, Type type)
{ {
return existingComponentStore.Has(type, entity); return existingComponentStore.Has(type, entity.ID);
} }
internal bool HasPendingComponent<TComponent>(Entity entity) where TComponent : struct, IComponent internal bool HasPendingComponent<TComponent>(Entity entity) where TComponent : struct, IComponent
{ {
return pendingComponentStore.Has<TComponent>(entity); return pendingComponentStore.Has<TComponent>(entity.ID);
} }
internal bool HasPendingComponent(Entity entity, Type type) internal bool HasPendingComponent(Entity entity, Type type)
{ {
return pendingComponentStore.Has(type, entity); return pendingComponentStore.Has(type, entity.ID);
} }
internal ComponentBitSet PendingBits { get { return pendingComponentStore.ComponentBitSet; } } internal ComponentBitSet PendingBits { get { return pendingComponentStore.ComponentBitSet; } }
internal ComponentBitSet ExistingBits { get { return existingComponentStore.ComponentBitSet; } } internal ComponentBitSet ExistingBits { get { return existingComponentStore.ComponentBitSet; } }
} }
} }

View File

@ -12,7 +12,7 @@ namespace Encompass
private readonly Dictionary<int, ComponentStore> layerIndexToComponentStore = new Dictionary<int, ComponentStore>(512); private readonly Dictionary<int, ComponentStore> layerIndexToComponentStore = new Dictionary<int, ComponentStore>(512);
private readonly Dictionary<int, HashSet<GeneralRenderer>> layerIndexToGeneralRenderers = new Dictionary<int, HashSet<GeneralRenderer>>(512); private readonly Dictionary<int, HashSet<GeneralRenderer>> layerIndexToGeneralRenderers = new Dictionary<int, HashSet<GeneralRenderer>>(512);
private readonly Dictionary<Type, Dictionary<Entity, int>> typeToEntityToLayer = new Dictionary<Type, Dictionary<Entity, int>>(512); private readonly Dictionary<Type, Dictionary<int, int>> typeToEntityToLayer = new Dictionary<Type, Dictionary<int, int>>(512);
private Dictionary<Type, int> typeToIndex; private Dictionary<Type, int> typeToIndex;
public IEnumerable<int> LayerOrder { get { return layerOrder.Values; } } public IEnumerable<int> LayerOrder { get { return layerOrder.Values; } }
@ -32,19 +32,11 @@ namespace Encompass
} }
} }
public void FinishRegistering()
{
foreach (var store in layerIndexToComponentStore.Values)
{
store.FinishRegistering();
}
}
public void RegisterOrderedDrawable<TComponent>() where TComponent : struct, IComponent public void RegisterOrderedDrawable<TComponent>() where TComponent : struct, IComponent
{ {
if (!typeToEntityToLayer.ContainsKey(typeof(TComponent))) if (!typeToEntityToLayer.ContainsKey(typeof(TComponent)))
{ {
typeToEntityToLayer.Add(typeof(TComponent), new Dictionary<Entity, int>(128)); typeToEntityToLayer.Add(typeof(TComponent), new Dictionary<int, int>(128));
} }
foreach (var pair in layerIndexToComponentStore) foreach (var pair in layerIndexToComponentStore)
@ -74,38 +66,38 @@ namespace Encompass
RegisterGeneralRendererWithLayer(renderer, newLayer); RegisterGeneralRendererWithLayer(renderer, newLayer);
} }
public void RegisterComponentWithLayer<TComponent>(Entity entity, TComponent component, int layer) where TComponent : struct, IComponent public void RegisterComponentWithLayer<TComponent>(int entityID, TComponent component, int layer) where TComponent : struct, IComponent
{ {
if (!layerIndexToComponentStore.ContainsKey(layer)) if (!layerIndexToComponentStore.ContainsKey(layer))
{ {
throw new UndefinedLayerException("Layer {0} is not defined. Use WorldBuilder.RegisterDrawLayer to register the layer.", layer); throw new UndefinedLayerException("Layer {0} is not defined. Use WorldBuilder.RegisterDrawLayer to register the layer.", layer);
} }
if (typeToEntityToLayer[typeof(TComponent)].ContainsKey(entity)) { UnRegisterComponentWithLayer<TComponent>(entity); } if (typeToEntityToLayer[typeof(TComponent)].ContainsKey(entityID)) { UnRegisterComponentWithLayer<TComponent>(entityID); }
var set = layerIndexToComponentStore[layer]; var set = layerIndexToComponentStore[layer];
set.Set<TComponent>(entity, component); set.Set<TComponent>(entityID, component);
typeToEntityToLayer[typeof(TComponent)].Add(entity, layer); typeToEntityToLayer[typeof(TComponent)].Add(entityID, layer);
} }
public void UnRegisterComponentWithLayer<TComponent>(Entity entity) where TComponent : struct, IComponent public void UnRegisterComponentWithLayer<TComponent>(int entityID) where TComponent : struct, IComponent
{ {
if (!typeToEntityToLayer.ContainsKey(typeof(TComponent))) { return; } if (!typeToEntityToLayer.ContainsKey(typeof(TComponent))) { return; }
if (typeToEntityToLayer[typeof(TComponent)].ContainsKey(entity)) if (typeToEntityToLayer[typeof(TComponent)].ContainsKey(entityID))
{ {
var layer = typeToEntityToLayer[typeof(TComponent)][entity]; var layer = typeToEntityToLayer[typeof(TComponent)][entityID];
layerIndexToComponentStore[layer].ForceRemove<TComponent>(entity); layerIndexToComponentStore[layer].ForceRemove<TComponent>(entityID);
} }
typeToEntityToLayer[typeof(TComponent)].Remove(entity); typeToEntityToLayer[typeof(TComponent)].Remove(entityID);
} }
public void UnRegisterEntityWithLayer(Entity entity) public void UnRegisterEntityWithLayer(int entityID)
{ {
foreach (var store in layerIndexToComponentStore.Values) foreach (var store in layerIndexToComponentStore.Values)
{ {
store.Remove(entity); store.Remove(entityID);
} }
} }
@ -116,11 +108,11 @@ namespace Encompass
Enumerable.Empty<GeneralRenderer>(); Enumerable.Empty<GeneralRenderer>();
} }
public IEnumerable<(Entity, Type, IComponent)> AllInLayer(int layer) public IEnumerable<(int, Type, IComponent)> AllInLayer(int layer)
{ {
return layerIndexToComponentStore.ContainsKey(layer) ? return layerIndexToComponentStore.ContainsKey(layer) ?
layerIndexToComponentStore[layer].AllInterfaceTyped() : layerIndexToComponentStore[layer].AllInterfaceTyped() :
Enumerable.Empty<(Entity, Type, IComponent)>(); Enumerable.Empty<(int, Type, IComponent)>();
} }
} }
} }

View File

@ -173,7 +173,7 @@ namespace Encompass
/// </summary> /// </summary>
protected Entity ReadEntity<TComponent>() where TComponent : struct, IComponent protected Entity ReadEntity<TComponent>() where TComponent : struct, IComponent
{ {
return ReadComponentHelper<TComponent>().Item2; return entityManager.GetEntity(ReadComponentHelper<TComponent>().Item2);
} }
/// <summary> /// <summary>
@ -183,7 +183,7 @@ namespace Encompass
{ {
foreach (var pair in ReadComponentsHelper<TComponent>()) foreach (var pair in ReadComponentsHelper<TComponent>())
{ {
yield return pair.Item2; yield return entityManager.GetEntity(pair.Item2);
} }
} }
@ -194,7 +194,7 @@ namespace Encompass
return componentManager.GetComponentsByType<TComponent>(); return componentManager.GetComponentsByType<TComponent>();
} }
private IEnumerable<(TComponent, Entity)> ReadComponentsHelper<TComponent>() where TComponent : struct, IComponent private IEnumerable<(TComponent, int)> ReadComponentsHelper<TComponent>() where TComponent : struct, IComponent
{ {
var pendingRead = readPendingTypes.Contains(typeof(TComponent)); var pendingRead = readPendingTypes.Contains(typeof(TComponent));
var existingRead = readTypes.Contains(typeof(TComponent)); var existingRead = readTypes.Contains(typeof(TComponent));
@ -232,15 +232,21 @@ namespace Encompass
/// </summary> /// </summary>
protected IEnumerable<(TComponent, Entity)> ReadComponentsIncludingEntity<TComponent>() where TComponent : struct, IComponent protected IEnumerable<(TComponent, Entity)> ReadComponentsIncludingEntity<TComponent>() where TComponent : struct, IComponent
{ {
return ReadComponentsHelper<TComponent>(); foreach (var (component, id) in ReadComponentsHelper<TComponent>())
{
yield return (component, entityManager.GetEntity(id));
}
} }
internal IEnumerable<(TComponent, Entity)> InternalRead<TComponent>() where TComponent : struct, IComponent internal IEnumerable<(TComponent, Entity)> InternalRead<TComponent>() where TComponent : struct, IComponent
{ {
return componentManager.GetComponentsIncludingEntity<TComponent>(); foreach (var (component, id) in componentManager.GetComponentsIncludingEntity<TComponent>())
{
yield return (component, entityManager.GetEntity(id));
}
} }
private (TComponent, Entity) ReadComponentHelper<TComponent>() where TComponent : struct, IComponent private (TComponent, int) ReadComponentHelper<TComponent>() where TComponent : struct, IComponent
{ {
var pendingRead = readPendingTypes.Contains(typeof(TComponent)); var pendingRead = readPendingTypes.Contains(typeof(TComponent));
var existingRead = readTypes.Contains(typeof(TComponent)); var existingRead = readTypes.Contains(typeof(TComponent));
@ -275,7 +281,8 @@ namespace Encompass
/// </summary> /// </summary>
protected (TComponent, Entity) ReadComponentIncludingEntity<TComponent>() where TComponent : struct, IComponent protected (TComponent, Entity) ReadComponentIncludingEntity<TComponent>() where TComponent : struct, IComponent
{ {
return ReadComponentHelper<TComponent>(); var (component, id) = ReadComponentHelper<TComponent>();
return (component, entityManager.GetEntity(id));
} }
/// <summary> /// <summary>

View File

@ -49,6 +49,16 @@ namespace Encompass
return IDs.ContainsKey(id); return IDs.ContainsKey(id);
} }
public Entity GetEntity(int id)
{
if (!EntityExists(id))
{
throw new Encompass.Exceptions.EntityNotFoundException("Entity with id {0} does not exist.", id);
}
return IDs[id];
}
public void MarkForDestroy(Entity entity) public void MarkForDestroy(Entity entity)
{ {
entitiesMarkedForDestroy.Add(entity); entitiesMarkedForDestroy.Add(entity);

View File

@ -25,8 +25,8 @@ namespace Encompass
{ {
foreach (var entity in entities) foreach (var entity in entities)
{ {
var pendingBits = pendingBitLookup.EntityBitArray(entity); var pendingBits = pendingBitLookup.EntityBitArray(entity.ID);
var existingBits = existingBitLookup.EntityBitArray(entity); var existingBits = existingBitLookup.EntityBitArray(entity.ID);
var pending = WithPendingMask.And(pendingBits); var pending = WithPendingMask.And(pendingBits);
var existing = WithExistingMask.And(existingBits); var existing = WithExistingMask.And(existingBits);

View File

@ -5,12 +5,14 @@ namespace Encompass
{ {
internal class RenderManager internal class RenderManager
{ {
private readonly EntityManager entityManager;
private readonly DrawLayerManager drawLayerManager; private readonly DrawLayerManager drawLayerManager;
private readonly Dictionary<Type, Action<Entity, IComponent>> drawComponentTypeToOrderedRenderer = new Dictionary<Type, Action<Entity, IComponent>>(256); private readonly Dictionary<Type, Action<Entity, IComponent>> drawComponentTypeToOrderedRenderer = new Dictionary<Type, Action<Entity, IComponent>>(256);
public RenderManager(DrawLayerManager drawLayerManager) public RenderManager(EntityManager entityManager, DrawLayerManager drawLayerManager)
{ {
this.entityManager = entityManager;
this.drawLayerManager = drawLayerManager; this.drawLayerManager = drawLayerManager;
} }
@ -31,12 +33,12 @@ namespace Encompass
{ {
var generalRendererSet = drawLayerManager.GeneralRenderersByLayer(layer); var generalRendererSet = drawLayerManager.GeneralRenderersByLayer(layer);
foreach (var (entity, componentType, component) in drawLayerManager.AllInLayer(layer)) foreach (var (entityID, componentType, component) in drawLayerManager.AllInLayer(layer))
{ {
if (drawComponentTypeToOrderedRenderer.ContainsKey(componentType)) if (drawComponentTypeToOrderedRenderer.ContainsKey(componentType))
{ {
var internalRenderAction = drawComponentTypeToOrderedRenderer[componentType]; var internalRenderAction = drawComponentTypeToOrderedRenderer[componentType];
internalRenderAction(entity, component); internalRenderAction(entityManager.GetEntity(entityID), component);
} }
} }

View File

@ -37,7 +37,10 @@ namespace Encompass
protected IEnumerable<(TComponent, Entity)> ReadComponentsIncludingEntity<TComponent>() where TComponent : struct, IComponent protected IEnumerable<(TComponent, Entity)> ReadComponentsIncludingEntity<TComponent>() where TComponent : struct, IComponent
{ {
return componentManager.GetComponentsIncludingEntity<TComponent>(); foreach (var (component, id) in componentManager.GetComponentsIncludingEntity<TComponent>())
{
yield return (component, entityManager.GetEntity(id));
}
} }
protected TComponent ReadComponent<TComponent>() where TComponent : struct, IComponent protected TComponent ReadComponent<TComponent>() where TComponent : struct, IComponent

View File

@ -9,9 +9,9 @@ namespace Encompass
{ {
private IEnumerable<Type> _componentTypes; private IEnumerable<Type> _componentTypes;
private IEnumerable<Type> _messageTypes; private IEnumerable<Type> _messageTypes;
private Entity _entity; public Entity Entity { get; private set; }
public UberEngine(Entity entity, IEnumerable<Type> componentTypes, IEnumerable<Type> messageTypes) public UberEngine(IEnumerable<Type> componentTypes, IEnumerable<Type> messageTypes)
{ {
_componentTypes = componentTypes; _componentTypes = componentTypes;
_messageTypes = messageTypes; _messageTypes = messageTypes;
@ -19,14 +19,15 @@ namespace Encompass
writeTypes.UnionWith(componentTypes); writeTypes.UnionWith(componentTypes);
sendTypes.UnionWith(messageTypes); sendTypes.UnionWith(messageTypes);
receiveTypes.UnionWith(messageTypes); receiveTypes.UnionWith(messageTypes);
_entity = entity;
} }
public void Write() public void Write()
{ {
Entity = CreateEntity();
foreach (var type in _componentTypes) foreach (var type in _componentTypes)
{ {
var instanceParam = new object[] { _entity, Activator.CreateInstance(type) }; var instanceParam = new object[] { Entity, Activator.CreateInstance(type) };
var setComponentMethod = typeof(Engine).GetMethod("SetComponent", BindingFlags.NonPublic | BindingFlags.Instance); var setComponentMethod = typeof(Engine).GetMethod("SetComponent", BindingFlags.NonPublic | BindingFlags.Instance);
var genericSetComponentMethod = setComponentMethod.MakeGenericMethod(type); var genericSetComponentMethod = setComponentMethod.MakeGenericMethod(type);
genericSetComponentMethod.Invoke(this, instanceParam); genericSetComponentMethod.Invoke(this, instanceParam);
@ -43,10 +44,10 @@ namespace Encompass
CallGenericMethod(type, "ReadComponentsIncludingEntity", null); CallGenericMethod(type, "ReadComponentsIncludingEntity", null);
CallGenericMethod(type, "ReadEntity", null); CallGenericMethod(type, "ReadEntity", null);
CallGenericMethod(type, "ReadEntities", null); CallGenericMethod(type, "ReadEntities", null);
CallGenericMethod(type, "GetComponent", new Type[] { typeof(Entity) }, new object[] { _entity }); CallGenericMethod(type, "GetComponent", new Type[] { typeof(Entity) }, new object[] { Entity });
CallGenericMethod(type, "HasComponent", new Type[] { typeof(Entity) }, new object[] { _entity }); CallGenericMethod(type, "HasComponent", new Type[] { typeof(Entity) }, new object[] { Entity });
CallGenericMethod(type, "SomeComponent", null); CallGenericMethod(type, "SomeComponent", null);
CallGenericMethod(type, "RemoveComponent", new Type[] { typeof(Entity) }, new object[] { _entity }); CallGenericMethod(type, "RemoveComponent", new Type[] { typeof(Entity) }, new object[] { Entity });
CallGenericMethod(type, "DestroyWith", null); CallGenericMethod(type, "DestroyWith", null);
CallGenericMethod(type, "DestroyAllWith", null); CallGenericMethod(type, "DestroyAllWith", null);
} }

View File

@ -6,13 +6,17 @@ namespace Encompass
{ {
class UberRenderer : Renderer class UberRenderer : Renderer
{ {
private Entity _entity;
private IEnumerable<Type> _componentTypes; private IEnumerable<Type> _componentTypes;
private Entity _entity;
public UberRenderer(Entity entity, IEnumerable<Type> componentTypes) public UberRenderer(IEnumerable<Type> componentTypes)
{
_componentTypes = componentTypes;
}
public void SetEntity(Entity entity)
{ {
_entity = entity; _entity = entity;
_componentTypes = componentTypes;
} }
public void Render() public void Render()

View File

@ -51,7 +51,7 @@ namespace Encompass
componentManager = new ComponentManager(drawLayerManager, componentUpdateManager, typeToIndex); componentManager = new ComponentManager(drawLayerManager, componentUpdateManager, typeToIndex);
messageManager = new MessageManager(timeManager); messageManager = new MessageManager(timeManager);
entityManager = new EntityManager(componentManager, entityCapacity); entityManager = new EntityManager(componentManager, entityCapacity);
renderManager = new RenderManager(drawLayerManager); renderManager = new RenderManager(entityManager, drawLayerManager);
startingComponentStoreForComponentManager = new ComponentStore(typeToIndex); startingComponentStoreForComponentManager = new ComponentStore(typeToIndex);
startingComponentStoreForComponentUpdateManager = new ComponentStore(typeToIndex); startingComponentStoreForComponentUpdateManager = new ComponentStore(typeToIndex);
@ -89,10 +89,8 @@ namespace Encompass
RegisterComponentType<TComponent>(); RegisterComponentType<TComponent>();
componentTypesToRegister.Add(typeof(TComponent)); componentTypesToRegister.Add(typeof(TComponent));
startingComponentStoreForComponentManager.FinishRegistering(); startingComponentStoreForComponentManager.Set(entity.ID, component);
startingComponentStoreForComponentManager.Set(entity, component); startingComponentStoreForComponentUpdateManager.Set(entity.ID, component);
startingComponentStoreForComponentUpdateManager.FinishRegistering();
startingComponentStoreForComponentUpdateManager.Set(entity, component);
if (component is IDrawableComponent drawableComponent) if (component is IDrawableComponent drawableComponent)
{ {
@ -371,12 +369,6 @@ namespace Encompass
engineOrder.Add(emitterEngine); engineOrder.Add(emitterEngine);
} }
componentManager.FinishRegistering();
componentUpdateManager.FinishRegistering();
drawLayerManager.FinishRegistering();
startingComponentStoreForComponentManager.FinishRegistering();
startingComponentStoreForComponentUpdateManager.FinishRegistering();
PreloadJIT(componentTypesToRegister, messageTypes); PreloadJIT(componentTypesToRegister, messageTypes);
foreach (var engine in engineGraph.TopologicalSort()) foreach (var engine in engineGraph.TopologicalSort())
@ -415,12 +407,11 @@ namespace Encompass
var dummyComponentUpdateManager = new ComponentUpdateManager(typeToIndex); var dummyComponentUpdateManager = new ComponentUpdateManager(typeToIndex);
var dummyComponentManager = new ComponentManager(dummyDrawLayerManager, dummyComponentUpdateManager, typeToIndex); var dummyComponentManager = new ComponentManager(dummyDrawLayerManager, dummyComponentUpdateManager, typeToIndex);
var dummyEntityManager = new EntityManager(dummyComponentManager, entityCapacity); var dummyEntityManager = new EntityManager(dummyComponentManager, entityCapacity);
var dummyRenderManager = new RenderManager(dummyDrawLayerManager); var dummyRenderManager = new RenderManager(dummyEntityManager, dummyDrawLayerManager);
var prepEngineOrder = new List<Engine>(); var prepEngineOrder = new List<Engine>();
var entity = dummyEntityManager.CreateEntity(); var uberEngine = new UberEngine(componentTypes, messageTypes);
var uberEngine = new UberEngine(entity, componentTypes, messageTypes);
uberEngine.AssignEntityManager(dummyEntityManager); uberEngine.AssignEntityManager(dummyEntityManager);
uberEngine.AssignComponentManager(dummyComponentManager); uberEngine.AssignComponentManager(dummyComponentManager);
@ -428,7 +419,7 @@ namespace Encompass
uberEngine.AssignComponentUpdateManager(dummyComponentUpdateManager); uberEngine.AssignComponentUpdateManager(dummyComponentUpdateManager);
uberEngine.AssignTimeManager(dummyTimeManager); uberEngine.AssignTimeManager(dummyTimeManager);
var uberRenderer = new UberRenderer(entity, componentTypes); var uberRenderer = new UberRenderer(componentTypes);
uberRenderer.AssignComponentManager(dummyComponentManager); uberRenderer.AssignComponentManager(dummyComponentManager);
uberRenderer.AssignEntityManager(dummyEntityManager); uberRenderer.AssignEntityManager(dummyEntityManager);
@ -481,6 +472,7 @@ namespace Encompass
dummyComponentManager.WriteComponents(); dummyComponentManager.WriteComponents();
dummyComponentUpdateManager.Clear(); dummyComponentUpdateManager.Clear();
uberRenderer.SetEntity(uberEngine.Entity);
uberRenderer.Render(); uberRenderer.Render();
} }
} }