From cf58acc7d2792a4cd18f704cb0ce502dce867aaf Mon Sep 17 00:00:00 2001 From: Robert Date: Sat, 27 Aug 2022 12:12:47 +0200 Subject: [PATCH 1/5] Easing nodes - Fixed going into a broken state when delay is 0 Numeric easing node - Fixed node not functioning at all Event cycle node - Fixed node not functioning at all --- src/Artemis.Core/Services/ScriptingService.cs | 4 ++-- src/Artemis.Core/VisualScripting/Node.cs | 19 +++++++++++++++---- .../Nodes/Easing/NumericEasingNode.cs | 6 ++++-- .../Nodes/Easing/SKColorEasingNode.cs | 3 ++- 4 files changed, 23 insertions(+), 9 deletions(-) diff --git a/src/Artemis.Core/Services/ScriptingService.cs b/src/Artemis.Core/Services/ScriptingService.cs index 6a6f859bd..ef9b8a5ad 100644 --- a/src/Artemis.Core/Services/ScriptingService.cs +++ b/src/Artemis.Core/Services/ScriptingService.cs @@ -121,9 +121,9 @@ internal class ScriptingService : IScriptingService throw new ArtemisCoreException("Scripts must have exactly one constructor"); // Find the ScriptConfiguration parameter, it is required by the base constructor so its there for sure - ParameterInfo configurationParameter = constructors.First().GetParameters().First(p => value.GetType().IsAssignableFrom(p.ParameterType)); + ParameterInfo? configurationParameter = constructors.First().GetParameters().FirstOrDefault(p => value.GetType().IsAssignableFrom(p.ParameterType)); - if (configurationParameter.Name == null) + if (configurationParameter?.Name == null) throw new ArtemisCoreException($"Couldn't find a valid constructor argument on {scriptType.Name} with type {value.GetType().Name}"); return new ConstructorArgument(configurationParameter.Name, value); } diff --git a/src/Artemis.Core/VisualScripting/Node.cs b/src/Artemis.Core/VisualScripting/Node.cs index bcca27806..fd73af8b8 100644 --- a/src/Artemis.Core/VisualScripting/Node.cs +++ b/src/Artemis.Core/VisualScripting/Node.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; +using System.Reflection; using Ninject; using Ninject.Parameters; @@ -16,7 +17,7 @@ public abstract class Node : CorePropertyChanged, INode public event EventHandler? Resetting; #region Properties & Fields - + private readonly List _outputPinBucket = new(); private readonly List _inputPinBucket = new(); @@ -164,7 +165,7 @@ public abstract class Node : CorePropertyChanged, INode OnPropertyChanged(nameof(Pins)); return pin; } - + /// /// Creates or adds an output pin to the node using a bucket. /// The bucket might grow a bit over time as the user edits the node but pins won't get lost, enabling undo/redo in the @@ -194,7 +195,7 @@ public abstract class Node : CorePropertyChanged, INode return pin; } - + /// /// Creates or adds an input pin to the node using a bucket. /// The bucket might grow a bit over time as the user edits the node but pins won't get lost, enabling undo/redo in the @@ -447,7 +448,17 @@ public abstract class Node : Node where TViewMod /// public virtual TViewModel GetViewModel(NodeScript nodeScript) { - return Kernel.Get(new ConstructorArgument("node", this), new ConstructorArgument("script", nodeScript)); + // Limit to one constructor, there's no need to have more and it complicates things anyway + ConstructorInfo[] constructors = typeof(TViewModel).GetConstructors(); + if (constructors.Length != 1) + throw new ArtemisCoreException("Node VMs must have exactly one constructor"); + + // Find the ScriptConfiguration parameter, it is required by the base constructor so its there for sure + ParameterInfo? configurationParameter = constructors.First().GetParameters().FirstOrDefault(p => GetType().IsAssignableFrom(p.ParameterType)); + + if (configurationParameter?.Name == null) + throw new ArtemisCoreException($"Couldn't find a valid constructor argument on {typeof(TViewModel).Name} with type {GetType().Name}"); + return Kernel.Get(new ConstructorArgument(configurationParameter.Name, this), new ConstructorArgument("script", nodeScript)); } /// diff --git a/src/Artemis.VisualScripting/Nodes/Easing/NumericEasingNode.cs b/src/Artemis.VisualScripting/Nodes/Easing/NumericEasingNode.cs index 9fe327f8a..3aee1d5c4 100644 --- a/src/Artemis.VisualScripting/Nodes/Easing/NumericEasingNode.cs +++ b/src/Artemis.VisualScripting/Nodes/Easing/NumericEasingNode.cs @@ -29,9 +29,10 @@ public class NumericEasingNode : Node public override void Evaluate() { DateTime now = DateTime.Now; + float inputValue = Input.Value; // If the value changed reset progress - if (Math.Abs(_targetValue - Input.Value) > 0.001f) + if (Math.Abs(_targetValue - inputValue) > 0.001f) { _sourceValue = _currentValue; _targetValue = Input.Value; @@ -55,10 +56,11 @@ public class NumericEasingNode : Node private void Update() { + float easingTime = EasingTime.Value != 0f ? EasingTime.Value : 1f; TimeSpan delta = DateTime.Now - _lastEvaluate; // In case of odd delta's, keep progress between 0f and 1f - _progress = Math.Clamp(_progress + (float) delta.TotalMilliseconds / EasingTime.Value, 0f, 1f); + _progress = Math.Clamp(_progress + (float) delta.TotalMilliseconds / easingTime, 0f, 1f); double eased = _sourceValue + (_targetValue - _sourceValue) * Easings.Interpolate(_progress, EasingFunction.Value); _currentValue = (float) eased; diff --git a/src/Artemis.VisualScripting/Nodes/Easing/SKColorEasingNode.cs b/src/Artemis.VisualScripting/Nodes/Easing/SKColorEasingNode.cs index 9c2d50062..e4f65536d 100644 --- a/src/Artemis.VisualScripting/Nodes/Easing/SKColorEasingNode.cs +++ b/src/Artemis.VisualScripting/Nodes/Easing/SKColorEasingNode.cs @@ -56,10 +56,11 @@ public class SKColorEasingNode : Node private void Update() { + float easingTime = EasingTime.Value != 0f ? EasingTime.Value : 1f; TimeSpan delta = DateTime.Now - _lastEvaluate; // In case of odd delta's, keep progress between 0f and 1f - _progress = Math.Clamp(_progress + (float) delta.TotalMilliseconds / EasingTime.Value, 0f, 1f); + _progress = Math.Clamp(_progress + (float) delta.TotalMilliseconds / easingTime, 0f, 1f); _currentValue = _sourceValue.Interpolate(_targetValue, (float) Easings.Interpolate(_progress, EasingFunction.Value)); } } \ No newline at end of file From c5a1777cf6963ad0fa5a0d3ff8db8fed4b9600f7 Mon Sep 17 00:00:00 2001 From: Robert Date: Sat, 27 Aug 2022 21:53:01 +0200 Subject: [PATCH 2/5] Nodes - Fixed memory leak --- src/Artemis.Core/VisualScripting/PinCollection.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Artemis.Core/VisualScripting/PinCollection.cs b/src/Artemis.Core/VisualScripting/PinCollection.cs index ceb556a94..d2ea74a69 100644 --- a/src/Artemis.Core/VisualScripting/PinCollection.cs +++ b/src/Artemis.Core/VisualScripting/PinCollection.cs @@ -45,12 +45,12 @@ public abstract class PinCollection : CorePropertyChanged, IPinCollection /// public abstract Type Type { get; } - private readonly ObservableCollection _pins = new(); + private readonly List _pins = new(); /// /// Gets a read only observable collection of the pins /// - public ReadOnlyObservableCollection Pins => new(_pins); + public ReadOnlyCollection Pins => new(_pins); #endregion From 08bef79b2fee187b3b9be4a4f705cbe00cf480cd Mon Sep 17 00:00:00 2001 From: Diogo Trindade Date: Sat, 20 Aug 2022 22:00:42 +0100 Subject: [PATCH 3/5] CI - Added Linux build --- ci/azure-pipelines.yml | 101 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 98 insertions(+), 3 deletions(-) diff --git a/ci/azure-pipelines.yml b/ci/azure-pipelines.yml index 6b680e70c..19ae253af 100644 --- a/ci/azure-pipelines.yml +++ b/ci/azure-pipelines.yml @@ -15,11 +15,9 @@ resources: name: Artemis-RGB/Artemis.Plugins ref: master -pool: - vmImage: "windows-latest" - variables: windowsProject: "**/Artemis.UI.Windows/Artemis.UI.Windows.csproj" + linuxProject: "**/Artemis.UI.Linux/Artemis.UI.Linux.csproj" pluginProjects: "**/Artemis.Plugins.*.csproj" BuildId: $(Build.BuildId) BuildNumber: $(Build.BuildNumber) @@ -28,6 +26,8 @@ variables: jobs: - job: Windows + pool: + vmImage: "windows-latest" steps: - checkout: self path: s/Artemis @@ -119,3 +119,98 @@ jobs: clean: false preservePaths: true trustSSL: false + + - job: Linux + pool: + vmImage: "ubuntu-latest" + steps: + - checkout: self + path: s/Artemis + - checkout: Plugins + path: s/Artemis.Plugins + + - task: DotNetCoreCLI@2 + displayName: "Artemis - Publish" + inputs: + command: "publish" + publishWebProjects: false + projects: "$(linuxProject)" + arguments: '--configuration Release --runtime linux-x64 --output $(Build.ArtifactStagingDirectory)/linux-build /nowarn:cs1591' + zipAfterPublish: false + modifyOutputPath: false + + - task: PowerShell@2 + displayName: "Artemis - Create buildinfo.json" + inputs: + targetType: "inline" + script: | + $OFS = "`r`n" + SET-Content -Path 'buildinfo.json' -Value ('{' + $OFS + ' "BuildId": 0,' + $OFS + ' "BuildNumber": 0.0,' + $OFS + ' "SourceBranch": "",' + $OFS + ' "SourceVersion": ""' + $OFS + '}') + workingDirectory: "$(Build.ArtifactStagingDirectory)/linux-build" + + - task: FileTransform@1 + displayName: "Artemis - Populate buildinfo.json" + inputs: + folderPath: "$(Build.ArtifactStagingDirectory)/linux-build" + fileType: "json" + targetFiles: "**/buildinfo.json" + + - task: PowerShell@2 + displayName: "Plugins - Insert build number into plugin.json" + inputs: + targetType: "inline" + script: | + Get-ChildItem -Recurse -Filter plugin.json | + Foreach-Object { + $buidNumber = "1.0.1." + $Env:BUILD_BUILDID; + $a = Get-Content $_.FullName | ConvertFrom-Json + $a.Version = $buidNumber; + $a | ConvertTo-Json | Set-Content $_.FullName + } + workingDirectory: "Artemis.Plugins" + + - task: DotNetCoreCLI@2 + displayName: "Plugins - Publish" + inputs: + command: "publish" + publishWebProjects: false + arguments: "--configuration Release --runtime linux-x64 --output $(Build.ArtifactStagingDirectory)/linux-build/Plugins" + projects: "$(pluginProjects)" + zipAfterPublish: true + + - task: PublishPipelineArtifact@1 + displayName: "Upload build to Azure Pipelines" + inputs: + targetPath: "$(Build.ArtifactStagingDirectory)/linux-build" + artifact: "Artemis build" + publishLocation: "pipeline" + + - task: ArchiveFiles@2 + displayName: "ZIP binaries" + inputs: + rootFolderOrFile: "$(Build.ArtifactStagingDirectory)/linux-build" + includeRootFolder: false + archiveType: "zip" + archiveFile: "$(Build.ArtifactStagingDirectory)/archive/artemis-build-linux.zip" + replaceExistingArchive: true + + - task: PowerShell@2 + displayName: "Calculate ZIP hash" + inputs: + targetType: "inline" + script: '(Get-FileHash .\artemis-build-linux.zip).Hash | Out-File -FilePath .\hash-linux.txt' + workingDirectory: "$(Build.ArtifactStagingDirectory)/archive" + + - task: FtpUpload@2 + displayName: "Upload binaries to FTP" + inputs: + credentialsOption: "inputs" + serverUrl: "ftp://artemis-rgb.com" + username: "devops" + password: "$(ftp_password)" + rootDirectory: "$(Build.ArtifactStagingDirectory)/archive" + filePatterns: "**" + remoteDirectory: "/builds.artemis-rgb.com/binaries/$(Build.SourceBranchName)/$(Build.BuildNumber)" + clean: false + preservePaths: true + trustSSL: false From 04ef4f0173a2b3b8855c25cc60790e45365a9786 Mon Sep 17 00:00:00 2001 From: Diogo Trindade Date: Thu, 25 Aug 2022 14:40:07 +0100 Subject: [PATCH 4/5] LinuxInputProvider - Fixed missing key map --- src/Artemis.UI.Linux/Utilities/InputUtilities.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Artemis.UI.Linux/Utilities/InputUtilities.cs b/src/Artemis.UI.Linux/Utilities/InputUtilities.cs index d9bd3de48..44017e602 100644 --- a/src/Artemis.UI.Linux/Utilities/InputUtilities.cs +++ b/src/Artemis.UI.Linux/Utilities/InputUtilities.cs @@ -107,7 +107,7 @@ public static class InputUtilities LinuxKeyboardKeyCodes.KEY_KPENTER => KeyboardKey.NumPadEnter, LinuxKeyboardKeyCodes.KEY_RIGHTCTRL => KeyboardKey.RightCtrl, LinuxKeyboardKeyCodes.KEY_KPSLASH => KeyboardKey.Divide, - LinuxKeyboardKeyCodes.KEY_SYSRQ => KeyboardKey.System, //TODO:? + LinuxKeyboardKeyCodes.KEY_SYSRQ => KeyboardKey.PrintScreen, LinuxKeyboardKeyCodes.KEY_RIGHTALT => KeyboardKey.RightAlt, LinuxKeyboardKeyCodes.KEY_LINEFEED => KeyboardKey.LineFeed, LinuxKeyboardKeyCodes.KEY_HOME => KeyboardKey.Home, @@ -135,7 +135,7 @@ public static class InputUtilities // LinuxKeyboardKeyCodes.KEY_YEN => expr, LinuxKeyboardKeyCodes.KEY_LEFTMETA => KeyboardKey.LWin, LinuxKeyboardKeyCodes.KEY_RIGHTMETA => KeyboardKey.RWin, - // LinuxKeyboardKeyCodes.KEY_COMPOSE => , + LinuxKeyboardKeyCodes.KEY_COMPOSE => KeyboardKey.Apps, LinuxKeyboardKeyCodes.KEY_STOP => KeyboardKey.MediaStop, // LinuxKeyboardKeyCodes.KEY_AGAIN => , // LinuxKeyboardKeyCodes.KEY_PROPS => expr, From ddfdbee340f425f4375bceb45bf430d02ee2890c Mon Sep 17 00:00:00 2001 From: Diogo Trindade Date: Sat, 27 Aug 2022 21:40:02 +0100 Subject: [PATCH 5/5] Linux - Fixed a couple small issues --- .../ProcessMonitor/ProcessMonitorService.cs | 4 ++-- .../Providers/Input/LinuxInputProvider.cs | 13 ++++++++++++- .../Panels/ProfileTree/TreeItemViewModel.cs | 6 ++++++ 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/Artemis.Core/Services/ProcessMonitor/ProcessMonitorService.cs b/src/Artemis.Core/Services/ProcessMonitor/ProcessMonitorService.cs index 959af2e55..e832df0b9 100644 --- a/src/Artemis.Core/Services/ProcessMonitor/ProcessMonitorService.cs +++ b/src/Artemis.Core/Services/ProcessMonitor/ProcessMonitorService.cs @@ -32,13 +32,13 @@ internal class ProcessMonitorService : IProcessMonitorService foreach (Process startedProcess in newProcesses.Except(_lastScannedProcesses, _comparer)) { ProcessStarted?.Invoke(this, new ProcessEventArgs(startedProcess)); - _logger.Verbose("Started Process: {startedProcess}", startedProcess.ProcessName); + //_logger.Verbose("Started Process: {startedProcess}", startedProcess.ProcessName); } foreach (Process stoppedProcess in _lastScannedProcesses.Except(newProcesses, _comparer)) { ProcessStopped?.Invoke(this, new ProcessEventArgs(stoppedProcess)); - _logger.Verbose("Stopped Process: {stoppedProcess}", stoppedProcess.ProcessName); + //_logger.Verbose("Stopped Process: {stoppedProcess}", stoppedProcess.ProcessName); } _lastScannedProcesses = newProcesses; diff --git a/src/Artemis.UI.Linux/Providers/Input/LinuxInputProvider.cs b/src/Artemis.UI.Linux/Providers/Input/LinuxInputProvider.cs index eca27fa2b..c903a1d84 100644 --- a/src/Artemis.UI.Linux/Providers/Input/LinuxInputProvider.cs +++ b/src/Artemis.UI.Linux/Providers/Input/LinuxInputProvider.cs @@ -112,7 +112,18 @@ public class LinuxInputProvider : InputProvider switch (args.Type) { case LinuxInputEventType.KEY: - bool isDown = args.Value != 0; + var key = (LinuxKeyboardKeyCodes)args.Code; + if (key == LinuxKeyboardKeyCodes.BTN_TOUCH || + (key >= LinuxKeyboardKeyCodes.BTN_TOOL_PEN && key <= LinuxKeyboardKeyCodes.BTN_TOOL_QUADTAP)) + { + //trackpad input, ignore. + return; + } + + //0 - up + //1 - down + //2 - repeat input + bool isDown = args.Value == 1; MouseButton button = InputUtilities.MouseButtonFromButtonCode((LinuxKeyboardKeyCodes) args.Code); //_logger.Verbose($"Mouse Button: {(LinuxKeyboardKeyCodes)args.Code} | Down: {isDown}"); diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/TreeItemViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/TreeItemViewModel.cs index 1511bc16d..6ccaea894 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/TreeItemViewModel.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/TreeItemViewModel.cs @@ -287,6 +287,12 @@ public abstract class TreeItemViewModel : ActivatableViewModelBase } string[] formats = await Application.Current.Clipboard.GetFormatsAsync(); + //diogotr7: This can be null on Linux sometimes. I'm not sure why. + if (formats == null) + { + CanPaste = false; + return; + } CanPaste = formats.Contains(ProfileElementExtensions.ClipboardDataFormat); }