diff --git a/src/Artemis.Core/Plugins/ScriptingProviders/Scripts/ProfileScript.cs b/src/Artemis.Core/Plugins/ScriptingProviders/Scripts/ProfileScript.cs index 5822e1884..8b5f18ce4 100644 --- a/src/Artemis.Core/Plugins/ScriptingProviders/Scripts/ProfileScript.cs +++ b/src/Artemis.Core/Plugins/ScriptingProviders/Scripts/ProfileScript.cs @@ -11,10 +11,6 @@ namespace Artemis.Core.ScriptingProviders protected ProfileScript(Profile profile, ScriptConfiguration configuration) : base(configuration) { Profile = profile; - lock (Profile.Scripts) - { - Profile.Scripts.Add(this); - } } /// diff --git a/src/Artemis.Core/Plugins/ScriptingProviders/Scripts/Script.cs b/src/Artemis.Core/Plugins/ScriptingProviders/Scripts/Script.cs index 1ddd8e5ac..279c18252 100644 --- a/src/Artemis.Core/Plugins/ScriptingProviders/Scripts/Script.cs +++ b/src/Artemis.Core/Plugins/ScriptingProviders/Scripts/Script.cs @@ -20,8 +20,6 @@ namespace Artemis.Core.ScriptingProviders throw new ArtemisCoreException("The provided script configuration already has an active script"); ScriptConfiguration = configuration; - ScriptConfiguration.Script = this; - ScriptConfiguration.PropertyChanged += ScriptConfigurationOnPropertyChanged; } diff --git a/src/Artemis.Core/Services/Input/InputService.cs b/src/Artemis.Core/Services/Input/InputService.cs index abb7ef643..9b42bc54f 100644 --- a/src/Artemis.Core/Services/Input/InputService.cs +++ b/src/Artemis.Core/Services/Input/InputService.cs @@ -305,10 +305,17 @@ namespace Artemis.Core.Services } } + public bool IsKeyDown(KeyboardKey key) + { + return _pressedKeys.Any(p => p.Value.Contains(key)); + } + #endregion #region Mouse + private readonly HashSet _pressedButtons = new(); + private void InputProviderOnMouseButtonDataReceived(object? sender, InputProviderMouseButtonEventArgs e) { bool foundLedId = InputKeyUtilities.MouseButtonLedIdMap.TryGetValue(e.Button, out LedId ledId); @@ -320,9 +327,17 @@ namespace Artemis.Core.Services ArtemisMouseButtonUpDownEventArgs eventArgs = new(e.Device, led, e.Button, e.IsDown); OnMouseButtonUpDown(eventArgs); if (e.IsDown) + { + if (!_pressedButtons.Contains(e.Button)) + _pressedButtons.Add(e.Button); OnMouseButtonDown(eventArgs); + } else + { + if (_pressedButtons.Contains(e.Button)) + _pressedButtons.Remove(e.Button); OnMouseButtonUp(eventArgs); + } // _logger.Verbose("Mouse button data: LED ID: {ledId}, button: {button}, is down: {isDown}, device: {device} ", ledId, e.Button, e.IsDown, e.Device); } @@ -339,6 +354,11 @@ namespace Artemis.Core.Services // _logger.Verbose("Mouse move data: XY: {X},{Y} - delta XY: {deltaX},{deltaY} - device: {device} ", e.CursorX, e.CursorY, e.DeltaX, e.DeltaY, e.Device); } + public bool IsButtonDown(MouseButton button) + { + return _pressedButtons.Contains(button); + } + #endregion #region Events diff --git a/src/Artemis.Core/Services/Input/Interfaces/IInputService.cs b/src/Artemis.Core/Services/Input/Interfaces/IInputService.cs index 3c2936354..19985f2de 100644 --- a/src/Artemis.Core/Services/Input/Interfaces/IInputService.cs +++ b/src/Artemis.Core/Services/Input/Interfaces/IInputService.cs @@ -40,7 +40,19 @@ namespace Artemis.Core.Services /// void ReleaseAll(); - #region Events + /// + /// Determines whether the provided key is pressed by any device + /// + /// The key to check + /// if the key is pressed; otherwise + bool IsKeyDown(KeyboardKey key); + + /// + /// Determines whether the button key is pressed by any device + /// + /// The button to check + /// if the button is pressed; otherwise + bool IsButtonDown(MouseButton button); /// /// Occurs whenever a key on a keyboard was pressed or released @@ -92,8 +104,6 @@ namespace Artemis.Core.Services /// public event EventHandler DeviceIdentified; - #endregion - #region Identification /// diff --git a/src/Artemis.Core/Services/ScriptingService.cs b/src/Artemis.Core/Services/ScriptingService.cs index 38db76e16..36b030d1f 100644 --- a/src/Artemis.Core/Services/ScriptingService.cs +++ b/src/Artemis.Core/Services/ScriptingService.cs @@ -6,17 +6,20 @@ using System.Reflection; using Artemis.Core.ScriptingProviders; using Ninject; using Ninject.Parameters; +using Serilog; namespace Artemis.Core.Services { internal class ScriptingService : IScriptingService { + private readonly ILogger _logger; private readonly IPluginManagementService _pluginManagementService; private readonly IProfileService _profileService; private List _scriptingProviders; - public ScriptingService(IPluginManagementService pluginManagementService, IProfileService profileService) + public ScriptingService(ILogger logger, IPluginManagementService pluginManagementService, IProfileService profileService) { + _logger = logger; _pluginManagementService = pluginManagementService; _profileService = profileService; @@ -81,43 +84,71 @@ namespace Artemis.Core.Services public GlobalScript? CreateScriptInstance(ScriptConfiguration scriptConfiguration) { - if (scriptConfiguration.Script != null) - throw new ArtemisCoreException("The provided script configuration already has an active script"); + GlobalScript? script = null; + try + { + if (scriptConfiguration.Script != null) + throw new ArtemisCoreException("The provided script configuration already has an active script"); - ScriptingProvider? provider = _scriptingProviders.FirstOrDefault(p => p.Id == scriptConfiguration.ScriptingProviderId); - if (provider == null) + ScriptingProvider? provider = _scriptingProviders.FirstOrDefault(p => p.Id == scriptConfiguration.ScriptingProviderId); + if (provider == null) + return null; + + script = (GlobalScript) provider.Plugin.Kernel!.Get( + provider.GlobalScriptType, + CreateScriptConstructorArgument(provider.GlobalScriptType, scriptConfiguration) + ); + + script.ScriptingProvider = provider; + script.ScriptingService = this; + provider.InternalScripts.Add(script); + InternalGlobalScripts.Add(script); + + scriptConfiguration.Script = script; + return script; + } + catch (Exception e) + { + _logger.Warning(e, "Failed to initialize global script"); + script?.Dispose(); return null; - - GlobalScript script = (GlobalScript) provider.Plugin.Kernel!.Get( - provider.GlobalScriptType, - CreateScriptConstructorArgument(provider.GlobalScriptType, scriptConfiguration) - ); - - script.ScriptingProvider = provider; - script.ScriptingService = this; - provider.InternalScripts.Add(script); - InternalGlobalScripts.Add(script); - return script; + } } public ProfileScript? CreateScriptInstance(Profile profile, ScriptConfiguration scriptConfiguration) { - if (scriptConfiguration.Script != null) - throw new ArtemisCoreException("The provided script configuration already has an active script"); + ProfileScript? script = null; + try + { + if (scriptConfiguration.Script != null) + throw new ArtemisCoreException("The provided script configuration already has an active script"); - ScriptingProvider? provider = _scriptingProviders.FirstOrDefault(p => p.Id == scriptConfiguration.ScriptingProviderId); - if (provider == null) + ScriptingProvider? provider = _scriptingProviders.FirstOrDefault(p => p.Id == scriptConfiguration.ScriptingProviderId); + if (provider == null) + return null; + + script = (ProfileScript) provider.Plugin.Kernel!.Get( + provider.ProfileScriptType, + CreateScriptConstructorArgument(provider.ProfileScriptType, profile), + CreateScriptConstructorArgument(provider.ProfileScriptType, scriptConfiguration) + ); + + script.ScriptingProvider = provider; + provider.InternalScripts.Add(script); + lock (profile) + { + scriptConfiguration.Script = script; + profile.Scripts.Add(script); + } + + return script; + } + catch (Exception e) + { + _logger.Warning(e, "Failed to initialize profile script"); + script?.Dispose(); return null; - - ProfileScript script = (ProfileScript) provider.Plugin.Kernel!.Get( - provider.ProfileScriptType, - CreateScriptConstructorArgument(provider.ProfileScriptType, profile), - CreateScriptConstructorArgument(provider.ProfileScriptType, scriptConfiguration) - ); - - script.ScriptingProvider = provider; - provider.InternalScripts.Add(script); - return script; + } } /// diff --git a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/Timeline/Dialogs/TimelineSegmentDialogViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/Timeline/Dialogs/TimelineSegmentDialogViewModel.cs index 4267951b9..8f2b0585a 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/Timeline/Dialogs/TimelineSegmentDialogViewModel.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/Timeline/Dialogs/TimelineSegmentDialogViewModel.cs @@ -3,7 +3,6 @@ using System.Globalization; using System.Text.RegularExpressions; using System.Threading.Tasks; using Artemis.UI.Shared.Services; -using Castle.Core.Internal; using FluentValidation; using Stylet; @@ -70,7 +69,7 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.Timeline.Dialogs if (parts.Length == 1) return TimeSpan.FromSeconds(double.Parse(parts[0])); // Only milliseconds provided with a leading . - if (parts[0].IsNullOrEmpty()) + if (string.IsNullOrEmpty(parts[0])) { // Add trailing zeros so 2.5 becomes 2.500, can't seem to make double.Parse do that while (parts[0].Length < 3) parts[0] += "0"; diff --git a/src/Artemis.UI/Screens/Settings/Tabs/About/AboutTabView.xaml b/src/Artemis.UI/Screens/Settings/Tabs/About/AboutTabView.xaml index 6167eafe1..95db917e2 100644 --- a/src/Artemis.UI/Screens/Settings/Tabs/About/AboutTabView.xaml +++ b/src/Artemis.UI/Screens/Settings/Tabs/About/AboutTabView.xaml @@ -96,7 +96,7 @@ Grid.Column="1" Style="{StaticResource MaterialDesignBody1TextBlock}" Padding="0"> - Robert 'Spoinky' Beekman + Robert Beekman + CommandParameter="https://github.com/RobertWasTaken/">