public void TestConnections()
        {
            NodeOutputViewModel nodeAOutput = new NodeOutputViewModel();
            NodeViewModel       nodeA       = new NodeViewModel();

            nodeA.Outputs.Add(nodeAOutput);

            NodeInputViewModel  nodeBInput  = new NodeInputViewModel();
            NodeOutputViewModel nodeBOutput = new NodeOutputViewModel();
            NodeViewModel       nodeB       = new NodeViewModel
            {
                CanBeRemovedByUser = false,
                IsSelected         = true
            };

            nodeB.Inputs.Add(nodeBInput);
            nodeB.Outputs.Add(nodeBOutput);

            NodeInputViewModel nodeCInput = new NodeInputViewModel
            {
                MaxConnections = 2
            };
            NodeViewModel nodeC = new NodeViewModel
            {
                IsSelected = true
            };

            nodeC.Inputs.Add(nodeCInput);

            NodeViewModel nodeD = new NodeViewModel
            {
                IsSelected = true
            };

            NetworkViewModel network = new NetworkViewModel
            {
                Nodes = { nodeA, nodeB, nodeC, nodeD }
            };

            Assert.IsTrue(nodeBInput.Connections.Count == 0);

            var conAB = network.ConnectionFactory(nodeBInput, nodeAOutput);
            var conBC = network.ConnectionFactory(nodeCInput, nodeBOutput);

            network.Connections.Add(conAB);
            network.Connections.Add(conBC);

            Assert.IsTrue(Enumerable.SequenceEqual(nodeBInput.Connections.Items, new[] { conAB }));

            network.Connections.Remove(conAB);

            Assert.IsTrue(nodeBInput.Connections.Count == 0);

            var conAC = network.ConnectionFactory(nodeCInput, nodeAOutput);

            network.Connections.Add(conAC);

            Assert.IsTrue(Enumerable.SequenceEqual(nodeCInput.Connections.Items, new[] { conBC, conAC }));
        }
        public void TestConnections()
        {
            NodeOutputViewModel nodeAOutput = new NodeOutputViewModel();
            NodeViewModel       nodeA       = new NodeViewModel
            {
                Outputs = { nodeAOutput }
            };

            NodeInputViewModel nodeBInput = new NodeInputViewModel();
            NodeViewModel      nodeB      = new NodeViewModel
            {
                Inputs = { nodeBInput }
            };

            NodeInputViewModel nodeCInput = new NodeInputViewModel();
            NodeViewModel      nodeC      = new NodeViewModel
            {
                Inputs = { nodeCInput }
            };

            NetworkViewModel network = new NetworkViewModel
            {
                Nodes = { nodeA, nodeB, nodeC }
            };

            Assert.AreEqual(0, nodeAOutput.Connections.Count);

            var conAB = network.ConnectionFactory(nodeBInput, nodeAOutput);

            network.Connections.Add(conAB);

            Assert.IsTrue(nodeAOutput.Connections.SequenceEqual(new[]
            {
                conAB
            }));

            var conAC = network.ConnectionFactory(nodeCInput, nodeAOutput);

            network.Connections.Add(conAC);

            Assert.IsTrue(nodeAOutput.Connections.SequenceEqual(new []
            {
                conAB, conAC
            }));

            network.Connections.Remove(conAB);

            Assert.IsTrue(nodeAOutput.Connections.SequenceEqual(new[]
            {
                conAC
            }));

            network.Connections.Remove(conAC);

            Assert.AreEqual(0, nodeAOutput.Connections.Count);
        }
