summaryrefslogtreecommitdiffstats
path: root/core/io
diff options
context:
space:
mode:
Diffstat (limited to 'core/io')
-rw-r--r--core/io/file_access.cpp7
-rw-r--r--core/io/file_access.h1
-rw-r--r--core/io/image_loader.h8
-rw-r--r--core/io/json.h14
-rw-r--r--core/io/marshalls.cpp212
-rw-r--r--core/io/resource.cpp1
-rw-r--r--core/io/resource_format_binary.h28
-rw-r--r--core/io/resource_importer.h30
-rw-r--r--core/io/translation_loader_po.h8
9 files changed, 221 insertions, 88 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_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..dc974a545a 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()) {
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/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() {}
};