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); }
public static void AddContentsToGraph(this SGraph graph, GraphModel graphModel, List <SConnection> brokenConnections = null) { graphModel.AddNodes(graph.Nodes); graphModel.AddConnections(graph.Connections, brokenConnections); }