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