diff options
author | Juan Linietsky <juan@godotengine.org> | 2020-02-12 14:24:06 -0300 |
---|---|---|
committer | Juan Linietsky <juan@godotengine.org> | 2020-02-12 14:24:54 -0300 |
commit | cf8c679a23b21d6c6f29cba6a54eaa2eed88bf92 (patch) | |
tree | 52aca947b395362b2addec4843915b15947c32ca /core | |
parent | 4aa31a2851e3dd5b67193194f899850239b2669d (diff) |
ObjectID converted to a structure, fixes many bugs where used incorrectly as 32 bits.
Diffstat (limited to 'core')
-rw-r--r-- | core/func_ref.cpp | 9 | ||||
-rw-r--r-- | core/hashfuncs.h | 3 | ||||
-rw-r--r-- | core/io/marshalls.cpp | 9 | ||||
-rw-r--r-- | core/io/multiplayer_api.cpp | 1 | ||||
-rw-r--r-- | core/method_ptrcall.h | 16 | ||||
-rw-r--r-- | core/object.cpp | 9 | ||||
-rw-r--r-- | core/object.h | 7 | ||||
-rw-r--r-- | core/object_id.h | 32 | ||||
-rw-r--r-- | core/reference.cpp | 9 | ||||
-rw-r--r-- | core/type_info.h | 10 | ||||
-rw-r--r-- | core/variant.cpp | 13 | ||||
-rw-r--r-- | core/variant.h | 4 |
12 files changed, 97 insertions, 25 deletions
diff --git a/core/func_ref.cpp b/core/func_ref.cpp index 2dffb30bab..e20188c813 100644 --- a/core/func_ref.cpp +++ b/core/func_ref.cpp @@ -32,7 +32,7 @@ Variant FuncRef::call_func(const Variant **p_args, int p_argcount, Variant::CallError &r_error) { - if (id == 0) { + if (id.is_null()) { r_error.error = Variant::CallError::CALL_ERROR_INSTANCE_IS_NULL; return Variant(); } @@ -48,7 +48,7 @@ Variant FuncRef::call_func(const Variant **p_args, int p_argcount, Variant::Call Variant FuncRef::call_funcv(const Array &p_args) { - ERR_FAIL_COND_V(id == 0, Variant()); + ERR_FAIL_COND_V(id.is_null(), Variant()); Object *obj = ObjectDB::get_instance(id); @@ -69,7 +69,7 @@ void FuncRef::set_function(const StringName &p_func) { } bool FuncRef::is_valid() const { - if (id == 0) + if (id.is_null()) return false; Object *obj = ObjectDB::get_instance(id); @@ -95,6 +95,5 @@ void FuncRef::_bind_methods() { ClassDB::bind_method(D_METHOD("is_valid"), &FuncRef::is_valid); } -FuncRef::FuncRef() : - id(0) { +FuncRef::FuncRef() { } diff --git a/core/hashfuncs.h b/core/hashfuncs.h index 647e8a40b2..d6cf04e560 100644 --- a/core/hashfuncs.h +++ b/core/hashfuncs.h @@ -34,10 +34,10 @@ #include "core/math/math_defs.h" #include "core/math/math_funcs.h" #include "core/node_path.h" +#include "core/object_id.h" #include "core/string_name.h" #include "core/typedefs.h" #include "core/ustring.h" - /** * Hashing functions */ @@ -137,6 +137,7 @@ struct HashMapHasherDefault { static _FORCE_INLINE_ uint32_t hash(const String &p_string) { return p_string.hash(); } static _FORCE_INLINE_ uint32_t hash(const char *p_cstr) { return hash_djb2(p_cstr); } static _FORCE_INLINE_ uint32_t hash(const uint64_t p_int) { return hash_one_uint64(p_int); } + static _FORCE_INLINE_ uint32_t hash(const ObjectID &p_id) { return hash_one_uint64(p_id); } static _FORCE_INLINE_ uint32_t hash(const int64_t p_int) { return hash(uint64_t(p_int)); } static _FORCE_INLINE_ uint32_t hash(const float p_float) { return hash_djb2_one_float(p_float); } diff --git a/core/io/marshalls.cpp b/core/io/marshalls.cpp index e847a9cf0c..fdce9db2a0 100644 --- a/core/io/marshalls.cpp +++ b/core/io/marshalls.cpp @@ -53,8 +53,7 @@ ObjectID EncodedObjectAsID::get_object_id() const { return id; } -EncodedObjectAsID::EncodedObjectAsID() : - id(0) { +EncodedObjectAsID::EncodedObjectAsID() { } #define _S(a) ((int32_t)a) @@ -386,11 +385,11 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int if (type & ENCODE_FLAG_OBJECT_AS_ID) { //this _is_ allowed ERR_FAIL_COND_V(len < 8, ERR_INVALID_DATA); - ObjectID val = decode_uint64(buf); + ObjectID val = ObjectID(decode_uint64(buf)); if (r_len) (*r_len) += 8; - if (val == 0) { + if (val.is_null()) { r_variant = (Object *)NULL; } else { Ref<EncodedObjectAsID> obj_as_id; @@ -1129,7 +1128,7 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo if (buf) { Object *obj = p_variant; - ObjectID id = 0; + ObjectID id; if (obj && ObjectDB::instance_validate(obj)) { id = obj->get_instance_id(); } diff --git a/core/io/multiplayer_api.cpp b/core/io/multiplayer_api.cpp index 27c122fac7..ce641dd0f5 100644 --- a/core/io/multiplayer_api.cpp +++ b/core/io/multiplayer_api.cpp @@ -446,7 +446,6 @@ void MultiplayerAPI::_process_simplify_path(int p_from, const uint8_t *p_packet, PathGetCache::NodeInfo ni; ni.path = path; - ni.instance = 0; path_get_cache[p_from].nodes[id] = ni; diff --git a/core/method_ptrcall.h b/core/method_ptrcall.h index 0f2458d982..118970de80 100644 --- a/core/method_ptrcall.h +++ b/core/method_ptrcall.h @@ -32,6 +32,7 @@ #define METHOD_PTRCALL_H #include "core/math/transform_2d.h" +#include "core/object_id.h" #include "core/typedefs.h" #include "core/variant.h" @@ -167,6 +168,21 @@ struct PtrToArg<const T *> { } }; +//this is for ObjectID + +template <> +struct PtrToArg<ObjectID> { + _FORCE_INLINE_ static const ObjectID convert(const void *p_ptr) { + + return ObjectID(*reinterpret_cast<const uint64_t *>(p_ptr)); + } + + _FORCE_INLINE_ static void encode(const ObjectID &p_val, void *p_ptr) { + + *((uint64_t *)p_ptr) = p_val; + } +}; + //this is for the special cases used by Variant #define MAKE_VECARG(m_type) \ diff --git a/core/object.cpp b/core/object.cpp index 937b1ae8d4..dc1dc2c41f 100644 --- a/core/object.cpp +++ b/core/object.cpp @@ -1916,7 +1916,6 @@ Object::Object() { _class_ptr = NULL; _block_signals = false; _predelete_ok = 0; - _instance_id = 0; _instance_id = ObjectDB::add_instance(this); _can_translate = true; _is_queued_for_deletion = false; @@ -1972,7 +1971,7 @@ Object::~Object() { } ObjectDB::remove_instance(this); - _instance_id = 0; + _instance_id = ObjectID(); _predelete_ok = 2; if (!ScriptServer::are_languages_finished()) { @@ -1995,14 +1994,14 @@ void postinitialize_handler(Object *p_object) { } HashMap<ObjectID, Object *> ObjectDB::instances; -ObjectID ObjectDB::instance_counter = 1; +uint64_t ObjectDB::instance_counter = 1; HashMap<Object *, ObjectID, ObjectDB::ObjectPtrHash> ObjectDB::instance_checks; ObjectID ObjectDB::add_instance(Object *p_object) { - ERR_FAIL_COND_V(p_object->get_instance_id() != 0, 0); + ERR_FAIL_COND_V(p_object->get_instance_id().is_valid(), ObjectID()); rw_lock->write_lock(); - ObjectID instance_id = ++instance_counter; + ObjectID instance_id = ObjectID(++instance_counter); instances[instance_id] = p_object; instance_checks[p_object] = instance_id; diff --git a/core/object.h b/core/object.h index 865c155764..312fe07a17 100644 --- a/core/object.h +++ b/core/object.h @@ -34,6 +34,7 @@ #include "core/hash_map.h" #include "core/list.h" #include "core/map.h" +#include "core/object_id.h" #include "core/os/rw_lock.h" #include "core/set.h" #include "core/variant.h" @@ -89,6 +90,7 @@ enum PropertyHint { PROPERTY_HINT_OBJECT_TOO_BIG, ///< object is too big to send PROPERTY_HINT_NODE_PATH_VALID_TYPES, PROPERTY_HINT_SAVE_FILE, ///< a file path must be passed, hint_text (optionally) is a filter "*.png,*.wav,*.doc,". This opens a save dialog + PROPERTY_HINT_INT_IS_OBJECTID, PROPERTY_HINT_MAX, // When updating PropertyHint, also sync the hardcoded list in VisualScriptEditorVariableEdit }; @@ -397,7 +399,6 @@ public: \ private: class ScriptInstance; -typedef uint64_t ObjectID; class Object { public: @@ -452,7 +453,7 @@ private: _id(p_id), method(p_method) { } - Target() { _id = 0; } + Target() { _id = ObjectID(); } }; struct Slot { @@ -775,7 +776,7 @@ class ObjectDB { static HashMap<ObjectID, Object *> instances; static HashMap<Object *, ObjectID, ObjectPtrHash> instance_checks; - static ObjectID instance_counter; + static uint64_t instance_counter; friend class Object; friend void unregister_core_types(); diff --git a/core/object_id.h b/core/object_id.h new file mode 100644 index 0000000000..f0ff2a24f5 --- /dev/null +++ b/core/object_id.h @@ -0,0 +1,32 @@ +#ifndef OBJECT_ID_H +#define OBJECT_ID_H + +#include "core/typedefs.h" + +// Class to store an object ID (int64) +// needs to be compatile with int64 because this is what Variant uses +// Also, need to be explicitly only castable to 64 bits integer types +// to avoid bugs due to loss of precision + +class ObjectID { + uint64_t id = 0; + +public: + _ALWAYS_INLINE_ bool is_valid() const { return id != 0; } + _ALWAYS_INLINE_ bool is_null() const { return id == 0; } + _ALWAYS_INLINE_ operator uint64_t() const { return id; } + _ALWAYS_INLINE_ operator int64_t() const { return id; } + + _ALWAYS_INLINE_ bool operator==(const ObjectID &p_id) const { return id == p_id.id; } + _ALWAYS_INLINE_ bool operator!=(const ObjectID &p_id) const { return id != p_id.id; } + _ALWAYS_INLINE_ bool operator<(const ObjectID &p_id) const { return id < p_id.id; } + + _ALWAYS_INLINE_ void operator=(int64_t p_int64) { id = p_int64; } + _ALWAYS_INLINE_ void operator=(uint64_t p_uint64) { id = p_uint64; } + + _ALWAYS_INLINE_ ObjectID() {} + _ALWAYS_INLINE_ explicit ObjectID(const uint64_t p_id) { id = p_id; } + _ALWAYS_INLINE_ explicit ObjectID(const int64_t p_id) { id = p_id; } +}; + +#endif // OBJECT_ID_H diff --git a/core/reference.cpp b/core/reference.cpp index b24b2a3ec0..5c211fe301 100644 --- a/core/reference.cpp +++ b/core/reference.cpp @@ -113,7 +113,7 @@ Reference::~Reference() { Variant WeakRef::get_ref() const { - if (ref == 0) + if (ref.is_null()) return Variant(); Object *obj = ObjectDB::get_instance(ref); @@ -129,16 +129,15 @@ Variant WeakRef::get_ref() const { } void WeakRef::set_obj(Object *p_object) { - ref = p_object ? p_object->get_instance_id() : 0; + ref = p_object ? p_object->get_instance_id() : ObjectID(); } void WeakRef::set_ref(const REF &p_ref) { - ref = p_ref.is_valid() ? p_ref->get_instance_id() : 0; + ref = p_ref.is_valid() ? p_ref->get_instance_id() : ObjectID(); } -WeakRef::WeakRef() : - ref(0) { +WeakRef::WeakRef() { } void WeakRef::_bind_methods() { diff --git a/core/type_info.h b/core/type_info.h index 68bc1cc554..b9e5b61a6a 100644 --- a/core/type_info.h +++ b/core/type_info.h @@ -187,6 +187,16 @@ struct GetTypeInfo<const RefPtr &> { } }; +//objectID +template <> +struct GetTypeInfo<ObjectID> { + static const Variant::Type VARIANT_TYPE = Variant::INT; + static const GodotTypeInfo::Metadata METADATA = GodotTypeInfo::METADATA_NONE; + static inline PropertyInfo get_class_info() { + return PropertyInfo(Variant::INT, String(), PROPERTY_HINT_INT_IS_OBJECTID); + } +}; + //for variant template <> struct GetTypeInfo<Variant> { diff --git a/core/variant.cpp b/core/variant.cpp index f4e4cd5341..0f04710d13 100644 --- a/core/variant.cpp +++ b/core/variant.cpp @@ -1248,6 +1248,14 @@ Variant::operator uint64_t() const { } } +Variant::operator ObjectID() const { + if (type == INT) { + return ObjectID(_data._int); + } else { + return ObjectID(); + } +} + #ifdef NEED_LONG_INT Variant::operator signed long() const { @@ -2193,6 +2201,11 @@ Variant::Variant(double p_double) { _data._real = p_double; } +Variant::Variant(const ObjectID &p_id) { + type = INT; + _data._int = p_id; +} + Variant::Variant(const StringName &p_string) { type = STRING; diff --git a/core/variant.h b/core/variant.h index 06be914408..d8007f9e12 100644 --- a/core/variant.h +++ b/core/variant.h @@ -44,6 +44,7 @@ #include "core/math/transform_2d.h" #include "core/math/vector3.h" #include "core/node_path.h" +#include "core/object_id.h" #include "core/pool_vector.h" #include "core/ref_ptr.h" #include "core/rid.h" @@ -177,6 +178,8 @@ public: operator unsigned long() const; #endif + operator ObjectID() const; + operator CharType() const; operator float() const; operator double() const; @@ -248,6 +251,7 @@ public: Variant(uint64_t p_int); Variant(float p_float); Variant(double p_double); + Variant(const ObjectID &p_id); Variant(const String &p_string); Variant(const StringName &p_string); Variant(const char *const p_cstring); |