239 lines
9.3 KiB
C#
239 lines
9.3 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
|
|
namespace Encompass
|
|
{
|
|
internal class ComponentManager
|
|
{
|
|
private readonly DrawLayerManager drawLayerManager;
|
|
|
|
private readonly ComponentStore existingComponentStore;
|
|
private readonly ComponentStore immediateComponentStore;
|
|
private ComponentStore upToDateComponentStore;
|
|
|
|
public Dictionary<Type, int> TypeToIndex { get; }
|
|
|
|
private readonly HashSet<int> entitiesMarkedForRemoval = new HashSet<int>();
|
|
|
|
internal ComponentBitSet ImmediateBits { get { return immediateComponentStore.ComponentBitSet; } }
|
|
internal ComponentBitSet ExistingBits { get { return existingComponentStore.ComponentBitSet; } }
|
|
|
|
public ComponentManager(DrawLayerManager drawLayerManager, Dictionary<Type, int> typeToIndex)
|
|
{
|
|
this.drawLayerManager = drawLayerManager;
|
|
existingComponentStore = new ComponentStore(typeToIndex);
|
|
immediateComponentStore = new ComponentStore(typeToIndex);
|
|
upToDateComponentStore = new ComponentStore(typeToIndex);
|
|
TypeToIndex = typeToIndex;
|
|
}
|
|
|
|
public void RegisterComponentType<TComponent>() where TComponent : struct, IComponent
|
|
{
|
|
existingComponentStore.RegisterComponentType<TComponent>();
|
|
immediateComponentStore.RegisterComponentType<TComponent>();
|
|
upToDateComponentStore.RegisterComponentType<TComponent>();
|
|
}
|
|
|
|
internal void SetComponentStore(ComponentStore componentStore)
|
|
{
|
|
existingComponentStore.SwapWith(componentStore);
|
|
}
|
|
|
|
internal void RegisterDrawableComponent<TComponent>(Entity entity, TComponent component, int layer) where TComponent : struct, IComponent
|
|
{
|
|
drawLayerManager.RegisterComponentWithLayer(entity.ID, component, layer);
|
|
}
|
|
|
|
internal void WriteComponents()
|
|
{
|
|
SetComponentStore(upToDateComponentStore);
|
|
upToDateComponentStore.ClearAll();
|
|
immediateComponentStore.ClearAll();
|
|
}
|
|
|
|
internal void AddExistingComponent<TComponent>(Entity entity, TComponent component) where TComponent : struct, IComponent
|
|
{
|
|
upToDateComponentStore.Set(entity.ID, component);
|
|
}
|
|
|
|
internal bool AddImmediateComponent<TComponent>(Entity entity, TComponent component, int priority) where TComponent : struct, IComponent
|
|
{
|
|
if (immediateComponentStore.Set(entity.ID, component, priority))
|
|
{
|
|
upToDateComponentStore.Set(entity.ID, component);
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public bool UpdateComponent<TComponent>(Entity entity, TComponent component, int priority) where TComponent : struct, IComponent
|
|
{
|
|
return upToDateComponentStore.Set(entity.ID, component, priority);
|
|
}
|
|
|
|
// existing or immediate reads
|
|
|
|
internal IEnumerable<(TComponent, int)> ReadExistingAndImmediateComponentsByType<TComponent>() where TComponent : struct, IComponent
|
|
{
|
|
return upToDateComponentStore.All<TComponent>();
|
|
}
|
|
|
|
internal (TComponent, int) ReadFirstExistingOrImmediateComponentByType<TComponent>() where TComponent : struct, IComponent
|
|
{
|
|
if (!SomeExistingOrImmediateComponent<TComponent>()) { throw new Exceptions.NoComponentOfTypeException($"No Component with type {typeof(TComponent)} exists"); }
|
|
var enumerator = ReadExistingAndImmediateComponentsByType<TComponent>().GetEnumerator();
|
|
enumerator.MoveNext();
|
|
return enumerator.Current;
|
|
}
|
|
|
|
internal bool SomeExistingOrImmediateComponent<TComponent>() where TComponent : struct, IComponent
|
|
{
|
|
return upToDateComponentStore.Any<TComponent>();
|
|
}
|
|
|
|
// existing reads
|
|
|
|
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 = GetComponentsIncludingEntity<TComponent>().GetEnumerator();
|
|
enumerator.MoveNext();
|
|
return enumerator.Current;
|
|
}
|
|
|
|
internal bool SomeExistingComponent<TComponent>() where TComponent : struct, IComponent
|
|
{
|
|
return existingComponentStore.Any<TComponent>();
|
|
}
|
|
|
|
// immediate reads
|
|
|
|
internal IEnumerable<(TComponent, int)> ReadImmediateComponentsByType<TComponent>() where TComponent : struct, IComponent
|
|
{
|
|
return immediateComponentStore.All<TComponent>();
|
|
}
|
|
|
|
internal (TComponent, int) ReadFirstImmediateComponentByType<TComponent>() where TComponent : struct, IComponent
|
|
{
|
|
if (!SomeImmediateComponent<TComponent>()) { throw new Exceptions.NoComponentOfTypeException($"No Component with type {typeof(TComponent)} exists"); }
|
|
var enumerator = ReadImmediateComponentsByType<TComponent>().GetEnumerator();
|
|
enumerator.MoveNext();
|
|
return enumerator.Current;
|
|
}
|
|
|
|
internal bool SomeImmediateComponent<TComponent>() where TComponent : struct, IComponent
|
|
{
|
|
return immediateComponentStore.Any<TComponent>();
|
|
}
|
|
|
|
// component getters
|
|
|
|
internal TComponent ReadImmediateOrExistingComponentByEntityAndType<TComponent>(Entity entity) where TComponent : struct, IComponent
|
|
{
|
|
return upToDateComponentStore.Get<TComponent>(entity.ID);
|
|
}
|
|
|
|
internal TComponent ReadExistingComponentByEntityAndType<TComponent>(Entity entity) where TComponent : struct, IComponent
|
|
{
|
|
return existingComponentStore.Get<TComponent>(entity.ID);
|
|
}
|
|
|
|
internal TComponent ReadImmediateComponentByEntityAndType<TComponent>(Entity entity) where TComponent : struct, IComponent
|
|
{
|
|
return immediateComponentStore.Get<TComponent>(entity.ID);
|
|
}
|
|
|
|
// has checkers
|
|
|
|
internal bool HasExistingOrImmediateComponent<TComponent>(Entity entity) where TComponent : struct, IComponent
|
|
{
|
|
return upToDateComponentStore.Has<TComponent>(entity.ID);
|
|
}
|
|
|
|
internal bool HasExistingOrImmediateComponent(Entity entity, Type type)
|
|
{
|
|
return upToDateComponentStore.Has(type, entity.ID);
|
|
}
|
|
|
|
internal bool HasExistingComponent<TComponent>(Entity entity) where TComponent : struct, IComponent
|
|
{
|
|
return existingComponentStore.Has<TComponent>(entity.ID);
|
|
}
|
|
|
|
internal bool HasExistingComponent(Entity entity, Type type)
|
|
{
|
|
return existingComponentStore.Has(type, entity.ID);
|
|
}
|
|
|
|
internal bool HasImmediateComponent<TComponent>(Entity entity) where TComponent : struct, IComponent
|
|
{
|
|
return immediateComponentStore.Has<TComponent>(entity.ID);
|
|
}
|
|
|
|
internal bool HasImmediateComponent(Entity entity, Type type)
|
|
{
|
|
return immediateComponentStore.Has(type, entity.ID);
|
|
}
|
|
|
|
internal IEnumerable<(TComponent, int)> GetComponentsIncludingEntity<TComponent>() where TComponent : struct, IComponent
|
|
{
|
|
return existingComponentStore.All<TComponent>();
|
|
}
|
|
|
|
internal IEnumerable<TComponent> GetComponentsByType<TComponent>() where TComponent : struct, IComponent
|
|
{
|
|
foreach (var pair in existingComponentStore.All<TComponent>())
|
|
{
|
|
yield return pair.Item1;
|
|
}
|
|
}
|
|
|
|
internal TComponent GetComponentByEntityAndType<TComponent>(Entity entity) where TComponent : struct, IComponent
|
|
{
|
|
return existingComponentStore.Get<TComponent>(entity.ID);
|
|
}
|
|
|
|
internal bool EntityHasComponentOfType<TComponent>(Entity entity) where TComponent : struct, IComponent
|
|
{
|
|
return existingComponentStore.Has<TComponent>(entity.ID);
|
|
}
|
|
|
|
internal void MarkAllComponentsOnEntityForRemoval(Entity entity)
|
|
{
|
|
entitiesMarkedForRemoval.Add(entity.ID);
|
|
}
|
|
|
|
internal void RemoveMarkedComponents()
|
|
{
|
|
foreach (var entityID in entitiesMarkedForRemoval)
|
|
{
|
|
existingComponentStore.Remove(entityID);
|
|
upToDateComponentStore.Remove(entityID);
|
|
drawLayerManager.UnRegisterEntityWithLayer(entityID);
|
|
}
|
|
|
|
entitiesMarkedForRemoval.Clear();
|
|
}
|
|
|
|
public bool RemoveImmediate<TComponent>(Entity entity, int priority) where TComponent : struct, IComponent
|
|
{
|
|
if (immediateComponentStore.Remove<TComponent>(entity.ID, priority))
|
|
{
|
|
upToDateComponentStore.Remove<TComponent>(entity.ID, priority);
|
|
drawLayerManager.UnRegisterComponentWithLayer<TComponent>(entity.ID);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public void Remove<TComponent>(Entity entity, int priority) where TComponent : struct, IComponent
|
|
{
|
|
if (upToDateComponentStore.Remove<TComponent>(entity.ID, priority))
|
|
{
|
|
drawLayerManager.UnRegisterComponentWithLayer<TComponent>(entity.ID);
|
|
}
|
|
}
|
|
}
|
|
}
|