Use ObjectID to track cached scene groups.

This prevents a crash that could occur when using the Node pointer
would reference a Node which had been freed after node_removal.
This commit is contained in:
Trevor Davenport 2023-12-22 15:38:43 -07:00 committed by Rémi Verschelde
parent 84e205b5a1
commit 39ae82623d
No known key found for this signature in database
GPG Key ID: C3336907360768E1
2 changed files with 14 additions and 12 deletions

View File

@ -274,20 +274,22 @@ void GroupsEditor::_update_groups_and_tree() {
_update_tree(); _update_tree();
} }
void GroupsEditor::_update_scene_groups(Node *p_node) { void GroupsEditor::_update_scene_groups(const ObjectID &p_id) {
if (scene_groups_cache.has(p_node)) { HashMap<ObjectID, HashMap<StringName, bool>>::Iterator I = scene_groups_cache.find(p_id);
scene_groups = scene_groups_cache[p_node]; if (I) {
scene_groups_cache.erase(p_node); scene_groups = I->value;
scene_groups_cache.remove(I);
} else { } else {
scene_groups = HashMap<StringName, bool>(); scene_groups = HashMap<StringName, bool>();
} }
} }
void GroupsEditor::_cache_scene_groups(Node *p_node) { void GroupsEditor::_cache_scene_groups(const ObjectID &p_id) {
const int edited_scene_count = EditorNode::get_editor_data().get_edited_scene_count(); const int edited_scene_count = EditorNode::get_editor_data().get_edited_scene_count();
for (int i = 0; i < edited_scene_count; i++) { for (int i = 0; i < edited_scene_count; i++) {
if (p_node == EditorNode::get_editor_data().get_edited_scene_root(i)) { Node *edited_scene_root = EditorNode::get_editor_data().get_edited_scene_root(i);
scene_groups_cache[p_node] = scene_groups_for_caching; if (edited_scene_root && p_id == edited_scene_root->get_instance_id()) {
scene_groups_cache[p_id] = scene_groups_for_caching;
break; break;
} }
} }
@ -305,7 +307,7 @@ void GroupsEditor::set_current(Node *p_node) {
if (scene_tree->get_edited_scene_root() != scene_root_node) { if (scene_tree->get_edited_scene_root() != scene_root_node) {
scene_root_node = scene_tree->get_edited_scene_root(); scene_root_node = scene_tree->get_edited_scene_root();
_update_scene_groups(scene_root_node); _update_scene_groups(scene_root_node->get_instance_id());
_update_groups(); _update_groups();
} }
@ -803,7 +805,7 @@ void GroupsEditor::_bind_methods() {
void GroupsEditor::_node_removed(Node *p_node) { void GroupsEditor::_node_removed(Node *p_node) {
if (scene_root_node == p_node) { if (scene_root_node == p_node) {
scene_groups_for_caching = scene_groups; scene_groups_for_caching = scene_groups;
callable_mp(this, &GroupsEditor::_cache_scene_groups).call_deferred(p_node); callable_mp(this, &GroupsEditor::_cache_scene_groups).call_deferred(p_node->get_instance_id());
scene_root_node = nullptr; scene_root_node = nullptr;
} }

View File

@ -78,14 +78,14 @@ class GroupsEditor : public VBoxContainer {
Button *add = nullptr; Button *add = nullptr;
Tree *tree = nullptr; Tree *tree = nullptr;
HashMap<Node *, HashMap<StringName, bool>> scene_groups_cache; HashMap<ObjectID, HashMap<StringName, bool>> scene_groups_cache;
HashMap<StringName, bool> scene_groups_for_caching; HashMap<StringName, bool> scene_groups_for_caching;
HashMap<StringName, bool> scene_groups; HashMap<StringName, bool> scene_groups;
HashMap<StringName, String> global_groups; HashMap<StringName, String> global_groups;
void _update_scene_groups(Node *p_node); void _update_scene_groups(const ObjectID &p_id);
void _cache_scene_groups(Node *p_node); void _cache_scene_groups(const ObjectID &p_id);
void _show_add_group_dialog(); void _show_add_group_dialog();
void _show_rename_group_dialog(); void _show_rename_group_dialog();