From e4e3f7d157ff79cc3afa424883e9b4f024c3fae2 Mon Sep 17 00:00:00 2001 From: reduz Date: Wed, 2 Feb 2022 11:22:11 +0100 Subject: [PATCH] Add a signal to notify when children nodes enter or exit tree -Allows more fine grained notifications (hence better performance) than using the global scene tree signals (node added and removed). -Required for #55950 (cherry picked from commit fbd9599b04086faefbf9796c41869dddbb6abf37) --- doc/classes/Node.xml | 12 ++++++++++++ scene/main/node.cpp | 14 ++++++++++++++ scene/scene_string_names.cpp | 2 ++ scene/scene_string_names.h | 2 ++ 4 files changed, 30 insertions(+) diff --git a/doc/classes/Node.xml b/doc/classes/Node.xml index 5f562c8e04d..c4a81b054c9 100644 --- a/doc/classes/Node.xml +++ b/doc/classes/Node.xml @@ -718,6 +718,18 @@ + + + + Emitted when a child node enters the scene tree, either because it entered on its own or because this node entered with it. + + + + + + Emitted when a child node exits the scene tree, either because it exited on its own or because this node exited. + + Emitted when the node is ready. diff --git a/scene/main/node.cpp b/scene/main/node.cpp index 9df729c7518..b798a9d9539 100644 --- a/scene/main/node.cpp +++ b/scene/main/node.cpp @@ -212,6 +212,12 @@ void Node::_propagate_enter_tree() { data.tree->node_added(this); + if (data.parent) { + Variant c = this; + const Variant *cptr = &c; + data.parent->emit_signal(SceneStringNames::get_singleton()->child_entered_tree, &cptr, 1); + } + data.blocked++; //block while adding children @@ -305,6 +311,12 @@ void Node::_propagate_exit_tree() { data.tree->node_removed(this); } + if (data.parent) { + Variant c = this; + const Variant *cptr = &c; + data.parent->emit_signal(SceneStringNames::get_singleton()->child_exited_tree, &cptr, 1); + } + // exit groups for (Map::Element *E = data.grouped.front(); E; E = E->next()) { @@ -2925,6 +2937,8 @@ void Node::_bind_methods() { ADD_SIGNAL(MethodInfo("tree_entered")); ADD_SIGNAL(MethodInfo("tree_exiting")); ADD_SIGNAL(MethodInfo("tree_exited")); + ADD_SIGNAL(MethodInfo("child_entered_tree", PropertyInfo(Variant::OBJECT, "node", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT, "Node"))); + ADD_SIGNAL(MethodInfo("child_exited_tree", PropertyInfo(Variant::OBJECT, "node", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT, "Node"))); ADD_PROPERTY(PropertyInfo(Variant::INT, "pause_mode", PROPERTY_HINT_ENUM, "Inherit,Stop,Process"), "set_pause_mode", "get_pause_mode"); diff --git a/scene/scene_string_names.cpp b/scene/scene_string_names.cpp index f0930edeced..d19a6df5dae 100644 --- a/scene/scene_string_names.cpp +++ b/scene/scene_string_names.cpp @@ -51,6 +51,8 @@ SceneStringNames::SceneStringNames() { tree_exiting = StaticCString::create("tree_exiting"); tree_exited = StaticCString::create("tree_exited"); ready = StaticCString::create("ready"); + child_entered_tree = StaticCString::create("child_entered_tree"); + child_exited_tree = StaticCString::create("child_exited_tree"); item_rect_changed = StaticCString::create("item_rect_changed"); size_flags_changed = StaticCString::create("size_flags_changed"); minimum_size_changed = StaticCString::create("minimum_size_changed"); diff --git a/scene/scene_string_names.h b/scene/scene_string_names.h index 8cdb30172a3..978ad3da935 100644 --- a/scene/scene_string_names.h +++ b/scene/scene_string_names.h @@ -71,6 +71,8 @@ public: StringName tree_exiting; StringName tree_exited; StringName ready; + StringName child_entered_tree; + StringName child_exited_tree; StringName size_flags_changed; StringName minimum_size_changed; StringName sleeping_state_changed;