using System; using System.Collections; using System.Collections.Generic; using MonoGame.Extended.Tiled; namespace MonoGame.Extended.Tilemaps { /// /// A collection of tilemap layers. /// public class TilemapLayerCollection : IReadOnlyList { private readonly List _layers = new(); private readonly Dictionary _layersByName = new(); /// /// Gets the layer at the specified index. /// /// The zero-based index of the layer to get. /// The layer at the specified index. public TilemapLayer this[int index] { get { return _layers[index]; } } /// /// Gets the layer with the specified name. /// /// The name of the layer. /// The layer with the specified name. /// No layer with the specified name was found. public TilemapLayer this[string name] { get { return _layersByName[name]; } } /// /// Gets the number of layers in the collection. /// public int Count => _layers.Count; /// /// Adds a layer to the collection. /// /// The layer to add. /// /// This method is not thread-safe. If multiple threads are accessing the collection, /// external synchronization is required. /// public void Add(TilemapLayer layer) { if (layer == null) throw new ArgumentNullException(nameof(layer)); _layers.Add(layer); _layersByName[layer.Name] = layer; } /// /// Removes a layer from the collection. /// /// The layer to remove. /// if the layer was removed; otherwise, . /// /// This is an O(n) operation. This method is not thread-safe. /// public bool Remove(TilemapLayer layer) { if (layer == null) return false; var removed = _layers.Remove(layer); if (removed) _layersByName.Remove(layer.Name); return removed; } /// /// Removes all layers from the collection. /// /// /// Warning: This operation cannot be undone and will remove all layer data. /// This method is not thread-safe. /// public void Clear() { _layers.Clear(); _layersByName.Clear(); } /// /// Attempts to get the layer with the specified name. /// /// The name of the layer. /// /// When this method returns, contains the layer with the specified name, /// if found; otherwise, . /// /// if the layer was found; otherwise, . public bool TryGetValue(string name, out TilemapLayer layer) { return _layersByName.TryGetValue(name, out layer); } /// /// Gets the layer with the specified name and type. /// /// The type of layer to retrieve. /// The name of the layer. /// The layer, or if not found or not of the specified type. public T GetLayer(string name) where T : TilemapLayer { if(_layersByName.TryGetValue(name, out var layer)) { return layer as T; } return null; } /// /// Gets all layers of the specified type. /// /// The type of layers to retrieve. /// An enumerable of layers of the specified type. public IEnumerable GetLayers() where T : TilemapLayer { for(int i = 0; i < _layers.Count; i++) { if(_layers[i] is T typed) { yield return typed; } } } /// /// Determines the index of a specific layer in the collection. /// /// The layer to locate in the collection. /// The index of the layer if found in the collection; otherwise, -1. public int IndexOf(TilemapLayer layer) { return _layers.IndexOf(layer); } public IEnumerator GetEnumerator() { return _layers.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); } }