using System; using System.Collections.Generic; namespace _Project.Develop.Runtime.Utils.ReactiveManagement { public class ReactiveVariable : IReadOnlyVariable where T : IEquatable { private readonly List> _subscribers = new List>(); private readonly List> _toAddList = new List>(); private readonly List> _toRemoveList = new List>(); public ReactiveVariable() => _value = default(T); public ReactiveVariable(T value) => _value = value; private T _value; public T Value { get => _value; set { T oldValue = _value; _value = value; if (_value.Equals(oldValue) == false) Invoke(oldValue, _value); } } public IDisposable Subscribe(Action action) { Subscriber subscriber = new Subscriber(action, RemoveSubscriber); _toAddList.Add(subscriber); return subscriber; } private void RemoveSubscriber(Subscriber subscriber) => _toRemoveList.Add(subscriber); private void Invoke(T oldValue, T newValue) { if (_toAddList.Count > 0) { _subscribers.AddRange(_toAddList); _toAddList.Clear(); } if (_toRemoveList.Count > 0) { foreach (Subscriber subscriber in _toRemoveList) _subscribers.Remove(subscriber); _toRemoveList.Clear(); } foreach (Subscriber subscriber in _subscribers) subscriber.Invoke(oldValue, newValue); } } }