diff --git a/src/Artemis.UI.Shared/Services/NodeEditor/Commands/DisconnectPins.cs b/src/Artemis.UI.Shared/Services/NodeEditor/Commands/DisconnectPins.cs
new file mode 100644
index 000000000..685350335
--- /dev/null
+++ b/src/Artemis.UI.Shared/Services/NodeEditor/Commands/DisconnectPins.cs
@@ -0,0 +1,43 @@
+using System.Collections.Generic;
+using Artemis.Core;
+
+namespace Artemis.UI.Shared.Services.NodeEditor.Commands;
+
+///
+/// Represents a node editor command that can be used to connect two pins.
+///
+public class DisconnectPins : INodeEditorCommand
+{
+ private readonly IPin _pin;
+ private readonly List _originalConnections;
+
+ ///
+ /// Creates a new instance of the class.
+ ///
+ /// The pin to disconnect.
+ public DisconnectPins(IPin pin)
+ {
+ _pin = pin;
+ _originalConnections = new List(_pin.ConnectedTo);
+ }
+
+ #region Implementation of INodeEditorCommand
+
+ ///
+ public string DisplayName => "Disconnect pins";
+
+ ///
+ public void Execute()
+ {
+ _pin.DisconnectAll();
+ }
+
+ ///
+ public void Undo()
+ {
+ foreach (IPin pin in _originalConnections)
+ _pin.ConnectTo(pin);
+ }
+
+ #endregion
+}
\ No newline at end of file
diff --git a/src/Artemis.UI/Ninject/Factories/IVMFactory.cs b/src/Artemis.UI/Ninject/Factories/IVMFactory.cs
index 989a1211f..be0109ed5 100644
--- a/src/Artemis.UI/Ninject/Factories/IVMFactory.cs
+++ b/src/Artemis.UI/Ninject/Factories/IVMFactory.cs
@@ -106,8 +106,8 @@ public interface INodeVmFactory : IVmFactory
NodeViewModel NodeViewModel(NodeScriptViewModel nodeScriptViewModel, INode node);
CableViewModel CableViewModel(NodeScriptViewModel nodeScriptViewModel, IPin from, IPin to);
DragCableViewModel DragCableViewModel(PinViewModel pinViewModel);
- InputPinViewModel InputPinViewModel(IPin inputPin);
- OutputPinViewModel OutputPinViewModel(IPin outputPin);
+ InputPinViewModel InputPinViewModel(IPin inputPin, NodeScriptViewModel nodeScriptViewModel);
+ OutputPinViewModel OutputPinViewModel(IPin outputPin, NodeScriptViewModel nodeScriptViewModel);
InputPinCollectionViewModel InputPinCollectionViewModel(IPinCollection inputPinCollection, NodeScriptViewModel nodeScriptViewModel);
OutputPinCollectionViewModel OutputPinCollectionViewModel(IPinCollection outputPinCollection, NodeScriptViewModel nodeScriptViewModel);
}
diff --git a/src/Artemis.UI/Screens/VisualScripting/NodeViewModel.cs b/src/Artemis.UI/Screens/VisualScripting/NodeViewModel.cs
index 79dca9758..c56b54bd7 100644
--- a/src/Artemis.UI/Screens/VisualScripting/NodeViewModel.cs
+++ b/src/Artemis.UI/Screens/VisualScripting/NodeViewModel.cs
@@ -47,12 +47,12 @@ public class NodeViewModel : ActivatableViewModelBase
// Create observable collections split up by direction
nodePins.Connect()
.Filter(n => n.Direction == PinDirection.Input)
- .Transform(p => (PinViewModel) nodeVmFactory.InputPinViewModel(p))
+ .Transform(p => (PinViewModel) nodeVmFactory.InputPinViewModel(p, nodeScriptViewModel))
.Bind(out ReadOnlyObservableCollection inputPins)
.Subscribe();
nodePins.Connect()
.Filter(n => n.Direction == PinDirection.Output)
- .Transform(p => (PinViewModel) nodeVmFactory.OutputPinViewModel(p))
+ .Transform(p => (PinViewModel) nodeVmFactory.OutputPinViewModel(p, nodeScriptViewModel))
.Bind(out ReadOnlyObservableCollection outputPins)
.Subscribe();
InputPinViewModels = inputPins;
diff --git a/src/Artemis.UI/Screens/VisualScripting/Pins/InputPinCollectionViewModel.cs b/src/Artemis.UI/Screens/VisualScripting/Pins/InputPinCollectionViewModel.cs
index 83a66fe5c..d6cfec82f 100644
--- a/src/Artemis.UI/Screens/VisualScripting/Pins/InputPinCollectionViewModel.cs
+++ b/src/Artemis.UI/Screens/VisualScripting/Pins/InputPinCollectionViewModel.cs
@@ -6,19 +6,21 @@ namespace Artemis.UI.Screens.VisualScripting.Pins;
public class InputPinCollectionViewModel : PinCollectionViewModel
{
+ private readonly NodeScriptViewModel _nodeScriptViewModel;
private readonly INodeVmFactory _nodeVmFactory;
public IPinCollection InputPinCollection { get; }
public InputPinCollectionViewModel(IPinCollection inputPinCollection, NodeScriptViewModel nodeScriptViewModel, INodeVmFactory nodeVmFactory, INodeEditorService nodeEditorService)
: base(inputPinCollection, nodeScriptViewModel, nodeEditorService)
{
+ _nodeScriptViewModel = nodeScriptViewModel;
_nodeVmFactory = nodeVmFactory;
InputPinCollection = inputPinCollection;
}
protected override PinViewModel CreatePinViewModel(IPin pin)
{
- PinViewModel vm = _nodeVmFactory.InputPinViewModel(pin);
+ PinViewModel vm = _nodeVmFactory.InputPinViewModel(pin, _nodeScriptViewModel);
vm.RemovePin = RemovePin;
return vm;
}
diff --git a/src/Artemis.UI/Screens/VisualScripting/Pins/InputPinView.axaml b/src/Artemis.UI/Screens/VisualScripting/Pins/InputPinView.axaml
index b995c00a1..330a18642 100644
--- a/src/Artemis.UI/Screens/VisualScripting/Pins/InputPinView.axaml
+++ b/src/Artemis.UI/Screens/VisualScripting/Pins/InputPinView.axaml
@@ -14,7 +14,7 @@
-
+
-
+
nodeEditorService.ExecuteCommand(nodeScriptViewModel.NodeScript, new DisconnectPins(Pin)));
+
SourceList connectedPins = new();
this.WhenActivated(d =>
{
@@ -78,6 +82,8 @@ public abstract class PinViewModel : ActivatableViewModelBase
set => RaiseAndSetIfChanged(ref _removePin, value);
}
+ public ReactiveCommand DisconnectPin { get; }
+
public bool IsCompatibleWith(PinViewModel pinViewModel)
{
if (pinViewModel.Pin.Direction == Pin.Direction || pinViewModel.Pin.Node == Pin.Node)
diff --git a/src/Artemis.VisualScripting/Artemis.VisualScripting.csproj b/src/Artemis.VisualScripting/Artemis.VisualScripting.csproj
index 8d46adae9..3a40c56b3 100644
--- a/src/Artemis.VisualScripting/Artemis.VisualScripting.csproj
+++ b/src/Artemis.VisualScripting/Artemis.VisualScripting.csproj
@@ -8,19 +8,19 @@
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
+
+
diff --git a/src/Artemis.VisualScripting/Nodes/Mathematics/MaxNode.cs b/src/Artemis.VisualScripting/Nodes/Mathematics/MaxNode.cs
new file mode 100644
index 000000000..001cca53f
--- /dev/null
+++ b/src/Artemis.VisualScripting/Nodes/Mathematics/MaxNode.cs
@@ -0,0 +1,35 @@
+using Artemis.Core;
+
+namespace Artemis.VisualScripting.Nodes.Mathematics;
+
+[Node("Max", "Outputs the largest of the connected numeric values.", "Mathematics", InputType = typeof(Numeric), OutputType = typeof(Numeric))]
+public class MaxNumericsNode : Node
+{
+ #region Constructors
+
+ public MaxNumericsNode()
+ : base("Max", "Outputs the largest of the connected numeric values.")
+ {
+ Values = CreateInputPinCollection("Values", 2);
+ Max = CreateOutputPin("Max");
+ }
+
+ #endregion
+
+ #region Methods
+
+ public override void Evaluate()
+ {
+ Max.Value = Values.Values.Max();
+ }
+
+ #endregion
+
+ #region Properties & Fields
+
+ public InputPinCollection Values { get; }
+
+ public OutputPin Max { get; }
+
+ #endregion
+}
\ No newline at end of file
diff --git a/src/Artemis.VisualScripting/Nodes/Mathematics/MinNode.cs b/src/Artemis.VisualScripting/Nodes/Mathematics/MinNode.cs
new file mode 100644
index 000000000..a10ff8c3a
--- /dev/null
+++ b/src/Artemis.VisualScripting/Nodes/Mathematics/MinNode.cs
@@ -0,0 +1,35 @@
+using Artemis.Core;
+
+namespace Artemis.VisualScripting.Nodes.Mathematics;
+
+[Node("Min", "Outputs the smallest of the connected numeric values.", "Mathematics", InputType = typeof(Numeric), OutputType = typeof(Numeric))]
+public class MinNumericsNode : Node
+{
+ #region Constructors
+
+ public MinNumericsNode()
+ : base("Min", "Outputs the smallest of the connected numeric values.")
+ {
+ Values = CreateInputPinCollection("Values", 2);
+ Min = CreateOutputPin("Min");
+ }
+
+ #endregion
+
+ #region Methods
+
+ public override void Evaluate()
+ {
+ Min.Value = Values.Values.Min();
+ }
+
+ #endregion
+
+ #region Properties & Fields
+
+ public InputPinCollection Values { get; }
+
+ public OutputPin Min { get; }
+
+ #endregion
+}
\ No newline at end of file