Browse Source

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)
reduz 3 years ago
parent
commit
e4e3f7d157
4 changed files with 30 additions and 0 deletions
  1. 12 0
      doc/classes/Node.xml
  2. 14 0
      scene/main/node.cpp
  3. 2 0
      scene/scene_string_names.cpp
  4. 2 0
      scene/scene_string_names.h

+ 12 - 0
doc/classes/Node.xml

@@ -718,6 +718,18 @@
 		</member>
 	</members>
 	<signals>
+		<signal name="child_entered_tree">
+			<argument index="0" name="node" type="Node" />
+			<description>
+				Emitted when a child node enters the scene tree, either because it entered on its own or because this node entered with it.
+			</description>
+		</signal>
+		<signal name="child_exited_tree">
+			<argument index="0" name="node" type="Node" />
+			<description>
+				Emitted when a child node exits the scene tree, either because it exited on its own or because this node exited.
+			</description>
+		</signal>
 		<signal name="ready">
 			<description>
 				Emitted when the node is ready.

+ 14 - 0
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<StringName, GroupData>::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");
 

+ 2 - 0
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");

+ 2 - 0
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;