47 bool ownsPublishedNodeClasses =
false;
52 triggerNodeClass = compiler->
getNodeClass(
"vuo.event.spinOffEvent2");
58 vector<VuoPortClass *> inputPortClasses;
59 vector<VuoPortClass *> outputPortClasses(1, triggerPortClass->
getBase());
60 VuoNodeClass *baseNodeClass =
new VuoNodeClass(
"vuo.event.spinOffEvent2", refreshPortClass, inputPortClasses, outputPortClasses);
67 if (! (publishedInputPorts.empty() && publishedOutputPorts.empty()) )
74 ownsPublishedNodeClasses =
false;
83 ownsPublishedNodeClasses =
true;
93 initializeInstance(composition, potentialCables, publishedInputNode, publishedOutputNode, publishedInputTriggerNode, ownsPublishedNodeClasses,
94 manuallyFirableTriggerNode);
121 void VuoCompilerGraph::initializeInstance(
VuoCompilerComposition *composition, set<VuoCompilerCable *> potentialCables,
123 VuoCompilerNode *publishedInputTriggerNode,
bool ownsPublishedNodeClasses,
126 this->publishedInputNode = publishedInputNode;
127 this->publishedOutputNode = publishedOutputNode;
128 this->ownsPublishedNodeClasses = ownsPublishedNodeClasses;
129 this->publishedInputTrigger =
nullptr;
133 set<VuoNode *> nodesIncludingInvalid = composition->
getBase()->
getNodes();
134 set<VuoNode *> nodesToAnalyze;
135 for (
VuoNode *node : nodesIncludingInvalid)
136 if (node->hasCompiler())
137 nodesToAnalyze.insert(node);
139 if (publishedInputNode && publishedOutputNode)
143 nodesToAnalyze.insert(publishedInputNode->
getBase());
144 nodesToAnalyze.insert(publishedOutputNode->
getBase());
148 nodesToAnalyze.insert(publishedInputTriggerNode->
getBase());
156 nodesToAnalyze.insert(manuallyFirableTriggerNode->
getBase());
163 set<VuoPort *> potentialCableInputs;
165 if (cable->carriesData())
166 potentialCableInputs.insert(cable->getBase()->getToPort());
168 set<VuoCable *> cablesIncludingInvalidAndPublished = composition->
getBase()->
getCables();
169 set<VuoCable *> cablesToAnalyze;
170 for (
VuoCable *cable : cablesIncludingInvalidAndPublished)
172 if ((cable->getFromPort() && cable->getToPort())
173 && (cable->getFromPort()->hasCompiler() && cable->getToPort()->hasCompiler())
174 && ! (cable->hasCompiler() && cable->getCompiler()->carriesData() &&
175 potentialCableInputs.find(cable->getToPort()) != potentialCableInputs.end()) )
177 if (cable->isPublished())
178 publishedCables.insert(cable);
180 cablesToAnalyze.insert(cable);
188 if (cable->getBase()->isPublished())
189 publishedCables.insert(cable->getBase());
191 cablesToAnalyze.insert(cable->getBase());
198 for (
VuoCable *cable : publishedCables)
205 if (cable->isPublishedInputCable())
207 size_t publishedPortIndex = std::distance(publishedInputPorts.begin(), std::find(publishedInputPorts.begin(), publishedInputPorts.end(), cable->getFromPort()));
209 fromNode = publishedInputNode->
getBase();
210 fromPort = getOutputPortOnPublishedInputNode(publishedPortIndex);
211 toNode = cable->getToNode();
212 toPort = cable->getToPort();
216 size_t publishedPortIndex = std::distance(publishedOutputPorts.begin(), std::find(publishedOutputPorts.begin(), publishedOutputPorts.end(), cable->getToPort()));
218 fromNode = cable->getFromNode();
219 fromPort = cable->getFromPort();
220 toNode = publishedOutputNode->
getBase();
227 cablesToAnalyze.insert(replacement->
getBase());
232 if (publishedInputTrigger)
237 cablesToAnalyze.insert(spinOffCable->
getBase());
249 cablesToAnalyze.insert(spinOffCable->
getBase());
253 for (
VuoNode *node : nodesToAnalyze)
254 nodes.insert(node->getCompiler());
256 makeTriggers(nodesToAnalyze);
257 makeVerticesAndEdges(cablesToAnalyze);
258 makeDownstreamVertices();
260 makeVertexDistances();
261 makeDownstreamNodesViaDataOnlyTransmission(nodesToAnalyze, cablesToAnalyze);
269 VuoCompilerNode *publishedInputTriggerNode = nodeForTrigger[publishedInputTrigger];
271 if (ownsPublishedNodeClasses)
278 delete publishedInputNode;
279 delete publishedOutputNode;
280 delete publishedInputTriggerNode;
286 void VuoCompilerGraph::makeTriggers(set<VuoNode *> nodes)
290 for (
VuoPort *port : node->getOutputPorts())
295 nodeForTrigger[trigger] = node->getCompiler();
296 triggers.push_back(trigger);
305 void VuoCompilerGraph::makeVerticesAndEdges(
const set<VuoCable *> &cables)
309 set<Vertex> allVertices;
316 Vertex vertex = (fromTrigger ? Vertex(fromTrigger, toNode) : Vertex(fromNode, toNode));
318 set<Vertex>::iterator vertexIter = allVertices.find(vertex);
319 if (vertexIter != allVertices.end())
321 vertex.cableBundle = (*vertexIter).cableBundle;
322 allVertices.erase(vertexIter);
324 vertex.cableBundle.insert(cable->getCompiler());
326 allVertices.insert(vertex);
333 set<Vertex> verticesToVisit;
334 set<Edge> edgesVisited;
336 for (set<Vertex>::iterator j = allVertices.begin(); j != allVertices.end(); ++j)
337 if ((*j).fromTrigger == trigger)
338 verticesToVisit.insert(*j);
340 map<VuoCompilerNode *, set<Vertex> > outgoingVerticesForNode;
341 for (set<Vertex>::iterator j = allVertices.begin(); j != allVertices.end(); ++j)
342 outgoingVerticesForNode[(*j).fromNode].insert(*j);
344 while (! verticesToVisit.empty())
346 Vertex vertex = *verticesToVisit.begin();
347 if (find(vertices[trigger].begin(), vertices[trigger].end(), vertex) == vertices[trigger].end())
348 vertices[trigger].push_back(vertex);
349 verticesToVisit.erase(verticesToVisit.begin());
351 set<Vertex> potentialOutgoingVertices = outgoingVerticesForNode[vertex.toNode];
352 for (set<Vertex>::iterator j = potentialOutgoingVertices.begin(); j != potentialOutgoingVertices.end(); ++j)
354 Vertex outgoingVertex = *j;
356 if (
mayTransmit(vertex.cableBundle, outgoingVertex.cableBundle))
358 Edge outgoingEdge(vertex, outgoingVertex);
359 if (edgesVisited.find(outgoingEdge) == edgesVisited.end())
361 edges[trigger].insert(outgoingEdge);
362 edgesVisited.insert(outgoingEdge);
364 verticesToVisit.insert(outgoingVertex);
376 void VuoCompilerGraph::makeDownstreamVerticesWithInclusionRule(
VuoCompilerTriggerPort *trigger, std::function<
bool(Edge)> includeEdge,
377 map<Vertex, set<Vertex> > &_downstreamVertices,
378 set<Vertex> &_repeatedVertices)
380 list<Vertex> verticesToVisit;
382 for (Vertex vertex : vertices[trigger])
383 if (vertex.fromTrigger == trigger)
384 verticesToVisit.push_back(vertex);
386 map<Vertex, set<Vertex> > outgoingVerticesFromVertex;
387 for (Edge edge : edges[trigger])
388 if (includeEdge(edge))
389 outgoingVerticesFromVertex[edge.fromVertex].insert(edge.toVertex);
391 while (! verticesToVisit.empty())
394 Vertex currentVertex = verticesToVisit.back();
396 set<Vertex> currentDownstreamVertices;
397 bool areDownstreamVerticesComplete =
true;
400 set<Vertex> outgoingVertices = outgoingVerticesFromVertex[currentVertex];
401 for (set<Vertex>::iterator j = outgoingVertices.begin(); j != outgoingVertices.end(); ++j)
403 Vertex outgoingVertex = *j;
404 currentDownstreamVertices.insert(outgoingVertex);
406 if (_downstreamVertices.find(outgoingVertex) != _downstreamVertices.end())
409 set<Vertex> furtherDownstreamVertices = _downstreamVertices[outgoingVertex];
410 currentDownstreamVertices.insert( furtherDownstreamVertices.begin(), furtherDownstreamVertices.end() );
414 if (find(verticesToVisit.begin(), verticesToVisit.end(), outgoingVertex) != verticesToVisit.end())
417 _repeatedVertices.insert(outgoingVertex);
422 verticesToVisit.push_back(outgoingVertex);
423 areDownstreamVerticesComplete =
false;
428 if (areDownstreamVerticesComplete)
430 _downstreamVertices[currentVertex] = currentDownstreamVertices;
431 verticesToVisit.pop_back();
437 set<Vertex> repeatedVerticesCopy = _repeatedVertices;
438 for (Vertex vertex : repeatedVerticesCopy)
439 if (_downstreamVertices[vertex].find(vertex) == _downstreamVertices[vertex].end())
440 _repeatedVertices.erase(vertex);
446 void VuoCompilerGraph::makeDownstreamVertices(
void)
448 auto includeAllEdges = [] (Edge edge) {
return true; };
452 makeDownstreamVerticesWithInclusionRule(trigger, includeAllEdges, downstreamVertices[trigger], repeatedVertices[trigger]);
454 if (repeatedVertices[trigger].empty())
455 repeatedVertices.erase(trigger);
465 if (publishedOutputNode)
469 set< pair<VuoCompilerTriggerPort *, Vertex> > leaves;
470 if (trigger != publishedInputTrigger && trigger != manuallyFirableTrigger && downstreamVertices[trigger].empty())
471 leaves.insert({ trigger, Vertex() });
473 for (
auto i : downstreamVertices[trigger])
474 if (i.first.toNode != publishedOutputNode && i.second.empty())
475 leaves.insert({
nullptr, i.first });
477 for (
auto &leaf : leaves)
479 VuoCompilerNode *fromNode = (leaf.first ? nodeForTrigger[leaf.first] : leaf.second.toNode);
486 Vertex gatherVertex = (leaf.first ? Vertex(fromPort, publishedOutputNode) : Vertex(fromNode, publishedOutputNode));
487 gatherVertex.cableBundle.insert(gather);
488 vertices[trigger].push_back(gatherVertex);
492 Vertex leafVertex = leaf.second;
493 Edge gatherEdge(leafVertex, gatherVertex);
494 edges[trigger].insert(gatherEdge);
495 downstreamVertices[trigger][leafVertex].insert(gatherVertex);
505 void VuoCompilerGraph::sortVertices(
void)
507 for (map<
VuoCompilerTriggerPort *, vector<Vertex> >::iterator i = vertices.begin(); i != vertices.end(); ++i)
510 vector<Vertex> verticesToSort = i->second;
512 map<Vertex, set<Vertex> > dependentVertices;
513 list<Vertex> verticesToVisit;
514 map<Vertex, bool> verticesCompleted;
516 for (vector<Vertex>::iterator j = verticesToSort.begin(); j != verticesToSort.end(); ++j)
517 if ((*j).fromTrigger == trigger)
518 verticesToVisit.push_back(*j);
520 map<VuoCompilerNode *, set<Vertex> > outgoingVerticesForNode;
521 for (vector<Vertex>::iterator j = verticesToSort.begin(); j != verticesToSort.end(); ++j)
522 outgoingVerticesForNode[(*j).fromNode].insert(*j);
524 while (! verticesToVisit.empty())
527 Vertex currentVertex = verticesToVisit.back();
529 set<Vertex> currentDependentVertices;
530 bool areDependentVerticesComplete =
true;
536 set<Vertex> outgoingVertices;
537 set<Vertex> potentialOutgoingVertices = outgoingVerticesForNode[currentVertex.toNode];
538 for (set<Vertex>::iterator j = potentialOutgoingVertices.begin(); j != potentialOutgoingVertices.end(); ++j)
540 Vertex outgoingVertex = *j;
541 if (downstreamVertices[trigger][outgoingVertex].find(currentVertex) == downstreamVertices[trigger][outgoingVertex].end())
542 outgoingVertices.insert(outgoingVertex);
545 outgoingVertices.clear();
550 for (set<Vertex>::iterator j = outgoingVertices.begin(); j != outgoingVertices.end(); ++j)
552 Vertex outgoingVertex = *j;
553 currentDependentVertices.insert(outgoingVertex);
555 if (verticesCompleted[outgoingVertex])
558 currentDependentVertices.insert( dependentVertices[outgoingVertex].begin(), dependentVertices[outgoingVertex].end() );
560 else if (find(verticesToVisit.begin(), verticesToVisit.end(), outgoingVertex) == verticesToVisit.end())
563 verticesToVisit.push_back(outgoingVertex);
564 areDependentVerticesComplete =
false;
568 if (areDependentVerticesComplete)
570 dependentVertices[currentVertex] = currentDependentVertices;
571 verticesToVisit.pop_back();
572 verticesCompleted[currentVertex] =
true;
577 vector< pair<size_t, Vertex> > verticesAndDependents;
578 for (map<Vertex, set<Vertex> >::iterator j = dependentVertices.begin(); j != dependentVertices.end(); ++j)
579 verticesAndDependents.push_back( make_pair(j->second.size(), j->first) );
580 sort(verticesAndDependents.begin(), verticesAndDependents.end());
582 vector<Vertex> sortedVertices;
583 for (vector< pair<size_t, Vertex> >::reverse_iterator j = verticesAndDependents.rbegin(); j != verticesAndDependents.rend(); ++j)
584 sortedVertices.push_back((*j).second);
586 vertices[trigger] = sortedVertices;
593 void VuoCompilerGraph::makeVertexDistances(
void)
595 for (map<
VuoCompilerTriggerPort *, vector<Vertex> >::iterator i = vertices.begin(); i != vertices.end(); ++i)
598 vector<Vertex> verticesDownstream = i->second;
600 map<VuoCompilerNode *, set<Vertex> > incomingVerticesForNode;
601 for (vector<Vertex>::iterator j = verticesDownstream.begin(); j != verticesDownstream.end(); ++j)
602 incomingVerticesForNode[(*j).toNode].insert(*j);
605 for (vector<Vertex>::iterator j = verticesDownstream.begin(); j != verticesDownstream.end(); ++j)
608 if (vertex.fromTrigger == trigger)
610 vertexDistanceFromTrigger[trigger][vertex] = 1;
611 triggerMustTransmitToVertex[trigger][vertex] =
true;
616 for (vector<Vertex>::iterator j = verticesDownstream.begin(); j != verticesDownstream.end(); ++j)
619 if (vertex.fromTrigger != trigger)
621 size_t minDistance = verticesDownstream.size();
622 bool anyMustTransmit =
false;
623 for (set<Vertex>::iterator k = incomingVerticesForNode[vertex.fromNode].begin(); k != incomingVerticesForNode[vertex.fromNode].end(); ++k)
625 Vertex upstreamVertex = *k;
627 minDistance = min(vertexDistanceFromTrigger[trigger][upstreamVertex], minDistance);
628 bool currMustTransmit = triggerMustTransmitToVertex[trigger][upstreamVertex] && mustTransmit(upstreamVertex, trigger);
629 anyMustTransmit = currMustTransmit || anyMustTransmit;
632 vertexDistanceFromTrigger[trigger][vertex] = minDistance + 1;
633 triggerMustTransmitToVertex[trigger][vertex] = anyMustTransmit;
642 void VuoCompilerGraph::makeDownstreamNodesViaDataOnlyTransmission(set<VuoNode *> nodes, set<VuoCable *> cables)
649 map<VuoCompilerNode *, set<VuoCompilerNode *> > remainingIncomingNodes;
650 map<VuoCompilerNode *, set<VuoCompilerNode *> > remainingOutgoingNodes;
655 if (fromTrigger || ! cable->getCompiler()->carriesData())
663 remainingOutgoingNodes[fromNode].insert(toNode);
665 remainingIncomingNodes[toNode].insert(fromNode);
668 map<VuoCompilerNode *, set<VuoCompilerNode *> > outgoingNodes = remainingOutgoingNodes;
670 set<VuoCompilerNode *> nodesToVisit;
674 remainingIncomingNodes.find(node->getCompiler()) == remainingIncomingNodes.end() &&
675 remainingOutgoingNodes.find(node->getCompiler()) != remainingOutgoingNodes.end())
676 nodesToVisit.insert(node->getCompiler());
679 vector<VuoCompilerNode *> sortedNodesAllowingDataOnlyTransmission;
680 while (! nodesToVisit.empty())
683 nodesToVisit.erase(nodesToVisit.begin());
685 sortedNodesAllowingDataOnlyTransmission.push_back(node);
687 set<VuoCompilerNode *> outgoingNodesCopy = remainingOutgoingNodes[node];
690 remainingIncomingNodes[outgoingNode].erase(node);
691 remainingOutgoingNodes[node].erase(outgoingNode);
693 if (remainingIncomingNodes[outgoingNode].empty())
694 nodesToVisit.insert(outgoingNode);
700 for (
int firstIndex = sortedNodesAllowingDataOnlyTransmission.size() - 1; firstIndex >= 0; --firstIndex)
702 VuoCompilerNode *firstNode = sortedNodesAllowingDataOnlyTransmission[firstIndex];
704 for (
size_t possiblyDownstreamIndex = firstIndex + 1; possiblyDownstreamIndex < sortedNodesAllowingDataOnlyTransmission.size(); ++possiblyDownstreamIndex)
706 VuoCompilerNode *possiblyDownstreamNode = sortedNodesAllowingDataOnlyTransmission[possiblyDownstreamIndex];
708 if (outgoingNodes[firstNode].find(possiblyDownstreamNode) != outgoingNodes[firstNode].end())
710 vector<VuoCompilerNode *> nodesToAdd = downstreamNodesViaDataOnlyTransmission[possiblyDownstreamNode];
711 nodesToAdd.insert(nodesToAdd.begin(), possiblyDownstreamNode);
714 if (find(downstreamNodesViaDataOnlyTransmission[firstNode].begin(), downstreamNodesViaDataOnlyTransmission[firstNode].end(), nodeToAdd) == downstreamNodesViaDataOnlyTransmission[firstNode].end())
715 downstreamNodesViaDataOnlyTransmission[firstNode].push_back(nodeToAdd);
727 bool VuoCompilerGraph::mustTransmit(
const set<VuoCompilerCable *> &fromCables,
const set<VuoCompilerCable *> &toCables)
729 bool fromCablesMustTransmit =
false;
732 VuoPort *inputPort = cable->getBase()->getToPort();
735 fromCablesMustTransmit =
true;
740 bool toCablesMayTransmit =
false;
743 VuoPort *outputPort = cable->getBase()->getFromPort();
746 toCablesMayTransmit =
true;
751 return fromCablesMustTransmit && toCablesMayTransmit;
759 set<VuoCompilerCable *> cablesBetweenFromNodeAndToNode = vertex.cableBundle;
761 set<VuoCompilerCable *> cablesOutOfToNode;
762 for (vector<Vertex>::iterator i = vertices[trigger].begin(); i != vertices[trigger].end(); ++i)
764 Vertex otherVertex = *i;
765 if (vertex.toNode == otherVertex.fromNode)
766 cablesOutOfToNode.insert(otherVertex.cableBundle.begin(), otherVertex.cableBundle.end());
769 return mustTransmit(cablesBetweenFromNodeAndToNode, cablesOutOfToNode);
781 bool fromCablesMayTransmit =
false;
784 VuoPort *inputPort = cable->getBase()->getToPort();
787 fromCablesMayTransmit =
true;
792 bool toCablesMayTransmit =
false;
795 VuoPort *outputPort = cable->getBase()->getFromPort();
798 toCablesMayTransmit =
true;
803 return fromCablesMayTransmit && toCablesMayTransmit;
811 set<VuoCompilerCable *> cablesBetweenFromNodeAndToNode = vertex.cableBundle;
813 set<VuoCompilerCable *> cablesOutOfToNode;
814 for (vector<Vertex>::iterator i = vertices[trigger].begin(); i != vertices[trigger].end(); ++i)
816 Vertex otherVertex = *i;
817 if (vertex.toNode == otherVertex.fromNode)
818 cablesOutOfToNode.insert(otherVertex.cableBundle.begin(), otherVertex.cableBundle.end());
821 return mayTransmit(cablesBetweenFromNodeAndToNode, cablesOutOfToNode);
829 set<VuoCompilerCable *> incomingCables;
830 set<VuoCompilerCable *> outgoingCables;
832 for (vector<Vertex>::iterator i = vertices[trigger].begin(); i != vertices[trigger].end(); ++i)
836 if (vertex.toNode == node)
837 incomingCables.insert( vertex.cableBundle.begin(), vertex.cableBundle.end() );
838 if (vertex.fromNode == node)
839 outgoingCables.insert( vertex.cableBundle.begin(), vertex.cableBundle.end() );
842 return mayTransmit(incomingCables, outgoingCables);
850 if (vertexMayTransmit[trigger].empty() && ! vertices[trigger].empty())
851 for (vector<Vertex>::iterator i = vertices[trigger].begin(); i != vertices[trigger].end(); ++i)
852 vertexMayTransmit[trigger][(*i).fromNode][(*i).toNode] =
true;
854 return vertexMayTransmit[trigger][fromNode][toNode];
878 auto foundIter = nodeForTrigger.find(trigger);
879 if (foundIter != nodeForTrigger.end())
880 return foundIter->second;
901 return publishedInputNode;
911 return publishedOutputNode;
919 return publishedInputTrigger;
935 VuoPort * VuoCompilerGraph::getOutputPortOnPublishedInputNode(
size_t publishedInputPortIndex)
967 return manuallyFirableTrigger;
976 for (vector<Vertex>::iterator i = vertices[trigger].begin(); i != vertices[trigger].end(); ++i)
977 if ((*i).fromNode == fromNode)
988 map<VuoCompilerTriggerPort *, map<VuoCompilerNode *, size_t> >::iterator triggerIter = numVerticesWithToNode.find(trigger);
989 if (triggerIter != numVerticesWithToNode.end())
991 map<VuoCompilerNode *, size_t>::iterator nodeIter = triggerIter->second.find(toNode);
992 if (nodeIter != triggerIter->second.end())
993 return nodeIter->second;
996 size_t numVertices = 0;
997 for (vector<Vertex>::iterator i = vertices[trigger].begin(); i != vertices[trigger].end(); ++i)
998 if ((*i).toNode == toNode)
1001 numVerticesWithToNode[trigger][toNode] = numVertices;
1018 if (! chains.empty())
1024 vector< vector<VuoCompilerNode *> > chainsInProgress;
1025 set<VuoCompilerNode *> nodesAdded;
1026 bool skippedPublishedOutputNode =
false;
1027 for (vector<Vertex>::iterator j = vertices[trigger].begin(); j != vertices[trigger].end(); ++j)
1030 bool addedToChain =
false;
1032 if (nodesAdded.find(vertex.toNode) != nodesAdded.end())
1035 if (vertex.toNode == publishedOutputNode)
1037 skippedPublishedOutputNode =
true;
1041 nodesAdded.insert(vertex.toNode);
1043 if (vertex.fromNode)
1045 if (getNumVerticesWithFromNode(vertex.fromNode, trigger) == 1 &&
1046 getNumVerticesWithToNode(vertex.toNode, trigger) == 1)
1048 for (
int k = 0; k < chainsInProgress.size(); ++k)
1051 if (lastNodeInChain == vertex.fromNode)
1054 chainsInProgress[k].push_back(vertex.toNode);
1055 addedToChain =
true;
1065 chainsInProgress.push_back( vector<VuoCompilerNode *>(1, vertex.toNode) );
1070 for (vector< vector<VuoCompilerNode *> >::iterator j = chainsInProgress.begin(); j != chainsInProgress.end(); ++j)
1072 vector<VuoCompilerNode *> chainNodes = *j;
1074 chains[trigger].push_back(chain);
1078 map<VuoCompilerNode *, bool> nodesSeen;
1079 for (vector<Vertex>::iterator j = vertices[trigger].begin(); j != vertices[trigger].end(); ++j)
1082 if (nodesSeen[node])
1084 nodesSeen[node] =
true;
1089 chains[trigger].push_back(chain);
1094 if (skippedPublishedOutputNode)
1097 chains[trigger].push_back(chain);
1109 set<VuoCompilerNode *> downstreamNodes;
1110 for (vector<Vertex>::iterator i = vertices[trigger].begin(); i != vertices[trigger].end(); ++i)
1111 if ((*i).fromTrigger == trigger)
1112 downstreamNodes.insert((*i).toNode);
1114 return vector<VuoCompilerNode *>(downstreamNodes.begin(), downstreamNodes.end());
1122 set<VuoCompilerNode *> downstreamNodes;
1123 for (vector<Vertex>::iterator i = vertices[trigger].begin(); i != vertices[trigger].end(); ++i)
1124 if ((*i).fromNode == node)
1125 downstreamNodes.insert((*i).toNode);
1127 return vector<VuoCompilerNode *>(downstreamNodes.begin(), downstreamNodes.end());
1135 map<VuoCompilerTriggerPort *, vector<VuoCompilerNode *> >::iterator triggerIter = downstreamNodesForTrigger.find(trigger);
1136 if (triggerIter != downstreamNodesForTrigger.end())
1137 return triggerIter->second;
1139 set<VuoCompilerNode *> downstreamNodes;
1141 downstreamNodes.insert(immediatelyDownstreamNodes.begin(), immediatelyDownstreamNodes.end());
1143 for (vector<VuoCompilerNode *>::iterator i = immediatelyDownstreamNodes.begin(); i != immediatelyDownstreamNodes.end(); ++i)
1146 downstreamNodes.insert(furtherDownstreamNodes.begin(), furtherDownstreamNodes.end());
1149 vector<VuoCompilerNode *> downstreamNodesVector(downstreamNodes.begin(), downstreamNodes.end());
1150 downstreamNodesForTrigger[trigger] = downstreamNodesVector;
1151 return downstreamNodesVector;
1159 map<VuoCompilerTriggerPort *, map<VuoCompilerNode *, vector<VuoCompilerNode *> > >::iterator triggerIter = downstreamNodesForNode.find(trigger);
1160 if (triggerIter != downstreamNodesForNode.end())
1162 map<VuoCompilerNode *, vector<VuoCompilerNode *> >::iterator nodeIter = triggerIter->second.find(node);
1163 if (nodeIter != triggerIter->second.end())
1164 return nodeIter->second;
1167 set<Vertex> verticesWithDownstreamNodes;
1168 for (vector<Vertex>::iterator i = vertices[trigger].begin(); i != vertices[trigger].end(); ++i)
1171 if (vertex.fromNode == node)
1173 verticesWithDownstreamNodes.insert(vertex);
1174 set<Vertex> downstream = downstreamVertices[trigger][vertex];
1175 verticesWithDownstreamNodes.insert(downstream.begin(), downstream.end());
1179 set<VuoCompilerNode *> downstreamNodes;
1180 for (set<Vertex>::iterator i = verticesWithDownstreamNodes.begin(); i != verticesWithDownstreamNodes.end(); ++i)
1181 downstreamNodes.insert((*i).toNode);
1183 vector<VuoCompilerNode *> downstreamNodesVector(downstreamNodes.begin(), downstreamNodes.end());
1184 downstreamNodesForNode[trigger][node] = downstreamNodesVector;
1185 return downstreamNodesVector;
1194 return downstreamNodesViaDataOnlyTransmission[node];
1204 set<VuoCompilerCable *> outgoingCables;
1209 if (cable->getToNode() && cable->getToNode()->hasCompiler())
1210 outgoingCables.insert(cable->getCompiler());
1215 for (Vertex vertex : kv.second)
1218 outgoingCables.insert(cable);
1220 return outgoingCables;
1228 set<VuoCompilerNode *> nodesTransmittingDataOnly;
1229 set<VuoCompilerNode *> nodesDownstreamOfAnother;
1231 for (
const map<
VuoCompilerNode *, vector<VuoCompilerNode *> >::value_type &i : downstreamNodesViaDataOnlyTransmission)
1233 nodesTransmittingDataOnly.insert(i.first);
1234 nodesDownstreamOfAnother.insert(i.second.begin(), i.second.end());
1237 set<VuoCompilerNode *> nodesNotDownstream;
1238 std::set_difference(nodesTransmittingDataOnly.begin(), nodesTransmittingDataOnly.end(),
1239 nodesDownstreamOfAnother.begin(), nodesDownstreamOfAnother.end(),
1240 std::inserter(nodesNotDownstream, nodesNotDownstream.end()));
1241 return nodesNotDownstream;
1251 minThreadsNeeded = 1;
1252 maxThreadsNeeded = 1;
1259 for (vector<VuoCompilerTriggerDescription *>::iterator k = triggerDescriptions.begin(); k != triggerDescriptions.end(); ++k)
1264 int minThreadsNeededForSubcomposition, maxThreadsNeededForSubcomposition;
1265 (*k)->getWorkerThreadsNeeded(minThreadsNeededForSubcomposition, maxThreadsNeededForSubcomposition);
1266 minThreadsNeeded = max(minThreadsNeeded, minThreadsNeededForSubcomposition + 1);
1267 maxThreadsNeeded = max(maxThreadsNeeded, maxThreadsNeededForSubcomposition + 1);
1282 vector<VuoCompilerChain *> chainsForTrigger =
getChains()[trigger];
1283 map<VuoCompilerChain *, pair<int, int> > threadsNeededForChain;
1284 for (vector<VuoCompilerChain *>::iterator i = chainsForTrigger.begin(); i != chainsForTrigger.end(); ++i)
1288 int minThreadsNeededForChain, maxThreadsNeededForChain;
1291 threadsNeededForChain[chain] = make_pair(minThreadsNeededForChain, maxThreadsNeededForChain);
1295 map<VuoCompilerChain *, set<VuoCompilerChain *> > chainsDownstream;
1296 for (vector<VuoCompilerChain *>::iterator i = chainsForTrigger.begin(); i != chainsForTrigger.end(); ++i)
1301 vector<VuoCompilerNode *> nodesDownstream =
getNodesDownstream(lastNodeInThisChain, trigger);
1303 for (vector<VuoCompilerChain *>::iterator j = i+1; j != chainsForTrigger.end(); ++j)
1308 if (find(nodesDownstream.begin(), nodesDownstream.end(), firstNodeInOtherChain) != nodesDownstream.end())
1309 chainsDownstream[chain].insert(otherChain);
1314 map<VuoCompilerChain *, set<VuoCompilerChain *> > chainsImmediatelyDownstream;
1315 map<VuoCompilerChain *, set<VuoCompilerChain *> > chainsImmediatelyUpstream;
1316 for (vector<VuoCompilerChain *>::iterator i = chainsForTrigger.begin(); i != chainsForTrigger.end(); ++i)
1323 for (vector<VuoCompilerChain *>::iterator j = i+1; j != chainsForTrigger.end(); ++j)
1328 if (find(nodesDownstream.begin(), nodesDownstream.end(), firstNodeInOtherChain) != nodesDownstream.end())
1330 chainsImmediatelyDownstream[chain].insert(otherChain);
1331 chainsImmediatelyUpstream[otherChain].insert(chain);
1337 minThreadsNeeded = 1;
1338 maxThreadsNeeded = 1;
1347 vector< pair<VuoCompilerChain *, vector<VuoCompilerChain *> > > potentialScatters;
1348 vector<VuoCompilerChain *> scatterForTrigger;
1349 for (vector<VuoCompilerChain *>::iterator i = chainsForTrigger.begin(); i != chainsForTrigger.end(); ++i)
1350 if (chainsImmediatelyUpstream.find(*i) == chainsImmediatelyUpstream.end())
1351 scatterForTrigger.push_back(*i);
1352 potentialScatters.push_back( make_pair((
VuoCompilerChain *)NULL, scatterForTrigger) );
1355 for (vector<VuoCompilerChain *>::iterator i = chainsForTrigger.begin(); i != chainsForTrigger.end(); ++i)
1357 vector<VuoCompilerChain *> scatterForChain(chainsImmediatelyDownstream[*i].begin(), chainsImmediatelyDownstream[*i].end());
1358 potentialScatters.push_back( make_pair(*i, scatterForChain) );
1361 map<VuoCompilerChain *, int> threadsNeededForScatters;
1362 for (vector< pair<
VuoCompilerChain *, vector<VuoCompilerChain *> > >::reverse_iterator i = potentialScatters.rbegin(); i != potentialScatters.rend(); ++i)
1365 vector<VuoCompilerChain *> scatterChains = (*i).second;
1369 for (
size_t j = 0; j < scatterChains.size(); ++j)
1373 for (
size_t k = j+1; k < scatterChains.size(); ++k)
1377 if (chainsDownstream[inner].find(outer) != chainsDownstream[inner].end())
1379 scatterChains.erase( scatterChains.begin() + j-- );
1383 if (chainsDownstream[outer].find(inner) != chainsDownstream[outer].end())
1384 scatterChains.erase( scatterChains.begin() + k-- );
1389 int threadsNeededForScatter = 0;
1390 for (vector<VuoCompilerChain *>::iterator j = scatterChains.begin(); j != scatterChains.end(); ++j)
1391 threadsNeededForScatter += threadsNeededForScatters[*j];
1394 threadsNeededForScatter = max(threadsNeededForScatter, threadsNeededForChain[chain].second);
1396 threadsNeededForScatters[chain] = threadsNeededForScatter;
1400 for (map<VuoCompilerChain *, int>::iterator i = threadsNeededForScatters.begin(); i != threadsNeededForScatters.end(); ++i)
1401 maxThreadsNeeded = max(maxThreadsNeeded, i->second);
1408 for (map<
VuoCompilerChain *, pair<int, int> >::iterator i = threadsNeededForChain.begin(); i != threadsNeededForChain.end(); ++i)
1409 minThreadsNeeded = max(minThreadsNeeded, i->second.first);
1424 vector< pair<VuoCompilerTriggerPort *, size_t> > distancesForMusts;
1425 vector< pair<VuoCompilerTriggerPort *, size_t> > distancesForMays;
1427 for (map<
VuoCompilerTriggerPort *, vector<Vertex> >::iterator i = vertices.begin(); i != vertices.end(); ++i)
1430 vector<Vertex> verticesDownstream = i->second;
1432 for (vector<Vertex>::iterator j = verticesDownstream.begin(); j != verticesDownstream.end(); ++j)
1435 if (vertex.toNode == node)
1437 pair<VuoCompilerTriggerPort *, size_t> p = make_pair(trigger, vertexDistanceFromTrigger[trigger][vertex]);
1438 if (triggerMustTransmitToVertex[trigger][vertex])
1439 distancesForMusts.push_back(p);
1441 distancesForMays.push_back(p);
1446 if (! distancesForMusts.empty())
1448 sort(distancesForMusts.begin(), distancesForMusts.end(), compareTriggers);
1449 return distancesForMusts[0].first;
1451 else if (! distancesForMays.empty())
1453 sort(distancesForMays.begin(), distancesForMays.end(), compareTriggers);
1454 return distancesForMays[0].first;
1464 bool VuoCompilerGraph::compareTriggers(
const pair<VuoCompilerTriggerPort *, size_t> &lhs,
const pair<VuoCompilerTriggerPort *, size_t> &rhs)
1466 if (lhs.second == rhs.second)
1467 return lhs.first->getIdentifier() < rhs.first->getIdentifier();
1469 return lhs.second < rhs.second;
1485 if (! publishedInputTrigger)
1493 if (publishedOutputCount - publishedOutputTriggers.size() == 0)
1496 VuoPort *outputPort = getOutputPortOnPublishedInputNode(publishedInputPortIndex);
1498 set<Vertex> verticesFromPublishedInputNode;
1499 for (Vertex vertex : vertices[publishedInputTrigger])
1500 if (vertex.fromNode == publishedInputNode)
1501 verticesFromPublishedInputNode.insert(vertex);
1505 auto includeNonBlocking = [
this] (Edge edge)
1507 return (edge.fromVertex.fromTrigger == publishedInputTrigger ||
1508 mustTransmit(edge.fromVertex.cableBundle, edge.toVertex.cableBundle));
1511 if (downstreamVerticesNonBlocking.empty())
1514 makeDownstreamVerticesWithInclusionRule(publishedInputTrigger, includeNonBlocking, downstreamVerticesNonBlocking, unused);
1519 auto includeNonBlockingAndDoor = [
this] (Edge edge)
1521 return (edge.fromVertex.fromTrigger == publishedInputTrigger ||
1522 mayTransmit(edge.fromVertex.cableBundle, edge.toVertex.cableBundle));
1525 if (downstreamVerticesNonBlockingOrDoor.empty())
1528 makeDownstreamVerticesWithInclusionRule(publishedInputTrigger, includeNonBlockingAndDoor, downstreamVerticesNonBlockingOrDoor, unused);
1544 vector<Vertex> verticesToPublishedOutputNode;
1545 for (Vertex vertex : verticesFromPublishedInputNode)
1555 blockingForVertex = minBlocking(blockingForVertex, toPortBlocking);
1565 auto isVertexToPublishedOutputNode = [
this] (Vertex downstreamVertex) {
return downstreamVertex.toNode == publishedOutputNode; };
1567 vector<Vertex> verticesNonBlocking;
1568 std::copy_if(downstreamVerticesNonBlocking[vertex].begin(), downstreamVerticesNonBlocking[vertex].end(),
1569 std::back_inserter(verticesNonBlocking), isVertexToPublishedOutputNode);
1571 verticesToPublishedOutputNode.insert(verticesToPublishedOutputNode.end(), verticesNonBlocking.begin(), verticesNonBlocking.end());
1573 if (! verticesNonBlocking.empty())
1580 vector<Vertex> verticesNonBlockingOrDoor;
1581 std::copy_if(downstreamVerticesNonBlockingOrDoor[vertex].begin(), downstreamVerticesNonBlockingOrDoor[vertex].end(),
1582 std::back_inserter(verticesNonBlockingOrDoor), isVertexToPublishedOutputNode);
1584 verticesToPublishedOutputNode.insert(verticesToPublishedOutputNode.end(), verticesNonBlocking.begin(), verticesNonBlocking.end());
1586 if (! verticesNonBlockingOrDoor.empty())
1599 blocking = minBlocking(blocking, blockingForVertex);
1604 set<VuoPort *> publishedOutputPortsReached;
1605 for (Vertex vertex : verticesToPublishedOutputNode)
1610 if (publishedOutputPortsReached.size() < publishedOutputCount - publishedOutputTriggers.size())
1622 set<string> triggerNames;
1626 triggerNames.insert(currTriggerNames.begin(), currTriggerNames.end());
1629 return triggerNames;
1638 if (trigger == publishedInputTrigger)
1639 return set<string>();
1644 set<string> triggerNames;
1645 std::set_difference(outputNames.begin(), outputNames.end(),
1646 outputNamesForPublishedInputTrigger.begin(), outputNamesForPublishedInputTrigger.end(),
1647 std::inserter(triggerNames, triggerNames.begin()));
1649 return triggerNames;
1657 auto iter = publishedOutputNames.find(trigger);
1658 if (iter != publishedOutputNames.end())
1659 return iter->second;
1662 for (Vertex vertex : vertices[trigger])
1664 if (vertex.toNode == publishedOutputNode)
1675 publishedOutputNames[trigger] = names;
1698 return find(downstreamNodes.begin(), downstreamNodes.end(), node) != downstreamNodes.end();
1707 for (vector<VuoCompilerNode *>::iterator i = downstreamNodes.begin(); i != downstreamNodes.end(); ++i)
1708 if (getNumVerticesWithToNode(*i, trigger) > 1)
1721 if (isScatterAtTrigger)
1724 return areNodesPartiallyOverlappedByAnotherTrigger(downstreamNodes, trigger);
1737 if (isScatterAtNode)
1740 return areNodesPartiallyOverlappedByAnotherTrigger(downstreamNodes, trigger);
1749 bool VuoCompilerGraph::areNodesPartiallyOverlappedByAnotherTrigger(
const vector<VuoCompilerNode *> &nodes,
VuoCompilerTriggerPort *trigger)
1751 for (vector<VuoCompilerTriggerPort *>::iterator i = triggers.begin(); i != triggers.end(); ++i)
1754 if (otherTrigger == trigger)
1757 vector<VuoCompilerNode *> nodesDownstreamOfOtherTrigger =
getNodesDownstream(otherTrigger);
1758 nodesDownstreamOfOtherTrigger.push_back(nodeForTrigger[otherTrigger]);
1760 bool hasOverlappedNode =
false;
1761 bool hasNonOverlappedNode =
false;
1762 for (vector<VuoCompilerNode *>::const_iterator j = nodes.begin(); j != nodes.end(); ++j)
1766 if (find(nodesDownstreamOfOtherTrigger.begin(), nodesDownstreamOfOtherTrigger.end(), downstreamNode) != nodesDownstreamOfOtherTrigger.end())
1767 hasOverlappedNode =
true;
1769 hasNonOverlappedNode =
true;
1772 if (hasOverlappedNode && hasNonOverlappedNode)
1786 vector<VuoCompilerNode *> nodesDownstreamOfSpinOffs;
1790 vector<VuoCompilerNode *> nodesToCheck = nodesDownstreamOfTrigger;
1791 map<VuoCompilerNode *, bool> nodesChecked;
1792 while (! nodesToCheck.empty())
1795 nodesToCheck.pop_back();
1797 if (nodesChecked[node])
1799 nodesChecked[node] =
true;
1801 if (node == nodeForTrigger[publishedInputTrigger])
1811 nodesDownstreamOfSpinOffs.insert(nodesDownstreamOfSpinOffs.end(), nodesDownstream.begin(), nodesDownstream.end());
1812 nodesToCheck.insert(nodesToCheck.end(), nodesDownstream.begin(), nodesDownstream.end());
1816 sort(nodesDownstreamOfTrigger.begin(), nodesDownstreamOfTrigger.end());
1817 sort(nodesDownstreamOfSpinOffs.begin(), nodesDownstreamOfSpinOffs.end());
1820 set<VuoCompilerNode *> nodesDownstreamOfBoth;
1821 set_intersection(nodesDownstreamOfTrigger.begin(), nodesDownstreamOfTrigger.end(),
1822 nodesDownstreamOfSpinOffs.begin(), nodesDownstreamOfSpinOffs.end(),
1823 std::inserter(nodesDownstreamOfBoth, nodesDownstreamOfBoth.begin()));
1824 return ! nodesDownstreamOfBoth.empty();
1838 if (! repeatedVertices.empty())
1841 vector< set<VuoNode *> > nodesInLoops;
1842 vector< set<VuoCable *> > cablesInLoops;
1843 for (
const auto &i : repeatedVertices)
1846 for (
const Vertex &repeatedVertex : i.second)
1848 set<VuoNode *> nodesInLoop;
1849 set<VuoCable *> cablesInLoop;
1850 for (
const Vertex &otherVertex : vertices[trigger])
1852 if (downstreamVertices[trigger][repeatedVertex].find(otherVertex) != downstreamVertices[trigger][repeatedVertex].end() &&
1853 downstreamVertices[trigger][otherVertex].find(repeatedVertex) != downstreamVertices[trigger][otherVertex].end())
1855 nodesInLoop.insert(otherVertex.fromNode->getBase());
1856 nodesInLoop.insert(otherVertex.toNode->getBase());
1858 for (set<VuoCompilerCable *>::iterator m = otherVertex.cableBundle.begin(); m != otherVertex.cableBundle.end(); ++m)
1859 cablesInLoop.insert((*m)->getBase());
1862 nodesInLoops.push_back(nodesInLoop);
1863 cablesInLoops.push_back(cablesInLoop);
1868 vector< set<VuoNode *> > coalescedNodesInLoops;
1869 vector< set<VuoCable *> > coalescedCablesInLoops;
1870 for (
size_t i = 0; i < nodesInLoops.size(); ++i)
1872 bool coalesced =
false;
1873 for (
size_t j = 0; j < coalescedNodesInLoops.size(); ++j)
1875 set<VuoNode *> nodesInBoth;
1876 std::set_intersection(nodesInLoops[i].begin(), nodesInLoops[i].end(),
1877 coalescedNodesInLoops[j].begin(), coalescedNodesInLoops[j].end(),
1878 std::inserter(nodesInBoth, nodesInBoth.begin()));
1880 set<VuoCable *> cablesInBoth;
1881 std::set_intersection(cablesInLoops[i].begin(), cablesInLoops[i].end(),
1882 coalescedCablesInLoops[j].begin(), coalescedCablesInLoops[j].end(),
1883 std::inserter(cablesInBoth, cablesInBoth.begin()));
1885 if (nodesInBoth.size() == nodesInLoops[i].size() && cablesInBoth.size() == cablesInLoops[i].size())
1891 else if (nodesInBoth.size() == coalescedNodesInLoops[j].size() && cablesInBoth.size() == coalescedCablesInLoops[j].size())
1894 coalescedNodesInLoops[j] = nodesInLoops[i];
1895 coalescedCablesInLoops[j] = cablesInLoops[i];
1904 coalescedNodesInLoops.push_back(nodesInLoops[i]);
1905 coalescedCablesInLoops.push_back(cablesInLoops[i]);
1910 for (
size_t i = 0; i < coalescedNodesInLoops.size(); ++i)
1913 "Infinite feedback loop",
1914 "An event is not allowed to travel through the same cable more than once.");
1915 issue.
setHelpPath(
"errors-warnings-and-other-issues.html");
1916 issue.
setNodes(coalescedNodesInLoops[i]);
1917 issue.
setCables(coalescedCablesInLoops[i]);
1918 exceptionIssues->append(issue);
1942 map<VuoCompilerNode *, set<VuoCompilerNode *> > downstreamNodes;
1943 for (map<Vertex, set<Vertex> >::iterator j = downstreamVertices[trigger].begin(); j != downstreamVertices[trigger].end(); ++j)
1945 Vertex upstreamVertex = j->first;
1946 set<VuoCompilerNode *> downstreamNodesForVertex;
1947 bool isRepeated =
false;
1949 for (set<Vertex>::iterator k = j->second.begin(); k != j->second.end(); ++k)
1951 Vertex downstreamVertex = *k;
1952 if (upstreamVertex.toNode == downstreamVertex.toNode)
1958 downstreamNodesForVertex.insert(downstreamVertex.toNode);
1962 downstreamNodes[upstreamVertex.toNode].insert(downstreamNodesForVertex.begin(), downstreamNodesForVertex.end());
1966 set< pair<VuoCompilerNode *, VuoCompilerNode *> > mutuallyDownstreamNodePairs;
1967 for (map<
VuoCompilerNode *, set<VuoCompilerNode *> >::iterator j = downstreamNodes.begin(); j != downstreamNodes.end(); ++j)
1970 for (set<VuoCompilerNode *>::iterator k = j->second.begin(); k != j->second.end(); ++k)
1973 if (downstreamNodes[downstreamNode].find(upstreamNode) != downstreamNodes[downstreamNode].end() &&
1974 mutuallyDownstreamNodePairs.find( make_pair(downstreamNode, upstreamNode) ) == mutuallyDownstreamNodePairs.end())
1976 mutuallyDownstreamNodePairs.insert( make_pair(upstreamNode, downstreamNode) );
1982 for (set< pair<VuoCompilerNode *, VuoCompilerNode *> >::iterator j = mutuallyDownstreamNodePairs.begin(); j != mutuallyDownstreamNodePairs.end(); ++j)
1987 set<VuoNode *> nodesInLoop;
1988 set<VuoCable *> cablesInLoop;
1989 nodesInLoop.insert(firstNode->
getBase());
1990 nodesInLoop.insert(secondNode->
getBase());
1992 for (set<VuoCompilerNode *>::iterator k = downstreamNodes[firstNode].begin(); k != downstreamNodes[firstNode].end(); ++k)
1995 if (downstreamNodes[otherNode].find(secondNode) != downstreamNodes[otherNode].end())
1996 nodesInLoop.insert(otherNode->
getBase());
1998 for (set<VuoCompilerNode *>::iterator k = downstreamNodes[secondNode].begin(); k != downstreamNodes[secondNode].end(); ++k)
2001 if (downstreamNodes[otherNode].find(firstNode) != downstreamNodes[otherNode].end())
2002 nodesInLoop.insert(otherNode->
getBase());
2005 for (vector<Vertex>::iterator k = vertices[trigger].begin(); k != vertices[trigger].end(); ++k)
2008 if (vertex.fromNode &&
2009 nodesInLoop.find(vertex.fromNode->getBase()) != nodesInLoop.end() &&
2010 nodesInLoop.find(vertex.toNode->getBase()) != nodesInLoop.end())
2012 for (set<VuoCompilerCable *>::iterator m = vertex.cableBundle.begin(); m != vertex.cableBundle.end(); ++m)
2013 cablesInLoop.insert((*m)->getBase());
2018 "Deadlocked feedback loop",
2019 "There's more than one possible path for events to travel through this composition. "
2020 "It's unclear which is the correct one.");
2021 issue.
setHelpPath(
"errors-warnings-and-other-issues.html");
2024 exceptionIssues->append(issue);
2030 if (!exceptionIssues->isEmpty())
2047 if (node->hasCompiler())
2049 compilerNode = node->getCompiler();
2052 s <<
"{" << compilerNode <<
"," << identifier <<
"},";
2059 for (set<VuoCable *>::iterator i = cables.begin(); i != cables.end(); ++i)
2062 string fromNode = ((*i)->getFromNode() && (*i)->getFromNode()->hasCompiler()) ? (*i)->getFromNode()->getCompiler()->
getIdentifier() :
"";
2063 string fromPort = (*i)->getFromPort() ? (*i)->getFromPort()->getClass()->getName() :
"";
2064 string toNode = ((*i)->getToNode() && (*i)->getToNode()->hasCompiler()) ? (*i)->getToNode()->getCompiler()->
getIdentifier() :
"";
2065 string toPort = (*i)->getToPort() ? (*i)->getToPort()->
getClass()->
getName() :
"";
2066 s <<
"{" << (*i)->getCompiler() <<
"," << fromNode <<
"," << fromPort <<
"," << toNode <<
"," << toPort <<
"},";
2073 for (vector<VuoPublishedPort *>::iterator i = publishedInputPorts.begin(); i != publishedInputPorts.end(); ++i)
2074 s <<
"{" << (*i)->getCompiler() <<
"," << (*i)->getClass()->getName() <<
"},";
2078 for (vector<VuoPublishedPort *>::iterator i = publishedOutputPorts.begin(); i != publishedOutputPorts.end(); ++i)
2079 s <<
"{" << (*i)->getCompiler() <<
"," << (*i)->getClass()->getName() <<
"},";
2085 if (manuallyFirableInputPort)
2105 return "ManuallyFirableTrigger";
2113 this->fromNode = NULL;
2114 this->fromTrigger = fromTrigger;
2115 this->toNode = toNode;
2123 this->fromTrigger = NULL;
2124 this->fromNode = fromNode;
2125 this->toNode = toNode;
2131 VuoCompilerGraph::Vertex::Vertex(
void)
2133 this->fromNode = NULL;
2134 this->fromTrigger = NULL;
2135 this->toNode = NULL;
2141 VuoCompilerGraph::Edge::Edge(
const VuoCompilerGraph::Vertex &fromVertex,
const VuoCompilerGraph::Vertex &toVertex)
2142 : fromVertex(fromVertex), toVertex(toVertex)
2149 VuoCompilerGraph::Edge::Edge(
void)
2156 bool operator==(
const VuoCompilerGraph::Vertex &lhs,
const VuoCompilerGraph::Vertex &rhs)
2158 return (lhs.fromTrigger == rhs.fromTrigger && lhs.fromNode == rhs.fromNode && lhs.toNode == rhs.toNode);
2164 bool operator!=(
const VuoCompilerGraph::Vertex &lhs,
const VuoCompilerGraph::Vertex &rhs)
2166 return ! (lhs == rhs);
2172 bool operator<(
const VuoCompilerGraph::Vertex &lhs,
const VuoCompilerGraph::Vertex &rhs)
2174 return (lhs.fromTrigger != rhs.fromTrigger ?
2175 lhs.fromTrigger < rhs.fromTrigger :
2176 (lhs.fromNode != rhs.fromNode ?
2177 lhs.fromNode < rhs.fromNode :
2178 lhs.toNode < rhs.toNode));
2184 bool operator<(
const VuoCompilerGraph::Edge &lhs,
const VuoCompilerGraph::Edge &rhs)
2186 return (lhs.fromVertex != rhs.fromVertex ?
2187 lhs.fromVertex < rhs.fromVertex :
2188 lhs.toVertex < rhs.toVertex);
2194 string VuoCompilerGraph::Vertex::toString(
void)
const
2205 string VuoCompilerGraph::Edge::toString(
void)
const
2207 return fromVertex.toString() +
" -> " + toVertex.toString();