encompass-cs/encompass-cs/DrawLayerManager.cs

119 lines
4.6 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 readonly Dictionary<Type, int> _typeToIndex;
public IEnumerable<int> LayerOrder { get { return _layerOrder.Values; } }
public DrawLayerManager(Dictionary<Type, int> typeToIndex)
{
_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)>();
}
}
}