Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use compatible text resource format when possible #90889

Merged
merged 1 commit into from
Apr 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 17 additions & 8 deletions core/variant/variant_parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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()) {
case Variant::NIL: {
p_store_string_func(p_store_string_ud, "null");
Expand Down Expand Up @@ -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 + "\":");
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);
}
}

Expand All @@ -2035,9 +2035,9 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str

p_store_string_func(p_store_string_ud, "{\n");
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, ": ");
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()) {
p_store_string_func(p_store_string_ud, ",\n");
} else {
Expand Down Expand Up @@ -2096,7 +2096,7 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
} else {
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, "]");
Expand All @@ -2110,7 +2110,16 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
case Variant::PACKED_BYTE_ARRAY: {
p_store_string_func(p_store_string_ud, "PackedByteArray(");
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, CryptoCore::b64_encode_str(data.ptr(), data.size()));
p_store_string_func(p_store_string_ud, "\"");
Expand Down Expand Up @@ -2255,8 +2264,8 @@ static Error _write_to_str(void *ud, const String &p_string) {
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();

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);
}
4 changes: 2 additions & 2 deletions core/variant/variant_parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -161,8 +161,8 @@ class VariantWriter {
typedef Error (*StoreStringFunc)(void *ud, const String &p_string);
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_to_string(const Variant &p_variant, String &r_string, EncodeResourceFunc p_encode_res_func = nullptr, void *p_encode_res_ud = nullptr);
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, bool p_compat = true);
};

#endif // VARIANT_PARSER_H
36 changes: 23 additions & 13 deletions scene/resources/resource_format_text.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
// Version 2: changed names for Basis, AABB, Vectors, etc.
// Version 3: new string ID for ext/subresources, breaks forward compat.
// Version 4: PackedByteArray is now stored as base64 encoded.
#define FORMAT_VERSION_COMPAT 3
#define FORMAT_VERSION 4

#define BINARY_FORMAT_VERSION 4
Expand Down Expand Up @@ -845,7 +846,7 @@ void ResourceLoaderText::set_translation_remapped(bool p_remapped) {
}

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) {
open(p_f);
Expand Down Expand Up @@ -954,13 +955,13 @@ Error ResourceLoaderText::rename_dependencies(Ref<FileAccess> p_f, const String
}

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 {
String script_res_text;
if (!script_class.is_empty()) {
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");
}
}

Expand Down Expand Up @@ -1063,13 +1064,15 @@ void ResourceLoaderText::open(Ref<FileAccess> p_f, bool p_skip_first_tag) {
}

if (tag.fields.has("format")) {
int fmt = tag.fields["format"];
if (fmt > FORMAT_VERSION) {
format_version = tag.fields["format"];
if (format_version > FORMAT_VERSION) {
error_text = "Saved with newer format version";
_printerr();
error = ERR_FILE_UNRECOGNIZED;
return;
}
} else {
format_version = FORMAT_VERSION;
}

if (tag.name == "gd_scene") {
Expand Down Expand Up @@ -1970,6 +1973,12 @@ void ResourceFormatSaverTextInstance::_find_resources(const Variant &p_variant,
_find_resources(v);
}
} 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: {
}
}
Expand Down Expand Up @@ -2005,6 +2014,7 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const Ref<Reso
}

// Save resources.
use_compat = true; // _find_resources() changes this.
_find_resources(p_resource, true);

if (packed_scene.is_valid()) {
Expand Down Expand Up @@ -2037,7 +2047,7 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const Ref<Reso
if (load_steps > 1) {
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);

Expand Down Expand Up @@ -2223,7 +2233,7 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const Ref<Reso
}

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");
}
}
Expand Down Expand Up @@ -2287,22 +2297,22 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const Ref<Reso
if (!instance_placeholder.is_empty()) {
String vars;
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);
}

if (instance.is_valid()) {
String vars;
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_line("]");

for (int j = 0; j < state->get_node_property_count(i); j++) {
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");
}
Expand Down Expand Up @@ -2336,7 +2346,7 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const Ref<Reso
f->store_string(connstr);
if (binds.size()) {
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);
}

Expand Down Expand Up @@ -2368,14 +2378,14 @@ Error ResourceLoaderText::set_uid(Ref<FileAccess> p_f, ResourceUID::ID p_uid) {

fw = FileAccess::open(local_path + ".uidren", FileAccess::WRITE);
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 {
String script_res_text;
if (!script_class.is_empty()) {
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();
Expand Down
2 changes: 2 additions & 0 deletions scene/resources/resource_format_text.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ class ResourceLoaderText {
};

bool is_scene = false;
int format_version;
KoBeWi marked this conversation as resolved.
Show resolved Hide resolved
String res_type;

bool ignore_resource_parsing = false;
Expand Down Expand Up @@ -178,6 +179,7 @@ class ResourceFormatSaverTextInstance {
List<Ref<Resource>> saved_resources;
HashMap<Ref<Resource>, String> external_resources;
HashMap<Ref<Resource>, String> internal_resources;
bool use_compat = true;

struct ResourceSort {
Ref<Resource> resource;
Expand Down
Loading