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
{
Dictionary<Entity, BitSet512> entities = new Dictionary<Entity, BitSet512>();
Dictionary<int, BitSet512> entities = new Dictionary<int, BitSet512>();
Dictionary<Type, int> TypeToIndex { get; }
public ComponentBitSet(Dictionary<Type, int> typeToIndex)
@ -15,46 +15,41 @@ namespace Encompass
TypeToIndex = typeToIndex;
}
public void FinishRegistering()
{
}
public void 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); }
entities[entity] = entities[entity].Set(TypeToIndex[typeof(TComponent)]);
if (!entities.ContainsKey(entityID)) { AddEntity(entityID); }
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
{
//RegisterComponentType<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);
ComponentBitSet.Set<TComponent>(entity);
Lookup<TComponent>().Set(entityID, component);
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 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 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)
{
entry.ForceRemove(entity);
entry.ForceRemove(entityID);
}
ComponentBitSet.RemoveEntity(entity);
ComponentBitSet.RemoveEntity(entityID);
}
public bool Any<TComponent>() where TComponent : struct, IComponent
@ -107,7 +102,7 @@ namespace Encompass
return Lookup<TComponent>().Count > 0;
}
public IEnumerable<(Entity, Type, IComponent)> AllInterfaceTyped()
public IEnumerable<(int, Type, IComponent)> AllInterfaceTyped()
{
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();
}

View File

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

View File

@ -9,7 +9,7 @@ namespace Encompass
private readonly ComponentUpdateManager componentUpdateManager;
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)
{
@ -23,11 +23,6 @@ namespace Encompass
componentStore.RegisterComponentType<TComponent>();
}
public void FinishRegistering()
{
componentStore.FinishRegistering();
}
internal void SetComponentStore(ComponentStore 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
{
drawLayerManager.RegisterComponentWithLayer(entity, component, layer);
drawLayerManager.RegisterComponentWithLayer(entity.ID, component, layer);
}
internal void AddComponent<TComponent>(Entity entity, TComponent component) where TComponent : struct, IComponent
{
componentStore.Set(entity, component);
componentStore.Set(entity.ID, component);
}
internal void WriteComponents()
@ -48,7 +43,7 @@ namespace Encompass
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>();
}
@ -63,12 +58,12 @@ namespace Encompass
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
{
return componentStore.Has<TComponent>(entity);
return componentStore.Has<TComponent>(entity.ID);
}
internal bool ComponentOfTypeExists<TComponent>() where TComponent : struct, IComponent
@ -78,15 +73,15 @@ namespace Encompass
internal void MarkAllComponentsOnEntityForRemoval(Entity entity)
{
entitiesMarkedForRemoval.Add(entity);
entitiesMarkedForRemoval.Add(entity.ID);
}
internal void RemoveMarkedComponents()
{
foreach (var entity in entitiesMarkedForRemoval)
foreach (var entityID in entitiesMarkedForRemoval)
{
componentStore.Remove(entity);
drawLayerManager.UnRegisterEntityWithLayer(entity);
componentStore.Remove(entityID);
drawLayerManager.UnRegisterEntityWithLayer(entityID);
}
entitiesMarkedForRemoval.Clear();
@ -96,7 +91,7 @@ namespace Encompass
{
if (componentUpdateManager.RemovePending<TComponent>(entity, priority))
{
drawLayerManager.UnRegisterComponentWithLayer<TComponent>(entity);
drawLayerManager.UnRegisterComponentWithLayer<TComponent>(entity.ID);
return true;
}
return false;
@ -106,7 +101,7 @@ namespace Encompass
{
if (componentUpdateManager.Remove<TComponent>(entity, priority))
{
drawLayerManager.UnRegisterComponentWithLayer<TComponent>(entity);
drawLayerManager.UnRegisterComponentWithLayer<TComponent>(entity.ID);
return true;
}
return false;

View File

@ -28,13 +28,6 @@ namespace Encompass
UpToDateComponentStore.RegisterComponentType<TComponent>();
}
public void FinishRegistering()
{
existingComponentStore.FinishRegistering();
pendingComponentStore.FinishRegistering();
UpToDateComponentStore.FinishRegistering();
}
internal void Clear()
{
existingComponentStore.ClearAll();
@ -56,12 +49,12 @@ namespace Encompass
{
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
{
if (pendingComponentStore.Set(entity, component, priority))
if (pendingComponentStore.Set(entity.ID, component, priority))
{
RegisterExistingOrPendingComponentMessage(entity, component);
return true;
@ -72,45 +65,45 @@ namespace Encompass
internal bool RemovePending<TComponent>(Entity entity, int priority) where TComponent : struct, IComponent
{
UpToDateComponentStore.Remove<TComponent>(entity, priority);
return pendingComponentStore.Remove<TComponent>(entity, priority);
UpToDateComponentStore.Remove<TComponent>(entity.ID, priority);
return pendingComponentStore.Remove<TComponent>(entity.ID, priority);
}
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
{
UpToDateComponentStore.Set(entity, component);
UpToDateComponentStore.Set(entity.ID, component);
}
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
internal IEnumerable<(TComponent, Entity)> ReadExistingAndPendingComponentsByType<TComponent>() where TComponent : struct, IComponent
internal IEnumerable<(TComponent, int)> ReadExistingAndPendingComponentsByType<TComponent>() where TComponent : struct, IComponent
{
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>();
}
internal IEnumerable<(TComponent, Entity)> ReadPendingComponentsByType<TComponent>() where TComponent : struct, IComponent
internal IEnumerable<(TComponent, int)> ReadPendingComponentsByType<TComponent>() where TComponent : struct, IComponent
{
return pendingComponentStore.All<TComponent>();
}
// 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"); }
var enumerator = ReadExistingAndPendingComponentsByType<TComponent>().GetEnumerator();
@ -118,7 +111,7 @@ namespace Encompass
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"); }
var enumerator = ReadExistingComponentsByType<TComponent>().GetEnumerator();
@ -126,7 +119,7 @@ namespace Encompass
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"); }
var enumerator = ReadPendingComponentsByType<TComponent>().GetEnumerator();
@ -155,47 +148,47 @@ namespace Encompass
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
{
return pendingComponentStore.Get<TComponent>(entity);
return pendingComponentStore.Get<TComponent>(entity.ID);
}
// check if entity has component of type
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)
{
return UpToDateComponentStore.Has(type, entity);
return UpToDateComponentStore.Has(type, entity.ID);
}
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)
{
return existingComponentStore.Has(type, entity);
return existingComponentStore.Has(type, entity.ID);
}
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)
{
return pendingComponentStore.Has(type, entity);
return pendingComponentStore.Has(type, entity.ID);
}
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, 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;
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
{
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)
@ -74,38 +66,38 @@ namespace Encompass
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))
{
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];
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[typeof(TComponent)].ContainsKey(entity))
if (typeToEntityToLayer[typeof(TComponent)].ContainsKey(entityID))
{
var layer = typeToEntityToLayer[typeof(TComponent)][entity];
layerIndexToComponentStore[layer].ForceRemove<TComponent>(entity);
var layer = typeToEntityToLayer[typeof(TComponent)][entityID];
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)
{
store.Remove(entity);
store.Remove(entityID);
}
}
@ -116,11 +108,11 @@ namespace Encompass
Enumerable.Empty<GeneralRenderer>();
}
public IEnumerable<(Entity, Type, IComponent)> AllInLayer(int layer)
public IEnumerable<(int, Type, IComponent)> AllInLayer(int layer)
{
return layerIndexToComponentStore.ContainsKey(layer) ?
layerIndexToComponentStore[layer].AllInterfaceTyped() :
Enumerable.Empty<(Entity, Type, IComponent)>();
Enumerable.Empty<(int, Type, IComponent)>();
}
}
}

