diff --git a/src/Artemis.Core/VisualScripting/Interfaces/INode.cs b/src/Artemis.Core/VisualScripting/Interfaces/INode.cs index 114048bcc..b5e16a50b 100644 --- a/src/Artemis.Core/VisualScripting/Interfaces/INode.cs +++ b/src/Artemis.Core/VisualScripting/Interfaces/INode.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.ComponentModel; +using Artemis.Core.Events; namespace Artemis.Core; @@ -58,6 +59,26 @@ public interface INode : INotifyPropertyChanged /// Called when the node resets /// event EventHandler Resetting; + + /// + /// Occurs when a pin was added to the node + /// + event EventHandler> PinAdded; + + /// + /// Occurs when a pin was removed from the node + /// + event EventHandler> PinRemoved; + + /// + /// Occurs when a pin collection was added to the node + /// + event EventHandler> PinCollectionAdded; + + /// + /// Occurs when a pin was removed from the node + /// + event EventHandler> PinCollectionRemoved; /// /// Called when the node was loaded from storage or newly created diff --git a/src/Artemis.Core/VisualScripting/Node.cs b/src/Artemis.Core/VisualScripting/Node.cs index fd73af8b8..5c1ccb03f 100644 --- a/src/Artemis.Core/VisualScripting/Node.cs +++ b/src/Artemis.Core/VisualScripting/Node.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using System.Reflection; +using Artemis.Core.Events; using Ninject; using Ninject.Parameters; @@ -16,6 +17,18 @@ public abstract class Node : CorePropertyChanged, INode /// public event EventHandler? Resetting; + /// + public event EventHandler>? PinAdded; + + /// + public event EventHandler>? PinRemoved; + + /// + public event EventHandler>? PinCollectionAdded; + + /// + public event EventHandler>? PinCollectionRemoved; + #region Properties & Fields private readonly List _outputPinBucket = new(); @@ -120,7 +133,7 @@ public abstract class Node : CorePropertyChanged, INode { InputPin pin = new(this, name); _pins.Add(pin); - OnPropertyChanged(nameof(Pins)); + PinAdded?.Invoke(this, new SingleValueEventArgs(pin)); return pin; } @@ -134,7 +147,7 @@ public abstract class Node : CorePropertyChanged, INode { InputPin pin = new(this, type, name); _pins.Add(pin); - OnPropertyChanged(nameof(Pins)); + PinAdded?.Invoke(this, new SingleValueEventArgs(pin)); return pin; } @@ -148,7 +161,7 @@ public abstract class Node : CorePropertyChanged, INode { OutputPin pin = new(this, name); _pins.Add(pin); - OnPropertyChanged(nameof(Pins)); + PinAdded?.Invoke(this, new SingleValueEventArgs(pin)); return pin; } @@ -162,7 +175,7 @@ public abstract class Node : CorePropertyChanged, INode { OutputPin pin = new(this, type, name); _pins.Add(pin); - OnPropertyChanged(nameof(Pins)); + PinAdded?.Invoke(this, new SingleValueEventArgs(pin)); return pin; } @@ -237,7 +250,7 @@ public abstract class Node : CorePropertyChanged, INode if (isRemoved) { pin.DisconnectAll(); - OnPropertyChanged(nameof(Pins)); + PinRemoved?.Invoke(this, new SingleValueEventArgs(pin)); } return isRemoved; @@ -255,7 +268,7 @@ public abstract class Node : CorePropertyChanged, INode return; _pins.Add(pin); - OnPropertyChanged(nameof(Pins)); + PinAdded?.Invoke(this, new SingleValueEventArgs(pin)); } /// @@ -269,7 +282,7 @@ public abstract class Node : CorePropertyChanged, INode { InputPinCollection pin = new(this, name, initialCount); _pinCollections.Add(pin); - OnPropertyChanged(nameof(PinCollections)); + PinCollectionAdded?.Invoke(this, new SingleValueEventArgs(pin)); return pin; } @@ -284,7 +297,7 @@ public abstract class Node : CorePropertyChanged, INode { InputPinCollection pin = new(this, type, name, initialCount); _pinCollections.Add(pin); - OnPropertyChanged(nameof(PinCollections)); + PinCollectionAdded?.Invoke(this, new SingleValueEventArgs(pin)); return pin; } @@ -299,7 +312,7 @@ public abstract class Node : CorePropertyChanged, INode { OutputPinCollection pin = new(this, name, initialCount); _pinCollections.Add(pin); - OnPropertyChanged(nameof(PinCollections)); + PinCollectionAdded?.Invoke(this, new SingleValueEventArgs(pin)); return pin; } @@ -316,7 +329,7 @@ public abstract class Node : CorePropertyChanged, INode { foreach (IPin pin in pinCollection) pin.DisconnectAll(); - OnPropertyChanged(nameof(PinCollections)); + PinCollectionRemoved?.Invoke(this, new SingleValueEventArgs(pinCollection)); } return isRemoved; diff --git a/src/Artemis.UI/Screens/VisualScripting/NodeScriptViewModel.cs b/src/Artemis.UI/Screens/VisualScripting/NodeScriptViewModel.cs index 02a9d34ab..6bbdb5ac0 100644 --- a/src/Artemis.UI/Screens/VisualScripting/NodeScriptViewModel.cs +++ b/src/Artemis.UI/Screens/VisualScripting/NodeScriptViewModel.cs @@ -66,7 +66,8 @@ public class NodeScriptViewModel : ActivatableViewModelBase }); NodeViewModels = nodeViewModels; - NodeViewModels.ToObservableChangeSet().TransformMany(vm => vm.PinViewModels) + NodeViewModels.ToObservableChangeSet() + .TransformMany(vm => vm.PinViewModels) .Bind(out ReadOnlyObservableCollection pinViewModels) .Subscribe(); PinViewModels = pinViewModels; diff --git a/src/Artemis.UI/Screens/VisualScripting/NodeViewModel.cs b/src/Artemis.UI/Screens/VisualScripting/NodeViewModel.cs index 49ebeba5f..5631a38be 100644 --- a/src/Artemis.UI/Screens/VisualScripting/NodeViewModel.cs +++ b/src/Artemis.UI/Screens/VisualScripting/NodeViewModel.cs @@ -3,6 +3,7 @@ using System.Collections.ObjectModel; using System.Reactive; using System.Reactive.Linq; using Artemis.Core; +using Artemis.Core.Events; using Artemis.UI.Ninject.Factories; using Artemis.UI.Screens.VisualScripting.Pins; using Artemis.UI.Shared; @@ -99,18 +100,31 @@ public class NodeViewModel : ActivatableViewModelBase .DisposeWith(d); // Subscribe to pin changes - Node.WhenAnyValue(n => n.Pins).Subscribe(p => nodePins.Edit(source => + Observable.FromEventPattern>(x => Node.PinAdded += x, x => Node.PinAdded -= x) + .Subscribe(p => nodePins.Add(p.EventArgs.Value)) + .DisposeWith(d); + Observable.FromEventPattern>(x => Node.PinRemoved += x, x => Node.PinRemoved -= x) + .Subscribe(p => nodePins.Remove(p.EventArgs.Value)) + .DisposeWith(d); + nodePins.Edit(l => { - source.Clear(); - source.AddRange(p); - })).DisposeWith(d); + l.Clear(); + l.AddRange(Node.Pins); + }); + // Subscribe to pin collection changes - Node.WhenAnyValue(n => n.PinCollections).Subscribe(c => nodePinCollections.Edit(source => + Observable.FromEventPattern>(x => Node.PinCollectionAdded += x, x => Node.PinCollectionAdded -= x) + .Subscribe(p => nodePinCollections.Add(p.EventArgs.Value)) + .DisposeWith(d); + Observable.FromEventPattern>(x => Node.PinCollectionRemoved += x, x => Node.PinCollectionRemoved -= x) + .Subscribe(p => nodePinCollections.Remove(p.EventArgs.Value)) + .DisposeWith(d); + nodePinCollections.Edit(l => { - source.Clear(); - source.AddRange(c); - })).DisposeWith(d); - + l.Clear(); + l.AddRange(Node.PinCollections); + }); + if (Node is Node coreNode) CustomNodeViewModel = coreNode.GetCustomViewModel(nodeScriptViewModel.NodeScript); });