Use compatible text resource format when possible

This commit is contained in:
Haoyu Qiu 2024-04-19 15:55:29 +08:00
parent 7abe0c6014
commit 941e5c4820
4 changed files with 44 additions and 23 deletions

View file

@ -1789,7 +1789,7 @@ static String rtos_fix(double p_value) {
} }
} }
Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_string_func, void *p_store_string_ud, EncodeResourceFunc p_encode_res_func, void *p_encode_res_ud, int p_recursion_count) { Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_string_func, void *p_store_string_ud, EncodeResourceFunc p_encode_res_func, void *p_encode_res_ud, int p_recursion_count, bool p_compat) {
switch (p_variant.get_type()) { switch (p_variant.get_type()) {
case Variant::NIL: { case Variant::NIL: {
p_store_string_func(p_store_string_ud, "null"); p_store_string_func(p_store_string_ud, "null");
@ -2009,7 +2009,7 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
} }
p_store_string_func(p_store_string_ud, "\"" + E.name + "\":"); p_store_string_func(p_store_string_ud, "\"" + E.name + "\":");
write(obj->get(E.name), p_store_string_func, p_store_string_ud, p_encode_res_func, p_encode_res_ud, p_recursion_count); write(obj->get(E.name), p_store_string_func, p_store_string_ud, p_encode_res_func, p_encode_res_ud, p_recursion_count, p_compat);
} }
} }
@ -2035,9 +2035,9 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
p_store_string_func(p_store_string_ud, "{\n"); p_store_string_func(p_store_string_ud, "{\n");
for (List<Variant>::Element *E = keys.front(); E; E = E->next()) { for (List<Variant>::Element *E = keys.front(); E; E = E->next()) {
write(E->get(), p_store_string_func, p_store_string_ud, p_encode_res_func, p_encode_res_ud, p_recursion_count); write(E->get(), p_store_string_func, p_store_string_ud, p_encode_res_func, p_encode_res_ud, p_recursion_count, p_compat);
p_store_string_func(p_store_string_ud, ": "); p_store_string_func(p_store_string_ud, ": ");
write(dict[E->get()], p_store_string_func, p_store_string_ud, p_encode_res_func, p_encode_res_ud, p_recursion_count); write(dict[E->get()], p_store_string_func, p_store_string_ud, p_encode_res_func, p_encode_res_ud, p_recursion_count, p_compat);
if (E->next()) { if (E->next()) {
p_store_string_func(p_store_string_ud, ",\n"); p_store_string_func(p_store_string_ud, ",\n");
} else { } else {
@ -2096,7 +2096,7 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
} else { } else {
p_store_string_func(p_store_string_ud, ", "); p_store_string_func(p_store_string_ud, ", ");
} }
write(var, p_store_string_func, p_store_string_ud, p_encode_res_func, p_encode_res_ud, p_recursion_count); write(var, p_store_string_func, p_store_string_ud, p_encode_res_func, p_encode_res_ud, p_recursion_count, p_compat);
} }
p_store_string_func(p_store_string_ud, "]"); p_store_string_func(p_store_string_ud, "]");
@ -2110,7 +2110,16 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
case Variant::PACKED_BYTE_ARRAY: { case Variant::PACKED_BYTE_ARRAY: {
p_store_string_func(p_store_string_ud, "PackedByteArray("); p_store_string_func(p_store_string_ud, "PackedByteArray(");
Vector<uint8_t> data = p_variant; Vector<uint8_t> data = p_variant;
if (data.size() > 0) { if (p_compat) {
int len = data.size();
const uint8_t *ptr = data.ptr();
for (int i = 0; i < len; i++) {
if (i > 0) {
p_store_string_func(p_store_string_ud, ", ");
}
p_store_string_func(p_store_string_ud, itos(ptr[i]));
}
} else if (data.size() > 0) {
p_store_string_func(p_store_string_ud, "\""); p_store_string_func(p_store_string_ud, "\"");
p_store_string_func(p_store_string_ud, CryptoCore::b64_encode_str(data.ptr(), data.size())); p_store_string_func(p_store_string_ud, CryptoCore::b64_encode_str(data.ptr(), data.size()));
p_store_string_func(p_store_string_ud, "\""); p_store_string_func(p_store_string_ud, "\"");
@ -2255,8 +2264,8 @@ static Error _write_to_str(void *ud, const String &p_string) {
return OK; return OK;
} }
Error VariantWriter::write_to_string(const Variant &p_variant, String &r_string, EncodeResourceFunc p_encode_res_func, void *p_encode_res_ud) { Error VariantWriter::write_to_string(const Variant &p_variant, String &r_string, EncodeResourceFunc p_encode_res_func, void *p_encode_res_ud, bool p_compat) {
r_string = String(); r_string = String();
return write(p_variant, _write_to_str, &r_string, p_encode_res_func, p_encode_res_ud); return write(p_variant, _write_to_str, &r_string, p_encode_res_func, p_encode_res_ud, 0, p_compat);
} }

View file

@ -161,8 +161,8 @@ public:
typedef Error (*StoreStringFunc)(void *ud, const String &p_string); typedef Error (*StoreStringFunc)(void *ud, const String &p_string);
typedef String (*EncodeResourceFunc)(void *ud, const Ref<Resource> &p_resource); typedef String (*EncodeResourceFunc)(void *ud, const Ref<Resource> &p_resource);
static Error write(const Variant &p_variant, StoreStringFunc p_store_string_func, void *p_store_string_ud, EncodeResourceFunc p_encode_res_func, void *p_encode_res_ud, int p_recursion_count = 0); static Error write(const Variant &p_variant, StoreStringFunc p_store_string_func, void *p_store_string_ud, EncodeResourceFunc p_encode_res_func, void *p_encode_res_ud, int p_recursion_count = 0, bool p_compat = true);
static Error write_to_string(const Variant &p_variant, String &r_string, EncodeResourceFunc p_encode_res_func = nullptr, void *p_encode_res_ud = nullptr); static Error write_to_string(const Variant &p_variant, String &r_string, EncodeResourceFunc p_encode_res_func = nullptr, void *p_encode_res_ud = nullptr, bool p_compat = true);
}; };
#endif // VARIANT_PARSER_H #endif // VARIANT_PARSER_H

View file

@ -40,6 +40,7 @@
// Version 2: changed names for Basis, AABB, Vectors, etc. // Version 2: changed names for Basis, AABB, Vectors, etc.
// Version 3: new string ID for ext/subresources, breaks forward compat. // Version 3: new string ID for ext/subresources, breaks forward compat.
// Version 4: PackedByteArray is now stored as base64 encoded. // Version 4: PackedByteArray is now stored as base64 encoded.
#define FORMAT_VERSION_COMPAT 3
#define FORMAT_VERSION 4 #define FORMAT_VERSION 4
#define BINARY_FORMAT_VERSION 4 #define BINARY_FORMAT_VERSION 4
@ -845,7 +846,7 @@ void ResourceLoaderText::set_translation_remapped(bool p_remapped) {
} }
ResourceLoaderText::ResourceLoaderText() : ResourceLoaderText::ResourceLoaderText() :
stream(false) {} stream(false), format_version(FORMAT_VERSION) {}
void ResourceLoaderText::get_dependencies(Ref<FileAccess> p_f, List<String> *p_dependencies, bool p_add_types) { void ResourceLoaderText::get_dependencies(Ref<FileAccess> p_f, List<String> *p_dependencies, bool p_add_types) {
open(p_f); open(p_f);
@ -954,13 +955,13 @@ Error ResourceLoaderText::rename_dependencies(Ref<FileAccess> p_f, const String
} }
if (is_scene) { if (is_scene) {
fw->store_line("[gd_scene load_steps=" + itos(resources_total) + " format=" + itos(FORMAT_VERSION) + uid_text + "]\n"); fw->store_line("[gd_scene load_steps=" + itos(resources_total) + " format=" + itos(format_version) + uid_text + "]\n");
} else { } else {
String script_res_text; String script_res_text;
if (!script_class.is_empty()) { if (!script_class.is_empty()) {
script_res_text = "script_class=\"" + script_class + "\" "; script_res_text = "script_class=\"" + script_class + "\" ";
} }
fw->store_line("[gd_resource type=\"" + res_type + "\" " + script_res_text + "load_steps=" + itos(resources_total) + " format=" + itos(FORMAT_VERSION) + uid_text + "]\n"); fw->store_line("[gd_resource type=\"" + res_type + "\" " + script_res_text + "load_steps=" + itos(resources_total) + " format=" + itos(format_version) + uid_text + "]\n");
} }
} }
@ -1063,13 +1064,15 @@ void ResourceLoaderText::open(Ref<FileAccess> p_f, bool p_skip_first_tag) {
} }
if (tag.fields.has("format")) { if (tag.fields.has("format")) {
int fmt = tag.fields["format"]; format_version = tag.fields["format"];
if (fmt > FORMAT_VERSION) { if (format_version > FORMAT_VERSION) {
error_text = "Saved with newer format version"; error_text = "Saved with newer format version";
_printerr(); _printerr();
error = ERR_FILE_UNRECOGNIZED; error = ERR_FILE_UNRECOGNIZED;
return; return;
} }
} else {
format_version = FORMAT_VERSION;
} }
if (tag.name == "gd_scene") { if (tag.name == "gd_scene") {
@ -1970,6 +1973,12 @@ void ResourceFormatSaverTextInstance::_find_resources(const Variant &p_variant,
_find_resources(v); _find_resources(v);
} }
} break; } break;
case Variant::PACKED_BYTE_ARRAY: {
// Balance between compatibility and performance.
if (use_compat && p_variant.operator PackedByteArray().size() > 64) {
use_compat = false;
}
} break;
default: { default: {
} }
} }
@ -2005,6 +2014,7 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const Ref<Reso
} }
// Save resources. // Save resources.
use_compat = true; // _find_resources() changes this.
_find_resources(p_resource, true); _find_resources(p_resource, true);
if (packed_scene.is_valid()) { if (packed_scene.is_valid()) {
@ -2037,7 +2047,7 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const Ref<Reso
if (load_steps > 1) { if (load_steps > 1) {
title += "load_steps=" + itos(load_steps) + " "; title += "load_steps=" + itos(load_steps) + " ";
} }
title += "format=" + itos(FORMAT_VERSION) + ""; title += "format=" + itos(use_compat ? FORMAT_VERSION_COMPAT : FORMAT_VERSION) + "";
ResourceUID::ID uid = ResourceSaver::get_resource_id_for_path(local_path, true); ResourceUID::ID uid = ResourceSaver::get_resource_id_for_path(local_path, true);
@ -2223,7 +2233,7 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const Ref<Reso
} }
String vars; String vars;
VariantWriter::write_to_string(value, vars, _write_resources, this); VariantWriter::write_to_string(value, vars, _write_resources, this, use_compat);
f->store_string(name.property_name_encode() + " = " + vars + "\n"); f->store_string(name.property_name_encode() + " = " + vars + "\n");
} }
} }
@ -2287,14 +2297,14 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const Ref<Reso
if (!instance_placeholder.is_empty()) { if (!instance_placeholder.is_empty()) {
String vars; String vars;
f->store_string(" instance_placeholder="); f->store_string(" instance_placeholder=");
VariantWriter::write_to_string(instance_placeholder, vars, _write_resources, this); VariantWriter::write_to_string(instance_placeholder, vars, _write_resources, this, use_compat);
f->store_string(vars); f->store_string(vars);
} }
if (instance.is_valid()) { if (instance.is_valid()) {
String vars; String vars;
f->store_string(" instance="); f->store_string(" instance=");
VariantWriter::write_to_string(instance, vars, _write_resources, this); VariantWriter::write_to_string(instance, vars, _write_resources, this, use_compat);
f->store_string(vars); f->store_string(vars);
} }
@ -2302,7 +2312,7 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const Ref<Reso
for (int j = 0; j < state->get_node_property_count(i); j++) { for (int j = 0; j < state->get_node_property_count(i); j++) {
String vars; String vars;
VariantWriter::write_to_string(state->get_node_property_value(i, j), vars, _write_resources, this); VariantWriter::write_to_string(state->get_node_property_value(i, j), vars, _write_resources, this, use_compat);
f->store_string(String(state->get_node_property_name(i, j)).property_name_encode() + " = " + vars + "\n"); f->store_string(String(state->get_node_property_name(i, j)).property_name_encode() + " = " + vars + "\n");
} }
@ -2336,7 +2346,7 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const Ref<Reso
f->store_string(connstr); f->store_string(connstr);
if (binds.size()) { if (binds.size()) {
String vars; String vars;
VariantWriter::write_to_string(binds, vars, _write_resources, this); VariantWriter::write_to_string(binds, vars, _write_resources, this, use_compat);
f->store_string(" binds= " + vars); f->store_string(" binds= " + vars);
} }
@ -2368,14 +2378,14 @@ Error ResourceLoaderText::set_uid(Ref<FileAccess> p_f, ResourceUID::ID p_uid) {
fw = FileAccess::open(local_path + ".uidren", FileAccess::WRITE); fw = FileAccess::open(local_path + ".uidren", FileAccess::WRITE);
if (is_scene) { if (is_scene) {
fw->store_string("[gd_scene load_steps=" + itos(resources_total) + " format=" + itos(FORMAT_VERSION) + " uid=\"" + ResourceUID::get_singleton()->id_to_text(p_uid) + "\"]"); fw->store_string("[gd_scene load_steps=" + itos(resources_total) + " format=" + itos(format_version) + " uid=\"" + ResourceUID::get_singleton()->id_to_text(p_uid) + "\"]");
} else { } else {
String script_res_text; String script_res_text;
if (!script_class.is_empty()) { if (!script_class.is_empty()) {
script_res_text = "script_class=\"" + script_class + "\" "; script_res_text = "script_class=\"" + script_class + "\" ";
} }
fw->store_string("[gd_resource type=\"" + res_type + "\" " + script_res_text + "load_steps=" + itos(resources_total) + " format=" + itos(FORMAT_VERSION) + " uid=\"" + ResourceUID::get_singleton()->id_to_text(p_uid) + "\"]"); fw->store_string("[gd_resource type=\"" + res_type + "\" " + script_res_text + "load_steps=" + itos(resources_total) + " format=" + itos(format_version) + " uid=\"" + ResourceUID::get_singleton()->id_to_text(p_uid) + "\"]");
} }
uint8_t c = f->get_8(); uint8_t c = f->get_8();

View file

@ -54,6 +54,7 @@ class ResourceLoaderText {
}; };
bool is_scene = false; bool is_scene = false;
int format_version;
String res_type; String res_type;
bool ignore_resource_parsing = false; bool ignore_resource_parsing = false;
@ -178,6 +179,7 @@ class ResourceFormatSaverTextInstance {
List<Ref<Resource>> saved_resources; List<Ref<Resource>> saved_resources;
HashMap<Ref<Resource>, String> external_resources; HashMap<Ref<Resource>, String> external_resources;
HashMap<Ref<Resource>, String> internal_resources; HashMap<Ref<Resource>, String> internal_resources;
bool use_compat = true;
struct ResourceSort { struct ResourceSort {
Ref<Resource> resource; Ref<Resource> resource;