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.
This commit is contained in:
parent
a51ca2beaf
commit
1aaff63b8f
|
@ -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,14 +602,21 @@ 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) {
|
||||
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("Error parsing JSON file at '" + p_path + "', on line " + itos(json->get_error_line()) + ": " + json->get_error_message());
|
||||
ERR_PRINT(err_text);
|
||||
return Ref<Resource>();
|
||||
}
|
||||
}
|
||||
|
||||
if (r_error) {
|
||||
*r_error = OK;
|
||||
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<class name="JSON" inherits="RefCounted" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
|
||||
<class name="JSON" inherits="Resource" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
|
||||
<brief_description>
|
||||
Helper class for creating and parsing JSON data.
|
||||
</brief_description>
|
||||
|
@ -49,13 +49,21 @@
|
|||
Returns an empty string if the last call to [method parse] was successful, or the error message if it failed.
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_parsed_text" qualifiers="const">
|
||||
<return type="String" />
|
||||
<description>
|
||||
Return the text parsed by [method parse] as long as the function is instructed to keep it.
|
||||
</description>
|
||||
</method>
|
||||
<method name="parse">
|
||||
<return type="int" enum="Error" />
|
||||
<param index="0" name="json_string" type="String" />
|
||||
<param index="0" name="json_text" type="String" />
|
||||
<param index="1" name="keep_text" type="bool" default="false" />
|
||||
<description>
|
||||
Attempts to parse the [param json_string] provided.
|
||||
Attempts to parse the [param json_text] provided.
|
||||
Returns an [enum Error]. If the parse was successful, it returns [constant OK] and the result can be retrieved using [member data]. If unsuccessful, use [method get_error_line] and [method get_error_message] for identifying the source of the failure.
|
||||
Non-static variant of [method parse_string], if you want custom error handling.
|
||||
The optional [param keep_text] argument instructs the parser to keep a copy of the original text. This text can be obtained later by using the [method get_parsed_text] function and is used when saving the resource (instead of generating new text from [member data]).
|
||||
</description>
|
||||
</method>
|
||||
<method name="parse_string" qualifiers="static">
|
||||
|
|
Loading…
Reference in New Issue