encompass-cs/encompass-cs/ComponentManager.cs

115 lines
4.0 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using Encompass.Exceptions;
using Collections.Pooled;
namespace Encompass
{
internal class ComponentManager
{
private readonly DrawLayerManager drawLayerManager;
private readonly ComponentStore componentStore = new ComponentStore();
private readonly Dictionary<(Entity, Type), IComponent> componentWriteData = new Dictionary<(Entity, Type), IComponent>();
private readonly Dictionary<(Entity, Type), int> componentWritePriorities = new Dictionary<(Entity, Type), int>();
private readonly HashSet<Entity> entitiesMarkedForRemoval = new HashSet<Entity>();
public ComponentManager(DrawLayerManager drawLayerManager)
{
this.drawLayerManager = drawLayerManager;
}
internal void MarkComponentForWrite<TComponent>(Entity entity, TComponent component, int priority) where TComponent : struct, IComponent
{
componentStore.RegisterComponentType<TComponent>();
if (componentWriteData.ContainsKey((entity, typeof(TComponent))))
{
var currentPriority = componentWritePriorities[(entity, typeof(TComponent))];
if (priority < currentPriority)
{
componentWriteData[(entity, typeof(TComponent))] = component;
componentWritePriorities[(entity, typeof(TComponent))] = priority;
}
}
else
{
componentWriteData.Add((entity, typeof(TComponent)), component);
componentWritePriorities[(entity, typeof(TComponent))] = priority;
}
}
internal void RegisterDrawableComponent<TComponent>(Guid componentID, TComponent component) where TComponent : IDrawableComponent
{
drawLayerManager.RegisterComponentWithLayer(componentID, component.Layer);
}
internal void AddComponent<TComponent>(Entity entity, TComponent component) where TComponent : struct, IComponent
{
componentStore.Set<TComponent>(entity, component);
}
internal void WriteComponents()
{
foreach (var keyValuePair in componentWriteData)
{
var (entity, type) = keyValuePair.Key;
var component = keyValuePair.Value;
AddComponent(entity, component);
}
componentWriteData.Clear();
componentWritePriorities.Clear();
}
internal IEnumerable<TComponent> GetComponentsByType<TComponent>() where TComponent : struct, IComponent
{
return componentStore.All<TComponent>().Select(pair => pair.Item2);
}
internal TComponent GetComponentByEntityAndType<TComponent>(Entity entity) where TComponent : struct, IComponent
{
return componentStore.Get<TComponent>(entity);
}
internal bool EntityHasComponentOfType<TComponent>(Entity entity) where TComponent : struct, IComponent
{
return componentStore.Has<TComponent>(entity);
}
internal bool ComponentOfTypeExists<TComponent>() where TComponent : struct, IComponent
{
return componentStore.Any<TComponent>();
}
internal void MarkAllComponentsOnEntityForRemoval(Entity entity)
{
entitiesMarkedForRemoval.Add(entity);
}
internal void RemoveMarkedComponents()
{
foreach (var entity in entitiesMarkedForRemoval)
{
componentStore.Remove(entity);
drawLayerManager.UnRegisterComponentWithLayer(entity);
}
entitiesMarkedForRemoval.Clear();
}
public void Remove<TComponent>(Entity entity) where TComponent : struct, IComponent
{
componentStore.Remove<TComponent>(entity);
}
private void Remove(Entity entity)
{
componentStore.Remove(entity);
}
}
}