示例#3
0
        public void TestCutLine()
        {
            NodeOutputViewModel nodeAOutput = new NodeOutputViewModel();
            NodeViewModel       nodeA       = new NodeViewModel();

            nodeA.Outputs.Add(nodeAOutput);

            NodeInputViewModel  nodeBInput  = new NodeInputViewModel();
            NodeOutputViewModel nodeBOutput = new NodeOutputViewModel();
            NodeViewModel       nodeB       = new NodeViewModel
            {
                CanBeRemovedByUser = false,
                IsSelected         = true
            };

            nodeB.Inputs.Add(nodeBInput);
            nodeB.Outputs.Add(nodeBOutput);

            NodeInputViewModel nodeCInput = new NodeInputViewModel();
            NodeViewModel      nodeC      = new NodeViewModel
            {
                IsSelected = true
            };

            nodeC.Inputs.Add(nodeCInput);

            NodeViewModel nodeD = new NodeViewModel
            {
                IsSelected = true
            };

            NetworkViewModel network = new NetworkViewModel
            {
                Nodes = { nodeA, nodeB, nodeC, nodeD }
            };

            var conAB = network.ConnectionFactory(nodeBInput, nodeAOutput);
            var conBC = network.ConnectionFactory(nodeCInput, nodeBOutput);

            network.Connections.Add(conAB);
            network.Connections.Add(conBC);

            network.StartCut();
            network.CutLine.IntersectingConnections.Add(conAB);
            network.FinishCut();

            Assert.IsTrue(network.Connections.Items.SequenceEqual(new [] { conBC }));
            Assert.IsFalse(network.CutLine.IsVisible);
        }
        public void TestValidateAfterConnectionsAllUpdated()
        {
            NodeInputViewModel  input1  = new NodeInputViewModel();
            NodeOutputViewModel output1 = new NodeOutputViewModel();
            NodeViewModel       node1   = new NodeViewModel
            {
                Inputs  = { input1 },
                Outputs = { output1 }
            };

            NodeInputViewModel  input2  = new NodeInputViewModel();
            NodeOutputViewModel output2 = new NodeOutputViewModel();
            NodeViewModel       node2   = new NodeViewModel
            {
                Inputs  = { input2 },
                Outputs = { output2 }
            };

            NetworkViewModel network = new NetworkViewModel();

            network.Validator = n =>
            {
                if (GraphAlgorithms.FindLoops(network).Any())
                {
                    return(new NetworkValidationResult(false, false, null));
                }
                return(new NetworkValidationResult(true, true, null));
            };

            network.Nodes.Add(node1);
            network.Nodes.Add(node2);

            var conn1 = network.ConnectionFactory(input1, output2);

            network.Connections.Add(conn1);

            Assert.IsTrue(network.LatestValidation.IsValid);

            var conn2 = network.ConnectionFactory(input2, output1);

            network.Connections.Add(conn2);

            Assert.IsFalse(network.LatestValidation.IsValid);

            network.Connections.Remove(conn1);

            Assert.IsTrue(network.LatestValidation.IsValid);
        }
        public void TestHideEditorIfConnected()
        {
            TestableOutput output = new TestableOutput();
            TestableInput  input  = new TestableInput();

            var outputNode = new NodeViewModel();

            outputNode.Outputs.Add(output);

            var inputNode = new NodeViewModel();

            inputNode.Inputs.Add(input);

            NetworkViewModel network = new NetworkViewModel
            {
                Nodes = { outputNode, inputNode }
            };

            input.HideEditorIfConnected = true;
            Assert.IsTrue(input.IsEditorVisible);

            network.Connections.Add(network.ConnectionFactory(input, output));

            Assert.IsFalse(input.IsEditorVisible);
        }
        public void TestHideEditorIfConnected()
        {
            TestableOutput   output  = new TestableOutput();
            TestableInput    input   = new TestableInput();
            NetworkViewModel network = new NetworkViewModel
            {
                Nodes =
                {
                    new NodeViewModel
                    {
                        Outputs ={ output               }
                    },
                    new NodeViewModel
                    {
                        Inputs ={ input                }
                    }
                }
            };

            input.HideEditorIfConnected = true;
            Assert.IsTrue(input.IsEditorVisible);

            network.Connections.Add(network.ConnectionFactory(input, output));

            Assert.IsFalse(input.IsEditorVisible);
        }
        public void TestListInputDisconnect()
        {
            using (TestUtils.WithScheduler(ImmediateScheduler.Instance))
            {
                var           input1 = new ValueListNodeInputViewModel <string>();
                NodeViewModel node1  = new NodeViewModel
                {
                    Inputs = { input1 }
                };

                var output2 = new ValueNodeOutputViewModel <string>
                {
                    Value = Observable.Return("Test")
                };
                NodeViewModel node2 = new NodeViewModel
                {
                    Outputs = { output2 }
                };

                NetworkViewModel network = new NetworkViewModel();

                network.Nodes.Add(node1);
                network.Nodes.Add(node2);

                var conn1 = network.ConnectionFactory(input1, output2);
                network.Connections.Add(conn1);

                CollectionAssert.AreEqual(new[] { "Test" }, input1.Values.ToArray());

                network.Connections.Remove(conn1);

                CollectionAssert.AreEqual(new string[0], input1.Values.ToArray());
            }
        }
        public void TestAddConnectionShouldUpdateInputAndOutputConnLists()
        {
            NodeOutputViewModel output = new NodeOutputViewModel();
            NodeViewModel       node1  = new NodeViewModel();

            node1.Outputs.Add(output);

            NodeInputViewModel input = new NodeInputViewModel();
            NodeViewModel      node2 = new NodeViewModel();

            node2.Inputs.Add(input);

            NetworkViewModel network = new NetworkViewModel();

            network.Nodes.Add(node1);
            network.Nodes.Add(node2);

            var conn = network.ConnectionFactory(input, output);

            network.Connections.Add(conn);

            CollectionAssert.AreEqual(new [] { conn }, input.Connections.Items.AsArray());
            CollectionAssert.AreEqual(new[] { conn }, output.Connections.Items.AsArray());

            network.Connections.Clear();

            CollectionAssert.AreEqual(new ConnectionViewModel[0], input.Connections.Items.AsArray());
            CollectionAssert.AreEqual(new ConnectionViewModel[0], output.Connections.Items.AsArray());
        }
