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