using System.Collections.Generic; using System.ComponentModel; using System.Linq; namespace RemSox.Utils; public abstract class ChangedPropertiesTracker : INotifyPropertyChanged { private readonly Dictionary properties = []; private readonly HashSet changedPropertyNames = []; public IReadOnlyDictionary ChangedProperties { get { var changes = new Dictionary(); foreach (var name in changedPropertyNames) { if (properties.TryGetValue(name, out var value)) { changes[name] = value; } } return changes; } } public IReadOnlyDictionary AllProperties => properties; public event PropertyChangedEventHandler? PropertyChanged; public bool AnyPropertyChanged => changedPropertyNames.Count > 0; protected void SetProperty(string name, ref T field, T value) { if (!EqualityComparer.Default.Equals(field, value)) { field = value; properties[name] = value; changedPropertyNames.Add(name); PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name)); } } public void ClearChangedProperties() => changedPropertyNames.Clear(); public bool IsPropertyChanged(string name) => changedPropertyNames.Contains(name); }