using System; using System.Collections; using System.Collections.Generic; using UnityEngine; namespace Stary.Evo { public interface IBindableProperty : IReadonlyBindableProperty { new T Value { get; set; } void SetValueWithoutEvent(T newValue); } public interface IReadonlyBindableProperty { T Value { get; } IUnRegister RegisterWithInitValue(Action action); void UnRegister(Action onValueChanged); IUnRegister Register(Action onValueChanged); } public class BindableProperty : IBindableProperty { public BindableProperty(T defaultValue = default) { mValue = defaultValue; } protected T mValue; public T Value { get => GetValue(); set { if (value == null && mValue == null) return; if (value != null && value.Equals(mValue)) return; SetValue(value); mOnValueChanged?.Invoke(value); } } protected virtual void SetValue(T newValue) { mValue = newValue; } protected virtual T GetValue() { return mValue; } public void SetValueWithoutEvent(T newValue) { mValue = newValue; } private Action mOnValueChanged = (v) => { }; public IUnRegister Register(Action onValueChanged) { mOnValueChanged += onValueChanged; return new BindablePropertyUnRegister() { BindableProperty = this, OnValueChanged = onValueChanged }; } public IUnRegister RegisterWithInitValue(Action onValueChanged) { onValueChanged(mValue); return Register(onValueChanged); } public static implicit operator T(BindableProperty property) { return property.Value; } public override string ToString() { return Value.ToString(); } public void UnRegister(Action onValueChanged) { mOnValueChanged -= onValueChanged; } } public class BindablePropertyUnRegister : IUnRegister { public BindableProperty BindableProperty { get; set; } public Action OnValueChanged { get; set; } public void UnRegister() { BindableProperty.UnRegister(OnValueChanged); BindableProperty = null; OnValueChanged = null; } } }