@@ -586,7 +586,7 @@ bool SceneTree::process(double p_time) {
586
586
MessageQueue::get_singleton ()->flush (); // small little hack
587
587
flush_transform_notifications (); // transforms after world update, to avoid unnecessary enter/exit notifications
588
588
589
- if (unlikely (pending_new_scene )) {
589
+ if (unlikely (pending_new_scene_id. is_valid () )) {
590
590
_flush_scene_change ();
591
591
}
592
592
@@ -1508,17 +1508,33 @@ Node *SceneTree::get_current_scene() const {
1508
1508
}
1509
1509
1510
1510
void SceneTree::_flush_scene_change () {
1511
- if (prev_scene) {
1512
- memdelete (prev_scene);
1513
- prev_scene = nullptr ;
1511
+ if (prev_scene_id.is_valid ()) {
1512
+ // Might have already been freed externally.
1513
+ Node *prev_scene = Object::cast_to<Node>(ObjectDB::get_instance (prev_scene_id));
1514
+ if (prev_scene) {
1515
+ memdelete (prev_scene);
1516
+ }
1517
+ prev_scene_id = ObjectID ();
1514
1518
}
1515
- current_scene = pending_new_scene;
1516
- root->add_child (pending_new_scene);
1517
- pending_new_scene = nullptr ;
1518
- // Update display for cursor instantly.
1519
- root->update_mouse_cursor_state ();
1520
1519
1521
- emit_signal (SNAME (" scene_changed" ));
1520
+ DEV_ASSERT (pending_new_scene_id.is_valid ());
1521
+ Node *pending_new_scene = Object::cast_to<Node>(ObjectDB::get_instance (pending_new_scene_id));
1522
+ if (pending_new_scene) {
1523
+ // Ensure correct state before `add_child` (might enqueue subsequent scene change).
1524
+ current_scene = pending_new_scene;
1525
+ pending_new_scene_id = ObjectID ();
1526
+
1527
+ root->add_child (pending_new_scene);
1528
+ // Update display for cursor instantly.
1529
+ root->update_mouse_cursor_state ();
1530
+
1531
+ // Only on successful scene change.
1532
+ emit_signal (SNAME (" scene_changed" ));
1533
+ } else {
1534
+ current_scene = nullptr ;
1535
+ pending_new_scene_id = ObjectID ();
1536
+ ERR_PRINT (" Scene instance has been freed before becoming the current scene. No current scene is set." );
1537
+ }
1522
1538
}
1523
1539
1524
1540
Error SceneTree::change_scene_to_file (const String &p_path) {
@@ -1538,21 +1554,23 @@ Error SceneTree::change_scene_to_packed(const Ref<PackedScene> &p_scene) {
1538
1554
ERR_FAIL_NULL_V (new_scene, ERR_CANT_CREATE);
1539
1555
1540
1556
// If called again while a change is pending.
1541
- if (pending_new_scene) {
1542
- queue_delete (pending_new_scene);
1543
- pending_new_scene = nullptr ;
1557
+ if (pending_new_scene_id.is_valid ()) {
1558
+ Node *pending_new_scene = Object::cast_to<Node>(ObjectDB::get_instance (pending_new_scene_id));
1559
+ if (pending_new_scene) {
1560
+ queue_delete (pending_new_scene);
1561
+ }
1562
+ pending_new_scene_id = ObjectID ();
1544
1563
}
1545
1564
1546
- prev_scene = current_scene;
1547
-
1548
1565
if (current_scene) {
1566
+ prev_scene_id = current_scene->get_instance_id ();
1549
1567
// Let as many side effects as possible happen or be queued now,
1550
1568
// so they are run before the scene is actually deleted.
1551
1569
root->remove_child (current_scene);
1552
1570
}
1553
1571
DEV_ASSERT (!current_scene);
1554
1572
1555
- pending_new_scene = new_scene;
1573
+ pending_new_scene_id = new_scene-> get_instance_id () ;
1556
1574
return OK;
1557
1575
}
1558
1576
@@ -2009,13 +2027,19 @@ SceneTree::SceneTree() {
2009
2027
}
2010
2028
2011
2029
SceneTree::~SceneTree () {
2012
- if (prev_scene) {
2013
- memdelete (prev_scene);
2014
- prev_scene = nullptr ;
2030
+ if (prev_scene_id.is_valid ()) {
2031
+ Node *prev_scene = Object::cast_to<Node>(ObjectDB::get_instance (prev_scene_id));
2032
+ if (prev_scene) {
2033
+ memdelete (prev_scene);
2034
+ }
2035
+ prev_scene_id = ObjectID ();
2015
2036
}
2016
- if (pending_new_scene) {
2017
- memdelete (pending_new_scene);
2018
- pending_new_scene = nullptr ;
2037
+ if (pending_new_scene_id.is_valid ()) {
2038
+ Node *pending_new_scene = Object::cast_to<Node>(ObjectDB::get_instance (pending_new_scene_id));
2039
+ if (pending_new_scene) {
2040
+ memdelete (pending_new_scene);
2041
+ }
2042
+ pending_new_scene_id = ObjectID ();
2019
2043
}
2020
2044
if (root) {
2021
2045
root->_set_tree (nullptr );
0 commit comments