Skip to content

Commit

Permalink
[VisualShader] Remove invalid graph connections when ports are removed
Browse files Browse the repository at this point in the history
Co-authored-by: EddieBreeg <[email protected]>
  • Loading branch information
Geometror and EddieBreeg committed Apr 8, 2024
1 parent fe01776 commit 0b9b479
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 3 deletions.
35 changes: 32 additions & 3 deletions editor/plugins/visual_shader_editor_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6747,8 +6747,35 @@ class VisualShaderNodePluginDefaultEditor : public VBoxContainer {
undo_redo->add_do_property(node.ptr(), p_property, p_value);
undo_redo->add_undo_property(node.ptr(), p_property, node->get(p_property));

Ref<VisualShaderNode> vsnode = editor->get_visual_shader()->get_node(shader_type, node_id);
ERR_FAIL_COND(vsnode.is_null());

// Check for invalid connections due to removed ports.
// We need to know the new state of the node to generate the proper undo/redo instructions.
// Quite hacky but the best way I could come up with for now.
Ref<VisualShaderNode> vsnode_new = vsnode->duplicate();
vsnode_new->set(p_property, p_value);
const int input_port_count = vsnode_new->get_input_port_count();
const int output_port_count = vsnode_new->get_output_port_count();

List<VisualShader::Connection> conns;
editor->get_visual_shader()->get_node_connections(shader_type, &conns);
VisualShaderGraphPlugin *graph_plugin = editor->get_graph_plugin();
bool undo_node_already_updated = false;
for (const VisualShader::Connection &c : conns) {
if ((c.from_node == node_id && c.from_port >= output_port_count) || (c.to_node == node_id && c.to_port >= input_port_count)) {
undo_redo->add_do_method(editor->get_visual_shader().ptr(), "disconnect_nodes", shader_type, c.from_node, c.from_port, c.to_node, c.to_port);
undo_redo->add_do_method(graph_plugin, "disconnect_nodes", shader_type, c.from_node, c.from_port, c.to_node, c.to_port);
// We need to update the node before reconnecting to avoid accessing a non-existing port.
undo_redo->add_undo_method(graph_plugin, "update_node_deferred", shader_type, node_id);
undo_node_already_updated = true;
undo_redo->add_undo_method(editor->get_visual_shader().ptr(), "connect_nodes", shader_type, c.from_node, c.from_port, c.to_node, c.to_port);
undo_redo->add_undo_method(graph_plugin, "connect_nodes", shader_type, c.from_node, c.from_port, c.to_node, c.to_port);
}
}

if (p_value.get_type() == Variant::OBJECT) {
Ref<Resource> prev_res = node->get(p_property);
Ref<Resource> prev_res = vsnode->get(p_property);
Ref<Resource> curr_res = p_value;

if (curr_res.is_null()) {
Expand All @@ -6763,14 +6790,16 @@ class VisualShaderNodePluginDefaultEditor : public VBoxContainer {
}
}
if (p_property != "constant") {
VisualShaderGraphPlugin *graph_plugin = editor->get_graph_plugin();
if (graph_plugin) {
undo_redo->add_do_method(editor, "_update_next_previews", node_id);
undo_redo->add_undo_method(editor, "_update_next_previews", node_id);
undo_redo->add_do_method(graph_plugin, "update_node_deferred", shader_type, node_id);
undo_redo->add_undo_method(graph_plugin, "update_node_deferred", shader_type, node_id);
if (!undo_node_already_updated) {
undo_redo->add_undo_method(graph_plugin, "update_node_deferred", shader_type, node_id);
}
}
}

undo_redo->commit_action();

updating = false;
Expand Down
3 changes: 3 additions & 0 deletions editor/plugins/visual_shader_editor_plugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -555,7 +555,10 @@ class VisualShaderEditor : public VBoxContainer {
void update_custom_type(const Ref<Resource> &p_resource);

virtual Size2 get_minimum_size() const override;

void edit(VisualShader *p_visual_shader);
Ref<VisualShader> get_visual_shader() const { return visual_shader; }

VisualShaderEditor();
};

Expand Down

0 comments on commit 0b9b479

Please sign in to comment.