summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--modules/gdscript/gdscript_cache.cpp1
-rw-r--r--scene/resources/packed_scene.cpp53
-rw-r--r--scene/resources/packed_scene.h3
3 files changed, 56 insertions, 1 deletions
diff --git a/modules/gdscript/gdscript_cache.cpp b/modules/gdscript/gdscript_cache.cpp
index 2e7263b652..c77364d337 100644
--- a/modules/gdscript/gdscript_cache.cpp
+++ b/modules/gdscript/gdscript_cache.cpp
@@ -360,7 +360,6 @@ Ref<PackedScene> GDScriptCache::get_packed_scene(const String &p_path, Error &r_
singleton->packed_scene_cache[p_path] = scene;
singleton->packed_scene_dependencies[p_path].insert(p_owner);
- scene->recreate_state();
scene->reload_from_file();
return scene;
}
diff --git a/scene/resources/packed_scene.cpp b/scene/resources/packed_scene.cpp
index f46faa1013..f4b7f3d0b2 100644
--- a/scene/resources/packed_scene.cpp
+++ b/scene/resources/packed_scene.cpp
@@ -1005,6 +1005,37 @@ void SceneState::clear() {
base_scene_idx = -1;
}
+Error SceneState::copy_from(const Ref<SceneState> &p_scene_state) {
+ ERR_FAIL_COND_V(p_scene_state.is_null(), ERR_INVALID_PARAMETER);
+
+ clear();
+
+ for (const StringName &E : p_scene_state->names) {
+ names.append(E);
+ }
+ for (const Variant &E : p_scene_state->variants) {
+ variants.append(E);
+ }
+ for (const SceneState::NodeData &E : p_scene_state->nodes) {
+ nodes.append(E);
+ }
+ for (const SceneState::ConnectionData &E : p_scene_state->connections) {
+ connections.append(E);
+ }
+ for (KeyValue<NodePath, int> &E : p_scene_state->node_path_cache) {
+ node_path_cache.insert(E.key, E.value);
+ }
+ for (const NodePath &E : p_scene_state->node_paths) {
+ node_paths.append(E);
+ }
+ for (const NodePath &E : p_scene_state->editable_instances) {
+ editable_instances.append(E);
+ }
+ base_scene_idx = p_scene_state->base_scene_idx;
+
+ return OK;
+}
+
Ref<SceneState> SceneState::get_base_scene_state() const {
if (base_scene_idx >= 0) {
Ref<PackedScene> ps = variants[base_scene_idx];
@@ -1737,6 +1768,28 @@ void PackedScene::clear() {
state->clear();
}
+void PackedScene::reload_from_file() {
+ String path = get_path();
+ if (!path.is_resource_file()) {
+ return;
+ }
+
+ Ref<PackedScene> s = ResourceLoader::load(ResourceLoader::path_remap(path), get_class(), ResourceFormatLoader::CACHE_MODE_IGNORE);
+ if (!s.is_valid()) {
+ return;
+ }
+
+ // Backup the loaded_state
+ Ref<SceneState> loaded_state = s->get_state();
+ // This assigns a new state to s->state
+ // We do this because of the next step
+ s->recreate_state();
+ // This has a side-effect to clear s->state
+ copy_from(s);
+ // Then, we copy the backed-up loaded_state to state
+ state->copy_from(loaded_state);
+}
+
bool PackedScene::can_instantiate() const {
return state->can_instantiate();
}
diff --git a/scene/resources/packed_scene.h b/scene/resources/packed_scene.h
index a30ec54d85..ad1f50cd39 100644
--- a/scene/resources/packed_scene.h
+++ b/scene/resources/packed_scene.h
@@ -143,6 +143,7 @@ public:
String get_path() const;
void clear();
+ Error copy_from(const Ref<SceneState> &p_scene_state);
bool can_instantiate() const;
Node *instantiate(GenEditState p_edit_state) const;
@@ -235,6 +236,8 @@ public:
void recreate_state();
void replace_state(Ref<SceneState> p_by);
+ virtual void reload_from_file() override;
+
virtual void set_path(const String &p_path, bool p_take_over = false) override;
#ifdef TOOLS_ENABLED
virtual void set_last_modified_time(uint64_t p_time) override {