using System.Collections.Generic; using System.ComponentModel; using System.Runtime.CompilerServices; namespace RGB.NET.Core; /// /// /// Represents a basic bindable class which notifies when a property value changes. /// public abstract class AbstractBindable : IBindable { #region Events /// /// Occurs when a property value changes. /// public event PropertyChangedEventHandler? PropertyChanged; #endregion #region Methods /// /// Checks if the property already matches the desired value or needs to be updated. /// /// Type of the property. /// Reference to the backing-filed. /// Value to apply. /// true if the value needs to be updated; otherwise false. [MethodImpl(MethodImplOptions.AggressiveInlining)] protected bool RequiresUpdate(ref T storage, T value) => !EqualityComparer.Default.Equals(storage, value); /// /// Checks if the property already matches the desired value and updates it if not. /// /// Type of the property. /// Reference to the backing-filed. /// Value to apply. /// Name of the property used to notify listeners. This value is optional /// and can be provided automatically when invoked from compilers that support . /// true if the value was changed, false if the existing value matched the desired value. protected bool SetProperty(ref T storage, T value, [CallerMemberName] string? propertyName = null) { if (!RequiresUpdate(ref storage, value)) return false; storage = value; // ReSharper disable once ExplicitCallerInfoArgument OnPropertyChanged(propertyName); return true; } /// /// Triggers the -event when a a property value has changed. /// /// Name of the property used to notify listeners. This value is optional /// and can be provided automatically when invoked from compilers that support . protected void OnPropertyChanged([CallerMemberName] string? propertyName = null) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); #endregion }