diff options
Diffstat (limited to 'core/io')
-rw-r--r-- | core/io/file_access.cpp | 7 | ||||
-rw-r--r-- | core/io/file_access.h | 1 | ||||
-rw-r--r-- | core/io/image.cpp | 2 | ||||
-rw-r--r-- | core/io/image_loader.h | 8 | ||||
-rw-r--r-- | core/io/json.h | 14 | ||||
-rw-r--r-- | core/io/marshalls.cpp | 212 | ||||
-rw-r--r-- | core/io/resource.cpp | 4 | ||||
-rw-r--r-- | core/io/resource_format_binary.h | 28 | ||||
-rw-r--r-- | core/io/resource_importer.h | 30 | ||||
-rw-r--r-- | core/io/resource_loader.cpp | 2 | ||||
-rw-r--r-- | core/io/translation_loader_po.h | 8 |
11 files changed, 224 insertions, 92 deletions
diff --git a/core/io/file_access.cpp b/core/io/file_access.cpp index 55286277fa..d2a5103953 100644 --- a/core/io/file_access.cpp +++ b/core/io/file_access.cpp @@ -47,6 +47,7 @@ thread_local Error FileAccess::last_file_open_error = OK; Ref<FileAccess> FileAccess::create(AccessType p_access) { ERR_FAIL_INDEX_V(p_access, ACCESS_MAX, nullptr); + ERR_FAIL_NULL_V(create_func[p_access], nullptr); Ref<FileAccess> ret = create_func[p_access](); ret->_set_access_type(p_access); @@ -75,7 +76,8 @@ Ref<FileAccess> FileAccess::create_for_path(const String &p_path) { ret = create(ACCESS_RESOURCES); } else if (p_path.begins_with("user://")) { ret = create(ACCESS_USERDATA); - + } else if (p_path.begins_with("pipe://")) { + ret = create(ACCESS_PIPE); } else { ret = create(ACCESS_FILESYSTEM); } @@ -209,6 +211,9 @@ String FileAccess::fix_path(const String &p_path) const { } } break; + case ACCESS_PIPE: { + return r_path; + } break; case ACCESS_FILESYSTEM: { return r_path; } break; diff --git a/core/io/file_access.h b/core/io/file_access.h index 122ae3b190..0b631f68b1 100644 --- a/core/io/file_access.h +++ b/core/io/file_access.h @@ -50,6 +50,7 @@ public: ACCESS_RESOURCES, ACCESS_USERDATA, ACCESS_FILESYSTEM, + ACCESS_PIPE, ACCESS_MAX }; diff --git a/core/io/image.cpp b/core/io/image.cpp index c454f06d67..6096211cff 100644 --- a/core/io/image.cpp +++ b/core/io/image.cpp @@ -4114,7 +4114,7 @@ Dictionary Image::compute_image_metrics(const Ref<Image> p_compared_image, bool continue; } - image_metric_max = MAX(image_metric_max, i); + image_metric_max = i; double x = i * hist[i]; diff --git a/core/io/image_loader.h b/core/io/image_loader.h index e9b434522d..26af650344 100644 --- a/core/io/image_loader.h +++ b/core/io/image_loader.h @@ -103,10 +103,10 @@ public: class ResourceFormatLoaderImage : public ResourceFormatLoader { public: - virtual Ref<Resource> load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE); - 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 Ref<Resource> load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE) override; + virtual void get_recognized_extensions(List<String> *p_extensions) const override; + virtual bool handles_type(const String &p_type) const override; + virtual String get_resource_type(const String &p_path) const override; }; #endif // IMAGE_LOADER_H diff --git a/core/io/json.h b/core/io/json.h index a21cc542fd..801fa29b4b 100644 --- a/core/io/json.h +++ b/core/io/json.h @@ -98,17 +98,17 @@ public: class ResourceFormatLoaderJSON : public ResourceFormatLoader { public: - virtual Ref<Resource> load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE); - 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 Ref<Resource> load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE) override; + virtual void get_recognized_extensions(List<String> *p_extensions) const override; + virtual bool handles_type(const String &p_type) const override; + virtual String get_resource_type(const String &p_path) const override; }; class ResourceFormatSaverJSON : public ResourceFormatSaver { public: - virtual Error save(const Ref<Resource> &p_resource, const String &p_path, uint32_t p_flags = 0); - virtual void get_recognized_extensions(const Ref<Resource> &p_resource, List<String> *p_extensions) const; - virtual bool recognize(const Ref<Resource> &p_resource) const; + virtual Error save(const Ref<Resource> &p_resource, const String &p_path, uint32_t p_flags = 0) override; + virtual void get_recognized_extensions(const Ref<Resource> &p_resource, List<String> *p_extensions) const override; + virtual bool recognize(const Ref<Resource> &p_resource) const override; }; #endif // JSON_H diff --git a/core/io/marshalls.cpp b/core/io/marshalls.cpp index bc2493d360..b25fcccd7f 100644 --- a/core/io/marshalls.cpp +++ b/core/io/marshalls.cpp @@ -30,7 +30,10 @@ #include "marshalls.h" +#include "core/core_string_names.h" +#include "core/io/resource_loader.h" #include "core/object/ref_counted.h" +#include "core/object/script_language.h" #include "core/os/keyboard.h" #include "core/string/print_string.h" @@ -55,9 +58,22 @@ ObjectID EncodedObjectAsID::get_object_id() const { #define ERR_FAIL_ADD_OF(a, b, err) ERR_FAIL_COND_V(((int32_t)(b)) < 0 || ((int32_t)(a)) < 0 || ((int32_t)(a)) > INT_MAX - ((int32_t)(b)), err) #define ERR_FAIL_MUL_OF(a, b, err) ERR_FAIL_COND_V(((int32_t)(a)) < 0 || ((int32_t)(b)) <= 0 || ((int32_t)(a)) > INT_MAX / ((int32_t)(b)), err) -#define ENCODE_MASK 0xFF -#define ENCODE_FLAG_64 1 << 16 -#define ENCODE_FLAG_OBJECT_AS_ID 1 << 16 +// Byte 0: `Variant::Type`, byte 1: unused, bytes 2 and 3: additional data. +#define HEADER_TYPE_MASK 0xFF + +// For `Variant::INT`, `Variant::FLOAT` and other math types. +#define HEADER_DATA_FLAG_64 (1 << 16) + +// For `Variant::OBJECT`. +#define HEADER_DATA_FLAG_OBJECT_AS_ID (1 << 16) + +// For `Variant::ARRAY`. +// Occupies bits 16 and 17. +#define HEADER_DATA_FIELD_TYPED_ARRAY_MASK (0b11 << 16) +#define HEADER_DATA_FIELD_TYPED_ARRAY_NONE (0b00 << 16) +#define HEADER_DATA_FIELD_TYPED_ARRAY_BUILTIN (0b01 << 16) +#define HEADER_DATA_FIELD_TYPED_ARRAY_CLASS_NAME (0b10 << 16) +#define HEADER_DATA_FIELD_TYPED_ARRAY_SCRIPT (0b11 << 16) static Error _decode_string(const uint8_t *&buf, int &len, int *r_len, String &r_string) { ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA); @@ -101,9 +117,9 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA); - uint32_t type = decode_uint32(buf); + uint32_t header = decode_uint32(buf); - ERR_FAIL_COND_V((type & ENCODE_MASK) >= Variant::VARIANT_MAX, ERR_INVALID_DATA); + ERR_FAIL_COND_V((header & HEADER_TYPE_MASK) >= Variant::VARIANT_MAX, ERR_INVALID_DATA); buf += 4; len -= 4; @@ -114,7 +130,7 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int // Note: We cannot use sizeof(real_t) for decoding, in case a different size is encoded. // Decoding math types always checks for the encoded size, while encoding always uses compilation setting. // This does lead to some code duplication for decoding, but compatibility is the priority. - switch (type & ENCODE_MASK) { + switch (header & HEADER_TYPE_MASK) { case Variant::NIL: { r_variant = Variant(); } break; @@ -127,7 +143,7 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int } } break; case Variant::INT: { - if (type & ENCODE_FLAG_64) { + if (header & HEADER_DATA_FLAG_64) { ERR_FAIL_COND_V(len < 8, ERR_INVALID_DATA); int64_t val = decode_uint64(buf); r_variant = val; @@ -146,7 +162,7 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int } break; case Variant::FLOAT: { - if (type & ENCODE_FLAG_64) { + if (header & HEADER_DATA_FLAG_64) { ERR_FAIL_COND_V((size_t)len < sizeof(double), ERR_INVALID_DATA); double val = decode_double(buf); r_variant = val; @@ -176,7 +192,7 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int // math types case Variant::VECTOR2: { Vector2 val; - if (type & ENCODE_FLAG_64) { + if (header & HEADER_DATA_FLAG_64) { ERR_FAIL_COND_V((size_t)len < sizeof(double) * 2, ERR_INVALID_DATA); val.x = decode_double(&buf[0]); val.y = decode_double(&buf[sizeof(double)]); @@ -210,7 +226,7 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int } break; case Variant::RECT2: { Rect2 val; - if (type & ENCODE_FLAG_64) { + if (header & HEADER_DATA_FLAG_64) { ERR_FAIL_COND_V((size_t)len < sizeof(double) * 4, ERR_INVALID_DATA); val.position.x = decode_double(&buf[0]); val.position.y = decode_double(&buf[sizeof(double)]); @@ -250,7 +266,7 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int } break; case Variant::VECTOR3: { Vector3 val; - if (type & ENCODE_FLAG_64) { + if (header & HEADER_DATA_FLAG_64) { ERR_FAIL_COND_V((size_t)len < sizeof(double) * 3, ERR_INVALID_DATA); val.x = decode_double(&buf[0]); val.y = decode_double(&buf[sizeof(double)]); @@ -287,7 +303,7 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int } break; case Variant::VECTOR4: { Vector4 val; - if (type & ENCODE_FLAG_64) { + if (header & HEADER_DATA_FLAG_64) { ERR_FAIL_COND_V((size_t)len < sizeof(double) * 4, ERR_INVALID_DATA); val.x = decode_double(&buf[0]); val.y = decode_double(&buf[sizeof(double)]); @@ -327,7 +343,7 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int } break; case Variant::TRANSFORM2D: { Transform2D val; - if (type & ENCODE_FLAG_64) { + if (header & HEADER_DATA_FLAG_64) { ERR_FAIL_COND_V((size_t)len < sizeof(double) * 6, ERR_INVALID_DATA); for (int i = 0; i < 3; i++) { for (int j = 0; j < 2; j++) { @@ -355,7 +371,7 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int } break; case Variant::PLANE: { Plane val; - if (type & ENCODE_FLAG_64) { + if (header & HEADER_DATA_FLAG_64) { ERR_FAIL_COND_V((size_t)len < sizeof(double) * 4, ERR_INVALID_DATA); val.normal.x = decode_double(&buf[0]); val.normal.y = decode_double(&buf[sizeof(double)]); @@ -381,7 +397,7 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int } break; case Variant::QUATERNION: { Quaternion val; - if (type & ENCODE_FLAG_64) { + if (header & HEADER_DATA_FLAG_64) { ERR_FAIL_COND_V((size_t)len < sizeof(double) * 4, ERR_INVALID_DATA); val.x = decode_double(&buf[0]); val.y = decode_double(&buf[sizeof(double)]); @@ -407,7 +423,7 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int } break; case Variant::AABB: { AABB val; - if (type & ENCODE_FLAG_64) { + if (header & HEADER_DATA_FLAG_64) { ERR_FAIL_COND_V((size_t)len < sizeof(double) * 6, ERR_INVALID_DATA); val.position.x = decode_double(&buf[0]); val.position.y = decode_double(&buf[sizeof(double)]); @@ -437,7 +453,7 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int } break; case Variant::BASIS: { Basis val; - if (type & ENCODE_FLAG_64) { + if (header & HEADER_DATA_FLAG_64) { ERR_FAIL_COND_V((size_t)len < sizeof(double) * 9, ERR_INVALID_DATA); for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { @@ -465,7 +481,7 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int } break; case Variant::TRANSFORM3D: { Transform3D val; - if (type & ENCODE_FLAG_64) { + if (header & HEADER_DATA_FLAG_64) { ERR_FAIL_COND_V((size_t)len < sizeof(double) * 12, ERR_INVALID_DATA); for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { @@ -499,7 +515,7 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int } break; case Variant::PROJECTION: { Projection val; - if (type & ENCODE_FLAG_64) { + if (header & HEADER_DATA_FLAG_64) { ERR_FAIL_COND_V((size_t)len < sizeof(double) * 16, ERR_INVALID_DATA); for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { @@ -560,12 +576,12 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int uint32_t namecount = strlen &= 0x7FFFFFFF; uint32_t subnamecount = decode_uint32(buf + 4); - uint32_t flags = decode_uint32(buf + 8); + uint32_t np_flags = decode_uint32(buf + 8); len -= 12; buf += 12; - if (flags & 2) { // Obsolete format with property separate from subpath + if (np_flags & 2) { // Obsolete format with property separate from subpath. subnamecount++; } @@ -589,7 +605,7 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int } } - r_variant = NodePath(names, subnames, flags & 1); + r_variant = NodePath(names, subnames, np_flags & 1); } else { //old format, just a string @@ -608,8 +624,8 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int r_variant = RID::from_uint64(id); } break; case Variant::OBJECT: { - if (type & ENCODE_FLAG_OBJECT_AS_ID) { - //this _is_ allowed + if (header & HEADER_DATA_FLAG_OBJECT_AS_ID) { + // This _is_ allowed. ERR_FAIL_COND_V(len < 8, ERR_INVALID_DATA); ObjectID val = ObjectID(decode_uint64(buf)); if (r_len) { @@ -625,7 +641,6 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int r_variant = obj_as_id; } - } else { ERR_FAIL_COND_V(!p_allow_objects, ERR_UNAUTHORIZED); @@ -672,7 +687,16 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int (*r_len) += used; } - obj->set(str, value); + if (str == "script") { + ERR_FAIL_COND_V_MSG(value.get_type() != Variant::STRING, ERR_INVALID_DATA, "Invalid value for \"script\" property, expected script path as String."); + String path = value; + ERR_FAIL_COND_V_MSG(path.is_empty() || !path.begins_with("res://") || !ResourceLoader::exists(path, "Script"), ERR_INVALID_DATA, "Invalid script path: '" + path + "'."); + Ref<Script> script = ResourceLoader::load(path, "Script"); + ERR_FAIL_COND_V_MSG(script.is_null(), ERR_INVALID_DATA, "Can't load script at path: '" + path + "'."); + obj->set_script(script); + } else { + obj->set(str, value); + } } if (Object::cast_to<RefCounted>(obj)) { @@ -747,7 +771,60 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int } break; case Variant::ARRAY: { + Variant::Type builtin_type = Variant::VARIANT_MAX; + StringName class_name; + Ref<Script> script; + + switch (header & HEADER_DATA_FIELD_TYPED_ARRAY_MASK) { + case HEADER_DATA_FIELD_TYPED_ARRAY_NONE: + break; // Untyped array. + case HEADER_DATA_FIELD_TYPED_ARRAY_BUILTIN: { + ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA); + + int32_t bt = decode_uint32(buf); + buf += 4; + len -= 4; + if (r_len) { + (*r_len) += 4; + } + + ERR_FAIL_INDEX_V(bt, Variant::VARIANT_MAX, ERR_INVALID_DATA); + builtin_type = (Variant::Type)bt; + ERR_FAIL_COND_V(!p_allow_objects && builtin_type == Variant::OBJECT, ERR_UNAUTHORIZED); + } break; + case HEADER_DATA_FIELD_TYPED_ARRAY_CLASS_NAME: { + ERR_FAIL_COND_V(!p_allow_objects, ERR_UNAUTHORIZED); + + String str; + Error err = _decode_string(buf, len, r_len, str); + if (err) { + return err; + } + + builtin_type = Variant::OBJECT; + class_name = str; + } break; + case HEADER_DATA_FIELD_TYPED_ARRAY_SCRIPT: { + ERR_FAIL_COND_V(!p_allow_objects, ERR_UNAUTHORIZED); + + String path; + Error err = _decode_string(buf, len, r_len, path); + if (err) { + return err; + } + ERR_FAIL_COND_V_MSG(path.is_empty() || !path.begins_with("res://") || !ResourceLoader::exists(path, "Script"), ERR_INVALID_DATA, "Invalid script path: '" + path + "'."); + script = ResourceLoader::load(path, "Script"); + ERR_FAIL_COND_V_MSG(script.is_null(), ERR_INVALID_DATA, "Can't load script at path: '" + path + "'."); + + builtin_type = Variant::OBJECT; + class_name = script->get_instance_base_type(); + } break; + default: + ERR_FAIL_V(ERR_INVALID_DATA); // Future proofing. + } + ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA); + int32_t count = decode_uint32(buf); // bool shared = count&0x80000000; count &= 0x7FFFFFFF; @@ -760,6 +837,9 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int } Array varr; + if (builtin_type != Variant::VARIANT_MAX) { + varr.set_typed(builtin_type, class_name, script); + } for (int i = 0; i < count; i++) { int used = 0; @@ -936,7 +1016,7 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int Vector<Vector2> varray; - if (type & ENCODE_FLAG_64) { + if (header & HEADER_DATA_FLAG_64) { ERR_FAIL_MUL_OF(count, sizeof(double) * 2, ERR_INVALID_DATA); ERR_FAIL_COND_V(count < 0 || count * sizeof(double) * 2 > (size_t)len, ERR_INVALID_DATA); @@ -996,7 +1076,7 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int Vector<Vector3> varray; - if (type & ENCODE_FLAG_64) { + if (header & HEADER_DATA_FLAG_64) { ERR_FAIL_MUL_OF(count, sizeof(double) * 3, ERR_INVALID_DATA); ERR_FAIL_COND_V(count < 0 || count * sizeof(double) * 3 > (size_t)len, ERR_INVALID_DATA); @@ -1122,20 +1202,20 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo r_len = 0; - uint32_t flags = 0; + uint32_t header = p_variant.get_type(); switch (p_variant.get_type()) { case Variant::INT: { int64_t val = p_variant; if (val > (int64_t)INT_MAX || val < (int64_t)INT_MIN) { - flags |= ENCODE_FLAG_64; + header |= HEADER_DATA_FLAG_64; } } break; case Variant::FLOAT: { double d = p_variant; float f = d; if (double(f) != d) { - flags |= ENCODE_FLAG_64; + header |= HEADER_DATA_FLAG_64; } } break; case Variant::OBJECT: { @@ -1151,7 +1231,23 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo } if (!p_full_objects) { - flags |= ENCODE_FLAG_OBJECT_AS_ID; + header |= HEADER_DATA_FLAG_OBJECT_AS_ID; + } + } break; + case Variant::ARRAY: { + Array array = p_variant; + if (array.is_typed()) { + Ref<Script> script = array.get_typed_script(); + if (script.is_valid()) { + ERR_FAIL_COND_V(!p_full_objects, ERR_UNAVAILABLE); + header |= HEADER_DATA_FIELD_TYPED_ARRAY_SCRIPT; + } else if (array.get_typed_class_name() != StringName()) { + ERR_FAIL_COND_V(!p_full_objects, ERR_UNAVAILABLE); + header |= HEADER_DATA_FIELD_TYPED_ARRAY_CLASS_NAME; + } else { + ERR_FAIL_COND_V(!p_full_objects && array.get_typed_builtin() == Variant::OBJECT, ERR_UNAVAILABLE); + header |= HEADER_DATA_FIELD_TYPED_ARRAY_BUILTIN; + } } } break; #ifdef REAL_T_IS_DOUBLE @@ -1168,7 +1264,7 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo case Variant::BASIS: case Variant::RECT2: case Variant::AABB: { - flags |= ENCODE_FLAG_64; + header |= HEADER_DATA_FLAG_64; } break; #endif // REAL_T_IS_DOUBLE default: { @@ -1176,7 +1272,7 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo } if (buf) { - encode_uint32(p_variant.get_type() | flags, buf); + encode_uint32(header, buf); buf += 4; } r_len += 4; @@ -1194,7 +1290,7 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo } break; case Variant::INT: { - if (flags & ENCODE_FLAG_64) { + if (header & HEADER_DATA_FLAG_64) { //64 bits if (buf) { encode_uint64(p_variant.operator int64_t(), buf); @@ -1210,7 +1306,7 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo } } break; case Variant::FLOAT: { - if (flags & ENCODE_FLAG_64) { + if (header & HEADER_DATA_FLAG_64) { if (buf) { encode_double(p_variant.operator double(), buf); } @@ -1523,8 +1619,21 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo _encode_string(E.name, buf, r_len); + Variant value; + + if (E.name == CoreStringNames::get_singleton()->_script) { + Ref<Script> script = obj->get_script(); + if (script.is_valid()) { + String path = script->get_path(); + ERR_FAIL_COND_V_MSG(path.is_empty() || !path.begins_with("res://"), ERR_UNAVAILABLE, "Failed to encode a path to a custom script."); + value = path; + } + } else { + value = obj->get(E.name); + } + int len; - Error err = encode_variant(obj->get(E.name), buf, len, p_full_objects, p_depth + 1); + Error err = encode_variant(value, buf, len, p_full_objects, p_depth + 1); ERR_FAIL_COND_V(err, err); ERR_FAIL_COND_V(len % 4, ERR_BUG); r_len += len; @@ -1594,24 +1703,41 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo } break; case Variant::ARRAY: { - Array v = p_variant; + Array array = p_variant; + + if (array.is_typed()) { + Variant variant = array.get_typed_script(); + Ref<Script> script = variant; + if (script.is_valid()) { + String path = script->get_path(); + ERR_FAIL_COND_V_MSG(path.is_empty() || !path.begins_with("res://"), ERR_UNAVAILABLE, "Failed to encode a path to a custom script for an array type."); + _encode_string(path, buf, r_len); + } else if (array.get_typed_class_name() != StringName()) { + _encode_string(array.get_typed_class_name(), buf, r_len); + } else { + if (buf) { + encode_uint32(array.get_typed_builtin(), buf); + buf += 4; + } + r_len += 4; + } + } if (buf) { - encode_uint32(uint32_t(v.size()), buf); + encode_uint32(uint32_t(array.size()), buf); buf += 4; } - r_len += 4; - for (int i = 0; i < v.size(); i++) { + for (int i = 0; i < array.size(); i++) { int len; - Error err = encode_variant(v.get(i), buf, len, p_full_objects, p_depth + 1); + Error err = encode_variant(array.get(i), buf, len, p_full_objects, p_depth + 1); ERR_FAIL_COND_V(err, err); ERR_FAIL_COND_V(len % 4, ERR_BUG); - r_len += len; if (buf) { buf += len; } + r_len += len; } } break; diff --git a/core/io/resource.cpp b/core/io/resource.cpp index 5edb045760..74f18ceee1 100644 --- a/core/io/resource.cpp +++ b/core/io/resource.cpp @@ -214,6 +214,7 @@ Error Resource::copy_from(const Ref<Resource> &p_resource) { } return OK; } + void Resource::reload_from_file() { String path = get_path(); if (!path.is_resource_file()) { @@ -423,8 +424,7 @@ RID Resource::get_rid() const { } } if (_get_extension() && _get_extension()->get_rid) { - RID ret; - ret.from_uint64(_get_extension()->get_rid(_get_extension_instance())); + RID ret = RID::from_uint64(_get_extension()->get_rid(_get_extension_instance())); if (ret.is_valid()) { return ret; } diff --git a/core/io/resource_format_binary.h b/core/io/resource_format_binary.h index e01c5fa467..222e633e58 100644 --- a/core/io/resource_format_binary.h +++ b/core/io/resource_format_binary.h @@ -110,16 +110,16 @@ public: class ResourceFormatLoaderBinary : public ResourceFormatLoader { public: - virtual Ref<Resource> load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE); - virtual void get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const; - 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); - virtual Error rename_dependencies(const String &p_path, const HashMap<String, String> &p_map); + virtual Ref<Resource> load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE) override; + virtual void get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const override; + virtual void get_recognized_extensions(List<String> *p_extensions) const override; + virtual bool handles_type(const String &p_type) const override; + virtual String get_resource_type(const String &p_path) const override; + virtual String get_resource_script_class(const String &p_path) const override; + virtual void get_classes_used(const String &p_path, HashSet<StringName> *r_classes) override; + virtual ResourceUID::ID get_resource_uid(const String &p_path) const override; + virtual void get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types = false) override; + virtual Error rename_dependencies(const String &p_path, const HashMap<String, String> &p_map) override; }; class ResourceFormatSaverBinaryInstance { @@ -181,10 +181,10 @@ public: class ResourceFormatSaverBinary : public ResourceFormatSaver { public: static ResourceFormatSaverBinary *singleton; - virtual Error save(const Ref<Resource> &p_resource, const String &p_path, uint32_t p_flags = 0); - virtual Error set_uid(const String &p_path, ResourceUID::ID p_uid); - virtual bool recognize(const Ref<Resource> &p_resource) const; - virtual void get_recognized_extensions(const Ref<Resource> &p_resource, List<String> *p_extensions) const; + virtual Error save(const Ref<Resource> &p_resource, const String &p_path, uint32_t p_flags = 0) override; + virtual Error set_uid(const String &p_path, ResourceUID::ID p_uid) override; + virtual bool recognize(const Ref<Resource> &p_resource) const override; + virtual void get_recognized_extensions(const Ref<Resource> &p_resource, List<String> *p_extensions) const override; ResourceFormatSaverBinary(); }; diff --git a/core/io/resource_importer.h b/core/io/resource_importer.h index e17644058a..dbd9e70d16 100644 --- a/core/io/resource_importer.h +++ b/core/io/resource_importer.h @@ -59,22 +59,22 @@ class ResourceFormatImporter : public ResourceFormatLoader { public: static ResourceFormatImporter *get_singleton() { return singleton; } - virtual Ref<Resource> load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE); - virtual void get_recognized_extensions(List<String> *p_extensions) const; - virtual void get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const; - virtual bool recognize_path(const String &p_path, const String &p_for_type = String()) const; - virtual bool handles_type(const String &p_type) const; - virtual String get_resource_type(const String &p_path) const; - virtual ResourceUID::ID get_resource_uid(const String &p_path) const; + virtual Ref<Resource> load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE) override; + virtual void get_recognized_extensions(List<String> *p_extensions) const override; + virtual void get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const override; + virtual bool recognize_path(const String &p_path, const String &p_for_type = String()) const override; + virtual bool handles_type(const String &p_type) const override; + virtual String get_resource_type(const String &p_path) const override; + virtual ResourceUID::ID get_resource_uid(const String &p_path) const override; virtual Variant get_resource_metadata(const String &p_path) const; - virtual bool is_import_valid(const String &p_path) const; - virtual void get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types = false); - virtual bool is_imported(const String &p_path) const { return recognize_path(p_path); } - virtual String get_import_group_file(const String &p_path) const; - virtual void get_classes_used(const String &p_path, HashSet<StringName> *r_classes); - virtual bool exists(const String &p_path) const; - - virtual int get_import_order(const String &p_path) const; + virtual bool is_import_valid(const String &p_path) const override; + virtual void get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types = false) override; + virtual bool is_imported(const String &p_path) const override { return recognize_path(p_path); } + virtual String get_import_group_file(const String &p_path) const override; + virtual void get_classes_used(const String &p_path, HashSet<StringName> *r_classes) override; + virtual bool exists(const String &p_path) const override; + + virtual int get_import_order(const String &p_path) const override; Error get_import_order_threads_and_importer(const String &p_path, int &r_order, bool &r_can_threads, String &r_importer) const; diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp index ff563a35b2..191abee315 100644 --- a/core/io/resource_loader.cpp +++ b/core/io/resource_loader.cpp @@ -402,7 +402,7 @@ static String _validate_local_path(const String &p_path) { if (uid != ResourceUID::INVALID_ID) { return ResourceUID::get_singleton()->get_id_path(uid); } else if (p_path.is_relative_path()) { - return "res://" + p_path; + return ("res://" + p_path).simplify_path(); } else { return ProjectSettings::get_singleton()->localize_path(p_path); } diff --git a/core/io/translation_loader_po.h b/core/io/translation_loader_po.h index 16e7c28cbe..a695826e59 100644 --- a/core/io/translation_loader_po.h +++ b/core/io/translation_loader_po.h @@ -38,10 +38,10 @@ class TranslationLoaderPO : public ResourceFormatLoader { public: static Ref<Resource> load_translation(Ref<FileAccess> f, Error *r_error = nullptr); - virtual Ref<Resource> load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE); - 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 Ref<Resource> load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE) override; + virtual void get_recognized_extensions(List<String> *p_extensions) const override; + virtual bool handles_type(const String &p_type) const override; + virtual String get_resource_type(const String &p_path) const override; TranslationLoaderPO() {} }; |