diff options
Diffstat (limited to 'core/io')
-rw-r--r-- | core/io/json.cpp | 33 | ||||
-rw-r--r-- | core/io/json.h | 9 | ||||
-rw-r--r-- | core/io/marshalls.h | 2 | ||||
-rw-r--r-- | core/io/resource_format_binary.cpp | 93 | ||||
-rw-r--r-- | core/io/resource_format_binary.h | 4 | ||||
-rw-r--r-- | core/io/resource_loader.cpp | 20 | ||||
-rw-r--r-- | core/io/resource_loader.h | 3 |
7 files changed, 151 insertions, 13 deletions
diff --git a/core/io/json.cpp b/core/io/json.cpp index ca29534c35..448e39b2c3 100644 --- a/core/io/json.cpp +++ b/core/io/json.cpp @@ -30,6 +30,7 @@ #include "json.h" +#include "core/config/engine.h" #include "core/string/print_string.h" const char *JSON::tk_name[TK_MAX] = { @@ -506,6 +507,7 @@ Error JSON::_parse_object(Dictionary &object, const char32_t *p_str, int &index, void JSON::set_data(const Variant &p_data) { data = p_data; + text.clear(); } Error JSON::_parse_string(const String &p_json, Variant &r_ret, String &r_err_str, int &r_err_line) { @@ -539,14 +541,21 @@ Error JSON::_parse_string(const String &p_json, Variant &r_ret, String &r_err_st return err; } -Error JSON::parse(const String &p_json_string) { +Error JSON::parse(const String &p_json_string, bool p_keep_text) { Error err = _parse_string(p_json_string, data, err_str, err_line); if (err == Error::OK) { err_line = 0; } + if (p_keep_text) { + text = p_json_string; + } return err; } +String JSON::get_parsed_text() const { + return text; +} + String JSON::stringify(const Variant &p_var, const String &p_indent, bool p_sort_keys, bool p_full_precision) { Ref<JSON> jason; jason.instantiate(); @@ -565,10 +574,11 @@ Variant JSON::parse_string(const String &p_json_string) { void JSON::_bind_methods() { ClassDB::bind_static_method("JSON", D_METHOD("stringify", "data", "indent", "sort_keys", "full_precision"), &JSON::stringify, DEFVAL(""), DEFVAL(true), DEFVAL(false)); ClassDB::bind_static_method("JSON", D_METHOD("parse_string", "json_string"), &JSON::parse_string); - ClassDB::bind_method(D_METHOD("parse", "json_string"), &JSON::parse); + ClassDB::bind_method(D_METHOD("parse", "json_text", "keep_text"), &JSON::parse, DEFVAL(false)); ClassDB::bind_method(D_METHOD("get_data"), &JSON::get_data); ClassDB::bind_method(D_METHOD("set_data", "data"), &JSON::set_data); + ClassDB::bind_method(D_METHOD("get_parsed_text"), &JSON::get_parsed_text); ClassDB::bind_method(D_METHOD("get_error_line"), &JSON::get_error_line); ClassDB::bind_method(D_METHOD("get_error_message"), &JSON::get_error_message); @@ -592,13 +602,20 @@ Ref<Resource> ResourceFormatLoaderJSON::load(const String &p_path, const String Ref<JSON> json; json.instantiate(); - Error err = json->parse(FileAccess::get_file_as_string(p_path)); + Error err = json->parse(FileAccess::get_file_as_string(p_path), Engine::get_singleton()->is_editor_hint()); if (err != OK) { - if (r_error) { - *r_error = err; + String err_text = "Error parsing JSON file at '" + p_path + "', on line " + itos(json->get_error_line()) + ": " + json->get_error_message(); + + if (Engine::get_singleton()->is_editor_hint()) { + // If running on editor, still allow opening the JSON so the code editor can edit it. + WARN_PRINT(err_text); + } else { + if (r_error) { + *r_error = err; + } + ERR_PRINT(err_text); + return Ref<Resource>(); } - ERR_PRINT("Error parsing JSON file at '" + p_path + "', on line " + itos(json->get_error_line()) + ": " + json->get_error_message()); - return Ref<Resource>(); } if (r_error) { @@ -628,7 +645,7 @@ Error ResourceFormatSaverJSON::save(const Ref<Resource> &p_resource, const Strin Ref<JSON> json = p_resource; ERR_FAIL_COND_V(json.is_null(), ERR_INVALID_PARAMETER); - String source = JSON::stringify(json->get_data(), "\t", false, true); + String source = json->get_parsed_text().is_empty() ? JSON::stringify(json->get_data(), "\t", false, true) : json->get_parsed_text(); Error err; Ref<FileAccess> file = FileAccess::open(p_path, FileAccess::WRITE, &err); diff --git a/core/io/json.h b/core/io/json.h index d66a4e24a3..a21cc542fd 100644 --- a/core/io/json.h +++ b/core/io/json.h @@ -36,8 +36,8 @@ #include "core/io/resource_saver.h" #include "core/variant/variant.h" -class JSON : public RefCounted { - GDCLASS(JSON, RefCounted); +class JSON : public Resource { + GDCLASS(JSON, Resource); enum TokenType { TK_CURLY_BRACKET_OPEN, @@ -65,6 +65,7 @@ class JSON : public RefCounted { Variant value; }; + String text; Variant data; String err_str; int err_line = 0; @@ -83,7 +84,9 @@ protected: static void _bind_methods(); public: - Error parse(const String &p_json_string); + Error parse(const String &p_json_string, bool p_keep_text = false); + String get_parsed_text() const; + static String stringify(const Variant &p_var, const String &p_indent = "", bool p_sort_keys = true, bool p_full_precision = false); static Variant parse_string(const String &p_json_string); diff --git a/core/io/marshalls.h b/core/io/marshalls.h index 5e760c7565..6f015ac386 100644 --- a/core/io/marshalls.h +++ b/core/io/marshalls.h @@ -44,7 +44,7 @@ typedef uint32_t uintr_t; #endif /** - * Miscellaneous helpers for marshalling data types, and encoding + * Miscellaneous helpers for marshaling data types, and encoding * in an endian independent way */ diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp index 03beb25b03..c0463de427 100644 --- a/core/io/resource_format_binary.cpp +++ b/core/io/resource_format_binary.cpp @@ -91,7 +91,8 @@ enum { // Version 2: added 64 bits support for float and int. // Version 3: changed nodepath encoding. // Version 4: new string ID for ext/subresources, breaks forward compat. - FORMAT_VERSION = 4, + // Version 5: Ability to store script class in the header. + FORMAT_VERSION = 5, FORMAT_VERSION_CAN_RENAME_DEPS = 1, FORMAT_VERSION_NO_NODEPATH_PROPERTY = 3, }; @@ -1009,6 +1010,10 @@ void ResourceLoaderBinary::open(Ref<FileAccess> p_f, bool p_no_resources, bool p uid = ResourceUID::INVALID_ID; } + if (flags & ResourceFormatSaverBinaryInstance::FORMAT_FLAG_HAS_SCRIPT_CLASS) { + script_class = get_unicode_string(); + } + for (int i = 0; i < ResourceFormatSaverBinaryInstance::RESERVED_FIELDS; i++) { f->get_32(); //skip a few reserved fields } @@ -1113,6 +1118,57 @@ String ResourceLoaderBinary::recognize(Ref<FileAccess> p_f) { return get_unicode_string(); } +String ResourceLoaderBinary::recognize_script_class(Ref<FileAccess> p_f) { + error = OK; + + f = p_f; + uint8_t header[4]; + f->get_buffer(header, 4); + if (header[0] == 'R' && header[1] == 'S' && header[2] == 'C' && header[3] == 'C') { + // Compressed. + Ref<FileAccessCompressed> fac; + fac.instantiate(); + error = fac->open_after_magic(f); + if (error != OK) { + f.unref(); + return ""; + } + f = fac; + + } else if (header[0] != 'R' || header[1] != 'S' || header[2] != 'R' || header[3] != 'C') { + // Not normal. + error = ERR_FILE_UNRECOGNIZED; + f.unref(); + return ""; + } + + bool big_endian = f->get_32(); + f->get_32(); // use_real64 + + f->set_big_endian(big_endian != 0); //read big endian if saved as big endian + + uint32_t ver_major = f->get_32(); + f->get_32(); // ver_minor + uint32_t ver_fmt = f->get_32(); + + if (ver_fmt > FORMAT_VERSION || ver_major > VERSION_MAJOR) { + f.unref(); + return ""; + } + + get_unicode_string(); // type + + f->get_64(); // Metadata offset + uint32_t flags = f->get_32(); + f->get_64(); // UID + + if (flags & ResourceFormatSaverBinaryInstance::FORMAT_FLAG_HAS_SCRIPT_CLASS) { + return get_unicode_string(); + } else { + return String(); + } +} + Ref<Resource> ResourceFormatLoaderBinary::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { if (r_error) { *r_error = ERR_FILE_CANT_OPEN; @@ -1295,6 +1351,9 @@ Error ResourceFormatLoaderBinary::rename_dependencies(const String &p_path, cons fw->store_32(flags); fw->store_64(uid_data); + if (flags & ResourceFormatSaverBinaryInstance::FORMAT_FLAG_HAS_SCRIPT_CLASS) { + save_ustring(fw, get_ustring(f)); + } for (int i = 0; i < ResourceFormatSaverBinaryInstance::RESERVED_FIELDS; i++) { fw->store_32(0); // reserved @@ -1416,6 +1475,18 @@ String ResourceFormatLoaderBinary::get_resource_type(const String &p_path) const return ClassDB::get_compatibility_remapped_class(r); } +String ResourceFormatLoaderBinary::get_resource_script_class(const String &p_path) const { + Ref<FileAccess> f = FileAccess::open(p_path, FileAccess::READ); + if (f.is_null()) { + return ""; //could not read + } + + ResourceLoaderBinary loader; + loader.local_path = ProjectSettings::get_singleton()->localize_path(p_path); + loader.res_path = loader.local_path; + return loader.recognize_script_class(f); +} + ResourceUID::ID ResourceFormatLoaderBinary::get_resource_uid(const String &p_path) const { String ext = p_path.get_extension().to_lower(); if (!ClassDB::is_resource_extension(ext)) { @@ -2033,15 +2104,31 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path, const Ref<Re save_unicode_string(f, _resource_get_class(p_resource)); f->store_64(0); //offset to import metadata + + String script_class; { uint32_t format_flags = FORMAT_FLAG_NAMED_SCENE_IDS | FORMAT_FLAG_UIDS; #ifdef REAL_T_IS_DOUBLE format_flags |= FORMAT_FLAG_REAL_T_IS_DOUBLE; #endif + if (!p_resource->is_class("PackedScene")) { + Ref<Script> s = p_resource->get_script(); + if (s.is_valid()) { + script_class = s->get_global_name(); + if (!script_class.is_empty()) { + format_flags |= ResourceFormatSaverBinaryInstance::FORMAT_FLAG_HAS_SCRIPT_CLASS; + } + } + } + f->store_32(format_flags); } ResourceUID::ID uid = ResourceSaver::get_resource_id_for_path(p_path, true); f->store_64(uid); + if (!script_class.is_empty()) { + save_unicode_string(f, script_class); + } + for (int i = 0; i < ResourceFormatSaverBinaryInstance::RESERVED_FIELDS; i++) { f->store_32(0); // reserved } @@ -2294,6 +2381,10 @@ Error ResourceFormatSaverBinaryInstance::set_uid(const String &p_path, ResourceU fw->store_32(flags); fw->store_64(p_uid); + if (flags & ResourceFormatSaverBinaryInstance::FORMAT_FLAG_HAS_SCRIPT_CLASS) { + save_ustring(fw, get_ustring(f)); + } + //rest of file uint8_t b = f->get_8(); while (!f->eof_reached()) { diff --git a/core/io/resource_format_binary.h b/core/io/resource_format_binary.h index 9dd208e3cd..add7cdf297 100644 --- a/core/io/resource_format_binary.h +++ b/core/io/resource_format_binary.h @@ -65,6 +65,7 @@ class ResourceLoaderBinary { bool using_named_scene_ids = false; bool using_uids = false; + String script_class; bool use_sub_threads = false; float *progress = nullptr; Vector<ExtResource> external_resources; @@ -99,6 +100,7 @@ public: void set_remaps(const HashMap<String, String> &p_remaps) { remaps = p_remaps; } void open(Ref<FileAccess> p_f, bool p_no_resources = false, bool p_keep_uuid_paths = false); String recognize(Ref<FileAccess> p_f); + String recognize_script_class(Ref<FileAccess> p_f); void get_dependencies(Ref<FileAccess> p_f, List<String> *p_dependencies, bool p_add_types); void get_classes_used(Ref<FileAccess> p_f, HashSet<StringName> *p_classes); @@ -112,6 +114,7 @@ public: virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; + virtual String get_resource_script_class(const String &p_path) const; virtual void get_classes_used(const String &p_path, HashSet<StringName> *r_classes); virtual ResourceUID::ID get_resource_uid(const String &p_path) const; virtual void get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types = false); @@ -164,6 +167,7 @@ public: FORMAT_FLAG_NAMED_SCENE_IDS = 1, FORMAT_FLAG_UIDS = 2, FORMAT_FLAG_REAL_T_IS_DOUBLE = 4, + FORMAT_FLAG_HAS_SCRIPT_CLASS = 8, // Amount of reserved 32-bit fields in resource header RESERVED_FIELDS = 11 diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp index 68b9f8b6f7..7447119ab7 100644 --- a/core/io/resource_loader.cpp +++ b/core/io/resource_loader.cpp @@ -99,6 +99,12 @@ String ResourceFormatLoader::get_resource_type(const String &p_path) const { return ret; } +String ResourceFormatLoader::get_resource_script_class(const String &p_path) const { + String ret; + GDVIRTUAL_CALL(_get_resource_script_class, p_path, ret); + return ret; +} + ResourceUID::ID ResourceFormatLoader::get_resource_uid(const String &p_path) const { int64_t uid = ResourceUID::INVALID_ID; GDVIRTUAL_CALL(_get_resource_uid, p_path, uid); @@ -184,6 +190,7 @@ void ResourceFormatLoader::_bind_methods() { GDVIRTUAL_BIND(_recognize_path, "path", "type"); GDVIRTUAL_BIND(_handles_type, "type"); GDVIRTUAL_BIND(_get_resource_type, "path"); + GDVIRTUAL_BIND(_get_resource_script_class, "path"); GDVIRTUAL_BIND(_get_resource_uid, "path"); GDVIRTUAL_BIND(_get_dependencies, "path", "add_types"); GDVIRTUAL_BIND(_rename_dependencies, "path", "renames"); @@ -764,6 +771,19 @@ String ResourceLoader::get_resource_type(const String &p_path) { return ""; } +String ResourceLoader::get_resource_script_class(const String &p_path) { + String local_path = _validate_local_path(p_path); + + for (int i = 0; i < loader_count; i++) { + String result = loader[i]->get_resource_script_class(local_path); + if (!result.is_empty()) { + return result; + } + } + + return ""; +} + ResourceUID::ID ResourceLoader::get_resource_uid(const String &p_path) { String local_path = _validate_local_path(p_path); diff --git a/core/io/resource_loader.h b/core/io/resource_loader.h index e427a2f5fc..eb8155e046 100644 --- a/core/io/resource_loader.h +++ b/core/io/resource_loader.h @@ -54,6 +54,7 @@ protected: GDVIRTUAL2RC(bool, _recognize_path, String, StringName) GDVIRTUAL1RC(bool, _handles_type, StringName) GDVIRTUAL1RC(String, _get_resource_type, String) + GDVIRTUAL1RC(String, _get_resource_script_class, String) GDVIRTUAL1RC(ResourceUID::ID, _get_resource_uid, String) GDVIRTUAL2RC(Vector<String>, _get_dependencies, String, bool) GDVIRTUAL1RC(Vector<String>, _get_classes_used, String) @@ -71,6 +72,7 @@ public: virtual bool handles_type(const String &p_type) const; virtual void get_classes_used(const String &p_path, HashSet<StringName> *r_classes); virtual String get_resource_type(const String &p_path) const; + virtual String get_resource_script_class(const String &p_path) const; virtual ResourceUID::ID get_resource_uid(const String &p_path) const; virtual void get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types = false); virtual Error rename_dependencies(const String &p_path, const HashMap<String, String> &p_map); @@ -175,6 +177,7 @@ public: static void remove_resource_format_loader(Ref<ResourceFormatLoader> p_format_loader); static void get_classes_used(const String &p_path, HashSet<StringName> *r_classes); static String get_resource_type(const String &p_path); + static String get_resource_script_class(const String &p_path); static ResourceUID::ID get_resource_uid(const String &p_path); static void get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types = false); static Error rename_dependencies(const String &p_path, const HashMap<String, String> &p_map); |