示例#9
0
        private void GenerateConnections(object sender, RoutedEventArgs e)
        {
            var connections = _network.Nodes.Zip(_network.Nodes.Skip(1),
                                                 (node1, node2) => _network.ConnectionFactory(node2.Inputs[0], node1.Outputs[0]));

            _network.Connections.AddRange(connections);
        }
        public void TestListInputDisconnect()
        {
            var           input1 = new ValueListNodeInputViewModel <string>();
            NodeViewModel node1  = new NodeViewModel();

            node1.Inputs.Add(input1);

            var output2 = new ValueNodeOutputViewModel <string>
            {
                Value = Observable.Return("Test")
            };
            NodeViewModel node2 = new NodeViewModel();

            node2.Outputs.Add(output2);

            NetworkViewModel network = new NetworkViewModel();

            network.Nodes.Add(node1);
            network.Nodes.Add(node2);

            var conn1 = network.ConnectionFactory(input1, output2);

            network.Connections.Add(conn1);

            CollectionAssert.AreEqual(new[] { "Test" }, input1.Values.Items.AsArray());

            network.Connections.Remove(conn1);

            CollectionAssert.AreEqual(new string[0], input1.Values.Items.AsArray());
        }
        public void TestDeleteOutputShouldRemoveConnections()
        {
            NodeOutputViewModel output = new NodeOutputViewModel();
            NodeViewModel       node1  = new NodeViewModel();

            node1.Outputs.Add(output);

            NodeInputViewModel input = new NodeInputViewModel();
            NodeViewModel      node2 = new NodeViewModel();

            node2.Inputs.Add(input);

            NetworkViewModel network = new NetworkViewModel();

            network.Nodes.Add(node1);
            network.Nodes.Add(node2);

            var conn = network.ConnectionFactory(input, output);

            network.Connections.Add(conn);

            Assert.IsTrue(network.Connections.Items.Contains(conn));
            node1.Outputs.Remove(output);
            Assert.IsFalse(network.Connections.Items.Contains(conn));

            node1.Outputs.Add(output);
            network.Connections.Add(conn);

            Assert.IsTrue(network.Connections.Items.Contains(conn));
            node1.Outputs.Clear();
            Assert.IsFalse(network.Connections.Items.Contains(conn));
        }
