encompass-cs/encompass-cs/DrawLayerManager.cs

119 lines
4.5 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using Encompass.Exceptions;
namespace Encompass
{
internal class DrawLayerManager
{
private readonly SortedList<int, int> layerOrder = new SortedList<int, int>();
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<int, int>> typeToEntityToLayer = new Dictionary<Type, Dictionary<int, int>>(512);
private Dictionary<Type, int> typeToIndex;
public IEnumerable<int> LayerOrder { get { return layerOrder.Values; } }
public DrawLayerManager(Dictionary<Type, int> typeToIndex)
{
this.typeToIndex = typeToIndex;
RegisterDrawLayer(0);
}
public void RegisterDrawLayer(int layer)
{
if (!layerIndexToComponentStore.ContainsKey(layer))
{
layerOrder.Add(layer, layer);
layerIndexToGeneralRenderers.Add(layer, new HashSet<GeneralRenderer>());
layerIndexToComponentStore.Add(layer, new ComponentStore(typeToIndex));
}
}
public void RegisterOrderedDrawable<TComponent>() where TComponent : struct, IComponent
{
if (!typeToEntityToLayer.ContainsKey(typeof(TComponent)))
{
typeToEntityToLayer.Add(typeof(TComponent), new Dictionary<int, int>(128));
}
foreach (var pair in layerIndexToComponentStore)
{
pair.Value.RegisterComponentType<TComponent>();
}
}
public void RegisterGeneralRendererWithLayer(GeneralRenderer renderer, int layer)
{
RegisterDrawLayer(layer);
var set = layerIndexToGeneralRenderers[layer];
set.Add(renderer);
}
public void UnregisterGeneralRendererWithLayer(GeneralRenderer renderer, int layer)
{
if (layerIndexToGeneralRenderers.ContainsKey(layer))
{
layerIndexToGeneralRenderers[layer].Remove(renderer);
}
}
public void AdjustRendererLayer(GeneralRenderer renderer, int oldLayer, int newLayer)
{
UnregisterGeneralRendererWithLayer(renderer, oldLayer);
RegisterGeneralRendererWithLayer(renderer, newLayer);
}
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(entityID)) { UnRegisterComponentWithLayer<TComponent>(entityID); }
var set = layerIndexToComponentStore[layer];
set.Set<TComponent>(entityID, component);
typeToEntityToLayer[typeof(TComponent)].Add(entityID, layer);
}
public void UnRegisterComponentWithLayer<TComponent>(int entityID) where TComponent : struct, IComponent
{
if (!typeToEntityToLayer.ContainsKey(typeof(TComponent))) { return; }
if (typeToEntityToLayer[typeof(TComponent)].ContainsKey(entityID))
{
var layer = typeToEntityToLayer[typeof(TComponent)][entityID];
layerIndexToComponentStore[layer].ForceRemove<TComponent>(entityID);
}
typeToEntityToLayer[typeof(TComponent)].Remove(entityID);
}
public void UnRegisterEntityWithLayer(int entityID)
{
foreach (var store in layerIndexToComponentStore.Values)
{
store.Remove(entityID);
}
}
public IEnumerable<GeneralRenderer> GeneralRenderersByLayer(int layer)
{
return layerIndexToGeneralRenderers.ContainsKey(layer) ?
layerIndexToGeneralRenderers[layer] :
Enumerable.Empty<GeneralRenderer>();
}
public IEnumerable<(int, Type, IComponent)> AllInLayer(int layer)
{
return layerIndexToComponentStore.ContainsKey(layer) ?
layerIndexToComponentStore[layer].AllInterfaceTyped() :
Enumerable.Empty<(int, Type, IComponent)>();
}
}
}