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();
}
}