示例#12
0
        public void TestDeleteSelectedNodes()
        {
            NodeOutputViewModel nodeAOutput = new NodeOutputViewModel();
            NodeViewModel       nodeA       = new NodeViewModel();

            nodeA.Outputs.Add(nodeAOutput);

            NodeInputViewModel  nodeBInput  = new NodeInputViewModel();
            NodeOutputViewModel nodeBOutput = new NodeOutputViewModel();
            NodeViewModel       nodeB       = new NodeViewModel
            {
                CanBeRemovedByUser = false,
                IsSelected         = true,
            };

            nodeB.Inputs.Add(nodeBInput);
            nodeB.Outputs.Add(nodeBOutput);

            NodeInputViewModel nodeCInput = new NodeInputViewModel();
            NodeViewModel      nodeC      = new NodeViewModel
            {
                IsSelected = true
            };

            nodeC.Inputs.Add(nodeCInput);

            NodeViewModel nodeD = new NodeViewModel
            {
                IsSelected = true
            };

            NetworkViewModel network = new NetworkViewModel
            {
                Nodes = { nodeA, nodeB, nodeC, nodeD }
            };

            network.Connections.Add(network.ConnectionFactory(nodeBInput, nodeAOutput));
            network.Connections.Add(network.ConnectionFactory(nodeCInput, nodeBOutput));

            Observable.Return(Unit.Default).InvokeCommand(network.DeleteSelectedNodes);

            Assert.AreEqual(1, network.Connections.Count);
            Assert.IsTrue(network.Nodes.SequenceEqual(new [] { nodeA, nodeB }));
        }
        public void TestDeleteNodeShouldRemoveConnections()
        {
            NodeInputViewModel  input1  = new NodeInputViewModel();
            NodeOutputViewModel output1 = new NodeOutputViewModel();
            NodeViewModel       node1   = new NodeViewModel
            {
                Inputs  = { input1 },
                Outputs = { output1 }
            };

            NodeInputViewModel  input2  = new NodeInputViewModel();
            NodeOutputViewModel output2 = new NodeOutputViewModel();
            NodeViewModel       node2   = new NodeViewModel
            {
                Inputs  = { input2 },
                Outputs = { output2 }
            };

            NetworkViewModel network = new NetworkViewModel();

            network.Nodes.Add(node1);
            network.Nodes.Add(node2);

            var conn1 = network.ConnectionFactory(input1, output2);
            var conn2 = network.ConnectionFactory(input2, output1);

            network.Connections.Add(conn1);
            network.Connections.Add(conn2);

            Assert.IsTrue(network.Connections.Contains(conn1));
            Assert.IsTrue(network.Connections.Contains(conn2));
            network.Nodes.Remove(node1);
            Assert.IsFalse(network.Connections.Contains(conn1));
            Assert.IsFalse(network.Connections.Contains(conn2));

            network.Nodes.AddRange(new [] { node1, node2 });
            network.Connections.AddRange(new[] { conn1, conn2 });

            Assert.IsTrue(network.Connections.Contains(conn1));
            Assert.IsTrue(network.Connections.Contains(conn2));
            network.Nodes.Clear();
            Assert.IsFalse(network.Connections.Contains(conn1));
            Assert.IsFalse(network.Connections.Contains(conn2));
        }
        public void TestNodeCollapse()
        {
            NodeOutputViewModel nodeAOutput = new NodeOutputViewModel();
            NodeViewModel       nodeA       = new NodeViewModel
            {
                Outputs = { nodeAOutput }
            };

            NodeInputViewModel  nodeBInput   = new NodeInputViewModel();
            NodeInputViewModel  nodeBInput2  = new NodeInputViewModel();
            NodeOutputViewModel nodeBOutput  = new NodeOutputViewModel();
            NodeOutputViewModel nodeBOutput2 = new NodeOutputViewModel();
            NodeViewModel       nodeB        = new NodeViewModel
            {
                Inputs  = { nodeBInput, nodeBInput2 },
                Outputs = { nodeBOutput, nodeBOutput2 }
            };

            NodeInputViewModel nodeCInput = new NodeInputViewModel();
            NodeViewModel      nodeC      = new NodeViewModel
            {
                Inputs = { nodeCInput }
            };

            NetworkViewModel network = new NetworkViewModel
            {
                Nodes = { nodeA, nodeB, nodeC }
            };

            network.Connections.Add(network.ConnectionFactory(nodeBInput, nodeAOutput));
            network.Connections.Add(network.ConnectionFactory(nodeCInput, nodeBOutput));

            nodeB.IsCollapsed = true;

            Assert.IsTrue(nodeB.VisibleInputs.SequenceEqual(new [] { nodeBInput }));
            Assert.IsTrue(nodeB.VisibleOutputs.SequenceEqual(new[] { nodeBOutput }));
        }
示例#15
0
        public void TestValuePropagation()
        {
            //Setup
            var scheduler = new TestScheduler();

            var           nodeA   = new NodeViewModel();
            Subject <int> sourceA = new Subject <int>();
            var           outputA = new ValueNodeOutputViewModel <int>
            {
                Value = sourceA
            };

            nodeA.Outputs.Add(outputA);

            var nodeB  = new NodeViewModel();
            var inputB = new ValueListNodeInputViewModel <int>();

            nodeB.Inputs.Add(inputB);

            NetworkViewModel network = new NetworkViewModel();

            network.Nodes.AddRange(new [] { nodeA, nodeB });

            network.Connections.Add(network.ConnectionFactory(inputB, outputA));

            //Define actions
            scheduler.Schedule(TimeSpan.FromTicks(10), () => sourceA.OnNext(1));
            scheduler.Schedule(TimeSpan.FromTicks(20), () => sourceA.OnNext(0));
            scheduler.Schedule(TimeSpan.FromTicks(30), () => sourceA.OnNext(1));
            scheduler.Schedule(TimeSpan.FromTicks(40), () => sourceA.OnNext(0));
            scheduler.Schedule(TimeSpan.FromTicks(50), () => sourceA.OnNext(2));
            var actual = scheduler.Start(() => inputB.Values.Connect().QueryWhenChanged(), created: 0, subscribed: 0, disposed: 100);

            //Assert
            Assert.AreEqual(actual.Messages.Count, 6);
            Assert.AreEqual(actual.Messages[0].Time, 1);
            Assert.IsTrue(actual.Messages[0].Value.Value.SequenceEqual(new[] { 0 }));
            Assert.AreEqual(actual.Messages[1].Time, 10);
            Assert.IsTrue(actual.Messages[1].Value.Value.SequenceEqual(new[] { 1 }));
            Assert.AreEqual(actual.Messages[2].Time, 20);
            Assert.IsTrue(actual.Messages[2].Value.Value.SequenceEqual(new[] { 0 }));
            Assert.AreEqual(actual.Messages[3].Time, 30);
            Assert.IsTrue(actual.Messages[3].Value.Value.SequenceEqual(new[] { 1 }));
            Assert.AreEqual(actual.Messages[4].Time, 40);
            Assert.IsTrue(actual.Messages[4].Value.Value.SequenceEqual(new[] { 0 }));
            Assert.AreEqual(actual.Messages[5].Time, 50);
            Assert.IsTrue(actual.Messages[5].Value.Value.SequenceEqual(new[] { 2 }));
        }
        public void TestNestedObserving()
        {
            //Setup
            var scheduler = new TestScheduler();

            NodeInputViewModel  input1  = new NodeInputViewModel();
            NodeOutputViewModel output1 = new NodeOutputViewModel();
            NodeViewModel       node1   = new NodeViewModel
            {
                Inputs  = { input1 },
                Outputs = { output1 }
            };

            NodeInputViewModel  input2  = new NodeInputViewModel();
            NodeOutputViewModel output2 = new NodeOutputViewModel();
            NodeViewModel       node2   = new NodeViewModel
            {
                Inputs  = { input2 },
                Outputs = { output2 }
            };

            NetworkViewModel network = new NetworkViewModel();

            network.Nodes.Add(node1);
            network.Nodes.Add(node2);

            var conn1 = network.ConnectionFactory(input1, output2);

            network.Connections.Add(conn1);

            var obs = network.ConnectionsUpdated;


            //Define actions
            scheduler.Schedule(TimeSpan.FromTicks(10), () => network.Connections.Remove(conn1));
            var actual = scheduler.Start(() => obs, created: 0, subscribed: 0, disposed: 100); // But subscribe to it here

            //Assert
            var expected = new[]
            {
                ReactiveTest.OnNext(10, Unit.Default)
            };

            ReactiveAssert.AreElementsEqual(expected, actual.Messages);
        }
        public void TestConnectionsUpdatedAfterPreexistingConnectionRemoved()
        {
            //Setup
            var scheduler = new TestScheduler();

            NodeInputViewModel  input1  = new NodeInputViewModel();
            NodeOutputViewModel output1 = new NodeOutputViewModel();
            NodeViewModel       node1   = new NodeViewModel();

            node1.Inputs.Add(input1);
            node1.Outputs.Add(output1);

            NodeInputViewModel  input2  = new NodeInputViewModel();
            NodeOutputViewModel output2 = new NodeOutputViewModel();
            NodeViewModel       node2   = new NodeViewModel();

            node2.Inputs.Add(input2);
            node2.Outputs.Add(output2);

            NetworkViewModel network = new NetworkViewModel();

            var observable = network.ConnectionsUpdated; // Create observable before nodes/connections are added

            network.Nodes.Add(node1);
            network.Nodes.Add(node2);

            var conn1 = network.ConnectionFactory(input1, output2);

            network.Connections.Add(conn1);


            //Define actions
            scheduler.Schedule(TimeSpan.FromTicks(10), () => network.Connections.Remove(conn1));
            var actual = scheduler.Start(() => observable, created: 0, subscribed: 0, disposed: 100); // But subscribe to it here

            //Assert
            var expected = new[]
            {
                ReactiveTest.OnNext(10, Unit.Default)
            };

            ReactiveAssert.AreElementsEqual(expected, actual.Messages);
        }
        public void TestCollapseWithGroups()
        {
            NodeViewModel node = new NodeViewModel();

            EndpointGroup groupA = new EndpointGroup {
                Name = "Group A"
            };
            EndpointGroup groupB = new EndpointGroup {
                Name = "Group B"
            };
            EndpointGroup groupC = new EndpointGroup(groupA)
            {
                Name = "Group C"
            };
            EndpointGroup groupD = new EndpointGroup(groupB)
            {
                Name = "Group D"
            };

            NodeInputViewModel inputC = new NodeInputViewModel {
                Group = groupC, Name = "Input C"
            };
            NodeOutputViewModel outputC = new NodeOutputViewModel {
                Group = groupC, Name = "Output C"
            };

            NodeInputViewModel inputD = new NodeInputViewModel {
                Group = groupD, Name = "Input D"
            };
            NodeOutputViewModel outputD = new NodeOutputViewModel {
                Group = groupD, Name = "Output D"
            };

            node.Inputs.Add(inputC);
            node.Inputs.Add(inputD);
            node.Outputs.Add(outputC);
            node.Outputs.Add(outputD);

            var network = new NetworkViewModel();

            network.Nodes.Add(node);
            network.Connections.Add(network.ConnectionFactory(inputC, new NodeOutputViewModel()));

            node.IsCollapsed = true;

            Assert.IsTrue(node.VisibleInputs.Count == 0);
            Assert.IsTrue(node.VisibleOutputs.Count == 0);
            Assert.IsTrue(node.VisibleEndpointGroups.Count == 1);

            EndpointGroupViewModel groupAViewModel = node.VisibleEndpointGroups[0];

            Assert.AreEqual(groupA, groupAViewModel.Group);
            Assert.IsTrue(groupAViewModel.VisibleInputs.Count == 0);
            Assert.IsTrue(groupAViewModel.VisibleOutputs.Count == 0);
            Assert.IsTrue(groupAViewModel.Children.Count == 1);
            EndpointGroupViewModel groupCViewModel = groupAViewModel.Children[0];

            Assert.AreEqual(groupC, groupCViewModel.Group);
            Assert.IsTrue(groupCViewModel.VisibleInputs.Count == 1);
            Assert.AreEqual(inputC, groupCViewModel.VisibleInputs.Items.First());
            Assert.IsTrue(groupCViewModel.VisibleOutputs.Count == 0);
        }
示例#19
0
        public void TestNodeCollapse(EndpointVisibility visibility, bool nonCollapsedNonConnectedVisible, bool nonCollapsedConnectedVisible, bool collapsedNonConnectedVisible, bool collapsedConnectedVisible)
        {
            NodeOutputViewModel nodeAOutput = new NodeOutputViewModel();
            NodeViewModel       nodeA       = new NodeViewModel
            {
                Outputs = { nodeAOutput }
            };

            NodeInputViewModel nodeBInput = new NodeInputViewModel {
                Visibility = visibility
            };
            NodeInputViewModel nodeBInput2 = new NodeInputViewModel {
                Visibility = visibility
            };
            NodeOutputViewModel nodeBOutput = new NodeOutputViewModel {
                Visibility = visibility
            };
            NodeOutputViewModel nodeBOutput2 = new NodeOutputViewModel {
                Visibility = visibility
            };
            NodeViewModel nodeB = new NodeViewModel
            {
                Inputs  = { nodeBInput, nodeBInput2 },
                Outputs = { nodeBOutput, nodeBOutput2 }
            };

            NodeInputViewModel nodeCInput = new NodeInputViewModel();
            NodeViewModel      nodeC      = new NodeViewModel
            {
                Inputs = { nodeCInput }
            };

            NetworkViewModel network = new NetworkViewModel
            {
                Nodes = { nodeA, nodeB, nodeC }
            };

            network.Connections.Add(network.ConnectionFactory(nodeBInput, nodeAOutput));
            network.Connections.Add(network.ConnectionFactory(nodeCInput, nodeBOutput));

            var expectedInputSeq  = Enumerable.Empty <Endpoint>();
            var expectedOutputSeq = Enumerable.Empty <Endpoint>();

            if (nonCollapsedConnectedVisible)
            {
                expectedInputSeq  = expectedInputSeq.Concat(new[] { nodeBInput });
                expectedOutputSeq = expectedOutputSeq.Concat(new[] { nodeBOutput });
            }
            if (nonCollapsedNonConnectedVisible)
            {
                expectedInputSeq  = expectedInputSeq.Concat(new[] { nodeBInput2 });
                expectedOutputSeq = expectedOutputSeq.Concat(new[] { nodeBOutput2 });
            }

            Assert.IsTrue(nodeB.VisibleInputs.SequenceEqual(expectedInputSeq));
            Assert.IsTrue(nodeB.VisibleOutputs.SequenceEqual(expectedOutputSeq));

            nodeB.IsCollapsed = true;

            expectedInputSeq  = Enumerable.Empty <Endpoint>();
            expectedOutputSeq = Enumerable.Empty <Endpoint>();

            if (collapsedConnectedVisible)
            {
                expectedInputSeq  = expectedInputSeq.Concat(new[] { nodeBInput });
                expectedOutputSeq = expectedOutputSeq.Concat(new[] { nodeBOutput });
            }
            if (collapsedNonConnectedVisible)
            {
                expectedInputSeq  = expectedInputSeq.Concat(new[] { nodeBInput2 });
                expectedOutputSeq = expectedOutputSeq.Concat(new[] { nodeBOutput2 });
            }

            Assert.IsTrue(nodeB.VisibleInputs.SequenceEqual(expectedInputSeq));
            Assert.IsTrue(nodeB.VisibleOutputs.SequenceEqual(expectedOutputSeq));
        }
