Skip to content

Commit

Permalink
Merge pull request #95264 from Hilderin/fix-reimport-file-multiple-sc…
Browse files Browse the repository at this point in the history
…enes

Fix reimport file multiple scenes
  • Loading branch information
akien-mga authored Aug 8, 2024
2 parents 4bef4d9 + b1c111d commit 9221294
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 39 deletions.
93 changes: 56 additions & 37 deletions editor/editor_node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1042,11 +1042,17 @@ void EditorNode::_resources_reimporting(const Vector<String> &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<String> 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<String> &p_resources) {
Expand Down Expand Up @@ -1080,9 +1086,10 @@ void EditorNode::_resources_reimported(const Vector<String> &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);
}

Expand Down Expand Up @@ -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<String> &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();
Expand All @@ -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<Node *> 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<Node *> instance_list_with_children;
for (Node *original_node : instance_list) {
InstanceModificationsEntry instance_modifications;
for (const String &instance_path : p_scenes) {
if (editor_data.get_scene_path(current_scene_idx) == instance_path) {
continue;
}

// Fetching all the modified properties of the nodes reimported scene.
get_preload_scene_modification_table(edited_scene_root, original_node, original_node, instance_modifications);
List<Node *> 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);

instance_modifications.original_node = original_node;
scene_motifications.instance_list.push_back(instance_modifications);
List<Node *> instance_list_with_children;
for (Node *original_node : instance_list) {
InstanceModificationsEntry instance_modifications;

instance_list_with_children.push_back(original_node);
get_children_nodes(original_node, instance_list_with_children);
}
// 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);

// 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);
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;
}
}
Expand All @@ -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<PackedScene> instance_scene_packed_scene = ResourceLoader::load(p_instance_path, "", ResourceFormatLoader::CACHE_MODE_REPLACE, &err);
Array replaced_nodes;
HashMap<String, Ref<PackedScene>> local_scene_cache;

// Reload the new instances.
for (KeyValue<int, SceneModificationsEntry> &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<PackedScene> 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());
ERR_FAIL_COND(err != OK);
ERR_FAIL_COND(instance_scene_packed_scene.is_null());

HashMap<String, Ref<PackedScene>> local_scene_cache;
local_scene_cache[p_instance_path] = instance_scene_packed_scene;
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();
Expand Down Expand Up @@ -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<PackedScene> instance_scene_packed_scene = local_scene_cache[instance_modifications.instance_path];

// Load a replacement scene for the node.
Ref<PackedScene> current_packed_scene;
Ref<PackedScene> 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;
Expand Down Expand Up @@ -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<SceneState> 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);

Expand Down Expand Up @@ -6167,7 +6186,7 @@ void EditorNode::reload_instances_with_path_in_edited_scenes(const String &p_ins
if (owner) {
Ref<SceneState> 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);
Expand Down
5 changes: 3 additions & 2 deletions editor/editor_node.h
Original file line number Diff line number Diff line change
Expand Up @@ -823,6 +823,7 @@ class EditorNode : public Node {

struct InstanceModificationsEntry {
Node *original_node;
String instance_path;
List<Node *> instance_list;
HashMap<NodePath, ModificationNodeEntry> modifications;
List<AdditiveNodeEntry> addition_list;
Expand Down Expand Up @@ -907,8 +908,8 @@ class EditorNode : public Node {
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<Node *> &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<String> &p_scenes);
void reload_instances_with_path_in_edited_scenes();

bool is_exiting() const { return exiting; }

Expand Down

0 comments on commit 9221294

Please sign in to comment.