summaryrefslogtreecommitdiff
path: root/core/io
diff options
context:
space:
mode:
Diffstat (limited to 'core/io')
-rw-r--r--core/io/json.cpp33
-rw-r--r--core/io/json.h9
-rw-r--r--core/io/marshalls.h2
-rw-r--r--core/io/resource_format_binary.cpp93
-rw-r--r--core/io/resource_format_binary.h4
-rw-r--r--core/io/resource_loader.cpp20
-rw-r--r--core/io/resource_loader.h3
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);