From 4b6846a59d785af3bef6a29958387ed0ee0f6575 Mon Sep 17 00:00:00 2001 From: Juan Linietsky Date: Fri, 7 Sep 2018 15:31:19 -0300 Subject: [PATCH] Ensure that tree_exited signal really happens after tree exited, fixes #19641 --- scene/main/node.cpp | 16 ++++++++++++++-- scene/main/node.h | 1 + scene/main/scene_tree.cpp | 1 + 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/scene/main/node.cpp b/scene/main/node.cpp index e30f58e0122..3d1614199ad 100644 --- a/scene/main/node.cpp +++ b/scene/main/node.cpp @@ -238,6 +238,16 @@ void Node::_propagate_enter_tree() { // 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(); + } + data.blocked--; + emit_signal(SceneStringNames::get_singleton()->tree_exited); +} + void Node::_propagate_exit_tree() { //block while removing children @@ -299,8 +309,6 @@ void Node::_propagate_exit_tree() { data.ready_notified = false; data.tree = NULL; data.depth = -1; - - emit_signal(SceneStringNames::get_singleton()->tree_exited); } void Node::move_child(Node *p_child, int p_pos) { @@ -1207,6 +1215,10 @@ void Node::remove_child(Node *p_child) { // validate owner p_child->_propagate_validate_owner(); + + if (data.inside_tree) { + p_child->_propagate_after_exit_tree(); + } } int Node::get_child_count() const { diff --git a/scene/main/node.h b/scene/main/node.h index f3422618cec..fb84981febc 100644 --- a/scene/main/node.h +++ b/scene/main/node.h @@ -166,6 +166,7 @@ private: void _propagate_enter_tree(); void _propagate_ready(); void _propagate_exit_tree(); + void _propagate_after_exit_tree(); void _propagate_validate_owner(); void _print_stray_nodes(); void _propagate_pause_owner(Node *p_owner); diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp index 11268cc5c64..0b763d24339 100644 --- a/scene/main/scene_tree.cpp +++ b/scene/main/scene_tree.cpp @@ -598,6 +598,7 @@ void SceneTree::finish() { if (root) { root->_set_tree(NULL); + root->_propagate_after_exit_tree(); memdelete(root); //delete root } }