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