TilemapLayerCollection.cs 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using MonoGame.Extended.Tiled;
  5. namespace MonoGame.Extended.Tilemaps
  6. {
  7. /// <summary>
  8. /// A collection of tilemap layers.
  9. /// </summary>
  10. public class TilemapLayerCollection : IReadOnlyList<TilemapLayer>
  11. {
  12. private readonly List<TilemapLayer> _layers = new();
  13. private readonly Dictionary<string, TilemapLayer> _layersByName = new();
  14. /// <summary>
  15. /// Gets the layer at the specified index.
  16. /// </summary>
  17. /// <param name="index">The zero-based index of the layer to get.</param>
  18. /// <returns>The layer at the specified index.</returns>
  19. public TilemapLayer this[int index]
  20. {
  21. get
  22. {
  23. return _layers[index];
  24. }
  25. }
  26. /// <summary>
  27. /// Gets the layer with the specified name.
  28. /// </summary>
  29. /// <param name="name">The name of the layer.</param>
  30. /// <returns>The layer with the specified name.</returns>
  31. /// <exception cref="KeyNotFoundException">No layer with the specified name was found.</exception>
  32. public TilemapLayer this[string name]
  33. {
  34. get
  35. {
  36. return _layersByName[name];
  37. }
  38. }
  39. /// <summary>
  40. /// Gets the number of layers in the collection.
  41. /// </summary>
  42. public int Count => _layers.Count;
  43. /// <summary>
  44. /// Adds a layer to the collection.
  45. /// </summary>
  46. /// <param name="layer">The layer to add.</param>
  47. /// <remarks>
  48. /// This method is not thread-safe. If multiple threads are accessing the collection,
  49. /// external synchronization is required.
  50. /// </remarks>
  51. public void Add(TilemapLayer layer)
  52. {
  53. if (layer == null)
  54. throw new ArgumentNullException(nameof(layer));
  55. _layers.Add(layer);
  56. _layersByName[layer.Name] = layer;
  57. }
  58. /// <summary>
  59. /// Removes a layer from the collection.
  60. /// </summary>
  61. /// <param name="layer">The layer to remove.</param>
  62. /// <returns><see langword="true"/> if the layer was removed; otherwise, <see langword="false"/>.</returns>
  63. /// <remarks>
  64. /// This is an O(n) operation. This method is not thread-safe.
  65. /// </remarks>
  66. public bool Remove(TilemapLayer layer)
  67. {
  68. if (layer == null)
  69. return false;
  70. var removed = _layers.Remove(layer);
  71. if (removed)
  72. _layersByName.Remove(layer.Name);
  73. return removed;
  74. }
  75. /// <summary>
  76. /// Removes all layers from the collection.
  77. /// </summary>
  78. /// <remarks>
  79. /// <strong>Warning:</strong> This operation cannot be undone and will remove all layer data.
  80. /// This method is not thread-safe.
  81. /// </remarks>
  82. public void Clear()
  83. {
  84. _layers.Clear();
  85. _layersByName.Clear();
  86. }
  87. /// <summary>
  88. /// Attempts to get the layer with the specified name.
  89. /// </summary>
  90. /// <param name="name">The name of the layer.</param>
  91. /// <param name="layer">
  92. /// When this method returns, contains the layer with the specified name,
  93. /// if found; otherwise, <see langword="null"/>.
  94. /// </param>
  95. /// <returns><see langword="true"/> if the layer was found; otherwise, <see langword="false"/>.</returns>
  96. public bool TryGetValue(string name, out TilemapLayer layer)
  97. {
  98. return _layersByName.TryGetValue(name, out layer);
  99. }
  100. /// <summary>
  101. /// Gets the layer with the specified name and type.
  102. /// </summary>
  103. /// <typeparam name="T">The type of layer to retrieve.</typeparam>
  104. /// <param name="name">The name of the layer.</param>
  105. /// <returns>The layer, or <see langword="null"/> if not found or not of the specified type.</returns>
  106. public T GetLayer<T>(string name) where T : TilemapLayer
  107. {
  108. if(_layersByName.TryGetValue(name, out var layer))
  109. {
  110. return layer as T;
  111. }
  112. return null;
  113. }
  114. /// <summary>
  115. /// Gets all layers of the specified type.
  116. /// </summary>
  117. /// <typeparam name="T">The type of layers to retrieve.</typeparam>
  118. /// <returns>An enumerable of layers of the specified type.</returns>
  119. public IEnumerable<T> GetLayers<T>() where T : TilemapLayer
  120. {
  121. for(int i = 0; i < _layers.Count; i++)
  122. {
  123. if(_layers[i] is T typed)
  124. {
  125. yield return typed;
  126. }
  127. }
  128. }
  129. /// <summary>
  130. /// Determines the index of a specific layer in the collection.
  131. /// </summary>
  132. /// <param name="layer">The layer to locate in the collection.</param>
  133. /// <returns>The index of the layer if found in the collection; otherwise, -1.</returns>
  134. public int IndexOf(TilemapLayer layer)
  135. {
  136. return _layers.IndexOf(layer);
  137. }
  138. public IEnumerator<TilemapLayer> GetEnumerator()
  139. {
  140. return _layers.GetEnumerator();
  141. }
  142. IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
  143. }
  144. }