internal storage using int ID instead of entity to avoid hash lookups
parent
7885c2e0f4
commit
47e1072c8d
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
if (!priorities.ContainsKey(entityID) || priority < priorities[entityID])
|
||||
{
|
||||
store[entityID] = component;
|
||||
priorities[entityID] = priority;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool Remove(Entity entity, int priority)
|
||||
public override bool Remove(int entityID, 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);
|
||||
priorities[entityID] = priority;
|
||||
store.Remove(entityID);
|
||||
priorities.Remove(entityID);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void ForceRemove(Entity entity)
|
||||
public override void ForceRemove(int entityID)
|
||||
{
|
||||
store.Remove(entity);
|
||||
priorities.Remove(entity);
|
||||
store.Remove(entityID);
|
||||
priorities.Remove(entityID);
|
||||
}
|
||||
|
||||
public override bool Has(Entity entity)
|
||||
public override bool Has(int entityID)
|
||||
{
|
||||
return store.ContainsKey(entity);
|
||||
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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,44 +148,44 @@ 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; } }
|
||||
|
|
|
@ -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)>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue