private static IReadOnlyList <object> BuildExecutionList(GraphModel graph)
        {
            var nodes = graph.Nodes;

            if (nodes.Count == 0)
            {
                return(Array.Empty <object>());
            }

            var nodesToCheck = new Queue <NodeModel>(nodes.Where(n => !n.InputPorts().Any()));

            if (nodesToCheck.Count == 0)
            {
                throw new InvalidOperationException("Cannot walk graph! All of its nodes have inputs");
            }

            var connections          = graph.Connections;
            var ret                  = new object[nodes.Count + connections.Count];
            var fulfilledConnections = new HashSet <ConnectionModel>();

            int indexer = 0;

            while (nodesToCheck.Count > 0)
            {
                var node = nodesToCheck.Dequeue();
                ret[indexer++] = node;

                var outputConnections = node.OutputConnections();

                // mark connected nodes' ports as fulfilled
                foreach (var connection in outputConnections)
                {
                    ret[indexer++] = connection;
                    fulfilledConnections.Add(connection);
                }

                // find new nodes, that can be added to queue
                foreach (var connection in outputConnections)
                {
                    var connectedNode = connection.To.Node;

                    var inputConnections = connectedNode.InputConnections();

                    // check if all input ports are connected and all input connections are fulfilled
                    if (connectedNode.InputPorts().All(p => p.Connections.Count > 0 || p.Optional) &&
                        inputConnections.All(c => fulfilledConnections.Contains(c)))
                    {
                        nodesToCheck.Enqueue(connectedNode);

                        foreach (var inConnection in inputConnections)
                        {
                            fulfilledConnections.Remove(inConnection);
                        }
                    }
                }
            }

            if (fulfilledConnections.Count > 0)
            {
                throw new InvalidOperationException("Cannot walk graph! Some nodes have unfulfilled connections!");
            }

            return(ret);
        }
Exemple #2
0
 public static void AddContentsToGraph(this SGraph graph, GraphModel graphModel, List <SConnection> brokenConnections = null)
 {
     graphModel.AddNodes(graph.Nodes);
     graphModel.AddConnections(graph.Connections, brokenConnections);
 }