From cf044f70c5bf7020c72b0f35655923766389aff5 Mon Sep 17 00:00:00 2001 From: SpoinkyNL Date: Sun, 23 Apr 2017 14:10:03 +0200 Subject: [PATCH] Fixed AudioVisualization issues after layer deactivation Fixed a crash when loading invalid profiles Added LUA storage module --- Artemis/Artemis/Artemis.csproj | 1 + Artemis/Artemis/DAL/ProfileProvider.cs | 2 +- .../CoolerMaster/MastermouseProL.cs | 13 +++- .../CoolerMaster/MastermouseProS.cs | 15 ++-- Artemis/Artemis/Managers/LuaManager.cs | 42 ++++++------ .../Audio/AudioCapturing/AudioCapture.cs | 28 +++++--- .../Profiles/Layers/Types/Audio/AudioType.cs | 19 +++--- .../Profiles/Lua/Modules/LuaStorageModule.cs | 68 +++++++++++++++++++ Artemis/Artemis/Profiles/ProfileModel.cs | 1 + 9 files changed, 141 insertions(+), 48 deletions(-) create mode 100644 Artemis/Artemis/Profiles/Lua/Modules/LuaStorageModule.cs diff --git a/Artemis/Artemis/Artemis.csproj b/Artemis/Artemis/Artemis.csproj index 04593aefe..6148ad36e 100644 --- a/Artemis/Artemis/Artemis.csproj +++ b/Artemis/Artemis/Artemis.csproj @@ -587,6 +587,7 @@ + diff --git a/Artemis/Artemis/DAL/ProfileProvider.cs b/Artemis/Artemis/DAL/ProfileProvider.cs index 356c53ec0..9a64c6446 100644 --- a/Artemis/Artemis/DAL/ProfileProvider.cs +++ b/Artemis/Artemis/DAL/ProfileProvider.cs @@ -134,7 +134,7 @@ namespace Artemis.DAL return null; return prof; } - catch (JsonSerializationException) + catch (JsonException) { return null; } diff --git a/Artemis/Artemis/DeviceProviders/CoolerMaster/MastermouseProL.cs b/Artemis/Artemis/DeviceProviders/CoolerMaster/MastermouseProL.cs index 284b970f9..057439fb9 100644 --- a/Artemis/Artemis/DeviceProviders/CoolerMaster/MastermouseProL.cs +++ b/Artemis/Artemis/DeviceProviders/CoolerMaster/MastermouseProL.cs @@ -42,9 +42,16 @@ namespace Artemis.DeviceProviders.CoolerMaster CmSdk.SetControlDevice(DEVICE_INDEX.DEV_MMouse_L); // Doesn't seem reliable but better than nothing I suppose - CanUse = CmSdk.IsDevicePlug(); - if (CanUse) - CmSdk.EnableLedControl(true); + try + { + CanUse = CmSdk.IsDevicePlug(); + if (CanUse) + CmSdk.EnableLedControl(true); + } + catch (Exception) + { + CanUse = false; + } Logger.Debug("Attempted to enable Mastermouse Pro L. CanUse: {0}", CanUse); return CanUse; diff --git a/Artemis/Artemis/DeviceProviders/CoolerMaster/MastermouseProS.cs b/Artemis/Artemis/DeviceProviders/CoolerMaster/MastermouseProS.cs index 3d1fcafc7..ebb07185c 100644 --- a/Artemis/Artemis/DeviceProviders/CoolerMaster/MastermouseProS.cs +++ b/Artemis/Artemis/DeviceProviders/CoolerMaster/MastermouseProS.cs @@ -38,10 +38,17 @@ namespace Artemis.DeviceProviders.CoolerMaster CmSdk.SetControlDevice(DEVICE_INDEX.DEV_MMouse_S); // Doesn't seem reliable but better than nothing I suppose - CanUse = CmSdk.IsDevicePlug(); - if (CanUse) - CmSdk.EnableLedControl(true); - + try + { + CanUse = CmSdk.IsDevicePlug(); + if (CanUse) + CmSdk.EnableLedControl(true); + } + catch (Exception) + { + CanUse = false; + } + Logger.Debug("Attempted to enable Mastermouse Pro S. CanUse: {0}", CanUse); return CanUse; } diff --git a/Artemis/Artemis/Managers/LuaManager.cs b/Artemis/Artemis/Managers/LuaManager.cs index bae48462d..f5df058a7 100644 --- a/Artemis/Artemis/Managers/LuaManager.cs +++ b/Artemis/Artemis/Managers/LuaManager.cs @@ -17,7 +17,6 @@ namespace Artemis.Managers private readonly DeviceManager _deviceManager; private readonly IKernel _kernel; private readonly ILogger _logger; - private readonly Script _luaScript; private List _luaModules; public LuaManager(IKernel kernel, ILogger logger, DeviceManager deviceManager) @@ -25,13 +24,14 @@ namespace Artemis.Managers _kernel = kernel; _logger = logger; _deviceManager = deviceManager; - _luaScript = new Script(CoreModules.Preset_SoftSandbox); + LuaScript = new Script(CoreModules.Preset_SoftSandbox); } public ProfileModel ProfileModel { get; private set; } public KeyboardProvider KeyboardProvider { get; private set; } public LuaProfileModule ProfileModule { get; private set; } public LuaEventsModule EventsModule { get; private set; } + public Script LuaScript { get; } public void SetupLua(ProfileModel profileModel) { @@ -52,11 +52,11 @@ namespace Artemis.Managers EventsModule = (LuaEventsModule) _luaModules.First(m => m.ModuleName == "Events"); // Setup new state - _luaScript.Options.DebugPrint = LuaPrint; + LuaScript.Options.DebugPrint = LuaPrint; - // Insert each module into the script's globals - foreach (var luaModule in _luaModules) - _luaScript.Globals[luaModule.ModuleName] = luaModule; + // Insert each module with a ModuleName into the script's globals + foreach (var luaModule in _luaModules.Where(m => m.ModuleName != null)) + LuaScript.Globals[luaModule.ModuleName] = luaModule; // If there is no LUA script, don't bother executing the string if (ProfileModel.LuaScript.IsNullOrEmpty()) @@ -66,9 +66,9 @@ namespace Artemis.Managers { lock (EventsModule.InvokeLock) { - lock (_luaScript) + lock (LuaScript) { - _luaScript.DoString(ProfileModel.LuaScript); + LuaScript.DoString(ProfileModel.LuaScript); } } } @@ -97,12 +97,12 @@ namespace Artemis.Managers try { - _luaScript.Globals.Clear(); - _luaScript.Registry.Clear(); - _luaScript.Registry.RegisterConstants(); - _luaScript.Registry.RegisterCoreModules(CoreModules.Preset_SoftSandbox); - _luaScript.Globals.RegisterConstants(); - _luaScript.Globals.RegisterCoreModules(CoreModules.Preset_SoftSandbox); + LuaScript.Globals.Clear(); + LuaScript.Registry.Clear(); + LuaScript.Registry.RegisterConstants(); + LuaScript.Registry.RegisterCoreModules(CoreModules.Preset_SoftSandbox); + LuaScript.Globals.RegisterConstants(); + LuaScript.Globals.RegisterCoreModules(CoreModules.Preset_SoftSandbox); } catch (NullReferenceException) { @@ -112,15 +112,15 @@ namespace Artemis.Managers if (EventsModule != null) lock (EventsModule.InvokeLock) { - lock (_luaScript) + lock (LuaScript) { - _luaScript.DoString(""); + LuaScript.DoString(""); } } else - lock (_luaScript) + lock (LuaScript) { - _luaScript.DoString(""); + LuaScript.DoString(""); } } @@ -138,12 +138,12 @@ namespace Artemis.Managers { lock (EventsModule.InvokeLock) { - lock (_luaScript) + lock (LuaScript) { if (args != null) - _luaScript.Call(function, args); + LuaScript.Call(function, args); else - _luaScript.Call(function); + LuaScript.Call(function); } } } diff --git a/Artemis/Artemis/Profiles/Layers/Types/Audio/AudioCapturing/AudioCapture.cs b/Artemis/Artemis/Profiles/Layers/Types/Audio/AudioCapturing/AudioCapture.cs index 147deb123..7c721f37a 100644 --- a/Artemis/Artemis/Profiles/Layers/Types/Audio/AudioCapturing/AudioCapture.cs +++ b/Artemis/Artemis/Profiles/Layers/Types/Audio/AudioCapturing/AudioCapture.cs @@ -97,18 +97,23 @@ namespace Artemis.Profiles.Layers.Types.Audio.AudioCapturing } } + private LineSpectrum _lineSpectrum; public LineSpectrum GetLineSpectrum(int barCount, ScalingStrategy scalingStrategy) { - if (_spectrumProvider == null) + if (_spectrumProvider == null || barCount <= 0) return null; - return new LineSpectrum(FftSize) - { - SpectrumProvider = _spectrumProvider, - UseAverage = true, - BarCount = barCount, - IsXLogScale = true, - ScalingStrategy = scalingStrategy - }; + + if (_lineSpectrum == null) + _lineSpectrum = new LineSpectrum(FftSize) + { + SpectrumProvider = _spectrumProvider, + UseAverage = true, + BarCount = barCount, + IsXLogScale = true, + ScalingStrategy = scalingStrategy + }; + + return _lineSpectrum; } /// @@ -148,13 +153,13 @@ namespace Artemis.Profiles.Layers.Types.Audio.AudioCapturing if (Type == MmDeviceType.Input) { _soundIn = Device != null - ? new WasapiCapture {Device = Device} + ? new WasapiCapture { Device = Device } : new WasapiCapture(); } else { _soundIn = Device != null - ? new WasapiLoopbackCapture {Device = Device} + ? new WasapiLoopbackCapture { Device = Device } : new WasapiLoopbackCapture(); } @@ -182,6 +187,7 @@ namespace Artemis.Profiles.Layers.Types.Audio.AudioCapturing } }; + _lineSpectrum = null; _singleSpectrum = new SingleSpectrum(FftSize, _spectrumProvider); _mayStop = false; diff --git a/Artemis/Artemis/Profiles/Layers/Types/Audio/AudioType.cs b/Artemis/Artemis/Profiles/Layers/Types/Audio/AudioType.cs index eb0b6ef5d..0a6b126e4 100644 --- a/Artemis/Artemis/Profiles/Layers/Types/Audio/AudioType.cs +++ b/Artemis/Artemis/Profiles/Layers/Types/Audio/AudioType.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Linq; using System.Windows; using System.Windows.Media; @@ -26,6 +27,7 @@ namespace Artemis.Profiles.Layers.Types.Audio private List _lineValues; private AudioPropertiesModel _properties; private bool _subscribed; + private DateTime _lastRender; public AudioType(AudioCaptureManager audioCaptureManager) { @@ -123,8 +125,7 @@ namespace Artemis.Profiles.Layers.Types.Audio SubscribeToAudioChange(); - if (_audioCapture == null || newProperties.Device != _properties.Device || - newProperties.DeviceType != _properties.DeviceType) + if (_audioCapture == null || newProperties.Device != _properties.Device || newProperties.DeviceType != _properties.DeviceType) { var device = GetMmDevice(); if (device != null) @@ -153,17 +154,19 @@ namespace Artemis.Profiles.Layers.Types.Audio currentHeight = layerModel.Width; } - if (_lines != currentLines || _lineSpectrum == null) + // Get a new line spectrum if the lines changed, it is null or the layer hasn't rendered for a few frames + if (_lines != currentLines || _lineSpectrum == null || DateTime.Now - _lastRender > TimeSpan.FromMilliseconds(100)) { _lines = currentLines; _lineSpectrum = _audioCapture.GetLineSpectrum(_lines, ScalingStrategy.Decibel); - if (_lineSpectrum == null) - return; } - - var newLineValues = _lineSpectrum?.GetLineValues(currentHeight); + + var newLineValues = _audioCapture.GetLineSpectrum(_lines, ScalingStrategy.Decibel)?.GetLineValues(currentHeight); if (newLineValues != null) + { _lineValues = newLineValues; + _lastRender = DateTime.Now; + } } public void SetupProperties(LayerModel layerModel) diff --git a/Artemis/Artemis/Profiles/Lua/Modules/LuaStorageModule.cs b/Artemis/Artemis/Profiles/Lua/Modules/LuaStorageModule.cs new file mode 100644 index 000000000..dc3840ba4 --- /dev/null +++ b/Artemis/Artemis/Profiles/Lua/Modules/LuaStorageModule.cs @@ -0,0 +1,68 @@ +using Artemis.DAL; +using Artemis.Managers; +using Artemis.Settings; +using MoonSharp.Interpreter; +using static MoonSharp.Interpreter.Serialization.Json.JsonTableConverter; + +namespace Artemis.Profiles.Lua.Modules +{ + [MoonSharpUserData] + public class LuaStorageModule : LuaModule + { + private readonly Table _globalValues; + private readonly Table _profileValues; + private readonly LuaGlobalSettings _globalSettings; + + public LuaStorageModule(LuaManager luaManager) : base(luaManager) + { + _globalSettings = SettingsProvider.Load(); + + // Load profile values + if (LuaManager.ProfileModel.LuaStorage != null) + _profileValues = JsonToTable(LuaManager.ProfileModel.LuaStorage, LuaManager.LuaScript); + else + _profileValues = new Table(LuaManager.LuaScript); + + // Load global values + if (_globalSettings.GlobalValues != null) + _globalValues = JsonToTable(_globalSettings.GlobalValues, LuaManager.LuaScript); + else + _globalValues = new Table(LuaManager.LuaScript); + + // Set the values onto the globals table so scripters can access them + LuaManager.LuaScript.Globals["ProfileStorage"] = _profileValues; + LuaManager.LuaScript.Globals["GlobalStorage"] = _globalValues; + } + + public override string ModuleName => null; + + public override void Dispose() + { + // Store profile values + LuaManager.ProfileModel.LuaStorage = _profileValues.TableToJson(); + ProfileProvider.AddOrUpdate(LuaManager.ProfileModel); + + // Store global values + _globalSettings.GlobalValues = _globalValues.TableToJson(); + _globalSettings.Save(); + } + } + + public class LuaGlobalSettings : IArtemisSettings + { + public string GlobalValues { get; set; } + + public void Save() + { + SettingsProvider.Save(this); + } + + public void Reset(bool save = false) + { + GlobalValues = null; + + if (save) + Save(); + } + } +} diff --git a/Artemis/Artemis/Profiles/ProfileModel.cs b/Artemis/Artemis/Profiles/ProfileModel.cs index f54714c0f..17cfeb245 100644 --- a/Artemis/Artemis/Profiles/ProfileModel.cs +++ b/Artemis/Artemis/Profiles/ProfileModel.cs @@ -38,6 +38,7 @@ namespace Artemis.Profiles public int Width { get; set; } public int Height { get; set; } public string LuaScript { get; set; } + public string LuaStorage { get; set; } [JsonIgnore] public string Slug => new string(Name.Where(ch => !_invalidFileNameChars.Contains(ch)).ToArray());