summaryrefslogtreecommitdiff
path: root/core/io/marshalls.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'core/io/marshalls.cpp')
-rw-r--r--core/io/marshalls.cpp206
1 files changed, 133 insertions, 73 deletions
diff --git a/core/io/marshalls.cpp b/core/io/marshalls.cpp
index 8eb40b61d7..c5d59f786d 100644
--- a/core/io/marshalls.cpp
+++ b/core/io/marshalls.cpp
@@ -33,8 +33,28 @@
#include "reference.h"
#include <stdio.h>
+void EncodedObjectAsID::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_object_id", "id"), &EncodedObjectAsID::set_object_id);
+ ClassDB::bind_method(D_METHOD("get_object_id"), &EncodedObjectAsID::get_object_id);
+}
+
+void EncodedObjectAsID::set_object_id(ObjectID p_id) {
+ id = p_id;
+}
+
+ObjectID EncodedObjectAsID::get_object_id() const {
+
+ return id;
+}
+
+EncodedObjectAsID::EncodedObjectAsID() {
+
+ id = 0;
+}
+
#define ENCODE_MASK 0xFF
#define ENCODE_FLAG_64 1 << 16
+#define ENCODE_FLAG_OBJECT_AS_ID 1 << 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);
@@ -381,56 +401,74 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
} break;
case Variant::OBJECT: {
- ERR_FAIL_COND_V(!p_allow_objects, ERR_UNAUTHORIZED);
-
- String str;
- Error err = _decode_string(buf, len, r_len, str);
- if (err)
- return err;
+ if (type & ENCODE_FLAG_OBJECT_AS_ID) {
+ //this _is_ allowed
+ ObjectID val = decode_uint64(buf);
+ if (r_len)
+ (*r_len) += 8;
- if (str == String()) {
- r_variant = (Object *)NULL;
- } else {
+ if (val == 0) {
+ r_variant = (Object *)NULL;
+ } else {
+ Ref<EncodedObjectAsID> obj_as_id;
+ obj_as_id.instance();
+ obj_as_id->set_object_id(val);
- Object *obj = ClassDB::instance(str);
+ r_variant = obj_as_id;
+ }
- ERR_FAIL_COND_V(!obj, ERR_UNAVAILABLE);
- ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA);
+ } else {
+ ERR_FAIL_COND_V(!p_allow_objects, ERR_UNAUTHORIZED);
- int32_t count = decode_uint32(buf);
- buf += 4;
- len -= 4;
- if (r_len) {
- (*r_len) += 4;
- }
+ String str;
+ Error err = _decode_string(buf, len, r_len, str);
+ if (err)
+ return err;
- for (int i = 0; i < count; i++) {
+ if (str == String()) {
+ r_variant = (Object *)NULL;
+ } else {
- str = String();
- err = _decode_string(buf, len, r_len, str);
- if (err)
- return err;
+ Object *obj = ClassDB::instance(str);
- Variant value;
- int used;
- err = decode_variant(value, buf, len, &used, p_allow_objects);
- if (err)
- return err;
+ ERR_FAIL_COND_V(!obj, ERR_UNAVAILABLE);
+ ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA);
- buf += used;
- len -= used;
+ int32_t count = decode_uint32(buf);
+ buf += 4;
+ len -= 4;
if (r_len) {
- (*r_len) += used;
+ (*r_len) += 4;
}
- obj->set(str, value);
- }
+ for (int i = 0; i < count; i++) {
- if (obj->cast_to<Reference>()) {
- REF ref = REF(obj->cast_to<Reference>());
- r_variant = ref;
- } else {
- r_variant = obj;
+ str = String();
+ err = _decode_string(buf, len, r_len, str);
+ if (err)
+ return err;
+
+ Variant value;
+ int used;
+ err = decode_variant(value, buf, len, &used, p_allow_objects);
+ if (err)
+ return err;
+
+ buf += used;
+ len -= used;
+ if (r_len) {
+ (*r_len) += used;
+ }
+
+ obj->set(str, value);
+ }
+
+ if (obj->cast_to<Reference>()) {
+ REF ref = REF(obj->cast_to<Reference>());
+ r_variant = ref;
+ } else {
+ r_variant = obj;
+ }
}
}
@@ -776,7 +814,7 @@ static void _encode_string(const String &p_string, uint8_t *&buf, int &r_len) {
r_len++; //pad
}
-Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len) {
+Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bool p_object_as_id) {
uint8_t *buf = r_buffer;
@@ -800,6 +838,11 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len) {
flags |= ENCODE_FLAG_64; //always encode real as double
}
} break;
+ case Variant::OBJECT: {
+ if (p_object_as_id) {
+ flags |= ENCODE_FLAG_OBJECT_AS_ID;
+ }
+ } break;
}
if (buf) {
@@ -1071,49 +1114,66 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len) {
} break;
case Variant::OBJECT: {
- Object *obj = p_variant;
- if (!obj) {
+ if (p_object_as_id) {
+
if (buf) {
- encode_uint32(0, buf);
- buf += 4;
- r_len += 4;
+
+ Object *obj = p_variant;
+ ObjectID id = 0;
+ if (obj && ObjectDB::instance_validate(obj)) {
+ id = obj->get_instance_id();
+ }
+
+ encode_uint64(id, buf);
}
+
+ r_len += 8;
+
} else {
- _encode_string(obj->get_class(), buf, r_len);
+ Object *obj = p_variant;
+ if (!obj) {
+ if (buf) {
+ encode_uint32(0, buf);
+ buf += 4;
+ r_len += 4;
+ }
+ } else {
+ _encode_string(obj->get_class(), buf, r_len);
- List<PropertyInfo> props;
- obj->get_property_list(&props);
+ List<PropertyInfo> props;
+ obj->get_property_list(&props);
- int pc = 0;
- for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) {
+ int pc = 0;
+ for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) {
- if (!(E->get().usage & PROPERTY_USAGE_STORAGE))
- continue;
- pc++;
- }
+ if (!(E->get().usage & PROPERTY_USAGE_STORAGE))
+ continue;
+ pc++;
+ }
- if (buf) {
- encode_uint32(pc, buf);
- buf += 4;
- }
+ if (buf) {
+ encode_uint32(pc, buf);
+ buf += 4;
+ }
- r_len += 4;
+ r_len += 4;
- for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) {
+ for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) {
- if (!(E->get().usage & PROPERTY_USAGE_STORAGE))
- continue;
+ if (!(E->get().usage & PROPERTY_USAGE_STORAGE))
+ continue;
- _encode_string(E->get().name, buf, r_len);
+ _encode_string(E->get().name, buf, r_len);
- int len;
- Error err = encode_variant(obj->get(E->get().name), buf, len);
- if (err)
- return err;
- ERR_FAIL_COND_V(len % 4, ERR_BUG);
- r_len += len;
- if (buf)
- buf += len;
+ int len;
+ Error err = encode_variant(obj->get(E->get().name), buf, len, p_object_as_id);
+ if (err)
+ return err;
+ ERR_FAIL_COND_V(len % 4, ERR_BUG);
+ r_len += len;
+ if (buf)
+ buf += len;
+ }
}
}
@@ -1147,12 +1207,12 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len) {
r_len++; //pad
*/
int len;
- encode_variant(E->get(), buf, len);
+ encode_variant(E->get(), buf, len, p_object_as_id);
ERR_FAIL_COND_V(len % 4, ERR_BUG);
r_len += len;
if (buf)
buf += len;
- encode_variant(d[E->get()], buf, len);
+ encode_variant(d[E->get()], buf, len, p_object_as_id);
ERR_FAIL_COND_V(len % 4, ERR_BUG);
r_len += len;
if (buf)
@@ -1174,7 +1234,7 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len) {
for (int i = 0; i < v.size(); i++) {
int len;
- encode_variant(v.get(i), buf, len);
+ encode_variant(v.get(i), buf, len, p_object_as_id);
ERR_FAIL_COND_V(len % 4, ERR_BUG);
r_len += len;
if (buf)