diff --git a/src/gui/util/qshadergraph.cpp b/src/gui/util/qshadergraph.cpp index 779e63b5c2d..45bf6429cd9 100644 --- a/src/gui/util/qshadergraph.cpp +++ b/src/gui/util/qshadergraph.cpp @@ -123,6 +123,50 @@ namespace } return targetStatement; } + + void removeNodesWithUnboundInputs(QVector &statements, + const QVector &allEdges) + { + // A node is invalid if any of its input ports is disconected + // or connected to the output port of another invalid node. + + // Keeps track of the edges from the nodes we know to be valid + // to unvisited nodes + auto currentEdges = QVector(); + + statements.erase(std::remove_if(statements.begin(), + statements.end(), + [¤tEdges, &allEdges] (const QShaderGraph::Statement &statement) { + const QShaderNode &node = statement.node; + const QVector outgoing = outgoingEdges(currentEdges, node.uuid()); + const QVector ports = node.ports(); + + bool allInputsConnected = true; + for (const QShaderNodePort &port : node.ports()) { + if (port.direction == QShaderNodePort::Output) + continue; + + const auto edgeIt = std::find_if(outgoing.cbegin(), + outgoing.cend(), + [&port] (const QShaderGraph::Edge &edge) { + return edge.targetPortName == port.name; + }); + + if (edgeIt != outgoing.cend()) + currentEdges.removeAll(*edgeIt); + else + allInputsConnected = false; + } + + if (allInputsConnected) { + const QVector incoming = incomingEdges(allEdges, node.uuid()); + currentEdges.append(incoming); + } + + return !allInputsConnected; + }), + statements.end()); + } } QUuid QShaderGraph::Statement::uuid() const Q_DECL_NOTHROW @@ -248,6 +292,9 @@ QVector QShaderGraph::createStatements(const QStringLis } std::reverse(result.begin(), result.end()); + + removeNodesWithUnboundInputs(result, enabledEdges); + return result; } diff --git a/tests/auto/gui/util/qshadergraph/tst_qshadergraph.cpp b/tests/auto/gui/util/qshadergraph/tst_qshadergraph.cpp index 50c925a1111..014a163f587 100644 --- a/tests/auto/gui/util/qshadergraph/tst_qshadergraph.cpp +++ b/tests/auto/gui/util/qshadergraph/tst_qshadergraph.cpp @@ -516,12 +516,9 @@ void tst_QShaderGraph::shouldHandleUnboundPortsDuringGraphSerialization() const auto statements = graph.createStatements(); // THEN - // Note that no edge leads to the unbound input + // Note that no statement has any unbound input const auto expected = QVector() - << createStatement(input, {}, {0}) - << createStatement(function, {-1, 0, -1}, {2, 3, 4}) - << createStatement(unboundOutput, {-1}, {}) - << createStatement(output, {3}, {}); + << createStatement(input, {}, {0}); dumpStatementsIfNeeded(statements, expected); QCOMPARE(statements, expected); } @@ -568,9 +565,8 @@ void tst_QShaderGraph::shouldSurviveCyclesDuringGraphSerialization() const auto statements = graph.createStatements(); // THEN - // Obviously will lead to a compile failure later on since it cuts everything beyond the cycle - const auto expected = QVector() - << createStatement(output, {2}, {}); + // The cycle is ignored + const auto expected = QVector(); dumpStatementsIfNeeded(statements, expected); QCOMPARE(statements, expected); }