diff options
Diffstat (limited to 'scene/main/node.cpp')
-rw-r--r-- | scene/main/node.cpp | 1115 |
1 files changed, 553 insertions, 562 deletions
diff --git a/scene/main/node.cpp b/scene/main/node.cpp index 350959dcc3..e7753089c7 100644 --- a/scene/main/node.cpp +++ b/scene/main/node.cpp @@ -35,6 +35,7 @@ #include "core/message_queue.h" #include "core/print_string.h" #include "instance_placeholder.h" +#include "scene/debugger/scene_debugger.h" #include "scene/resources/packed_scene.h" #include "scene/scene_string_names.h" #include "viewport.h" @@ -43,30 +44,24 @@ #include "editor/editor_settings.h" #endif +#include <stdint.h> + VARIANT_ENUM_CAST(Node::PauseMode); int Node::orphan_node_count = 0; void Node::_notification(int p_notification) { - switch (p_notification) { - case NOTIFICATION_PROCESS: { - if (get_script_instance()) { - Variant time = get_process_delta_time(); - const Variant *ptr[1] = { &time }; - get_script_instance()->call_multilevel(SceneStringNames::get_singleton()->_process, ptr, 1); + get_script_instance()->call(SceneStringNames::get_singleton()->_process, time); } } break; case NOTIFICATION_PHYSICS_PROCESS: { - if (get_script_instance()) { - Variant time = get_physics_process_delta_time(); - const Variant *ptr[1] = { &time }; - get_script_instance()->call_multilevel(SceneStringNames::get_singleton()->_physics_process, ptr, 1); + get_script_instance()->call(SceneStringNames::get_singleton()->_physics_process, time); } } break; @@ -75,21 +70,24 @@ void Node::_notification(int p_notification) { ERR_FAIL_COND(!get_tree()); if (data.pause_mode == PAUSE_MODE_INHERIT) { - - if (data.parent) + if (data.parent) { data.pause_owner = data.parent->data.pause_owner; - else - data.pause_owner = NULL; + } else { + data.pause_owner = nullptr; + } } else { data.pause_owner = this; } - if (data.input) + if (data.input) { add_to_group("_vp_input" + itos(get_viewport()->get_instance_id())); - if (data.unhandled_input) + } + if (data.unhandled_input) { add_to_group("_vp_unhandled_input" + itos(get_viewport()->get_instance_id())); - if (data.unhandled_key_input) + } + if (data.unhandled_key_input) { add_to_group("_vp_unhandled_key_input" + itos(get_viewport()->get_instance_id())); + } get_tree()->node_count++; orphan_node_count--; @@ -102,30 +100,30 @@ void Node::_notification(int p_notification) { get_tree()->node_count--; orphan_node_count++; - if (data.input) + if (data.input) { remove_from_group("_vp_input" + itos(get_viewport()->get_instance_id())); - if (data.unhandled_input) + } + if (data.unhandled_input) { remove_from_group("_vp_unhandled_input" + itos(get_viewport()->get_instance_id())); - if (data.unhandled_key_input) + } + if (data.unhandled_key_input) { remove_from_group("_vp_unhandled_key_input" + itos(get_viewport()->get_instance_id())); + } - data.pause_owner = NULL; + data.pause_owner = nullptr; if (data.path_cache) { memdelete(data.path_cache); - data.path_cache = NULL; + data.path_cache = nullptr; } } break; case NOTIFICATION_PATH_CHANGED: { - if (data.path_cache) { memdelete(data.path_cache); - data.path_cache = NULL; + data.path_cache = nullptr; } } break; case NOTIFICATION_READY: { - if (get_script_instance()) { - if (get_script_instance()->has_method(SceneStringNames::get_singleton()->_input)) { set_process_input(true); } @@ -146,7 +144,7 @@ void Node::_notification(int p_notification) { set_physics_process(true); } - get_script_instance()->call_multilevel_reversed(SceneStringNames::get_singleton()->_ready, NULL, 0); + get_script_instance()->call(SceneStringNames::get_singleton()->_ready); } } break; @@ -154,22 +152,18 @@ void Node::_notification(int p_notification) { data.in_constructor = false; } break; case NOTIFICATION_PREDELETE: { - - set_owner(NULL); + set_owner(nullptr); while (data.owned.size()) { - - data.owned.front()->get()->set_owner(NULL); + data.owned.front()->get()->set_owner(nullptr); } if (data.parent) { - data.parent->remove_child(this); } // kill children as cleanly as possible while (data.children.size()) { - Node *child = data.children[data.children.size() - 1]; //begin from the end because its faster and more consistent with creation remove_child(child); memdelete(child); @@ -180,11 +174,9 @@ void Node::_notification(int p_notification) { } void Node::_propagate_ready() { - data.ready_notified = true; data.blocked++; for (int i = 0; i < data.children.size(); i++) { - data.children[i]->_propagate_ready(); } data.blocked--; @@ -205,13 +197,13 @@ void Node::_propagate_enter_tree() { data.tree = data.parent->data.tree; data.depth = data.parent->data.depth + 1; } else { - data.depth = 1; } data.viewport = Object::cast_to<Viewport>(this); - if (!data.viewport && data.parent) + if (!data.viewport && data.parent) { data.viewport = data.parent->data.viewport; + } data.inside_tree = true; @@ -222,8 +214,7 @@ void Node::_propagate_enter_tree() { notification(NOTIFICATION_ENTER_TREE); if (get_script_instance()) { - - get_script_instance()->call_multilevel_reversed(SceneStringNames::get_singleton()->_enter_tree, NULL, 0); + get_script_instance()->call(SceneStringNames::get_singleton()->_enter_tree); } emit_signal(SceneStringNames::get_singleton()->tree_entered); @@ -234,25 +225,20 @@ void Node::_propagate_enter_tree() { //block while adding children for (int i = 0; i < data.children.size(); i++) { - - if (!data.children[i]->is_inside_tree()) // could have been added in enter_tree + if (!data.children[i]->is_inside_tree()) { // could have been added in enter_tree data.children[i]->_propagate_enter_tree(); + } } data.blocked--; #ifdef DEBUG_ENABLED - - if (ScriptDebugger::get_singleton() && data.filename != String()) { - //used for live edit - data.tree->live_scene_edit_cache[data.filename].insert(this); - } + SceneDebugger::add_to_cache(data.filename, this); #endif // enter groups } void Node::_propagate_after_exit_tree() { - data.blocked++; for (int i = 0; i < data.children.size(); i++) { data.children[i]->_propagate_after_exit_tree(); @@ -262,70 +248,49 @@ void Node::_propagate_after_exit_tree() { } void Node::_propagate_exit_tree() { - //block while removing children #ifdef DEBUG_ENABLED - - if (ScriptDebugger::get_singleton() && data.filename != String()) { - //used for live edit - Map<String, Set<Node *> >::Element *E = data.tree->live_scene_edit_cache.find(data.filename); - if (E) { - E->get().erase(this); - if (E->get().size() == 0) { - data.tree->live_scene_edit_cache.erase(E); - } - } - - Map<Node *, Map<ObjectID, Node *> >::Element *F = data.tree->live_edit_remove_list.find(this); - if (F) { - for (Map<ObjectID, Node *>::Element *G = F->get().front(); G; G = G->next()) { - - memdelete(G->get()); - } - data.tree->live_edit_remove_list.erase(F); - } - } + SceneDebugger::remove_from_cache(data.filename, this); #endif data.blocked++; for (int i = data.children.size() - 1; i >= 0; i--) { - data.children[i]->_propagate_exit_tree(); } data.blocked--; if (get_script_instance()) { - - get_script_instance()->call_multilevel(SceneStringNames::get_singleton()->_exit_tree, NULL, 0); + get_script_instance()->call(SceneStringNames::get_singleton()->_exit_tree); } emit_signal(SceneStringNames::get_singleton()->tree_exiting); notification(NOTIFICATION_EXIT_TREE, true); - if (data.tree) + if (data.tree) { data.tree->node_removed(this); + } // exit groups for (Map<StringName, GroupData>::Element *E = data.grouped.front(); E; E = E->next()) { data.tree->remove_from_group(E->key(), this); - E->get().group = NULL; + E->get().group = nullptr; } - data.viewport = NULL; + data.viewport = nullptr; - if (data.tree) + if (data.tree) { data.tree->tree_changed(); + } data.inside_tree = false; data.ready_notified = false; - data.tree = NULL; + data.tree = nullptr; data.depth = -1; } void Node::move_child(Node *p_child, int p_pos) { - ERR_FAIL_NULL(p_child); ERR_FAIL_INDEX_MSG(p_pos, data.children.size() + 1, "Invalid new child position: " + itos(p_pos) + "."); ERR_FAIL_COND_MSG(p_child->data.parent != this, "Child is not a child of this node."); @@ -333,11 +298,13 @@ void Node::move_child(Node *p_child, int p_pos) { // Specifying one place beyond the end // means the same as moving to the last position - if (p_pos == data.children.size()) + if (p_pos == data.children.size()) { p_pos--; + } - if (p_child->data.pos == p_pos) + if (p_child->data.pos == p_pos) { return; //do nothing + } int motion_from = MIN(p_pos, p_child->data.pos); int motion_to = MAX(p_pos, p_child->data.pos); @@ -352,7 +319,6 @@ void Node::move_child(Node *p_child, int p_pos) { data.blocked++; //new pos first for (int i = motion_from; i <= motion_to; i++) { - data.children[i]->data.pos = i; } // notification second @@ -361,94 +327,94 @@ void Node::move_child(Node *p_child, int p_pos) { data.children[i]->notification(NOTIFICATION_MOVED_IN_PARENT); } for (const Map<StringName, GroupData>::Element *E = p_child->data.grouped.front(); E; E = E->next()) { - if (E->get().group) + if (E->get().group) { E->get().group->changed = true; + } } data.blocked--; } void Node::raise() { - - if (!data.parent) + if (!data.parent) { return; + } data.parent->move_child(this, data.parent->data.children.size() - 1); } void Node::add_child_notify(Node *p_child) { - // to be used when not wanted } void Node::remove_child_notify(Node *p_child) { - // to be used when not wanted } void Node::move_child_notify(Node *p_child) { - // to be used when not wanted } void Node::set_physics_process(bool p_process) { - - if (data.physics_process == p_process) + if (data.physics_process == p_process) { return; + } data.physics_process = p_process; - if (data.physics_process) + if (data.physics_process) { add_to_group("physics_process", false); - else + } else { remove_from_group("physics_process"); + } _change_notify("physics_process"); } bool Node::is_physics_processing() const { - return data.physics_process; } void Node::set_physics_process_internal(bool p_process_internal) { - - if (data.physics_process_internal == p_process_internal) + if (data.physics_process_internal == p_process_internal) { return; + } data.physics_process_internal = p_process_internal; - if (data.physics_process_internal) + if (data.physics_process_internal) { add_to_group("physics_process_internal", false); - else + } else { remove_from_group("physics_process_internal"); + } _change_notify("physics_process_internal"); } bool Node::is_physics_processing_internal() const { - return data.physics_process_internal; } void Node::set_pause_mode(PauseMode p_mode) { - - if (data.pause_mode == p_mode) + if (data.pause_mode == p_mode) { return; + } bool prev_inherits = data.pause_mode == PAUSE_MODE_INHERIT; data.pause_mode = p_mode; - if (!is_inside_tree()) + if (!is_inside_tree()) { return; //pointless - if ((data.pause_mode == PAUSE_MODE_INHERIT) == prev_inherits) + } + if ((data.pause_mode == PAUSE_MODE_INHERIT) == prev_inherits) { return; ///nothing changed + } - Node *owner = NULL; + Node *owner = nullptr; if (data.pause_mode == PAUSE_MODE_INHERIT) { - - if (data.parent) + if (data.parent) { owner = data.parent->data.pause_owner; + } } else { owner = this; } @@ -457,40 +423,34 @@ void Node::set_pause_mode(PauseMode p_mode) { } Node::PauseMode Node::get_pause_mode() const { - return data.pause_mode; } void Node::_propagate_pause_owner(Node *p_owner) { - - if (this != p_owner && data.pause_mode != PAUSE_MODE_INHERIT) + if (this != p_owner && data.pause_mode != PAUSE_MODE_INHERIT) { return; + } data.pause_owner = p_owner; for (int i = 0; i < data.children.size(); i++) { - data.children[i]->_propagate_pause_owner(p_owner); } } void Node::set_network_master(int p_peer_id, bool p_recursive) { - data.network_master = p_peer_id; if (p_recursive) { for (int i = 0; i < data.children.size(); i++) { - data.children[i]->set_network_master(p_peer_id, true); } } } int Node::get_network_master() const { - return data.network_master; } bool Node::is_network_master() const { - ERR_FAIL_COND_V(!is_inside_tree(), false); return get_multiplayer()->get_network_unique_id() == data.network_master; @@ -498,34 +458,48 @@ bool Node::is_network_master() const { /***** RPC CONFIG ********/ -void Node::rpc_config(const StringName &p_method, MultiplayerAPI::RPCMode p_mode) { - - if (p_mode == MultiplayerAPI::RPC_MODE_DISABLED) { - data.rpc_methods.erase(p_method); +uint16_t Node::rpc_config(const StringName &p_method, MultiplayerAPI::RPCMode p_mode) { + uint16_t mid = get_node_rpc_method_id(p_method); + if (mid == UINT16_MAX) { + // It's new + NetData nd; + nd.name = p_method; + nd.mode = p_mode; + data.rpc_methods.push_back(nd); + return ((uint16_t)data.rpc_properties.size() - 1) | (1 << 15); } else { - data.rpc_methods[p_method] = p_mode; - }; + int c_mid = (~(1 << 15)) & mid; + data.rpc_methods.write[c_mid].mode = p_mode; + return mid; + } } -void Node::rset_config(const StringName &p_property, MultiplayerAPI::RPCMode p_mode) { - - if (p_mode == MultiplayerAPI::RPC_MODE_DISABLED) { - data.rpc_properties.erase(p_property); +uint16_t Node::rset_config(const StringName &p_property, MultiplayerAPI::RPCMode p_mode) { + uint16_t pid = get_node_rset_property_id(p_property); + if (pid == UINT16_MAX) { + // It's new + NetData nd; + nd.name = p_property; + nd.mode = p_mode; + data.rpc_properties.push_back(nd); + return ((uint16_t)data.rpc_properties.size() - 1) | (1 << 15); } else { - data.rpc_properties[p_property] = p_mode; - }; + int c_pid = (~(1 << 15)) & pid; + data.rpc_properties.write[c_pid].mode = p_mode; + return pid; + } } /***** RPC FUNCTIONS ********/ void Node::rpc(const StringName &p_method, VARIANT_ARG_DECLARE) { - VARIANT_ARGPTRS; int argc = 0; for (int i = 0; i < VARIANT_ARG_MAX; i++) { - if (argptr[i]->get_type() == Variant::NIL) + if (argptr[i]->get_type() == Variant::NIL) { break; + } argc++; } @@ -533,13 +507,13 @@ void Node::rpc(const StringName &p_method, VARIANT_ARG_DECLARE) { } void Node::rpc_id(int p_peer_id, const StringName &p_method, VARIANT_ARG_DECLARE) { - VARIANT_ARGPTRS; int argc = 0; for (int i = 0; i < VARIANT_ARG_MAX; i++) { - if (argptr[i]->get_type() == Variant::NIL) + if (argptr[i]->get_type() == Variant::NIL) { break; + } argc++; } @@ -547,13 +521,13 @@ void Node::rpc_id(int p_peer_id, const StringName &p_method, VARIANT_ARG_DECLARE } void Node::rpc_unreliable(const StringName &p_method, VARIANT_ARG_DECLARE) { - VARIANT_ARGPTRS; int argc = 0; for (int i = 0; i < VARIANT_ARG_MAX; i++) { - if (argptr[i]->get_type() == Variant::NIL) + if (argptr[i]->get_type() == Variant::NIL) { break; + } argc++; } @@ -561,29 +535,28 @@ void Node::rpc_unreliable(const StringName &p_method, VARIANT_ARG_DECLARE) { } void Node::rpc_unreliable_id(int p_peer_id, const StringName &p_method, VARIANT_ARG_DECLARE) { - VARIANT_ARGPTRS; int argc = 0; for (int i = 0; i < VARIANT_ARG_MAX; i++) { - if (argptr[i]->get_type() == Variant::NIL) + if (argptr[i]->get_type() == Variant::NIL) { break; + } argc++; } rpcp(p_peer_id, true, p_method, argptr, argc); } -Variant Node::_rpc_bind(const Variant **p_args, int p_argcount, Variant::CallError &r_error) { - +Variant Node::_rpc_bind(const Variant **p_args, int p_argcount, Callable::CallError &r_error) { if (p_argcount < 1) { - r_error.error = Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; + r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; r_error.argument = 1; return Variant(); } if (p_args[0]->get_type() != Variant::STRING) { - r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; r_error.argument = 0; r_error.expected = Variant::STRING; return Variant(); @@ -593,27 +566,26 @@ Variant Node::_rpc_bind(const Variant **p_args, int p_argcount, Variant::CallErr rpcp(0, false, method, &p_args[1], p_argcount - 1); - r_error.error = Variant::CallError::CALL_OK; + r_error.error = Callable::CallError::CALL_OK; return Variant(); } -Variant Node::_rpc_id_bind(const Variant **p_args, int p_argcount, Variant::CallError &r_error) { - +Variant Node::_rpc_id_bind(const Variant **p_args, int p_argcount, Callable::CallError &r_error) { if (p_argcount < 2) { - r_error.error = Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; + r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; r_error.argument = 2; return Variant(); } if (p_args[0]->get_type() != Variant::INT) { - r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; r_error.argument = 0; r_error.expected = Variant::INT; return Variant(); } if (p_args[1]->get_type() != Variant::STRING) { - r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; r_error.argument = 1; r_error.expected = Variant::STRING; return Variant(); @@ -624,20 +596,19 @@ Variant Node::_rpc_id_bind(const Variant **p_args, int p_argcount, Variant::Call rpcp(peer_id, false, method, &p_args[2], p_argcount - 2); - r_error.error = Variant::CallError::CALL_OK; + r_error.error = Callable::CallError::CALL_OK; return Variant(); } -Variant Node::_rpc_unreliable_bind(const Variant **p_args, int p_argcount, Variant::CallError &r_error) { - +Variant Node::_rpc_unreliable_bind(const Variant **p_args, int p_argcount, Callable::CallError &r_error) { if (p_argcount < 1) { - r_error.error = Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; + r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; r_error.argument = 1; return Variant(); } if (p_args[0]->get_type() != Variant::STRING) { - r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; r_error.argument = 0; r_error.expected = Variant::STRING; return Variant(); @@ -647,27 +618,26 @@ Variant Node::_rpc_unreliable_bind(const Variant **p_args, int p_argcount, Varia rpcp(0, true, method, &p_args[1], p_argcount - 1); - r_error.error = Variant::CallError::CALL_OK; + r_error.error = Callable::CallError::CALL_OK; return Variant(); } -Variant Node::_rpc_unreliable_id_bind(const Variant **p_args, int p_argcount, Variant::CallError &r_error) { - +Variant Node::_rpc_unreliable_id_bind(const Variant **p_args, int p_argcount, Callable::CallError &r_error) { if (p_argcount < 2) { - r_error.error = Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; + r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; r_error.argument = 2; return Variant(); } if (p_args[0]->get_type() != Variant::INT) { - r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; r_error.argument = 0; r_error.expected = Variant::INT; return Variant(); } if (p_args[1]->get_type() != Variant::STRING) { - r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; r_error.argument = 1; r_error.expected = Variant::STRING; return Variant(); @@ -678,7 +648,7 @@ Variant Node::_rpc_unreliable_id_bind(const Variant **p_args, int p_argcount, Va rpcp(peer_id, true, method, &p_args[2], p_argcount - 2); - r_error.error = Variant::CallError::CALL_OK; + r_error.error = Callable::CallError::CALL_OK; return Variant(); } @@ -694,31 +664,29 @@ void Node::rsetp(int p_peer_id, bool p_unreliable, const StringName &p_property, /******** RSET *********/ void Node::rset(const StringName &p_property, const Variant &p_value) { - rsetp(0, false, p_property, p_value); } void Node::rset_id(int p_peer_id, const StringName &p_property, const Variant &p_value) { - rsetp(p_peer_id, false, p_property, p_value); } void Node::rset_unreliable(const StringName &p_property, const Variant &p_value) { - rsetp(0, true, p_property, p_value); } void Node::rset_unreliable_id(int p_peer_id, const StringName &p_property, const Variant &p_value) { - rsetp(p_peer_id, true, p_property, p_value); } //////////// end of rpc Ref<MultiplayerAPI> Node::get_multiplayer() const { - if (multiplayer.is_valid()) + if (multiplayer.is_valid()) { return multiplayer; - if (!is_inside_tree()) + } + if (!is_inside_tree()) { return Ref<MultiplayerAPI>(); + } return get_tree()->get_multiplayer(); } @@ -727,49 +695,140 @@ Ref<MultiplayerAPI> Node::get_custom_multiplayer() const { } void Node::set_custom_multiplayer(Ref<MultiplayerAPI> p_multiplayer) { - multiplayer = p_multiplayer; } -const Map<StringName, MultiplayerAPI::RPCMode>::Element *Node::get_node_rpc_mode(const StringName &p_method) { - return data.rpc_methods.find(p_method); +uint16_t Node::get_node_rpc_method_id(const StringName &p_method) const { + for (int i = 0; i < data.rpc_methods.size(); i++) { + if (data.rpc_methods[i].name == p_method) { + // Returns `i` with the high bit set to 1 so we know that this id comes + // from the node and not the script. + return i | (1 << 15); + } + } + return UINT16_MAX; +} + +StringName Node::get_node_rpc_method(const uint16_t p_rpc_method_id) const { + // Make sure this is a node generated ID. + if (((1 << 15) & p_rpc_method_id) > 0) { + int mid = (~(1 << 15)) & p_rpc_method_id; + if (mid < data.rpc_methods.size()) { + return data.rpc_methods[mid].name; + } + } + return StringName(); +} + +MultiplayerAPI::RPCMode Node::get_node_rpc_mode_by_id(const uint16_t p_rpc_method_id) const { + // Make sure this is a node generated ID. + if (((1 << 15) & p_rpc_method_id) > 0) { + int mid = (~(1 << 15)) & p_rpc_method_id; + if (mid < data.rpc_methods.size()) { + return data.rpc_methods[mid].mode; + } + } + return MultiplayerAPI::RPC_MODE_DISABLED; +} + +MultiplayerAPI::RPCMode Node::get_node_rpc_mode(const StringName &p_method) const { + return get_node_rpc_mode_by_id(get_node_rpc_method_id(p_method)); +} + +uint16_t Node::get_node_rset_property_id(const StringName &p_property) const { + for (int i = 0; i < data.rpc_properties.size(); i++) { + if (data.rpc_properties[i].name == p_property) { + // Returns `i` with the high bit set to 1 so we know that this id comes + // from the node and not the script. + return i | (1 << 15); + } + } + return UINT16_MAX; +} + +StringName Node::get_node_rset_property(const uint16_t p_rset_property_id) const { + // Make sure this is a node generated ID. + if (((1 << 15) & p_rset_property_id) > 0) { + int mid = (~(1 << 15)) & p_rset_property_id; + if (mid < data.rpc_properties.size()) { + return data.rpc_properties[mid].name; + } + } + return StringName(); +} + +MultiplayerAPI::RPCMode Node::get_node_rset_mode_by_id(const uint16_t p_rset_property_id) const { + if (((1 << 15) & p_rset_property_id) > 0) { + int mid = (~(1 << 15)) & p_rset_property_id; + if (mid < data.rpc_properties.size()) { + return data.rpc_properties[mid].mode; + } + } + return MultiplayerAPI::RPC_MODE_DISABLED; +} + +MultiplayerAPI::RPCMode Node::get_node_rset_mode(const StringName &p_property) const { + return get_node_rset_mode_by_id(get_node_rset_property_id(p_property)); } -const Map<StringName, MultiplayerAPI::RPCMode>::Element *Node::get_node_rset_mode(const StringName &p_property) { - return data.rpc_properties.find(p_property); +String Node::get_rpc_md5() const { + String rpc_list; + for (int i = 0; i < data.rpc_methods.size(); i += 1) { + rpc_list += String(data.rpc_methods[i].name); + } + for (int i = 0; i < data.rpc_properties.size(); i += 1) { + rpc_list += String(data.rpc_properties[i].name); + } + if (get_script_instance()) { + Vector<ScriptNetData> rpc = get_script_instance()->get_rpc_methods(); + for (int i = 0; i < rpc.size(); i += 1) { + rpc_list += String(rpc[i].name); + } + rpc = get_script_instance()->get_rset_properties(); + for (int i = 0; i < rpc.size(); i += 1) { + rpc_list += String(rpc[i].name); + } + } + return rpc_list.md5_text(); } bool Node::can_process_notification(int p_what) const { switch (p_what) { - case NOTIFICATION_PHYSICS_PROCESS: return data.physics_process; - case NOTIFICATION_PROCESS: return data.idle_process; - case NOTIFICATION_INTERNAL_PROCESS: return data.idle_process_internal; - case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: return data.physics_process_internal; + case NOTIFICATION_PHYSICS_PROCESS: + return data.physics_process; + case NOTIFICATION_PROCESS: + return data.idle_process; + case NOTIFICATION_INTERNAL_PROCESS: + return data.idle_process_internal; + case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: + return data.physics_process_internal; } return true; } bool Node::can_process() const { - ERR_FAIL_COND_V(!is_inside_tree(), false); if (get_tree()->is_paused()) { - - if (data.pause_mode == PAUSE_MODE_STOP) + if (data.pause_mode == PAUSE_MODE_STOP) { return false; - if (data.pause_mode == PAUSE_MODE_PROCESS) + } + if (data.pause_mode == PAUSE_MODE_PROCESS) { return true; + } if (data.pause_mode == PAUSE_MODE_INHERIT) { - - if (!data.pause_owner) + if (!data.pause_owner) { return false; //clearly no pause owner by default + } - if (data.pause_owner->data.pause_mode == PAUSE_MODE_PROCESS) + if (data.pause_owner->data.pause_mode == PAUSE_MODE_PROCESS) { return true; + } - if (data.pause_owner->data.pause_mode == PAUSE_MODE_STOP) + if (data.pause_owner->data.pause_mode == PAUSE_MODE_STOP) { return false; + } } } @@ -777,58 +836,58 @@ bool Node::can_process() const { } float Node::get_physics_process_delta_time() const { - - if (data.tree) + if (data.tree) { return data.tree->get_physics_process_time(); - else + } else { return 0; + } } float Node::get_process_delta_time() const { - - if (data.tree) + if (data.tree) { return data.tree->get_idle_process_time(); - else + } else { return 0; + } } void Node::set_process(bool p_idle_process) { - - if (data.idle_process == p_idle_process) + if (data.idle_process == p_idle_process) { return; + } data.idle_process = p_idle_process; - if (data.idle_process) + if (data.idle_process) { add_to_group("idle_process", false); - else + } else { remove_from_group("idle_process"); + } _change_notify("idle_process"); } bool Node::is_processing() const { - return data.idle_process; } void Node::set_process_internal(bool p_idle_process_internal) { - - if (data.idle_process_internal == p_idle_process_internal) + if (data.idle_process_internal == p_idle_process_internal) { return; + } data.idle_process_internal = p_idle_process_internal; - if (data.idle_process_internal) + if (data.idle_process_internal) { add_to_group("idle_process_internal", false); - else + } else { remove_from_group("idle_process_internal"); + } _change_notify("idle_process_internal"); } bool Node::is_processing_internal() const { - return data.idle_process_internal; } @@ -836,7 +895,7 @@ void Node::set_process_priority(int p_priority) { data.process_priority = p_priority; // Make sure we are in SceneTree. - if (data.tree == NULL) { + if (data.tree == nullptr) { return; } @@ -858,23 +917,24 @@ void Node::set_process_priority(int p_priority) { } int Node::get_process_priority() const { - return data.process_priority; } void Node::set_process_input(bool p_enable) { - - if (p_enable == data.input) + if (p_enable == data.input) { return; + } data.input = p_enable; - if (!is_inside_tree()) + if (!is_inside_tree()) { return; + } - if (p_enable) + if (p_enable) { add_to_group("_vp_input" + itos(get_viewport()->get_instance_id())); - else + } else { remove_from_group("_vp_input" + itos(get_viewport()->get_instance_id())); + } } bool Node::is_processing_input() const { @@ -882,17 +942,19 @@ bool Node::is_processing_input() const { } void Node::set_process_unhandled_input(bool p_enable) { - - if (p_enable == data.unhandled_input) + if (p_enable == data.unhandled_input) { return; + } data.unhandled_input = p_enable; - if (!is_inside_tree()) + if (!is_inside_tree()) { return; + } - if (p_enable) + if (p_enable) { add_to_group("_vp_unhandled_input" + itos(get_viewport()->get_instance_id())); - else + } else { remove_from_group("_vp_unhandled_input" + itos(get_viewport()->get_instance_id())); + } } bool Node::is_processing_unhandled_input() const { @@ -900,17 +962,19 @@ bool Node::is_processing_unhandled_input() const { } void Node::set_process_unhandled_key_input(bool p_enable) { - - if (p_enable == data.unhandled_key_input) + if (p_enable == data.unhandled_key_input) { return; + } data.unhandled_key_input = p_enable; - if (!is_inside_tree()) + if (!is_inside_tree()) { return; + } - if (p_enable) + if (p_enable) { add_to_group("_vp_unhandled_key_input" + itos(get_viewport()->get_instance_id())); - else + } else { remove_from_group("_vp_unhandled_key_input" + itos(get_viewport()->get_instance_id())); + } } bool Node::is_processing_unhandled_key_input() const { @@ -918,12 +982,10 @@ bool Node::is_processing_unhandled_key_input() const { } StringName Node::get_name() const { - return data.name; } void Node::_set_name_nocheck(const StringName &p_name) { - data.name = p_name; } @@ -941,7 +1003,6 @@ bool Node::_validate_node_name(String &p_name) { } void Node::set_name(const String &p_name) { - String name = p_name; _validate_node_name(name); @@ -949,14 +1010,12 @@ void Node::set_name(const String &p_name) { data.name = name; if (data.parent) { - data.parent->_validate_child_name(this); } propagate_notification(NOTIFICATION_PATH_CHANGED); if (is_inside_tree()) { - emit_signal("renamed"); get_tree()->node_renamed(this); get_tree()->tree_changed(); @@ -971,13 +1030,11 @@ void Node::init_node_hrcr() { } void Node::set_human_readable_collision_renaming(bool p_enabled) { - node_hrcr = p_enabled; } #ifdef TOOLS_ENABLED String Node::validate_child_name(Node *p_child) { - StringName name = p_child->data.name; _generate_serial_child_name(p_child, name); return name; @@ -985,11 +1042,9 @@ String Node::validate_child_name(Node *p_child) { #endif void Node::_validate_child_name(Node *p_child, bool p_force_human_readable) { - /* Make sure the name is unique */ if (node_hrcr || p_force_human_readable) { - //this approach to autoset node names is human readable but very slow //it's turned on while running in the editor @@ -998,13 +1053,12 @@ void Node::_validate_child_name(Node *p_child, bool p_force_human_readable) { p_child->data.name = name; } else { - //this approach to autoset node names is fast but not as readable //it's the default and reserves the '@' character for unique names. bool unique = true; - if (p_child->data.name == StringName() || p_child->data.name.operator String()[0] == '@') { + if (p_child->data.name == StringName()) { //new unique name must be assigned unique = false; } else { @@ -1013,8 +1067,9 @@ void Node::_validate_child_name(Node *p_child, bool p_force_human_readable) { int cc = data.children.size(); for (int i = 0; i < cc; i++) { - if (children[i] == p_child) + if (children[i] == p_child) { continue; + } if (children[i]->data.name == p_child->data.name) { unique = false; break; @@ -1023,7 +1078,6 @@ void Node::_validate_child_name(Node *p_child, bool p_force_human_readable) { } if (!unique) { - ERR_FAIL_COND(!node_hrcr_count.ref()); String name = "@" + String(p_child->get_name()) + "@" + itos(node_hrcr_count.get()); p_child->data.name = name; @@ -1033,7 +1087,6 @@ void Node::_validate_child_name(Node *p_child, bool p_force_human_readable) { // Return s + 1 as if it were an integer String increase_numeric_string(const String &s) { - String res = s; bool carry = res.length() > 0; @@ -1041,7 +1094,7 @@ String increase_numeric_string(const String &s) { if (!carry) { break; } - CharType n = s[i]; + char32_t n = s[i]; if (n == '9') { // keep carry as true: 9 + 1 res[i] = '0'; } else { @@ -1058,7 +1111,6 @@ String increase_numeric_string(const String &s) { } void Node::_generate_serial_child_name(const Node *p_child, StringName &name) const { - if (name == StringName()) { //no name and a new nade is needed, create one. @@ -1083,7 +1135,6 @@ void Node::_generate_serial_child_name(const Node *p_child, StringName &name) co const Node *const *children_ptr = data.children.ptr(); { - bool exists = false; for (int i = 0; i < cc; i++) { @@ -1104,7 +1155,7 @@ void Node::_generate_serial_child_name(const Node *p_child, StringName &name) co String name_string = name; String nums; for (int i = name_string.length() - 1; i >= 0; i--) { - CharType n = name_string[i]; + char32_t n = name_string[i]; if (n >= '0' && n <= '9') { nums = String::chr(name_string[i]) + nums; } else { @@ -1170,7 +1221,6 @@ void Node::_add_child_nocheck(Node *p_child, const StringName &p_name) { } void Node::add_child(Node *p_child, bool p_legible_unique_name) { - ERR_FAIL_NULL(p_child); ERR_FAIL_COND_MSG(p_child == this, "Can't add child '" + p_child->get_name() + "' to itself."); // adding to itself! ERR_FAIL_COND_MSG(p_child->data.parent, "Can't add child '" + p_child->get_name() + "' to '" + get_name() + "', already has a parent '" + p_child->data.parent->get_name() + "'."); //Fail if node has a parent @@ -1182,31 +1232,22 @@ void Node::add_child(Node *p_child, bool p_legible_unique_name) { _add_child_nocheck(p_child, p_child->data.name); } -void Node::add_child_below_node(Node *p_node, Node *p_child, bool p_legible_unique_name) { - - ERR_FAIL_NULL(p_node); - ERR_FAIL_NULL(p_child); - - add_child(p_child, p_legible_unique_name); +void Node::add_sibling(Node *p_sibling, bool p_legible_unique_name) { + ERR_FAIL_NULL(p_sibling); + ERR_FAIL_COND_MSG(p_sibling == this, "Can't add sibling '" + p_sibling->get_name() + "' to itself."); // adding to itself! + ERR_FAIL_COND_MSG(data.blocked > 0, "Parent node is busy setting up children, add_sibling() failed. Consider using call_deferred(\"add_sibling\", sibling) instead."); - if (is_a_parent_of(p_node)) { - move_child(p_child, p_node->get_position_in_parent() + 1); - } else { - WARN_PRINTS("Cannot move under node " + p_node->get_name() + " as " + p_child->get_name() + " does not share a parent."); - } + get_parent()->add_child(p_sibling, p_legible_unique_name); + get_parent()->move_child(p_sibling, this->get_index() + 1); } void Node::_propagate_validate_owner() { - if (data.owner) { - bool found = false; Node *parent = data.parent; while (parent) { - if (parent == data.owner) { - found = true; break; } @@ -1215,20 +1256,17 @@ void Node::_propagate_validate_owner() { } if (!found) { - data.owner->data.owned.erase(data.OW); - data.owner = NULL; + data.owner = nullptr; } } for (int i = 0; i < data.children.size(); i++) { - data.children[i]->_propagate_validate_owner(); } } void Node::remove_child(Node *p_child) { - ERR_FAIL_NULL(p_child); ERR_FAIL_COND_MSG(data.blocked > 0, "Parent node is busy setting up children, remove_node() failed. Consider using call_deferred(\"remove_child\", child) instead."); @@ -1244,9 +1282,7 @@ void Node::remove_child(Node *p_child) { if (idx == -1) { //maybe removed while unparenting or something and index was not updated, so just in case the above fails, try this. for (int i = 0; i < child_count; i++) { - if (children[i] == p_child) { - idx = i; break; } @@ -1258,7 +1294,7 @@ void Node::remove_child(Node *p_child) { //if (data.scene) { does not matter - p_child->_set_tree(NULL); + p_child->_set_tree(nullptr); //} remove_child_notify(p_child); @@ -1271,12 +1307,11 @@ void Node::remove_child(Node *p_child) { children = data.children.ptrw(); for (int i = idx; i < child_count; i++) { - children[i]->data.pos = i; children[i]->notification(NOTIFICATION_MOVED_IN_PARENT); } - p_child->data.parent = NULL; + p_child->data.parent = nullptr; p_child->data.pos = -1; // validate owner @@ -1288,53 +1323,53 @@ void Node::remove_child(Node *p_child) { } int Node::get_child_count() const { - return data.children.size(); } -Node *Node::get_child(int p_index) const { - ERR_FAIL_INDEX_V(p_index, data.children.size(), NULL); +Node *Node::get_child(int p_index) const { + if (p_index < 0) { + p_index += data.children.size(); + } + ERR_FAIL_INDEX_V(p_index, data.children.size(), nullptr); return data.children[p_index]; } Node *Node::_get_child_by_name(const StringName &p_name) const { - int cc = data.children.size(); Node *const *cd = data.children.ptr(); for (int i = 0; i < cc; i++) { - if (cd[i]->data.name == p_name) + if (cd[i]->data.name == p_name) { return cd[i]; + } } - return NULL; + return nullptr; } Node *Node::get_node_or_null(const NodePath &p_path) const { - if (p_path.is_empty()) { - return NULL; + return nullptr; } - ERR_FAIL_COND_V_MSG(!data.inside_tree && p_path.is_absolute(), NULL, "Can't use get_node() with absolute paths from outside the active scene tree."); + ERR_FAIL_COND_V_MSG(!data.inside_tree && p_path.is_absolute(), nullptr, "Can't use get_node() with absolute paths from outside the active scene tree."); - Node *current = NULL; - Node *root = NULL; + Node *current = nullptr; + Node *root = nullptr; if (!p_path.is_absolute()) { current = const_cast<Node *>(this); //start from this } else { - root = const_cast<Node *>(this); - while (root->data.parent) + while (root->data.parent) { root = root->data.parent; //start from root + } } for (int i = 0; i < p_path.get_name_count(); i++) { - StringName name = p_path.get_name(i); - Node *next = NULL; + Node *next = nullptr; if (name == SceneStringNames::get_singleton()->dot) { // . @@ -1342,31 +1377,29 @@ Node *Node::get_node_or_null(const NodePath &p_path) const { } else if (name == SceneStringNames::get_singleton()->doubledot) { // .. - if (current == NULL || !current->data.parent) - return NULL; + if (current == nullptr || !current->data.parent) { + return nullptr; + } next = current->data.parent; - } else if (current == NULL) { - - if (name == root->get_name()) + } else if (current == nullptr) { + if (name == root->get_name()) { next = root; + } } else { - - next = NULL; + next = nullptr; for (int j = 0; j < current->data.children.size(); j++) { - Node *child = current->data.children[j]; if (child->data.name == name) { - next = child; break; } } - if (next == NULL) { - return NULL; + if (next == nullptr) { + return nullptr; }; } current = next; @@ -1376,63 +1409,61 @@ Node *Node::get_node_or_null(const NodePath &p_path) const { } Node *Node::get_node(const NodePath &p_path) const { - Node *node = get_node_or_null(p_path); - ERR_FAIL_COND_V_MSG(!node, NULL, "Node not found: " + p_path + "."); + ERR_FAIL_COND_V_MSG(!node, nullptr, "Node not found: " + p_path + "."); return node; } bool Node::has_node(const NodePath &p_path) const { - - return get_node_or_null(p_path) != NULL; + return get_node_or_null(p_path) != nullptr; } Node *Node::find_node(const String &p_mask, bool p_recursive, bool p_owned) const { - Node *const *cptr = data.children.ptr(); int ccount = data.children.size(); for (int i = 0; i < ccount; i++) { - if (p_owned && !cptr[i]->data.owner) + if (p_owned && !cptr[i]->data.owner) { continue; - if (cptr[i]->data.name.operator String().match(p_mask)) + } + if (cptr[i]->data.name.operator String().match(p_mask)) { return cptr[i]; + } - if (!p_recursive) + if (!p_recursive) { continue; + } Node *ret = cptr[i]->find_node(p_mask, true, p_owned); - if (ret) + if (ret) { return ret; + } } - return NULL; + return nullptr; } Node *Node::get_parent() const { - return data.parent; } Node *Node::find_parent(const String &p_mask) const { - Node *p = data.parent; while (p) { - - if (p->data.name.operator String().match(p_mask)) + if (p->data.name.operator String().match(p_mask)) { return p; + } p = p->data.parent; } - return NULL; + return nullptr; } bool Node::is_a_parent_of(const Node *p_node) const { - ERR_FAIL_NULL_V(p_node, false); Node *p = p_node->data.parent; while (p) { - - if (p == this) + if (p == this) { return true; + } p = p->data.parent; } @@ -1440,7 +1471,6 @@ bool Node::is_a_parent_of(const Node *p_node) const { } bool Node::is_greater_than(const Node *p_node) const { - ERR_FAIL_NULL_V(p_node, false); ERR_FAIL_COND_V(!data.inside_tree, false); ERR_FAIL_COND_V(!p_node->data.inside_tree, false); @@ -1483,7 +1513,6 @@ bool Node::is_greater_than(const Node *p_node) const { bool res; while (true) { - // using -2 since out-of-tree or nonroot nodes have -1 int this_idx = (idx >= data.depth) ? -2 : this_stack[idx]; int that_idx = (idx >= p_node->data.depth) ? -2 : that_stack[idx]; @@ -1505,18 +1534,19 @@ bool Node::is_greater_than(const Node *p_node) const { } void Node::get_owned_by(Node *p_by, List<Node *> *p_owned) { - - if (data.owner == p_by) + if (data.owner == p_by) { p_owned->push_back(this); + } - for (int i = 0; i < get_child_count(); i++) + for (int i = 0; i < get_child_count(); i++) { get_child(i)->get_owned_by(p_by, p_owned); + } } void Node::_set_owner_nocheck(Node *p_owner) { - - if (data.owner == p_owner) + if (data.owner == p_owner) { return; + } ERR_FAIL_COND(data.owner); data.owner = p_owner; @@ -1525,24 +1555,22 @@ void Node::_set_owner_nocheck(Node *p_owner) { } void Node::set_owner(Node *p_owner) { - if (data.owner) { - data.owner->data.owned.erase(data.OW); - data.OW = NULL; - data.owner = NULL; + data.OW = nullptr; + data.owner = nullptr; } ERR_FAIL_COND(p_owner == this); - if (!p_owner) + if (!p_owner) { return; + } Node *check = this->get_parent(); bool owner_valid = false; while (check) { - if (check == p_owner) { owner_valid = true; break; @@ -1555,22 +1583,21 @@ void Node::set_owner(Node *p_owner) { _set_owner_nocheck(p_owner); } -Node *Node::get_owner() const { +Node *Node::get_owner() const { return data.owner; } Node *Node::find_common_parent_with(const Node *p_node) const { - - if (this == p_node) + if (this == p_node) { return const_cast<Node *>(p_node); + } Set<const Node *> visited; const Node *n = this; while (n) { - visited.insert(n); n = n->data.parent; } @@ -1578,31 +1605,31 @@ Node *Node::find_common_parent_with(const Node *p_node) const { const Node *common_parent = p_node; while (common_parent) { - - if (visited.has(common_parent)) + if (visited.has(common_parent)) { break; + } common_parent = common_parent->data.parent; } - if (!common_parent) - return NULL; + if (!common_parent) { + return nullptr; + } return const_cast<Node *>(common_parent); } NodePath Node::get_path_to(const Node *p_node) const { - ERR_FAIL_NULL_V(p_node, NodePath()); - if (this == p_node) + if (this == p_node) { return NodePath("."); + } Set<const Node *> visited; const Node *n = this; while (n) { - visited.insert(n); n = n->data.parent; } @@ -1610,9 +1637,9 @@ NodePath Node::get_path_to(const Node *p_node) const { const Node *common_parent = p_node; while (common_parent) { - - if (visited.has(common_parent)) + if (visited.has(common_parent)) { break; + } common_parent = common_parent->data.parent; } @@ -1625,7 +1652,6 @@ NodePath Node::get_path_to(const Node *p_node) const { n = p_node; while (n != common_parent) { - path.push_back(n->get_name()); n = n->data.parent; } @@ -1634,7 +1660,6 @@ NodePath Node::get_path_to(const Node *p_node) const { StringName up = String(".."); while (n != common_parent) { - path.push_back(up); n = n->data.parent; } @@ -1645,11 +1670,11 @@ NodePath Node::get_path_to(const Node *p_node) const { } NodePath Node::get_path() const { - ERR_FAIL_COND_V_MSG(!is_inside_tree(), NodePath(), "Cannot get path of node as it is not in a scene tree."); - if (data.path_cache) + if (data.path_cache) { return *data.path_cache; + } const Node *n = this; @@ -1668,23 +1693,22 @@ NodePath Node::get_path() const { } bool Node::is_in_group(const StringName &p_identifier) const { - return data.grouped.has(p_identifier); } void Node::add_to_group(const StringName &p_identifier, bool p_persistent) { - ERR_FAIL_COND(!p_identifier.operator String().length()); - if (data.grouped.has(p_identifier)) + if (data.grouped.has(p_identifier)) { return; + } GroupData gd; if (data.tree) { gd.group = data.tree->add_to_group(p_identifier, this); } else { - gd.group = NULL; + gd.group = nullptr; } gd.persistent = p_persistent; @@ -1693,21 +1717,20 @@ void Node::add_to_group(const StringName &p_identifier, bool p_persistent) { } void Node::remove_from_group(const StringName &p_identifier) { - ERR_FAIL_COND(!data.grouped.has(p_identifier)); Map<StringName, GroupData>::Element *E = data.grouped.find(p_identifier); ERR_FAIL_COND(!E); - if (data.tree) + if (data.tree) { data.tree->remove_from_group(E->key(), this); + } data.grouped.erase(E); } Array Node::_get_groups() const { - Array groups; List<GroupInfo> gi; get_groups(&gi); @@ -1719,7 +1742,6 @@ Array Node::_get_groups() const { } void Node::get_groups(List<GroupInfo> *p_groups) const { - for (const Map<StringName, GroupData>::Element *E = data.grouped.front(); E; E = E->next()) { GroupInfo gi; gi.name = E->key(); @@ -1729,7 +1751,6 @@ void Node::get_groups(List<GroupInfo> *p_groups) const { } int Node::get_persistent_group_count() const { - int count = 0; for (const Map<StringName, GroupData>::Element *E = data.grouped.front(); E; E = E->next()) { @@ -1740,8 +1761,8 @@ int Node::get_persistent_group_count() const { return count; } -void Node::_print_tree_pretty(const String &prefix, const bool last) { +void Node::_print_tree_pretty(const String &prefix, const bool last) { String new_prefix = last ? String::utf8(" ┖╴") : String::utf8(" ┠╴"); print_line(prefix + new_prefix + String(get_name())); for (int i = 0; i < data.children.size(); i++) { @@ -1755,21 +1776,19 @@ void Node::print_tree_pretty() { } void Node::print_tree() { - _print_tree(this); } void Node::_print_tree(const Node *p_node) { print_line(String(p_node->get_path_to(this))); - for (int i = 0; i < data.children.size(); i++) + for (int i = 0; i < data.children.size(); i++) { data.children[i]->_print_tree(p_node); + } } void Node::_propagate_reverse_notification(int p_notification) { - data.blocked++; for (int i = data.children.size() - 1; i >= 0; i--) { - data.children[i]->_propagate_reverse_notification(p_notification); } @@ -1778,70 +1797,70 @@ void Node::_propagate_reverse_notification(int p_notification) { } void Node::_propagate_deferred_notification(int p_notification, bool p_reverse) { - ERR_FAIL_COND(!is_inside_tree()); data.blocked++; - if (!p_reverse) + if (!p_reverse) { MessageQueue::get_singleton()->push_notification(this, p_notification); + } for (int i = 0; i < data.children.size(); i++) { - data.children[i]->_propagate_deferred_notification(p_notification, p_reverse); } - if (p_reverse) + if (p_reverse) { MessageQueue::get_singleton()->push_notification(this, p_notification); + } data.blocked--; } void Node::propagate_notification(int p_notification) { - data.blocked++; notification(p_notification); for (int i = 0; i < data.children.size(); i++) { - data.children[i]->propagate_notification(p_notification); } data.blocked--; } void Node::propagate_call(const StringName &p_method, const Array &p_args, const bool p_parent_first) { - data.blocked++; - if (p_parent_first && has_method(p_method)) + if (p_parent_first && has_method(p_method)) { callv(p_method, p_args); + } for (int i = 0; i < data.children.size(); i++) { data.children[i]->propagate_call(p_method, p_args, p_parent_first); } - if (!p_parent_first && has_method(p_method)) + if (!p_parent_first && has_method(p_method)) { callv(p_method, p_args); + } data.blocked--; } void Node::_propagate_replace_owner(Node *p_owner, Node *p_by_owner) { - if (get_owner() == p_owner) + if (get_owner() == p_owner) { set_owner(p_by_owner); + } data.blocked++; - for (int i = 0; i < data.children.size(); i++) + for (int i = 0; i < data.children.size(); i++) { data.children[i]->_propagate_replace_owner(p_owner, p_by_owner); + } data.blocked--; } int Node::get_index() const { - return data.pos; } -void Node::remove_and_skip() { +void Node::remove_and_skip() { ERR_FAIL_COND(!data.parent); Node *new_owner = get_owner(); @@ -1849,29 +1868,29 @@ void Node::remove_and_skip() { List<Node *> children; while (true) { - bool clear = true; for (int i = 0; i < data.children.size(); i++) { Node *c_node = data.children[i]; - if (!c_node->get_owner()) + if (!c_node->get_owner()) { continue; + } remove_child(c_node); - c_node->_propagate_replace_owner(this, NULL); + c_node->_propagate_replace_owner(this, nullptr); children.push_back(c_node); clear = false; break; } - if (clear) + if (clear) { break; + } } while (!children.empty()) { - Node *c_node = children.front()->get(); data.parent->add_child(c_node); - c_node->_propagate_replace_owner(NULL, new_owner); + c_node->_propagate_replace_owner(nullptr, new_owner); children.pop_front(); } @@ -1879,20 +1898,18 @@ void Node::remove_and_skip() { } void Node::set_filename(const String &p_filename) { - data.filename = p_filename; } -String Node::get_filename() const { +String Node::get_filename() const { return data.filename; } void Node::set_editor_description(const String &p_editor_description) { - set_meta("_editor_description_", p_editor_description); } -String Node::get_editor_description() const { +String Node::get_editor_description() const { if (has_meta("_editor_description_")) { return get_meta("_editor_description_"); } else { @@ -1901,7 +1918,6 @@ String Node::get_editor_description() const { } void Node::set_editable_instance(Node *p_node, bool p_editable) { - ERR_FAIL_NULL(p_node); ERR_FAIL_COND(!is_a_parent_of(p_node)); NodePath p = get_path_to(p_node); @@ -1916,94 +1932,79 @@ void Node::set_editable_instance(Node *p_node, bool p_editable) { } bool Node::is_editable_instance(const Node *p_node) const { - - if (!p_node) + if (!p_node) { return false; //easier, null is never editable :) + } ERR_FAIL_COND_V(!is_a_parent_of(p_node), false); NodePath p = get_path_to(p_node); return data.editable_instances.has(p); } void Node::set_editable_instances(const HashMap<NodePath, int> &p_editable_instances) { - data.editable_instances = p_editable_instances; } HashMap<NodePath, int> Node::get_editable_instances() const { - return data.editable_instances; } void Node::set_scene_instance_state(const Ref<SceneState> &p_state) { - data.instance_state = p_state; } Ref<SceneState> Node::get_scene_instance_state() const { - return data.instance_state; } void Node::set_scene_inherited_state(const Ref<SceneState> &p_state) { - data.inherited_state = p_state; } Ref<SceneState> Node::get_scene_inherited_state() const { - return data.inherited_state; } void Node::set_scene_instance_load_placeholder(bool p_enable) { - data.use_placeholder = p_enable; } bool Node::get_scene_instance_load_placeholder() const { - return data.use_placeholder; } -int Node::get_position_in_parent() const { - - return data.pos; -} - Node *Node::_duplicate(int p_flags, Map<const Node *, Node *> *r_duplimap) const { - - Node *node = NULL; + Node *node = nullptr; bool instanced = false; if (Object::cast_to<InstancePlaceholder>(this)) { - const InstancePlaceholder *ip = Object::cast_to<const InstancePlaceholder>(this); InstancePlaceholder *nip = memnew(InstancePlaceholder); nip->set_instance_path(ip->get_instance_path()); node = nip; } else if ((p_flags & DUPLICATE_USE_INSTANCING) && get_filename() != String()) { - Ref<PackedScene> res = ResourceLoader::load(get_filename()); - ERR_FAIL_COND_V(res.is_null(), NULL); + ERR_FAIL_COND_V(res.is_null(), nullptr); PackedScene::GenEditState ges = PackedScene::GEN_EDIT_STATE_DISABLED; #ifdef TOOLS_ENABLED - if (p_flags & DUPLICATE_FROM_EDITOR) + if (p_flags & DUPLICATE_FROM_EDITOR) { ges = PackedScene::GEN_EDIT_STATE_INSTANCE; + } #endif node = res->instance(ges); - ERR_FAIL_COND_V(!node, NULL); + ERR_FAIL_COND_V(!node, nullptr); instanced = true; } else { - Object *obj = ClassDB::instance(get_class()); - ERR_FAIL_COND_V(!obj, NULL); + ERR_FAIL_COND_V(!obj, nullptr); node = Object::cast_to<Node>(obj); - if (!node) + if (!node) { memdelete(obj); - ERR_FAIL_COND_V(!node, NULL); + } + ERR_FAIL_COND_V(!node, nullptr); } if (get_filename() != "") { //an instance @@ -2022,13 +2023,13 @@ Node *Node::_duplicate(int p_flags, Map<const Node *, Node *> *r_duplimap) const for (List<const Node *>::Element *N = node_tree.front(); N; N = N->next()) { for (int i = 0; i < N->get()->get_child_count(); ++i) { - Node *descendant = N->get()->get_child(i); // Skip nodes not really belonging to the instanced hierarchy; they'll be processed normally later // but remember non-instanced nodes that are hidden below instanced ones if (descendant->data.owner != this) { - if (descendant->get_parent() && descendant->get_parent() != this && descendant->get_parent()->data.owner == this && descendant->data.owner != descendant->get_parent()) + if (descendant->get_parent() && descendant->get_parent() != this && descendant->get_parent()->data.owner == this && descendant->data.owner != descendant->get_parent()) { hidden_roots.push_back(descendant); + } continue; } @@ -2038,7 +2039,6 @@ Node *Node::_duplicate(int p_flags, Map<const Node *, Node *> *r_duplimap) const } for (List<const Node *>::Element *N = node_tree.front(); N; N = N->next()) { - Node *current_node = node->get_node(get_path_to(N->get())); ERR_CONTINUE(!current_node); @@ -2054,24 +2054,23 @@ Node *Node::_duplicate(int p_flags, Map<const Node *, Node *> *r_duplimap) const N->get()->get_property_list(&plist); for (List<PropertyInfo>::Element *E = plist.front(); E; E = E->next()) { - - if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) + if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) { continue; + } String name = E->get().name; - if (name == script_property_name) + if (name == script_property_name) { continue; + } Variant value = N->get()->get(name).duplicate(true); if (E->get().usage & PROPERTY_USAGE_DO_NOT_SHARE_ON_DUPLICATE) { - Resource *res = Object::cast_to<Resource>(value); if (res) { // Duplicate only if it's a resource current_node->set(name, res->duplicate()); } } else { - current_node->set(name, value); } } @@ -2082,18 +2081,19 @@ Node *Node::_duplicate(int p_flags, Map<const Node *, Node *> *r_duplimap) const } #ifdef TOOLS_ENABLED - if ((p_flags & DUPLICATE_FROM_EDITOR) && r_duplimap) + if ((p_flags & DUPLICATE_FROM_EDITOR) && r_duplimap) { r_duplimap->insert(this, node); + } #endif if (p_flags & DUPLICATE_GROUPS) { List<GroupInfo> gi; get_groups(&gi); for (List<GroupInfo>::Element *E = gi.front(); E; E = E->next()) { - #ifdef TOOLS_ENABLED - if ((p_flags & DUPLICATE_FROM_EDITOR) && !E->get().persistent) + if ((p_flags & DUPLICATE_FROM_EDITOR) && !E->get().persistent) { continue; + } #endif node->add_to_group(E->get().name, E->get().persistent); @@ -2101,17 +2101,17 @@ Node *Node::_duplicate(int p_flags, Map<const Node *, Node *> *r_duplimap) const } for (int i = 0; i < get_child_count(); i++) { - - if (get_child(i)->data.parent_owned) + if (get_child(i)->data.parent_owned) { continue; - if (instanced && get_child(i)->data.owner == this) + } + if (instanced && get_child(i)->data.owner == this) { continue; //part of instance + } Node *dup = get_child(i)->_duplicate(p_flags, r_duplimap); if (!dup) { - memdelete(node); - return NULL; + return nullptr; } node->add_child(dup); @@ -2121,26 +2121,22 @@ Node *Node::_duplicate(int p_flags, Map<const Node *, Node *> *r_duplimap) const } for (List<const Node *>::Element *E = hidden_roots.front(); E; E = E->next()) { - Node *parent = node->get_node(get_path_to(E->get()->data.parent)); if (!parent) { - memdelete(node); - return NULL; + return nullptr; } Node *dup = E->get()->_duplicate(p_flags, r_duplimap); if (!dup) { - memdelete(node); - return NULL; + return nullptr; } parent->add_child(dup); - int pos = E->get()->get_position_in_parent(); + int pos = E->get()->get_index(); if (pos < parent->get_child_count() - 1) { - parent->move_child(dup, pos); } } @@ -2149,7 +2145,6 @@ Node *Node::_duplicate(int p_flags, Map<const Node *, Node *> *r_duplimap) const } Node *Node::duplicate(int p_flags) const { - Node *dupe = _duplicate(p_flags); if (dupe && (p_flags & DUPLICATE_SIGNALS)) { @@ -2161,7 +2156,6 @@ Node *Node::duplicate(int p_flags) const { #ifdef TOOLS_ENABLED Node *Node::duplicate_from_editor(Map<const Node *, Node *> &r_duplimap) const { - Node *dupe = _duplicate(DUPLICATE_SIGNALS | DUPLICATE_GROUPS | DUPLICATE_SCRIPTS | DUPLICATE_USE_INSTANCING | DUPLICATE_FROM_EDITOR, &r_duplimap); // Duplication of signals must happen after all the node descendants have been copied, @@ -2174,20 +2168,18 @@ Node *Node::duplicate_from_editor(Map<const Node *, Node *> &r_duplimap) const { #endif void Node::_duplicate_and_reown(Node *p_new_parent, const Map<Node *, Node *> &p_reown_map) const { - - if (get_owner() != get_parent()->get_owner()) + if (get_owner() != get_parent()->get_owner()) { return; + } - Node *node = NULL; + Node *node = nullptr; if (get_filename() != "") { - Ref<PackedScene> res = ResourceLoader::load(get_filename()); ERR_FAIL_COND_MSG(res.is_null(), "Cannot load scene: " + get_filename()); node = res->instance(); ERR_FAIL_COND(!node); } else { - Object *obj = ClassDB::instance(get_class()); ERR_FAIL_COND_MSG(!obj, "Node: Could not duplicate: " + String(get_class()) + "."); node = Object::cast_to<Node>(obj); @@ -2202,9 +2194,9 @@ void Node::_duplicate_and_reown(Node *p_new_parent, const Map<Node *, Node *> &p get_property_list(&plist); for (List<PropertyInfo>::Element *E = plist.front(); E; E = E->next()) { - - if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) + if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) { continue; + } String name = E->get().name; Variant value = get(name).duplicate(true); @@ -2215,16 +2207,18 @@ void Node::_duplicate_and_reown(Node *p_new_parent, const Map<Node *, Node *> &p List<GroupInfo> groups; get_groups(&groups); - for (List<GroupInfo>::Element *E = groups.front(); E; E = E->next()) + for (List<GroupInfo>::Element *E = groups.front(); E; E = E->next()) { node->add_to_group(E->get().name, E->get().persistent); + } node->set_name(get_name()); p_new_parent->add_child(node); Node *owner = get_owner(); - if (p_reown_map.has(owner)) + if (p_reown_map.has(owner)) { owner = p_reown_map[owner]; + } if (owner) { NodePath p = get_path_to(owner); @@ -2237,7 +2231,6 @@ void Node::_duplicate_and_reown(Node *p_new_parent, const Map<Node *, Node *> &p } for (int i = 0; i < get_child_count(); i++) { - get_child(i)->_duplicate_and_reown(node, p_reown_map); } } @@ -2246,57 +2239,66 @@ void Node::_duplicate_and_reown(Node *p_new_parent, const Map<Node *, Node *> &p // because re-targeting of connections from some descendant to another is not possible // if the emitter node comes later in tree order than the receiver void Node::_duplicate_signals(const Node *p_original, Node *p_copy) const { - - if (this != p_original && (get_owner() != p_original && get_owner() != p_original->get_owner())) + if ((this != p_original) && !(p_original->is_a_parent_of(this))) { return; + } - List<Connection> conns; - get_all_signal_connections(&conns); + List<const Node *> process_list; + process_list.push_back(this); + while (!process_list.empty()) { + const Node *n = process_list.front()->get(); + process_list.pop_front(); - for (List<Connection>::Element *E = conns.front(); E; E = E->next()) { + List<Connection> conns; + n->get_all_signal_connections(&conns); - if (E->get().flags & CONNECT_PERSIST) { - //user connected - NodePath p = p_original->get_path_to(this); - Node *copy = p_copy->get_node(p); + for (List<Connection>::Element *E = conns.front(); E; E = E->next()) { + if (E->get().flags & CONNECT_PERSIST) { + //user connected + NodePath p = p_original->get_path_to(n); + Node *copy = p_copy->get_node(p); - Node *target = Object::cast_to<Node>(E->get().target); - if (!target) { - continue; - } - NodePath ptarget = p_original->get_path_to(target); + Node *target = Object::cast_to<Node>(E->get().callable.get_object()); + if (!target) { + continue; + } + NodePath ptarget = p_original->get_path_to(target); - Node *copytarget = target; + Node *copytarget = target; - // Atempt to find a path to the duplicate target, if it seems it's not part - // of the duplicated and not yet parented hierarchy then at least try to connect - // to the same target as the original + // Attempt to find a path to the duplicate target, if it seems it's not part + // of the duplicated and not yet parented hierarchy then at least try to connect + // to the same target as the original - if (p_copy->has_node(ptarget)) - copytarget = p_copy->get_node(ptarget); + if (p_copy->has_node(ptarget)) { + copytarget = p_copy->get_node(ptarget); + } - if (copy && copytarget && !copy->is_connected(E->get().signal, copytarget, E->get().method)) { - copy->connect(E->get().signal, copytarget, E->get().method, E->get().binds, E->get().flags); + if (copy && copytarget) { + const Callable copy_callable = Callable(copytarget, E->get().callable.get_method()); + if (!copy->is_connected(E->get().signal.get_name(), copy_callable)) { + copy->connect(E->get().signal.get_name(), copy_callable, E->get().binds, E->get().flags); + } + } } } - } - for (int i = 0; i < get_child_count(); i++) { - get_child(i)->_duplicate_signals(p_original, p_copy); + for (int i = 0; i < n->get_child_count(); i++) { + process_list.push_back(n->get_child(i)); + } } } Node *Node::duplicate_and_reown(const Map<Node *, Node *> &p_reown_map) const { - - ERR_FAIL_COND_V(get_filename() != "", NULL); + ERR_FAIL_COND_V(get_filename() != "", nullptr); Object *obj = ClassDB::instance(get_class()); - ERR_FAIL_COND_V_MSG(!obj, NULL, "Node: Could not duplicate: " + String(get_class()) + "."); + ERR_FAIL_COND_V_MSG(!obj, nullptr, "Node: Could not duplicate: " + String(get_class()) + "."); Node *node = Object::cast_to<Node>(obj); if (!node) { memdelete(obj); - ERR_FAIL_V_MSG(NULL, "Node: Could not duplicate: " + String(get_class()) + "."); + ERR_FAIL_V_MSG(nullptr, "Node: Could not duplicate: " + String(get_class()) + "."); } node->set_name(get_name()); @@ -2305,9 +2307,9 @@ Node *Node::duplicate_and_reown(const Map<Node *, Node *> &p_reown_map) const { get_property_list(&plist); for (List<PropertyInfo>::Element *E = plist.front(); E; E = E->next()) { - - if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) + if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) { continue; + } String name = E->get().name; node->set(name, get(name)); } @@ -2315,11 +2317,11 @@ Node *Node::duplicate_and_reown(const Map<Node *, Node *> &p_reown_map) const { List<GroupInfo> groups; get_groups(&groups); - for (List<GroupInfo>::Element *E = groups.front(); E; E = E->next()) + for (List<GroupInfo>::Element *E = groups.front(); E; E = E->next()) { node->add_to_group(E->get().name, E->get().persistent); + } for (int i = 0; i < get_child_count(); i++) { - get_child(i)->_duplicate_and_reown(node, p_reown_map); } @@ -2331,24 +2333,21 @@ Node *Node::duplicate_and_reown(const Map<Node *, Node *> &p_reown_map) const { } static void find_owned_by(Node *p_by, Node *p_node, List<Node *> *p_owned) { - - if (p_node->get_owner() == p_by) + if (p_node->get_owner() == p_by) { p_owned->push_back(p_node); + } for (int i = 0; i < p_node->get_child_count(); i++) { - find_owned_by(p_by, p_node->get_child(i), p_owned); } } struct _NodeReplaceByPair { - String name; Variant value; }; void Node::replace_by(Node *p_node, bool p_keep_data) { - ERR_FAIL_NULL(p_node); ERR_FAIL_COND(p_node->data.parent); @@ -2359,15 +2358,14 @@ void Node::replace_by(Node *p_node, bool p_keep_data) { List<_NodeReplaceByPair> replace_data; if (p_keep_data) { - List<PropertyInfo> plist; get_property_list(&plist); for (List<PropertyInfo>::Element *E = plist.front(); E; E = E->next()) { - _NodeReplaceByPair rd; - if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) + if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) { continue; + } rd.name = E->get().name; rd.value = get(rd.name); } @@ -2375,29 +2373,29 @@ void Node::replace_by(Node *p_node, bool p_keep_data) { List<GroupInfo> groups; get_groups(&groups); - for (List<GroupInfo>::Element *E = groups.front(); E; E = E->next()) + for (List<GroupInfo>::Element *E = groups.front(); E; E = E->next()) { p_node->add_to_group(E->get().name, E->get().persistent); + } } _replace_connections_target(p_node); if (data.owner) { - for (int i = 0; i < get_child_count(); i++) + for (int i = 0; i < get_child_count(); i++) { find_owned_by(data.owner, get_child(i), &owned_by_owner); + } } Node *parent = data.parent; int pos_in_parent = data.pos; if (data.parent) { - parent->remove_child(this); parent->add_child(p_node); parent->move_child(p_node, pos_in_parent); } while (get_child_count()) { - Node *child = get_child(0); remove_child(child); if (!child->is_owned_by_parent()) { @@ -2407,74 +2405,77 @@ void Node::replace_by(Node *p_node, bool p_keep_data) { } p_node->set_owner(owner); - for (int i = 0; i < owned.size(); i++) + for (int i = 0; i < owned.size(); i++) { owned[i]->set_owner(p_node); + } - for (int i = 0; i < owned_by_owner.size(); i++) + for (int i = 0; i < owned_by_owner.size(); i++) { owned_by_owner[i]->set_owner(owner); + } p_node->set_filename(get_filename()); for (List<_NodeReplaceByPair>::Element *E = replace_data.front(); E; E = E->next()) { - p_node->set(E->get().name, E->get().value); } } void Node::_replace_connections_target(Node *p_new_target) { - List<Connection> cl; get_signals_connected_to_this(&cl); for (List<Connection>::Element *E = cl.front(); E; E = E->next()) { - Connection &c = E->get(); if (c.flags & CONNECT_PERSIST) { - c.source->disconnect(c.signal, this, c.method); - bool valid = p_new_target->has_method(c.method) || Ref<Script>(p_new_target->get_script()).is_null() || Ref<Script>(p_new_target->get_script())->has_method(c.method); - ERR_CONTINUE_MSG(!valid, "Attempt to connect signal '" + c.source->get_class() + "." + c.signal + "' to nonexistent method '" + c.target->get_class() + "." + c.method + "'."); - c.source->connect(c.signal, p_new_target, c.method, c.binds, c.flags); + c.signal.get_object()->disconnect(c.signal.get_name(), Callable(this, c.callable.get_method())); + bool valid = p_new_target->has_method(c.callable.get_method()) || Ref<Script>(p_new_target->get_script()).is_null() || Ref<Script>(p_new_target->get_script())->has_method(c.callable.get_method()); + ERR_CONTINUE_MSG(!valid, "Attempt to connect signal '" + c.signal.get_object()->get_class() + "." + c.signal.get_name() + "' to nonexistent method '" + c.callable.get_object()->get_class() + "." + c.callable.get_method() + "'."); + c.signal.get_object()->connect(c.signal.get_name(), Callable(p_new_target, c.callable.get_method()), c.binds, c.flags); } } } Vector<Variant> Node::make_binds(VARIANT_ARG_DECLARE) { - Vector<Variant> ret; - if (p_arg1.get_type() == Variant::NIL) + if (p_arg1.get_type() == Variant::NIL) { return ret; - else + } else { ret.push_back(p_arg1); + } - if (p_arg2.get_type() == Variant::NIL) + if (p_arg2.get_type() == Variant::NIL) { return ret; - else + } else { ret.push_back(p_arg2); + } - if (p_arg3.get_type() == Variant::NIL) + if (p_arg3.get_type() == Variant::NIL) { return ret; - else + } else { ret.push_back(p_arg3); + } - if (p_arg4.get_type() == Variant::NIL) + if (p_arg4.get_type() == Variant::NIL) { return ret; - else + } else { ret.push_back(p_arg4); + } - if (p_arg5.get_type() == Variant::NIL) + if (p_arg5.get_type() == Variant::NIL) { return ret; - else + } else { ret.push_back(p_arg5); + } return ret; } bool Node::has_node_and_resource(const NodePath &p_path) const { - - if (!has_node(p_path)) + if (!has_node(p_path)) { return false; + } RES res; Vector<StringName> leftover_path; Node *node = get_node_and_resource(p_path, res, leftover_path, false); @@ -2483,21 +2484,22 @@ bool Node::has_node_and_resource(const NodePath &p_path) const { } Array Node::_get_node_and_resource(const NodePath &p_path) { - RES res; Vector<StringName> leftover_path; Node *node = get_node_and_resource(p_path, res, leftover_path, false); Array result; - if (node) + if (node) { result.push_back(node); - else + } else { result.push_back(Variant()); + } - if (res.is_valid()) + if (res.is_valid()) { result.push_back(res); - else + } else { result.push_back(Variant()); + } result.push_back(NodePath(Vector<StringName>(), leftover_path, false)); @@ -2505,22 +2507,21 @@ Array Node::_get_node_and_resource(const NodePath &p_path) { } Node *Node::get_node_and_resource(const NodePath &p_path, RES &r_res, Vector<StringName> &r_leftover_subpath, bool p_last_is_property) const { - Node *node = get_node(p_path); r_res = RES(); r_leftover_subpath = Vector<StringName>(); - if (!node) - return NULL; + if (!node) { + return nullptr; + } if (p_path.get_subname_count()) { - int j = 0; // If not p_last_is_property, we shouldn't consider the last one as part of the resource for (; j < p_path.get_subname_count() - (int)p_last_is_property; j++) { Variant new_res_v = j == 0 ? node->get(p_path.get_subname(j)) : r_res->get(p_path.get_subname(j)); if (new_res_v.get_type() == Variant::NIL) { // Found nothing on that path - return NULL; + return nullptr; } RES new_res = new_res_v; @@ -2541,9 +2542,8 @@ Node *Node::get_node_and_resource(const NodePath &p_path, RES &r_res, Vector<Str } void Node::_set_tree(SceneTree *p_tree) { - - SceneTree *tree_changed_a = NULL; - SceneTree *tree_changed_b = NULL; + SceneTree *tree_changed_a = nullptr; + SceneTree *tree_changed_b = nullptr; //ERR_FAIL_COND(p_scene && data.parent && !data.parent->data.scene); //nobug if both are null @@ -2556,7 +2556,6 @@ void Node::_set_tree(SceneTree *p_tree) { data.tree = p_tree; if (data.tree) { - _propagate_enter_tree(); if (!data.parent || data.parent->data.ready_notified) { // No parent (root) or parent ready _propagate_ready(); //reverse_notification(NOTIFICATION_READY); @@ -2565,21 +2564,24 @@ void Node::_set_tree(SceneTree *p_tree) { tree_changed_b = data.tree; } - if (tree_changed_a) + if (tree_changed_a) { tree_changed_a->tree_changed(); - if (tree_changed_b) + } + if (tree_changed_b) { tree_changed_b->tree_changed(); + } } #ifdef DEBUG_ENABLED static void _Node_debug_sn(Object *p_obj) { - Node *n = Object::cast_to<Node>(p_obj); - if (!n) + if (!n) { return; + } - if (n->is_inside_tree()) + if (n->is_inside_tree()) { return; + } Node *p = n; while (p->get_parent()) { @@ -2587,28 +2589,26 @@ static void _Node_debug_sn(Object *p_obj) { } String path; - if (p == n) + if (p == n) { path = n->get_name(); - else + } else { path = String(p->get_name()) + "/" + p->get_path_to(n); + } print_line(itos(p_obj->get_instance_id()) + " - Stray Node: " + path + " (Type: " + n->get_class() + ")"); } #endif // DEBUG_ENABLED void Node::_print_stray_nodes() { - print_stray_nodes(); } void Node::print_stray_nodes() { - #ifdef DEBUG_ENABLED ObjectDB::debug_objects(_Node_debug_sn); #endif } void Node::queue_delete() { - if (is_inside_tree()) { get_tree()->queue_delete(this); } else { @@ -2616,26 +2616,24 @@ void Node::queue_delete() { } } -Array Node::_get_children() const { - - Array arr; +TypedArray<Node> Node::_get_children() const { + TypedArray<Node> arr; int cc = get_child_count(); arr.resize(cc); - for (int i = 0; i < cc; i++) + for (int i = 0; i < cc; i++) { arr[i] = get_child(i); + } return arr; } void Node::set_import_path(const NodePath &p_import_path) { - #ifdef TOOLS_ENABLED data.import_path = p_import_path; #endif } NodePath Node::get_import_path() const { - #ifdef TOOLS_ENABLED return data.import_path; #else @@ -2644,15 +2642,15 @@ NodePath Node::get_import_path() const { } static void _add_nodes_to_options(const Node *p_base, const Node *p_node, List<String> *r_options) { - #ifdef TOOLS_ENABLED const String quote_style = EDITOR_DEF("text_editor/completion/use_single_quotes", 0) ? "'" : "\""; #else const String quote_style = "\""; #endif - if (p_node != p_base && !p_node->get_owner()) + if (p_node != p_base && !p_node->get_owner()) { return; + } String n = p_base->get_path_to(p_node); r_options->push_back(quote_style + n + quote_style); for (int i = 0; i < p_node->get_child_count(); i++) { @@ -2661,17 +2659,14 @@ static void _add_nodes_to_options(const Node *p_base, const Node *p_node, List<S } void Node::get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const { - String pf = p_function; if ((pf == "has_node" || pf == "get_node") && p_idx == 0) { - _add_nodes_to_options(this, this, r_options); } Object::get_argument_options(p_function, p_idx, r_options); } void Node::clear_internal_tree_resource_paths() { - clear_internal_resource_paths(); for (int i = 0; i < data.children.size(); i++) { data.children[i]->clear_internal_tree_resource_paths(); @@ -2679,7 +2674,6 @@ void Node::clear_internal_tree_resource_paths() { } String Node::get_configuration_warning() const { - if (get_script_instance() && get_script_instance()->get_script().is_valid() && get_script_instance()->get_script()->is_tool() && get_script_instance()->has_method("_get_configuration_warning")) { return get_script_instance()->call("_get_configuration_warning"); @@ -2688,10 +2682,10 @@ String Node::get_configuration_warning() const { } void Node::update_configuration_warning() { - #ifdef TOOLS_ENABLED - if (!is_inside_tree()) + if (!is_inside_tree()) { return; + } if (get_tree()->get_edited_scene_root() && (get_tree()->get_edited_scene_root() == this || get_tree()->get_edited_scene_root()->is_a_parent_of(this))) { get_tree()->emit_signal(SceneStringNames::get_singleton()->node_configuration_warning_changed, this); } @@ -2707,7 +2701,6 @@ void Node::set_display_folded(bool p_folded) { } bool Node::is_displayed_folded() const { - return data.display_folded; } @@ -2716,13 +2709,12 @@ void Node::request_ready() { } void Node::_bind_methods() { - GLOBAL_DEF("node/name_num_separator", 0); ProjectSettings::get_singleton()->set_custom_property_info("node/name_num_separator", PropertyInfo(Variant::INT, "node/name_num_separator", PROPERTY_HINT_ENUM, "None,Space,Underscore,Dash")); GLOBAL_DEF("node/name_casing", NAME_CASING_PASCAL_CASE); ProjectSettings::get_singleton()->set_custom_property_info("node/name_casing", PropertyInfo(Variant::INT, "node/name_casing", PROPERTY_HINT_ENUM, "PascalCase,camelCase,snake_case")); - ClassDB::bind_method(D_METHOD("add_child_below_node", "node", "child_node", "legible_unique_name"), &Node::add_child_below_node, DEFVAL(false)); + ClassDB::bind_method(D_METHOD("add_sibling", "sibling", "legible_unique_name"), &Node::add_sibling, DEFVAL(false)); ClassDB::bind_method(D_METHOD("set_name", "name"), &Node::set_name); ClassDB::bind_method(D_METHOD("get_name"), &Node::get_name); @@ -2779,7 +2771,6 @@ void Node::_bind_methods() { ClassDB::bind_method(D_METHOD("get_pause_mode"), &Node::get_pause_mode); ClassDB::bind_method(D_METHOD("can_process"), &Node::can_process); ClassDB::bind_method(D_METHOD("print_stray_nodes"), &Node::_print_stray_nodes); - ClassDB::bind_method(D_METHOD("get_position_in_parent"), &Node::get_position_in_parent); ClassDB::bind_method(D_METHOD("set_display_folded", "fold"), &Node::set_display_folded); ClassDB::bind_method(D_METHOD("is_displayed_folded"), &Node::is_displayed_folded); @@ -2826,7 +2817,7 @@ void Node::_bind_methods() { { MethodInfo mi; - mi.arguments.push_back(PropertyInfo(Variant::STRING, "method")); + mi.arguments.push_back(PropertyInfo(Variant::STRING_NAME, "method")); mi.name = "rpc"; ClassDB::bind_vararg_method(METHOD_FLAGS_DEFAULT, "rpc", &Node::_rpc_bind, mi); @@ -2864,21 +2855,24 @@ void Node::_bind_methods() { BIND_CONSTANT(NOTIFICATION_PATH_CHANGED); BIND_CONSTANT(NOTIFICATION_INTERNAL_PROCESS); BIND_CONSTANT(NOTIFICATION_INTERNAL_PHYSICS_PROCESS); + BIND_CONSTANT(NOTIFICATION_POST_ENTER_TREE); BIND_CONSTANT(NOTIFICATION_WM_MOUSE_ENTER); BIND_CONSTANT(NOTIFICATION_WM_MOUSE_EXIT); - BIND_CONSTANT(NOTIFICATION_WM_FOCUS_IN); - BIND_CONSTANT(NOTIFICATION_WM_FOCUS_OUT); - BIND_CONSTANT(NOTIFICATION_WM_QUIT_REQUEST); + BIND_CONSTANT(NOTIFICATION_WM_WINDOW_FOCUS_IN); + BIND_CONSTANT(NOTIFICATION_WM_WINDOW_FOCUS_OUT); + BIND_CONSTANT(NOTIFICATION_WM_CLOSE_REQUEST); BIND_CONSTANT(NOTIFICATION_WM_GO_BACK_REQUEST); - BIND_CONSTANT(NOTIFICATION_WM_UNFOCUS_REQUEST); + BIND_CONSTANT(NOTIFICATION_WM_SIZE_CHANGED); BIND_CONSTANT(NOTIFICATION_OS_MEMORY_WARNING); BIND_CONSTANT(NOTIFICATION_TRANSLATION_CHANGED); BIND_CONSTANT(NOTIFICATION_WM_ABOUT); BIND_CONSTANT(NOTIFICATION_CRASH); BIND_CONSTANT(NOTIFICATION_OS_IME_UPDATE); - BIND_CONSTANT(NOTIFICATION_APP_RESUMED); - BIND_CONSTANT(NOTIFICATION_APP_PAUSED); + BIND_CONSTANT(NOTIFICATION_APPLICATION_RESUMED); + BIND_CONSTANT(NOTIFICATION_APPLICATION_PAUSED); + BIND_CONSTANT(NOTIFICATION_APPLICATION_FOCUS_IN); + BIND_CONSTANT(NOTIFICATION_APPLICATION_FOCUS_OUT); BIND_ENUM_CONSTANT(PAUSE_MODE_INHERIT); BIND_ENUM_CONSTANT(PAUSE_MODE_STOP); @@ -2898,20 +2892,15 @@ void Node::_bind_methods() { ADD_GROUP("Pause", "pause_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "pause_mode", PROPERTY_HINT_ENUM, "Inherit,Stop,Process"), "set_pause_mode", "get_pause_mode"); -#ifdef ENABLE_DEPRECATED - //no longer exists, but remains for compatibility (keep previous scenes folded - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "editor/display_folded", PROPERTY_HINT_NONE, "", 0), "set_display_folded", "is_displayed_folded"); -#endif - - ADD_PROPERTY(PropertyInfo(Variant::STRING, "name", PROPERTY_HINT_NONE, "", 0), "set_name", "get_name"); + ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "name", PROPERTY_HINT_NONE, "", 0), "set_name", "get_name"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "filename", PROPERTY_HINT_NONE, "", 0), "set_filename", "get_filename"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "owner", PROPERTY_HINT_RESOURCE_TYPE, "Node", 0), "set_owner", "get_owner"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "multiplayer", PROPERTY_HINT_RESOURCE_TYPE, "MultiplayerAPI", 0), "", "get_multiplayer"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "custom_multiplayer", PROPERTY_HINT_RESOURCE_TYPE, "MultiplayerAPI", 0), "set_custom_multiplayer", "get_custom_multiplayer"); ADD_PROPERTY(PropertyInfo(Variant::INT, "process_priority"), "set_process_priority", "get_process_priority"); - BIND_VMETHOD(MethodInfo("_process", PropertyInfo(Variant::REAL, "delta"))); - BIND_VMETHOD(MethodInfo("_physics_process", PropertyInfo(Variant::REAL, "delta"))); + BIND_VMETHOD(MethodInfo("_process", PropertyInfo(Variant::FLOAT, "delta"))); + BIND_VMETHOD(MethodInfo("_physics_process", PropertyInfo(Variant::FLOAT, "delta"))); BIND_VMETHOD(MethodInfo("_enter_tree")); BIND_VMETHOD(MethodInfo("_exit_tree")); BIND_VMETHOD(MethodInfo("_ready")); @@ -2923,21 +2912,24 @@ void Node::_bind_methods() { String Node::_get_name_num_separator() { switch (ProjectSettings::get_singleton()->get("node/name_num_separator").operator int()) { - case 0: return ""; - case 1: return " "; - case 2: return "_"; - case 3: return "-"; + case 0: + return ""; + case 1: + return " "; + case 2: + return "_"; + case 3: + return "-"; } return " "; } Node::Node() { - data.pos = -1; data.depth = -1; data.blocked = 0; - data.parent = NULL; - data.tree = NULL; + data.parent = nullptr; + data.tree = nullptr; data.physics_process = false; data.idle_process = false; data.process_priority = 0; @@ -2946,18 +2938,18 @@ Node::Node() { data.inside_tree = false; data.ready_notified = false; - data.owner = NULL; - data.OW = NULL; + data.owner = nullptr; + data.OW = nullptr; data.input = false; data.unhandled_input = false; data.unhandled_key_input = false; data.pause_mode = PAUSE_MODE_INHERIT; - data.pause_owner = NULL; + data.pause_owner = nullptr; data.network_master = 1; //server by default - data.path_cache = NULL; + data.path_cache = nullptr; data.parent_owned = false; data.in_constructor = true; - data.viewport = NULL; + data.viewport = nullptr; data.use_placeholder = false; data.display_folded = false; data.ready_first = true; @@ -2966,7 +2958,6 @@ Node::Node() { } Node::~Node() { - data.grouped.clear(); data.owned.clear(); data.children.clear(); |