using System; using UnityEngine; using UnityAtoms; namespace UnityAtoms.BaseAtoms { /// /// A Collection / Dictionary of Atom Variables (AtomBaseVariable). /// [CreateAssetMenu(menuName = "Unity Atoms/Collection", fileName = "Collection")] [EditorIcon("atom-icon-kingsyellow")] public class AtomCollection : AtomBaseVariable, IGetValue, IWithCollectionEvents { /// /// Get value as an `IAtomCollection`. Needed in order to inject Collection into the Variable Instancer class. /// /// The value as an `IAtomCollection`. public IAtomCollection GetValue() => this.Value; /// /// Event for when and item is added to the collection. /// public AtomBaseVariableEvent Added { get => _added; set => _added = value; } /// /// Event for when and item is removed from the collection. /// public AtomBaseVariableEvent Removed { get => _removed; set => _removed = value; } /// /// Event for when the collection is cleared. /// public VoidEvent Cleared { get => _cleared; set => _cleared = value; } [SerializeField] private AtomBaseVariableEvent _added; [SerializeField] private AtomBaseVariableEvent _removed; [SerializeField] private VoidEvent _cleared; void OnEnable() { if (Value == null) return; Value.Added += PropogateAdded; Value.Removed += PropogateRemoved; Value.Cleared += PropogateCleared; } void OnDisable() { if (Value == null) return; Value.Added -= PropogateAdded; Value.Removed -= PropogateRemoved; Value.Cleared -= PropogateCleared; } void PropogateAdded(AtomBaseVariable baseVariable) { if (_added == null) return; _added.Raise(baseVariable); } void PropogateRemoved(AtomBaseVariable baseVariable) { if (_removed == null) return; _removed.Raise(baseVariable); } void PropogateCleared() { if (_cleared == null) return; _cleared.Raise(); } #region Observable /// /// Make the add event into an `IObservable<T>`. Makes Collection's add Event compatible with for example UniRx. /// /// The add Event as an `IObservable<T>`. public IObservable ObserveAdd() { if (Added == null) { throw new Exception("You must assign an Added event in order to observe when adding to the collection."); } return new ObservableEvent(Added.Register, Added.Unregister); } /// /// Make the remove event into an `IObservable<T>`. Makes Collection's remove Event compatible with for example UniRx. /// /// The remove Event as an `IObservable<T>`. public IObservable ObserveRemove() { if (Removed == null) { throw new Exception("You must assign a Removed event in order to observe when removing from the collection."); } return new ObservableEvent(Removed.Register, Removed.Unregister); } /// /// Make the clear event into an `IObservable<Void>`. Makes Collection's clear Event compatible with for example UniRx. /// /// The clear Event as an `IObservable<Void>`. public IObservable ObserveClear() { if (Cleared == null) { throw new Exception("You must assign a Cleared event in order to observe when clearing the collection."); } return new ObservableVoidEvent(Cleared.Register, Cleared.Unregister); } #endregion // Observable } }