diff --git a/modules/visual_script/visual_script.cpp b/modules/visual_script/visual_script.cpp index ab2a12bcb47..1a2f8458fe8 100644 --- a/modules/visual_script/visual_script.cpp +++ b/modules/visual_script/visual_script.cpp @@ -34,6 +34,7 @@ #include "core/os/os.h" #include "core/project_settings.h" #include "scene/main/node.h" +#include "visual_script_func_nodes.h" #include "visual_script_nodes.h" //used by editor, this is not really saved @@ -291,80 +292,113 @@ void VisualScript::_node_ports_changed(int p_id) { #endif } -void VisualScript::add_node(const StringName &p_func, int p_id, const Ref &p_node, const Point2 &p_pos) { +void VisualScript::add_node(const StringName &p_name, int p_id, const Ref &p_node, const Point2 &p_pos) { ERR_FAIL_COND(instances.size()); - ERR_FAIL_COND(!functions.has(p_func)); ERR_FAIL_COND(p_node.is_null()); - for (Map::Element *E = functions.front(); E; E = E->next()) { - ERR_FAIL_COND(E->get().nodes.has(p_id)); //id can exist only one in script, even for different functions + StringName var_name; + if (Object::cast_to(*p_node)) { + Ref vget = p_node; + var_name = vget->get_variable(); + } else if (Object::cast_to(*p_node)) { + Ref vset = p_node; + var_name = vset->get_variable(); + } + if (variables.has(var_name)) { + for (Map::Element *E = variables.front(); E; E = E->next()) { + ERR_FAIL_COND(E->get().nodes.has(p_id)); // Only unique ids can exist in a script, even for different functions + } + + Variable &var = variables[var_name]; + var.nodes[p_id] = p_node; } - Function &func = functions[p_func]; + if (functions.has(p_name)) { + for (Map::Element *E = functions.front(); E; E = E->next()) { + ERR_FAIL_COND(E->get().nodes.has(p_id)); // Only unique id can exist in a script, even for different functions + } - if (Object::cast_to(*p_node)) { - //the function indeed - ERR_FAIL_COND_MSG(func.function_id >= 0, "A function node has already been set here."); + Function &func = functions[p_name]; + if (Object::cast_to(*p_node)) { + // The function indeed + ERR_FAIL_COND_MSG(func.function_id >= 0, "A function node has already been set here."); - func.function_id = p_id; + func.function_id = p_id; + } + + Function::NodeData nd; + nd.node = p_node; + nd.pos = p_pos; + func.nodes[p_id] = nd; } - Function::NodeData nd; - nd.node = p_node; - nd.pos = p_pos; - Ref vsn = p_node; vsn->connect("ports_changed", this, "_node_ports_changed", varray(p_id)); vsn->scripts_used.insert(this); vsn->validate_input_default_values(); // Validate when fully loaded - - func.nodes[p_id] = nd; } -void VisualScript::remove_node(const StringName &p_func, int p_id) { +void VisualScript::remove_node(const StringName &p_name, int p_id) { ERR_FAIL_COND(instances.size()); - ERR_FAIL_COND(!functions.has(p_func)); - Function &func = functions[p_func]; - ERR_FAIL_COND(!func.nodes.has(p_id)); - { - List to_remove; + if (functions.has(p_name)) { + Function &func = functions[p_name]; + if (func.nodes.has(p_id)) { + { + List to_remove; - for (Set::Element *E = func.sequence_connections.front(); E; E = E->next()) { - if (E->get().from_node == p_id || E->get().to_node == p_id) { - to_remove.push_back(E->get()); + for (Set::Element *E = func.sequence_connections.front(); E; E = E->next()) { + if (E->get().from_node == p_id || E->get().to_node == p_id) { + to_remove.push_back(E->get()); + } + } + + while (to_remove.size()) { + func.sequence_connections.erase(to_remove.front()->get()); + to_remove.pop_front(); + } } - } - while (to_remove.size()) { - func.sequence_connections.erase(to_remove.front()->get()); - to_remove.pop_front(); - } - } + { + List to_remove; - { - List to_remove; + for (Set::Element *E = func.data_connections.front(); E; E = E->next()) { + if (E->get().from_node == p_id || E->get().to_node == p_id) { + to_remove.push_back(E->get()); + } + } - for (Set::Element *E = func.data_connections.front(); E; E = E->next()) { - if (E->get().from_node == p_id || E->get().to_node == p_id) { - to_remove.push_back(E->get()); + while (to_remove.size()) { + func.data_connections.erase(to_remove.front()->get()); + to_remove.pop_front(); + } } - } - while (to_remove.size()) { - func.data_connections.erase(to_remove.front()->get()); - to_remove.pop_front(); + if (Object::cast_to(func.nodes[p_id].node.ptr())) { + func.function_id = -1; // Revert to invalid + } + + { + StringName var_name; + if (Object::cast_to(*func.nodes[p_id].node)) { + Ref vget = func.nodes[p_id].node; + var_name = vget->get_variable(); + } else if (Object::cast_to(*func.nodes[p_id].node)) { + Ref vset = func.nodes[p_id].node; + var_name = vset->get_variable(); + } + + if (variables.has(var_name)) { + variables[var_name].nodes.erase(p_id); + } + } + + func.nodes[p_id].node->disconnect("ports_changed", this, "_node_ports_changed"); + func.nodes[p_id].node->scripts_used.erase(this); + + func.nodes.erase(p_id); } } - - if (Object::cast_to(func.nodes[p_id].node.ptr())) { - func.function_id = -1; //revert to invalid - } - - func.nodes[p_id].node->disconnect("ports_changed", this, "_node_ports_changed"); - func.nodes[p_id].node->scripts_used.erase(this); - - func.nodes.erase(p_id); } bool VisualScript::has_node(const StringName &p_func, int p_id) const { @@ -374,13 +408,22 @@ bool VisualScript::has_node(const StringName &p_func, int p_id) const { return func.nodes.has(p_id); } -Ref VisualScript::get_node(const StringName &p_func, int p_id) const { - ERR_FAIL_COND_V(!functions.has(p_func), Ref()); - const Function &func = functions[p_func]; +Ref VisualScript::get_node(const StringName &p_name, int p_id) const { + if (functions.has(p_name)) { + const Function &func = functions[p_name]; + if (func.nodes.has(p_id)) { + return func.nodes[p_id].node; + } + } - ERR_FAIL_COND_V(!func.nodes.has(p_id), Ref()); + if (variables.has(p_name)) { + const Variable &var = variables[p_name]; + if (var.nodes.has(p_id)) { + return var.nodes[p_id]; + } + } - return func.nodes[p_id].node; + return Ref(); } void VisualScript::set_node_position(const StringName &p_func, int p_id, const Point2 &p_pos) { @@ -401,11 +444,18 @@ Point2 VisualScript::get_node_position(const StringName &p_func, int p_id) const } void VisualScript::get_node_list(const StringName &p_func, List *r_nodes) const { - ERR_FAIL_COND(!functions.has(p_func)); - const Function &func = functions[p_func]; + if (functions.has(p_func)) { + const Function &func = functions[p_func]; + for (const Map::Element *E = func.nodes.front(); E; E = E->next()) { + r_nodes->push_back(E->key()); + } + } - for (const Map::Element *E = func.nodes.front(); E; E = E->next()) { - r_nodes->push_back(E->key()); + if (variables.has(p_func)) { + const Variable &var = variables[p_func]; + for (const Map>::Element *E = var.nodes.front(); E; E = E->next()) { + r_nodes->push_back(E->key()); + } } } diff --git a/modules/visual_script/visual_script.h b/modules/visual_script/visual_script.h index 88535ab87b6..8755035d4d0 100644 --- a/modules/visual_script/visual_script.h +++ b/modules/visual_script/visual_script.h @@ -228,6 +228,7 @@ private: }; struct Variable { + Map> nodes; PropertyInfo info; Variant default_value; bool _export; diff --git a/modules/visual_script/visual_script_editor.cpp b/modules/visual_script/visual_script_editor.cpp index 5b8f5cadc92..ee284dea7b1 100644 --- a/modules/visual_script/visual_script_editor.cpp +++ b/modules/visual_script/visual_script_editor.cpp @@ -1253,8 +1253,32 @@ void VisualScriptEditor::_member_edited() { undo_redo->create_action(TTR("Rename Variable")); undo_redo->add_do_method(script.ptr(), "rename_variable", name, new_name); undo_redo->add_undo_method(script.ptr(), "rename_variable", new_name, name); + + // also fix all variable setter & getter calls + List vlst; + script->get_variable_list(&vlst); + for (List::Element *E = vlst.front(); E; E = E->next()) { + List lst; + script->get_node_list(E->get(), &lst); + for (List::Element *F = lst.front(); F; F = F->next()) { + Ref vget = script->get_node(E->get(), F->get()); + if (vget.is_valid() && vget->get_variable() == name) { + undo_redo->add_do_method(vget.ptr(), "set_variable", new_name); + undo_redo->add_undo_method(vget.ptr(), "set_variable", name); + } + + Ref vset = script->get_node(E->get(), F->get()); + if (vset.is_valid() && vset->get_variable() == name) { + undo_redo->add_do_method(vset.ptr(), "set_variable", new_name); + undo_redo->add_undo_method(vset.ptr(), "set_variable", name); + } + } + } + undo_redo->add_do_method(this, "_update_members"); undo_redo->add_undo_method(this, "_update_members"); + undo_redo->add_do_method(this, "_update_graph"); + undo_redo->add_undo_method(this, "_update_graph"); undo_redo->add_do_method(this, "emit_signal", "edited_script_changed"); undo_redo->add_undo_method(this, "emit_signal", "edited_script_changed"); undo_redo->commit_action();