소스 검색

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.
Trevor Davenport 1 년 전
부모
커밋
39ae82623d
2개의 변경된 파일14개의 추가작업 그리고 12개의 파일을 삭제
  1. 11 9
      editor/groups_editor.cpp
  2. 3 3
      editor/groups_editor.h

+ 11 - 9
editor/groups_editor.cpp

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

+ 3 - 3
editor/groups_editor.h

@@ -78,14 +78,14 @@ class GroupsEditor : public VBoxContainer {
 	Button *add = 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;
 	HashMap<StringName, String> global_groups;
 
-	void _update_scene_groups(Node *p_node);
-	void _cache_scene_groups(Node *p_node);
+	void _update_scene_groups(const ObjectID &p_id);
+	void _cache_scene_groups(const ObjectID &p_id);
 
 	void _show_add_group_dialog();
 	void _show_rename_group_dialog();