diff --git a/Artemis/Artemis/LogitechLedEnginesWrapper.dll b/Artemis/Artemis/LogitechLedEnginesWrapper.dll index d28ee9e94..37f959c2e 100644 Binary files a/Artemis/Artemis/LogitechLedEnginesWrapper.dll and b/Artemis/Artemis/LogitechLedEnginesWrapper.dll differ diff --git a/Artemis/Artemis/Managers/MainManager.cs b/Artemis/Artemis/Managers/MainManager.cs index b24d99cc1..096dd18f7 100644 --- a/Artemis/Artemis/Managers/MainManager.cs +++ b/Artemis/Artemis/Managers/MainManager.cs @@ -1,8 +1,7 @@ using System; -using System.ComponentModel; using System.Diagnostics; using System.Linq; -using System.Threading; +using System.Timers; using Artemis.Events; using Artemis.Models; using Artemis.Modules.Effects.ProfilePreview; @@ -25,6 +24,7 @@ namespace Artemis.Managers private readonly IEventAggregator _events; private readonly ILogger _logger; + private readonly Timer _processTimer; public MainManager(IEventAggregator events, ILogger logger, LoopManager loopManager, KeyboardManager keyboardManager, EffectManager effectManager, ProfileManager profileManager) @@ -38,20 +38,16 @@ namespace Artemis.Managers _logger.Info("Intializing MainManager"); _events = events; - - //DialogService = dialogService; - KeyboardHook = new KeyboardHook(); - - ProcessWorker = new BackgroundWorker {WorkerSupportsCancellation = true}; - ProcessWorker.DoWork += ProcessWorker_DoWork; - ProcessWorker.RunWorkerCompleted += BackgroundWorkerExceptionCatcher; - - // Process worker will always run (and just do nothing when ProgramEnabled is false) - ProcessWorker.RunWorkerAsync(); + + _processTimer = new Timer(1000); + _processTimer.Elapsed += ScanProcesses; + _processTimer.Start(); ProgramEnabled = false; Running = false; + KeyboardHook = new KeyboardHook(); // TODO: DI + // Create and start the web server GameStateWebServer = new GameStateWebServer(); GameStateWebServer.Start(); @@ -72,7 +68,6 @@ namespace Artemis.Managers public ProfileManager ProfileManager { get; set; } public PipeServer PipeServer { get; set; } - public BackgroundWorker ProcessWorker { get; set; } public KeyboardHook KeyboardHook { get; set; } public GameStateWebServer GameStateWebServer { get; set; } public bool ProgramEnabled { get; private set; } @@ -81,8 +76,10 @@ namespace Artemis.Managers public void Dispose() { _logger.Debug("Shutting down MainManager"); + + _processTimer.Stop(); + _processTimer.Dispose(); LoopManager.Stop(); - ProcessWorker.CancelAsync(); GameStateWebServer.Stop(); PipeServer.Stop(); } @@ -109,59 +106,46 @@ namespace Artemis.Managers _events.PublishOnUIThread(new ToggleEnabled(ProgramEnabled)); } - private void ProcessWorker_DoWork(object sender, DoWorkEventArgs e) + /// + /// Manages active games by keeping an eye on their processes + /// + /// + /// + private void ScanProcesses(object sender, ElapsedEventArgs e) { - while (!ProcessWorker.CancellationPending) - { - if (!ProgramEnabled) - { - Thread.Sleep(1000); - continue; - } - - var runningProcesses = Process.GetProcesses(); - - // If the currently active effect is a disabled game, get rid of it. - if (EffectManager.ActiveEffect != null) - EffectManager.DisableInactiveGame(); - - if (EffectManager.ActiveEffect is ProfilePreviewModel) - return; - - // If the currently active effect is a no longer running game, get rid of it. - var activeGame = EffectManager.ActiveEffect as GameModel; - if (activeGame != null) - { - if (!runningProcesses.Any(p => p.ProcessName == activeGame.ProcessName && p.HasExited == false)) - { - _logger.Info("Disabling game: {0}", activeGame.Name); - EffectManager.DisableGame(activeGame); - } - } - - // Look for running games, stopping on the first one that's found. - var newGame = EffectManager.EnabledGames - .FirstOrDefault(g => runningProcesses - .Any(p => p.ProcessName == g.ProcessName && p.HasExited == false)); - - // If it's not already enabled, do so. - if (newGame != null && EffectManager.ActiveEffect != newGame) - { - _logger.Info("Detected and enabling game: {0}", newGame.Name); - EffectManager.ChangeEffect(newGame, LoopManager); - } - - Thread.Sleep(1000); - } - } - - private void BackgroundWorkerExceptionCatcher(object sender, RunWorkerCompletedEventArgs e) - { - if (e.Error == null) + if (!ProgramEnabled) return; - _logger.Error(e.Error, "Exception in the BackgroundWorker"); - throw e.Error; + var runningProcesses = Process.GetProcesses(); + + // If the currently active effect is a disabled game, get rid of it. + if (EffectManager.ActiveEffect != null) + EffectManager.DisableInactiveGame(); + + if (EffectManager.ActiveEffect is ProfilePreviewModel) + return; + + // If the currently active effect is a no longer running game, get rid of it. + var activeGame = EffectManager.ActiveEffect as GameModel; + if (activeGame != null) + { + if (!runningProcesses.Any(p => p.ProcessName == activeGame.ProcessName && p.HasExited == false)) + { + _logger.Info("Disabling game: {0}", activeGame.Name); + EffectManager.DisableGame(activeGame); + } + } + + // Look for running games, stopping on the first one that's found. + var newGame = EffectManager.EnabledGames + .FirstOrDefault(g => runningProcesses + .Any(p => p.ProcessName == g.ProcessName && p.HasExited == false)); + + if (newGame == null || EffectManager.ActiveEffect == newGame) + return; + // If it's not already enabled, do so. + _logger.Info("Detected and enabling game: {0}", newGame.Name); + EffectManager.ChangeEffect(newGame, LoopManager); } } } \ No newline at end of file diff --git a/Artemis/Artemis/Models/Profiles/Properties/DynamicPropertiesModel.cs b/Artemis/Artemis/Models/Profiles/Properties/DynamicPropertiesModel.cs index 952a55b6f..186d70878 100644 --- a/Artemis/Artemis/Models/Profiles/Properties/DynamicPropertiesModel.cs +++ b/Artemis/Artemis/Models/Profiles/Properties/DynamicPropertiesModel.cs @@ -1,4 +1,5 @@ -using System.ComponentModel; +using System; +using System.ComponentModel; using Artemis.Models.Interfaces; using Artemis.Utilities; using static System.Decimal; @@ -31,10 +32,7 @@ namespace Artemis.Models.Profiles.Properties /// Type of property /// public LayerPropertyType LayerPropertyType { get; set; } - - - internal void ApplyProperty(IGameDataModel dataModel, KeyboardPropertiesModel properties) { if (LayerPropertyType == LayerPropertyType.PercentageOf) @@ -55,23 +53,24 @@ namespace Artemis.Models.Profiles.Properties return; var percentage = ToDouble(gameProperty)/percentageSource; - var appliedValue = percentage*(double) layerProp.GetValue(layerProp, null); + var appliedValue = percentage*(double)layerProp.GetValue(properties); // Opacity requires some special treatment as it causes an exception if it's < 0.0 or > 1.0 if (LayerProperty == "Opacity") { + appliedValue = percentage; if (appliedValue < 0.0) appliedValue = 0.0; if (appliedValue > 1.0) appliedValue = 1.0; } - layerProp.SetValue(layerProp, appliedValue); + layerProp.SetValue(properties, appliedValue); } private void ApplyPercentageOfProperty(IGameDataModel dataModel, KeyboardPropertiesModel properties) { - var value = dataModel.GetPropValue(PercentageProperty); + var value = dataModel.GetPropValue(PercentageProperty); ApplyPercentageOf(dataModel, properties, value); } } diff --git a/Artemis/Artemis/Utilities/Layers/Drawer.cs b/Artemis/Artemis/Utilities/Layers/Drawer.cs index da6169404..5bc5ff572 100644 --- a/Artemis/Artemis/Utilities/Layers/Drawer.cs +++ b/Artemis/Artemis/Utilities/Layers/Drawer.cs @@ -52,20 +52,23 @@ namespace Artemis.Utilities.Layers private static void DrawRectangle(DrawingContext c, KeyboardPropertiesModel properties, Rect rectangle, Rect slide1, Rect slide2) { + var brush = properties.Brush.CloneCurrentValue(); + brush.Opacity = properties.Opacity; + // TODO: Implement clipping modes // Most animation types can be drawn regularly if (properties.Animation == LayerAnimation.None || properties.Animation == LayerAnimation.Grow || properties.Animation == LayerAnimation.Pulse) { - c.DrawRectangle(properties.Brush, null, rectangle); + c.DrawRectangle(brush, null, rectangle); } // Sliding animations however, require offsetting two rects else { c.PushClip(new RectangleGeometry(rectangle)); - c.DrawRectangle(properties.Brush, null, slide1); - c.DrawRectangle(properties.Brush, null, slide2); + c.DrawRectangle(brush, null, slide1); + c.DrawRectangle(brush, null, slide2); c.Pop(); } } diff --git a/Artemis/Artemis/ViewModels/LayerEditor/KeyboardPropertiesViewModel.cs b/Artemis/Artemis/ViewModels/LayerEditor/KeyboardPropertiesViewModel.cs index f49255b4a..001e2f648 100644 --- a/Artemis/Artemis/ViewModels/LayerEditor/KeyboardPropertiesViewModel.cs +++ b/Artemis/Artemis/ViewModels/LayerEditor/KeyboardPropertiesViewModel.cs @@ -57,9 +57,10 @@ namespace Artemis.ViewModels.LayerEditor public override LayerPropertiesModel GetAppliedProperties() { - HeightProperties.Apply(); - WidthProperties.Apply(); - OpacityProperties.Apply(); + + HeightProperties.Apply(ProposedProperties); + WidthProperties.Apply(ProposedProperties); + OpacityProperties.Apply(ProposedProperties); return GeneralHelpers.Clone(ProposedProperties); } diff --git a/Artemis/Artemis/ViewModels/LayerEditor/LayerDynamicPropertiesViewModel.cs b/Artemis/Artemis/ViewModels/LayerEditor/LayerDynamicPropertiesViewModel.cs index 46093a0b9..6aaf24fd4 100644 --- a/Artemis/Artemis/ViewModels/LayerEditor/LayerDynamicPropertiesViewModel.cs +++ b/Artemis/Artemis/ViewModels/LayerEditor/LayerDynamicPropertiesViewModel.cs @@ -8,7 +8,6 @@ namespace Artemis.ViewModels.LayerEditor { public sealed class LayerDynamicPropertiesViewModel : PropertyChangedBase { - private readonly KeyboardPropertiesModel _keyboardProperties; private readonly string _property; private DynamicPropertiesModel _proposed; private LayerPropertyType _layerPropertyType; @@ -21,11 +20,10 @@ namespace Artemis.ViewModels.LayerEditor public LayerDynamicPropertiesViewModel(string property, BindableCollection dataModelProps, KeyboardPropertiesModel keyboardProperties) { _property = property; - _keyboardProperties = keyboardProperties; // Look for the existing property model Proposed = new DynamicPropertiesModel(); - var original = _keyboardProperties.DynamicProperties.FirstOrDefault(lp => lp.LayerProperty == _property); + var original = keyboardProperties.DynamicProperties.FirstOrDefault(lp => lp.LayerProperty == _property); if (original == null) { Proposed.LayerProperty = property; @@ -142,13 +140,13 @@ namespace Artemis.ViewModels.LayerEditor } } - public void Apply() + public void Apply(KeyboardPropertiesModel keyboardProperties) { - var original = _keyboardProperties.DynamicProperties.FirstOrDefault(lp => lp.LayerProperty == _property); - if (original == null) - _keyboardProperties.DynamicProperties.Add(Proposed); - else - GeneralHelpers.CopyProperties(original, Proposed); + var original = keyboardProperties.DynamicProperties.FirstOrDefault(lp => lp.LayerProperty == _property); + if (original != null) + keyboardProperties.DynamicProperties.Remove(original); + + keyboardProperties.DynamicProperties.Add(Proposed); } } } \ No newline at end of file