diff --git a/NetPrints/Base/INode.cs b/NetPrints/Base/INode.cs
new file mode 100644
index 0000000..5b98901
--- /dev/null
+++ b/NetPrints/Base/INode.cs
@@ -0,0 +1,28 @@
+using NetPrints.Core;
+
+namespace NetPrints.Base
+{
+ ///
+ /// Interface for all node types.
+ ///
+ public interface INode
+ {
+ ///
+ /// All pins on this node.
+ ///
+ public ObservableRangeCollection Pins { get; }
+
+ ///
+ /// Name of this node.
+ ///
+ public string Name { get; set; }
+
+ ///
+ /// Graph this node is contained in.
+ ///
+ public INodeGraph Graph
+ {
+ get;
+ }
+ }
+}
diff --git a/NetPrints/Base/INodeDataPin.cs b/NetPrints/Base/INodeDataPin.cs
new file mode 100644
index 0000000..547a47a
--- /dev/null
+++ b/NetPrints/Base/INodeDataPin.cs
@@ -0,0 +1,10 @@
+using NetPrints.Core;
+using NetPrints.Graph;
+
+namespace NetPrints.Base
+{
+ public interface INodeDataPin : INodePin
+ {
+ public ObservableValue PinType { get; }
+ }
+}
diff --git a/NetPrints/Base/INodeExecutionPin.cs b/NetPrints/Base/INodeExecutionPin.cs
new file mode 100644
index 0000000..bd5ce3b
--- /dev/null
+++ b/NetPrints/Base/INodeExecutionPin.cs
@@ -0,0 +1,6 @@
+namespace NetPrints.Base
+{
+ public interface INodeExecutionPin : INodePin
+ {
+ }
+}
diff --git a/NetPrints/Base/INodeGraph.cs b/NetPrints/Base/INodeGraph.cs
new file mode 100644
index 0000000..04e5ad2
--- /dev/null
+++ b/NetPrints/Base/INodeGraph.cs
@@ -0,0 +1,15 @@
+using NetPrints.Core;
+
+namespace NetPrints.Base
+{
+ public interface INodeGraph
+ {
+ ///
+ /// List of nodes in this graph.
+ ///
+ public ObservableRangeCollection Nodes
+ {
+ get;
+ }
+ }
+}
diff --git a/NetPrints/Base/INodeInputPin.cs b/NetPrints/Base/INodeInputPin.cs
new file mode 100644
index 0000000..2e29047
--- /dev/null
+++ b/NetPrints/Base/INodeInputPin.cs
@@ -0,0 +1,10 @@
+using NetPrints.Core;
+using System.Collections.ObjectModel;
+
+namespace NetPrints.Base
+{
+ public interface INodeInputPin : INodePin
+ {
+ public IObservableCollectionView IncomingPins { get; }
+ }
+}
diff --git a/NetPrints/Base/INodeOutputPin.cs b/NetPrints/Base/INodeOutputPin.cs
new file mode 100644
index 0000000..04c85da
--- /dev/null
+++ b/NetPrints/Base/INodeOutputPin.cs
@@ -0,0 +1,10 @@
+using NetPrints.Core;
+using System.Collections.ObjectModel;
+
+namespace NetPrints.Base
+{
+ public interface INodeOutputPin : INodePin
+ {
+ public IObservableCollectionView OutgoingPins { get; }
+ }
+}
diff --git a/NetPrints/Base/INodePin.cs b/NetPrints/Base/INodePin.cs
new file mode 100644
index 0000000..da2a668
--- /dev/null
+++ b/NetPrints/Base/INodePin.cs
@@ -0,0 +1,29 @@
+using NetPrints.Core;
+
+namespace NetPrints.Base
+{
+ public enum NodePinConnectionType
+ {
+ Single,
+ Multiple
+ }
+
+ ///
+ /// Interface for node pins.
+ ///
+ public interface INodePin
+ {
+ ///
+ /// Name of the pin.
+ ///
+ public string Name { get; }
+
+ ///
+ /// Node this pin is contained in.
+ ///
+ public INode Node { get; }
+
+ public NodePinConnectionType ConnectionType { get; }
+ public ObservableRangeCollection ConnectedPins { get; }
+ }
+}
diff --git a/NetPrints/Base/INodeTypePin.cs b/NetPrints/Base/INodeTypePin.cs
new file mode 100644
index 0000000..71a5c7c
--- /dev/null
+++ b/NetPrints/Base/INodeTypePin.cs
@@ -0,0 +1,10 @@
+using NetPrints.Core;
+using NetPrints.Graph;
+
+namespace NetPrints.Base
+{
+ public interface INodeTypePin : INodePin
+ {
+ public ObservableValue InferredType { get; }
+ }
+}
diff --git a/NetPrints/Core/FilteredObservableCollection.cs b/NetPrints/Core/FilteredObservableCollection.cs
new file mode 100644
index 0000000..77f999a
--- /dev/null
+++ b/NetPrints/Core/FilteredObservableCollection.cs
@@ -0,0 +1,128 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Collections.Specialized;
+using System.Diagnostics;
+using System.Linq;
+
+namespace NetPrints.Core
+{
+ public interface IObservableCollectionView : IReadOnlyList, INotifyCollectionChanged
+ {
+ public bool Contains(T item);
+
+ public int IndexOf(T item);
+ }
+
+ public class FilteredObservableCollection : IObservableCollectionView where TFiltered : TOriginal
+ {
+ public event NotifyCollectionChangedEventHandler CollectionChanged;
+
+ private readonly ObservableCollection original;
+ private readonly Func filter;
+
+ private readonly List subset;
+
+ public int Count => subset.Count;
+
+ TFiltered IReadOnlyList.this[int index] => subset[index];
+
+ public TFiltered this[int index] => subset[index];
+
+ public FilteredObservableCollection(ObservableCollection original, Func filter)
+ {
+ Debug.Assert(original != null, "Original collection was null.");
+ Debug.Assert(filter != null, "Filter was null.");
+
+ this.original = original;
+ this.filter = filter;
+
+ original.CollectionChanged += OnOriginalCollectionChanged;
+
+ subset = original.OfType().Where(item => filter(item)).ToList();
+ }
+
+ public static FilteredObservableCollection TypeFilter(ObservableCollection original)
+ {
+ return new FilteredObservableCollection(original, item => item is TFiltered);
+ }
+
+ private void OnOriginalCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
+ {
+ subset.Clear();
+ CollectionChanged?.Invoke(sender, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
+
+ subset.AddRange(original.OfType().Where(item => filter(item)));
+ CollectionChanged?.Invoke(sender, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, subset, 0));
+
+ // TODO: Handle inserts / replace correctly.
+
+ /*if (e.Action != NotifyCollectionChangedAction.Reset)
+ {
+ List oldItems = null, newItems = null;
+ int oldIndex = -1;
+
+ // Remove old items
+ if (e.OldItems != null)
+ {
+ oldIndex = IndexOf(e.OldItems.OfType().Last());
+ oldItems = e.OldItems.OfType().Where(item => subset.Remove(item)).ToList();
+ }
+
+ // Add new items if filter applies
+ if (e.NewItems != null)
+ {
+ newItems = e.NewItems.OfType().Where(item => filter(item)).ToList();
+
+ foreach (var newItem in newItems)
+ {
+ subset.Add(newItem);
+ }
+ }
+
+ // Trigger collection change event if any items were added or removed.
+ switch (e.Action)
+ {
+ case NotifyCollectionChangedAction.Add:
+ if (newItems != null && newItems.Count > 0)
+ {
+ CollectionChanged?.Invoke(sender, new NotifyCollectionChangedEventArgs(e.Action, newItems, subset.Count - newItems.Count));
+ }
+ break;
+ case NotifyCollectionChangedAction.Remove:
+ if (oldItems != null && oldItems.Count > 0)
+ {
+ CollectionChanged?.Invoke(sender, new NotifyCollectionChangedEventArgs(e.Action, oldItems, oldIndex));
+ }
+ break;
+ case NotifyCollectionChangedAction.Replace:
+ if ((oldItems != null && oldItems.Count > 0) || (newItems != null && newItems.Count > 0))
+ {
+ CollectionChanged?.Invoke(sender, new NotifyCollectionChangedEventArgs(e.Action, oldItems, newItems));
+ }
+ break;
+ default:
+ throw new NotImplementedException();
+ }
+
+ }
+ else
+ {
+ if (subset.Count > 0)
+ {
+ subset.Clear();
+ CollectionChanged?.Invoke(sender, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
+ }
+ }*/
+ }
+
+ public IEnumerator GetEnumerator() => subset.GetEnumerator();
+
+ IEnumerator IEnumerable.GetEnumerator() => subset.GetEnumerator();
+
+ public bool Contains(TFiltered item) => subset.Contains(item);
+
+ public int IndexOf(TFiltered item) => subset.IndexOf(item);
+ }
+}
diff --git a/NetPrints/Core/GraphConnectionTracker.cs b/NetPrints/Core/GraphConnectionTracker.cs
new file mode 100644
index 0000000..f82b775
--- /dev/null
+++ b/NetPrints/Core/GraphConnectionTracker.cs
@@ -0,0 +1,126 @@
+using NetPrints.Base;
+using NetPrints.Graph;
+using System.Collections.Specialized;
+using System.Linq;
+
+namespace NetPrints.Core
+{
+ public class GraphConnectionTracker
+ {
+ public ObservableRangeCollection Connections { get; private set; }
+
+ private INodeGraph graph;
+
+ public GraphConnectionTracker(INodeGraph graph)
+ {
+ this.graph = graph;
+
+ SetupInitialConnections();
+ }
+
+ private void SetupInitialConnections()
+ {
+ if (Connections is null)
+ {
+ Connections = new ObservableRangeCollection();
+ }
+
+ OnNodeCollectionChanged(null, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, graph.Nodes, 0));
+ graph.Nodes.CollectionChanged += OnNodeCollectionChanged;
+ }
+
+ private void OnNodeCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
+ {
+ if (e.OldItems != null)
+ {
+ foreach (var node in e.OldItems.Cast())
+ {
+ SetupNodeEvents(node, false);
+ }
+ }
+
+ if (e.NewItems != null)
+ {
+ foreach (var node in e.NewItems.Cast())
+ {
+ SetupNodeEvents(node, true);
+ }
+ }
+ }
+
+ private void OnNodePinsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
+ {
+ if (e.OldItems != null)
+ {
+ foreach (var pin in e.OldItems.Cast())
+ {
+ SetupPinEvents(pin, false);
+ }
+ }
+
+ if (e.NewItems != null)
+ {
+ foreach (var pin in e.NewItems.Cast())
+ {
+ SetupPinEvents(pin, true);
+ }
+ }
+ }
+
+ private void OnPinConnectionsCollectionChanged(NodePin fromPin, object sender, NotifyCollectionChangedEventArgs e)
+ {
+ if (e.OldItems != null)
+ {
+ var removedConnections = Connections.Where(conn =>
+ (conn.PinA == fromPin && e.OldItems.Contains(conn.PinB))
+ || (conn.PinB == fromPin && e.OldItems.Contains(conn.PinA)))
+ .ToArray();
+
+ Connections.RemoveRange(removedConnections);
+ }
+
+ if (e.NewItems != null)
+ {
+ Connections.AddRange(e.NewItems.Cast()
+ .Where(pin => pin.ConnectionType == NodePinConnectionType.Single)
+ .Select(toPin => new PinConnection(fromPin, toPin)));
+ }
+ }
+
+ private void SetupNodeEvents(INode node, bool add)
+ {
+ if (!add)
+ {
+ node.Pins.CollectionChanged -= OnNodePinsCollectionChanged;
+ }
+
+ foreach (var pin in node.Pins.Cast())
+ {
+ SetupPinEvents(pin, add);
+ }
+
+ if (add)
+ {
+ node.Pins.CollectionChanged += OnNodePinsCollectionChanged;
+ }
+ }
+
+ private void SetupPinEvents(NodePin pin, bool add)
+ {
+ if (add)
+ {
+ if (pin.ConnectionType == NodePinConnectionType.Single)
+ {
+ Connections.AddRange(pin.ConnectedPins.Select(toPin => new PinConnection((NodePin)pin, (NodePin)toPin)));
+ }
+
+ pin.ConnectedPins.CollectionChanged += (object sender, NotifyCollectionChangedEventArgs e) => OnPinConnectionsCollectionChanged(pin, sender, e);
+ }
+ else
+ {
+ //pin.ConnectedPins.CollectionChanged -= (object sender, NotifyCollectionChangedEventArgs e) => OnPinConnectionsCollectionChanged(pin, sender, e);
+ Connections.RemoveRange(Connections.Where(conn => conn.PinA == pin || conn.PinB == pin).ToArray());
+ }
+ }
+ }
+}
diff --git a/NetPrints/Core/INodeInputButtons.cs b/NetPrints/Core/INodeInputButtons.cs
new file mode 100644
index 0000000..4a5acc3
--- /dev/null
+++ b/NetPrints/Core/INodeInputButtons.cs
@@ -0,0 +1,8 @@
+namespace NetPrints.Core
+{
+ public interface INodeInputButtons
+ {
+ public void InputPlusClicked();
+ public void InputMinusClicked();
+ }
+}
diff --git a/NetPrints/Core/INodeOutputButtons.cs b/NetPrints/Core/INodeOutputButtons.cs
new file mode 100644
index 0000000..5ba7761
--- /dev/null
+++ b/NetPrints/Core/INodeOutputButtons.cs
@@ -0,0 +1,8 @@
+namespace NetPrints.Core
+{
+ public interface INodeOutputButtons
+ {
+ public void OutputPlusClicked();
+ public void OutputMinusClicked();
+ }
+}
diff --git a/NetPrints/Core/MethodGraph.cs b/NetPrints/Core/MethodGraph.cs
index ddff2b1..1b4b161 100644
--- a/NetPrints/Core/MethodGraph.cs
+++ b/NetPrints/Core/MethodGraph.cs
@@ -1,4 +1,5 @@
-using NetPrints.Graph;
+using NetPrints.Base;
+using NetPrints.Graph;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -128,11 +129,13 @@ private void OnDeserialized(StreamingContext context)
foreach (var node in Nodes)
{
- node.InputTypePins.ToList().ForEach(p => pinTypes.Add(p, p.InferredType?.Value));
+ var inputTypePins = node.Pins.OfType().ToList();
- node.OnMethodDeserialized();
+ inputTypePins.ForEach(p => pinTypes.Add(p, p.InferredType?.Value));
- if (node.InputTypePins.Any(p => pinTypes[p] != p.InferredType?.Value))
+ ((Node)node).OnMethodDeserialized();
+
+ if (inputTypePins.Any(p => pinTypes[p] != p.InferredType?.Value))
{
anyTypeChanged = true;
}
diff --git a/NetPrints/Core/NetPrintsUtil.cs b/NetPrints/Core/NetPrintsUtil.cs
index 96f33f7..5ec4620 100644
--- a/NetPrints/Core/NetPrintsUtil.cs
+++ b/NetPrints/Core/NetPrintsUtil.cs
@@ -1,10 +1,34 @@
using System;
using System.Collections.Generic;
+using System.Collections.ObjectModel;
namespace NetPrints.Core
{
public static class NetPrintsUtil
{
+ public static int IndexOf(this IReadOnlyList list, T element)
+ {
+ for (int i = 0; i < list.Count; i++)
+ {
+ if (list[i].Equals(element))
+ {
+ return i;
+ }
+ }
+
+ return -1;
+ }
+
+ public static FilteredObservableCollection ObservableOfType(this ObservableCollection original) where TFiltered : TOriginal
+ {
+ return new FilteredObservableCollection(original, item => item is TFiltered);
+ }
+
+ public static FilteredObservableCollection ObservableWhere(this ObservableCollection observableCollection, Func predicate)
+ {
+ return new FilteredObservableCollection(observableCollection, predicate);
+ }
+
///
/// Returns the first name not already contained in a list of names by
/// trying to generate a unique name based on the given name.
diff --git a/NetPrints/Core/NodeGraph.cs b/NetPrints/Core/NodeGraph.cs
index ec198ee..a35c15b 100644
--- a/NetPrints/Core/NodeGraph.cs
+++ b/NetPrints/Core/NodeGraph.cs
@@ -1,4 +1,8 @@
-using NetPrints.Graph;
+using NetPrints.Base;
+using NetPrints.Graph;
+using System.Collections.Generic;
+using System.Collections.Specialized;
+using System.Linq;
using System.Runtime.Serialization;
namespace NetPrints.Core
@@ -8,17 +12,17 @@ namespace NetPrints.Core
[KnownType(typeof(ConstructorGraph))]
[KnownType(typeof(ClassGraph))]
[KnownType(typeof(TypeGraph))]
- public abstract class NodeGraph
+ public abstract class NodeGraph : INodeGraph
{
///
/// Collection of nodes in this graph.
///
[DataMember]
- public ObservableRangeCollection Nodes
+ public ObservableRangeCollection Nodes
{
get;
private set;
- } = new ObservableRangeCollection();
+ } = new ObservableRangeCollection();
///
/// Class this graph is contained in.
diff --git a/NetPrints/Core/PinConnection.cs b/NetPrints/Core/PinConnection.cs
new file mode 100644
index 0000000..8e1b03e
--- /dev/null
+++ b/NetPrints/Core/PinConnection.cs
@@ -0,0 +1,42 @@
+using NetPrints.Graph;
+using PropertyChanged;
+using System.Drawing;
+
+namespace NetPrints.Base
+{
+ [AddINotifyPropertyChangedInterface]
+ public class PinConnection
+ {
+ public NodePin PinA { get; }
+ public NodePin PinB { get; }
+
+ public Point PointA { get; private set; }
+ public Point PointB { get; private set; }
+ public Point PointC { get; private set; }
+ public Point PointD { get; private set; }
+
+ private const double CPOffset = 100;
+
+ public PinConnection(NodePin a, NodePin b)
+ {
+ PinA = a;
+ PinB = b;
+
+ PinA.PositionChanged += (sender, e) => RecalculatePoints();
+ PinB.PositionChanged += (sender, e) => RecalculatePoints();
+
+ RecalculatePoints();
+ }
+
+ private void RecalculatePoints()
+ {
+ PointA = new Point((int)PinA.PositionX, (int)PinA.PositionY);
+ PointD = new Point((int)PinB.PositionX, (int)PinB.PositionY);
+
+ int sign = PinA is INodeOutputPin ? 1 : -1;
+
+ PointB = new Point((int)(PinA.PositionX + sign * CPOffset), (int)PinA.PositionY);
+ PointC = new Point((int)(PinB.PositionX - sign * CPOffset), (int)PinB.PositionY);
+ }
+ }
+}
diff --git a/NetPrints/Core/Variable.cs b/NetPrints/Core/Variable.cs
index fa671ad..304cf50 100644
--- a/NetPrints/Core/Variable.cs
+++ b/NetPrints/Core/Variable.cs
@@ -189,7 +189,7 @@ public Variable(ClassGraph cls, string name, TypeSpecifier type, MethodGraph get
NodeOutputTypePin typePin = GraphUtil.CreateNestedTypeNode(TypeGraph, type, 500, 300).OutputTypePins[0];
TypeGraph.ReturnNode.PositionX = 800;
TypeGraph.ReturnNode.PositionY = 300;
- GraphUtil.ConnectTypePins(typePin, TypeGraph.ReturnNode.TypePin);
+ GraphUtil.ConnectPins(typePin, TypeGraph.ReturnNode.TypePin);
}
[OnDeserialized]
diff --git a/NetPrints/Graph/AwaitNode.cs b/NetPrints/Graph/AwaitNode.cs
index 544856e..534b7e5 100644
--- a/NetPrints/Graph/AwaitNode.cs
+++ b/NetPrints/Graph/AwaitNode.cs
@@ -63,7 +63,7 @@ private void UpdateResultPin()
// to determine if the types are still compatible.
foreach (var outgoingPin in ResultPin.OutgoingPins)
{
- GraphUtil.DisconnectOutputDataPin(ResultPin);
+ GraphUtil.DisconnectPin(ResultPin);
}
}
else
@@ -76,8 +76,8 @@ private void UpdateResultPin()
// Remove existing result pin if any
if (ResultPin != null)
{
- GraphUtil.DisconnectOutputDataPin(ResultPin);
- OutputDataPins.Remove(ResultPin);
+ GraphUtil.DisconnectPin(ResultPin);
+ Pins.Remove(ResultPin);
}
}
}
diff --git a/NetPrints/Graph/CallMethodNode.cs b/NetPrints/Graph/CallMethodNode.cs
index 140163f..ba510c3 100644
--- a/NetPrints/Graph/CallMethodNode.cs
+++ b/NetPrints/Graph/CallMethodNode.cs
@@ -126,13 +126,13 @@ public NodeOutputExecPin CatchPin
///
public bool HandlesExceptions
{
- get => !IsPure && OutputExecPins.Any(p => p.Name == CatchPinName) && CatchPin.OutgoingPin != null;
+ get => !IsPure && OutputExecPins.Any(p => p.Name == CatchPinName) && CatchPin.OutgoingExecPin != null;
}
///
/// List of node pins, one for each argument the method takes.
///
- public IList ArgumentPins
+ public IReadOnlyList ArgumentPins
{
get
{
@@ -218,12 +218,12 @@ private void AddCatchPinChangedEvent()
///
private void UpdateExceptionPin()
{
- if (CatchPin?.OutgoingPin == null && ExceptionPin != null)
+ if (CatchPin?.OutgoingExecPin == null && ExceptionPin != null)
{
- GraphUtil.DisconnectOutputDataPin(ExceptionPin);
- OutputDataPins.Remove(ExceptionPin);
+ GraphUtil.DisconnectPin(ExceptionPin);
+ Pins.Remove(ExceptionPin);
}
- else if (CatchPin?.OutgoingPin != null && ExceptionPin == null)
+ else if (CatchPin?.OutgoingExecPin != null && ExceptionPin == null)
{
AddOutputDataPin(ExceptionPinName, TypeSpecifier.FromType());
}
@@ -244,8 +244,8 @@ protected override void SetPurity(bool pure)
{
// Remove catch pin. Exception pin gets automatically removed because
// of its pin changed ev ent.
- GraphUtil.DisconnectOutputExecPin(CatchPin);
- OutputExecPins.Remove(CatchPin);
+ GraphUtil.DisconnectPin(CatchPin);
+ Pins.Remove(CatchPin);
}
else
{
diff --git a/NetPrints/Graph/ClassReturnNode.cs b/NetPrints/Graph/ClassReturnNode.cs
index e327564..ea1d9c2 100644
--- a/NetPrints/Graph/ClassReturnNode.cs
+++ b/NetPrints/Graph/ClassReturnNode.cs
@@ -8,7 +8,7 @@
namespace NetPrints.Graph
{
[DataContract]
- public class ClassReturnNode : Node
+ public class ClassReturnNode : Node, INodeInputButtons
{
public NodeInputTypePin SuperTypePin
{
@@ -26,20 +26,24 @@ public ClassReturnNode(ClassGraph graph)
AddInputTypePin("BaseType");
}
- public void AddInterfacePin()
+ public void AddArgument()
{
AddInputTypePin($"Interface{InputTypePins.Count}");
}
- public void RemoveInterfacePin()
+ public void RemoveArgument()
{
var interfacePin = InterfacePins.LastOrDefault();
if (interfacePin != null)
{
- GraphUtil.DisconnectInputTypePin(interfacePin);
- InputTypePins.Remove(interfacePin);
+ GraphUtil.DisconnectPin(interfacePin);
+ Pins.Remove(interfacePin);
}
}
+
+ public void InputPlusClicked() => AddArgument();
+
+ public void InputMinusClicked() => RemoveArgument();
}
}
diff --git a/NetPrints/Graph/ConstructorNode.cs b/NetPrints/Graph/ConstructorNode.cs
index 2a4f148..8f4ad98 100644
--- a/NetPrints/Graph/ConstructorNode.cs
+++ b/NetPrints/Graph/ConstructorNode.cs
@@ -46,7 +46,7 @@ public IReadOnlyList ArgumentTypes
///
/// List of node pins, one for each argument the constructor takes.
///
- public IList ArgumentPins
+ public IReadOnlyList ArgumentPins
{
get { return InputDataPins; }
}
diff --git a/NetPrints/Graph/ExecNode.cs b/NetPrints/Graph/ExecNode.cs
index 5be1d97..1906d45 100644
--- a/NetPrints/Graph/ExecNode.cs
+++ b/NetPrints/Graph/ExecNode.cs
@@ -1,4 +1,5 @@
using NetPrints.Core;
+using System.Linq;
using System.Runtime.Serialization;
namespace NetPrints.Graph
@@ -29,11 +30,11 @@ protected override void SetPurity(bool pure)
if (pure)
{
- GraphUtil.DisconnectInputExecPin(InputExecPins[0]);
- InputExecPins.RemoveAt(0);
-
- GraphUtil.DisconnectOutputExecPin(OutputExecPins[0]);
- OutputExecPins.RemoveAt(0);
+ GraphUtil.DisconnectPin(InputExecPins[0]);
+ Pins.Remove(Pins.First(pin => pin is NodeInputExecPin));
+
+ GraphUtil.DisconnectPin(OutputExecPins[0]);
+ Pins.Remove(Pins.First(pin => pin is NodeOutputExecPin));
}
else if (!pure)
{
diff --git a/NetPrints/Graph/ExplicitCastNode.cs b/NetPrints/Graph/ExplicitCastNode.cs
index d31fbf7..0638839 100644
--- a/NetPrints/Graph/ExplicitCastNode.cs
+++ b/NetPrints/Graph/ExplicitCastNode.cs
@@ -94,13 +94,13 @@ protected override void SetPurity(bool pure)
foreach (var execPin in outExecPins)
{
- GraphUtil.DisconnectOutputExecPin(execPin);
- OutputExecPins.Remove(execPin);
+ GraphUtil.DisconnectPin(execPin);
+ Pins.Remove(execPin);
}
var inExecPin = InputExecPins.Single(p => p.Name == "Exec");
- GraphUtil.DisconnectInputExecPin(inExecPin);
- InputExecPins.Remove(inExecPin);
+ GraphUtil.DisconnectPin(inExecPin);
+ Pins.Remove(inExecPin);
}
else
{
diff --git a/NetPrints/Graph/GraphUtil.cs b/NetPrints/Graph/GraphUtil.cs
index e85b97d..611174a 100644
--- a/NetPrints/Graph/GraphUtil.cs
+++ b/NetPrints/Graph/GraphUtil.cs
@@ -1,6 +1,8 @@
-using NetPrints.Core;
+using NetPrints.Base;
+using NetPrints.Core;
using System;
using System.Collections.Generic;
+using System.Diagnostics;
using System.Linq;
using System.Text.RegularExpressions;
@@ -26,7 +28,7 @@ public static string SplitCamelCase(string input)
/// Function for determining whether one type is the subclass of another type.
/// Whether we want pinB to be the first pin and vice versa.
///
- public static bool CanConnectNodePins(NodePin pinA, NodePin pinB, Func isSubclassOf, Func hasImplicitCast, bool swapped=false)
+ public static bool CanConnectNodePins(INodePin pinA, INodePin pinB, Func isSubclassOf, Func hasImplicitCast, bool swapped=false)
{
if (pinA is NodeInputExecPin && pinB is NodeOutputExecPin)
{
@@ -85,203 +87,53 @@ public static bool CanConnectNodePins(NodePin pinA, NodePin pinB, Func
- /// Connects two node pins together. Makes sure any previous connections will be disconnected.
- /// If the pin types are not compatible an ArgumentException will be thrown.
- ///
- /// First pin.
- /// Second pin.
- /// Whether we want pinB to be the first pin and vice versa.
- public static void ConnectNodePins(NodePin pinA, NodePin pinB, bool swapped=false)
+ public static void ConnectPins(INodePin pinA, INodePin pinB)
{
- if (pinA is NodeInputExecPin exA && pinB is NodeOutputExecPin exB)
- {
- ConnectExecPins(exB, exA);
- }
- else if (pinA is NodeInputDataPin datA && pinB is NodeOutputDataPin datB)
- {
- ConnectDataPins(datB, datA);
- }
- else if (pinA is NodeInputTypePin typA && pinB is NodeOutputTypePin typB)
- {
- ConnectTypePins(typB, typA);
- }
- else if (!swapped)
- {
- ConnectNodePins(pinB, pinA, true);
- }
- else
- {
- throw new ArgumentException("The passed pins can not be connected because their types are incompatible.");
- }
- }
+ // Remove old connections for single connection pins
- ///
- /// Connects two node execution pins. Removes any previous connection.
- ///
- /// Output execution pin to connect.
- /// Input execution pin to connect.
- public static void ConnectExecPins(NodeOutputExecPin fromPin, NodeInputExecPin toPin)
- {
- // Remove from old pin if any
- if (fromPin.OutgoingPin != null)
+ if (pinA.ConnectionType == NodePinConnectionType.Single)
{
- fromPin.OutgoingPin.IncomingPins.Remove(fromPin);
+ DisconnectPin(pinA);
}
- fromPin.OutgoingPin = toPin;
- toPin.IncomingPins.Add(fromPin);
- }
-
- ///
- /// Connects two node data pins. Removes any previous connection.
- ///
- /// Output data pin to connect.
- /// Input data pin to connect.
- public static void ConnectDataPins(NodeOutputDataPin fromPin, NodeInputDataPin toPin)
- {
- // Remove from old pin if any
- if (toPin.IncomingPin != null)
+ if (pinB.ConnectionType == NodePinConnectionType.Single)
{
- toPin.IncomingPin.OutgoingPins.Remove(toPin);
+ DisconnectPin(pinB);
}
- fromPin.OutgoingPins.Add(toPin);
- toPin.IncomingPin = fromPin;
+ // Add new connections
+ pinA.ConnectedPins.Add(pinB);
+ pinB.ConnectedPins.Add(pinA);
}
- ///
- /// Connects two node type pins. Removes any previous connection.
- ///
- /// Output type pin to connect.
- /// Input type pin to connect.
- public static void ConnectTypePins(NodeOutputTypePin fromPin, NodeInputTypePin toPin)
+ public static void DisconnectPin(INodePin nodePin)
{
- // Remove from old pin if any
- if (toPin.IncomingPin != null)
+ foreach (var otherPin in nodePin.ConnectedPins)
{
- toPin.IncomingPin.OutgoingPins.Remove(toPin);
+ otherPin.ConnectedPins.Remove(nodePin);
}
- fromPin.OutgoingPins.Add(toPin);
- toPin.IncomingPin = fromPin;
+ nodePin.ConnectedPins.Clear();
}
///
/// Disconnects all pins of a node.
///
/// Node to have all its pins disconnected.
- public static void DisconnectNodePins(Node node)
+ public static void DisconnectNodePins(INode node)
{
- foreach (NodeInputDataPin pin in node.InputDataPins)
+ foreach (var pin in node.Pins)
{
- DisconnectInputDataPin(pin);
+ DisconnectPin(pin);
}
-
- foreach (NodeOutputDataPin pin in node.OutputDataPins)
- {
- DisconnectOutputDataPin(pin);
- }
-
- foreach (NodeInputExecPin pin in node.InputExecPins)
- {
- DisconnectInputExecPin(pin);
- }
-
- foreach (NodeOutputExecPin pin in node.OutputExecPins)
- {
- DisconnectOutputExecPin(pin);
- }
-
- foreach (NodeInputTypePin pin in node.InputTypePins)
- {
- DisconnectInputTypePin(pin);
- }
-
- foreach (NodeOutputTypePin pin in node.OutputTypePins)
- {
- DisconnectOutputTypePin(pin);
- }
- }
-
- public static void DisconnectPin(NodePin nodePin)
- {
- if (nodePin is NodeInputDataPin idp)
- {
- DisconnectInputDataPin(idp);
- }
- else if (nodePin is NodeOutputDataPin odp)
- {
- DisconnectOutputDataPin(odp);
- }
- else if (nodePin is NodeInputExecPin ixp)
- {
- DisconnectInputExecPin(ixp);
- }
- else if (nodePin is NodeOutputExecPin oxp)
- {
- DisconnectOutputExecPin(oxp);
- }
- else if (nodePin is NodeInputTypePin itp)
- {
- DisconnectInputTypePin(itp);
- }
- else if (nodePin is NodeOutputTypePin otp)
- {
- DisconnectOutputTypePin(otp);
- }
- else
- {
- throw new NotImplementedException("Unknown pin type to disconnect.");
- }
- }
-
- public static void DisconnectInputDataPin(NodeInputDataPin pin)
- {
- pin.IncomingPin?.OutgoingPins.Remove(pin);
- pin.IncomingPin = null;
}
- public static void DisconnectOutputDataPin(NodeOutputDataPin pin)
+ public static void DisconnectPins(INodePin a, INodePin b)
{
- foreach(NodeInputDataPin outgoingPin in pin.OutgoingPins)
- {
- outgoingPin.IncomingPin = null;
- }
-
- pin.OutgoingPins.Clear();
- }
-
- public static void DisconnectInputTypePin(NodeInputTypePin pin)
- {
- pin.IncomingPin?.OutgoingPins.Remove(pin);
- pin.IncomingPin = null;
- }
-
- public static void DisconnectOutputTypePin(NodeOutputTypePin pin)
- {
- foreach (NodeInputTypePin outgoingPin in pin.OutgoingPins)
- {
- outgoingPin.IncomingPin = null;
- }
-
- pin.OutgoingPins.Clear();
- }
-
- public static void DisconnectOutputExecPin(NodeOutputExecPin pin)
- {
- pin.OutgoingPin?.IncomingPins.Remove(pin);
- pin.OutgoingPin = null;
- }
-
- public static void DisconnectInputExecPin(NodeInputExecPin pin)
- {
- foreach (NodeOutputExecPin incomingPin in pin.IncomingPins)
- {
- incomingPin.OutgoingPin = null;
- }
+ Debug.Assert(a.ConnectedPins.Contains(b) && b.ConnectedPins.Contains(a), "Tried to disconnect two pins which don't connect to each other.");
- pin.IncomingPins.Clear();
+ a.ConnectedPins.Remove(b);
+ b.ConnectedPins.Remove(a);
}
///
@@ -301,8 +153,8 @@ public static RerouteNode AddRerouteNode(NodeInputDataPin pin)
new Tuple(pin.PinType, pin.IncomingPin.PinType)
});
- GraphUtil.ConnectDataPins(pin.IncomingPin, rerouteNode.InputDataPins[0]);
- GraphUtil.ConnectDataPins(rerouteNode.OutputDataPins[0], pin);
+ GraphUtil.ConnectPins(pin.IncomingPin, rerouteNode.InputDataPins[0]);
+ GraphUtil.ConnectPins(rerouteNode.OutputDataPins[0], pin);
return rerouteNode;
}
@@ -314,15 +166,15 @@ public static RerouteNode AddRerouteNode(NodeInputDataPin pin)
/// Reroute node created for the execution pin.
public static RerouteNode AddRerouteNode(NodeOutputExecPin pin)
{
- if (pin?.OutgoingPin == null)
+ if (pin?.OutgoingExecPin == null)
{
throw new ArgumentException("Pin or its connected pin were null");
}
var rerouteNode = RerouteNode.MakeExecution(pin.Node.Graph, 1);
- GraphUtil.ConnectExecPins(rerouteNode.OutputExecPins[0], pin.OutgoingPin);
- GraphUtil.ConnectExecPins(pin, rerouteNode.InputExecPins[0]);
+ GraphUtil.ConnectPins(rerouteNode.OutputExecPins[0], pin.OutgoingExecPin);
+ GraphUtil.ConnectPins(pin, rerouteNode.InputExecPins[0]);
return rerouteNode;
}
@@ -341,8 +193,8 @@ public static RerouteNode AddRerouteNode(NodeInputTypePin pin)
var rerouteNode = RerouteNode.MakeType(pin.Node.Graph, 1);
- GraphUtil.ConnectTypePins(pin.IncomingPin, rerouteNode.InputTypePins[0]);
- GraphUtil.ConnectTypePins(rerouteNode.OutputTypePins[0], pin);
+ GraphUtil.ConnectPins(pin.IncomingPin, rerouteNode.InputTypePins[0]);
+ GraphUtil.ConnectPins(rerouteNode.OutputTypePins[0], pin);
return rerouteNode;
}
@@ -376,7 +228,7 @@ public static TypeNode CreateNestedTypeNode(NodeGraph graph, BaseType type, doub
foreach (TypeNode genericArgNode in genericArgNodes)
{
- GraphUtil.ConnectTypePins(genericArgNode.OutputTypePins[0], typeNode.InputTypePins[0]);
+ GraphUtil.ConnectPins(genericArgNode.OutputTypePins[0], typeNode.InputTypePins[0]);
}
}
@@ -420,7 +272,7 @@ public static MethodGraph AddOverrideMethod(ClassGraph cls, MethodSpecifier meth
newMethod.ReturnNodes.First().PositionY = newMethod.EntryNode.PositionY;
// Connect entry and return node execution pins
- GraphUtil.ConnectExecPins(newMethod.EntryNode.InitialExecutionPin, newMethod.MainReturnNode.ReturnPin);
+ GraphUtil.ConnectPins(newMethod.EntryNode.InitialExecutionPin, newMethod.MainReturnNode.ReturnPin);
// Add generic arguments
for (var i = 0; i < methodSpecifier.GenericArguments.Count; i++)
@@ -439,7 +291,7 @@ public static MethodGraph AddOverrideMethod(ClassGraph cls, MethodSpecifier meth
newMethod.MethodEntryNode.AddArgument();
- ConnectTypePins(argTypeNode.OutputTypePins[0], newMethod.EntryNode.InputTypePins[i]);
+ ConnectPins(argTypeNode.OutputTypePins[0], newMethod.EntryNode.InputTypePins[i]);
}
// Add return types, their type nodes and connect them
@@ -450,7 +302,7 @@ public static MethodGraph AddOverrideMethod(ClassGraph cls, MethodSpecifier meth
newMethod.MainReturnNode.AddReturnType();
- ConnectTypePins(returnTypeNode.OutputTypePins[0], newMethod.MainReturnNode.InputTypePins[i]);
+ ConnectPins(returnTypeNode.OutputTypePins[0], newMethod.MainReturnNode.InputTypePins[i]);
}
cls.Methods.Add(newMethod);
@@ -468,36 +320,36 @@ public static void ConnectRelevantPins(NodePin pin, Node node, Func 0 && node.OutputExecPins.Count > 0)
{
- var oldConnected = pin.Node.InputExecPins[0].IncomingPins.FirstOrDefault();
+ var oldConnected = pin.Node.InputExecPins[0].IncomingExecutionPins.FirstOrDefault();
if (oldConnected != null)
{
- GraphUtil.DisconnectOutputExecPin(oldConnected);
+ GraphUtil.DisconnectPin(oldConnected);
}
- GraphUtil.ConnectExecPins(node.OutputExecPins[0], pin.Node.InputExecPins[0]);
+ GraphUtil.ConnectPins(node.OutputExecPins[0], pin.Node.InputExecPins[0]);
if (oldConnected != null && node.InputExecPins.Count > 0)
{
- GraphUtil.ConnectExecPins(oldConnected, node.InputExecPins[0]);
+ GraphUtil.ConnectPins(oldConnected, node.InputExecPins[0]);
}
}
@@ -511,19 +363,19 @@ public static void ConnectRelevantPins(NodePin pin, Node node, Func 0 && pin.Node.OutputExecPins.Count > 0)
{
- var oldConnected = pin.Node.OutputExecPins[0].OutgoingPin;
+ var oldConnected = pin.Node.OutputExecPins[0].OutgoingExecPin;
- GraphUtil.ConnectExecPins(pin.Node.OutputExecPins[0], node.InputExecPins[0]);
+ GraphUtil.ConnectPins(pin.Node.OutputExecPins[0], node.InputExecPins[0]);
if (oldConnected != null && node.OutputExecPins.Count > 0)
{
- GraphUtil.ConnectExecPins(node.OutputExecPins[0], oldConnected);
+ GraphUtil.ConnectPins(node.OutputExecPins[0], oldConnected);
}
}
@@ -535,14 +387,14 @@ public static void ConnectRelevantPins(NodePin pin, Node node, Func 0)
{
- GraphUtil.ConnectTypePins(node.OutputTypePins[0], itp);
+ GraphUtil.ConnectPins(node.OutputTypePins[0], itp);
}
}
else if (pin is NodeOutputTypePin otp)
{
if (node.InputTypePins.Count > 0)
{
- GraphUtil.ConnectTypePins(otp, node.InputTypePins[0]);
+ GraphUtil.ConnectPins(otp, node.InputTypePins[0]);
}
}
}
diff --git a/NetPrints/Graph/LiteralNode.cs b/NetPrints/Graph/LiteralNode.cs
index 6b7c8ec..a00db90 100644
--- a/NetPrints/Graph/LiteralNode.cs
+++ b/NetPrints/Graph/LiteralNode.cs
@@ -68,13 +68,13 @@ private void UpdatePinTypes()
if (constructedType != InputValuePin.PinType.Value)
{
- GraphUtil.DisconnectInputDataPin(InputValuePin);
+ GraphUtil.DisconnectPin(InputValuePin);
InputValuePin.PinType.Value = constructedType;
}
if (constructedType != ValuePin.PinType.Value)
{
- GraphUtil.DisconnectOutputDataPin(ValuePin);
+ GraphUtil.DisconnectPin(ValuePin);
ValuePin.PinType.Value = constructedType;
}
}
diff --git a/NetPrints/Graph/MakeArrayNode.cs b/NetPrints/Graph/MakeArrayNode.cs
index 703b167..b2a2842 100644
--- a/NetPrints/Graph/MakeArrayNode.cs
+++ b/NetPrints/Graph/MakeArrayNode.cs
@@ -1,5 +1,7 @@
-using NetPrints.Core;
+using NetPrints.Base;
+using NetPrints.Core;
using System;
+using System.Linq;
using System.Runtime.Serialization;
namespace NetPrints.Graph
@@ -8,7 +10,7 @@ namespace NetPrints.Graph
/// Node representing the creation of an array.
///
[DataContract]
- public class MakeArrayNode : Node
+ public class MakeArrayNode : Node, INodeInputButtons
{
///
/// Whether this node is in predefined-size
@@ -108,8 +110,8 @@ private void UpdateInputDataPins()
else
{
// Remove size pin
- GraphUtil.DisconnectInputDataPin(InputDataPins[0]);
- InputDataPins.RemoveAt(0);
+ GraphUtil.DisconnectPin(InputDataPins[0]);
+ Pins.Remove(Pins.First(p => p is NodeDataPin));
}
}
@@ -127,34 +129,31 @@ protected override void OnInputTypeChanged(object sender, EventArgs eventArgs)
///
/// Adds an input data pin for an array element.
///
- public void AddElementPin()
- {
- AddInputDataPin($"Element{InputDataPins.Count}", ElementType);
- }
-
+ public void AddElementPin() => AddInputDataPin($"Element{InputDataPins.Count}", ElementType);
+
///
/// Removes the last input data pin for an array element.
/// Returns whether one was actually removed.
///
/// Whether a pin was removed.
- public bool RemoveElementPin()
+ public void RemoveElementPin()
{
if (InputDataPins.Count > 0)
{
// TODO: Add method for removing pins on Node
NodeInputDataPin inputDataPin = InputDataPins[InputDataPins.Count - 1];
- GraphUtil.DisconnectInputDataPin(inputDataPin);
- InputDataPins.Remove(inputDataPin);
-
- return true;
+ GraphUtil.DisconnectPin(inputDataPin);
+ Pins.Remove(inputDataPin);
}
-
- return false;
}
public override string ToString()
{
return $"Make {ElementType.Name} Array";
}
+
+ public void InputPlusClicked() => AddElementPin();
+
+ public void InputMinusClicked() => RemoveElementPin();
}
}
diff --git a/NetPrints/Graph/MethodEntryNode.cs b/NetPrints/Graph/MethodEntryNode.cs
index a394c01..7dcf9eb 100644
--- a/NetPrints/Graph/MethodEntryNode.cs
+++ b/NetPrints/Graph/MethodEntryNode.cs
@@ -9,7 +9,7 @@ namespace NetPrints.Graph
/// Node representing the initial execution node of a method.
///
[DataContract]
- public class MethodEntryNode : ExecutionEntryNode
+ public class MethodEntryNode : ExecutionEntryNode, INodeInputButtons, INodeOutputButtons
{
public MethodEntryNode(MethodGraph graph)
: base(graph)
@@ -46,11 +46,11 @@ public void RemoveArgument()
NodeOutputDataPin odpToRemove = OutputDataPins.Last();
NodeInputTypePin itpToRemove = InputTypePins.Last();
- GraphUtil.DisconnectOutputDataPin(odpToRemove);
- GraphUtil.DisconnectInputTypePin(itpToRemove);
+ GraphUtil.DisconnectPin(odpToRemove);
+ GraphUtil.DisconnectPin(itpToRemove);
- OutputDataPins.Remove(odpToRemove);
- InputTypePins.Remove(itpToRemove);
+ Pins.Remove(odpToRemove);
+ Pins.Remove(itpToRemove);
}
}
@@ -66,10 +66,18 @@ public void RemoveGenericArgument()
{
NodeOutputTypePin otpToRemove = OutputTypePins.Last();
- GraphUtil.DisconnectOutputTypePin(otpToRemove);
+ GraphUtil.DisconnectPin(otpToRemove);
- OutputTypePins.Remove(otpToRemove);
+ Pins.Remove(otpToRemove);
}
}
+
+ public void InputPlusClicked() => AddArgument();
+
+ public void InputMinusClicked() => RemoveArgument();
+
+ public void OutputPlusClicked() => AddGenericArgument();
+
+ public void OutputMinusClicked() => RemoveGenericArgument();
}
}
diff --git a/NetPrints/Graph/Node.cs b/NetPrints/Graph/Node.cs
index 559b6e5..70fc52a 100644
--- a/NetPrints/Graph/Node.cs
+++ b/NetPrints/Graph/Node.cs
@@ -1,6 +1,9 @@
-using NetPrints.Core;
+using NetPrints.Base;
+using NetPrints.Core;
using PropertyChanged;
using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Linq;
using System.Runtime.Serialization;
@@ -35,43 +38,41 @@ namespace NetPrints.Graph
[KnownType(typeof(TypeReturnNode))]
[KnownType(typeof(DefaultNode))]
[AddINotifyPropertyChangedInterface]
- public abstract class Node
+ public abstract class Node : INode
{
+ [DataMember]
+ public ObservableRangeCollection Pins { get; private set; } = new ObservableRangeCollection();
+
///
/// Input data pins of this node.
///
- [DataMember]
- public ObservableRangeCollection InputDataPins { get; private set; } = new ObservableRangeCollection();
+
+ public IObservableCollectionView InputDataPins { get; private set; }
///
/// Output data pins of this node.
///
- [DataMember]
- public ObservableRangeCollection OutputDataPins { get; private set; } = new ObservableRangeCollection();
+ public IObservableCollectionView OutputDataPins { get; private set; }
///
/// Input execution pins of this node.
///
- [DataMember]
- public ObservableRangeCollection InputExecPins { get; private set; } = new ObservableRangeCollection();
+ public IObservableCollectionView InputExecPins { get; private set; }
///
/// Output execution pins of this node.
///
- [DataMember]
- public ObservableRangeCollection OutputExecPins { get; private set; } = new ObservableRangeCollection();
+ public IObservableCollectionView OutputExecPins { get; private set; }
///
/// Input type pins of this node.
///
- [DataMember]
- public ObservableRangeCollection InputTypePins { get; private set; } = new ObservableRangeCollection();
+ public IObservableCollectionView InputTypePins { get; private set; }
///
/// Output type pins of this node.
///
- [DataMember]
- public ObservableRangeCollection OutputTypePins { get; private set; } = new ObservableRangeCollection();
+ public IObservableCollectionView OutputTypePins { get; private set; }
///
/// Delegate for the event of a position change of a node.
@@ -180,12 +181,28 @@ public NodeGraph Graph
private set;
}
+ INodeGraph INode.Graph => Graph;
+
protected Node(NodeGraph graph)
{
+ SetupPinViews();
+
+ Name = NetPrintsUtil.GetUniqueName(GetType().Name, graph.Nodes.Select(n => n.Name).ToList());
+
Graph = graph;
Graph.Nodes.Add(this);
+ }
- Name = NetPrintsUtil.GetUniqueName(GetType().Name, Graph.Nodes.Select(n => n.Name).ToList());
+ private void SetupPinViews()
+ {
+ static bool isType(object x) => x is T;
+
+ InputDataPins = new FilteredObservableCollection(Pins, isType);
+ OutputDataPins = new FilteredObservableCollection(Pins, isType);
+ InputExecPins = new FilteredObservableCollection(Pins, isType);
+ OutputExecPins = new FilteredObservableCollection(Pins, isType);
+ InputTypePins = new FilteredObservableCollection(Pins, isType);
+ OutputTypePins = new FilteredObservableCollection(Pins, isType);
}
public override string ToString()
@@ -200,7 +217,7 @@ public override string ToString()
/// Specifier for the type of this pin.
protected void AddInputDataPin(string pinName, ObservableValue pinType)
{
- InputDataPins.Add(new NodeInputDataPin(this, pinName, pinType));
+ Pins.Add(new NodeInputDataPin(this, pinName, pinType));
}
///
@@ -210,7 +227,7 @@ protected void AddInputDataPin(string pinName, ObservableValue pinType
/// Specifier for the type of this pin.
protected void AddOutputDataPin(string pinName, ObservableValue pinType)
{
- OutputDataPins.Add(new NodeOutputDataPin(this, pinName, pinType));
+ Pins.Add(new NodeOutputDataPin(this, pinName, pinType));
}
///
@@ -219,7 +236,7 @@ protected void AddOutputDataPin(string pinName, ObservableValue pinTyp
/// Name of the pin.
protected void AddInputExecPin(string pinName)
{
- InputExecPins.Add(new NodeInputExecPin(this, pinName));
+ Pins.Add(new NodeInputExecPin(this, pinName));
}
///
@@ -228,7 +245,7 @@ protected void AddInputExecPin(string pinName)
/// Name of the pin.
protected void AddOutputExecPin(string pinName)
{
- OutputExecPins.Add(new NodeOutputExecPin(this, pinName));
+ Pins.Add(new NodeOutputExecPin(this, pinName));
}
///
@@ -239,7 +256,7 @@ protected void AddInputTypePin(string pinName)
{
var typePin = new NodeInputTypePin(this, pinName);
typePin.IncomingPinChanged += OnIncomingTypePinChanged;
- InputTypePins.Add(typePin);
+ Pins.Add(typePin);
}
///
@@ -249,7 +266,7 @@ protected void AddInputTypePin(string pinName)
/// Function that generates the output type.
protected void AddOutputTypePin(string pinName, ObservableValue outputType)
{
- OutputTypePins.Add(new NodeOutputTypePin(this, pinName, outputType));
+ Pins.Add(new NodeOutputTypePin(this, pinName, outputType));
}
private void OnIncomingTypePinChanged(NodeInputTypePin pin, NodeOutputTypePin oldPin, NodeOutputTypePin newPin)
@@ -283,6 +300,8 @@ protected virtual void OnInputTypeChanged(object sender, EventArgs eventArgs)
[OnDeserialized]
private void OnDeserializing(StreamingContext context)
{
+ SetupPinViews();
+
foreach (var inputTypePin in InputTypePins)
{
if (inputTypePin.InferredType != null)
diff --git a/NetPrints/Graph/NodeDataPin.cs b/NetPrints/Graph/NodeDataPin.cs
index 4e1d80a..9369093 100644
--- a/NetPrints/Graph/NodeDataPin.cs
+++ b/NetPrints/Graph/NodeDataPin.cs
@@ -1,4 +1,5 @@
-using NetPrints.Core;
+using NetPrints.Base;
+using NetPrints.Core;
using System.Runtime.Serialization;
namespace NetPrints.Graph
@@ -7,7 +8,7 @@ namespace NetPrints.Graph
/// Abstract class for data pins.
///
[DataContract]
- public abstract class NodeDataPin : NodePin
+ public abstract class NodeDataPin : NodePin, INodeDataPin
{
///
/// Specifier for the type of this data pin.
diff --git a/NetPrints/Graph/NodeExecPin.cs b/NetPrints/Graph/NodeExecPin.cs
index 93a4c4f..6dcefd2 100644
--- a/NetPrints/Graph/NodeExecPin.cs
+++ b/NetPrints/Graph/NodeExecPin.cs
@@ -1,4 +1,5 @@
-using System.Runtime.Serialization;
+using NetPrints.Base;
+using System.Runtime.Serialization;
namespace NetPrints.Graph
{
@@ -6,7 +7,7 @@ namespace NetPrints.Graph
/// Abstract class for execution pins.
///
[DataContract]
- public abstract class NodeExecPin : NodePin
+ public abstract class NodeExecPin : NodePin, INodeExecutionPin
{
protected NodeExecPin(Node node, string name)
: base(node, name)
diff --git a/NetPrints/Graph/NodeInputDataPin.cs b/NetPrints/Graph/NodeInputDataPin.cs
index 978df79..6687363 100644
--- a/NetPrints/Graph/NodeInputDataPin.cs
+++ b/NetPrints/Graph/NodeInputDataPin.cs
@@ -1,5 +1,7 @@
-using NetPrints.Core;
+using NetPrints.Base;
+using NetPrints.Core;
using System;
+using System.Collections.ObjectModel;
using System.Runtime.Serialization;
namespace NetPrints.Graph
@@ -11,7 +13,7 @@ public delegate void InputDataPinIncomingPinChangedDelegate(
/// Input data pin which can be connected to up to one output data pin to receive a value.
///
[DataContract]
- public class NodeInputDataPin : NodeDataPin
+ public class NodeInputDataPin : NodeDataPin, INodeInputPin
{
///
/// Called when the node's incoming pin changed.
@@ -22,22 +24,7 @@ public class NodeInputDataPin : NodeDataPin
/// Incoming data pin for this pin. Null when not connected.
/// Can trigger IncomingPinChanged when set.
///
- [DataMember]
- public NodeOutputDataPin IncomingPin
- {
- get => incomingPin;
- set
- {
- if (incomingPin != value)
- {
- var oldPin = incomingPin;
-
- incomingPin = value;
-
- IncomingPinChanged?.Invoke(this, oldPin, incomingPin);
- }
- }
- }
+ public NodeOutputDataPin IncomingPin => IncomingPins.Count > 0 ? (NodeOutputDataPin)IncomingPins[0] : null;
///
/// Whether this pin uses its unconnected value to output a value
@@ -48,8 +35,6 @@ public bool UsesUnconnectedValue
get => PinType.Value is TypeSpecifier t && t.IsPrimitive;
}
- private NodeOutputDataPin incomingPin;
-
///
/// Unconnected value of this pin when no pin is connected to it.
/// Setting this for types that don't support unconnected values will throw
@@ -91,8 +76,12 @@ public bool UsesExplicitDefaultValue
{
get;
set;
- }
-
+ }
+
+ public IObservableCollectionView IncomingPins => ConnectedPins.ObservableOfType();
+
+ public override NodePinConnectionType ConnectionType => NodePinConnectionType.Single;
+
public NodeInputDataPin(Node node, string name, ObservableValue pinType)
: base(node, name, pinType)
{
diff --git a/NetPrints/Graph/NodeInputExecPin.cs b/NetPrints/Graph/NodeInputExecPin.cs
index e2c32cf..fc65c47 100644
--- a/NetPrints/Graph/NodeInputExecPin.cs
+++ b/NetPrints/Graph/NodeInputExecPin.cs
@@ -1,4 +1,6 @@
-using NetPrints.Core;
+using NetPrints.Base;
+using NetPrints.Core;
+using System.Collections.ObjectModel;
using System.Runtime.Serialization;
namespace NetPrints.Graph
@@ -7,15 +9,17 @@ namespace NetPrints.Graph
/// Pin that can be connected to output execution pins to receive execution.
///
[DataContract]
- public class NodeInputExecPin : NodeExecPin
- {
+ public class NodeInputExecPin : NodeExecPin, INodeInputPin
+ {
///
/// Output execution pins connected to this pin.
- ///
- [DataMember]
- public ObservableRangeCollection IncomingPins { get; private set; } =
- new ObservableRangeCollection();
-
+ ///
+ public IObservableCollectionView IncomingExecutionPins => ConnectedPins.ObservableOfType();
+
+ public IObservableCollectionView IncomingPins => ConnectedPins.ObservableOfType();
+
+ public override NodePinConnectionType ConnectionType => NodePinConnectionType.Multiple;
+
public NodeInputExecPin(Node node, string name)
: base(node, name)
{
diff --git a/NetPrints/Graph/NodeInputTypePin.cs b/NetPrints/Graph/NodeInputTypePin.cs
index dc5a670..2eb89fc 100644
--- a/NetPrints/Graph/NodeInputTypePin.cs
+++ b/NetPrints/Graph/NodeInputTypePin.cs
@@ -1,4 +1,5 @@
-using NetPrints.Core;
+using NetPrints.Base;
+using NetPrints.Core;
using System.Runtime.Serialization;
namespace NetPrints.Graph
@@ -10,41 +11,28 @@ public delegate void InputTypePinIncomingPinChangedDelegate(
/// Pin which can receive types.
///
[DataContract]
- public class NodeInputTypePin : NodeTypePin
+ public class NodeInputTypePin : NodeTypePin, INodeInputPin
{
///
/// Called when the node's incoming pin changed.
///
- public event InputTypePinIncomingPinChangedDelegate IncomingPinChanged;
-
+ public event InputTypePinIncomingPinChangedDelegate IncomingPinChanged;
+
///
/// Incoming type pin for this pin. Null when not connected.
/// Can trigger IncomingPinChanged when set.
- ///
- [DataMember]
- public NodeOutputTypePin IncomingPin
- {
- get => incomingPin;
- set
- {
- if (incomingPin != value)
- {
- var oldPin = incomingPin;
-
- incomingPin = value;
-
- IncomingPinChanged?.Invoke(this, oldPin, incomingPin);
- }
- }
- }
+ ///
+ public NodeOutputTypePin IncomingPin => IncomingPins.Count > 0 ? (NodeOutputTypePin)IncomingPins[0] : null;
public override ObservableValue InferredType
{
get => IncomingPin?.InferredType;
}
- private NodeOutputTypePin incomingPin;
-
+ public IObservableCollectionView IncomingPins => ConnectedPins.ObservableOfType();
+
+ public override NodePinConnectionType ConnectionType => NodePinConnectionType.Single;
+
public NodeInputTypePin(Node node, string name)
: base(node, name)
{
diff --git a/NetPrints/Graph/NodeOutputDataPin.cs b/NetPrints/Graph/NodeOutputDataPin.cs
index a1341f9..9209d15 100644
--- a/NetPrints/Graph/NodeOutputDataPin.cs
+++ b/NetPrints/Graph/NodeOutputDataPin.cs
@@ -1,4 +1,5 @@
-using NetPrints.Core;
+using NetPrints.Base;
+using NetPrints.Core;
using System.Runtime.Serialization;
namespace NetPrints.Graph
@@ -7,15 +8,17 @@ namespace NetPrints.Graph
/// Pin which outputs a value. Can be connected to input data pins.
///
[DataContract]
- public class NodeOutputDataPin : NodeDataPin
+ public class NodeOutputDataPin : NodeDataPin, INodeOutputPin
{
///
/// Connected input data pins.
///
- [DataMember]
- public ObservableRangeCollection OutgoingPins { get; private set; }
- = new ObservableRangeCollection();
-
+ public IObservableCollectionView OutgoingDataPins => ConnectedPins.ObservableOfType();
+
+ public IObservableCollectionView OutgoingPins => ConnectedPins.ObservableOfType();
+
+ public override NodePinConnectionType ConnectionType => NodePinConnectionType.Multiple;
+
public NodeOutputDataPin(Node node, string name, ObservableValue pinType)
: base(node, name, pinType)
{
diff --git a/NetPrints/Graph/NodeOutputExecPin.cs b/NetPrints/Graph/NodeOutputExecPin.cs
index 2776284..2e0d3ec 100644
--- a/NetPrints/Graph/NodeOutputExecPin.cs
+++ b/NetPrints/Graph/NodeOutputExecPin.cs
@@ -1,4 +1,6 @@
-using System.Runtime.Serialization;
+using NetPrints.Base;
+using NetPrints.Core;
+using System.Runtime.Serialization;
namespace NetPrints.Graph
{
@@ -9,7 +11,7 @@ public delegate void OutputExecPinOutgoingPinChangedDelegate(
/// Pin which can be connected to an input execution pin to pass along execution.
///
[DataContract]
- public class NodeOutputExecPin : NodeExecPin
+ public class NodeOutputExecPin : NodeExecPin, INodeOutputPin
{
///
/// Called when the connected outgoing pin changed.
@@ -20,25 +22,13 @@ public class NodeOutputExecPin : NodeExecPin
/// Connected input execution pin. Null if not connected.
/// Can trigger OutgoingPinChanged when set.
///
- [DataMember]
- public NodeInputExecPin OutgoingPin
- {
- get => outgoingPin;
- set
- {
- if (outgoingPin != value)
- {
- var oldPin = outgoingPin;
-
- outgoingPin = value;
-
- OutgoingPinChanged?.Invoke(this, oldPin, outgoingPin);
- }
- }
- }
-
- private NodeInputExecPin outgoingPin;
-
+
+ public NodeInputExecPin OutgoingExecPin => OutgoingPins.Count > 0 ? (NodeInputExecPin)OutgoingPins[0] : null;
+
+ public IObservableCollectionView OutgoingPins => ConnectedPins.ObservableOfType();
+
+ public override NodePinConnectionType ConnectionType => NodePinConnectionType.Single;
+
public NodeOutputExecPin(Node node, string name)
: base(node, name)
{
diff --git a/NetPrints/Graph/NodeOutputTypePin.cs b/NetPrints/Graph/NodeOutputTypePin.cs
index ad4085a..5f7f63b 100644
--- a/NetPrints/Graph/NodeOutputTypePin.cs
+++ b/NetPrints/Graph/NodeOutputTypePin.cs
@@ -1,4 +1,6 @@
-using NetPrints.Core;
+using NetPrints.Base;
+using NetPrints.Core;
+using System.Linq;
using System.Runtime.Serialization;
namespace NetPrints.Graph
@@ -7,32 +9,29 @@ namespace NetPrints.Graph
/// Pin which outputs a type. Can be connected to input type pins.
///
[DataContract]
- public class NodeOutputTypePin : NodeTypePin
+ public class NodeOutputTypePin : NodeTypePin, INodeOutputPin
{
///
/// Connected input data pins.
///
- [DataMember]
- public ObservableRangeCollection OutgoingPins { get; private set; }
- = new ObservableRangeCollection();
-
- public override ObservableValue InferredType
- {
- get => outputType;
- }
+ public IObservableCollectionView OutgoingTypePins => ConnectedPins.ObservableOfType();
[DataMember]
- private ObservableValue outputType;
+ public override ObservableValue InferredType { get; }
+
+ public IObservableCollectionView OutgoingPins => ConnectedPins.ObservableOfType();
+
+ public override NodePinConnectionType ConnectionType => NodePinConnectionType.Multiple;
public NodeOutputTypePin(Node node, string name, ObservableValue outputType)
: base(node, name)
{
- this.outputType = outputType;
+ InferredType = outputType;
}
public override string ToString()
{
- return outputType.Value?.ShortName ?? "None";
+ return InferredType.Value?.ShortName ?? "None";
}
}
}
diff --git a/NetPrints/Graph/NodePin.cs b/NetPrints/Graph/NodePin.cs
index fee7345..9495234 100644
--- a/NetPrints/Graph/NodePin.cs
+++ b/NetPrints/Graph/NodePin.cs
@@ -1,4 +1,8 @@
-using PropertyChanged;
+using NetPrints.Base;
+using NetPrints.Core;
+using PropertyChanged;
+using System;
+using System.ComponentModel;
using System.Runtime.Serialization;
namespace NetPrints.Graph
@@ -14,8 +18,11 @@ namespace NetPrints.Graph
[KnownType(typeof(NodeInputTypePin))]
[KnownType(typeof(NodeOutputTypePin))]
[AddINotifyPropertyChangedInterface]
- public abstract class NodePin
- {
+ public abstract class NodePin : INodePin
+ {
+ private double positionX;
+ private double positionY;
+
///
/// Name of the pin.
///
@@ -34,8 +41,30 @@ public Node Node
{
get;
private set;
- }
-
+ }
+
+ public double PositionX
+ {
+ get { return positionX; }
+ set { positionX = value; PositionChanged?.Invoke(this, EventArgs.Empty); }
+ }
+ public double PositionY
+ {
+ get { return positionY; }
+ set { positionY = value; PositionChanged?.Invoke(this, EventArgs.Empty); }
+ }
+
+ public event EventHandler PositionChanged;
+
+ INode INodePin.Node => Node;
+
+ public abstract NodePinConnectionType ConnectionType { get; }
+
+ public ObservableRangeCollection ConnectedPins => connectedPins;
+
+ [DataMember]
+ private ObservableRangeCollection connectedPins = new ObservableRangeCollection();
+
protected NodePin(Node node, string name)
{
Node = node;
diff --git a/NetPrints/Graph/NodeTypePin.cs b/NetPrints/Graph/NodeTypePin.cs
index 81de5dc..1d5b467 100644
--- a/NetPrints/Graph/NodeTypePin.cs
+++ b/NetPrints/Graph/NodeTypePin.cs
@@ -1,4 +1,5 @@
-using NetPrints.Core;
+using NetPrints.Base;
+using NetPrints.Core;
using System.Runtime.Serialization;
namespace NetPrints.Graph
@@ -7,7 +8,7 @@ namespace NetPrints.Graph
/// Abstract class for type pins.
///
[DataContract]
- public abstract class NodeTypePin : NodePin
+ public abstract class NodeTypePin : NodePin, INodeTypePin
{
public abstract ObservableValue InferredType
{
diff --git a/NetPrints/Graph/ReturnNode.cs b/NetPrints/Graph/ReturnNode.cs
index faf2445..64f3876 100644
--- a/NetPrints/Graph/ReturnNode.cs
+++ b/NetPrints/Graph/ReturnNode.cs
@@ -1,4 +1,5 @@
-using NetPrints.Core;
+using NetPrints.Base;
+using NetPrints.Core;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -10,7 +11,7 @@ namespace NetPrints.Graph
/// Represents a node which returns from a method.
///
[DataContract]
- public class ReturnNode : Node
+ public class ReturnNode : Node, INodeInputButtons
{
///
/// Execution pin that returns from the method when executed.
@@ -52,10 +53,11 @@ private void ReplicateMainNodeInputTypes()
oldConnections.Add(i, pin.IncomingPin);
}
- GraphUtil.DisconnectInputDataPin(pin);
+ GraphUtil.DisconnectPin(pin);
}
- InputDataPins.Clear();
+ // Remove old data pins
+ Pins.RemoveRange(Pins.Where(pin => pin is INodeInputPin && pin is INodeDataPin));
foreach (NodeInputDataPin mainInputPin in mainInputPins)
{
@@ -65,7 +67,7 @@ private void ReplicateMainNodeInputTypes()
// Restore old connections
foreach (var oldConn in oldConnections)
{
- GraphUtil.ConnectDataPins(oldConn.Value, InputDataPins[oldConn.Key]);
+ GraphUtil.ConnectPins(oldConn.Value, InputDataPins[oldConn.Key]);
}
}
@@ -116,11 +118,11 @@ public void RemoveReturnType()
NodeInputDataPin idpToRemove = InputDataPins.Last();
NodeInputTypePin itpToRemove = InputTypePins.Last();
- GraphUtil.DisconnectInputDataPin(idpToRemove);
- GraphUtil.DisconnectInputTypePin(itpToRemove);
+ GraphUtil.DisconnectPin(idpToRemove);
+ GraphUtil.DisconnectPin(itpToRemove);
- InputDataPins.Remove(idpToRemove);
- InputTypePins.Remove(itpToRemove);
+ Pins.Remove(idpToRemove);
+ Pins.Remove(itpToRemove);
}
}
@@ -144,6 +146,10 @@ private void SetupSecondaryNodeEvents()
public override string ToString()
{
return "Return";
- }
+ }
+
+ public void InputPlusClicked() => AddReturnType();
+
+ public void InputMinusClicked() => RemoveReturnType();
}
}
diff --git a/NetPrints/Serialization/SerializationHelper.cs b/NetPrints/Serialization/SerializationHelper.cs
index 825f988..bfbae02 100644
--- a/NetPrints/Serialization/SerializationHelper.cs
+++ b/NetPrints/Serialization/SerializationHelper.cs
@@ -1,4 +1,7 @@
using NetPrints.Core;
+using NetPrints.Graph;
+using System;
+using System.Collections.Generic;
using System.IO;
using System.Runtime.Serialization;
@@ -10,6 +13,12 @@ public static class SerializationHelper
{
PreserveObjectReferences = true,
MaxItemsInObjectGraph = int.MaxValue,
+ KnownTypes = new Type[]
+ {
+ typeof(Node),
+ typeof(NodeGraph),
+ typeof(NodePin)
+ },
});
///
diff --git a/NetPrints/Translator/ExecutionGraphTranslator.cs b/NetPrints/Translator/ExecutionGraphTranslator.cs
index 847a427..a45e770 100644
--- a/NetPrints/Translator/ExecutionGraphTranslator.cs
+++ b/NetPrints/Translator/ExecutionGraphTranslator.cs
@@ -332,7 +332,7 @@ public string Translate(ExecutionGraph graph, bool withSignature)
builder.AppendLine();
// Start at node after method entry if necessary (id!=0)
- if (graph.EntryNode.OutputExecPins[0].OutgoingPin != null && GetExecPinStateId(graph.EntryNode.OutputExecPins[0].OutgoingPin) != 0)
+ if (graph.EntryNode.OutputExecPins[0].OutgoingExecPin != null && GetExecPinStateId(graph.EntryNode.OutputExecPins[0].OutgoingExecPin) != 0)
{
WriteGotoOutputPin(graph.EntryNode.OutputExecPins[0]);
}
@@ -423,13 +423,13 @@ private void WriteGotoInputPin(NodeInputExecPin pin)
private void WriteGotoOutputPin(NodeOutputExecPin pin)
{
- if (pin.OutgoingPin == null)
+ if (pin.OutgoingExecPin == null)
{
WriteGotoJumpStack();
}
else
{
- WriteGotoInputPin(pin.OutgoingPin);
+ WriteGotoInputPin(pin.OutgoingExecPin);
}
}
@@ -438,7 +438,7 @@ private void WriteGotoOutputPinIfNecessary(NodeOutputExecPin pin, NodeInputExecP
int fromId = GetExecPinStateId(fromPin);
int nextId = fromId + 1;
- if (pin.OutgoingPin == null)
+ if (pin.OutgoingExecPin == null)
{
if (nextId != jumpStackStateId)
{
@@ -447,13 +447,13 @@ private void WriteGotoOutputPinIfNecessary(NodeOutputExecPin pin, NodeInputExecP
}
else
{
- int toId = GetExecPinStateId(pin.OutgoingPin);
+ int toId = GetExecPinStateId(pin.OutgoingExecPin);
// Only write the goto if the next state is not
// the state we want to go to.
if (nextId != toId)
{
- WriteGotoInputPin(pin.OutgoingPin);
+ WriteGotoInputPin(pin.OutgoingExecPin);
}
}
}
@@ -747,7 +747,7 @@ public void TranslateExplicitCastNode(ExplicitCastNode node)
// If failure pin is not connected write explicit cast that throws.
// Otherwise check if cast object is null and execute failure
// path if it is.
- if (node.IsPure || node.CastFailedPin.OutgoingPin == null)
+ if (node.IsPure || node.CastFailedPin.OutgoingExecPin == null)
{
builder.AppendLine($"{outputName} = ({node.CastType.FullCodeNameUnbound}){pinToCastName};");
@@ -918,7 +918,7 @@ public void TranslateIfElseNode(IfElseNode node)
builder.AppendLine($"if ({conditionVar})");
builder.AppendLine("{");
- if (node.TruePin.OutgoingPin != null)
+ if (node.TruePin.OutgoingExecPin != null)
{
WriteGotoOutputPinIfNecessary(node.TruePin, node.InputExecPins[0]);
}
@@ -932,7 +932,7 @@ public void TranslateIfElseNode(IfElseNode node)
builder.AppendLine("else");
builder.AppendLine("{");
- if (node.FalsePin.OutgoingPin != null)
+ if (node.FalsePin.OutgoingExecPin != null)
{
WriteGotoOutputPinIfNecessary(node.FalsePin, node.InputExecPins[0]);
}
@@ -1083,6 +1083,7 @@ public void PureTranslateMakeArrayNode(MakeArrayNode node)
builder.AppendLine("};");
}
}
+
public void PureTranslateDefaultNode(DefaultNode node)
{
builder.AppendLine($"{GetOrCreatePinName(node.DefaultValuePin)} = default({node.Type.FullCodeName});");
diff --git a/NetPrints/Translator/TranslatorUtil.cs b/NetPrints/Translator/TranslatorUtil.cs
index cacfdc3..eb47f87 100644
--- a/NetPrints/Translator/TranslatorUtil.cs
+++ b/NetPrints/Translator/TranslatorUtil.cs
@@ -140,9 +140,9 @@ private static void AddAllNodes(Node node, ref HashSet nodes)
foreach (NodeOutputExecPin pin in node.OutputExecPins)
{
- if (pin.OutgoingPin != null && !nodes.Contains(pin.OutgoingPin.Node))
+ if (pin.OutgoingExecPin != null && !nodes.Contains(pin.OutgoingExecPin.Node))
{
- AddAllNodes(pin.OutgoingPin.Node, ref nodes);
+ AddAllNodes(pin.OutgoingExecPin.Node, ref nodes);
}
}
@@ -183,9 +183,9 @@ private static void AddExecNodes(Node node, ref HashSet nodes)
foreach (NodeOutputExecPin pin in node.OutputExecPins)
{
- if (pin.OutgoingPin != null && !nodes.Contains(pin.OutgoingPin.Node))
+ if (pin.OutgoingExecPin != null && !nodes.Contains(pin.OutgoingExecPin.Node))
{
- AddExecNodes(pin.OutgoingPin.Node, ref nodes);
+ AddExecNodes(pin.OutgoingExecPin.Node, ref nodes);
}
}
}
diff --git a/NetPrintsEditor/Controls/GraphEditorView.xaml b/NetPrintsEditor/Controls/GraphEditorView.xaml
index 1c90d1a..b9b8905 100644
--- a/NetPrintsEditor/Controls/GraphEditorView.xaml
+++ b/NetPrintsEditor/Controls/GraphEditorView.xaml
@@ -12,6 +12,8 @@
+
+
-
+
@@ -76,21 +78,28 @@
-
+
+
+
+
-
+
+ Point1="{Binding Connection.PointB, Converter={StaticResource PointConverter}}"
+ Point2="{Binding Connection.PointC, Converter={StaticResource PointConverter}}"
+ Point3="{Binding Connection.PointD, Converter={StaticResource PointConverter}}" />
diff --git a/NetPrintsEditor/Controls/GraphEditorView.xaml.cs b/NetPrintsEditor/Controls/GraphEditorView.xaml.cs
index 869867e..2daec87 100644
--- a/NetPrintsEditor/Controls/GraphEditorView.xaml.cs
+++ b/NetPrintsEditor/Controls/GraphEditorView.xaml.cs
@@ -1,4 +1,5 @@
-using NetPrints.Core;
+using NetPrints.Base;
+using NetPrints.Core;
using NetPrints.Graph;
using NetPrintsEditor.Commands;
using NetPrintsEditor.Dialogs;
@@ -475,32 +476,43 @@ private void CablePath_MouseLeave(object sender, MouseEventArgs e)
private void CablePath_MouseDown(object sender, MouseButtonEventArgs e)
{
var element = sender as FrameworkElement;
- if (!(element?.DataContext is NodePinVM pin))
+ if (!(element?.DataContext is PinConnectionVM connViewModel))
{
throw new Exception("Could not find cable's pin.");
}
if (e.ChangedButton == MouseButton.Left && e.LeftButton == MouseButtonState.Pressed && e.ClickCount == 2)
{
- pin.AddRerouteNode();
+ if (connViewModel.Connection.PinA is NodeInputDataPin idp)
+ {
+ GraphUtil.AddRerouteNode(idp);
+ }
+ else if (connViewModel.Connection.PinA is NodeInputTypePin itp)
+ {
+ GraphUtil.AddRerouteNode(itp);
+ }
+ else if (connViewModel.Connection.PinA is NodeOutputExecPin oep)
+ {
+ GraphUtil.AddRerouteNode(oep);
+ }
}
else if (e.ChangedButton == MouseButton.Middle)
{
- pin.DisconnectAll();
+ GraphUtil.DisconnectPins(connViewModel.Connection.PinA, connViewModel.Connection.PinB);
}
}
private void CablePath_MouseUp(object sender, MouseButtonEventArgs e)
{
var element = sender as FrameworkElement;
- if (!(element?.DataContext is NodePinVM pin))
+ if (!(element?.DataContext is PinConnectionVM connection))
{
throw new Exception("Could not find cable's pin.");
}
if (e.ChangedButton == MouseButton.XButton1 && e.RightButton == MouseButtonState.Released)
{
- pin.IsFaint = !pin.IsFaint;
+ //connection.IsFaint = !connection.IsFaint;
}
}
}
diff --git a/NetPrintsEditor/Controls/PinControl.xaml.cs b/NetPrintsEditor/Controls/PinControl.xaml.cs
index e152d01..e1ea6f5 100644
--- a/NetPrintsEditor/Controls/PinControl.xaml.cs
+++ b/NetPrintsEditor/Controls/PinControl.xaml.cs
@@ -96,7 +96,7 @@ private void OnPinElementDrop(object sender, DragEventArgs e)
// Another pin was dropped on this pin, link it
NodePinVM droppedPin = (NodePinVM)e.Data.GetData(typeof(NodePinVM));
- droppedPin.ConnectTo(Pin);
+ GraphUtil.ConnectPins(droppedPin.Pin, Pin.Pin);
e.Handled = true;
}
diff --git a/NetPrintsEditor/Converters/ModelToViewModelConverter.cs b/NetPrintsEditor/Converters/ModelToViewModelConverter.cs
index ff6c11a..c7a7d89 100644
--- a/NetPrintsEditor/Converters/ModelToViewModelConverter.cs
+++ b/NetPrintsEditor/Converters/ModelToViewModelConverter.cs
@@ -1,4 +1,5 @@
-using NetPrints.Core;
+using NetPrints.Base;
+using NetPrints.Core;
using NetPrints.Graph;
using NetPrintsEditor.ViewModels;
using System;
@@ -31,6 +32,10 @@ public object Convert(object value, Type targetType, object parameter, CultureIn
{
return new CompilationReferenceVM(reference);
}
+ else if (value is PinConnection connection)
+ {
+ return new PinConnectionVM(connection);
+ }
throw new ArgumentException();
}
diff --git a/NetPrintsEditor/Converters/PointConverter.cs b/NetPrintsEditor/Converters/PointConverter.cs
new file mode 100644
index 0000000..a5d52ab
--- /dev/null
+++ b/NetPrintsEditor/Converters/PointConverter.cs
@@ -0,0 +1,20 @@
+using System;
+using System.Globalization;
+
+namespace NetPrintsEditor.Converters
+{
+ public class PointConverter : System.Windows.Data.IValueConverter
+ {
+ public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ System.Drawing.Point dp = (System.Drawing.Point)value;
+ return new System.Windows.Point(dp.X, dp.Y);
+ }
+
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ System.Windows.Point wp = (System.Windows.Point)value;
+ return new System.Drawing.Point((int)wp.X, (int)wp.Y);
+ }
+ }
+}
diff --git a/NetPrintsEditor/Reflection/ISuggestionGenerator.cs b/NetPrintsEditor/Reflection/ISuggestionGenerator.cs
new file mode 100644
index 0000000..0012630
--- /dev/null
+++ b/NetPrintsEditor/Reflection/ISuggestionGenerator.cs
@@ -0,0 +1,10 @@
+using NetPrints.Base;
+using System.Collections.Generic;
+
+namespace NetPrintsEditor.Reflection
+{
+ public interface ISuggestionGenerator
+ {
+ IEnumerable<(string, object)> GetSuggestions(INodeGraph graph, INodePin pin = null);
+ }
+}
diff --git a/NetPrintsEditor/Reflection/SuggestionGenerator.cs b/NetPrintsEditor/Reflection/SuggestionGenerator.cs
new file mode 100644
index 0000000..f283c67
--- /dev/null
+++ b/NetPrintsEditor/Reflection/SuggestionGenerator.cs
@@ -0,0 +1,250 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using NetPrints.Base;
+using NetPrints.Core;
+using NetPrints.Graph;
+using NetPrintsEditor.Dialogs;
+
+namespace NetPrintsEditor.Reflection
+{
+ public class SuggestionGenerator : ISuggestionGenerator
+ {
+ private readonly Dictionary> builtInNodes = new Dictionary>()
+ {
+ [typeof(MethodGraph)] = new List
public NodePin SuggestionPin { get; set; }
- private readonly Dictionary> builtInNodes = new Dictionary>()
- {
- [typeof(MethodGraph)] = new List()
- {
- TypeSpecifier.FromType(),
- TypeSpecifier.FromType(),
- TypeSpecifier.FromType(),
- TypeSpecifier.FromType(),
- TypeSpecifier.FromType(),
- TypeSpecifier.FromType(),
- TypeSpecifier.FromType(),
- TypeSpecifier.FromType(),
- TypeSpecifier.FromType(),
- TypeSpecifier.FromType(),
- TypeSpecifier.FromType(),
- TypeSpecifier.FromType(),
- TypeSpecifier.FromType(),
- TypeSpecifier.FromType(),
- },
- [typeof(ConstructorGraph)] = new List()
- {
- TypeSpecifier.FromType(),
- TypeSpecifier.FromType(),
- TypeSpecifier.FromType(),
- TypeSpecifier.FromType(),
- TypeSpecifier.FromType(),
- TypeSpecifier.FromType(),
- TypeSpecifier.FromType(),
- TypeSpecifier.FromType(),
- TypeSpecifier.FromType(),
- TypeSpecifier.FromType(),
- TypeSpecifier.FromType(),
- TypeSpecifier.FromType(),
- },
- [typeof(ClassGraph)] = new List()
- {
- TypeSpecifier.FromType(),
- TypeSpecifier.FromType(),
- },
- };
+ public ObservableRangeCollection Connections => connectionTracker.Connections;
+
+ private GraphConnectionTracker connectionTracker;
public SuggestionListVM SuggestionViewModel { get; } = new SuggestionListVM();
public event EventHandler OnHideContextMenu;
- private List GetBuiltInNodes(NodeGraph graph)
- {
- if (builtInNodes.TryGetValue(graph.GetType(), out var nodes))
- {
- return nodes;
- }
-
- return new List();
- }
+ private readonly ISuggestionGenerator suggestionGenerator = new SuggestionGenerator();
public void UpdateSuggestions(double mouseX, double mouseY)
{
@@ -92,188 +48,7 @@ public void UpdateSuggestions(double mouseX, double mouseY)
SuggestionViewModel.SuggestionPin = SuggestionPin;
SuggestionViewModel.HideContextMenu = () => OnHideContextMenu?.Invoke(this, EventArgs.Empty);
- // Show all relevant methods for the type of the pin
- IEnumerable<(string, object)> suggestions = new (string, object)[0];
-
- void AddSuggestionsWithCategory(string category, IEnumerable newSuggestions)
- {
- suggestions = suggestions.Concat(newSuggestions.Select(suggestion => (category, suggestion)));
- }
-
- if (SuggestionPin != null)
- {
- if (SuggestionPin is NodeOutputDataPin odp)
- {
- if (odp.PinType.Value is TypeSpecifier pinTypeSpec)
- {
- // Add make delegate
- AddSuggestionsWithCategory("NetPrints", new[] { new MakeDelegateTypeInfo(pinTypeSpec, Graph.Class.Type) });
-
- // Add variables and methods of the pin type
- AddSuggestionsWithCategory("Pin Variables",
- App.ReflectionProvider.GetVariables(
- new ReflectionProviderVariableQuery()
- .WithType(pinTypeSpec)
- .WithVisibleFrom(Graph.Class.Type)
- .WithStatic(false)));
-
- AddSuggestionsWithCategory("Pin Methods", App.ReflectionProvider.GetMethods(
- new ReflectionProviderMethodQuery()
- .WithVisibleFrom(Graph.Class.Type)
- .WithStatic(false)
- .WithType(pinTypeSpec)));
-
- // Add methods of the base types that can accept the pin type as argument
- foreach (var baseType in Graph.Class.AllBaseTypes)
- {
- AddSuggestionsWithCategory("This Methods", App.ReflectionProvider.GetMethods(
- new ReflectionProviderMethodQuery()
- .WithVisibleFrom(Graph.Class.Type)
- .WithStatic(false)
- .WithArgumentType(pinTypeSpec)
- .WithType(baseType)));
- }
-
- // Add static functions taking the type of the pin
- AddSuggestionsWithCategory("Static Methods", App.ReflectionProvider.GetMethods(
- new ReflectionProviderMethodQuery()
- .WithArgumentType(pinTypeSpec)
- .WithVisibleFrom(Graph.Class.Type)
- .WithStatic(true)));
- }
- }
- else if (SuggestionPin is NodeInputDataPin idp)
- {
- if (idp.PinType.Value is TypeSpecifier pinTypeSpec)
- {
- // Variables of base classes that inherit from needed type
- foreach (var baseType in Graph.Class.AllBaseTypes)
- {
- AddSuggestionsWithCategory("This Variables", App.ReflectionProvider.GetVariables(
- new ReflectionProviderVariableQuery()
- .WithType(baseType)
- .WithVisibleFrom(Graph.Class.Type)
- .WithVariableType(pinTypeSpec, true)));
- }
-
- // Add static functions returning the type of the pin
- AddSuggestionsWithCategory("Static Methods", App.ReflectionProvider.GetMethods(
- new ReflectionProviderMethodQuery()
- .WithStatic(true)
- .WithVisibleFrom(Graph.Class.Type)
- .WithReturnType(pinTypeSpec)));
- }
- }
- else if (SuggestionPin is NodeOutputExecPin oxp)
- {
- GraphUtil.DisconnectOutputExecPin(oxp);
-
- AddSuggestionsWithCategory("NetPrints", GetBuiltInNodes(Graph));
-
- foreach (var baseType in Graph.Class.AllBaseTypes)
- {
- AddSuggestionsWithCategory("This Methods", App.ReflectionProvider.GetMethods(
- new ReflectionProviderMethodQuery()
- .WithType(baseType)
- .WithStatic(false)
- .WithVisibleFrom(Graph.Class.Type)));
- }
-
- AddSuggestionsWithCategory("Static Methods", App.ReflectionProvider.GetMethods(
- new ReflectionProviderMethodQuery()
- .WithStatic(true)
- .WithVisibleFrom(Graph.Class.Type)));
- }
- else if (SuggestionPin is NodeInputExecPin ixp)
- {
- AddSuggestionsWithCategory("NetPrints", GetBuiltInNodes(Graph));
-
- foreach (var baseType in Graph.Class.AllBaseTypes)
- {
- AddSuggestionsWithCategory("This Methods", App.ReflectionProvider.GetMethods(
- new ReflectionProviderMethodQuery()
- .WithType(baseType)
- .WithStatic(false)
- .WithVisibleFrom(Graph.Class.Type)));
- }
-
- AddSuggestionsWithCategory("Static Methods", App.ReflectionProvider.GetMethods(
- new ReflectionProviderMethodQuery()
- .WithStatic(true)
- .WithVisibleFrom(Graph.Class.Type)));
- }
- else if (SuggestionPin is NodeInputTypePin itp)
- {
- // TODO: Consider static types
- AddSuggestionsWithCategory("Types", App.ReflectionProvider.GetNonStaticTypes());
- }
- else if (SuggestionPin is NodeOutputTypePin otp)
- {
- if (Graph is ExecutionGraph && otp.InferredType.Value is TypeSpecifier typeSpecifier)
- {
- AddSuggestionsWithCategory("Pin Static Methods", App.ReflectionProvider
- .GetMethods(new ReflectionProviderMethodQuery()
- .WithType(typeSpecifier)
- .WithStatic(true)
- .WithVisibleFrom(Graph.Class.Type)));
- }
-
- // Types with type parameters
- AddSuggestionsWithCategory("Generic Types", App.ReflectionProvider.GetNonStaticTypes()
- .Where(t => t.GenericArguments.Any()));
-
- if (Graph is ExecutionGraph)
- {
- // Public static methods that have type parameters
- AddSuggestionsWithCategory("Generic Static Methods", App.ReflectionProvider
- .GetMethods(new ReflectionProviderMethodQuery()
- .WithStatic(true)
- .WithHasGenericArguments(true)
- .WithVisibleFrom(Graph.Class.Type)));
- }
- }
-
- Suggestions = suggestions.Distinct().Select(x => new SearchableComboBoxItem(x.Item1, x.Item2));
- }
- else
- {
- AddSuggestionsWithCategory("NetPrints", GetBuiltInNodes(Graph));
-
- if (Graph is ExecutionGraph)
- {
- // Get properties and methods of base class.
- foreach (var baseType in Graph.Class.AllBaseTypes)
- {
- AddSuggestionsWithCategory("This Variables", App.ReflectionProvider.GetVariables(
- new ReflectionProviderVariableQuery()
- .WithVisibleFrom(Graph.Class.Type)
- .WithType(baseType)
- .WithStatic(false)));
-
- AddSuggestionsWithCategory("This Methods", App.ReflectionProvider.GetMethods(
- new ReflectionProviderMethodQuery()
- .WithType(baseType)
- .WithVisibleFrom(Graph.Class.Type)
- .WithStatic(false)));
- }
-
- AddSuggestionsWithCategory("Static Methods", App.ReflectionProvider.GetMethods(
- new ReflectionProviderMethodQuery()
- .WithStatic(true)
- .WithVisibleFrom(Graph.Class.Type)));
-
- AddSuggestionsWithCategory("Static Variables", App.ReflectionProvider.GetVariables(
- new ReflectionProviderVariableQuery()
- .WithStatic(true)
- .WithVisibleFrom(Graph.Class.Type)));
- }
- else if (Graph is ClassGraph)
- {
- AddSuggestionsWithCategory("Types", App.ReflectionProvider.GetNonStaticTypes());
- }
- }
-
- Suggestions = suggestions.Distinct().Select(x => new SearchableComboBoxItem(x.Item1, x.Item2));
+ Suggestions = suggestionGenerator.GetSuggestions(Graph, SuggestionPin).Select(x => new SearchableComboBoxItem(x.Item1, x.Item2));
}
public IEnumerable SelectedNodes
@@ -322,7 +97,7 @@ public string Name
public bool IsConstructor => graph is ConstructorGraph;
- public ObservableViewModelCollection Nodes { get; set; }
+ public ObservableViewModelCollection Nodes { get; set; }
public IEnumerable ArgumentTypes =>
graph is ExecutionGraph execGraph ? execGraph.ArgumentTypes : null;
@@ -366,76 +141,34 @@ public MemberVisibility Visibility
MemberVisibility.Protected,
MemberVisibility.Public,
};
+
+ #region Node dragging
+ public double NodeDragScale
+ {
+ get;
+ set;
+ } = 1;
+
+ private double nodeDragAccumX;
+ private double nodeDragAccumY;
- /*
- Scenarios:
-
- Method changed [0]:
- (Un)assign (old) nodes changed events [1]
- (Un)assign (old)new pins changed events [2]
- (Un)assign (old)new pin connection changed events [3]
- (Un)setup (old)new method pins' connections in VM
-
- Node changed [1]:
- (Un)assign (old)new pins changed events [2]
- (Un)assign (old)new pin connection changed events [3]
- (Un)setup (old)new node pins' connections in VM
-
- Pin changed [2]:
- (Un)assign (old)new pin connection changed events [3]
- (Un)setup (old)new pin connection in VM
-
- Pin connection changed [3]:
- (Un)setup (old)new connection in VM
- */
-
- private void SetupNodeEvents(NodeVM node, bool add)
+ private readonly Dictionary nodeStartPositions = new Dictionary();
+
+ private void SetupNodeDragEvents(NodeVM node, bool add)
{
- // (Un)assign (old)new pins changed events [2]
if (add)
{
- node.InputDataPins.CollectionChanged += OnPinCollectionChanged;
- node.OutputDataPins.CollectionChanged += OnPinCollectionChanged;
- node.InputExecPins.CollectionChanged += OnPinCollectionChanged;
- node.OutputExecPins.CollectionChanged += OnPinCollectionChanged;
- node.InputTypePins.CollectionChanged += OnPinCollectionChanged;
- node.OutputTypePins.CollectionChanged += OnPinCollectionChanged;
-
node.OnDragStart += OnNodeDragStart;
node.OnDragEnd += OnNodeDragEnd;
node.OnDragMove += OnNodeDragMove;
}
else
{
- node.InputDataPins.CollectionChanged -= OnPinCollectionChanged;
- node.OutputDataPins.CollectionChanged -= OnPinCollectionChanged;
- node.InputExecPins.CollectionChanged -= OnPinCollectionChanged;
- node.OutputExecPins.CollectionChanged -= OnPinCollectionChanged;
- node.InputTypePins.CollectionChanged -= OnPinCollectionChanged;
- node.OutputTypePins.CollectionChanged -= OnPinCollectionChanged;
-
node.OnDragStart -= OnNodeDragStart;
node.OnDragEnd -= OnNodeDragEnd;
node.OnDragMove -= OnNodeDragMove;
}
-
- // (Un)assign (old)new pin connection changed events [3]
- node.InputDataPins.ToList().ForEach(p => SetupPinEvents(p, add));
- node.OutputExecPins.ToList().ForEach(p => SetupPinEvents(p, add));
- node.InputTypePins.ToList().ForEach(p => SetupPinEvents(p, add));
- }
-
- #region Node dragging
- public double NodeDragScale
- {
- get;
- set;
- } = 1;
-
- private double nodeDragAccumX;
- private double nodeDragAccumY;
-
- private readonly Dictionary nodeStartPositions = new Dictionary();
+ }
///
/// Called when a node starts dragging.
@@ -492,122 +225,6 @@ private void OnNodeDragMove(NodeVM node, double dx, double dy)
}
}
#endregion
-
- private void SetupPinEvents(NodePinVM pin, bool add)
- {
- // (Un)assign (old)new pin connection changed events [3]
-
- if (pin.Pin is NodeInputDataPin idp)
- {
- if (add)
- {
- idp.IncomingPinChanged += OnInputDataPinIncomingPinChanged;
- }
- else
- {
- idp.IncomingPinChanged -= OnInputDataPinIncomingPinChanged;
- }
- }
- else if (pin.Pin is NodeOutputExecPin oxp)
- {
- if (add)
- {
- oxp.OutgoingPinChanged += OnOutputExecPinIncomingPinChanged;
- }
- else
- {
- oxp.OutgoingPinChanged -= OnOutputExecPinIncomingPinChanged;
- }
- }
- else if (pin.Pin is NodeInputTypePin itp)
- {
- if (add)
- {
- itp.IncomingPinChanged += OnInputTypePinIncomingPinChanged;
- }
- else
- {
- itp.IncomingPinChanged -= OnInputTypePinIncomingPinChanged;
- }
- }
- }
-
- private void SetupPinConnection(NodePinVM pin, bool add)
- {
- if (pin.Pin is NodeInputDataPin idp)
- {
- if (idp.IncomingPin != null)
- {
- if (add)
- {
- NodeOutputDataPin connPin = idp.IncomingPin as NodeOutputDataPin;
- pin.ConnectedPin = Nodes
- .SingleOrDefault(n => n.Node == connPin.Node)
- ?.OutputDataPins
- ?.Single(x => x.Pin == connPin);
- }
- else
- {
- pin.ConnectedPin = null;
- }
- }
- }
- else if (pin.Pin is NodeOutputExecPin oxp)
- {
- if (oxp.OutgoingPin != null)
- {
- if (add)
- {
- NodeInputExecPin connPin = oxp.OutgoingPin as NodeInputExecPin;
- pin.ConnectedPin = Nodes
- .Single(n => n.Node == connPin.Node)
- .InputExecPins
- .Single(x => x.Pin == connPin);
- }
- else
- {
- pin.ConnectedPin = null;
- }
- }
- }
- else if (pin.Pin is NodeInputTypePin itp)
- {
- if (itp.IncomingPin != null)
- {
- if (add)
- {
- NodeOutputTypePin connPin = itp.IncomingPin as NodeOutputTypePin;
- pin.ConnectedPin = Nodes
- .Single(n => n.Node == connPin.Node)
- .OutputTypePins
- .Single(x => x.Pin == connPin);
- }
- else
- {
- pin.ConnectedPin = null;
- }
- }
- }
- }
-
- private void SetupNodeConnections(NodeVM node, bool add)
- {
- node.OutputExecPins.ToList().ForEach(p => SetupPinConnection(p, add));
- node.InputDataPins.ToList().ForEach(p => SetupPinConnection(p, add));
- node.InputTypePins.ToList().ForEach(p => SetupPinConnection(p, add));
-
- // Make sure to remove the IXP and ODP connections
- // any other nodes are connecting to too
-
- if (!add)
- {
- AllPins.Where(p =>
- node.InputExecPins.Contains(p.ConnectedPin)
- || node.OutputDataPins.Contains(p.ConnectedPin)
- || node.OutputTypePins.Contains(p.ConnectedPin)
- ).ToList().ForEach(p => p.ConnectedPin = null);
- }
- }
public NodeGraph Graph
{
@@ -619,26 +236,23 @@ public NodeGraph Graph
if (graph != null)
{
Nodes.CollectionChanged -= OnNodeCollectionChanged;
- Nodes.ToList().ForEach(n => SetupNodeEvents(n, false));
-
- Nodes.ToList().ForEach(n => SetupNodeConnections(n, false));
+ Nodes.ToList().ForEach(n => SetupNodeDragEvents(n, false));
}
graph = value;
RaisePropertyChanged(nameof(AllPins));
RaisePropertyChanged(nameof(Visibility));
- Nodes = new ObservableViewModelCollection(Graph.Nodes, n => new NodeVM(n));
+ Nodes = new ObservableViewModelCollection(Graph.Nodes, n => new NodeVM((Node)n));
if (graph != null)
{
Nodes.CollectionChanged += OnNodeCollectionChanged;
- Nodes.ToList().ForEach(n => SetupNodeEvents(n, true));
-
- // Connections on normal pins already exist,
- // Set them up for the viewmodels of the pins
- Nodes.ToList().ForEach(n => SetupNodeConnections(n, true));
+ Nodes.ToList().ForEach(n => SetupNodeDragEvents(n, true));
}
+
+ connectionTracker = new GraphConnectionTracker(graph);
+ RaisePropertyChanged(nameof(Connections));
}
}
}
@@ -650,103 +264,19 @@ private void OnNodeCollectionChanged(object sender, NotifyCollectionChangedEvent
if (e.OldItems != null)
{
var removedNodes = e.OldItems.Cast();
- removedNodes.ToList().ForEach(n => SetupNodeEvents(n, false));
-
- removedNodes.ToList().ForEach(n => SetupNodeConnections(n, false));
+ removedNodes.ToList().ForEach(n => SetupNodeDragEvents(n, false));
}
if (e.NewItems != null)
{
var addedNodes = e.NewItems.Cast();
- addedNodes.ToList().ForEach(n => SetupNodeEvents(n, true));
-
- addedNodes.ToList().ForEach(n => SetupNodeConnections(n, true));
- }
-
- RaisePropertyChanged(nameof(AllPins));
- }
-
- private void OnPinCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
- {
- if (e.OldItems != null)
- {
- var removedPins = e.OldItems.Cast();
-
- // Unsetup initial connections of added pins
- removedPins.ToList().ForEach(p => SetupPinConnection(p, false));
-
- // Remove events for removed pins
- removedPins.ToList().ForEach(p => SetupPinEvents(p, false));
- }
-
- if (e.NewItems != null)
- {
- var addedPins = e.NewItems.Cast();
-
- // Setup initial connections of added pins
- addedPins.ToList().ForEach(p => SetupPinConnection(p, true));
-
- // Add events for added pins
- addedPins.ToList().ForEach(p => SetupPinEvents(p, true));
+ addedNodes.ToList().ForEach(n => SetupNodeDragEvents(n, true));
}
RaisePropertyChanged(nameof(AllPins));
}
- private void OnInputDataPinIncomingPinChanged(NodeInputDataPin pin, NodeOutputDataPin oldPin, NodeOutputDataPin newPin)
- {
- // Connect pinVM newPinVM (or null if newPin is null)
-
- NodePinVM pinVM = FindPinVMFromPin(pin);
- pinVM.ConnectedPin = newPin == null ? null : FindPinVMFromPin(newPin);
- }
-
- private void OnOutputExecPinIncomingPinChanged(NodeOutputExecPin pin, NodeInputExecPin oldPin, NodeInputExecPin newPin)
- {
- // Connect pinVM newPinVM (or null if newPin is null)
-
- NodePinVM pinVM = FindPinVMFromPin(pin);
- pinVM.ConnectedPin = newPin == null ? null : FindPinVMFromPin(newPin);
- }
-
- private void OnInputTypePinIncomingPinChanged(NodeInputTypePin pin, NodeOutputTypePin oldPin, NodeOutputTypePin newPin)
- {
- // Connect pinVM newPinVM (or null if newPin is null)
-
- NodePinVM pinVM = FindPinVMFromPin(pin);
- if (pinVM != null)
- {
- pinVM.ConnectedPin = newPin == null ? null : FindPinVMFromPin(newPin);
- }
- }
-
- private NodePinVM FindPinVMFromPin(NodePin pin)
- {
- return AllPins.SingleOrDefault(p => p.Pin == pin);
- }
-
- public IEnumerable AllPins
- {
- get
- {
- List pins = new List();
-
- if (Graph != null)
- {
- foreach (NodeVM node in Nodes)
- {
- pins.AddRange(node.InputDataPins);
- pins.AddRange(node.OutputDataPins);
- pins.AddRange(node.InputExecPins);
- pins.AddRange(node.OutputExecPins);
- pins.AddRange(node.InputTypePins);
- pins.AddRange(node.OutputTypePins);
- }
- }
-
- return pins;
- }
- }
+ public IEnumerable AllPins => Graph != null ? Nodes.SelectMany(node => node.Pins) : new NodePinVM[0];
///
/// Sends a message to deselect all nodes and select the given nodes.
diff --git a/NetPrintsEditor/ViewModels/NodePinVM.cs b/NetPrintsEditor/ViewModels/NodePinVM.cs
index 9ba59ea..6701d6b 100644
--- a/NetPrintsEditor/ViewModels/NodePinVM.cs
+++ b/NetPrintsEditor/ViewModels/NodePinVM.cs
@@ -1,4 +1,5 @@
using GalaSoft.MvvmLight;
+using NetPrints.Base;
using NetPrints.Core;
using NetPrints.Graph;
using NetPrints.Translator;
@@ -105,13 +106,6 @@ public bool IsBeingConnected
{
isBeingConnected = value;
- // Disconnect pin if its being connected
- // and is an IDP, OXP or ITP
- if (value && (Pin is NodeInputDataPin || Pin is NodeOutputExecPin || Pin is NodeInputTypePin))
- {
- ConnectedPin = null;
- }
-
RaisePropertyChanged();
RaisePropertyChanged(nameof(IsCableVisible));
OnConnectionPositionUpdate();
@@ -168,10 +162,7 @@ private void OnInputTypeChanged(object sender, EventArgs eventArgs)
RaisePropertyChanged(nameof(ToolTip));
}
- public bool IsRerouteNodePin
- {
- get => Node is RerouteNode;
- }
+ public bool IsRerouteNodePin => Node is RerouteNode;
///
/// Disconnects the pin from all of its connections.
@@ -349,12 +340,7 @@ public Brush FillBrush
get
{
// Check if the pin is connected to anything
- if ((pin is NodeInputDataPin idp && idp.IncomingPin != null)
- || (pin is NodeOutputDataPin odp && odp.OutgoingPins.Count > 0)
- || (pin is NodeInputExecPin iep && iep.IncomingPins.Count > 0)
- || (pin is NodeOutputExecPin oep && oep.OutgoingPin != null)
- || (pin is NodeInputTypePin itp && itp.IncomingPin != null)
- || (pin is NodeOutputTypePin otp && otp.OutgoingPins.Count > 0))
+ if (pin.ConnectedPins.Count > 0)
{
return BorderBrush;
}
@@ -365,11 +351,11 @@ public Brush FillBrush
}
}
- public bool ShowRectangle => pin is NodeExecPin;
+ public bool ShowRectangle => pin is INodeExecutionPin;
- public bool ShowCircle => pin is NodeDataPin;
+ public bool ShowCircle => pin is INodeDataPin;
- public bool ShowTriangle => pin is NodeTypePin;
+ public bool ShowTriangle => pin is INodeTypePin;
public bool ShowDefaultValueIndicator => pin is NodeInputDataPin idp && idp.UsesExplicitDefaultValue;
@@ -383,6 +369,12 @@ pin is NodeInputDataPin idp
Node.PositionX + NodeRelativePosition.X,
Node.PositionY + NodeRelativePosition.Y);
+ private void OnAbsolutePositionChanged()
+ {
+ Pin.PositionX = AbsolutePosition.X;
+ Pin.PositionY = AbsolutePosition.Y;
+ }
+
public Point NodeRelativePosition
{
get => nodeRelativePosition;
@@ -401,146 +393,15 @@ public Point NodeRelativePosition
private void OnConnectionPositionUpdate()
{
RaisePropertyChanged(nameof(NodeRelativePosition));
- RaisePropertyChanged(nameof(ConnectedAbsolutePosition));
- RaisePropertyChanged(nameof(ConnectedCP1));
- RaisePropertyChanged(nameof(ConnectedCP2));
RaisePropertyChanged(nameof(AbsolutePosition));
+ OnAbsolutePositionChanged();
}
- // = Incoming pin for data input
- // = Outgoing pin for exec output
- // = Incoming pin for type input
- // = null for rest
- public NodePinVM ConnectedPin
- {
- get => connectedPin;
- set
- {
- if (!(Pin is NodeOutputExecPin || Pin is NodeInputDataPin || Pin is NodeInputTypePin))
- {
- throw new Exception("Can only set connected pin of NodeOutputExecPin and NodeInputDataPin");
- }
-
- if (connectedPin != value)
- {
- if (connectedPin != null)
- {
- connectedPin.Node.OnPositionChanged -= OnConnectedPinNodePositionChanged;
- connectedPin.PropertyChanged -= OnConnectedPinPropertyChanged;
- }
-
- if (value != null)
- {
- GraphUtil.ConnectNodePins(Pin, value.Pin);
- }
- else
- {
- if (Pin is NodeOutputExecPin oxp)
- {
- GraphUtil.DisconnectOutputExecPin(oxp);
- }
- else if (Pin is NodeInputDataPin idp)
- {
- GraphUtil.DisconnectInputDataPin(idp);
- }
- else if (Pin is NodeInputTypePin itp)
- {
- GraphUtil.DisconnectInputTypePin(itp);
- }
- }
-
- connectedPin = value;
- RaisePropertyChanged();
- RaisePropertyChanged(nameof(IsConnected));
- RaisePropertyChanged(nameof(IsCableVisible));
- RaisePropertyChanged(nameof(ShowUnconnectedValue));
- RaisePropertyChanged(nameof(ShowEnumValue));
- RaisePropertyChanged(nameof(PossibleEnumNames));
- RaisePropertyChanged(nameof(FillBrush));
- RaisePropertyChanged(nameof(DefaultValueIndicatorBrush));
- OnConnectionPositionUpdate();
-
- if (connectedPin != null)
- {
- connectedPin.Node.OnPositionChanged += OnConnectedPinNodePositionChanged;
- connectedPin.PropertyChanged += OnConnectedPinPropertyChanged;
- }
- }
- }
- }
-
- private void OnConnectedPinPropertyChanged(object sender, PropertyChangedEventArgs e)
- {
- if (e.PropertyName == nameof(Position) || e.PropertyName == nameof(NodeRelativePosition))
- {
- OnConnectionPositionUpdate();
- }
- }
-
- public bool IsConnected
- {
- get => connectedPin != null;
- }
-
- public bool IsCableVisible
- {
- get => IsConnected || IsBeingConnected;
- }
-
- private void OnConnectedPinNodePositionChanged(Node node, double posX, double posY)
- {
- OnConnectionPositionUpdate();
- }
-
- private const double CPOffset = 100;
-
- public Point ConnectedCP1
- {
- get
- {
- if (Pin is NodeOutputExecPin || Pin is NodeOutputDataPin || Pin is NodeOutputTypePin)
- {
- return new Point(AbsolutePosition.X + CPOffset, AbsolutePosition.Y);
- }
- else
- {
- return new Point(AbsolutePosition.X - CPOffset, AbsolutePosition.Y);
- }
- }
- }
+ public bool IsConnected => pin.ConnectedPins.Count > 0;
- public Point ConnectedCP2
- {
- get
- {
- if (Pin is NodeOutputExecPin || Pin is NodeOutputDataPin || Pin is NodeOutputTypePin)
- {
- return new Point(ConnectedAbsolutePosition.X - CPOffset, ConnectedAbsolutePosition.Y);
- }
- else
- {
- return new Point(ConnectedAbsolutePosition.X + CPOffset, ConnectedAbsolutePosition.Y);
- }
- }
- }
-
- public Point ConnectedAbsolutePosition
- {
- get
- {
- if (IsBeingConnected)
- {
- return ConnectingAbsolutePosition;
- }
- else
- {
- return IsConnected ? ConnectedPin.AbsolutePosition : AbsolutePosition;
- }
- }
- }
+ public bool IsCableVisible => IsBeingConnected;
private NodePin pin;
- private NodePinVM connectedPin;
private double positionX;
private double positionY;
@@ -550,52 +411,6 @@ public NodePinVM(NodePin pin)
Pin = pin;
}
- ///
- /// Adds a reroute node for this pin. Only valid
- /// for input data pins and output execution pins.
- ///
- public void AddRerouteNode()
- {
- if (Pin is NodeInputDataPin dataPin)
- {
- RerouteNode rerouteNode = GraphUtil.AddRerouteNode(dataPin);
- rerouteNode.PositionX = (Pin.Node.PositionX + dataPin.IncomingPin.Node.PositionX) / 2;
- rerouteNode.PositionY = (Pin.Node.PositionY + dataPin.IncomingPin.Node.PositionY) / 2;
- }
- else if (Pin is NodeOutputExecPin execPin)
- {
- RerouteNode rerouteNode = GraphUtil.AddRerouteNode(execPin);
- rerouteNode.PositionX = (Pin.Node.PositionX + execPin.OutgoingPin.Node.PositionX) / 2;
- rerouteNode.PositionY = (Pin.Node.PositionY + execPin.OutgoingPin.Node.PositionY) / 2;
- }
- else if (Pin is NodeInputTypePin typePin)
- {
- RerouteNode rerouteNode = GraphUtil.AddRerouteNode(typePin);
- rerouteNode.PositionX = (Pin.Node.PositionX + typePin.IncomingPin.Node.PositionX) / 2;
- rerouteNode.PositionY = (Pin.Node.PositionY + typePin.IncomingPin.Node.PositionY) / 2;
- }
- else
- {
- throw new Exception("Can't add reroute node for invalid pin type");
- }
- }
-
- ///
- /// Connects this pin to another pin.
- ///
- /// Pin to connect to.
- public void ConnectTo(NodePinVM other)
- {
- if (Pin is NodeInputDataPin || Pin is NodeOutputExecPin || Pin is NodeInputTypePin)
- {
- ConnectedPin = other;
- }
- else
- {
- other.ConnectedPin = this;
- }
- }
-
private void OnPinChanged()
{
pin.PropertyChanged += OnPinPropertyChanged;
diff --git a/NetPrintsEditor/ViewModels/NodeVM.cs b/NetPrintsEditor/ViewModels/NodeVM.cs
index 9231dde..6e46230 100644
--- a/NetPrintsEditor/ViewModels/NodeVM.cs
+++ b/NetPrintsEditor/ViewModels/NodeVM.cs
@@ -1,13 +1,13 @@
using NetPrints.Core;
using NetPrints.Graph;
using System.ComponentModel;
-using System.Runtime.CompilerServices;
using System.Windows.Media;
using System.Linq;
using System;
using GalaSoft.MvvmLight;
using NetPrintsEditor.Messages;
-
+using NetPrints.Base;
+
namespace NetPrintsEditor.ViewModels
{
public class NodeVM : ViewModelBase
@@ -271,90 +271,13 @@ public string Name
}
}
- public ObservableViewModelCollection InputDataPins
- {
- get => inputDataPins;
- set
- {
- if (inputDataPins != value)
- {
- inputDataPins = value;
- RaisePropertyChanged();
- }
- }
- }
-
- public ObservableViewModelCollection OutputDataPins
- {
- get => outputDataPins;
- set
- {
- if (outputDataPins != value)
- {
- outputDataPins = value;
- RaisePropertyChanged();
- }
- }
- }
-
- public ObservableViewModelCollection InputExecPins
- {
- get => inputExecPins;
- set
- {
- if (inputExecPins != value)
- {
- inputExecPins = value;
- RaisePropertyChanged();
- }
- }
- }
-
- public ObservableViewModelCollection OutputExecPins
- {
- get => outputExecPins;
- set
- {
- if (outputExecPins != value)
- {
- outputExecPins = value;
- RaisePropertyChanged();
- }
- }
- }
-
- public ObservableViewModelCollection InputTypePins
- {
- get => inputTypePins;
- set
- {
- if (inputTypePins != value)
- {
- inputTypePins = value;
- RaisePropertyChanged();
- }
- }
- }
-
- public ObservableViewModelCollection OutputTypePins
- {
- get => outputTypePins;
- set
- {
- if (outputTypePins != value)
- {
- outputTypePins = value;
- RaisePropertyChanged();
- }
- }
- }
-
- private ObservableViewModelCollection inputDataPins;
- private ObservableViewModelCollection outputDataPins;
- private ObservableViewModelCollection inputExecPins;
- private ObservableViewModelCollection outputExecPins;
- private ObservableViewModelCollection inputTypePins;
- private ObservableViewModelCollection outputTypePins;
+ public ObservableViewModelCollection Pins { get; private set; }
+ public IObservableCollectionView InputExecPins { get; private set; }
+ public IObservableCollectionView OutputExecPins { get; private set; }
+ public IObservableCollectionView InputDataPins { get; private set; }
+ public IObservableCollectionView OutputDataPins { get; private set; }
+ public IObservableCollectionView InputTypePins { get; private set; }
+ public IObservableCollectionView OutputTypePins { get; private set; }
public bool IsPure
{
@@ -386,23 +309,13 @@ public Node Node
{
node.InputTypeChanged += OnInputTypeChanged;
- InputDataPins = new ObservableViewModelCollection(
- Node.InputDataPins, p => new NodePinVM(p));
-
- OutputDataPins = new ObservableViewModelCollection(
- Node.OutputDataPins, p => new NodePinVM(p));
-
- InputExecPins = new ObservableViewModelCollection(
- Node.InputExecPins, p => new NodePinVM(p));
-
- OutputExecPins = new ObservableViewModelCollection(
- Node.OutputExecPins, p => new NodePinVM(p));
-
- InputTypePins = new ObservableViewModelCollection(
- Node.InputTypePins, p => new NodePinVM(p));
-
- OutputTypePins = new ObservableViewModelCollection(
- Node.OutputTypePins, p => new NodePinVM(p));
+ Pins = new ObservableViewModelCollection(Node.Pins, p => new NodePinVM((NodePin)p));
+ InputExecPins = Pins.ObservableWhere(pinViewModel => pinViewModel.Pin is NodeInputExecPin);
+ OutputExecPins = Pins.ObservableWhere(pinViewModel => pinViewModel.Pin is NodeOutputExecPin);
+ InputDataPins = Pins.ObservableWhere(pinViewModel => pinViewModel.Pin is NodeInputDataPin);
+ OutputDataPins = Pins.ObservableWhere(pinViewModel => pinViewModel.Pin is NodeOutputDataPin);
+ InputTypePins = Pins.ObservableWhere(pinViewModel => pinViewModel.Pin is NodeInputTypePin);
+ OutputTypePins = Pins.ObservableWhere(pinViewModel => pinViewModel.Pin is NodeOutputTypePin);
}
UpdateOverloads();
@@ -520,8 +433,8 @@ public void ChangeOverload(object overload)
bool oldPurity = Node.IsPure;
if (!oldPurity)
{
- oldIncomingPins = Node.InputExecPins[0].IncomingPins.ToArray();
- oldOutgoingPin = Node.OutputExecPins[0].OutgoingPin;
+ oldIncomingPins = Node.InputExecPins[0].IncomingExecutionPins.ToArray();
+ oldOutgoingPin = Node.OutputExecPins[0].OutgoingExecPin;
}
// Disconnect the old node from other nodes and remove it
@@ -543,14 +456,14 @@ public void ChangeOverload(object overload)
{
if (oldOutgoingPin != null)
{
- GraphUtil.ConnectExecPins(newNode.OutputExecPins[0], oldOutgoingPin);
+ GraphUtil.ConnectPins(newNode.OutputExecPins[0], oldOutgoingPin);
}
if (oldIncomingPins != null)
{
foreach (NodeOutputExecPin oldIncomingPin in oldIncomingPins)
{
- GraphUtil.ConnectExecPins(oldIncomingPin, newNode.InputExecPins[0]);
+ GraphUtil.ConnectPins(oldIncomingPin, newNode.InputExecPins[0]);
}
}
}
@@ -576,7 +489,7 @@ public NodeGraph Graph
///
public bool ShowLeftPinButtons
{
- get => node is MakeArrayNode || node is MethodEntryNode || (node is ReturnNode && node == Method.MainReturnNode) || node is ClassReturnNode;
+ get => node is INodeInputButtons;
}
///
@@ -585,7 +498,7 @@ public bool ShowLeftPinButtons
///
public bool ShowRightPinButtons
{
- get => node is MethodEntryNode;
+ get => node is INodeOutputButtons;
}
///
@@ -593,45 +506,15 @@ public bool ShowRightPinButtons
///
public void LeftPinsPlusClicked()
{
- if (node is MakeArrayNode makeArrayNode)
- {
- makeArrayNode.AddElementPin();
- }
- else if (node is MethodEntryNode entryNode)
- {
- entryNode.AddArgument();
- }
- else if (node is ReturnNode returnNode)
- {
- returnNode.AddReturnType();
- }
- else if (node is ClassReturnNode classReturnNode)
- {
- classReturnNode.AddInterfacePin();
- }
+ (node as INodeInputButtons)?.InputPlusClicked();
}
///
/// Called when the left pins' minus button was clicked.
///
public void LeftPinsMinusClicked()
- {
- if (node is MakeArrayNode makeArrayNode)
- {
- makeArrayNode.RemoveElementPin();
- }
- else if (node is MethodEntryNode entryNode)
- {
- entryNode.RemoveArgument();
- }
- else if (node is ReturnNode returnNode)
- {
- returnNode.RemoveReturnType();
- }
- else if (node is ClassReturnNode classReturnNode)
- {
- classReturnNode.RemoveInterfacePin();
- }
+ {
+ (node as INodeInputButtons)?.InputMinusClicked();
}
///
@@ -639,10 +522,7 @@ public void LeftPinsMinusClicked()
///
public void RightPinsPlusClicked()
{
- if (node is MethodEntryNode entryNode)
- {
- entryNode.AddGenericArgument();
- }
+ (node as INodeOutputButtons)?.OutputPlusClicked();
}
///
@@ -650,10 +530,7 @@ public void RightPinsPlusClicked()
///
public void RightPinsMinusClicked()
{
- if (node is MethodEntryNode entryNode)
- {
- entryNode.RemoveGenericArgument();
- }
+ (node as INodeOutputButtons)?.OutputMinusClicked();
}
private Node node;
diff --git a/NetPrintsEditor/ViewModels/PinConnectionVM.cs b/NetPrintsEditor/ViewModels/PinConnectionVM.cs
new file mode 100644
index 0000000..d99333f
--- /dev/null
+++ b/NetPrintsEditor/ViewModels/PinConnectionVM.cs
@@ -0,0 +1,31 @@
+using GalaSoft.MvvmLight;
+using NetPrints.Base;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Windows.Media;
+
+namespace NetPrintsEditor.ViewModels
+{
+ public class PinConnectionVM : ViewModelBase
+ {
+ public PinConnection Connection { get; }
+
+ private static readonly Dictionary typeBrushes = new Dictionary()
+ {
+ [typeof(INodeExecutionPin)] = new SolidColorBrush(Color.FromArgb(0xFF, 0xE0, 0xFF, 0xE0)),
+ [typeof(INodeDataPin)] = new SolidColorBrush(Color.FromArgb(0xFF, 0xE0, 0xE0, 0xFF)),
+ [typeof(INodeTypePin)] = new SolidColorBrush(Color.FromArgb(0xFF, 0xFF, 0xE0, 0xE0)),
+ };
+
+ public Brush Brush
+ {
+ get => typeBrushes.Single(x => (Connection.PinA.ConnectionType == NodePinConnectionType.Single ? Connection.PinA : Connection.PinB).GetType().GetInterfaces().Any(interf => interf == x.Key)).Value;
+ }
+
+ public PinConnectionVM(PinConnection connection)
+ {
+ Connection = connection;
+ }
+ }
+}
diff --git a/NetPrintsUnitTests/ClassTranslatorTests.cs b/NetPrintsUnitTests/ClassTranslatorTests.cs
index 6c492a5..1b651d8 100644
--- a/NetPrintsUnitTests/ClassTranslatorTests.cs
+++ b/NetPrintsUnitTests/ClassTranslatorTests.cs
@@ -34,7 +34,7 @@ public void CreateStringLengthMethod()
for (int i = 0; i < returnTypeNodes.Count; i++)
{
stringLengthMethod.MainReturnNode.AddReturnType();
- GraphUtil.ConnectTypePins(returnTypeNodes[i].OutputTypePins[0], stringLengthMethod.MainReturnNode.InputTypePins[i]);
+ GraphUtil.ConnectPins(returnTypeNodes[i].OutputTypePins[0], stringLengthMethod.MainReturnNode.InputTypePins[i]);
}
TypeSpecifier stringType = TypeSpecifier.FromType();
@@ -45,11 +45,11 @@ public void CreateStringLengthMethod()
VariableGetterNode getLengthNode = new VariableGetterNode(stringLengthMethod, new VariableSpecifier("Length", intType, MemberVisibility.Public, MemberVisibility.Public, stringType, VariableModifiers.None));
// Connect node execs
- GraphUtil.ConnectExecPins(stringLengthMethod.EntryNode.InitialExecutionPin, stringLengthMethod.ReturnNodes.First().ReturnPin);
+ GraphUtil.ConnectPins(stringLengthMethod.EntryNode.InitialExecutionPin, stringLengthMethod.ReturnNodes.First().ReturnPin);
// Connect node data
- GraphUtil.ConnectDataPins(getStringNode.ValuePin, getLengthNode.TargetPin);
- GraphUtil.ConnectDataPins(getLengthNode.ValuePin, stringLengthMethod.ReturnNodes.First().InputDataPins[0]);
+ GraphUtil.ConnectPins(getStringNode.ValuePin, getLengthNode.TargetPin);
+ GraphUtil.ConnectPins(getLengthNode.ValuePin, stringLengthMethod.ReturnNodes.First().InputDataPins[0]);
}
public void CreateMainMethod()
@@ -74,14 +74,14 @@ public void CreateMainMethod()
CallMethodNode writeConsoleNode = new CallMethodNode(mainMethod, writeConsoleSpecifier);
// Connect node execs
- GraphUtil.ConnectExecPins(mainMethod.EntryNode.InitialExecutionPin, setStringNode.InputExecPins[0]);
- GraphUtil.ConnectExecPins(setStringNode.OutputExecPins[0], getStringLengthNode.InputExecPins[0]);
- GraphUtil.ConnectExecPins(getStringLengthNode.OutputExecPins[0], writeConsoleNode.InputExecPins[0]);
- GraphUtil.ConnectExecPins(writeConsoleNode.OutputExecPins[0], mainMethod.ReturnNodes.First().InputExecPins[0]);
+ GraphUtil.ConnectPins(mainMethod.EntryNode.InitialExecutionPin, setStringNode.InputExecPins[0]);
+ GraphUtil.ConnectPins(setStringNode.OutputExecPins[0], getStringLengthNode.InputExecPins[0]);
+ GraphUtil.ConnectPins(getStringLengthNode.OutputExecPins[0], writeConsoleNode.InputExecPins[0]);
+ GraphUtil.ConnectPins(writeConsoleNode.OutputExecPins[0], mainMethod.ReturnNodes.First().InputExecPins[0]);
// Connect node data
- GraphUtil.ConnectDataPins(stringLiteralNode.ValuePin, setStringNode.NewValuePin);
- GraphUtil.ConnectDataPins(getStringLengthNode.OutputDataPins[0], writeConsoleNode.ArgumentPins[0]);
+ GraphUtil.ConnectPins(stringLiteralNode.ValuePin, setStringNode.NewValuePin);
+ GraphUtil.ConnectPins(getStringLengthNode.OutputDataPins[0], writeConsoleNode.ArgumentPins[0]);
}
[TestInitialize]
diff --git a/NetPrintsUnitTests/DelegateTranslatorTests.cs b/NetPrintsUnitTests/DelegateTranslatorTests.cs
index 23c2ea7..496900b 100644
--- a/NetPrintsUnitTests/DelegateTranslatorTests.cs
+++ b/NetPrintsUnitTests/DelegateTranslatorTests.cs
@@ -36,7 +36,7 @@ public void TestDelegate()
for (int i = 0; i < returnTypeNodes.Count; i++)
{
delegateMethod.MainReturnNode.AddReturnType();
- GraphUtil.ConnectTypePins(returnTypeNodes[i].OutputTypePins[0], delegateMethod.MainReturnNode.InputTypePins[i]);
+ GraphUtil.ConnectPins(returnTypeNodes[i].OutputTypePins[0], delegateMethod.MainReturnNode.InputTypePins[i]);
}
MethodSpecifier delegateMethodSpecifier = new MethodSpecifier("TestMethod",
@@ -53,10 +53,10 @@ public void TestDelegate()
MakeDelegateNode makeDelegateNode = new MakeDelegateNode(delegateMethod, delegateMethodSpecifier);
// Connect node execs
- GraphUtil.ConnectExecPins(delegateMethod.EntryNode.InitialExecutionPin, delegateMethod.ReturnNodes.First().ReturnPin);
+ GraphUtil.ConnectPins(delegateMethod.EntryNode.InitialExecutionPin, delegateMethod.ReturnNodes.First().ReturnPin);
// Connect node data
- GraphUtil.ConnectDataPins(makeDelegateNode.OutputDataPins[0], delegateMethod.ReturnNodes.First().InputDataPins[0]);
+ GraphUtil.ConnectPins(makeDelegateNode.OutputDataPins[0], delegateMethod.ReturnNodes.First().InputDataPins[0]);
string translated = methodTranslator.Translate(delegateMethod, true);
}
diff --git a/NetPrintsUnitTests/GenericsTests.cs b/NetPrintsUnitTests/GenericsTests.cs
index 4e0622a..7d4e2ab 100644
--- a/NetPrintsUnitTests/GenericsTests.cs
+++ b/NetPrintsUnitTests/GenericsTests.cs
@@ -34,13 +34,13 @@ public void TestGenerics()
TypeNode listTypeNode = new TypeNode(openMethod, listType);
openMethod.MainReturnNode.AddReturnType();
- GraphUtil.ConnectTypePins(listTypeNode.OutputTypePins[0], openMethod.MainReturnNode.InputTypePins[0]);
+ GraphUtil.ConnectPins(listTypeNode.OutputTypePins[0], openMethod.MainReturnNode.InputTypePins[0]);
DefaultNode defaultNode = new DefaultNode(openMethod);
- GraphUtil.ConnectTypePins(listTypeNode.OutputTypePins[0], defaultNode.TypePin);
- GraphUtil.ConnectDataPins(defaultNode.DefaultValuePin, openMethod.MainReturnNode.InputDataPins[0]);
+ GraphUtil.ConnectPins(listTypeNode.OutputTypePins[0], defaultNode.TypePin);
+ GraphUtil.ConnectPins(defaultNode.DefaultValuePin, openMethod.MainReturnNode.InputDataPins[0]);
- GraphUtil.ConnectExecPins(openMethod.EntryNode.InitialExecutionPin, openMethod.ReturnNodes.First().ReturnPin);
+ GraphUtil.ConnectPins(openMethod.EntryNode.InitialExecutionPin, openMethod.ReturnNodes.First().ReturnPin);
openClass.Methods.Add(openMethod);
@@ -57,13 +57,13 @@ public void TestGenerics()
// Add closed list parameter
TypeNode closedListTypeNode = new TypeNode(closedMethod, closedListType);
closedMethod.MainReturnNode.AddReturnType();
- GraphUtil.ConnectTypePins(closedListTypeNode.OutputTypePins[0], closedMethod.MainReturnNode.InputTypePins[0]);
+ GraphUtil.ConnectPins(closedListTypeNode.OutputTypePins[0], closedMethod.MainReturnNode.InputTypePins[0]);
DefaultNode closedDefaultNode = new DefaultNode(closedMethod);
- GraphUtil.ConnectTypePins(closedListTypeNode.OutputTypePins[0], closedDefaultNode.TypePin);
- GraphUtil.ConnectDataPins(closedDefaultNode.DefaultValuePin, closedMethod.MainReturnNode.InputDataPins[0]);
+ GraphUtil.ConnectPins(closedListTypeNode.OutputTypePins[0], closedDefaultNode.TypePin);
+ GraphUtil.ConnectPins(closedDefaultNode.DefaultValuePin, closedMethod.MainReturnNode.InputDataPins[0]);
- GraphUtil.ConnectExecPins(closedMethod.EntryNode.InitialExecutionPin, closedMethod.ReturnNodes.First().ReturnPin);
+ GraphUtil.ConnectPins(closedMethod.EntryNode.InitialExecutionPin, closedMethod.ReturnNodes.First().ReturnPin);
closedClass.Methods.Add(closedMethod);
@@ -89,7 +89,7 @@ public void TestTypeGraph()
var typeNode = new TypeNode(method, TypeSpecifier.FromType());
Assert.AreEqual(literalNode.InputTypePins.Count, 1);
- GraphUtil.ConnectTypePins(typeNode.OutputTypePins[0], literalNode.InputTypePins[0]);
+ GraphUtil.ConnectPins(typeNode.OutputTypePins[0], literalNode.InputTypePins[0]);
Assert.AreEqual(literalNode.InputTypePins[0].InferredType.Value, new TypeSpecifier("System.Int32"));
Assert.AreEqual(literalNode.OutputDataPins[0].PinType.Value, new TypeSpecifier("System.Collections.Generic.List", genericArguments: new BaseType[] { new TypeSpecifier("System.Int32") }));
}
diff --git a/NetPrintsUnitTests/MethodTranslatorTests.cs b/NetPrintsUnitTests/MethodTranslatorTests.cs
index 8d3a14e..96086be 100644
--- a/NetPrintsUnitTests/MethodTranslatorTests.cs
+++ b/NetPrintsUnitTests/MethodTranslatorTests.cs
@@ -47,7 +47,7 @@ public void CreateStringLengthMethod()
for (int i = 0; i < argTypeNodes.Count; i++)
{
((MethodEntryNode)stringLengthMethod.EntryNode).AddArgument();
- GraphUtil.ConnectTypePins(argTypeNodes[i].OutputTypePins[0], stringLengthMethod.EntryNode.InputTypePins[i]);
+ GraphUtil.ConnectPins(argTypeNodes[i].OutputTypePins[0], stringLengthMethod.EntryNode.InputTypePins[i]);
}
// Add return types
@@ -59,7 +59,7 @@ public void CreateStringLengthMethod()
for (int i = 0; i < returnTypeNodes.Count; i++)
{
stringLengthMethod.MainReturnNode.AddReturnType();
- GraphUtil.ConnectTypePins(returnTypeNodes[i].OutputTypePins[0], stringLengthMethod.MainReturnNode.InputTypePins[i]);
+ GraphUtil.ConnectPins(returnTypeNodes[i].OutputTypePins[0], stringLengthMethod.MainReturnNode.InputTypePins[i]);
}
// Create nodes
@@ -67,11 +67,11 @@ public void CreateStringLengthMethod()
MemberVisibility.Public,MemberVisibility.Public, TypeSpecifier.FromType(), VariableModifiers.None));
// Connect node execs
- GraphUtil.ConnectExecPins(stringLengthMethod.EntryNode.InitialExecutionPin, stringLengthMethod.ReturnNodes.First().ReturnPin);
+ GraphUtil.ConnectPins(stringLengthMethod.EntryNode.InitialExecutionPin, stringLengthMethod.ReturnNodes.First().ReturnPin);
// Connect node data
- GraphUtil.ConnectDataPins(stringLengthMethod.EntryNode.OutputDataPins[0], getLengthNode.InputDataPins[0]);
- GraphUtil.ConnectDataPins(getLengthNode.OutputDataPins[0], stringLengthMethod.ReturnNodes.First().InputDataPins[0]);
+ GraphUtil.ConnectPins(stringLengthMethod.EntryNode.OutputDataPins[0], getLengthNode.InputDataPins[0]);
+ GraphUtil.ConnectPins(getLengthNode.OutputDataPins[0], stringLengthMethod.ReturnNodes.First().InputDataPins[0]);
}
public void CreateIfElseMethod()
@@ -92,7 +92,7 @@ public void CreateIfElseMethod()
for (int i = 0; i < argTypeNodes.Count; i++)
{
((MethodEntryNode)ifElseMethod.EntryNode).AddArgument();
- GraphUtil.ConnectTypePins(argTypeNodes[i].OutputTypePins[0], ifElseMethod.EntryNode.InputTypePins[i]);
+ GraphUtil.ConnectPins(argTypeNodes[i].OutputTypePins[0], ifElseMethod.EntryNode.InputTypePins[i]);
}
// Add return types
@@ -104,7 +104,7 @@ public void CreateIfElseMethod()
for (int i = 0; i < returnTypeNodes.Count; i++)
{
ifElseMethod.MainReturnNode.AddReturnType();
- GraphUtil.ConnectTypePins(returnTypeNodes[i].OutputTypePins[0], ifElseMethod.MainReturnNode.InputTypePins[i]);
+ GraphUtil.ConnectPins(returnTypeNodes[i].OutputTypePins[0], ifElseMethod.MainReturnNode.InputTypePins[i]);
}
// Create nodes
@@ -112,14 +112,14 @@ public void CreateIfElseMethod()
LiteralNode literalNode = LiteralNode.WithValue(ifElseMethod, 123);
// Connect exec nodes
- GraphUtil.ConnectExecPins(ifElseMethod.EntryNode.InitialExecutionPin, ifElseNode.ExecutionPin);
- GraphUtil.ConnectExecPins(ifElseNode.TruePin, ifElseMethod.ReturnNodes.First().ReturnPin);
- GraphUtil.ConnectExecPins(ifElseNode.FalsePin, ifElseMethod.ReturnNodes.First().ReturnPin);
+ GraphUtil.ConnectPins(ifElseMethod.EntryNode.InitialExecutionPin, ifElseNode.ExecutionPin);
+ GraphUtil.ConnectPins(ifElseNode.TruePin, ifElseMethod.ReturnNodes.First().ReturnPin);
+ GraphUtil.ConnectPins(ifElseNode.FalsePin, ifElseMethod.ReturnNodes.First().ReturnPin);
// Connect node data
- GraphUtil.ConnectDataPins(ifElseMethod.EntryNode.OutputDataPins[1], ifElseNode.ConditionPin);
- GraphUtil.ConnectDataPins(ifElseMethod.EntryNode.OutputDataPins[0], ifElseMethod.ReturnNodes.First().InputDataPins[0]);
- GraphUtil.ConnectDataPins(literalNode.ValuePin, ifElseMethod.ReturnNodes.First().InputDataPins[0]);
+ GraphUtil.ConnectPins(ifElseMethod.EntryNode.OutputDataPins[1], ifElseNode.ConditionPin);
+ GraphUtil.ConnectPins(ifElseMethod.EntryNode.OutputDataPins[0], ifElseMethod.ReturnNodes.First().InputDataPins[0]);
+ GraphUtil.ConnectPins(literalNode.ValuePin, ifElseMethod.ReturnNodes.First().InputDataPins[0]);
}
public void CreateForLoopMethod()
@@ -135,11 +135,11 @@ public void CreateForLoopMethod()
ForLoopNode forLoopNode = new ForLoopNode(forLoopMethod);
// Connect exec nodes
- GraphUtil.ConnectExecPins(forLoopMethod.EntryNode.InitialExecutionPin, forLoopNode.ExecutionPin);
- GraphUtil.ConnectExecPins(forLoopNode.CompletedPin, forLoopMethod.ReturnNodes.First().ReturnPin);
+ GraphUtil.ConnectPins(forLoopMethod.EntryNode.InitialExecutionPin, forLoopNode.ExecutionPin);
+ GraphUtil.ConnectPins(forLoopNode.CompletedPin, forLoopMethod.ReturnNodes.First().ReturnPin);
// Connect node data
- GraphUtil.ConnectDataPins(maxIndexLiteralNode.ValuePin, forLoopNode.MaxIndexPin);
+ GraphUtil.ConnectPins(maxIndexLiteralNode.ValuePin, forLoopNode.MaxIndexPin);
}
[TestMethod]