diff --git a/src/Artemis.Core/MVVM/CorePropertyChanged.cs b/src/Artemis.Core/MVVM/CorePropertyChanged.cs index 06db7bd0b..69aeef147 100644 --- a/src/Artemis.Core/MVVM/CorePropertyChanged.cs +++ b/src/Artemis.Core/MVVM/CorePropertyChanged.cs @@ -46,7 +46,7 @@ namespace Artemis.Core /// /// true if the value was changed, false if the existing value matched the desired value. [NotifyPropertyChangedInvocator] - protected virtual bool SetAndNotify(ref T storage, T value, [CallerMemberName] string propertyName = null) + protected virtual bool SetAndNotify(ref T storage, T value, [CallerMemberName] string? propertyName = null) { if (!RequiresUpdate(ref storage, value)) return false; @@ -64,7 +64,7 @@ namespace Artemis.Core /// and can be provided automatically when invoked from compilers that support /// . /// - protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) + protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } diff --git a/src/Artemis.Core/Models/Profile/AdaptionHints/CategoryAdaptionHint.cs b/src/Artemis.Core/Models/Profile/AdaptionHints/CategoryAdaptionHint.cs index 1e31bb371..824b27963 100644 --- a/src/Artemis.Core/Models/Profile/AdaptionHints/CategoryAdaptionHint.cs +++ b/src/Artemis.Core/Models/Profile/AdaptionHints/CategoryAdaptionHint.cs @@ -9,6 +9,9 @@ namespace Artemis.Core /// public class CategoryAdaptionHint : IAdaptionHint { + /// + /// Creates a new instance of the class + /// public CategoryAdaptionHint() { } @@ -41,6 +44,12 @@ namespace Artemis.Core /// public int Amount { get; set; } + /// + public override string ToString() + { + return $"Category adaption - {nameof(Category)}: {Category}, {nameof(Skip)}: {Skip}, {nameof(LimitAmount)}: {LimitAmount}, {nameof(Amount)}: {Amount}"; + } + #region Implementation of IAdaptionHint /// @@ -65,11 +74,5 @@ namespace Artemis.Core } #endregion - - /// - public override string ToString() - { - return $"Category adaption - {nameof(Category)}: {Category}, {nameof(Skip)}: {Skip}, {nameof(LimitAmount)}: {LimitAmount}, {nameof(Amount)}: {Amount}"; - } } } \ No newline at end of file diff --git a/src/Artemis.Core/Models/Profile/AdaptionHints/DeviceAdaptionHint.cs b/src/Artemis.Core/Models/Profile/AdaptionHints/DeviceAdaptionHint.cs index b51e68547..28058f641 100644 --- a/src/Artemis.Core/Models/Profile/AdaptionHints/DeviceAdaptionHint.cs +++ b/src/Artemis.Core/Models/Profile/AdaptionHints/DeviceAdaptionHint.cs @@ -10,6 +10,9 @@ namespace Artemis.Core /// public class DeviceAdaptionHint : IAdaptionHint { + /// + /// Creates a new instance of the class + /// public DeviceAdaptionHint() { } diff --git a/src/Artemis.Core/Models/Profile/AdaptionHints/KeyboardSectionAdaptionHint.cs b/src/Artemis.Core/Models/Profile/AdaptionHints/KeyboardSectionAdaptionHint.cs index 2a68be352..0177a8938 100644 --- a/src/Artemis.Core/Models/Profile/AdaptionHints/KeyboardSectionAdaptionHint.cs +++ b/src/Artemis.Core/Models/Profile/AdaptionHints/KeyboardSectionAdaptionHint.cs @@ -18,6 +18,9 @@ namespace Artemis.Core {KeyboardSection.Extra, Enum.GetValues().Where(l => l >= LedId.Keyboard_Custom1 && l <= LedId.Keyboard_Custom64).ToList()} }; + /// + /// Creates a new instance of the class + /// public KeyboardSectionAdaptionHint() { } diff --git a/src/Artemis.Core/Models/Profile/LayerProperties/LayerProperty.cs b/src/Artemis.Core/Models/Profile/LayerProperties/LayerProperty.cs index 3bbb7f557..2877482c5 100644 --- a/src/Artemis.Core/Models/Profile/LayerProperties/LayerProperty.cs +++ b/src/Artemis.Core/Models/Profile/LayerProperties/LayerProperty.cs @@ -421,7 +421,7 @@ namespace Artemis.Core { if (keyframeEntity.Position > ProfileElement.Timeline.Length) return null; - T value = CoreJson.DeserializeObject(keyframeEntity.Value); + T? value = CoreJson.DeserializeObject(keyframeEntity.Value); if (value == null) return null; diff --git a/src/Artemis.Core/Models/Profile/ProfileCategory.cs b/src/Artemis.Core/Models/Profile/ProfileCategory.cs index f2e9cac5a..c53e36129 100644 --- a/src/Artemis.Core/Models/Profile/ProfileCategory.cs +++ b/src/Artemis.Core/Models/Profile/ProfileCategory.cs @@ -28,6 +28,7 @@ namespace Artemis.Core internal ProfileCategory(ProfileCategoryEntity entity) { + _name = null!; Entity = entity; Load(); } diff --git a/src/Artemis.Core/Ninject/CoreModule.cs b/src/Artemis.Core/Ninject/CoreModule.cs index 66a882bf7..323cfbcce 100644 --- a/src/Artemis.Core/Ninject/CoreModule.cs +++ b/src/Artemis.Core/Ninject/CoreModule.cs @@ -1,7 +1,4 @@ -using System; -using System.Diagnostics; -using System.IO; -using System.Reflection; +using System.IO; using Artemis.Core.Services; using Artemis.Storage; using Artemis.Storage.Migrations.Interfaces; diff --git a/src/Artemis.Core/Plugins/Modules/DynamicChild.cs b/src/Artemis.Core/Plugins/Modules/DynamicChild.cs index 203562865..a0fff499c 100644 --- a/src/Artemis.Core/Plugins/Modules/DynamicChild.cs +++ b/src/Artemis.Core/Plugins/Modules/DynamicChild.cs @@ -15,7 +15,7 @@ namespace Artemis.Core.Modules /// /// Gets or sets the current value of the dynamic child /// - public new T Value { get; set; } + public T Value { get; set; } /// protected override object? GetValue() diff --git a/src/Artemis.Core/Plugins/Plugin.cs b/src/Artemis.Core/Plugins/Plugin.cs index ca8645a44..49f67ed78 100644 --- a/src/Artemis.Core/Plugins/Plugin.cs +++ b/src/Artemis.Core/Plugins/Plugin.cs @@ -66,6 +66,9 @@ namespace Artemis.Core /// public ReadOnlyCollection Features => _features.AsReadOnly(); + /// + /// Gets a read-only collection of profiles running on the plugin + /// public ReadOnlyCollection Profilers => _profilers.AsReadOnly(); /// diff --git a/src/Artemis.Core/Plugins/PluginFeatureInfo.cs b/src/Artemis.Core/Plugins/PluginFeatureInfo.cs index a7b468835..4947ab20a 100644 --- a/src/Artemis.Core/Plugins/PluginFeatureInfo.cs +++ b/src/Artemis.Core/Plugins/PluginFeatureInfo.cs @@ -51,6 +51,7 @@ namespace Artemis.Core if (instance == null) throw new ArgumentNullException(nameof(instance)); Plugin = plugin ?? throw new ArgumentNullException(nameof(plugin)); FeatureType = instance.GetType(); + Entity = new PluginFeatureEntity(); Name = attribute?.Name ?? instance.GetType().Name.Humanize(LetterCasing.Title); Description = attribute?.Description; diff --git a/src/Artemis.Core/Plugins/Prerequisites/PrerequisiteActionProgress.cs b/src/Artemis.Core/Plugins/Prerequisites/PrerequisiteActionProgress.cs index 96b48bde3..4cefa4582 100644 --- a/src/Artemis.Core/Plugins/Prerequisites/PrerequisiteActionProgress.cs +++ b/src/Artemis.Core/Plugins/Prerequisites/PrerequisiteActionProgress.cs @@ -9,10 +9,10 @@ namespace Artemis.Core { private long _current; private DateTime _lastReport; + private long _lastReportValue; private double _percentage; private double _progressPerSecond; private long _total; - private long _lastReportValue; /// /// The current amount @@ -81,6 +81,9 @@ namespace Artemis.Core /// public event EventHandler? ProgressReported; + /// + /// Invokes the event + /// protected virtual void OnProgressReported() { ProgressReported?.Invoke(this, EventArgs.Empty); diff --git a/src/Artemis.Core/Plugins/ScriptingProviders/ScriptConfiguration.cs b/src/Artemis.Core/Plugins/ScriptingProviders/ScriptConfiguration.cs index 10095bf4f..d27b0e145 100644 --- a/src/Artemis.Core/Plugins/ScriptingProviders/ScriptConfiguration.cs +++ b/src/Artemis.Core/Plugins/ScriptingProviders/ScriptConfiguration.cs @@ -1,4 +1,5 @@ -using Artemis.Storage.Entities.General; +using System; +using Artemis.Storage.Entities.General; namespace Artemis.Core.ScriptingProviders { @@ -7,24 +8,26 @@ namespace Artemis.Core.ScriptingProviders /// public class ScriptConfiguration : CorePropertyChanged, IStorageModel { - private string _scriptingProviderId; + private bool _hasChanges; private string _name; + private string? _pendingScriptContent; private string? _scriptContent; + private string _scriptingProviderId; /// /// Creates a new instance of the class /// public ScriptConfiguration(ScriptingProvider provider, string name) { - ScriptingProviderId = provider.Id; - Name = name; + _scriptingProviderId = provider.Id; + _name = name; Entity = new ScriptConfigurationEntity(); } internal ScriptConfiguration(ScriptConfigurationEntity entity) { - ScriptingProviderId = null!; - Name = null!; + _scriptingProviderId = null!; + _name = null!; Entity = entity; Load(); @@ -54,7 +57,36 @@ namespace Artemis.Core.ScriptingProviders public string? ScriptContent { get => _scriptContent; - set => SetAndNotify(ref _scriptContent, value); + private set + { + if (!SetAndNotify(ref _scriptContent, value)) return; + OnScriptContentChanged(); + } + } + + /// + /// Gets or sets the pending changes to the script's content + /// + public string? PendingScriptContent + { + get => _pendingScriptContent; + set + { + if (string.IsNullOrWhiteSpace(value)) + value = null; + if (!SetAndNotify(ref _pendingScriptContent, value)) return; + HasChanges = ScriptContent != PendingScriptContent; + } + } + + /// + /// Gets or sets a boolean indicating whether this configuration has pending changes to it's + /// + /// + public bool HasChanges + { + get => _hasChanges; + set => SetAndNotify(ref _hasChanges, value); } /// @@ -64,6 +96,24 @@ namespace Artemis.Core.ScriptingProviders internal ScriptConfigurationEntity Entity { get; } + /// + /// Applies the to the + /// + public void ApplyPendingChanges() + { + ScriptContent = PendingScriptContent; + HasChanges = false; + } + + /// + /// Discards the + /// + public void DiscardPendingChanges() + { + PendingScriptContent = ScriptContent; + HasChanges = false; + } + #region Implementation of IStorageModel /// @@ -71,6 +121,7 @@ namespace Artemis.Core.ScriptingProviders { ScriptingProviderId = Entity.ScriptingProviderId; ScriptContent = Entity.ScriptContent; + PendingScriptContent = Entity.ScriptContent; Name = Entity.Name; } @@ -79,6 +130,24 @@ namespace Artemis.Core.ScriptingProviders { Entity.ScriptingProviderId = ScriptingProviderId; Entity.ScriptContent = ScriptContent; + Entity.Name = Name; + } + + #endregion + + #region Events + + /// + /// Occurs whenever the contents of the script have changed + /// + public event EventHandler? ScriptContentChanged; + + /// + /// Invokes the event + /// + protected virtual void OnScriptContentChanged() + { + ScriptContentChanged?.Invoke(this, EventArgs.Empty); } #endregion diff --git a/src/Artemis.Core/Plugins/ScriptingProviders/ScriptingProvider.cs b/src/Artemis.Core/Plugins/ScriptingProviders/ScriptingProvider.cs index 26baa7362..e9a06fd0d 100644 --- a/src/Artemis.Core/Plugins/ScriptingProviders/ScriptingProvider.cs +++ b/src/Artemis.Core/Plugins/ScriptingProviders/ScriptingProvider.cs @@ -37,6 +37,19 @@ namespace Artemis.Core.ScriptingProviders /// The script the editor must edit public abstract IScriptEditorViewModel CreatePropertyScriptEditor(TPropertyScript script); + #region Overrides of PluginFeature + + /// + internal override void InternalDisable() + { + base.InternalDisable(); + + while (Scripts.Count > 0) + Scripts[0].Dispose(); + } + + #endregion + #region Overrides of ScriptingProvider /// @@ -104,19 +117,6 @@ namespace Artemis.Core.ScriptingProviders } #endregion - - #region Overrides of PluginFeature - - /// - internal override void InternalDisable() - { - base.InternalDisable(); - - while (Scripts.Count > 0) - Scripts[0].Dispose(); - } - - #endregion } /// @@ -128,17 +128,22 @@ namespace Artemis.Core.ScriptingProviders /// public abstract class ScriptingProvider : PluginFeature { - internal abstract Type GlobalScriptType { get; } - internal abstract Type PropertyScriptType { get; } - internal abstract Type LayerScriptType { get; } - internal abstract Type ProfileScriptType { get; } - internal List