summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--editor/editor_node.cpp112
-rw-r--r--editor/editor_node.h11
-rw-r--r--scene/resources/packed_scene.cpp19
3 files changed, 81 insertions, 61 deletions
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index d3fa2ed716..ac682eed69 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -4391,6 +4391,21 @@ bool EditorNode::is_additional_node_in_scene(Node *p_edited_scene, Node *p_reimp
return true;
}
+void EditorNode::get_scene_editor_data_for_node(Node *p_root, Node *p_node, HashMap<NodePath, SceneEditorDataEntry> &p_table) {
+ SceneEditorDataEntry new_entry;
+ new_entry.is_display_folded = p_node->is_displayed_folded();
+
+ if (p_root != p_node) {
+ new_entry.is_editable = p_root->is_editable_instance(p_node);
+ }
+
+ p_table.insert(p_root->get_path_to(p_node), new_entry);
+
+ for (int i = 0; i < p_node->get_child_count(); i++) {
+ get_scene_editor_data_for_node(p_root, p_node->get_child(i), p_table);
+ }
+}
+
void EditorNode::get_preload_scene_modification_table(
Node *p_edited_scene,
Node *p_reimported_root,
@@ -4497,7 +4512,7 @@ void EditorNode::get_preload_scene_modification_table(
void EditorNode::get_preload_modifications_reference_to_nodes(
Node *p_root,
Node *p_node,
- List<Node *> &p_excluded_nodes,
+ HashSet<Node *> &p_excluded_nodes,
List<Node *> &p_instance_list_with_children,
HashMap<NodePath, ModificationNodeEntry> &p_modification_table) {
if (!p_excluded_nodes.find(p_node)) {
@@ -5962,12 +5977,14 @@ void EditorNode::reload_scene(const String &p_path) {
scene_tabs->set_current_tab(current_tab);
}
-void EditorNode::find_all_instances_inheriting_path_in_node(Node *p_root, Node *p_node, const String &p_instance_path, List<Node *> &p_instance_list) {
+void EditorNode::find_all_instances_inheriting_path_in_node(Node *p_root, Node *p_node, const String &p_instance_path, HashSet<Node *> &p_instance_list) {
String scene_file_path = p_node->get_scene_file_path();
- // This is going to get messy...
+ bool valid_instance_found = false;
+
+ // Attempt to find all the instances matching path we're going to reload.
if (p_node->get_scene_file_path() == p_instance_path) {
- p_instance_list.push_back(p_node);
+ valid_instance_found = true;
} else {
Node *current_node = p_node;
@@ -5975,7 +5992,7 @@ void EditorNode::find_all_instances_inheriting_path_in_node(Node *p_root, Node *
while (inherited_state.is_valid()) {
String inherited_path = inherited_state->get_path();
if (inherited_path == p_instance_path) {
- p_instance_list.push_back(p_node);
+ valid_instance_found = true;
break;
}
@@ -5983,6 +6000,19 @@ void EditorNode::find_all_instances_inheriting_path_in_node(Node *p_root, Node *
}
}
+ // Instead of adding this instance directly, if its not owned by the scene, walk its ancestors
+ // and find the first node still owned by the scene. This is what we will reloading instead.
+ if (valid_instance_found) {
+ Node *current_node = p_node;
+ while (true) {
+ if (current_node->get_owner() == p_root || current_node->get_owner() == nullptr) {
+ p_instance_list.insert(current_node);
+ break;
+ }
+ current_node = current_node->get_parent();
+ }
+ }
+
for (int i = 0; i < p_node->get_child_count(); i++) {
find_all_instances_inheriting_path_in_node(p_root, p_node->get_child(i), p_instance_path, p_instance_list);
}
@@ -6001,20 +6031,20 @@ void EditorNode::preload_reimporting_with_path_in_edited_scenes(const List<Strin
Node *edited_scene_root = editor_data.get_edited_scene_root(current_scene_idx);
if (edited_scene_root) {
- SceneModificationsEntry scene_motifications;
+ SceneModificationsEntry scene_modifications;
for (const String &instance_path : p_scenes) {
if (editor_data.get_scene_path(current_scene_idx) == instance_path) {
continue;
}
- 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) {
+ HashSet<Node *> instances_to_reimport;
+ find_all_instances_inheriting_path_in_node(edited_scene_root, edited_scene_root, instance_path, instances_to_reimport);
+ if (instances_to_reimport.size() > 0) {
editor_data.set_edited_scene(current_scene_idx);
List<Node *> instance_list_with_children;
- for (Node *original_node : instance_list) {
+ for (Node *original_node : instances_to_reimport) {
InstanceModificationsEntry instance_modifications;
// Fetching all the modified properties of the nodes reimported scene.
@@ -6022,19 +6052,19 @@ void EditorNode::preload_reimporting_with_path_in_edited_scenes(const List<Strin
instance_modifications.original_node = original_node;
instance_modifications.instance_path = instance_path;
- scene_motifications.instance_list.push_back(instance_modifications);
+ scene_modifications.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);
+ get_preload_modifications_reference_to_nodes(edited_scene_root, edited_scene_root, instances_to_reimport, instance_list_with_children, scene_modifications.other_instances_modifications);
}
}
- if (scene_motifications.instance_list.size() > 0) {
- scenes_modification_table[current_scene_idx] = scene_motifications;
+ if (scene_modifications.instance_list.size() > 0) {
+ scenes_modification_table[current_scene_idx] = scene_modifications;
}
}
}
@@ -6157,10 +6187,10 @@ void EditorNode::reload_instances_with_path_in_edited_scenes() {
// Instantiate early so that caches cleared on load in SceneState can be rebuilt early.
Node *instantiated_node = nullptr;
- // If we are in a inherit scene, it's easier to create a new base scene and
+ // If we are in a inherited scene, it's easier to create a new base scene and
// grab the node from there.
// When scene_path_to_node is '.' and we have scene_inherited_state, it's because
- // it's a muli-level inheritance scene. We should use
+ // it's a multi-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() != instance_modifications.instance_path && scene_state->find_node_by_path(scene_path_to_node) >= 0) {
@@ -6184,9 +6214,9 @@ void EditorNode::reload_instances_with_path_in_edited_scenes() {
if (!instantiated_node) {
// If no base scene was found to create the node, we will use the reimported packed scene directly.
- // But, when the current edited scene is the reimported scene, it's because it's a inherited scene
- // of the reimported scene. In that case, we will not instantiate current_packed_scene, because
- // we would reinstanciate ourself. Using the base scene is better.
+ // But, when the current edited scene is the reimported scene, it's because it's an inherited scene
+ // derived from the reimported scene. In that case, we will not instantiate current_packed_scene, because
+ // we would reinstantiate ourself. Using the base scene is better.
if (current_edited_scene == original_node) {
if (base_packed_scene.is_valid()) {
instantiated_node = base_packed_scene->instantiate(PackedScene::GEN_EDIT_STATE_INSTANCE);
@@ -6242,6 +6272,17 @@ void EditorNode::reload_instances_with_path_in_edited_scenes() {
// crash when reimporting scenes with animations when "Editable children" was enabled.
replace_history_reimported_nodes(original_node, instantiated_node, original_node);
+ // Reset the editable instance state.
+ HashMap<NodePath, SceneEditorDataEntry> scene_editor_data_table;
+ Node *owner = original_node->get_owner();
+ if (!owner) {
+ owner = original_node;
+ }
+
+ get_scene_editor_data_for_node(owner, original_node, scene_editor_data_table);
+
+ bool original_node_scene_instance_load_placeholder = original_node->get_scene_instance_load_placeholder();
+
// Delete all the remaining node children.
while (original_node->get_child_count()) {
Node *child = original_node->get_child(0);
@@ -6250,16 +6291,6 @@ void EditorNode::reload_instances_with_path_in_edited_scenes() {
child->queue_free();
}
- // Reset the editable instance state.
- bool is_editable = true;
- Node *owner = original_node->get_owner();
- if (owner) {
- is_editable = owner->is_editable_instance(original_node);
- }
-
- bool original_node_is_displayed_folded = original_node->is_displayed_folded();
- bool original_node_scene_instance_load_placeholder = original_node->get_scene_instance_load_placeholder();
-
// Update the name to match
instantiated_node->set_name(original_node->get_name());
@@ -6290,19 +6321,9 @@ void EditorNode::reload_instances_with_path_in_edited_scenes() {
// Mark the old node for deletion.
original_node->queue_free();
- // Restore the folded and placeholder state from the original node.
- instantiated_node->set_display_folded(original_node_is_displayed_folded);
+ // Restore the placeholder state from the original node.
instantiated_node->set_scene_instance_load_placeholder(original_node_scene_instance_load_placeholder);
- if (owner) {
- Ref<SceneState> ss_inst = owner->get_scene_instance_state();
- if (ss_inst.is_valid()) {
- ss_inst->update_instance_resource(instance_modifications.instance_path, current_packed_scene);
- }
-
- owner->set_editable_instance(instantiated_node, is_editable);
- }
-
// Attempt to re-add all the additional nodes.
for (AdditiveNodeEntry additive_node_entry : instance_modifications.addition_list) {
Node *parent_node = instantiated_node->get_node_or_null(additive_node_entry.parent);
@@ -6334,6 +6355,17 @@ void EditorNode::reload_instances_with_path_in_edited_scenes() {
}
}
+ // Restore the scene's editable instance and folded states.
+ for (HashMap<NodePath, SceneEditorDataEntry>::Iterator I = scene_editor_data_table.begin(); I; ++I) {
+ Node *node = owner->get_node_or_null(I->key);
+ if (node) {
+ if (owner != node) {
+ owner->set_editable_instance(node, I->value.is_editable);
+ }
+ node->set_display_folded(I->value.is_display_folded);
+ }
+ }
+
// Restore the selection.
if (selected_node_paths.size()) {
for (NodePath selected_node_path : selected_node_paths) {
diff --git a/editor/editor_node.h b/editor/editor_node.h
index bdf9b26a7a..52692db74b 100644
--- a/editor/editor_node.h
+++ b/editor/editor_node.h
@@ -849,12 +849,19 @@ public:
HashMap<NodePath, ModificationNodeEntry> other_instances_modifications;
};
+ struct SceneEditorDataEntry {
+ bool is_editable;
+ bool is_display_folded;
+ };
+
HashMap<int, SceneModificationsEntry> scenes_modification_table;
List<String> scenes_reimported;
List<String> resources_reimported;
void update_node_from_node_modification_entry(Node *p_node, ModificationNodeEntry &p_node_modification);
+ void get_scene_editor_data_for_node(Node *p_root, Node *p_node, HashMap<NodePath, SceneEditorDataEntry> &p_table);
+
void get_preload_scene_modification_table(
Node *p_edited_scene,
Node *p_reimported_root,
@@ -863,7 +870,7 @@ public:
void get_preload_modifications_reference_to_nodes(
Node *p_root,
Node *p_node,
- List<Node *> &p_excluded_nodes,
+ HashSet<Node *> &p_excluded_nodes,
List<Node *> &p_instance_list_with_children,
HashMap<NodePath, ModificationNodeEntry> &p_modification_table);
void get_children_nodes(Node *p_node, List<Node *> &p_nodes);
@@ -924,7 +931,7 @@ 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<Node *> &p_instance_list);
+ void find_all_instances_inheriting_path_in_node(Node *p_root, Node *p_node, const String &p_instance_path, HashSet<Node *> &p_instance_list);
void preload_reimporting_with_path_in_edited_scenes(const List<String> &p_scenes);
void reload_instances_with_path_in_edited_scenes();
diff --git a/scene/resources/packed_scene.cpp b/scene/resources/packed_scene.cpp
index 27db65bb1a..f93070aea6 100644
--- a/scene/resources/packed_scene.cpp
+++ b/scene/resources/packed_scene.cpp
@@ -1267,25 +1267,6 @@ Ref<SceneState> SceneState::get_base_scene_state() const {
return Ref<SceneState>();
}
-void SceneState::update_instance_resource(String p_path, Ref<PackedScene> p_packed_scene) {
- ERR_FAIL_COND(p_packed_scene.is_null());
-
- for (const NodeData &nd : nodes) {
- if (nd.instance >= 0) {
- if (!(nd.instance & FLAG_INSTANCE_IS_PLACEHOLDER)) {
- int instance_id = nd.instance & FLAG_MASK;
- Ref<PackedScene> original_packed_scene = variants[instance_id];
- if (original_packed_scene.is_valid()) {
- if (original_packed_scene->get_path() == p_path) {
- variants.remove_at(instance_id);
- variants.insert(instance_id, p_packed_scene);
- }
- }
- }
- }
- }
-}
-
int SceneState::find_node_by_path(const NodePath &p_node) const {
ERR_FAIL_COND_V_MSG(node_path_cache.is_empty(), -1, "This operation requires the node cache to have been built.");