示例#20
0
        /// <summary>
        /// Move the specified set of nodes to a new subnetwork, create a new group node that contains this subnet,
        /// restore inter- and intra-network connections.
        /// </summary>
        /// <param name="network">The parent network</param>
        /// <param name="nodesToGroup">The nodes to group</param>
        /// <returns>Returns the NodeGroupIOBinding that was constructed for this group using the IOBindingFactory.</returns>
        public NodeGroupIOBinding MergeIntoGroup(NetworkViewModel network, IEnumerable <NodeViewModel> nodesToGroup)
        {
            if (!CheckPropertiesValid())
            {
                throw new InvalidOperationException("All properties must be set before usage");
            }
            else if (network == null)
            {
                throw new ArgumentNullException(nameof(network));
            }
            else if (nodesToGroup == null)
            {
                throw new ArgumentNullException(nameof(nodesToGroup));
            }

            var groupNodesSet = nodesToGroup is HashSet <NodeViewModel> set
                ? set
                : new HashSet <NodeViewModel>(nodesToGroup);

            // Check if nodesToGroup can be combined into a single group
            if (groupNodesSet.Count == 0 || !GraphAlgorithms.IsContinuousSubGraphSet(groupNodesSet))
            {
                return(null);
            }

            // Create new empty group
            var subnet = SubNetworkFactory();

            var groupNode = GroupNodeFactory(subnet);

            network.Nodes.Add(groupNode);

            var groupEntranceNode = EntranceNodeFactory();
            var groupExitNode     = ExitNodeFactory();

            subnet.Nodes.AddRange(new [] { groupEntranceNode, groupExitNode });

            // Map from input on a group member node to group node input
            var groupNodeInputs = new Dictionary <NodeInputViewModel, NodeInputViewModel>();
            // Map from output on a group member node to group node output
            var groupNodeOutputs = new Dictionary <NodeOutputViewModel, NodeOutputViewModel>();

            // Move the new nodes to appropriate positions
            groupNode.Position = new Point(
                groupNodesSet.Average(n => n.Position.X),
                groupNodesSet.Average(n => n.Position.Y)
                );

            double yCoord = groupNodesSet.Average(n => n.Position.Y);

            groupEntranceNode.Position = new Point(
                groupNodesSet.Min(n => n.Position.X) - 100,
                yCoord
                );
            groupExitNode.Position = new Point(
                groupNodesSet.Max(n => n.Position.X) + 100,
                yCoord
                );

            // Setup binding between entrance/exit inputs and outputs
            var ioBinding = IOBindingFactory(groupNode, groupEntranceNode, groupExitNode);

            // Calculate set of connections to replace
            var subnetConnections       = new List <ConnectionViewModel>();
            var borderInputConnections  = new List <ConnectionViewModel>();
            var borderOutputConnections = new List <ConnectionViewModel>();

            foreach (var con in network.Connections.Items)
            {
                bool inputIsInSubnet  = groupNodesSet.Contains(con.Input.Parent);
                bool outputIsInSubnet = groupNodesSet.Contains(con.Output.Parent);

                if (inputIsInSubnet && outputIsInSubnet)
                {
                    subnetConnections.Add(con);
                }
                else if (inputIsInSubnet)
                {
                    borderInputConnections.Add(con);
                }
                else if (outputIsInSubnet)
                {
                    borderOutputConnections.Add(con);
                }
            }

            // Construct inputs/outputs into/out of the group
            foreach (var borderInCon in borderInputConnections)
            {
                if (!groupNodeInputs.ContainsKey(borderInCon.Input))
                {
                    groupNodeInputs[borderInCon.Input] = ioBinding.AddNewGroupNodeInput(borderInCon.Output);
                }
            }

            foreach (var borderOutCon in borderOutputConnections)
            {
                if (!groupNodeOutputs.ContainsKey(borderOutCon.Output))
                {
                    groupNodeOutputs[borderOutCon.Output] = ioBinding.AddNewGroupNodeOutput(borderOutCon.Input);
                }
            }

            // Transfer nodes and inner connections to subnet
            network.Connections.Edit(l =>
            {
                l.RemoveMany(subnetConnections);
                l.RemoveMany(borderInputConnections);
                l.RemoveMany(borderOutputConnections);
            });
            network.Nodes.RemoveMany(groupNodesSet);
            subnet.Nodes.AddRange(groupNodesSet);
            subnet.Connections.AddRange(subnetConnections.Select(con => subnet.ConnectionFactory(con.Input, con.Output)));

            // Restore connections in/out of group
            network.Connections.AddRange(Enumerable.Concat(
                                             borderInputConnections.Select(con => network.ConnectionFactory(groupNodeInputs[con.Input], con.Output)),
                                             borderOutputConnections.Select(con => network.ConnectionFactory(con.Input, groupNodeOutputs[con.Output]))
                                             ));
            subnet.Connections.AddRange(Enumerable.Concat(
                                            borderInputConnections.Select(con => subnet.ConnectionFactory(con.Input, ioBinding.GetSubnetInlet(groupNodeInputs[con.Input]))),
                                            borderOutputConnections.Select(con => subnet.ConnectionFactory(ioBinding.GetSubnetOutlet(groupNodeOutputs[con.Output]), con.Output))
                                            ));

            return(ioBinding);
        }