summaryrefslogtreecommitdiff
path: root/core/io
diff options
context:
space:
mode:
authorJuan Linietsky <reduzio@gmail.com>2023-01-14 12:57:28 +0100
committerJuan Linietsky <reduzio@gmail.com>2023-01-14 14:41:51 +0100
commit1aaff63b8fd774898bf9f8bbff0f4f42920f4cca (patch)
tree3baa9d73da4ddaa6e54f8008ca67755a629c73dc /core/io
parenta51ca2beafc5d74d3e62cb56fbba76ceb39160a3 (diff)
Fixes to JSON as resource
* It was not a resource, hence it was not working to load it as such. * Changed so, when opened in editor, a parse error will not fail load and the text will be kept. * This should allow proper editing from within the code editor, including syntax checking and saving files as-is in text. Partially addresses #66820. The code editor still needs to be changed for this to work.
Diffstat (limited to 'core/io')
-rw-r--r--core/io/json.cpp33
-rw-r--r--core/io/json.h9
2 files changed, 31 insertions, 11 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);