Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Revert new scene change algorithm #85298

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions doc/classes/SceneTree.xml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
<description>
Changes the running scene to the one at the given [param path], after loading it into a [PackedScene] and creating a new instance.
Returns [constant OK] on success, [constant ERR_CANT_OPEN] if the [param path] cannot be loaded into a [PackedScene], or [constant ERR_CANT_CREATE] if that scene cannot be instantiated.
[b]Note:[/b] The new scene node is added to the tree at the end of the frame. This ensures that both scenes aren't running at the same time, while still freeing the previous scene in a safe way similar to [method Node.queue_free]. As such, you won't be able to access the loaded scene immediately after the [method change_scene_to_file] call.
[b]Note:[/b] The scene change is deferred, which means that the new scene node is added to the tree at the end of the frame. This ensures that both scenes aren't running at the same time, while still freeing the previous scene in a safe way similar to [method Node.queue_free]. As such, you won't be able to access the loaded scene immediately after the [method change_scene_to_file] call.
</description>
</method>
<method name="change_scene_to_packed">
Expand All @@ -51,7 +51,7 @@
<description>
Changes the running scene to a new instance of the given [PackedScene] (which must be valid).
Returns [constant OK] on success, [constant ERR_CANT_CREATE] if the scene cannot be instantiated, or [constant ERR_INVALID_PARAMETER] if the scene is invalid.
[b]Note:[/b] The new scene node is added to the tree at the end of the frame. You won't be able to access it immediately after the [method change_scene_to_packed] call.
[b]Note:[/b] The scene change is deferred, which means that the new scene node is added to the tree at the end of the frame. You won't be able to access it immediately after the [method change_scene_to_packed] call.
</description>
</method>
<method name="create_timer">
Expand Down
60 changes: 23 additions & 37 deletions scene/main/scene_tree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -515,10 +515,6 @@ bool SceneTree::process(double p_time) {

_flush_delete_queue();

if (unlikely(pending_new_scene)) {
_flush_scene_change();
}

process_timers(p_time, false); //go through timers

process_tweens(p_time, false);
Expand Down Expand Up @@ -1383,16 +1379,27 @@ Node *SceneTree::get_current_scene() const {
return current_scene;
}

void SceneTree::_flush_scene_change() {
if (prev_scene) {
memdelete(prev_scene);
prev_scene = nullptr;
void SceneTree::_change_scene(Node *p_to) {
ERR_FAIL_COND_MSG(!Thread::is_main_thread(), "Changing scene can only be done from the main thread.");
if (current_scene) {
memdelete(current_scene);
current_scene = nullptr;
}

// If we're quitting, abort.
if (unlikely(_quit)) {
if (p_to) { // Prevent memory leak.
memdelete(p_to);
}
return;
}

if (p_to) {
current_scene = p_to;
root->add_child(p_to);
// Update display for cursor instantly.
root->update_mouse_cursor_state();
}
current_scene = pending_new_scene;
root->add_child(pending_new_scene);
pending_new_scene = nullptr;
// Update display for cursor instantly.
root->update_mouse_cursor_state();
}

Error SceneTree::change_scene_to_file(const String &p_path) {
Expand All @@ -1411,22 +1418,7 @@ Error SceneTree::change_scene_to_packed(const Ref<PackedScene> &p_scene) {
Node *new_scene = p_scene->instantiate();
ERR_FAIL_NULL_V(new_scene, ERR_CANT_CREATE);

// If called again while a change is pending.
if (pending_new_scene) {
queue_delete(pending_new_scene);
pending_new_scene = nullptr;
}

prev_scene = current_scene;

if (current_scene) {
// Let as many side effects as possible happen or be queued now,
// so they are run before the scene is actually deleted.
root->remove_child(current_scene);
}
DEV_ASSERT(!current_scene);

pending_new_scene = new_scene;
call_deferred(SNAME("_change_scene"), new_scene);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this have to be a named call?

return OK;
}

Expand Down Expand Up @@ -1627,6 +1619,8 @@ void SceneTree::_bind_methods() {
ClassDB::bind_method(D_METHOD("reload_current_scene"), &SceneTree::reload_current_scene);
ClassDB::bind_method(D_METHOD("unload_current_scene"), &SceneTree::unload_current_scene);

ClassDB::bind_method(D_METHOD("_change_scene"), &SceneTree::_change_scene);

ClassDB::bind_method(D_METHOD("set_multiplayer", "multiplayer", "root_path"), &SceneTree::set_multiplayer, DEFVAL(NodePath()));
ClassDB::bind_method(D_METHOD("get_multiplayer", "for_path"), &SceneTree::get_multiplayer, DEFVAL(NodePath()));
ClassDB::bind_method(D_METHOD("set_multiplayer_poll_enabled", "enabled"), &SceneTree::set_multiplayer_poll_enabled);
Expand Down Expand Up @@ -1868,14 +1862,6 @@ SceneTree::SceneTree() {
}

SceneTree::~SceneTree() {
if (prev_scene) {
memdelete(prev_scene);
prev_scene = nullptr;
}
if (pending_new_scene) {
memdelete(pending_new_scene);
pending_new_scene = nullptr;
}
if (root) {
root->_set_tree(nullptr);
root->_propagate_after_exit_tree();
Expand Down
4 changes: 1 addition & 3 deletions scene/main/scene_tree.h
Original file line number Diff line number Diff line change
Expand Up @@ -178,8 +178,6 @@ class SceneTree : public MainLoop {
TypedArray<Node> _get_nodes_in_group(const StringName &p_group);

Node *current_scene = nullptr;
Node *prev_scene = nullptr;
Node *pending_new_scene = nullptr;

Color debug_collisions_color;
Color debug_collision_contact_color;
Expand All @@ -190,7 +188,7 @@ class SceneTree : public MainLoop {
Ref<Material> collision_material;
int collision_debug_contacts;

void _flush_scene_change();
void _change_scene(Node *p_to);

List<Ref<SceneTreeTimer>> timers;
List<Ref<Tween>> tweens;
Expand Down
Loading