From b748be07de87c970e5eecd04b68bdb7cf978a056 Mon Sep 17 00:00:00 2001 From: Will Bennion Date: Wed, 6 May 2020 14:59:46 +0100 Subject: [PATCH] Added the PropertyChanged Fody weaver. Removed NotifyPropertyChangedEx. --- .../Project-Aurora/ConfigUI.xaml.cs | 2 + .../Controls/GameStateParameterPicker.xaml.cs | 2 + Project-Aurora/Project-Aurora/FodyWeavers.xml | 3 + Project-Aurora/Project-Aurora/FodyWeavers.xsd | 64 +++++++++ .../Project-Aurora/Profiles/Application.cs | 43 ++----- .../EliteDangerous/EliteDangerousSettings.cs | 4 +- .../GenericApplicationSettings.cs | 11 +- .../Profiles/LightingStateManager.cs | 13 +- .../Project-Aurora/Project-Aurora.csproj | 9 +- .../Settings/ApplicationProfile.cs | 121 +++++------------- .../Settings/ApplicationSettings.cs | 42 ++---- .../Project-Aurora/Settings/Configuration.cs | 78 ++++------- .../Settings/Control_LayerList.xaml.cs | 2 + .../Settings/Control_ProfileManager.xaml.cs | 3 +- .../Settings/INotifyPropertyChangedEx.cs | 43 ------- .../Settings/Layers/AmbilightLayerHandler.cs | 2 + .../Layers/ParticleLayerHandlerBase.cs | 5 - .../Settings/Layers/ScriptLayerHandler.cs | 17 +-- .../Layers/SimpleParticleLayerHandler.cs | 65 ++++------ .../Overrides/Control_OverridesEditor.xaml.cs | 2 + .../Logic/Boolean/Boolean_ProcessRunning.cs | 4 +- .../Project-Aurora/Settings/PluginManager.cs | 3 +- .../Project-Aurora/Utils/GenericUtils.cs | 12 +- .../Utils/ObservableConcurrentDictionary.cs | 2 + 24 files changed, 211 insertions(+), 341 deletions(-) create mode 100644 Project-Aurora/Project-Aurora/FodyWeavers.xml create mode 100644 Project-Aurora/Project-Aurora/FodyWeavers.xsd delete mode 100644 Project-Aurora/Project-Aurora/Settings/INotifyPropertyChangedEx.cs diff --git a/Project-Aurora/Project-Aurora/ConfigUI.xaml.cs b/Project-Aurora/Project-Aurora/ConfigUI.xaml.cs index 13264ecb8..ee165ba2b 100755 --- a/Project-Aurora/Project-Aurora/ConfigUI.xaml.cs +++ b/Project-Aurora/Project-Aurora/ConfigUI.xaml.cs @@ -22,9 +22,11 @@ using System.Collections.ObjectModel; using System.ComponentModel; using System.Runtime.CompilerServices; +using PropertyChanged; namespace Aurora { + [DoNotNotify] partial class ConfigUI : Window, INotifyPropertyChanged { Control_Settings settingsControl = new Control_Settings(); diff --git a/Project-Aurora/Project-Aurora/Controls/GameStateParameterPicker.xaml.cs b/Project-Aurora/Project-Aurora/Controls/GameStateParameterPicker.xaml.cs index 9db498c68..e0e6e1da3 100644 --- a/Project-Aurora/Project-Aurora/Controls/GameStateParameterPicker.xaml.cs +++ b/Project-Aurora/Project-Aurora/Controls/GameStateParameterPicker.xaml.cs @@ -1,5 +1,6 @@ using Aurora.Profiles; using Aurora.Utils; +using PropertyChanged; using System; using System.Collections.Generic; using System.ComponentModel; @@ -14,6 +15,7 @@ namespace Aurora.Controls { + [DoNotNotify] public partial class GameStateParameterPicker : UserControl, INotifyPropertyChanged { public event EventHandler SelectedPathChanged; diff --git a/Project-Aurora/Project-Aurora/FodyWeavers.xml b/Project-Aurora/Project-Aurora/FodyWeavers.xml new file mode 100644 index 000000000..d5abfed81 --- /dev/null +++ b/Project-Aurora/Project-Aurora/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/Project-Aurora/Project-Aurora/FodyWeavers.xsd b/Project-Aurora/Project-Aurora/FodyWeavers.xsd new file mode 100644 index 000000000..221aeb8a5 --- /dev/null +++ b/Project-Aurora/Project-Aurora/FodyWeavers.xsd @@ -0,0 +1,64 @@ + + + + + + + + + + + Used to control if the On_PropertyName_Changed feature is enabled. + + + + + Used to change the name of the method that fires the notify event. This is a string that accepts multiple values in a comma separated form. + + + + + Used to control if equality checks should be inserted. If false, equality checking will be disabled for the project. + + + + + Used to control if equality checks should use the Equals method resolved from the base class. + + + + + Used to control if equality checks should use the static Equals method resolved from the base class. + + + + + Used to turn off build warnings from this weaver. + + + + + Used to turn off build warnings about mismatched On_PropertyName_Changed methods. + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/Project-Aurora/Project-Aurora/Profiles/Application.cs b/Project-Aurora/Project-Aurora/Profiles/Application.cs index f6dc1c7d0..8c5b51dad 100755 --- a/Project-Aurora/Project-Aurora/Profiles/Application.cs +++ b/Project-Aurora/Project-Aurora/Profiles/Application.cs @@ -17,12 +17,12 @@ using Newtonsoft.Json.Serialization; using System.Collections.ObjectModel; using Aurora.Settings; +using System.ComponentModel; namespace Aurora.Profiles { - public class LightEventConfig : NotifyPropertyChangedEx + public class LightEventConfig : INotifyPropertyChanged { - //TODO: Add NotifyPropertyChanged to properties public string[] ProcessNames { get; set; } /// One or more REGULAR EXPRESSIONS that can be used to match the title of an application @@ -50,24 +50,15 @@ public class LightEventConfig : NotifyPropertyChangedEx public HashSet ExtraAvailableLayers { get; set; } = new HashSet(); - protected LightEventType? type = LightEventType.Normal; - public LightEventType? Type - { - get { return type; } - set - { - object old = type; - object newVal = value; - type = value; - InvokePropertyChanged(old, newVal); - } - } + public LightEventType? Type { get; set; } = LightEventType.Normal; public bool EnableByDefault { get; set; } = true; public bool EnableOverlaysByDefault { get; set; } = true; + + public event PropertyChangedEventHandler PropertyChanged; } - public class Application : ObjectSettings, IInit, ILightEvent, IDisposable + public class Application : ObjectSettings, IInit, ILightEvent, INotifyPropertyChanged, IDisposable { #region Public Properties public bool Initialized { get; protected set; } = false; @@ -83,19 +74,7 @@ public class Application : ObjectSettings, IInit, ILightEve public Type GameStateType { get { return Config.GameStateType; } } public bool IsEnabled { get { return Settings.IsEnabled; } } public bool IsOverlayEnabled { get { return Settings.IsOverlayEnabled; } } - public event PropertyChangedExEventHandler PropertyChanged; - protected LightEventType type; - public LightEventType Type - { - get { return type; } - protected set - { - object old = type; - object newVal = value; - type = value; - InvokePropertyChanged(old, newVal); - } - } + public LightEventType Type { get; set; } #endregion #region Internal Properties @@ -108,8 +87,7 @@ protected set internal Dictionary EffectScripts { get; set; } #endregion - #region Private Fields/Properties - #endregion + public event PropertyChangedEventHandler PropertyChanged; public Application(LightEventConfig config) { @@ -147,11 +125,6 @@ protected override void SettingsCreateHook() { Settings.IsOverlayEnabled = Config.EnableOverlaysByDefault; } - protected void InvokePropertyChanged(object oldValue, object newValue, [CallerMemberName] string propertyName = null) - { - PropertyChanged?.Invoke(this, new PropertyChangedExEventArgs(propertyName, oldValue, newValue)); - } - public void SwitchToProfile(ApplicationProfile newProfileSettings) { if (Disposed) diff --git a/Project-Aurora/Project-Aurora/Profiles/EliteDangerous/EliteDangerousSettings.cs b/Project-Aurora/Project-Aurora/Profiles/EliteDangerous/EliteDangerousSettings.cs index 7bb3e476d..f582debc5 100644 --- a/Project-Aurora/Project-Aurora/Profiles/EliteDangerous/EliteDangerousSettings.cs +++ b/Project-Aurora/Project-Aurora/Profiles/EliteDangerous/EliteDangerousSettings.cs @@ -4,8 +4,6 @@ namespace Aurora.Profiles.EliteDangerous { public class EliteDangerousSettings : FirstTimeApplicationSettings { - private string gamePath = ""; - - public string GamePath { get { return gamePath; } set { gamePath = value; InvokePropertyChanged(); } } + public string GamePath { get; set; } = ""; } } \ No newline at end of file diff --git a/Project-Aurora/Project-Aurora/Profiles/Generic_Application/GenericApplicationSettings.cs b/Project-Aurora/Project-Aurora/Profiles/Generic_Application/GenericApplicationSettings.cs index 21d38ae50..3c38be09c 100644 --- a/Project-Aurora/Project-Aurora/Profiles/Generic_Application/GenericApplicationSettings.cs +++ b/Project-Aurora/Project-Aurora/Profiles/Generic_Application/GenericApplicationSettings.cs @@ -9,13 +9,7 @@ namespace Aurora.Profiles.Generic_Application { public class GenericApplicationSettings : ApplicationSettings { - #region Private Properties - private string applicationName = "New Application Profile"; - #endregion - - #region Public Properties - public string ApplicationName { get { return applicationName; } set { applicationName = value; InvokePropertyChanged(); } } - #endregion + public string ApplicationName { get; set; } = "New Application Profile"; public GenericApplicationSettings() { @@ -24,8 +18,7 @@ public GenericApplicationSettings() public GenericApplicationSettings(string appname) : base() { - applicationName = appname; + ApplicationName = appname; } - } } diff --git a/Project-Aurora/Project-Aurora/Profiles/LightingStateManager.cs b/Project-Aurora/Project-Aurora/Profiles/LightingStateManager.cs index eecddc593..a5878cff5 100755 --- a/Project-Aurora/Project-Aurora/Profiles/LightingStateManager.cs +++ b/Project-Aurora/Project-Aurora/Profiles/LightingStateManager.cs @@ -21,6 +21,7 @@ using System.Windows; using System.Windows.Data; using System.Globalization; +using System.ComponentModel; namespace Aurora.Profiles { @@ -307,19 +308,11 @@ private bool InsertLightEvent(ILightEvent lightEvent, LightEventType? old = null return true; } - private void LightEvent_PropertyChanged(object sender, PropertyChangedExEventArgs e) + private void LightEvent_PropertyChanged(object sender, PropertyChangedEventArgs e) { ILightEvent lightEvent = (ILightEvent)sender; if (e.PropertyName.Equals(nameof(LightEventConfig.Type))) - { - LightEventType old = (LightEventType)e.OldValue; - LightEventType newVal = (LightEventType)e.NewValue; - - if (!old.Equals(newVal)) - { - InsertLightEvent(lightEvent, old); - } - } + InsertLightEvent(lightEvent); } public bool RegisterEvent(ILightEvent @event) diff --git a/Project-Aurora/Project-Aurora/Project-Aurora.csproj b/Project-Aurora/Project-Aurora/Project-Aurora.csproj index 931376966..fa289e692 100644 --- a/Project-Aurora/Project-Aurora/Project-Aurora.csproj +++ b/Project-Aurora/Project-Aurora/Project-Aurora.csproj @@ -924,7 +924,6 @@ Control_ScriptManager.xaml - Control_GlitchLayer.xaml @@ -2527,6 +2526,11 @@ 1.13.7 + + 6.1.1 + runtime; build; native; contentfiles; analyzers; buildtransitive + all + 3.2.46 @@ -2551,6 +2555,9 @@ 0.47.0 + + 3.2.8 + 0.1.32 diff --git a/Project-Aurora/Project-Aurora/Settings/ApplicationProfile.cs b/Project-Aurora/Project-Aurora/Settings/ApplicationProfile.cs index 4f43525b4..3badae7cb 100755 --- a/Project-Aurora/Project-Aurora/Settings/ApplicationProfile.cs +++ b/Project-Aurora/Project-Aurora/Settings/ApplicationProfile.cs @@ -1,6 +1,9 @@ using Aurora.Settings; using Aurora.Settings.Layers; +using Aurora.Utils; +using Microsoft.Scripting.Utils; using Newtonsoft.Json; +using PropertyChanged; using System; using System.Collections.Generic; using System.Collections.ObjectModel; @@ -9,125 +12,69 @@ namespace Aurora.Settings { - public abstract class Settings : INotifyPropertyChanged, ICloneable - { - public event PropertyChangedEventHandler PropertyChanged; - - protected void InvokePropertyChanged([CallerMemberName] string propertyName = null) - { - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); - } - public object Clone() - { - string str = JsonConvert.SerializeObject(this, Formatting.None, new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All, Binder = Aurora.Utils.JSONUtils.SerializationBinder }); - - return JsonConvert.DeserializeObject( - str, - this.GetType(), - new JsonSerializerSettings { ObjectCreationHandling = ObjectCreationHandling.Replace, TypeNameHandling = TypeNameHandling.All, Binder = Aurora.Utils.JSONUtils.SerializationBinder } - ); - } - } - - public class ScriptSettings : Settings + public class ScriptSettings : INotifyPropertyChanged { - #region Private Properties - private KeySequence _Keys; - - private bool _Enabled = false; - - private bool _ExceptionHit = false; - - private Exception _Exception = null; - #endregion - - #region Public Properties - public KeySequence Keys { get { return _Keys; } set { _Keys = value; InvokePropertyChanged(); } } - - public bool Enabled { get { return _Enabled; } - set { - _Enabled = value; - if (value) - { - ExceptionHit = false; - Exception = null; - } - InvokePropertyChanged(); - } - } - - [JsonIgnore] - public bool ExceptionHit { get { return _ExceptionHit; } set { _ExceptionHit = value; InvokePropertyChanged(); } } + public event PropertyChangedEventHandler PropertyChanged; - [JsonIgnore] - public Exception Exception { get { return _Exception; } set { _Exception = value; InvokePropertyChanged(); } } - #endregion + public KeySequence Keys { get; set; } + [OnChangedMethod(nameof(OnEnabledChanged))] public bool Enabled { get; set; } + [JsonIgnore] public bool ExceptionHit { get; set; } + [JsonIgnore] public Exception Exception { get; set; } public ScriptSettings(dynamic script) { if (script?.DefaultKeys != null && script?.DefaultKeys is KeySequence) Keys = script.DefaultKeys; } + + private void OnEnabledChanged() { + if (Enabled) { + ExceptionHit = false; + Exception = null; + } + } } - public class ApplicationProfile : Settings, IDisposable + public class ApplicationProfile : INotifyPropertyChanged, IDisposable { - #region Private Properties - private string _ProfileName = ""; - - private Keybind _triggerKeybind; - - private Dictionary _ScriptSettings; - - private ObservableCollection _Layers; - - private ObservableCollection _OverlayLayers; - #endregion - - #region Public Properties - public string ProfileName { get => _ProfileName; set { _ProfileName = value; InvokePropertyChanged(); } } - - public Keybind TriggerKeybind { get => _triggerKeybind; set { _triggerKeybind = value; InvokePropertyChanged(); } } - - [JsonIgnore] - public string ProfileFilepath { get; set; } - - public Dictionary ScriptSettings { get => _ScriptSettings; set { _ScriptSettings = value; InvokePropertyChanged(); } } - - public ObservableCollection Layers { get => _Layers; set { _Layers = value; InvokePropertyChanged(); } } - - public ObservableCollection OverlayLayers { get => _OverlayLayers; set { _OverlayLayers = value; InvokePropertyChanged(); } } - #endregion + public string ProfileName { get; set; } + public Keybind TriggerKeybind { get; set; } + [JsonIgnore] public string ProfileFilepath { get; set; } + public Dictionary ScriptSettings { get; set; } + public ObservableCollection Layers { get; set; } + public ObservableCollection OverlayLayers { get; set; } public ApplicationProfile() { this.Reset(); } + public event PropertyChangedEventHandler PropertyChanged; + public virtual void Reset() { - _Layers = new ObservableCollection(); - _OverlayLayers = new ObservableCollection(); - _ScriptSettings = new Dictionary(); - _triggerKeybind = new Keybind(); + Layers = new ObservableCollection(); + OverlayLayers = new ObservableCollection(); + ScriptSettings = new Dictionary(); + TriggerKeybind = new Keybind(); } - public virtual void SetApplication(Aurora.Profiles.Application app) + public virtual void SetApplication(Profiles.Application app) { - foreach (Layer l in _Layers) + foreach (Layer l in Layers) l.SetProfile(app); - foreach (Layer l in _OverlayLayers) + foreach (Layer l in OverlayLayers) l.SetProfile(app); } public virtual void Dispose() { - foreach (Layer l in _Layers) + foreach (Layer l in Layers) l.Dispose(); - foreach (Layer l in _OverlayLayers) + foreach (Layer l in OverlayLayers) l.Dispose(); } } diff --git a/Project-Aurora/Project-Aurora/Settings/ApplicationSettings.cs b/Project-Aurora/Project-Aurora/Settings/ApplicationSettings.cs index 3e35ce28f..6464df7e3 100644 --- a/Project-Aurora/Project-Aurora/Settings/ApplicationSettings.cs +++ b/Project-Aurora/Project-Aurora/Settings/ApplicationSettings.cs @@ -1,50 +1,28 @@ using System; using System.Collections.Generic; +using System.ComponentModel; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Aurora.Settings { - public class ApplicationSettings : Settings + public class ApplicationSettings : INotifyPropertyChanged { - #region Private Properties - private bool isEnabled = true; - private bool isOverlayEnabled = true; + public bool IsEnabled { get; set; } = true; + public bool IsOverlayEnabled { get; set; } = true; + public bool Hidden { get; set; } = false; + public string SelectedProfile { get; set; } = "default"; - private bool hidden = false; + public event PropertyChangedEventHandler PropertyChanged; - private string selectedProfile = "default"; - #endregion - - #region Public Properties - public bool IsEnabled { get { return isEnabled; } set { isEnabled = value; InvokePropertyChanged(); } } - public bool IsOverlayEnabled { get { return isOverlayEnabled; } set { isOverlayEnabled = value; InvokePropertyChanged(); } } - - public bool Hidden { get { return hidden; } set { hidden = value; InvokePropertyChanged(); } } - - public string SelectedProfile { get { return selectedProfile; } set { selectedProfile = value; InvokePropertyChanged(); } } - #endregion - - public ApplicationSettings() - { - - } + public ApplicationSettings() { } } public class FirstTimeApplicationSettings : ApplicationSettings { - #region Private Properties - private bool isFirstTimeInstalled = false; - #endregion - - #region Public Properties - public bool IsFirstTimeInstalled { get { return isFirstTimeInstalled; } set { isFirstTimeInstalled = value; InvokePropertyChanged(); } } - #endregion - - public FirstTimeApplicationSettings() - { + public bool IsFirstTimeInstalled { get; set; } - } + public FirstTimeApplicationSettings() { } } } diff --git a/Project-Aurora/Project-Aurora/Settings/Configuration.cs b/Project-Aurora/Project-Aurora/Settings/Configuration.cs index e748f0528..b31745419 100755 --- a/Project-Aurora/Project-Aurora/Settings/Configuration.cs +++ b/Project-Aurora/Project-Aurora/Settings/Configuration.cs @@ -386,8 +386,10 @@ public enum BitmapAccuracy Fine = 12 } - public class Configuration : Settings + public class Configuration : INotifyPropertyChanged { + public event PropertyChangedEventHandler PropertyChanged; + //First Time Installs public bool redist_first_time; public bool logitech_first_time; @@ -402,36 +404,23 @@ public class Configuration : Settings public bool allow_wrappers_in_background; public bool allow_all_logitech_bitmaps; - private bool useVolumeAsBrightness = false; - [JsonProperty(PropertyName = "use_volume_as_brightness")] - public bool UseVolumeAsBrightness { get { return useVolumeAsBrightness; } set { useVolumeAsBrightness = value; InvokePropertyChanged(); } } - - private float globalBrightness = 1.0f; - [JsonProperty(PropertyName = "global_brightness")] - public float GlobalBrightness { get { return globalBrightness; } set { globalBrightness = value; InvokePropertyChanged(); } } - - private float keyboardBrightness = 1.0f; - [JsonProperty(PropertyName = "keyboard_brightness_modifier")] - public float KeyboardBrightness { get { return keyboardBrightness; } set { keyboardBrightness = value; InvokePropertyChanged(); } } - - private float peripheralBrightness = 1.0f; - [JsonProperty(PropertyName = "peripheral_brightness_modifier")] - public float PeripheralBrightness { get { return peripheralBrightness; } set { peripheralBrightness = value; InvokePropertyChanged(); } } - - private bool getDevReleases = false; - public bool GetDevReleases { get { return getDevReleases; } set { getDevReleases = value; InvokePropertyChanged(); } } + [JsonProperty("use_volume_as_brightness")] + public bool UseVolumeAsBrightness { get; set; } - private bool getPointerUpdates = true; - public bool GetPointerUpdates { get { return getPointerUpdates; } set { getPointerUpdates = value; InvokePropertyChanged(); } } + [JsonProperty("global_brightness")] + public float GlobalBrightness { get; set; } = 1.0f; - private bool highPriority = false; - public bool HighPriority { get { return highPriority; } set { highPriority = value; InvokePropertyChanged(); } } + [JsonProperty("keyboard_brightness_modifier")] + public float KeyboardBrightness { get; set; } = 1.0f; - private BitmapAccuracy bitmapAccuracy = BitmapAccuracy.Okay; - public BitmapAccuracy BitmapAccuracy { get { return bitmapAccuracy; } set { bitmapAccuracy = value; InvokePropertyChanged(); } } + [JsonProperty("peripheral_brightness_modifier")] + public float PeripheralBrightness { get; set; } = 1.0f; - private bool enableAudioCapture; - public bool EnableAudioCapture { get => enableAudioCapture; set { enableAudioCapture = value; InvokePropertyChanged(); } } + public bool GetDevReleases { get; set; } = false; + public bool GetPointerUpdates { get; set; } = true; + public bool HighPriority { get; set; } = false; + public BitmapAccuracy BitmapAccuracy { get; set; } = BitmapAccuracy.Okay; + public bool EnableAudioCapture { get; set; } = false; public bool updates_check_on_start_up; public bool start_silently; @@ -479,27 +468,16 @@ public class Configuration : Settings public VariableRegistry VarRegistry; //BitmapDebug Data - private bool bitmapDebugTopMost; - public bool BitmapDebugTopMost { get { return bitmapDebugTopMost; } set { bitmapDebugTopMost = value; InvokePropertyChanged(); } } - - private WINDOWPLACEMENT bitmapPlacement; - public WINDOWPLACEMENT BitmapPlacement { get { return bitmapPlacement; } set { bitmapPlacement = value; InvokePropertyChanged(); } } - - private bool bitmapWindowOnStartUp; - public bool BitmapWindowOnStartUp { get { return bitmapWindowOnStartUp; } set { bitmapWindowOnStartUp = value; InvokePropertyChanged(); } } + public bool BitmapDebugTopMost { get; set; } = false; + public WINDOWPLACEMENT BitmapPlacement { get; set; } + public bool BitmapWindowOnStartUp { get; set; } = false; //httpDebug Data - private bool httpDebugTopMost; - public bool HttpDebugTopMost { get { return httpDebugTopMost; } set { httpDebugTopMost = value; InvokePropertyChanged(); } } - - private WINDOWPLACEMENT httpDebugPlacement; - public WINDOWPLACEMENT HttpDebugPlacement { get { return httpDebugPlacement; } set { httpDebugPlacement = value; InvokePropertyChanged(); } } - - private bool httpWindowOnStartUp; - public bool HttpWindowOnStartUp { get { return httpWindowOnStartUp; } set { httpWindowOnStartUp = value; InvokePropertyChanged(); } } + public bool HttpDebugTopMost { get; set; } = false; + public WINDOWPLACEMENT HttpDebugPlacement { get; set; } + public bool HttpWindowOnStartUp { get; set; } = false; - private ObservableConcurrentDictionary evaluatableTemplates; - public ObservableConcurrentDictionary EvaluatableTemplates { get => evaluatableTemplates; set { evaluatableTemplates = value; InvokePropertyChanged(); } } + public ObservableConcurrentDictionary EvaluatableTemplates { get; set; } = new ObservableConcurrentDictionary(); public List ProfileOrder { get; set; } = new List(); @@ -520,7 +498,7 @@ public Configuration() allow_all_logitech_bitmaps = true; GlobalBrightness = 1.0f; KeyboardBrightness = 1.0f; - peripheralBrightness = 1.0f; + PeripheralBrightness = 1.0f; updates_check_on_start_up = true; start_silently = false; close_mode = AppExitMode.Ask; @@ -567,14 +545,14 @@ public Configuration() HardwareMonitorUpdateRate = 200; //Debug - bitmapDebugTopMost = false; - httpDebugTopMost = false; + BitmapDebugTopMost = false; + HttpDebugTopMost = false; //ProfileOrder = new List(ApplicationProfiles.Keys); VarRegistry = new VariableRegistry(); - evaluatableTemplates = new ObservableConcurrentDictionary(); + EvaluatableTemplates = new ObservableConcurrentDictionary(); } /// @@ -586,7 +564,7 @@ public void OnPostLoad() { unified_hid_disabled = true; } - evaluatableTemplates.CollectionChanged += (sender, e) => InvokePropertyChanged(nameof(EvaluatableTemplates)); + EvaluatableTemplates.CollectionChanged += (sender, e) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(EvaluatableTemplates))); } } diff --git a/Project-Aurora/Project-Aurora/Settings/Control_LayerList.xaml.cs b/Project-Aurora/Project-Aurora/Settings/Control_LayerList.xaml.cs index b8b2d8c5e..aaa93533d 100644 --- a/Project-Aurora/Project-Aurora/Settings/Control_LayerList.xaml.cs +++ b/Project-Aurora/Project-Aurora/Settings/Control_LayerList.xaml.cs @@ -1,4 +1,5 @@ using Aurora.Settings.Layers; +using PropertyChanged; using System.Collections.ObjectModel; using System.ComponentModel; using System.Runtime.CompilerServices; @@ -8,6 +9,7 @@ namespace Aurora.Settings { + [DoNotNotify] public partial class Control_LayerList : UserControl, INotifyPropertyChanged { public Control_LayerList() { diff --git a/Project-Aurora/Project-Aurora/Settings/Control_ProfileManager.xaml.cs b/Project-Aurora/Project-Aurora/Settings/Control_ProfileManager.xaml.cs index 62e9f4b17..77bccf26f 100755 --- a/Project-Aurora/Project-Aurora/Settings/Control_ProfileManager.xaml.cs +++ b/Project-Aurora/Project-Aurora/Settings/Control_ProfileManager.xaml.cs @@ -1,6 +1,7 @@ using Aurora.EffectsEngine.Animations; using Aurora.Profiles; using Aurora.Settings.Layers; +using Aurora.Utils; using Microsoft.Win32; using System; using System.Collections.Generic; @@ -234,7 +235,7 @@ private void btnExportProfile_Click(object sender, RoutedEventArgs e) private void btnCopyProfile_Click(object sender, RoutedEventArgs e) { - Global.Clipboard = (lstProfiles.SelectedItem as ApplicationProfile)?.Clone(); + Global.Clipboard = (lstProfiles.SelectedItem as ApplicationProfile)?.TryClone(true); } private void btnPasteProfile_Click(object sender, RoutedEventArgs e) diff --git a/Project-Aurora/Project-Aurora/Settings/INotifyPropertyChangedEx.cs b/Project-Aurora/Project-Aurora/Settings/INotifyPropertyChangedEx.cs deleted file mode 100644 index d420ec940..000000000 --- a/Project-Aurora/Project-Aurora/Settings/INotifyPropertyChangedEx.cs +++ /dev/null @@ -1,43 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Runtime.CompilerServices; -using System.Text; -using System.Threading.Tasks; - -namespace Aurora.Settings -{ - public class PropertyChangedExEventArgs : EventArgs - { - public string PropertyName { get; set; } - - public object OldValue { get; set; } - - public object NewValue { get; set; } - - public PropertyChangedExEventArgs(string propertyName, object oldValue, object newValue) - { - PropertyName = propertyName; - OldValue = oldValue; - NewValue = newValue; - } - } - - public delegate void PropertyChangedExEventHandler(object sender, PropertyChangedExEventArgs e); - - - public interface INotifyPropertyChangedEx - { - event PropertyChangedExEventHandler PropertyChanged; - } - - public abstract class NotifyPropertyChangedEx : INotifyPropertyChangedEx - { - public event PropertyChangedExEventHandler PropertyChanged; - - protected void InvokePropertyChanged(object oldValue, object newValue, [CallerMemberName] string propertyName = null) - { - PropertyChanged?.Invoke(this, new PropertyChangedExEventArgs(propertyName, oldValue, newValue)); - } - } -} diff --git a/Project-Aurora/Project-Aurora/Settings/Layers/AmbilightLayerHandler.cs b/Project-Aurora/Project-Aurora/Settings/Layers/AmbilightLayerHandler.cs index 44cf9cc6f..bf352f7e4 100644 --- a/Project-Aurora/Project-Aurora/Settings/Layers/AmbilightLayerHandler.cs +++ b/Project-Aurora/Project-Aurora/Settings/Layers/AmbilightLayerHandler.cs @@ -2,6 +2,7 @@ using Aurora.Profiles; using Aurora.Settings.Overrides; using Newtonsoft.Json; +using PropertyChanged; using SharpDX; using SharpDX.DXGI; using SharpDX.Mathematics.Interop; @@ -159,6 +160,7 @@ public override void Default() [LogicOverrideIgnoreProperty("_PrimaryColor")] [LogicOverrideIgnoreProperty("_SecondaryColor")] [LogicOverrideIgnoreProperty("_Sequence")] + [DoNotNotify] public class AmbilightLayerHandler : LayerHandler, INotifyPropertyChanged { private static System.Timers.Timer captureTimer; diff --git a/Project-Aurora/Project-Aurora/Settings/Layers/ParticleLayerHandlerBase.cs b/Project-Aurora/Project-Aurora/Settings/Layers/ParticleLayerHandlerBase.cs index 71e54466d..4374a2243 100644 --- a/Project-Aurora/Project-Aurora/Settings/Layers/ParticleLayerHandlerBase.cs +++ b/Project-Aurora/Project-Aurora/Settings/Layers/ParticleLayerHandlerBase.cs @@ -32,11 +32,6 @@ public override void Default() { base.Default(); _Sequence = new KeySequence(Effects.WholeCanvasFreeForm); } - - protected void SetAndNotify(ref T field, T value, [CallerMemberName] string propName = null) { - field = value; - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName)); - } } diff --git a/Project-Aurora/Project-Aurora/Settings/Layers/ScriptLayerHandler.cs b/Project-Aurora/Project-Aurora/Settings/Layers/ScriptLayerHandler.cs index 404516095..5686acc58 100755 --- a/Project-Aurora/Project-Aurora/Settings/Layers/ScriptLayerHandler.cs +++ b/Project-Aurora/Project-Aurora/Settings/Layers/ScriptLayerHandler.cs @@ -49,18 +49,8 @@ public class ScriptLayerHandler : LayerHandler, IN public event PropertyChangedEventHandler PropertyChanged; - private Exception scriptException = null; - [JsonIgnore] - public Exception ScriptException { get { return scriptException; } - private set - { - bool diff = !(scriptException?.Equals(value) ?? false); - scriptException = value; - if (diff) - InvokePropertyChanged(); - } - } + public Exception ScriptException { get; private set; } public ScriptLayerHandler() : base() { @@ -131,10 +121,5 @@ protected override UserControl CreateControl() { return new Control_ScriptLayer(this); } - - protected void InvokePropertyChanged([CallerMemberName] string propertyName = null) - { - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); - } } } diff --git a/Project-Aurora/Project-Aurora/Settings/Layers/SimpleParticleLayerHandler.cs b/Project-Aurora/Project-Aurora/Settings/Layers/SimpleParticleLayerHandler.cs index 4b3798b83..63085e65d 100644 --- a/Project-Aurora/Project-Aurora/Settings/Layers/SimpleParticleLayerHandler.cs +++ b/Project-Aurora/Project-Aurora/Settings/Layers/SimpleParticleLayerHandler.cs @@ -27,108 +27,91 @@ namespace Aurora.Settings.Layers { public class SimpleParticleLayerProperties : ParticleLayerPropertiesBase where TSelf : SimpleParticleLayerProperties { // Override the default key sequence property so that we can make it trigger a property change notification - private KeySequence sequence; - [LogicOverridable("Spawn region")] public override KeySequence _Sequence { get => sequence; set => SetAndNotify(ref sequence, value); } + [LogicOverridable("Spawn region")] public override KeySequence _Sequence { get; set; } // The shortest time (in seconds) between particles spawning. A random time between this value and "MaxSpawnTime" will be chosen. - private float? minSpawnTime; - [LogicOverridable] public float? _MinSpawnTime { get => minSpawnTime; set => SetAndNotify(ref minSpawnTime, value); } + [LogicOverridable] public float? _MinSpawnTime { get; set; } [JsonIgnore] public float MinSpawnTime => Logic._MinSpawnTime ?? _MinSpawnTime ?? .5f; // The longest time (in seconds) between particles spawning. A random time from "MinSpawnTime" up to this value will be chosen. - private float? maxSpawnTime; - [LogicOverridable] public float? _MaxSpawnTime { get => maxSpawnTime; set => SetAndNotify(ref maxSpawnTime, value); } + [LogicOverridable] public float? _MaxSpawnTime { get; set; } [JsonIgnore] public float MaxSpawnTime => Logic._MaxSpawnTime ?? _MaxSpawnTime ?? 1f; // The smallest quantity of particles that will spawn at a time. A random value between this value and "MaxSpawnAmount" will be chosen. - private int? minSpawnAmount; - [LogicOverridable] public int? _MinSpawnAmount { get => minSpawnAmount; set => SetAndNotify(ref minSpawnAmount, value); } + [LogicOverridable] public int? _MinSpawnAmount { get; set; } [JsonIgnore] public int MinSpawnAmount => Logic._MinSpawnAmount ?? _MinSpawnAmount ?? 1; // The largest quantity of particles that will spawn at a time. A random value between "MinSpawnAmount" and this value will be chosen. - private int? maxSpawnAmount; - [LogicOverridable] public int? _MaxSpawnAmount { get => maxSpawnAmount; set => SetAndNotify(ref maxSpawnAmount, value); } + [LogicOverridable] public int? _MaxSpawnAmount { get; set; } [JsonIgnore] public int MaxSpawnAmount => Logic._MaxSpawnAmount ?? _MaxSpawnAmount ?? 1; // The smallest possible initial horizontal velocity of the spawned particles. A random value between this value and "MaxInitialVelocityX" will be chosen for each particle. - private float? minInitialVelocityX; - [LogicOverridable] public float? _MinInitialVelocityX { get => minInitialVelocityX; set => SetAndNotify(ref minInitialVelocityX, value); } + [LogicOverridable] public float? _MinInitialVelocityX { get; set; } [JsonIgnore] public float MinInitialVelocityX => Logic._MinInitialVelocityX ?? _MinInitialVelocityX ?? 0f; // The largest possible initial horizontal velocity of the spawned particles. A random value between "MinInitialVelocityX" and this value will be chosen for each particle. - private float? maxInitialVelocityX; - [LogicOverridable] public float? _MaxInitialVelocityX { get => maxInitialVelocityX; set => SetAndNotify(ref maxInitialVelocityX, value); } + [LogicOverridable] public float? _MaxInitialVelocityX { get; set; } [JsonIgnore] public float MaxInitialVelocityX => Logic._MaxInitialVelocityX ?? _MaxInitialVelocityX ?? 0f; // The smallest possible initial vertical velocity of the spawned particles. A random value between this value and "MaxInitialVelocityY" will be chosen for each particle. - private float? minInitialVelocityY; - [LogicOverridable] public float? _MinInitialVelocityY { get => minInitialVelocityY; set => SetAndNotify(ref minInitialVelocityY, value); } + [LogicOverridable] public float? _MinInitialVelocityY { get; set; } [JsonIgnore] public float MinInitialVelocityY => Logic._MinInitialVelocityY ?? _MinInitialVelocityY ?? 0f; // The largest possible initial vertical velocity of the spawned particles. A random value between "MinInitialVelocityY" and this value will be chosen for each particle. - private float? maxInitialVelocityY; - [LogicOverridable] public float? _MaxInitialVelocityY { get => maxInitialVelocityY; set => SetAndNotify(ref maxInitialVelocityY, value); } + [LogicOverridable] public float? _MaxInitialVelocityY { get; set; } [JsonIgnore] public float MaxInitialVelocityY => Logic._MaxInitialVelocityY ?? _MaxInitialVelocityY ?? 0f; // The minimum possible lifetime of the particles (in seconds). A random lifetime between this number and "MaxLifetime" will be chosen. - private float? minLifetime; - [LogicOverridable] public float? _MinLifetime { get => minLifetime; set => SetAndNotify(ref minLifetime, value); } + [LogicOverridable] public float? _MinLifetime { get; set; } [JsonIgnore] public float MinLifetime => Logic._MinLifetime ?? _MinLifetime ?? 3f; // The maximum possible lifetime of the particles (in seconds). A random lifetime between from "MinLifetime" up to this number will be chosen. - private float? maxLifetime; - [LogicOverridable] public float? _MaxLifetime { get => maxLifetime; set => SetAndNotify(ref maxLifetime, value); } + [LogicOverridable] public float? _MaxLifetime { get; set; } [JsonIgnore] public float MaxLifetime => Logic._MaxLifetime ?? _MaxLifetime ?? 3f; // The amount the speed of the particle in the horizontal direction will change per second. - private float? accelerationX; - [LogicOverridable] public float? _AccelerationX { get => accelerationX; set => SetAndNotify(ref accelerationX, value); } + [LogicOverridable] public float? _AccelerationX { get; set; } [JsonIgnore] public float AccelerationX => Logic._AccelerationX ?? _AccelerationX ?? 0f; // The amount the speed of the particle in the vertical direction will change per second. - private float? accelerationY; - [LogicOverridable] public float? _AccelerationY { get => accelerationY; set => SetAndNotify(ref accelerationY, value); } + [LogicOverridable] public float? _AccelerationY { get; set; } [JsonIgnore] public float AccelerationY => Logic._AccelerationY ?? _AccelerationY ?? -1f; // The amount of velocity per second the particle loses in the horizontal direction as a percentage of its current velocity - private float? dragX; - [LogicOverridable] public float? _DragX { get => dragX; set => SetAndNotify(ref dragX, value); } + [LogicOverridable] public float? _DragX { get; set; } [JsonIgnore] public float DragX => Logic._DragX ?? _DragX ?? 0; // The amount of velocity per second the particle loses in the vertical direction as a percentage of its current velocity - private float? dragY; - [LogicOverridable] public float? _DragY { get => dragY; set => SetAndNotify(ref dragY, value); } + [LogicOverridable] public float? _DragY { get; set; } [JsonIgnore] public float DragY => Logic._DragY ?? _DragY ?? 0; // The smallest initial size of the particles - private float? minSize; - [LogicOverridable] public float? _MinSize { get => minSize; set => SetAndNotify(ref minSize, value); } + [LogicOverridable] public float? _MinSize { get; set; } [JsonIgnore] public float MinSize => Logic._MinSize ?? _MinSize ?? 6; // The largest initial size of the particles - private float? maxSize; - [LogicOverridable] public float? _MaxSize { get => maxSize; set => SetAndNotify(ref maxSize, value); } + [LogicOverridable] public float? _MaxSize { get; set; } [JsonIgnore] public float MaxSize => Logic._MaxSize ?? _MaxSize ?? 6; // The initial size of the particles - private float? deltaSize; - [LogicOverridable] public float? _DeltaSize { get => deltaSize; set => SetAndNotify(ref deltaSize, value); } + [LogicOverridable] public float? _DeltaSize { get; set; } [JsonIgnore] public float DeltaSize => Logic._DeltaSize ?? _DeltaSize ?? 0; // Where the particles will spawn from - private ParticleSpawnLocations? spawnLocation; - public ParticleSpawnLocations? _SpawnLocation { get => spawnLocation; set => SetAndNotify(ref spawnLocation, value); } + public ParticleSpawnLocations? _SpawnLocation { get; set; } [JsonIgnore] public ParticleSpawnLocations SpawnLocation => Logic._SpawnLocation ?? _SpawnLocation ?? ParticleSpawnLocations.BottomEdge; // The color gradient stops for the particle. Note this is sorted by offset when set using _ParticleColorStops. Not using a linear brush here because: // 1) there are multithreading issues when trying to access a Media brush's gradient collection since it belongs to the UI thread // 2) We don't actually need the gradient as a brush since we're not drawing particles as gradients, only a solid color based on their lifetime, so we only need to access the color stops - private ColorStopCollection particleColorStops; - public ColorStopCollection _ParticleColorStops { get => particleColorStops; set => SetAndNotify(ref particleColorStops, value); } + public ColorStopCollection _ParticleColorStops { get; set; } [JsonIgnore] public ColorStopCollection ParticleColorStops => Logic._ParticleColorStops ?? _ParticleColorStops ?? defaultParticleColor; // An override proxy for setting the particle color stops - [JsonIgnore, LogicOverridable("Color over time")] public EffectBrush _ParticleBrush { get => new EffectBrush(_ParticleColorStops.ToMediaBrush()); set => _ParticleColorStops = value == null ? null : ColorStopCollection.FromMediaBrush(value.GetMediaBrush()); } + [JsonIgnore, LogicOverridable("Color over time")] public EffectBrush _ParticleBrush { + get => new EffectBrush(_ParticleColorStops.ToMediaBrush()); + set => _ParticleColorStops = value == null ? null : ColorStopCollection.FromMediaBrush(value.GetMediaBrush()); + } private static readonly ColorStopCollection defaultParticleColor = new ColorStopCollection { {0f, Color.White }, diff --git a/Project-Aurora/Project-Aurora/Settings/Overrides/Control_OverridesEditor.xaml.cs b/Project-Aurora/Project-Aurora/Settings/Overrides/Control_OverridesEditor.xaml.cs index b7f55b309..f7e49f558 100644 --- a/Project-Aurora/Project-Aurora/Settings/Overrides/Control_OverridesEditor.xaml.cs +++ b/Project-Aurora/Project-Aurora/Settings/Overrides/Control_OverridesEditor.xaml.cs @@ -1,6 +1,7 @@ using Aurora.Settings.Layers; using Aurora.Settings.Overrides.Logic; using Aurora.Utils; +using PropertyChanged; using System; using System.Collections.Generic; using System.Collections.ObjectModel; @@ -18,6 +19,7 @@ namespace Aurora.Settings.Overrides { /// /// Interaction logic for Control_OverridesEditor.xaml /// + [DoNotNotify] public partial class Control_OverridesEditor : UserControl, INotifyPropertyChanged { public Control_OverridesEditor() { diff --git a/Project-Aurora/Project-Aurora/Settings/Overrides/Logic/Boolean/Boolean_ProcessRunning.cs b/Project-Aurora/Project-Aurora/Settings/Overrides/Logic/Boolean/Boolean_ProcessRunning.cs index e961cbf68..b5f64dba7 100644 --- a/Project-Aurora/Project-Aurora/Settings/Overrides/Logic/Boolean/Boolean_ProcessRunning.cs +++ b/Project-Aurora/Project-Aurora/Settings/Overrides/Logic/Boolean/Boolean_ProcessRunning.cs @@ -24,10 +24,8 @@ public Visual GetControl() { var selectButton = new Button { Content = "Select", Padding = new System.Windows.Thickness(8, 0, 8, 0), Margin = new System.Windows.Thickness(8, 0, 0, 0) }; selectButton.Click += (sender, e) => { var wnd = new Window_ProcessSelection { ButtonLabel = "Select" }; - if (wnd.ShowDialog() == true && !string.IsNullOrWhiteSpace(wnd.ChosenExecutableName)) { + if (wnd.ShowDialog() == true && !string.IsNullOrWhiteSpace(wnd.ChosenExecutableName)) ProcessName = wnd.ChosenExecutableName; - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(ProcessName))); - } }; return new StackPanel { Orientation = Orientation.Horizontal } diff --git a/Project-Aurora/Project-Aurora/Settings/PluginManager.cs b/Project-Aurora/Project-Aurora/Settings/PluginManager.cs index 92cc0e959..c5f57356c 100644 --- a/Project-Aurora/Project-Aurora/Settings/PluginManager.cs +++ b/Project-Aurora/Project-Aurora/Settings/PluginManager.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.ComponentModel; using System.Globalization; using System.IO; using System.Linq; @@ -97,7 +98,7 @@ public object ConvertBack(object value, Type targetType, object parameter, Cultu } } - public class PluginManagerSettings : Settings + public class PluginManagerSettings { public Dictionary PluginManagement { get; private set; } = new Dictionary(); diff --git a/Project-Aurora/Project-Aurora/Utils/GenericUtils.cs b/Project-Aurora/Project-Aurora/Utils/GenericUtils.cs index 3a453fe8b..6065404eb 100644 --- a/Project-Aurora/Project-Aurora/Utils/GenericUtils.cs +++ b/Project-Aurora/Project-Aurora/Utils/GenericUtils.cs @@ -1,4 +1,5 @@ -using System; +using Newtonsoft.Json; +using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; @@ -9,12 +10,15 @@ namespace Aurora.Utils { public static class TypeExtensions { - - public static object TryClone(this object self) + public static object TryClone(this object self, bool deep = false) { if (self is ICloneable) return ((ICloneable)self).Clone(); - else + else if (deep) { + var settings = new JsonSerializerSettings { ObjectCreationHandling = ObjectCreationHandling.Replace, TypeNameHandling = TypeNameHandling.All, Binder = Aurora.Utils.JSONUtils.SerializationBinder }; + var json = JsonConvert.SerializeObject(self, Formatting.None, settings); + return JsonConvert.DeserializeObject(json, self.GetType(), settings); + } else return self; } } diff --git a/Project-Aurora/Project-Aurora/Utils/ObservableConcurrentDictionary.cs b/Project-Aurora/Project-Aurora/Utils/ObservableConcurrentDictionary.cs index 39cce7f32..46ff55727 100644 --- a/Project-Aurora/Project-Aurora/Utils/ObservableConcurrentDictionary.cs +++ b/Project-Aurora/Project-Aurora/Utils/ObservableConcurrentDictionary.cs @@ -12,6 +12,7 @@ using System.ComponentModel; using System.Threading; using System.Diagnostics; +using PropertyChanged; namespace System.Collections.Concurrent { /// @@ -20,6 +21,7 @@ namespace System.Collections.Concurrent { /// Specifies the type of the keys in this collection. /// Specifies the type of the values in this collection. [DebuggerDisplay("Count={Count}")] + [DoNotNotify] public class ObservableConcurrentDictionary : ICollection>, IDictionary, INotifyCollectionChanged, INotifyPropertyChanged {