Browse Source

Merge pull request #56185 from nikitalita/fix-save-as-binary

Fix ResourceLoaderText::save_as_binary()
Rémi Verschelde 3 years ago
parent
commit
5fc2864b05
1 changed files with 21 additions and 11 deletions
  1. 21 11
      scene/resources/resource_format_text.cpp

+ 21 - 11
scene/resources/resource_format_text.cpp

@@ -40,6 +40,8 @@
 // Version 3: new string ID for ext/subresources, breaks forward compat.
 #define FORMAT_VERSION 3
 
+#define BINARY_FORMAT_VERSION 4
+
 #include "core/io/dir_access.h"
 #include "core/version.h"
 
@@ -66,12 +68,8 @@ Error ResourceLoaderText::_parse_sub_resource_dummy(DummyReadData *p_data, Varia
 	String unique_id = token.value;
 
 	if (!p_data->resource_map.has(unique_id)) {
-		Ref<DummyResource> dr;
-		dr.instantiate();
-		dr->set_scene_unique_id(unique_id);
-		p_data->resource_map[unique_id] = dr;
-		uint32_t im_size = p_data->resource_index_map.size();
-		p_data->resource_index_map.insert(dr, im_size);
+		r_err_str = "Found unique_id reference before mapping, sub-resources stored out of order in resource file";
+		return ERR_PARSE_ERROR;
 	}
 
 	r_res = p_data->resource_map[unique_id];
@@ -1078,7 +1076,7 @@ Error ResourceLoaderText::save_as_binary(Ref<FileAccess> p_f, const String &p_pa
 	wf->store_32(0); //64 bits file, false for now
 	wf->store_32(VERSION_MAJOR);
 	wf->store_32(VERSION_MINOR);
-	static const int save_format_version = 3; //use format version 3 for saving
+	static const int save_format_version = BINARY_FORMAT_VERSION;
 	wf->store_32(save_format_version);
 
 	bs_save_unicode_string(wf, is_scene ? "PackedScene" : resource_type);
@@ -1176,7 +1174,7 @@ Error ResourceLoaderText::save_as_binary(Ref<FileAccess> p_f, const String &p_pa
 
 		while (next_tag.name == "sub_resource" || next_tag.name == "resource") {
 			String type;
-			int id = -1;
+			String id;
 			bool main_res;
 
 			if (next_tag.name == "sub_resource") {
@@ -1197,15 +1195,26 @@ Error ResourceLoaderText::save_as_binary(Ref<FileAccess> p_f, const String &p_pa
 				type = next_tag.fields["type"];
 				id = next_tag.fields["id"];
 				main_res = false;
+
+				if (!dummy_read.resource_map.has(id)) {
+					Ref<DummyResource> dr;
+					dr.instantiate();
+					dr->set_scene_unique_id(id);
+					dummy_read.resource_map[id] = dr;
+					uint32_t im_size = dummy_read.resource_index_map.size();
+					dummy_read.resource_index_map.insert(dr, im_size);
+				}
+
 			} else {
 				type = res_type;
-				id = 0; //used for last anyway
+				String uid_text = ResourceUID::get_singleton()->id_to_text(res_uid);
+				id = type + "_" + uid_text.replace("uid://", "").replace("<invalid>", "0");
 				main_res = true;
 			}
 
 			local_offsets.push_back(wf2->get_position());
 
-			bs_save_unicode_string(wf, "local://" + itos(id));
+			bs_save_unicode_string(wf, "local://" + id);
 			local_pointers_pos.push_back(wf->get_position());
 			wf->store_64(0); //temp local offset
 
@@ -1274,7 +1283,8 @@ Error ResourceLoaderText::save_as_binary(Ref<FileAccess> p_f, const String &p_pa
 			List<PropertyInfo> props;
 			packed_scene->get_property_list(&props);
 
-			bs_save_unicode_string(wf, "local://0");
+			String id = "PackedScene_" + ResourceUID::get_singleton()->id_to_text(res_uid).replace("uid://", "").replace("<invalid>", "0");
+			bs_save_unicode_string(wf, "local://" + id);
 			local_pointers_pos.push_back(wf->get_position());
 			wf->store_64(0); //temp local offset