diff options
Diffstat (limited to 'core/io/marshalls.cpp')
-rw-r--r-- | core/io/marshalls.cpp | 206 |
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) |