Merge pull request #35362 from Chaosus/fix_vs_recursion
Forbid recursive connections in visual shader
This commit is contained in:
commit
fa638a290f
2 changed files with 33 additions and 0 deletions
|
@ -378,6 +378,9 @@ void VisualShader::remove_node(Type p_type, int p_id) {
|
||||||
List<Connection>::Element *N = E->next();
|
List<Connection>::Element *N = E->next();
|
||||||
if (E->get().from_node == p_id || E->get().to_node == p_id) {
|
if (E->get().from_node == p_id || E->get().to_node == p_id) {
|
||||||
g->connections.erase(E);
|
g->connections.erase(E);
|
||||||
|
if (E->get().from_node == p_id) {
|
||||||
|
g->nodes[E->get().to_node].prev_connected_nodes.erase(p_id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
E = N;
|
E = N;
|
||||||
}
|
}
|
||||||
|
@ -399,6 +402,25 @@ bool VisualShader::is_node_connection(Type p_type, int p_from_node, int p_from_p
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool VisualShader::is_nodes_connected_relatively(const Graph *p_graph, int p_node, int p_target) const {
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
const VisualShader::Node &node = p_graph->nodes[p_node];
|
||||||
|
|
||||||
|
for (const List<int>::Element *E = node.prev_connected_nodes.front(); E; E = E->next()) {
|
||||||
|
|
||||||
|
if (E->get() == p_target) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = is_nodes_connected_relatively(p_graph, E->get(), p_target);
|
||||||
|
if (result) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
bool VisualShader::can_connect_nodes(Type p_type, int p_from_node, int p_from_port, int p_to_node, int p_to_port) const {
|
bool VisualShader::can_connect_nodes(Type p_type, int p_from_node, int p_from_port, int p_to_node, int p_to_port) const {
|
||||||
|
|
||||||
ERR_FAIL_INDEX_V(p_type, TYPE_MAX, false);
|
ERR_FAIL_INDEX_V(p_type, TYPE_MAX, false);
|
||||||
|
@ -433,6 +455,9 @@ bool VisualShader::can_connect_nodes(Type p_type, int p_from_node, int p_from_po
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (is_nodes_connected_relatively(g, p_from_node, p_to_node))
|
||||||
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -449,6 +474,8 @@ void VisualShader::connect_nodes_forced(Type p_type, int p_from_node, int p_from
|
||||||
c.to_node = p_to_node;
|
c.to_node = p_to_node;
|
||||||
c.to_port = p_to_port;
|
c.to_port = p_to_port;
|
||||||
g->connections.push_back(c);
|
g->connections.push_back(c);
|
||||||
|
g->nodes[p_to_node].prev_connected_nodes.push_back(p_from_node);
|
||||||
|
|
||||||
_queue_update();
|
_queue_update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -479,6 +506,7 @@ Error VisualShader::connect_nodes(Type p_type, int p_from_node, int p_from_port,
|
||||||
c.to_node = p_to_node;
|
c.to_node = p_to_node;
|
||||||
c.to_port = p_to_port;
|
c.to_port = p_to_port;
|
||||||
g->connections.push_back(c);
|
g->connections.push_back(c);
|
||||||
|
g->nodes[p_to_node].prev_connected_nodes.push_back(p_from_node);
|
||||||
|
|
||||||
_queue_update();
|
_queue_update();
|
||||||
return OK;
|
return OK;
|
||||||
|
@ -492,6 +520,7 @@ void VisualShader::disconnect_nodes(Type p_type, int p_from_node, int p_from_por
|
||||||
|
|
||||||
if (E->get().from_node == p_from_node && E->get().from_port == p_from_port && E->get().to_node == p_to_node && E->get().to_port == p_to_port) {
|
if (E->get().from_node == p_from_node && E->get().from_port == p_from_port && E->get().to_node == p_to_node && E->get().to_port == p_to_port) {
|
||||||
g->connections.erase(E);
|
g->connections.erase(E);
|
||||||
|
g->nodes[p_to_node].prev_connected_nodes.erase(p_from_node);
|
||||||
_queue_update();
|
_queue_update();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1326,6 +1355,7 @@ void VisualShader::_input_type_changed(Type p_type, int p_id) {
|
||||||
List<Connection>::Element *N = E->next();
|
List<Connection>::Element *N = E->next();
|
||||||
if (E->get().from_node == p_id) {
|
if (E->get().from_node == p_id) {
|
||||||
g->connections.erase(E);
|
g->connections.erase(E);
|
||||||
|
g->nodes[E->get().to_node].prev_connected_nodes.erase(p_id);
|
||||||
}
|
}
|
||||||
E = N;
|
E = N;
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,6 +65,7 @@ private:
|
||||||
struct Node {
|
struct Node {
|
||||||
Ref<VisualShaderNode> node;
|
Ref<VisualShaderNode> node;
|
||||||
Vector2 position;
|
Vector2 position;
|
||||||
|
List<int> prev_connected_nodes;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Graph {
|
struct Graph {
|
||||||
|
@ -135,6 +136,8 @@ public:
|
||||||
void remove_node(Type p_type, int p_id);
|
void remove_node(Type p_type, int p_id);
|
||||||
|
|
||||||
bool is_node_connection(Type p_type, int p_from_node, int p_from_port, int p_to_node, int p_to_port) const;
|
bool is_node_connection(Type p_type, int p_from_node, int p_from_port, int p_to_node, int p_to_port) const;
|
||||||
|
|
||||||
|
bool is_nodes_connected_relatively(const Graph *p_graph, int p_node, int p_target) const;
|
||||||
bool can_connect_nodes(Type p_type, int p_from_node, int p_from_port, int p_to_node, int p_to_port) const;
|
bool can_connect_nodes(Type p_type, int p_from_node, int p_from_port, int p_to_node, int p_to_port) const;
|
||||||
Error connect_nodes(Type p_type, int p_from_node, int p_from_port, int p_to_node, int p_to_port);
|
Error connect_nodes(Type p_type, int p_from_node, int p_from_port, int p_to_node, int p_to_port);
|
||||||
void disconnect_nodes(Type p_type, int p_from_node, int p_from_port, int p_to_node, int p_to_port);
|
void disconnect_nodes(Type p_type, int p_from_node, int p_from_port, int p_to_node, int p_to_port);
|
||||||
|
|
Loading…
Reference in a new issue