Przeglądaj źródła

Add PackedScene::reload_from_file() override

Adam Scott 2 lat temu
rodzic
commit
a34a26eb66

+ 0 - 1
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;
 }

+ 53 - 0
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();
 }

+ 3 - 0
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 {