133 lines
4.7 KiB
C#
133 lines
4.7 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, Dictionary<Type, HashSet<int>>> _layerIndexToTypeToID = new Dictionary<int, Dictionary<Type, HashSet<int>>>();
|
|
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);
|
|
public IEnumerable<int> LayerOrder { get { return _layerOrder.Values; } }
|
|
|
|
public DrawLayerManager()
|
|
{
|
|
RegisterDrawLayer(0);
|
|
}
|
|
|
|
public void RegisterDrawLayer(int layer)
|
|
{
|
|
if (!_layerIndexToTypeToID.ContainsKey(layer))
|
|
{
|
|
_layerOrder.Add(layer, layer);
|
|
_layerIndexToGeneralRenderers.Add(layer, new HashSet<GeneralRenderer>());
|
|
_layerIndexToTypeToID.Add(layer, new Dictionary<Type, HashSet<int>>());
|
|
}
|
|
}
|
|
|
|
public void RegisterOrderedDrawable<TComponent>() where TComponent : struct
|
|
{
|
|
if (!_typeToEntityToLayer.ContainsKey(typeof(TComponent)))
|
|
{
|
|
_typeToEntityToLayer.Add(typeof(TComponent), new Dictionary<int, int>(128));
|
|
}
|
|
|
|
foreach (var pair in _layerIndexToTypeToID)
|
|
{
|
|
if (!pair.Value.ContainsKey(typeof(TComponent)))
|
|
{
|
|
pair.Value.Add(typeof(TComponent), new HashSet<int>());
|
|
}
|
|
}
|
|
}
|
|
|
|
public void RegisterGeneralRendererWithLayer(GeneralRenderer renderer, int layer)
|
|
{
|
|
RegisterDrawLayer(layer);
|
|
var set = _layerIndexToGeneralRenderers[layer];
|
|
set.Add(renderer);
|
|
}
|
|
|
|
public void RegisterComponentWithLayer<TComponent>(int entityID, int layer) where TComponent : struct
|
|
{
|
|
if (!_layerIndexToTypeToID.ContainsKey(layer))
|
|
{
|
|
throw new UndefinedLayerException("Layer {0} is not defined. Use WorldBuilder.RegisterDrawLayer to register the layer.", layer);
|
|
}
|
|
|
|
if (_typeToEntityToLayer[typeof(TComponent)].ContainsKey(entityID))
|
|
{
|
|
if (_typeToEntityToLayer[typeof(TComponent)][entityID] != layer)
|
|
{
|
|
UnRegisterComponentWithLayer<TComponent>(entityID);
|
|
|
|
var set = _layerIndexToTypeToID[layer][typeof(TComponent)];
|
|
set.Add(entityID);
|
|
|
|
_typeToEntityToLayer[typeof(TComponent)].Add(entityID, layer);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
var set = _layerIndexToTypeToID[layer][typeof(TComponent)];
|
|
set.Add(entityID);
|
|
|
|
_typeToEntityToLayer[typeof(TComponent)].Add(entityID, layer);
|
|
}
|
|
}
|
|
|
|
public void UnRegisterComponentWithLayer<TComponent>(int entityID) where TComponent : struct
|
|
{
|
|
if (!_typeToEntityToLayer.ContainsKey(typeof(TComponent))) { return; }
|
|
|
|
if (_typeToEntityToLayer[typeof(TComponent)].ContainsKey(entityID))
|
|
{
|
|
var layer = _typeToEntityToLayer[typeof(TComponent)][entityID];
|
|
_layerIndexToTypeToID[layer][typeof(TComponent)].Remove(entityID);
|
|
}
|
|
_typeToEntityToLayer[typeof(TComponent)].Remove(entityID);
|
|
}
|
|
|
|
public void UnRegisterEntityWithLayer(int entityID)
|
|
{
|
|
foreach (var store in _layerIndexToTypeToID.Values)
|
|
{
|
|
foreach (var typeToSet in store)
|
|
{
|
|
var type = typeToSet.Key;
|
|
var set = typeToSet.Value;
|
|
|
|
if (set.Contains(entityID))
|
|
{
|
|
_typeToEntityToLayer[type].Remove(entityID);
|
|
set.Remove(entityID);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public IEnumerable<GeneralRenderer> GeneralRenderersByLayer(int layer)
|
|
{
|
|
return _layerIndexToGeneralRenderers.ContainsKey(layer) ?
|
|
_layerIndexToGeneralRenderers[layer] :
|
|
Enumerable.Empty<GeneralRenderer>();
|
|
}
|
|
|
|
public IEnumerable<(int, Type)> AllInLayer(int layer)
|
|
{
|
|
foreach (var kvp in _layerIndexToTypeToID[layer])
|
|
{
|
|
foreach (var id in kvp.Value)
|
|
{
|
|
yield return (id, kvp.Key);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|