Files
project-entity/Assets/_Project/Develop/Runtime/Utilities/ReactiveManagement/Variable/ReactiveVariable.cs
2026-03-02 19:00:06 +05:00

62 lines
1.8 KiB
C#

using System;
using System.Collections.Generic;
namespace _Project.Develop.Runtime.Utils.ReactiveManagement
{
public class ReactiveVariable<T> : IReadOnlyVariable<T> where T : IEquatable<T>
{
private readonly List<Subscriber<T, T>> _subscribers = new List<Subscriber<T, T>>();
private readonly List<Subscriber<T, T>> _toAddList = new List<Subscriber<T, T>>();
private readonly List<Subscriber<T, T>> _toRemoveList = new List<Subscriber<T, T>>();
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<T, T> action)
{
Subscriber<T, T> subscriber = new Subscriber<T, T>(action, RemoveSubscriber);
_toAddList.Add(subscriber);
return subscriber;
}
private void RemoveSubscriber(Subscriber<T, T> 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<T, T> subscriber in _toRemoveList)
_subscribers.Remove(subscriber);
_toRemoveList.Clear();
}
foreach (Subscriber<T, T> subscriber in _subscribers)
subscriber.Invoke(oldValue, newValue);
}
}
}