diff options
Diffstat (limited to 'modules/visual_script/visual_script.cpp')
-rw-r--r-- | modules/visual_script/visual_script.cpp | 1087 |
1 files changed, 490 insertions, 597 deletions
diff --git a/modules/visual_script/visual_script.cpp b/modules/visual_script/visual_script.cpp index b10d4523f2..fe92f59179 100644 --- a/modules/visual_script/visual_script.cpp +++ b/modules/visual_script/visual_script.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -36,7 +36,7 @@ #include "scene/main/node.h" #include "visual_script_nodes.h" -//used by editor, this is not really saved +// Used by editor, this is not really saved. void VisualScriptNode::set_breakpoint(bool p_breakpoint) { breakpoint = p_breakpoint; } @@ -55,8 +55,8 @@ void VisualScriptNode::set_default_input_value(int p_port, const Variant &p_valu default_input_values[p_port] = p_value; #ifdef TOOLS_ENABLED - for (Set<VisualScript *>::Element *E = scripts_used.front(); E; E = E->next()) { - E->get()->set_edited(true); + if (script_used.is_valid()) { + script_used->set_edited(true); } #endif } @@ -73,14 +73,14 @@ void VisualScriptNode::_set_default_input_values(Array p_values) { void VisualScriptNode::validate_input_default_values() { default_input_values.resize(MAX(default_input_values.size(), get_input_value_port_count())); //let it grow as big as possible, we don't want to lose values on resize - //actually validate on save + // Actually validate on save. for (int i = 0; i < get_input_value_port_count(); i++) { Variant::Type expected = get_input_value_port_info(i).type; if (expected == Variant::NIL || expected == default_input_values[i].get_type()) { continue; } else { - //not the same, reconvert + // Not the same, reconvert. Callable::CallError ce; Variant existing = default_input_values[i]; const Variant *existingp = &existing; @@ -94,7 +94,7 @@ void VisualScriptNode::validate_input_default_values() { } Array VisualScriptNode::_get_default_input_values() const { - //validate on save, since on load there is little info about this + // Validate on save, since on load there is little info about this. Array values = default_input_values; values.resize(get_input_value_port_count()); @@ -118,6 +118,8 @@ void VisualScriptNode::_bind_methods() { } VisualScriptNode::TypeGuess VisualScriptNode::guess_output_type(TypeGuess *p_inputs, int p_output) const { + ERR_FAIL_COND_V(get_output_value_port_count() <= p_output, TypeGuess()); + PropertyInfo pinfo = get_output_value_port_info(p_output); TypeGuess tg; @@ -131,11 +133,7 @@ VisualScriptNode::TypeGuess VisualScriptNode::guess_output_type(TypeGuess *p_inp } Ref<VisualScript> VisualScriptNode::get_visual_script() const { - if (scripts_used.size()) { - return Ref<VisualScript>(scripts_used.front()->get()); - } - - return Ref<VisualScript>(); + return script_used; } VisualScriptNode::VisualScriptNode() { @@ -165,13 +163,15 @@ VisualScriptNodeInstance::~VisualScriptNodeInstance() { } } -void VisualScript::add_function(const StringName &p_name) { +void VisualScript::add_function(const StringName &p_name, int p_func_node_id) { ERR_FAIL_COND(instances.size()); ERR_FAIL_COND(!String(p_name).is_valid_identifier()); ERR_FAIL_COND(functions.has(p_name)); + ERR_FAIL_COND(variables.has(p_name)); + ERR_FAIL_COND(custom_signals.has(p_name)); functions[p_name] = Function(); - functions[p_name].scroll = Vector2(-50, -100); + functions[p_name].func_id = p_func_node_id; } bool VisualScript::has_function(const StringName &p_name) const { @@ -182,11 +182,7 @@ void VisualScript::remove_function(const StringName &p_name) { ERR_FAIL_COND(instances.size()); ERR_FAIL_COND(!functions.has(p_name)); - for (Map<int, Function::NodeData>::Element *E = functions[p_name].nodes.front(); E; E = E->next()) { - E->get().node->disconnect("ports_changed", callable_mp(this, &VisualScript::_node_ports_changed)); - E->get().node->scripts_used.erase(this); - } - + // Let the editor handle the node removal. functions.erase(p_name); } @@ -207,53 +203,36 @@ void VisualScript::rename_function(const StringName &p_name, const StringName &p functions.erase(p_name); } -void VisualScript::set_function_scroll(const StringName &p_name, const Vector2 &p_scroll) { - ERR_FAIL_COND(!functions.has(p_name)); - functions[p_name].scroll = p_scroll; +void VisualScript::set_scroll(const Vector2 &p_scroll) { + scroll = p_scroll; } -Vector2 VisualScript::get_function_scroll(const StringName &p_name) const { - ERR_FAIL_COND_V(!functions.has(p_name), Vector2()); - return functions[p_name].scroll; +Vector2 VisualScript::get_scroll() const { + return scroll; } void VisualScript::get_function_list(List<StringName> *r_functions) const { - for (const Map<StringName, Function>::Element *E = functions.front(); E; E = E->next()) { - r_functions->push_back(E->key()); - } - - r_functions->sort_custom<StringName::AlphCompare>(); + functions.get_key_list(r_functions); + // r_functions->sort_custom<StringName::AlphCompare>(); // Don't force sorting. } int VisualScript::get_function_node_id(const StringName &p_name) const { ERR_FAIL_COND_V(!functions.has(p_name), -1); - return functions[p_name].function_id; + return functions[p_name].func_id; } void VisualScript::_node_ports_changed(int p_id) { - StringName function; - - for (Map<StringName, Function>::Element *E = functions.front(); E; E = E->next()) { - if (E->get().nodes.has(p_id)) { - function = E->key(); - break; - } - } - - ERR_FAIL_COND(function == StringName()); - - Function &func = functions[function]; - Ref<VisualScriptNode> vsn = func.nodes[p_id].node; + Ref<VisualScriptNode> vsn = nodes[p_id].node; vsn->validate_input_default_values(); - //must revalidate all the functions + // Must revalidate all the functions. { List<SequenceConnection> to_remove; - for (Set<SequenceConnection>::Element *E = func.sequence_connections.front(); E; E = E->next()) { + for (Set<SequenceConnection>::Element *E = sequence_connections.front(); E; E = E->next()) { if (E->get().from_node == p_id && E->get().from_output >= vsn->get_output_sequence_port_count()) { to_remove.push_back(E->get()); } @@ -263,7 +242,7 @@ void VisualScript::_node_ports_changed(int p_id) { } while (to_remove.size()) { - func.sequence_connections.erase(to_remove.front()->get()); + sequence_connections.erase(to_remove.front()->get()); to_remove.pop_front(); } } @@ -271,7 +250,7 @@ void VisualScript::_node_ports_changed(int p_id) { { List<DataConnection> to_remove; - for (Set<DataConnection>::Element *E = func.data_connections.front(); E; E = E->next()) { + for (Set<DataConnection>::Element *E = data_connections.front(); E; E = E->next()) { if (E->get().from_node == p_id && E->get().from_port >= vsn->get_output_value_port_count()) { to_remove.push_back(E->get()); } @@ -281,63 +260,47 @@ void VisualScript::_node_ports_changed(int p_id) { } while (to_remove.size()) { - func.data_connections.erase(to_remove.front()->get()); + data_connections.erase(to_remove.front()->get()); to_remove.pop_front(); } } #ifdef TOOLS_ENABLED - set_edited(true); //something changed, let's set as edited - emit_signal("node_ports_changed", function, p_id); + set_edited(true); // Something changed, let's set as edited. + emit_signal("node_ports_changed", p_id); #endif } -void VisualScript::add_node(const StringName &p_func, int p_id, const Ref<VisualScriptNode> &p_node, const Point2 &p_pos) { +void VisualScript::add_node(int p_id, const Ref<VisualScriptNode> &p_node, const Point2 &p_pos) { ERR_FAIL_COND(instances.size()); - ERR_FAIL_COND(!functions.has(p_func)); - - for (Map<StringName, Function>::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 - } + ERR_FAIL_COND(nodes.has(p_id)); // ID can exist only one in script. - Function &func = functions[p_func]; - - if (Object::cast_to<VisualScriptFunction>(*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; - } - - Function::NodeData nd; + NodeData nd; nd.node = p_node; nd.pos = p_pos; Ref<VisualScriptNode> vsn = p_node; vsn->connect("ports_changed", callable_mp(this, &VisualScript::_node_ports_changed), varray(p_id)); - vsn->scripts_used.insert(this); - vsn->validate_input_default_values(); // Validate when fully loaded + vsn->script_used = Ref<VisualScript>(this); + vsn->validate_input_default_values(); // Validate when fully loaded. - func.nodes[p_id] = nd; + nodes[p_id] = nd; } -void VisualScript::remove_node(const StringName &p_func, int p_id) { +void VisualScript::remove_node(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)); + ERR_FAIL_COND(!nodes.has(p_id)); { List<SequenceConnection> to_remove; - for (Set<SequenceConnection>::Element *E = func.sequence_connections.front(); E; E = E->next()) { + for (Set<SequenceConnection>::Element *E = 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()); + sequence_connections.erase(to_remove.front()->get()); to_remove.pop_front(); } } @@ -345,122 +308,88 @@ void VisualScript::remove_node(const StringName &p_func, int p_id) { { List<DataConnection> to_remove; - for (Set<DataConnection>::Element *E = func.data_connections.front(); E; E = E->next()) { + for (Set<DataConnection>::Element *E = 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()); + data_connections.erase(to_remove.front()->get()); to_remove.pop_front(); } } - if (Object::cast_to<VisualScriptFunction>(func.nodes[p_id].node.ptr())) { - func.function_id = -1; //revert to invalid - } + nodes[p_id].node->disconnect("ports_changed", callable_mp(this, &VisualScript::_node_ports_changed)); + nodes[p_id].node->script_used.unref(); - func.nodes[p_id].node->disconnect("ports_changed", callable_mp(this, &VisualScript::_node_ports_changed)); - func.nodes[p_id].node->scripts_used.erase(this); - - func.nodes.erase(p_id); + nodes.erase(p_id); } -bool VisualScript::has_node(const StringName &p_func, int p_id) const { - ERR_FAIL_COND_V(!functions.has(p_func), false); - const Function &func = functions[p_func]; - - return func.nodes.has(p_id); +bool VisualScript::has_node(int p_id) const { + return nodes.has(p_id); } -Ref<VisualScriptNode> VisualScript::get_node(const StringName &p_func, int p_id) const { - ERR_FAIL_COND_V(!functions.has(p_func), Ref<VisualScriptNode>()); - const Function &func = functions[p_func]; - - ERR_FAIL_COND_V(!func.nodes.has(p_id), Ref<VisualScriptNode>()); +Ref<VisualScriptNode> VisualScript::get_node(int p_id) const { + ERR_FAIL_COND_V(!nodes.has(p_id), Ref<VisualScriptNode>()); - return func.nodes[p_id].node; + return nodes[p_id].node; } -void VisualScript::set_node_position(const StringName &p_func, int p_id, const Point2 &p_pos) { +void VisualScript::set_node_position(int p_id, const Point2 &p_pos) { 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)); - func.nodes[p_id].pos = p_pos; + ERR_FAIL_COND(!nodes.has(p_id)); + nodes[p_id].pos = p_pos; } -Point2 VisualScript::get_node_position(const StringName &p_func, int p_id) const { - ERR_FAIL_COND_V(!functions.has(p_func), Point2()); - const Function &func = functions[p_func]; - - ERR_FAIL_COND_V(!func.nodes.has(p_id), Point2()); - return func.nodes[p_id].pos; +Point2 VisualScript::get_node_position(int p_id) const { + ERR_FAIL_COND_V(!nodes.has(p_id), Point2()); + return nodes[p_id].pos; } -void VisualScript::get_node_list(const StringName &p_func, List<int> *r_nodes) const { - ERR_FAIL_COND(!functions.has(p_func)); - const Function &func = functions[p_func]; - - for (const Map<int, Function::NodeData>::Element *E = func.nodes.front(); E; E = E->next()) { - r_nodes->push_back(E->key()); - } +void VisualScript::get_node_list(List<int> *r_nodes) const { + nodes.get_key_list(r_nodes); } -void VisualScript::sequence_connect(const StringName &p_func, int p_from_node, int p_from_output, int p_to_node) { +void VisualScript::sequence_connect(int p_from_node, int p_from_output, int p_to_node) { ERR_FAIL_COND(instances.size()); - ERR_FAIL_COND(!functions.has(p_func)); - Function &func = functions[p_func]; SequenceConnection sc; sc.from_node = p_from_node; sc.from_output = p_from_output; sc.to_node = p_to_node; - ERR_FAIL_COND(func.sequence_connections.has(sc)); + ERR_FAIL_COND(sequence_connections.has(sc)); - func.sequence_connections.insert(sc); + sequence_connections.insert(sc); } -void VisualScript::sequence_disconnect(const StringName &p_func, int p_from_node, int p_from_output, int p_to_node) { - ERR_FAIL_COND(!functions.has(p_func)); - Function &func = functions[p_func]; - +void VisualScript::sequence_disconnect(int p_from_node, int p_from_output, int p_to_node) { SequenceConnection sc; sc.from_node = p_from_node; sc.from_output = p_from_output; sc.to_node = p_to_node; - ERR_FAIL_COND(!func.sequence_connections.has(sc)); + ERR_FAIL_COND(!sequence_connections.has(sc)); - func.sequence_connections.erase(sc); + sequence_connections.erase(sc); } -bool VisualScript::has_sequence_connection(const StringName &p_func, int p_from_node, int p_from_output, int p_to_node) const { - ERR_FAIL_COND_V(!functions.has(p_func), false); - const Function &func = functions[p_func]; - +bool VisualScript::has_sequence_connection(int p_from_node, int p_from_output, int p_to_node) const { SequenceConnection sc; sc.from_node = p_from_node; sc.from_output = p_from_output; sc.to_node = p_to_node; - return func.sequence_connections.has(sc); + return sequence_connections.has(sc); } -void VisualScript::get_sequence_connection_list(const StringName &p_func, List<SequenceConnection> *r_connection) const { - ERR_FAIL_COND(!functions.has(p_func)); - const Function &func = functions[p_func]; - - for (const Set<SequenceConnection>::Element *E = func.sequence_connections.front(); E; E = E->next()) { +void VisualScript::get_sequence_connection_list(List<SequenceConnection> *r_connection) const { + for (const Set<SequenceConnection>::Element *E = sequence_connections.front(); E; E = E->next()) { r_connection->push_back(E->get()); } } -void VisualScript::data_connect(const StringName &p_func, int p_from_node, int p_from_port, int p_to_node, int p_to_port) { +void VisualScript::data_connect(int p_from_node, int p_from_port, int p_to_node, int p_to_port) { ERR_FAIL_COND(instances.size()); - ERR_FAIL_COND(!functions.has(p_func)); - Function &func = functions[p_func]; DataConnection dc; dc.from_node = p_from_node; @@ -468,72 +397,55 @@ void VisualScript::data_connect(const StringName &p_func, int p_from_node, int p dc.to_node = p_to_node; dc.to_port = p_to_port; - ERR_FAIL_COND(func.data_connections.has(dc)); + ERR_FAIL_COND(data_connections.has(dc)); - func.data_connections.insert(dc); + data_connections.insert(dc); } -void VisualScript::data_disconnect(const StringName &p_func, int p_from_node, int p_from_port, int p_to_node, int p_to_port) { - ERR_FAIL_COND(!functions.has(p_func)); - Function &func = functions[p_func]; - +void VisualScript::data_disconnect(int p_from_node, int p_from_port, int p_to_node, int p_to_port) { DataConnection dc; dc.from_node = p_from_node; dc.from_port = p_from_port; dc.to_node = p_to_node; dc.to_port = p_to_port; - ERR_FAIL_COND(!func.data_connections.has(dc)); + ERR_FAIL_COND(!data_connections.has(dc)); - func.data_connections.erase(dc); + data_connections.erase(dc); } -bool VisualScript::has_data_connection(const StringName &p_func, int p_from_node, int p_from_port, int p_to_node, int p_to_port) const { - ERR_FAIL_COND_V(!functions.has(p_func), false); - const Function &func = functions[p_func]; - +bool VisualScript::has_data_connection(int p_from_node, int p_from_port, int p_to_node, int p_to_port) const { DataConnection dc; dc.from_node = p_from_node; dc.from_port = p_from_port; dc.to_node = p_to_node; dc.to_port = p_to_port; - return func.data_connections.has(dc); + return data_connections.has(dc); } -bool VisualScript::is_input_value_port_connected(const StringName &p_func, int p_node, int p_port) const { - ERR_FAIL_COND_V(!functions.has(p_func), false); - const Function &func = functions[p_func]; - - for (const Set<DataConnection>::Element *E = func.data_connections.front(); E; E = E->next()) { +bool VisualScript::is_input_value_port_connected(int p_node, int p_port) const { + for (const Set<DataConnection>::Element *E = data_connections.front(); E; E = E->next()) { if (E->get().to_node == p_node && E->get().to_port == p_port) { return true; } } - return false; } -bool VisualScript::get_input_value_port_connection_source(const StringName &p_func, int p_node, int p_port, int *r_node, int *r_port) const { - ERR_FAIL_COND_V(!functions.has(p_func), false); - const Function &func = functions[p_func]; - - for (const Set<DataConnection>::Element *E = func.data_connections.front(); E; E = E->next()) { +bool VisualScript::get_input_value_port_connection_source(int p_node, int p_port, int *r_node, int *r_port) const { + for (const Set<DataConnection>::Element *E = data_connections.front(); E; E = E->next()) { if (E->get().to_node == p_node && E->get().to_port == p_port) { *r_node = E->get().from_node; *r_port = E->get().from_port; return true; } } - return false; } -void VisualScript::get_data_connection_list(const StringName &p_func, List<DataConnection> *r_connection) const { - ERR_FAIL_COND(!functions.has(p_func)); - const Function &func = functions[p_func]; - - for (const Set<DataConnection>::Element *E = func.data_connections.front(); E; E = E->next()) { +void VisualScript::get_data_connection_list(List<DataConnection> *r_connection) const { + for (const Set<DataConnection>::Element *E = data_connections.front(); E; E = E->next()) { r_connection->push_back(E->get()); } } @@ -653,11 +565,8 @@ Dictionary VisualScript::_get_variable_info(const StringName &p_name) const { } void VisualScript::get_variable_list(List<StringName> *r_variables) const { - for (Map<StringName, Variable>::Element *E = variables.front(); E; E = E->next()) { - r_variables->push_back(E->key()); - } - - r_variables->sort_custom<StringName::AlphCompare>(); + variables.get_key_list(r_variables); + // r_variables->sort_custom<StringName::AlphCompare>(); // Don't force it. } void VisualScript::set_instance_base_type(const StringName &p_type) { @@ -680,24 +589,19 @@ void VisualScript::rename_variable(const StringName &p_name, const StringName &p variables[p_new_name] = variables[p_name]; variables.erase(p_name); - - List<StringName> funcs; - get_function_list(&funcs); - for (List<StringName>::Element *F = funcs.front(); F; F = F->next()) { // loop through all the functions - List<int> ids; - get_node_list(F->get(), &ids); - for (List<int>::Element *E = ids.front(); E; E = E->next()) { - Ref<VisualScriptVariableGet> nodeget = get_node(F->get(), E->get()); - if (nodeget.is_valid()) { - if (nodeget->get_variable() == p_name) { - nodeget->set_variable(p_new_name); - } - } else { - Ref<VisualScriptVariableSet> nodeset = get_node(F->get(), E->get()); - if (nodeset.is_valid()) { - if (nodeset->get_variable() == p_name) { - nodeset->set_variable(p_new_name); - } + List<int> ids; + get_node_list(&ids); + for (List<int>::Element *E = ids.front(); E; E = E->next()) { + Ref<VisualScriptVariableGet> nodeget = get_node(E->get()); + if (nodeget.is_valid()) { + if (nodeget->get_variable() == p_name) { + nodeget->set_variable(p_new_name); + } + } else { + Ref<VisualScriptVariableSet> nodeset = get_node(E->get()); + if (nodeset.is_valid()) { + if (nodeset->get_variable() == p_name) { + nodeset->set_variable(p_new_name); } } } @@ -808,23 +712,24 @@ void VisualScript::get_custom_signal_list(List<StringName> *r_custom_signals) co } int VisualScript::get_available_id() const { - int max_id = 0; - for (Map<StringName, Function>::Element *E = functions.front(); E; E = E->next()) { - if (E->get().nodes.empty()) { - continue; + // This is infinitely increasing, + // so one might want to implement a better solution, + // if the there is a case for huge number of nodes to be added to visual script. + List<int> nds; + nodes.get_key_list(&nds); + int max = -1; + for (const List<int>::Element *E = nds.front(); E; E = E->next()) { + if (E->get() > max) { + max = E->get(); } - - int last_id = E->get().nodes.back()->key(); - max_id = MAX(max_id, last_id + 1); } - - return max_id; + return (max + 1); } ///////////////////////////////// bool VisualScript::can_instance() const { - return true; //ScriptServer::is_scripting_enabled(); + return true; // ScriptServer::is_scripting_enabled(); } StringName VisualScript::get_instance_base_type() const { @@ -832,7 +737,7 @@ StringName VisualScript::get_instance_base_type() const { } Ref<Script> VisualScript::get_base_script() const { - return Ref<Script>(); // no inheritance in visual script + return Ref<Script>(); // No inheritance in visual script. } #ifdef TOOLS_ENABLED @@ -842,20 +747,23 @@ void VisualScript::_placeholder_erased(PlaceHolderScriptInstance *p_placeholder) void VisualScript::_update_placeholders() { if (placeholders.size() == 0) { - return; //no bother if no placeholders + return; // No bother if no placeholders. } List<PropertyInfo> pinfo; Map<StringName, Variant> values; - for (Map<StringName, Variable>::Element *E = variables.front(); E; E = E->next()) { - if (!E->get()._export) { + List<StringName> keys; + variables.get_key_list(&keys); + + for (List<StringName>::Element *E = keys.front(); E; E = E->next()) { + if (!variables[E->get()]._export) { continue; } - PropertyInfo p = E->get().info; - p.name = String(E->key()); + PropertyInfo p = variables[E->get()].info; + p.name = String(E->get()); pinfo.push_back(p); - values[p.name] = E->get().default_value; + values[p.name] = variables[E->get()].default_value; } for (Set<PlaceHolderScriptInstance *>::Element *E = placeholders.front(); E; E = E->next()) { @@ -875,17 +783,18 @@ ScriptInstance *VisualScript::instance_create(Object *p_this) { List<PropertyInfo> pinfo; Map<StringName, Variant> values; - for (Map<StringName, Variable>::Element *E = variables.front(); E; E = E->next()) { - if (!E->get()._export) { + List<StringName> keys; + variables.get_key_list(&keys); + + for (const List<StringName>::Element *E = keys.front(); E; E = E->next()) { + if (!variables[E->get()]._export) continue; - } - PropertyInfo p = E->get().info; - p.name = String(E->key()); + PropertyInfo p = variables[E->get()].info; + p.name = String(E->get()); pinfo.push_back(p); - values[p.name] = E->get().default_value; + values[p.name] = variables[E->get()].default_value; } - sins->update(pinfo, values); return sins; @@ -928,7 +837,7 @@ bool VisualScript::is_tool() const { } bool VisualScript::is_valid() const { - return true; //always valid + return true; // Always valid. } ScriptLanguage *VisualScript::get_language() const { @@ -964,11 +873,14 @@ bool VisualScript::get_property_default_value(const StringName &p_property, Vari } void VisualScript::get_script_method_list(List<MethodInfo> *p_list) const { - for (Map<StringName, Function>::Element *E = functions.front(); E; E = E->next()) { + List<StringName> funcs; + functions.get_key_list(&funcs); + + for (List<StringName>::Element *E = funcs.front(); E; E = E->next()) { MethodInfo mi; - mi.name = E->key(); - if (E->get().function_id >= 0) { - Ref<VisualScriptFunction> func = E->get().nodes[E->get().function_id].node; + mi.name = E->get(); + if (functions[E->get()].func_id >= 0) { + Ref<VisualScriptFunction> func = nodes[functions[E->get()].func_id].node; if (func.is_valid()) { for (int i = 0; i < func->get_argument_count(); i++) { PropertyInfo arg; @@ -988,15 +900,15 @@ bool VisualScript::has_method(const StringName &p_method) const { } MethodInfo VisualScript::get_method_info(const StringName &p_method) const { - const Map<StringName, Function>::Element *E = functions.find(p_method); - if (!E) { + const Function funct = functions[p_method]; + if (funct.func_id == -1) { return MethodInfo(); } MethodInfo mi; - mi.name = E->key(); - if (E->get().function_id >= 0) { - Ref<VisualScriptFunction> func = E->get().nodes[E->get().function_id].node; + mi.name = p_method; + if (funct.func_id >= 0) { + Ref<VisualScriptFunction> func = nodes[funct.func_id].node; if (func.is_valid()) { for (int i = 0; i < func->get_argument_count(); i++) { PropertyInfo arg; @@ -1028,28 +940,18 @@ void VisualScript::get_script_property_list(List<PropertyInfo> *p_list) const { } int VisualScript::get_member_line(const StringName &p_member) const { -#ifdef TOOLS_ENABLED - if (has_function(p_member)) { - for (Map<int, Function::NodeData>::Element *E = functions[p_member].nodes.front(); E; E = E->next()) { - if (Object::cast_to<VisualScriptFunction>(E->get().node.ptr())) { - return E->key(); - } - } - } -#endif - return -1; + return functions[p_member].func_id; // will be -1 if not found } #ifdef TOOLS_ENABLED bool VisualScript::are_subnodes_edited() const { - for (const Map<StringName, Function>::Element *E = functions.front(); E; E = E->next()) { - for (const Map<int, Function::NodeData>::Element *F = E->get().nodes.front(); F; F = F->next()) { - if (F->get().node->is_edited()) { - return true; - } + List<int> keys; + nodes.get_key_list(&keys); + for (const List<int>::Element *F = keys.front(); F; F = F->next()) { + if (nodes[F->get()].node->is_edited()) { + return true; } } - return false; } #endif @@ -1140,85 +1042,41 @@ void VisualScript::_set_data(const Dictionary &p_data) { Array funcs = d["functions"]; functions.clear(); - Vector2 last_pos = Vector2(-100 * funcs.size(), -100 * funcs.size()); // this is the center of the last fn box - Vector2 last_size = Vector2(0.0, 0.0); - for (int i = 0; i < funcs.size(); i++) { Dictionary func = funcs[i]; - - StringName name = func["name"]; - //int id=func["function_id"]; - add_function(name); - - set_function_scroll(name, func["scroll"]); - - Array nodes = func["nodes"]; - - if (!d.has("vs_unify") && nodes.size() > 0) { - Vector2 top_left = nodes[1]; - Vector2 bottom_right = nodes[1]; - - for (int j = 0; j < nodes.size(); j += 3) { - Point2 pos = nodes[j + 1]; - if (pos.y > top_left.y) { - top_left.y = pos.y; - } - if (pos.y < bottom_right.y) { - bottom_right.y = pos.y; - } - if (pos.x > bottom_right.x) { - bottom_right.x = pos.x; - } - if (pos.x < top_left.x) { - top_left.x = pos.x; - } - } - - Vector2 size = Vector2(bottom_right.x - top_left.x, top_left.y - bottom_right.y); - - Vector2 offset = last_pos + (last_size / 2.0) + (size / 2.0); // dunno I might just keep it in one axis but diagonal feels better.... - - last_pos = offset; - last_size = size; - - for (int j = 0; j < nodes.size(); j += 3) { - add_node(name, nodes[j], nodes[j + 2], offset + nodes[j + 1]); // also add an additional buffer if you want to - } - - } else { - for (int j = 0; j < nodes.size(); j += 3) { - add_node(name, nodes[j], nodes[j + 2], nodes[j + 1]); - } + add_function(func["name"], func["function_id"]); + } + { + Array nodes = d["nodes"]; + for (int i = 0; i < nodes.size(); i += 3) { + add_node(nodes[i], nodes[i + 2], nodes[i + 1]); } - Array sequence_connections = func["sequence_connections"]; + Array sequence_connections = d["sequence_connections"]; for (int j = 0; j < sequence_connections.size(); j += 3) { - sequence_connect(name, sequence_connections[j + 0], sequence_connections[j + 1], sequence_connections[j + 2]); + sequence_connect(sequence_connections[j + 0], sequence_connections[j + 1], sequence_connections[j + 2]); } - Array data_connections = func["data_connections"]; - + Array data_connections = d["data_connections"]; for (int j = 0; j < data_connections.size(); j += 4) { - data_connect(name, data_connections[j + 0], data_connections[j + 1], data_connections[j + 2], data_connections[j + 3]); + data_connect(data_connections[j + 0], data_connections[j + 1], data_connections[j + 2], data_connections[j + 3]); } } + is_tool_script = d["is_tool_script"]; + scroll = d["scroll"]; - if (d.has("is_tool_script")) { - is_tool_script = d["is_tool_script"]; - } else { - is_tool_script = false; - } - - // Takes all the rpc methods + // Takes all the rpc methods. rpc_functions.clear(); rpc_variables.clear(); - for (Map<StringName, Function>::Element *E = functions.front(); E; E = E->next()) { - if (E->get().function_id >= 0 && E->get().nodes.find(E->get().function_id)) { - Ref<VisualScriptFunction> vsf = E->get().nodes[E->get().function_id].node; + List<StringName> fns; + functions.get_key_list(&fns); + for (const List<StringName>::Element *E = fns.front(); E; E = E->next()) { + if (functions[E->get()].func_id >= 0 && nodes.has(functions[E->get()].func_id)) { + Ref<VisualScriptFunction> vsf = nodes[functions[E->get()].func_id].node; if (vsf.is_valid()) { if (vsf->get_rpc_mode() != MultiplayerAPI::RPC_MODE_DISABLED) { ScriptNetData nd; - nd.name = E->key(); + nd.name = E->get(); nd.mode = vsf->get_rpc_mode(); if (rpc_functions.find(nd) == -1) { rpc_functions.push_back(nd); @@ -1228,8 +1086,6 @@ void VisualScript::_set_data(const Dictionary &p_data) { } } - // Visual script doesn't have rset :( - // Sort so we are 100% that they are always the same. rpc_functions.sort_custom<SortNetData>(); } @@ -1237,12 +1093,15 @@ void VisualScript::_set_data(const Dictionary &p_data) { Dictionary VisualScript::_get_data() const { Dictionary d; d["base_type"] = base_type; + Array vars; - for (const Map<StringName, Variable>::Element *E = variables.front(); E; E = E->next()) { - Dictionary var = _get_variable_info(E->key()); - var["name"] = E->key(); //make sure it's the right one - var["default_value"] = E->get().default_value; - var["export"] = E->get()._export; + List<StringName> var_names; + variables.get_key_list(&var_names); + for (const List<StringName>::Element *E = var_names.front(); E; E = E->next()) { + Dictionary var = _get_variable_info(E->get()); + var["name"] = E->get(); // Make sure it's the right one. + var["default_value"] = variables[E->get()].default_value; + var["export"] = variables[E->get()]._export; vars.push_back(var); } d["variables"] = vars; @@ -1264,78 +1123,73 @@ Dictionary VisualScript::_get_data() const { d["signals"] = sigs; Array funcs; - - for (const Map<StringName, Function>::Element *E = functions.front(); E; E = E->next()) { + List<StringName> func_names; + functions.get_key_list(&func_names); + for (const List<StringName>::Element *E = func_names.front(); E; E = E->next()) { Dictionary func; - func["name"] = E->key(); - func["function_id"] = E->get().function_id; - func["scroll"] = E->get().scroll; - - Array nodes; - - for (const Map<int, Function::NodeData>::Element *F = E->get().nodes.front(); F; F = F->next()) { - nodes.push_back(F->key()); - nodes.push_back(F->get().pos); - nodes.push_back(F->get().node); - } - - func["nodes"] = nodes; - - Array sequence_connections; - - for (const Set<SequenceConnection>::Element *F = E->get().sequence_connections.front(); F; F = F->next()) { - sequence_connections.push_back(F->get().from_node); - sequence_connections.push_back(F->get().from_output); - sequence_connections.push_back(F->get().to_node); - } - - func["sequence_connections"] = sequence_connections; - - Array data_connections; + func["name"] = E->get(); + func["function_id"] = functions[E->get()].func_id; + funcs.push_back(func); + } + d["functions"] = funcs; - for (const Set<DataConnection>::Element *F = E->get().data_connections.front(); F; F = F->next()) { - data_connections.push_back(F->get().from_node); - data_connections.push_back(F->get().from_port); - data_connections.push_back(F->get().to_node); - data_connections.push_back(F->get().to_port); - } + Array nds; + List<int> node_ids; + nodes.get_key_list(&node_ids); + for (const List<int>::Element *F = node_ids.front(); F; F = F->next()) { + nds.push_back(F->get()); + nds.push_back(nodes[F->get()].pos); + nds.push_back(nodes[F->get()].node); + } + d["nodes"] = nds; - func["data_connections"] = data_connections; + Array seqconns; + for (const Set<SequenceConnection>::Element *F = sequence_connections.front(); F; F = F->next()) { + seqconns.push_back(F->get().from_node); + seqconns.push_back(F->get().from_output); + seqconns.push_back(F->get().to_node); + } + d["sequence_connections"] = seqconns; - funcs.push_back(func); + Array dataconns; + for (const Set<DataConnection>::Element *F = data_connections.front(); F; F = F->next()) { + dataconns.push_back(F->get().from_node); + dataconns.push_back(F->get().from_port); + dataconns.push_back(F->get().to_node); + dataconns.push_back(F->get().to_port); } + d["data_connections"] = dataconns; - d["functions"] = funcs; d["is_tool_script"] = is_tool_script; - d["vs_unify"] = true; + d["scroll"] = scroll; return d; } void VisualScript::_bind_methods() { - ClassDB::bind_method(D_METHOD("add_function", "name"), &VisualScript::add_function); + ClassDB::bind_method(D_METHOD("add_function", "name", "func_node_id"), &VisualScript::add_function); ClassDB::bind_method(D_METHOD("has_function", "name"), &VisualScript::has_function); ClassDB::bind_method(D_METHOD("remove_function", "name"), &VisualScript::remove_function); ClassDB::bind_method(D_METHOD("rename_function", "name", "new_name"), &VisualScript::rename_function); - ClassDB::bind_method(D_METHOD("set_function_scroll", "name", "ofs"), &VisualScript::set_function_scroll); - ClassDB::bind_method(D_METHOD("get_function_scroll", "name"), &VisualScript::get_function_scroll); + ClassDB::bind_method(D_METHOD("set_scroll", "ofs"), &VisualScript::set_scroll); + ClassDB::bind_method(D_METHOD("get_scroll"), &VisualScript::get_scroll); - ClassDB::bind_method(D_METHOD("add_node", "func", "id", "node", "position"), &VisualScript::add_node, DEFVAL(Point2())); - ClassDB::bind_method(D_METHOD("remove_node", "func", "id"), &VisualScript::remove_node); + ClassDB::bind_method(D_METHOD("add_node", "id", "node", "position"), &VisualScript::add_node, DEFVAL(Point2())); + ClassDB::bind_method(D_METHOD("remove_node", "id"), &VisualScript::remove_node); ClassDB::bind_method(D_METHOD("get_function_node_id", "name"), &VisualScript::get_function_node_id); - ClassDB::bind_method(D_METHOD("get_node", "func", "id"), &VisualScript::get_node); - ClassDB::bind_method(D_METHOD("has_node", "func", "id"), &VisualScript::has_node); - ClassDB::bind_method(D_METHOD("set_node_position", "func", "id", "position"), &VisualScript::set_node_position); - ClassDB::bind_method(D_METHOD("get_node_position", "func", "id"), &VisualScript::get_node_position); + ClassDB::bind_method(D_METHOD("get_node", "id"), &VisualScript::get_node); + ClassDB::bind_method(D_METHOD("has_node", "id"), &VisualScript::has_node); + ClassDB::bind_method(D_METHOD("set_node_position", "id", "position"), &VisualScript::set_node_position); + ClassDB::bind_method(D_METHOD("get_node_position", "id"), &VisualScript::get_node_position); - ClassDB::bind_method(D_METHOD("sequence_connect", "func", "from_node", "from_output", "to_node"), &VisualScript::sequence_connect); - ClassDB::bind_method(D_METHOD("sequence_disconnect", "func", "from_node", "from_output", "to_node"), &VisualScript::sequence_disconnect); - ClassDB::bind_method(D_METHOD("has_sequence_connection", "func", "from_node", "from_output", "to_node"), &VisualScript::has_sequence_connection); + ClassDB::bind_method(D_METHOD("sequence_connect", "from_node", "from_output", "to_node"), &VisualScript::sequence_connect); + ClassDB::bind_method(D_METHOD("sequence_disconnect", "from_node", "from_output", "to_node"), &VisualScript::sequence_disconnect); + ClassDB::bind_method(D_METHOD("has_sequence_connection", "from_node", "from_output", "to_node"), &VisualScript::has_sequence_connection); - ClassDB::bind_method(D_METHOD("data_connect", "func", "from_node", "from_port", "to_node", "to_port"), &VisualScript::data_connect); - ClassDB::bind_method(D_METHOD("data_disconnect", "func", "from_node", "from_port", "to_node", "to_port"), &VisualScript::data_disconnect); - ClassDB::bind_method(D_METHOD("has_data_connection", "func", "from_node", "from_port", "to_node", "to_port"), &VisualScript::has_data_connection); + ClassDB::bind_method(D_METHOD("data_connect", "from_node", "from_port", "to_node", "to_port"), &VisualScript::data_connect); + ClassDB::bind_method(D_METHOD("data_disconnect", "from_node", "from_port", "to_node", "to_port"), &VisualScript::data_disconnect); + ClassDB::bind_method(D_METHOD("has_data_connection", "from_node", "from_port", "to_node", "to_port"), &VisualScript::has_data_connection); ClassDB::bind_method(D_METHOD("add_variable", "name", "default_value", "export"), &VisualScript::add_variable, DEFVAL(Variant()), DEFVAL(false)); ClassDB::bind_method(D_METHOD("has_variable", "name"), &VisualScript::has_variable); @@ -1371,7 +1225,7 @@ void VisualScript::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_data", "_get_data"); - ADD_SIGNAL(MethodInfo("node_ports_changed", PropertyInfo(Variant::STRING, "function"), PropertyInfo(Variant::INT, "id"))); + ADD_SIGNAL(MethodInfo("node_ports_changed", PropertyInfo(Variant::INT, "id"))); } VisualScript::VisualScript() { @@ -1380,16 +1234,12 @@ VisualScript::VisualScript() { } bool VisualScript::inherits_script(const Ref<Script> &p_script) const { - return this == p_script.ptr(); //there is no inheritance in visual scripts, so this is enough -} - -StringName VisualScript::get_default_func() const { - return StringName("f_312843592"); + return this == p_script.ptr(); // There is no inheritance in visual scripts, so this is enough. } -Set<int> VisualScript::get_output_sequence_ports_connected(const String &edited_func, int from_node) { +Set<int> VisualScript::get_output_sequence_ports_connected(int from_node) { List<VisualScript::SequenceConnection> *sc = memnew(List<VisualScript::SequenceConnection>); - get_sequence_connection_list(edited_func, sc); + get_sequence_connection_list(sc); Set<int> connected; for (List<VisualScript::SequenceConnection>::Element *E = sc->front(); E; E = E->next()) { if (E->get().from_node == from_node) { @@ -1401,8 +1251,11 @@ Set<int> VisualScript::get_output_sequence_ports_connected(const String &edited_ } VisualScript::~VisualScript() { - while (!functions.empty()) { - remove_function(functions.front()->key()); + // Remove all nodes and stuff that hold data refs. + List<int> nds; + nodes.get_key_list(&nds); + for (const List<int>::Element *E = nds.front(); E; E = E->next()) { + remove_node(E->get()); } } @@ -1430,20 +1283,21 @@ bool VisualScriptInstance::get(const StringName &p_name, Variant &r_ret) const { } void VisualScriptInstance::get_property_list(List<PropertyInfo> *p_properties) const { - for (const Map<StringName, VisualScript::Variable>::Element *E = script->variables.front(); E; E = E->next()) { - if (!E->get()._export) { + List<StringName> vars; + script->variables.get_key_list(&vars); + for (const List<StringName>::Element *E = vars.front(); E; E = E->next()) { + if (!script->variables[E->get()]._export) { continue; } - PropertyInfo p = E->get().info; - p.name = String(E->key()); + PropertyInfo p = script->variables[E->get()].info; + p.name = String(E->get()); p.usage |= PROPERTY_USAGE_SCRIPT_VARIABLE; p_properties->push_back(p); } } Variant::Type VisualScriptInstance::get_property_type(const StringName &p_name, bool *r_is_valid) const { - const Map<StringName, VisualScript::Variable>::Element *E = script->variables.find(p_name); - if (!E) { + if (!script->variables.has(p_name)) { if (r_is_valid) { *r_is_valid = false; } @@ -1454,19 +1308,17 @@ Variant::Type VisualScriptInstance::get_property_type(const StringName &p_name, *r_is_valid = true; } - return E->get().info.type; + return script->variables[p_name].info.type; } void VisualScriptInstance::get_method_list(List<MethodInfo> *p_list) const { - for (const Map<StringName, VisualScript::Function>::Element *E = script->functions.front(); E; E = E->next()) { - if (E->key() == script->get_default_func()) { - continue; - } - + List<StringName> fns; + script->functions.get_key_list(&fns); + for (const List<StringName>::Element *E = fns.front(); E; E = E->next()) { MethodInfo mi; - mi.name = E->key(); - if (E->get().function_id >= 0 && E->get().nodes.has(E->get().function_id)) { - Ref<VisualScriptFunction> vsf = E->get().nodes[E->get().function_id].node; + mi.name = E->get(); + if (script->functions[E->get()].func_id >= 0 && script->nodes.has(script->functions[E->get()].func_id)) { + Ref<VisualScriptFunction> vsf = script->nodes[script->functions[E->get()].func_id].node; if (vsf.is_valid()) { for (int i = 0; i < vsf->get_argument_count(); i++) { PropertyInfo arg; @@ -1476,21 +1328,16 @@ void VisualScriptInstance::get_method_list(List<MethodInfo> *p_list) const { mi.arguments.push_back(arg); } - if (!vsf->is_sequenced()) { //assumed constant if not sequenced + if (!vsf->is_sequenced()) { // Assumed constant if not sequenced. mi.flags |= METHOD_FLAG_CONST; } } } - p_list->push_back(mi); } } bool VisualScriptInstance::has_method(const StringName &p_method) const { - if (p_method == script->get_default_func()) { - return false; - } - return script->functions.has(p_method); } @@ -1506,7 +1353,7 @@ void VisualScriptInstance::_dependency_step(VisualScriptNodeInstance *node, int pass_stack[node->pass_idx] = p_pass; - if (!node->dependencies.empty()) { + if (!node->dependencies.is_empty()) { int dc = node->dependencies.size(); VisualScriptNodeInstance **deps = node->dependencies.ptrw(); @@ -1522,10 +1369,10 @@ void VisualScriptInstance::_dependency_step(VisualScriptNodeInstance *node, int int index = node->input_ports[i] & VisualScriptNodeInstance::INPUT_MASK; if (node->input_ports[i] & VisualScriptNodeInstance::INPUT_DEFAULT_VALUE_BIT) { - //is a default value (unassigned input port) + // Is a default value (unassigned input port). input_args[i] = &default_values[index]; } else { - //regular temporary in stack + // Rregular temporary in stack. input_args[i] = &variant_stack[index]; } } @@ -1536,7 +1383,7 @@ void VisualScriptInstance::_dependency_step(VisualScriptNodeInstance *node, int Variant *working_mem = node->working_mem_idx >= 0 ? &variant_stack[node->working_mem_idx] : (Variant *)nullptr; node->step(input_args, output_args, VisualScriptNodeInstance::START_MODE_BEGIN_SEQUENCE, working_mem, r_error, error_str); - //ignore return + // Ignore return. if (r_error.error != Callable::CallError::CALL_OK) { *r_error_node = node; } @@ -1547,7 +1394,7 @@ Variant VisualScriptInstance::_call_internal(const StringName &p_method, void *p ERR_FAIL_COND_V(!F, Variant()); Function *f = &F->get(); - //this call goes separate, so it can e yielded and suspended + // This call goes separate, so it can e yielded and suspended. Variant *variant_stack = (Variant *)p_stack; bool *sequence_bits = (bool *)(variant_stack + f->max_stack); const Variant **input_args = (const Variant **)(sequence_bits + f->node_count); @@ -1573,27 +1420,27 @@ Variant VisualScriptInstance::_call_internal(const StringName &p_method, void *p #endif while (true) { - p_pass++; //increment pass + p_pass++; // Increment pass. current_node_id = node->get_id(); VSDEBUG("==========AT NODE: " + itos(current_node_id) + " base: " + node->get_base_node()->get_class_name()); VSDEBUG("AT STACK POS: " + itos(flow_stack_pos)); - //setup working mem + // Setup working mem. working_mem = node->working_mem_idx >= 0 ? &variant_stack[node->working_mem_idx] : (Variant *)nullptr; VSDEBUG("WORKING MEM: " + itos(node->working_mem_idx)); if (current_node_id == f->node) { - //if function node, set up function arguments from beginning of stack + // If function node, set up function arguments from beginning of stack. for (int i = 0; i < f->argument_count; i++) { input_args[i] = &variant_stack[i]; } } else { - //run dependencies first + // Run dependencies first. - if (!node->dependencies.empty()) { + if (!node->dependencies.is_empty()) { int dc = node->dependencies.size(); VisualScriptNodeInstance **deps = node->dependencies.ptrw(); @@ -1608,18 +1455,18 @@ Variant VisualScriptInstance::_call_internal(const StringName &p_method, void *p } if (!error) { - //setup input pointers normally + // Setup input pointers normally. VSDEBUG("INPUT PORTS: " + itos(node->input_port_count)); for (int i = 0; i < node->input_port_count; i++) { int index = node->input_ports[i] & VisualScriptNodeInstance::INPUT_MASK; if (node->input_ports[i] & VisualScriptNodeInstance::INPUT_DEFAULT_VALUE_BIT) { - //is a default value (unassigned input port) + // Is a default value (unassigned input port). input_args[i] = &default_values[index]; VSDEBUG("\tPORT " + itos(i) + " DEFAULT VAL"); } else { - //regular temporary in stack + // Regular temporary in stack. input_args[i] = &variant_stack[index]; VSDEBUG("PORT " + itos(i) + " AT STACK " + itos(index)); } @@ -1631,7 +1478,7 @@ Variant VisualScriptInstance::_call_internal(const StringName &p_method, void *p break; } - //setup output pointers + // Setup output pointers. VSDEBUG("OUTPUT PORTS: " + itos(node->output_port_count)); for (int i = 0; i < node->output_port_count; i++) { @@ -1639,15 +1486,15 @@ Variant VisualScriptInstance::_call_internal(const StringName &p_method, void *p VSDEBUG("PORT " + itos(i) + " AT STACK " + itos(node->output_ports[i])); } - //do step + // Do step. VisualScriptNodeInstance::StartMode start_mode; { if (p_resuming_yield) { start_mode = VisualScriptNodeInstance::START_MODE_RESUME_YIELD; - p_resuming_yield = false; // should resume only the first time + p_resuming_yield = false; // Should resume only the first time. } else if (flow_stack && (flow_stack[flow_stack_pos] & VisualScriptNodeInstance::FLOW_STACK_PUSHED_BIT)) { - //if there is a push bit, it means we are continuing a sequence + // If there is a push bit, it means we are continuing a sequence. start_mode = VisualScriptNodeInstance::START_MODE_CONTINUE_SEQUENCE; } else { start_mode = VisualScriptNodeInstance::START_MODE_BEGIN_SEQUENCE; @@ -1659,13 +1506,13 @@ Variant VisualScriptInstance::_call_internal(const StringName &p_method, void *p int ret = node->step(input_args, output_args, start_mode, working_mem, r_error, error_str); if (r_error.error != Callable::CallError::CALL_OK) { - //use error from step + // Use error from step. error = true; break; } if (ret & VisualScriptNodeInstance::STEP_YIELD_BIT) { - //yielded! + // Yielded! if (node->get_working_memory_size() == 0) { r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; error_str = RTR("A node yielded without working memory, please read the docs on how to yield properly!"); @@ -1681,7 +1528,7 @@ Variant VisualScriptInstance::_call_internal(const StringName &p_method, void *p break; } - //step 1, capture all state + // Step 1, capture all state. state->instance_id = get_owner_ptr()->get_instance_id(); state->script_id = get_script()->get_instance_id(); state->instance = this; @@ -1693,11 +1540,11 @@ Variant VisualScriptInstance::_call_internal(const StringName &p_method, void *p state->stack.resize(p_stack_size); state->pass = p_pass; copymem(state->stack.ptrw(), p_stack, p_stack_size); - //step 2, run away, return directly + // Step 2, run away, return directly. r_error.error = Callable::CallError::CALL_OK; #ifdef DEBUG_ENABLED - //will re-enter later, so exiting + // Will re-enter later, so exiting. if (EngineDebugger::is_active()) { VisualScriptLanguage::singleton->exit_function(); } @@ -1742,18 +1589,18 @@ Variant VisualScriptInstance::_call_internal(const StringName &p_method, void *p error_str = RTR("Return value must be assigned to first element of node working memory! Fix your node please."); error = true; } else { - //assign from working memory, first element + // Assign from working memory, first element. return_value = *working_mem; } VSDEBUG("EXITING FUNCTION - VALUE " + String(return_value)); - break; //exit function requested, bye + break; // Exit function requested, bye } - VisualScriptNodeInstance *next = nullptr; //next node + VisualScriptNodeInstance *next = nullptr; // Next node. if ((ret == output || ret & VisualScriptNodeInstance::STEP_FLAG_PUSH_STACK_BIT) && node->sequence_output_count) { - //if no exit bit was set, and has sequence outputs, guess next node + // If no exit bit was set, and has sequence outputs, guess next node. if (output >= node->sequence_output_count) { r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; error_str = RTR("Node returned an invalid sequence output: ") + itos(output); @@ -1766,21 +1613,21 @@ Variant VisualScriptInstance::_call_internal(const StringName &p_method, void *p } if (flow_stack) { - //update flow stack pos (may have changed) + // Update flow stack pos (may have changed). flow_stack[flow_stack_pos] = current_node_id; - //add stack push bit if requested + // Add stack push bit if requested. if (ret & VisualScriptNodeInstance::STEP_FLAG_PUSH_STACK_BIT) { flow_stack[flow_stack_pos] |= VisualScriptNodeInstance::FLOW_STACK_PUSHED_BIT; - sequence_bits[node->sequence_index] = true; //remember sequence bit + sequence_bits[node->sequence_index] = true; // Remember sequence bit. VSDEBUG("NEXT SEQ - FLAG BIT"); } else { - sequence_bits[node->sequence_index] = false; //forget sequence bit + sequence_bits[node->sequence_index] = false; // Forget sequence bit. VSDEBUG("NEXT SEQ - NORMAL"); } if (ret & VisualScriptNodeInstance::STEP_FLAG_GO_BACK_BIT) { - //go back request + // Go back request. if (flow_stack_pos > 0) { flow_stack_pos--; @@ -1788,20 +1635,20 @@ Variant VisualScriptInstance::_call_internal(const StringName &p_method, void *p VSDEBUG("NEXT IS GO BACK"); } else { VSDEBUG("NEXT IS GO BACK, BUT NO NEXT SO EXIT"); - break; //simply exit without value or error + break; // Simply exit without value or error. } } else if (next) { if (sequence_bits[next->sequence_index]) { - // what happened here is that we are entering a node that is in the middle of doing a sequence (pushed stack) from the front + // What happened here is that we are entering a node that is in the middle of doing a sequence (pushed stack) from the front // because each node has a working memory, we can't really do a sub-sequence // as a result, the sequence will be restarted and the stack will roll back to find where this node - // started the sequence + // started the sequence. bool found = false; for (int i = flow_stack_pos; i >= 0; i--) { if ((flow_stack[i] & VisualScriptNodeInstance::FLOW_STACK_MASK) == next->get_id()) { - flow_stack_pos = i; //roll back and remove bit + flow_stack_pos = i; // Roll back and remove bit. flow_stack[i] = next->get_id(); sequence_bits[next->sequence_index] = false; found = true; @@ -1819,7 +1666,7 @@ Variant VisualScriptInstance::_call_internal(const StringName &p_method, void *p VSDEBUG("RE-ENTERED A LOOP, RETURNED STACK POS TO - " + itos(flow_stack_pos)); } else { - // check for stack overflow + // Check for stack overflow. if (flow_stack_pos + 1 >= flow_max) { r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; error_str = RTR("Stack overflow with stack depth: ") + itos(output); @@ -1836,7 +1683,7 @@ Variant VisualScriptInstance::_call_internal(const StringName &p_method, void *p } } else { - //no next node, try to go back in stack to pushed bit + // No next node, try to go back in stack to pushed bit. bool found = false; @@ -1852,22 +1699,22 @@ Variant VisualScriptInstance::_call_internal(const StringName &p_method, void *p if (!found) { VSDEBUG("NO NEXT NODE, NO GO BACK, EXITING"); - break; //done, couldn't find a push stack bit + break; // Done, couldn't find a push stack bit. } VSDEBUG("NO NEXT NODE, GO BACK TO: " + itos(flow_stack_pos)); } } else { - node = next; //stackless mode, simply assign next node + node = next; // Stackless mode, simply assign next node. } } if (error) { - //error - // function, file, line, error, explanation + // Error + // Function, file, line, error, explanation. String err_file = script->get_path(); String err_func = p_method; - int err_line = current_node_id; //not a line but it works as one + int err_line = current_node_id; // Not a line but it works as one. if (node && (r_error.error != Callable::CallError::CALL_ERROR_INVALID_METHOD || error_str == String())) { if (error_str != String()) { @@ -1906,7 +1753,7 @@ Variant VisualScriptInstance::_call_internal(const StringName &p_method, void *p } #endif - //clean up variant stack + // Clean up variant stack. for (int i = 0; i < f->max_stack; i++) { variant_stack[i].~Variant(); } @@ -1954,7 +1801,7 @@ Variant VisualScriptInstance::call(const StringName &p_method, const Variant **p int *pass_stack = flow_stack ? (int *)(flow_stack + flow_max) : (int *)nullptr; for (int i = 0; i < f->node_count; i++) { - sequence_bits[i] = false; //all starts as false + sequence_bits[i] = false; // All starts as false. } zeromem(pass_stack, f->pass_stack_size * sizeof(int)); @@ -1988,12 +1835,12 @@ Variant VisualScriptInstance::call(const StringName &p_method, const Variant **p return Variant(); } - //allocate variant stack + // Allocate variant stack. for (int i = 0; i < f->max_stack; i++) { memnew_placement(&variant_stack[i], Variant); } - //allocate function arguments (must be copied for yield to work properly) + // Allocate function arguments (must be copied for yield to work properly). for (int i = 0; i < p_argcount; i++) { variant_stack[i] = *p_args[i]; } @@ -2002,12 +1849,12 @@ Variant VisualScriptInstance::call(const StringName &p_method, const Variant **p } void VisualScriptInstance::notification(int p_notification) { - //do nothing as this is called using virtual + // Do nothing as this is called using virtual. Variant what = p_notification; const Variant *whatp = &what; Callable::CallError ce; - call(VisualScriptLanguage::singleton->notification, &whatp, 1, ce); //do as call + call(VisualScriptLanguage::singleton->notification, &whatp, 1, ce); // Do as call. } String VisualScriptInstance::to_string(bool *r_valid) { @@ -2086,7 +1933,7 @@ void VisualScriptInstance::create(const Ref<VisualScript> &p_script, Object *p_o max_output_args = 0; if (Object::cast_to<Node>(p_owner)) { - //turn on these if they exist and base is a node + // Turn on these if they exist and base is a node. Node *node = Object::cast_to<Node>(p_owner); if (p_script->functions.has("_process")) { node->set_process(true); @@ -2105,190 +1952,236 @@ void VisualScriptInstance::create(const Ref<VisualScript> &p_script, Object *p_o } } - for (const Map<StringName, VisualScript::Variable>::Element *E = script->variables.front(); E; E = E->next()) { - variables[E->key()] = E->get().default_value; - } - - for (const Map<StringName, VisualScript::Function>::Element *E = script->functions.front(); E; E = E->next()) { - if (E->key() == script->get_default_func()) { - continue; - } - - Function function; - function.node = E->get().function_id; - function.max_stack = 0; - function.flow_stack_size = 0; - function.pass_stack_size = 0; - function.node_count = 0; - - Map<StringName, int> local_var_indices; - - if (function.node < 0) { - VisualScriptLanguage::singleton->debug_break_parse(get_script()->get_path(), 0, "No start node in function: " + String(E->key())); - - ERR_CONTINUE(function.node < 0); + // Setup variables. + { + List<StringName> keys; + script->variables.get_key_list(&keys); + for (const List<StringName>::Element *E = keys.front(); E; E = E->next()) { + variables[E->get()] = script->variables[E->get()].default_value; } + } - { - Ref<VisualScriptFunction> func_node = script->get_node(E->key(), E->get().function_id); - - if (func_node.is_null()) { - VisualScriptLanguage::singleton->debug_break_parse(get_script()->get_path(), 0, "No VisualScriptFunction typed start node in function: " + String(E->key())); + // Setup functions from sequence trees. + { + List<StringName> keys; + script->functions.get_key_list(&keys); + for (const List<StringName>::Element *E = keys.front(); E; E = E->next()) { + const VisualScript::Function vsfn = p_script->functions[E->get()]; + Function function; + function.node = vsfn.func_id; + function.max_stack = 0; + function.flow_stack_size = 0; + function.pass_stack_size = 0; + function.node_count = 0; + + Map<StringName, int> local_var_indices; + + if (function.node < 0) { + VisualScriptLanguage::singleton->debug_break_parse(get_script()->get_path(), 0, "No start node in function: " + String(E->get())); + ERR_CONTINUE(function.node < 0); } - ERR_CONTINUE(!func_node.is_valid()); - - function.argument_count = func_node->get_argument_count(); - function.max_stack += function.argument_count; - function.flow_stack_size = func_node->is_stack_less() ? 0 : func_node->get_stack_size(); - max_input_args = MAX(max_input_args, function.argument_count); - } - - //multiple passes are required to set up this complex thing.. - - //first create the nodes - for (const Map<int, VisualScript::Function::NodeData>::Element *F = E->get().nodes.front(); F; F = F->next()) { - Ref<VisualScriptNode> node = F->get().node; - - VisualScriptNodeInstance *instance = node->instance(this); //create instance - ERR_FAIL_COND(!instance); + { + Ref<VisualScriptFunction> func_node = script->get_node(vsfn.func_id); - instance->base = node.ptr(); + if (func_node.is_null()) { + VisualScriptLanguage::singleton->debug_break_parse(get_script()->get_path(), 0, "No VisualScriptFunction typed start node in function: " + String(E->get())); + } - instance->id = F->key(); - instance->input_port_count = node->get_input_value_port_count(); - instance->input_ports = nullptr; - instance->output_port_count = node->get_output_value_port_count(); - instance->output_ports = nullptr; - instance->sequence_output_count = node->get_output_sequence_port_count(); - instance->sequence_index = function.node_count++; - instance->sequence_outputs = nullptr; - instance->pass_idx = -1; + ERR_CONTINUE(!func_node.is_valid()); - if (instance->input_port_count) { - instance->input_ports = memnew_arr(int, instance->input_port_count); - for (int i = 0; i < instance->input_port_count; i++) { - instance->input_ports[i] = -1; //if not assigned, will become default value - } + function.argument_count = func_node->get_argument_count(); + function.max_stack += function.argument_count; + function.flow_stack_size = func_node->is_stack_less() ? 0 : func_node->get_stack_size(); + max_input_args = MAX(max_input_args, function.argument_count); } - - if (instance->output_port_count) { - instance->output_ports = memnew_arr(int, instance->output_port_count); - for (int i = 0; i < instance->output_port_count; i++) { - instance->output_ports[i] = -1; //if not assigned, will output to trash + // Function nodes graphs. + Set<VisualScript::SequenceConnection> seqconns; + Set<VisualScript::DataConnection> dataconns; + Set<int> node_ids; + node_ids.insert(function.node); + { + List<int> nd_queue; + nd_queue.push_back(function.node); + while (!nd_queue.is_empty()) { + for (const Set<VisualScript::SequenceConnection>::Element *F = script->sequence_connections.front(); F; F = F->next()) { + if (nd_queue.front()->get() == F->get().from_node && !node_ids.has(F->get().to_node)) { + nd_queue.push_back(F->get().to_node); + node_ids.insert(F->get().to_node); + } + if (nd_queue.front()->get() == F->get().from_node && !seqconns.has(F->get())) { + seqconns.insert(F->get()); + } + } + nd_queue.pop_front(); } - } - - if (instance->sequence_output_count) { - instance->sequence_outputs = memnew_arr(VisualScriptNodeInstance *, instance->sequence_output_count); - for (int i = 0; i < instance->sequence_output_count; i++) { - instance->sequence_outputs[i] = nullptr; //if it remains null, flow ends here + HashMap<int, HashMap<int, Pair<int, int>>> dc_lut; // :: to -> to_port -> (from, from_port) + for (const Set<VisualScript::DataConnection>::Element *F = script->data_connections.front(); F; F = F->next()) { + dc_lut[F->get().to_node][F->get().to_port] = Pair<int, int>(F->get().from_node, F->get().from_port); + } + for (const Set<int>::Element *F = node_ids.front(); F; F = F->next()) { + nd_queue.push_back(F->get()); + } + List<int> dc_keys; + while (!nd_queue.is_empty()) { + int ky = nd_queue.front()->get(); + dc_lut[ky].get_key_list(&dc_keys); + for (const List<int>::Element *F = dc_keys.front(); F; F = F->next()) { + VisualScript::DataConnection dc; + dc.from_node = dc_lut[ky][F->get()].first; + dc.from_port = dc_lut[ky][F->get()].second; + dc.to_node = ky; + dc.to_port = F->get(); + dataconns.insert(dc); + nd_queue.push_back(dc.from_node); + node_ids.insert(dc.from_node); + } + dc_keys.clear(); // Necessary as get_key_list does a push_back not a set. + nd_queue.pop_front(); } } - if (Object::cast_to<VisualScriptLocalVar>(node.ptr()) || Object::cast_to<VisualScriptLocalVarSet>(*node)) { - //working memory is shared only for this node, for the same variables - Ref<VisualScriptLocalVar> vslv = node; - - StringName var_name; + //Multiple passes are required to set up this complex thing.. + //First create the nodes. + for (const Set<int>::Element *F = node_ids.front(); F; F = F->next()) { + Ref<VisualScriptNode> node = script->nodes[F->get()].node; + + VisualScriptNodeInstance *instance = node->instance(this); // Create instance. + ERR_FAIL_COND(!instance); + + instance->base = node.ptr(); + + instance->id = F->get(); + instance->input_port_count = node->get_input_value_port_count(); + instance->input_ports = NULL; + instance->output_port_count = node->get_output_value_port_count(); + instance->output_ports = NULL; + instance->sequence_output_count = node->get_output_sequence_port_count(); + instance->sequence_index = function.node_count++; + instance->sequence_outputs = NULL; + instance->pass_idx = -1; + + if (instance->input_port_count) { + instance->input_ports = memnew_arr(int, instance->input_port_count); + for (int i = 0; i < instance->input_port_count; i++) { + instance->input_ports[i] = -1; // If not assigned, will become default value. + } + } - if (Object::cast_to<VisualScriptLocalVar>(*node)) { - var_name = String(Object::cast_to<VisualScriptLocalVar>(*node)->get_var_name()).strip_edges(); - } else { - var_name = String(Object::cast_to<VisualScriptLocalVarSet>(*node)->get_var_name()).strip_edges(); + if (instance->output_port_count) { + instance->output_ports = memnew_arr(int, instance->output_port_count); + for (int i = 0; i < instance->output_port_count; i++) { + instance->output_ports[i] = -1; // If not assigned, will output to trash. + } } - if (!local_var_indices.has(var_name)) { - local_var_indices[var_name] = function.max_stack; - function.max_stack++; + if (instance->sequence_output_count) { + instance->sequence_outputs = memnew_arr(VisualScriptNodeInstance *, instance->sequence_output_count); + for (int i = 0; i < instance->sequence_output_count; i++) { + instance->sequence_outputs[i] = NULL; // If it remains null, flow ends here. + } } - instance->working_mem_idx = local_var_indices[var_name]; + if (Object::cast_to<VisualScriptLocalVar>(node.ptr()) || Object::cast_to<VisualScriptLocalVarSet>(*node)) { + // Working memory is shared only for this node, for the same variables. + Ref<VisualScriptLocalVar> vslv = node; - } else if (instance->get_working_memory_size()) { - instance->working_mem_idx = function.max_stack; - function.max_stack += instance->get_working_memory_size(); - } else { - instance->working_mem_idx = -1; //no working mem - } + StringName var_name; - max_input_args = MAX(max_input_args, instance->input_port_count); - max_output_args = MAX(max_output_args, instance->output_port_count); + if (Object::cast_to<VisualScriptLocalVar>(*node)) + var_name = String(Object::cast_to<VisualScriptLocalVar>(*node)->get_var_name()).strip_edges(); + else + var_name = String(Object::cast_to<VisualScriptLocalVarSet>(*node)->get_var_name()).strip_edges(); - instances[F->key()] = instance; - } + if (!local_var_indices.has(var_name)) { + local_var_indices[var_name] = function.max_stack; + function.max_stack++; + } - function.trash_pos = function.max_stack++; //create pos for trash + instance->working_mem_idx = local_var_indices[var_name]; - //second pass, do data connections + } else if (instance->get_working_memory_size()) { + instance->working_mem_idx = function.max_stack; + function.max_stack += instance->get_working_memory_size(); + } else { + instance->working_mem_idx = -1; //no working mem + } - for (const Set<VisualScript::DataConnection>::Element *F = E->get().data_connections.front(); F; F = F->next()) { - VisualScript::DataConnection dc = F->get(); - ERR_CONTINUE(!instances.has(dc.from_node)); - VisualScriptNodeInstance *from = instances[dc.from_node]; - ERR_CONTINUE(!instances.has(dc.to_node)); - VisualScriptNodeInstance *to = instances[dc.to_node]; - ERR_CONTINUE(dc.from_port >= from->output_port_count); - ERR_CONTINUE(dc.to_port >= to->input_port_count); + max_input_args = MAX(max_input_args, instance->input_port_count); + max_output_args = MAX(max_output_args, instance->output_port_count); - if (from->output_ports[dc.from_port] == -1) { - int stack_pos = function.max_stack++; - from->output_ports[dc.from_port] = stack_pos; + instances[F->get()] = instance; } - if (from->get_sequence_output_count() == 0 && to->dependencies.find(from) == -1) { - //if the node we are reading from has no output sequence, we must call step() before reading from it. - if (from->pass_idx == -1) { - from->pass_idx = function.pass_stack_size; - function.pass_stack_size++; + function.trash_pos = function.max_stack++; // create pos for trash + + // Second pass, do data connections. + for (const Set<VisualScript::DataConnection>::Element *F = dataconns.front(); F; F = F->next()) { + VisualScript::DataConnection dc = F->get(); + ERR_CONTINUE(!instances.has(dc.from_node)); + VisualScriptNodeInstance *from = instances[dc.from_node]; + ERR_CONTINUE(!instances.has(dc.to_node)); + VisualScriptNodeInstance *to = instances[dc.to_node]; + ERR_CONTINUE(dc.from_port >= from->output_port_count); + ERR_CONTINUE(dc.to_port >= to->input_port_count); + + if (from->output_ports[dc.from_port] == -1) { + int stack_pos = function.max_stack++; + from->output_ports[dc.from_port] = stack_pos; } - to->dependencies.push_back(from); - } - to->input_ports[dc.to_port] = from->output_ports[dc.from_port]; //read from wherever the stack is - } - - //third pass, do sequence connections + if (from->get_sequence_output_count() == 0 && to->dependencies.find(from) == -1) { + // If the node we are reading from has no output sequence, we must call step() before reading from it. + if (from->pass_idx == -1) { + from->pass_idx = function.pass_stack_size; + function.pass_stack_size++; + } + to->dependencies.push_back(from); + } - for (const Set<VisualScript::SequenceConnection>::Element *F = E->get().sequence_connections.front(); F; F = F->next()) { - VisualScript::SequenceConnection sc = F->get(); - ERR_CONTINUE(!instances.has(sc.from_node)); - VisualScriptNodeInstance *from = instances[sc.from_node]; - ERR_CONTINUE(!instances.has(sc.to_node)); - VisualScriptNodeInstance *to = instances[sc.to_node]; - ERR_CONTINUE(sc.from_output >= from->sequence_output_count); + to->input_ports[dc.to_port] = from->output_ports[dc.from_port]; // Read from wherever the stack is. + } - from->sequence_outputs[sc.from_output] = to; - } + // Third pass, do sequence connections. + for (const Set<VisualScript::SequenceConnection>::Element *F = seqconns.front(); F; F = F->next()) { + VisualScript::SequenceConnection sc = F->get(); + ERR_CONTINUE(!instances.has(sc.from_node)); + VisualScriptNodeInstance *from = instances[sc.from_node]; + ERR_CONTINUE(!instances.has(sc.to_node)); + VisualScriptNodeInstance *to = instances[sc.to_node]; + ERR_CONTINUE(sc.from_output >= from->sequence_output_count); - //fourth pass: - // 1) unassigned input ports to default values - // 2) connect unassigned output ports to trash + from->sequence_outputs[sc.from_output] = to; + } - for (const Map<int, VisualScript::Function::NodeData>::Element *F = E->get().nodes.front(); F; F = F->next()) { - ERR_CONTINUE(!instances.has(F->key())); + //fourth pass: + // 1) unassigned input ports to default values + // 2) connect unassigned output ports to trash + for (const Set<int>::Element *F = node_ids.front(); F; F = F->next()) { + ERR_CONTINUE(!instances.has(F->get())); - Ref<VisualScriptNode> node = F->get().node; - VisualScriptNodeInstance *instance = instances[F->key()]; + Ref<VisualScriptNode> node = script->nodes[F->get()].node; + VisualScriptNodeInstance *instance = instances[F->get()]; - // connect to default values - for (int i = 0; i < instance->input_port_count; i++) { - if (instance->input_ports[i] == -1) { - //unassigned, connect to default val - instance->input_ports[i] = default_values.size() | VisualScriptNodeInstance::INPUT_DEFAULT_VALUE_BIT; - default_values.push_back(node->get_default_input_value(i)); + // Connect to default values. + for (int i = 0; i < instance->input_port_count; i++) { + if (instance->input_ports[i] == -1) { + // Unassigned, connect to default val. + instance->input_ports[i] = default_values.size() | VisualScriptNodeInstance::INPUT_DEFAULT_VALUE_BIT; + default_values.push_back(node->get_default_input_value(i)); + } } - } - // connect to trash - for (int i = 0; i < instance->output_port_count; i++) { - if (instance->output_ports[i] == -1) { - instance->output_ports[i] = function.trash_pos; //trash is same for all + // Connect to trash. + for (int i = 0; i < instance->output_port_count; i++) { + if (instance->output_ports[i] == -1) { + instance->output_ports[i] = function.trash_pos; //trash is same for all + } } } - } - functions[E->key()] = function; + functions[E->get()] = function; + } } } @@ -2354,7 +2247,7 @@ Variant VisualScriptFunctionState::_signal_callback(const Variant **p_args, int Variant *working_mem = ((Variant *)stack.ptr()) + working_mem_index; - *working_mem = args; //arguments go to working mem. + *working_mem = args; // Arguments go to working mem. Variant ret = instance->_call_internal(function, stack.ptrw(), stack.size(), node, flow_stack_pos, pass, true, r_error); function = StringName(); //invalidate @@ -2367,7 +2260,7 @@ void VisualScriptFunctionState::connect_to_signal(Object *p_obj, const String &p binds.push_back(p_binds[i]); } binds.push_back(Ref<VisualScriptFunctionState>(this)); //add myself on the back to avoid dying from unreferencing - p_obj->connect_compat(p_signal, this, "_signal_callback", binds, CONNECT_ONESHOT); + p_obj->connect(p_signal, Callable(this, "_signal_callback"), binds, CONNECT_ONESHOT); } bool VisualScriptFunctionState::is_valid() const { @@ -2388,7 +2281,7 @@ Variant VisualScriptFunctionState::resume(Array p_args) { Variant *working_mem = ((Variant *)stack.ptr()) + working_mem_index; - *working_mem = p_args; //arguments go to working mem. + *working_mem = p_args; // Arguments go to working mem. Variant ret = instance->_call_internal(function, stack.ptrw(), stack.size(), node, flow_stack_pos, pass, true, r_error); function = StringName(); //invalidate @@ -2498,7 +2391,7 @@ void VisualScriptLanguage::add_global_constant(const StringName &p_variable, con /* DEBUGGER FUNCTIONS */ bool VisualScriptLanguage::debug_break_parse(const String &p_file, int p_node, const String &p_error) { - //break because of parse error + // Break because of parse error. if (EngineDebugger::is_active() && Thread::get_caller_id() == Thread::get_main_id()) { _debug_parse_err_node = p_node; @@ -2666,7 +2559,7 @@ void VisualScriptLanguage::debug_get_stack_level_members(int p_level, List<Strin } void VisualScriptLanguage::debug_get_globals(List<String> *p_locals, List<Variant> *p_values, int p_max_subitems, int p_max_depth) { - //no globals are really reachable in gdscript + // No globals are really reachable in gdscript. } String VisualScriptLanguage::debug_parse_stack_level_expression(int p_level, const String &p_expression, int p_max_subitems, int p_max_depth) { @@ -2742,7 +2635,7 @@ VisualScriptLanguage::VisualScriptLanguage() { ProjectSettings::get_singleton()->set_custom_property_info("debug/settings/visual_script/max_call_stack", PropertyInfo(Variant::INT, "debug/settings/visual_script/max_call_stack", PROPERTY_HINT_RANGE, "1024,4096,1,or_greater")); //minimum is 1024 if (EngineDebugger::is_active()) { - //debugging enabled! + // Debugging enabled! _debug_max_call_stack = dmcs; _call_stack = memnew_arr(CallLevel, _debug_max_call_stack + 1); |