diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 678092ff0c1..f24fa344ae5 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -1042,11 +1042,17 @@ void EditorNode::_resources_reimporting(const Vector &p_resources) { // because if a mesh is present in an inherited scene, the resource will be modified in // the inherited scene. Then, get_modified_properties_for_node will return the mesh property, // which will trigger a recopy of the previous mesh, preventing the reload. + scenes_modification_table.clear(); + List scenes; for (const String &res_path : p_resources) { if (ResourceLoader::get_resource_type(res_path) == "PackedScene") { - preload_reimporting_with_path_in_edited_scenes(res_path); + scenes.push_back(res_path); } } + + if (scenes.size() > 0) { + preload_reimporting_with_path_in_edited_scenes(scenes); + } } void EditorNode::_resources_reimported(const Vector &p_resources) { @@ -1080,9 +1086,10 @@ void EditorNode::_resources_reimported(const Vector &p_resources) { for (const String &E : scenes) { reload_scene(E); - reload_instances_with_path_in_edited_scenes(E); } + reload_instances_with_path_in_edited_scenes(); + _set_current_scene_nocheck(current_tab); } @@ -5870,9 +5877,7 @@ void EditorNode::find_all_instances_inheriting_path_in_node(Node *p_root, Node * } } -void EditorNode::preload_reimporting_with_path_in_edited_scenes(const String &p_instance_path) { - scenes_modification_table.clear(); - +void EditorNode::preload_reimporting_with_path_in_edited_scenes(const List &p_scenes) { EditorProgress progress("preload_reimporting_scene", TTR("Preparing scenes for reload"), editor_data.get_edited_scene_count()); int original_edited_scene_idx = editor_data.get_edited_scene(); @@ -5882,35 +5887,42 @@ void EditorNode::preload_reimporting_with_path_in_edited_scenes(const String &p_ for (int current_scene_idx = 0; current_scene_idx < editor_data.get_edited_scene_count(); current_scene_idx++) { progress.step(vformat(TTR("Analyzing scene %s"), editor_data.get_scene_title(current_scene_idx)), current_scene_idx); - if (editor_data.get_scene_path(current_scene_idx) == p_instance_path) { - continue; - } Node *edited_scene_root = editor_data.get_edited_scene_root(current_scene_idx); if (edited_scene_root) { - List instance_list; - find_all_instances_inheriting_path_in_node(edited_scene_root, edited_scene_root, p_instance_path, instance_list); - if (instance_list.size() > 0) { - SceneModificationsEntry scene_motifications; - editor_data.set_edited_scene(current_scene_idx); + SceneModificationsEntry scene_motifications; - List instance_list_with_children; - for (Node *original_node : instance_list) { - InstanceModificationsEntry instance_modifications; - - // Fetching all the modified properties of the nodes reimported scene. - get_preload_scene_modification_table(edited_scene_root, original_node, original_node, instance_modifications); - - instance_modifications.original_node = original_node; - scene_motifications.instance_list.push_back(instance_modifications); - - instance_list_with_children.push_back(original_node); - get_children_nodes(original_node, instance_list_with_children); + for (const String &instance_path : p_scenes) { + if (editor_data.get_scene_path(current_scene_idx) == instance_path) { + continue; } - // Search the scene to find nodes that references the nodes will be recreated. - get_preload_modifications_reference_to_nodes(edited_scene_root, edited_scene_root, instance_list, instance_list_with_children, scene_motifications.other_instances_modifications); + List instance_list; + find_all_instances_inheriting_path_in_node(edited_scene_root, edited_scene_root, instance_path, instance_list); + if (instance_list.size() > 0) { + editor_data.set_edited_scene(current_scene_idx); + List instance_list_with_children; + for (Node *original_node : instance_list) { + InstanceModificationsEntry instance_modifications; + + // Fetching all the modified properties of the nodes reimported scene. + get_preload_scene_modification_table(edited_scene_root, original_node, original_node, instance_modifications); + + instance_modifications.original_node = original_node; + instance_modifications.instance_path = instance_path; + scene_motifications.instance_list.push_back(instance_modifications); + + instance_list_with_children.push_back(original_node); + get_children_nodes(original_node, instance_list_with_children); + } + + // Search the scene to find nodes that references the nodes will be recreated. + get_preload_modifications_reference_to_nodes(edited_scene_root, edited_scene_root, instance_list, instance_list_with_children, scene_motifications.other_instances_modifications); + } + } + + if (scene_motifications.instance_list.size() > 0) { scenes_modification_table[current_scene_idx] = scene_motifications; } } @@ -5921,24 +5933,30 @@ void EditorNode::preload_reimporting_with_path_in_edited_scenes(const String &p_ progress.step(TTR("Preparation done."), editor_data.get_edited_scene_count()); } -void EditorNode::reload_instances_with_path_in_edited_scenes(const String &p_instance_path) { +void EditorNode::reload_instances_with_path_in_edited_scenes() { if (scenes_modification_table.size() == 0) { return; } - Array replaced_nodes; - EditorProgress progress("reloading_scene", TTR("Scenes reloading"), editor_data.get_edited_scene_count()); progress.step(TTR("Reloading..."), 0, true); - // Reload the new instance. Error err; - Ref instance_scene_packed_scene = ResourceLoader::load(p_instance_path, "", ResourceFormatLoader::CACHE_MODE_REPLACE, &err); - - ERR_FAIL_COND(err != OK); - ERR_FAIL_COND(instance_scene_packed_scene.is_null()); - + Array replaced_nodes; HashMap> local_scene_cache; - local_scene_cache[p_instance_path] = instance_scene_packed_scene; + + // Reload the new instances. + for (KeyValue &scene_modifications_elem : scenes_modification_table) { + for (InstanceModificationsEntry instance_modifications : scene_modifications_elem.value.instance_list) { + if (!local_scene_cache.has(instance_modifications.instance_path)) { + Ref instance_scene_packed_scene = ResourceLoader::load(instance_modifications.instance_path, "", ResourceFormatLoader::CACHE_MODE_REPLACE, &err); + + ERR_FAIL_COND(err != OK); + ERR_FAIL_COND(instance_scene_packed_scene.is_null()); + + local_scene_cache[instance_modifications.instance_path] = instance_scene_packed_scene; + } + } + } // Save the current scene state/selection in case of lost. Dictionary editor_state = _get_main_scene_state(); @@ -5980,11 +5998,12 @@ void EditorNode::reload_instances_with_path_in_edited_scenes(const String &p_ins for (InstanceModificationsEntry instance_modifications : scene_modifications->instance_list) { Node *original_node = instance_modifications.original_node; String original_node_file_path = original_node->get_scene_file_path(); + Ref instance_scene_packed_scene = local_scene_cache[instance_modifications.instance_path]; // Load a replacement scene for the node. Ref current_packed_scene; Ref base_packed_scene; - if (original_node_file_path == p_instance_path) { + if (original_node_file_path == instance_modifications.instance_path) { // If the node file name directly matches the scene we're replacing, // just load it since we already cached it. current_packed_scene = instance_scene_packed_scene; @@ -6033,7 +6052,7 @@ void EditorNode::reload_instances_with_path_in_edited_scenes(const String &p_ins // it's a muli-level inheritance scene. We should use NodePath scene_path_to_node = current_edited_scene->get_path_to(original_node); Ref scene_state = current_edited_scene->get_scene_inherited_state(); - if (scene_path_to_node != "." && scene_state.is_valid() && scene_state->get_path() != p_instance_path && scene_state->find_node_by_path(scene_path_to_node) >= 0) { + if (scene_path_to_node != "." && scene_state.is_valid() && scene_state->get_path() != instance_modifications.instance_path && scene_state->find_node_by_path(scene_path_to_node) >= 0) { Node *root_node = scene_state->instantiate(SceneState::GenEditState::GEN_EDIT_STATE_INSTANCE); instantiated_node = root_node->get_node(scene_path_to_node); @@ -6167,7 +6186,7 @@ void EditorNode::reload_instances_with_path_in_edited_scenes(const String &p_ins if (owner) { Ref ss_inst = owner->get_scene_instance_state(); if (ss_inst.is_valid()) { - ss_inst->update_instance_resource(p_instance_path, current_packed_scene); + ss_inst->update_instance_resource(instance_modifications.instance_path, current_packed_scene); } owner->set_editable_instance(instantiated_node, is_editable); diff --git a/editor/editor_node.h b/editor/editor_node.h index 71f0d210a07..0877d458a7c 100644 --- a/editor/editor_node.h +++ b/editor/editor_node.h @@ -823,6 +823,7 @@ public: struct InstanceModificationsEntry { Node *original_node; + String instance_path; List instance_list; HashMap modifications; List addition_list; @@ -907,8 +908,8 @@ public: void reload_scene(const String &p_path); void find_all_instances_inheriting_path_in_node(Node *p_root, Node *p_node, const String &p_instance_path, List &p_instance_list); - void preload_reimporting_with_path_in_edited_scenes(const String &p_path); - void reload_instances_with_path_in_edited_scenes(const String &p_path); + void preload_reimporting_with_path_in_edited_scenes(const List &p_scenes); + void reload_instances_with_path_in_edited_scenes(); bool is_exiting() const { return exiting; }