View File

@ -173,7 +173,7 @@ namespace Encompass
/// </summary>
protected Entity ReadEntity<TComponent>() where TComponent : struct, IComponent
{
return ReadComponentHelper<TComponent>().Item2;
return entityManager.GetEntity(ReadComponentHelper<TComponent>().Item2);
}
/// <summary>
@ -183,7 +183,7 @@ namespace Encompass
{
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>();
}
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 existingRead = readTypes.Contains(typeof(TComponent));
@ -232,15 +232,21 @@ namespace Encompass
/// </summary>
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
{
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 existingRead = readTypes.Contains(typeof(TComponent));
@ -275,7 +281,8 @@ namespace Encompass
/// </summary>
protected (TComponent, Entity) ReadComponentIncludingEntity<TComponent>() where TComponent : struct, IComponent
{
return ReadComponentHelper<TComponent>();
var (component, id) = ReadComponentHelper<TComponent>();
return (component, entityManager.GetEntity(id));
}
/// <summary>

View File

@ -49,6 +49,16 @@ namespace Encompass
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)
{
entitiesMarkedForDestroy.Add(entity);

View File

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

View File

@ -5,12 +5,14 @@ namespace Encompass
{
internal class RenderManager
{
private readonly EntityManager entityManager;
private readonly DrawLayerManager drawLayerManager;
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;
}
@ -31,12 +33,12 @@ namespace Encompass
{
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))
{
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
{
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

View File

@ -9,9 +9,9 @@ namespace Encompass
{
private IEnumerable<Type> _componentTypes;
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;
_messageTypes = messageTypes;
@ -19,14 +19,15 @@ namespace Encompass
writeTypes.UnionWith(componentTypes);
sendTypes.UnionWith(messageTypes);
receiveTypes.UnionWith(messageTypes);
_entity = entity;
}
public void Write()
{
Entity = CreateEntity();
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 genericSetComponentMethod = setComponentMethod.MakeGenericMethod(type);
genericSetComponentMethod.Invoke(this, instanceParam);
@ -43,10 +44,10 @@ namespace Encompass
CallGenericMethod(type, "ReadComponentsIncludingEntity", null);
CallGenericMethod(type, "ReadEntity", null);
CallGenericMethod(type, "ReadEntities", null);
CallGenericMethod(type, "GetComponent", new Type[] { typeof(Entity) }, new object[] { _entity });
CallGenericMethod(type, "HasComponent", 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, "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, "DestroyAllWith", null);
}

View File

@ -6,13 +6,17 @@ namespace Encompass
{
class UberRenderer : Renderer
{
private Entity _entity;
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;
_componentTypes = componentTypes;
}
public void Render()

View File

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