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); public IEnumerable LayerOrder { get { return layerOrder.Values; } } public DrawLayerManager() { 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()); } } 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(Entity entity, 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(entity)) { UnRegisterComponentWithLayer(entity); } var set = layerIndexToComponentStore[layer]; set.Set(entity, component); typeToEntityToLayer[typeof(TComponent)].Add(entity, layer); } public void UnRegisterComponentWithLayer(Entity entity) where TComponent : struct, IComponent { if (!typeToEntityToLayer.ContainsKey(typeof(TComponent))) { return; } if (typeToEntityToLayer[typeof(TComponent)].ContainsKey(entity)) { var layer = typeToEntityToLayer[typeof(TComponent)][entity]; layerIndexToComponentStore[layer].Remove(entity); } typeToEntityToLayer[typeof(TComponent)].Remove(entity); } public void UnRegisterEntityWithLayer(Entity entity) { foreach (var store in layerIndexToComponentStore.Values) { store.Remove(entity); } } public IEnumerable GeneralRenderersByLayer(int layer) { return layerIndexToGeneralRenderers.ContainsKey(layer) ? layerIndexToGeneralRenderers[layer] : Enumerable.Empty(); } public IEnumerable<(Entity, Type, IComponent)> AllInLayer(int layer) { return layerIndexToComponentStore.ContainsKey(layer) ? layerIndexToComponentStore[layer].AllInterfaceTyped() : Enumerable.Empty<(Entity, Type, IComponent)>(); } } }