namespace Zinnia.Data.Collection.Counter { using System.Collections.Generic; using UnityEngine; using UnityEngine.Events; using Zinnia.Extension; /// /// Allows counting the amount of attempts an element is added or removed from a . /// /// The type of the elements to count. /// The type to use. public class ObservableCounter : MonoBehaviour where TEvent : UnityEvent, new() { /// /// Emitted when an element is added for the first time. /// public TEvent Added = new TEvent(); /// /// Emitted when an element is removed completely. /// public TEvent Removed = new TEvent(); /// /// The elements being counted. /// public Dictionary ElementsCounter { get; protected set; } = new Dictionary(); /// /// Increases the count of the given element. /// /// The element to count. public virtual void IncreaseCount(TElement element) { if (!this.IsValidState() || EqualityComparer.Default.Equals(element, default)) { return; } if (ElementsCounter.ContainsKey(element)) { ElementsCounter[element]++; } else { ElementsCounter.Add(element, 1); Added?.Invoke(element); } } /// /// Decreases the count of the given element. /// /// The element to count. public virtual void DecreaseCount(TElement element) { if (!this.IsValidState() || EqualityComparer.Default.Equals(element, default)) { return; } if (!ElementsCounter.TryGetValue(element, out int counter)) { return; } counter--; ElementsCounter[element] = counter; if (counter > 0) { return; } ElementsCounter.Remove(element); Removed?.Invoke(element); } /// /// Removes the element from the counter. /// /// The element to clear. public virtual void RemoveFromCount(TElement element) { if (!this.IsValidState() || EqualityComparer.Default.Equals(element, default) || !ElementsCounter.Remove(element)) { return; } Removed?.Invoke(element); } /// /// Clears all elements from the counter. /// public virtual void Clear() { if (!this.IsValidState()) { return; } foreach (TElement element in ElementsCounter.Keys) { if (!EqualityComparer.Default.Equals(element, default)) { Removed?.Invoke(element); } } ElementsCounter.Clear(); } /// /// How often an element was added to the counter without being removed. /// /// The element to check. /// The count of the given element. public virtual int GetCount(TElement element) { ElementsCounter.TryGetValue(element, out int countValue); return countValue; } } }