using GFramework.Core.Abstractions.events;
using GFramework.Core.Abstractions.property;
namespace GFramework.Core.property;
///
/// 可绑定属性类,用于实现数据绑定功能
///
/// 属性值的类型
/// 属性的默认值
public class BindableProperty(T defaultValue = default!) : IBindableProperty
{
private Action? _mOnValueChanged;
protected T MValue = defaultValue;
///
/// 获取或设置属性值比较器,默认使用Equals方法进行比较
///
public static Func Comparer { get; set; } = (a, b) => a!.Equals(b)!;
///
/// 获取或设置属性值,当值发生变化时会触发注册的回调事件
///
public T Value
{
get => GetValue();
set
{
// 使用 default(T) 替代 null 比较,避免 SonarQube 警告
if (EqualityComparer.Default.Equals(value, default!) &&
EqualityComparer.Default.Equals(MValue, default!))
return;
// 若新值与旧值相等则不执行后续操作
if (!EqualityComparer.Default.Equals(value, default!) && Comparer(value, MValue))
return;
SetValue(value);
_mOnValueChanged?.Invoke(value);
}
}
///
/// 直接设置属性值而不触发事件
///
/// 新的属性值
public void SetValueWithoutEvent(T newValue)
{
MValue = newValue;
}
///
/// 实现IEasyEvent接口的注册方法,将无参事件转换为有参事件处理
///
/// 无参事件回调
/// 可用于取消注册的接口
IUnRegister IEasyEvent.Register(Action onEvent)
{
return Register(Action);
void Action(T _)
{
onEvent();
}
}
///
/// 注册属性值变化事件回调
///
/// 属性值变化时的回调函数
/// 可用于取消注册的接口
public IUnRegister Register(Action onValueChanged)
{
_mOnValueChanged += onValueChanged;
return new BindablePropertyUnRegister(this, onValueChanged);
}
///
/// 注册属性值变化事件回调,并立即调用回调函数传递当前值
///
/// 属性值变化时的回调函数
/// 可用于取消注册的接口
public IUnRegister RegisterWithInitValue(Action action)
{
action(MValue);
return Register(action);
}
///
/// 取消注册属性值变化事件回调
///
/// 要取消注册的回调函数
public void UnRegister(Action onValueChanged)
{
_mOnValueChanged -= onValueChanged;
}
///
/// 设置自定义比较器
///
/// 用于比较两个值是否相等的函数
/// 当前可绑定属性实例
public BindableProperty WithComparer(Func comparer)
{
Comparer = comparer;
return this;
}
///
/// 设置属性值的虚方法,可在子类中重写
///
/// 新的属性值
protected virtual void SetValue(T newValue)
{
MValue = newValue;
}
///
/// 获取属性值的虚方法,可在子类中重写
///
/// 当前属性值
protected virtual T GetValue()
{
return MValue;
}
///
/// 返回属性值的字符串表示形式
///
/// 属性值的字符串表示
public override string ToString()
{
return Value?.ToString() ?? string.Empty;
}
}