diff options
author | Rémi Verschelde <rverschelde@gmail.com> | 2020-02-15 15:30:46 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-02-15 15:30:46 +0100 |
commit | 264f20f8c1b326546494b10f485ff8bc7464b253 (patch) | |
tree | 3a0fa22ce848b4ee20df2057ebb5eb5d7ea8e89b | |
parent | 53cf289f309ef44821e5bb1fe0c81de29a82d9d3 (diff) | |
parent | 867d073b98344b848c96012418912a7e72841a31 (diff) |
Merge pull request #36189 from reduz/object-id-refactor
Changed logic and optimized ObjectID in ObjectDB and Variant, removed…
51 files changed, 432 insertions, 559 deletions
diff --git a/core/io/marshalls.cpp b/core/io/marshalls.cpp index fdce9db2a0..17edc4982c 100644 --- a/core/io/marshalls.cpp +++ b/core/io/marshalls.cpp @@ -802,10 +802,10 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo } } break; case Variant::OBJECT: { -#ifdef DEBUG_ENABLED + // Test for potential wrong values sent by the debugger when it breaks. - Object *obj = p_variant; - if (!obj || !ObjectDB::instance_validate(obj)) { + Object *obj = p_variant.get_validated_object(); + if (!obj) { // Object is invalid, send a NULL instead. if (buf) { encode_uint32(Variant::NIL, buf); @@ -813,7 +813,7 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo r_len += 4; return OK; } -#endif // DEBUG_ENABLED + if (!p_full_objects) { flags |= ENCODE_FLAG_OBJECT_AS_ID; } @@ -1127,9 +1127,9 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo } else { if (buf) { - Object *obj = p_variant; + Object *obj = p_variant.get_validated_object(); ObjectID id; - if (obj && ObjectDB::instance_validate(obj)) { + if (obj) { id = obj->get_instance_id(); } diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp index 4a2bea3182..02ae5788fc 100644 --- a/core/io/resource_format_binary.cpp +++ b/core/io/resource_format_binary.cpp @@ -1573,7 +1573,7 @@ void ResourceFormatSaverBinaryInstance::_find_resources(const Variant &p_variant switch (p_variant.get_type()) { case Variant::OBJECT: { - RES res = p_variant.operator RefPtr(); + RES res = p_variant; if (res.is_null() || external_resources.has(res)) return; diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp index 0ee6478fa2..6877f816e1 100644 --- a/core/io/resource_loader.cpp +++ b/core/io/resource_loader.cpp @@ -955,7 +955,7 @@ bool ResourceLoader::add_custom_resource_format_loader(String script_path) { ERR_FAIL_COND_V_MSG(obj == NULL, false, "Cannot instance script as custom resource loader, expected 'ResourceFormatLoader' inheritance, got: " + String(ibt) + "."); ResourceFormatLoader *crl = Object::cast_to<ResourceFormatLoader>(obj); - crl->set_script(s.get_ref_ptr()); + crl->set_script(s); ResourceLoader::add_resource_format_loader(crl); return true; diff --git a/core/io/resource_saver.cpp b/core/io/resource_saver.cpp index b468685e4d..685d21107f 100644 --- a/core/io/resource_saver.cpp +++ b/core/io/resource_saver.cpp @@ -221,7 +221,7 @@ bool ResourceSaver::add_custom_resource_format_saver(String script_path) { ERR_FAIL_COND_V_MSG(obj == NULL, false, "Cannot instance script as custom resource saver, expected 'ResourceFormatSaver' inheritance, got: " + String(ibt) + "."); ResourceFormatSaver *crl = Object::cast_to<ResourceFormatSaver>(obj); - crl->set_script(s.get_ref_ptr()); + crl->set_script(s); ResourceSaver::add_resource_format_saver(crl); return true; diff --git a/core/object.cpp b/core/object.cpp index dc1dc2c41f..9a5cfe5c22 100644 --- a/core/object.cpp +++ b/core/object.cpp @@ -968,7 +968,7 @@ void Object::cancel_delete() { _predelete_ok = true; } -void Object::set_script_and_instance(const RefPtr &p_script, ScriptInstance *p_instance) { +void Object::set_script_and_instance(const Variant &p_script, ScriptInstance *p_instance) { //this function is not meant to be used in any of these ways ERR_FAIL_COND(p_script.is_null()); @@ -979,7 +979,7 @@ void Object::set_script_and_instance(const RefPtr &p_script, ScriptInstance *p_i script_instance = p_instance; } -void Object::set_script(const RefPtr &p_script) { +void Object::set_script(const Variant &p_script) { if (script == p_script) return; @@ -990,7 +990,7 @@ void Object::set_script(const RefPtr &p_script) { } script = p_script; - Ref<Script> s(script); + Ref<Script> s = script; if (!s.is_null()) { if (s->can_instance()) { @@ -1017,12 +1017,12 @@ void Object::set_script_instance(ScriptInstance *p_instance) { script_instance = p_instance; if (p_instance) - script = p_instance->get_script().get_ref_ptr(); + script = p_instance->get_script(); else - script = RefPtr(); + script = Variant(); } -RefPtr Object::get_script() const { +Variant Object::get_script() const { return script; } @@ -1911,8 +1911,8 @@ void Object::set_script_instance_binding(int p_script_language_index, void *p_da _script_instance_bindings[p_script_language_index] = p_data; } -Object::Object() { - +void Object::_construct_object(bool p_reference) { + type_is_reference = p_reference; _class_ptr = NULL; _block_signals = false; _predelete_ok = 0; @@ -1933,6 +1933,14 @@ Object::Object() { _lock_index.init(1); #endif } +Object::Object(bool p_reference) { + _construct_object(p_reference); +} + +Object::Object() { + + _construct_object(false); +} Object::~Object() { @@ -1993,96 +2001,139 @@ void postinitialize_handler(Object *p_object) { p_object->_postinitialize(); } -HashMap<ObjectID, Object *> ObjectDB::instances; -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().is_valid(), ObjectID()); - - rw_lock->write_lock(); - ObjectID instance_id = ObjectID(++instance_counter); - instances[instance_id] = p_object; - instance_checks[p_object] = instance_id; - - rw_lock->write_unlock(); +void ObjectDB::debug_objects(DebugFunc p_func) { - return instance_id; + spin_lock.lock(); + for (uint32_t i = 0; i < slot_count; i++) { + uint32_t slot = object_slots[i].next_free; + p_func(object_slots[slot].object); + } + spin_lock.unlock(); } -void ObjectDB::remove_instance(Object *p_object) { +void Object::get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const { +} - rw_lock->write_lock(); +SpinLock ObjectDB::spin_lock; +uint32_t ObjectDB::slot_count = 0; +uint32_t ObjectDB::slot_max = 0; +ObjectDB::ObjectSlot *ObjectDB::object_slots = nullptr; +uint64_t ObjectDB::validator_counter = 0; - instances.erase(p_object->get_instance_id()); - instance_checks.erase(p_object); +int ObjectDB::get_object_count() { - rw_lock->write_unlock(); + return slot_count; } -Object *ObjectDB::get_instance(ObjectID p_instance_id) { - rw_lock->read_lock(); - Object **obj = instances.getptr(p_instance_id); - rw_lock->read_unlock(); +ObjectID ObjectDB::add_instance(Object *p_object) { - if (!obj) - return NULL; - return *obj; -} + spin_lock.lock(); + if (unlikely(slot_count == slot_max)) { -void ObjectDB::debug_objects(DebugFunc p_func) { + CRASH_COND(slot_count == (1 << OBJECTDB_SLOT_MAX_COUNT_BITS)); + + uint32_t new_slot_max = slot_max > 0 ? slot_max * 2 : 1; + object_slots = (ObjectSlot *)memrealloc(object_slots, sizeof(ObjectSlot) * new_slot_max); + for (uint32_t i = slot_max; i < new_slot_max; i++) { + object_slots[i].object = nullptr; + object_slots[i].is_reference = false; + object_slots[i].next_free = i; + object_slots[i].validator = 0; + } + slot_max = new_slot_max; + } - rw_lock->read_lock(); + uint32_t slot = object_slots[slot_count].next_free; + if (object_slots[slot].object != nullptr) { + spin_lock.unlock(); + ERR_FAIL_COND_V(object_slots[slot].object != nullptr, ObjectID()); + } + object_slots[slot].object = p_object; + object_slots[slot].is_reference = p_object->is_reference(); + validator_counter = (validator_counter + 1) & OBJECTDB_VALIDATOR_MASK; + if (unlikely(validator_counter == 0)) { + validator_counter = 1; + } + object_slots[slot].validator = validator_counter; - const ObjectID *K = NULL; - while ((K = instances.next(K))) { + uint64_t id = validator_counter; + id <<= OBJECTDB_SLOT_MAX_COUNT_BITS; + id |= uint64_t(slot); - p_func(instances[*K]); + if (p_object->is_reference()) { + id |= OBJECTDB_REFERENCE_BIT; } - rw_lock->read_unlock(); -} + slot_count++; -void Object::get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const { + spin_lock.unlock(); + + return ObjectID(id); } -int ObjectDB::get_object_count() { +void ObjectDB::remove_instance(Object *p_object) { + uint64_t t = p_object->get_instance_id(); + uint32_t slot = t & OBJECTDB_SLOT_MAX_COUNT_MASK; //slot is always valid on valid object - rw_lock->read_lock(); - int count = instances.size(); - rw_lock->read_unlock(); + spin_lock.lock(); - return count; -} +#ifdef DEBUG_ENABLED -RWLock *ObjectDB::rw_lock = NULL; + if (object_slots[slot].object != p_object) { + spin_lock.unlock(); + ERR_FAIL_COND(object_slots[slot].object != p_object); + } + { + uint64_t validator = (t >> OBJECTDB_SLOT_MAX_COUNT_BITS) & OBJECTDB_VALIDATOR_MASK; + if (object_slots[slot].validator != validator) { + spin_lock.unlock(); + ERR_FAIL_COND(object_slots[slot].validator != validator); + } + } + +#endif + //decrease slot count + slot_count--; + //set the free slot properly + object_slots[slot_count].next_free = slot; + //invalidate, so checks against it fail + object_slots[slot].validator = 0; + object_slots[slot].is_reference = false; + object_slots[slot].object = nullptr; + + spin_lock.unlock(); +} void ObjectDB::setup() { - rw_lock = RWLock::create(); + //nothing to do now } void ObjectDB::cleanup() { - rw_lock->write_lock(); - if (instances.size()) { + if (slot_count > 0) { + spin_lock.lock(); WARN_PRINT("ObjectDB Instances still exist!"); if (OS::get_singleton()->is_stdout_verbose()) { - const ObjectID *K = NULL; - while ((K = instances.next(K))) { + for (uint32_t i = 0; i < slot_count; i++) { + uint32_t slot = object_slots[i].next_free; + Object *obj = object_slots[slot].object; String node_name; - if (instances[*K]->is_class("Node")) - node_name = " - Node name: " + String(instances[*K]->call("get_name")); - if (instances[*K]->is_class("Resource")) - node_name = " - Resource name: " + String(instances[*K]->call("get_name")) + " Path: " + String(instances[*K]->call("get_path")); - print_line("Leaked instance: " + String(instances[*K]->get_class()) + ":" + itos(*K) + node_name); + if (obj->is_class("Node")) + node_name = " - Node name: " + String(obj->call("get_name")); + if (obj->is_class("Resource")) + node_name = " - Resource name: " + String(obj->call("get_name")) + " Path: " + String(obj->call("get_path")); + + uint64_t id = uint64_t(slot) | (uint64_t(object_slots[slot].validator) << OBJECTDB_VALIDATOR_BITS) | (object_slots[slot].is_reference ? OBJECTDB_REFERENCE_BIT : 0); + print_line("Leaked instance: " + String(obj->get_class()) + ":" + itos(id) + node_name); } } + spin_lock.unlock(); + } + + if (object_slots) { + memfree(object_slots); } - instances.clear(); - instance_checks.clear(); - rw_lock->write_unlock(); - memdelete(rw_lock); } diff --git a/core/object.h b/core/object.h index 312fe07a17..6a229afaea 100644 --- a/core/object.h +++ b/core/object.h @@ -37,6 +37,7 @@ #include "core/object_id.h" #include "core/os/rw_lock.h" #include "core/set.h" +#include "core/spin_lock.h" #include "core/variant.h" #include "core/vmap.h" @@ -488,7 +489,7 @@ private: Set<String> editor_section_folding; #endif ScriptInstance *script_instance; - RefPtr script; + Variant script; //reference does not yet exist, store it in a Dictionary metadata; mutable StringName _class_name; mutable const StringName *_class_ptr; @@ -506,9 +507,13 @@ private: void property_list_changed_notify(); + _FORCE_INLINE_ void _construct_object(bool p_reference); + friend class Reference; + bool type_is_reference = false; uint32_t instance_binding_count; void *_script_instance_bindings[MAX_SCRIPT_INSTANCE_BINDINGS]; + Object(bool p_reference); protected: virtual void _initialize_classv() { initialize_class(); } @@ -680,8 +685,8 @@ public: /* SCRIPT */ - void set_script(const RefPtr &p_script); - RefPtr get_script() const; + void set_script(const Variant &p_script); + Variant get_script() const; /* SCRIPT */ @@ -700,7 +705,7 @@ public: void set_script_instance(ScriptInstance *p_instance); _FORCE_INLINE_ ScriptInstance *get_script_instance() const { return script_instance; } - void set_script_and_instance(const RefPtr &p_script, ScriptInstance *p_instance); //some script languages can't control instance creation, so this function eases the process + void set_script_and_instance(const Variant &p_script, ScriptInstance *p_instance); //some script languages can't control instance creation, so this function eases the process void add_user_signal(const MethodInfo &p_signal); Error emit_signal(const StringName &p_name, VARIANT_ARG_LIST); @@ -751,6 +756,7 @@ public: void clear_internal_resource_paths(); + _ALWAYS_INLINE_ bool is_reference() const { return type_is_reference; } Object(); virtual ~Object(); }; @@ -760,49 +766,63 @@ void postinitialize_handler(Object *p_object); class ObjectDB { - struct ObjectPtrHash { - - static _FORCE_INLINE_ uint32_t hash(const Object *p_obj) { - - union { - const Object *p; - unsigned long i; - } u; - u.p = p_obj; - return HashMapHasherDefault::hash((uint64_t)u.i); - } +//this needs to add up to 63, 1 bit is for reference +#define OBJECTDB_VALIDATOR_BITS 39 +#define OBJECTDB_VALIDATOR_MASK ((uint64_t(1) << OBJECTDB_VALIDATOR_BITS) - 1) +#define OBJECTDB_SLOT_MAX_COUNT_BITS 24 +#define OBJECTDB_SLOT_MAX_COUNT_MASK ((uint64_t(1) << OBJECTDB_SLOT_MAX_COUNT_BITS) - 1) +#define OBJECTDB_REFERENCE_BIT (uint64_t(1) << (OBJECTDB_SLOT_MAX_COUNT_BITS + OBJECTDB_VALIDATOR_BITS)) + + struct ObjectSlot { //128 bits per slot + uint64_t validator : OBJECTDB_VALIDATOR_BITS; + uint64_t next_free : OBJECTDB_SLOT_MAX_COUNT_BITS; + uint64_t is_reference : 1; + Object *object; }; - static HashMap<ObjectID, Object *> instances; - static HashMap<Object *, ObjectID, ObjectPtrHash> instance_checks; + static SpinLock spin_lock; + static uint32_t slot_count; + static uint32_t slot_max; + static ObjectSlot *object_slots; + static uint64_t validator_counter; - static uint64_t instance_counter; friend class Object; friend void unregister_core_types(); - - static RWLock *rw_lock; static void cleanup(); + static ObjectID add_instance(Object *p_object); static void remove_instance(Object *p_object); + friend void register_core_types(); static void setup(); public: typedef void (*DebugFunc)(Object *p_obj); - static Object *get_instance(ObjectID p_instance_id); - static void debug_objects(DebugFunc p_func); - static int get_object_count(); + _ALWAYS_INLINE_ static Object *get_instance(ObjectID p_instance_id) { + + uint64_t id = p_instance_id; + uint32_t slot = id & OBJECTDB_SLOT_MAX_COUNT_MASK; + + ERR_FAIL_COND_V(slot >= slot_max, nullptr); //this should never happen unless RID is corrupted + + spin_lock.lock(); - _FORCE_INLINE_ static bool instance_validate(Object *p_ptr) { - rw_lock->read_lock(); + uint64_t validator = (id >> OBJECTDB_SLOT_MAX_COUNT_BITS) & OBJECTDB_VALIDATOR_MASK; - bool exists = instance_checks.has(p_ptr); + if (unlikely(object_slots[slot].validator != validator)) { + spin_lock.unlock(); + return nullptr; + } + + Object *object = object_slots[slot].object; - rw_lock->read_unlock(); + spin_lock.unlock(); - return exists; + return object; } + static void debug_objects(DebugFunc p_func); + static int get_object_count(); }; //needed by macros diff --git a/core/object_id.h b/core/object_id.h index f0ff2a24f5..6ab1a3031a 100644 --- a/core/object_id.h +++ b/core/object_id.h @@ -12,6 +12,7 @@ class ObjectID { uint64_t id = 0; public: + _ALWAYS_INLINE_ bool is_reference() const { return (id & (uint64_t(1) << 63)) != 0; } _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; } diff --git a/core/os/main_loop.cpp b/core/os/main_loop.cpp index 5ecdd74a4b..6020c4b219 100644 --- a/core/os/main_loop.cpp +++ b/core/os/main_loop.cpp @@ -95,7 +95,7 @@ void MainLoop::input_event(const Ref<InputEvent> &p_event) { void MainLoop::init() { if (init_script.is_valid()) - set_script(init_script.get_ref_ptr()); + set_script(init_script); if (get_script_instance()) get_script_instance()->call("_initialize"); @@ -131,6 +131,6 @@ void MainLoop::finish() { if (get_script_instance()) { get_script_instance()->call("_finalize"); - set_script(RefPtr()); //clear script + set_script(Variant()); //clear script } } diff --git a/core/ref_ptr.cpp b/core/ref_ptr.cpp deleted file mode 100644 index 7e35bcc56c..0000000000 --- a/core/ref_ptr.cpp +++ /dev/null @@ -1,103 +0,0 @@ -/*************************************************************************/ -/* ref_ptr.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "ref_ptr.h" - -#include "core/reference.h" -#include "core/resource.h" - -void RefPtr::operator=(const RefPtr &p_other) { - - Ref<Reference> *ref = reinterpret_cast<Ref<Reference> *>(&data[0]); - Ref<Reference> *ref_other = reinterpret_cast<Ref<Reference> *>(const_cast<char *>(&p_other.data[0])); - - *ref = *ref_other; -} - -bool RefPtr::operator==(const RefPtr &p_other) const { - - Ref<Reference> *ref = reinterpret_cast<Ref<Reference> *>(&data[0]); - Ref<Reference> *ref_other = reinterpret_cast<Ref<Reference> *>(const_cast<char *>(&p_other.data[0])); - - return *ref == *ref_other; -} - -bool RefPtr::operator!=(const RefPtr &p_other) const { - - Ref<Reference> *ref = reinterpret_cast<Ref<Reference> *>(&data[0]); - Ref<Reference> *ref_other = reinterpret_cast<Ref<Reference> *>(const_cast<char *>(&p_other.data[0])); - - return *ref != *ref_other; -} - -RefPtr::RefPtr(const RefPtr &p_other) { - - memnew_placement(&data[0], Ref<Reference>); - - Ref<Reference> *ref = reinterpret_cast<Ref<Reference> *>(&data[0]); - Ref<Reference> *ref_other = reinterpret_cast<Ref<Reference> *>(const_cast<char *>(&p_other.data[0])); - - *ref = *ref_other; -} - -bool RefPtr::is_null() const { - - Ref<Reference> *ref = reinterpret_cast<Ref<Reference> *>(&data[0]); - return ref->is_null(); -} - -RID RefPtr::get_rid() const { - - Ref<Reference> *ref = reinterpret_cast<Ref<Reference> *>(&data[0]); - if (ref->is_null()) - return RID(); - Resource *res = Object::cast_to<Resource>(ref->ptr()); - if (res) - return res->get_rid(); - return RID(); -} - -void RefPtr::unref() { - - Ref<Reference> *ref = reinterpret_cast<Ref<Reference> *>(&data[0]); - ref->unref(); -} - -RefPtr::RefPtr() { - - ERR_FAIL_COND(sizeof(Ref<Reference>) > DATASIZE); - memnew_placement(&data[0], Ref<Reference>); -} - -RefPtr::~RefPtr() { - - Ref<Reference> *ref = reinterpret_cast<Ref<Reference> *>(&data[0]); - ref->~Ref<Reference>(); -} diff --git a/core/ref_ptr.h b/core/ref_ptr.h deleted file mode 100644 index 4736106b4f..0000000000 --- a/core/ref_ptr.h +++ /dev/null @@ -1,62 +0,0 @@ -/*************************************************************************/ -/* ref_ptr.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef REF_PTR_H -#define REF_PTR_H -/** - @author Juan Linietsky <reduzio@gmail.com> - * This class exists to workaround a limitation in C++ but keep the design OK. - * It's basically an opaque container of a Reference reference, so Variant can use it. -*/ - -#include "core/rid.h" - -class RefPtr { - - enum { - - DATASIZE = sizeof(void *) //*4 -ref was shrunk - }; - - mutable char data[DATASIZE]; // too much probably, virtual class + pointer -public: - bool is_null() const; - void operator=(const RefPtr &p_other); - bool operator==(const RefPtr &p_other) const; - bool operator!=(const RefPtr &p_other) const; - RID get_rid() const; - void unref(); - _FORCE_INLINE_ void *get_data() const { return data; } - RefPtr(const RefPtr &p_other); - RefPtr(); - ~RefPtr(); -}; - -#endif // REF_PTR_H diff --git a/core/reference.cpp b/core/reference.cpp index 5c211fe301..dd65ccce69 100644 --- a/core/reference.cpp +++ b/core/reference.cpp @@ -102,7 +102,8 @@ bool Reference::unreference() { return die; } -Reference::Reference() { +Reference::Reference() : + Object(true) { refcount.init(); refcount_init.init(); diff --git a/core/reference.h b/core/reference.h index d2314005b9..b01e0035a7 100644 --- a/core/reference.h +++ b/core/reference.h @@ -33,7 +33,6 @@ #include "core/class_db.h" #include "core/object.h" -#include "core/ref_ptr.h" #include "core/safe_refcount.h" class Reference : public Object { @@ -133,17 +132,9 @@ public: return reference; } - RefPtr get_ref_ptr() const { - - RefPtr refptr; - Ref<Reference> *irr = reinterpret_cast<Ref<Reference> *>(refptr.get_data()); - *irr = *this; - return refptr; - }; - operator Variant() const { - return Variant(get_ref_ptr()); + return Variant(reference); } void operator=(const Ref &p_from) { @@ -165,33 +156,24 @@ public: r.reference = NULL; } - void operator=(const RefPtr &p_refptr) { + void operator=(const Variant &p_variant) { - Ref<Reference> *irr = reinterpret_cast<Ref<Reference> *>(p_refptr.get_data()); - Reference *refb = irr->ptr(); - if (!refb) { - unref(); + Object *object = p_variant.get_validated_object(); + + if (object == reference) { return; } - Ref r; - r.reference = Object::cast_to<T>(refb); - ref(r); - r.reference = NULL; - } - void operator=(const Variant &p_variant) { + unref(); - RefPtr refptr = p_variant; - Ref<Reference> *irr = reinterpret_cast<Ref<Reference> *>(refptr.get_data()); - Reference *refb = irr->ptr(); - if (!refb) { - unref(); + if (!object) { return; } - Ref r; - r.reference = Object::cast_to<T>(refb); - ref(r); - r.reference = NULL; + + Reference *r = Object::cast_to<Reference>(object); + if (r && r->reference()) { + reference = static_cast<T *>(r); + } } template <class T_Other> @@ -237,33 +219,19 @@ public: Ref(const Variant &p_variant) { - RefPtr refptr = p_variant; - Ref<Reference> *irr = reinterpret_cast<Ref<Reference> *>(refptr.get_data()); - reference = NULL; - Reference *refb = irr->ptr(); - if (!refb) { - unref(); + Object *object = p_variant.get_validated_object(); + + if (!object) { + reference = nullptr; return; } - Ref r; - r.reference = Object::cast_to<T>(refb); - ref(r); - r.reference = NULL; - } - - Ref(const RefPtr &p_refptr) { - Ref<Reference> *irr = reinterpret_cast<Ref<Reference> *>(p_refptr.get_data()); - reference = NULL; - Reference *refb = irr->ptr(); - if (!refb) { - unref(); - return; + Reference *r = Object::cast_to<Reference>(object); + if (r && r->reference()) { + reference = static_cast<T *>(r); + } else { + reference = nullptr; } - Ref r; - r.reference = Object::cast_to<T>(refb); - ref(r); - r.reference = NULL; } inline bool is_valid() const { return reference != NULL; } @@ -340,32 +308,6 @@ struct PtrToArg<const Ref<T> &> { } }; -//this is for RefPtr - -template <> -struct PtrToArg<RefPtr> { - - _FORCE_INLINE_ static RefPtr convert(const void *p_ptr) { - - return Ref<Reference>(const_cast<Reference *>(reinterpret_cast<const Reference *>(p_ptr))).get_ref_ptr(); - } - - _FORCE_INLINE_ static void encode(RefPtr p_val, const void *p_ptr) { - - Ref<Reference> r = p_val; - *(Ref<Reference> *)p_ptr = r; - } -}; - -template <> -struct PtrToArg<const RefPtr &> { - - _FORCE_INLINE_ static RefPtr convert(const void *p_ptr) { - - return Ref<Reference>(const_cast<Reference *>(reinterpret_cast<const Reference *>(p_ptr))).get_ref_ptr(); - } -}; - #endif // PTRCALL_ENABLED #ifdef DEBUG_METHODS_ENABLED diff --git a/core/resource.h b/core/resource.h index 00d330a094..b30788010b 100644 --- a/core/resource.h +++ b/core/resource.h @@ -33,7 +33,6 @@ #include "core/class_db.h" #include "core/object.h" -#include "core/ref_ptr.h" #include "core/reference.h" #include "core/safe_refcount.h" #include "core/self_list.h" diff --git a/core/type_info.h b/core/type_info.h index b9e5b61a6a..9ca6d7fe73 100644 --- a/core/type_info.h +++ b/core/type_info.h @@ -169,24 +169,6 @@ MAKE_TYPE_INFO(IP_Address, Variant::STRING) class BSP_Tree; MAKE_TYPE_INFO(BSP_Tree, Variant::DICTIONARY) -//for RefPtr -template <> -struct GetTypeInfo<RefPtr> { - static const Variant::Type VARIANT_TYPE = Variant::OBJECT; - static const GodotTypeInfo::Metadata METADATA = GodotTypeInfo::METADATA_NONE; - static inline PropertyInfo get_class_info() { - return PropertyInfo(Variant::OBJECT, String(), PROPERTY_HINT_RESOURCE_TYPE, "Reference"); - } -}; -template <> -struct GetTypeInfo<const RefPtr &> { - static const Variant::Type VARIANT_TYPE = Variant::OBJECT; - static const GodotTypeInfo::Metadata METADATA = GodotTypeInfo::METADATA_NONE; - static inline PropertyInfo get_class_info() { - return PropertyInfo(Variant::OBJECT, String(), PROPERTY_HINT_RESOURCE_TYPE, "Reference"); - } -}; - //objectID template <> struct GetTypeInfo<ObjectID> { diff --git a/core/variant.cpp b/core/variant.cpp index 0f04710d13..c2ffe3721f 100644 --- a/core/variant.cpp +++ b/core/variant.cpp @@ -908,6 +908,14 @@ bool Variant::is_one() const { return false; } +bool Variant::is_null() const { + if (type == OBJECT && _get_obj().obj) { + return false; + } else { + return true; + } +} + void Variant::reference(const Variant &p_variant) { switch (type) { @@ -999,7 +1007,20 @@ void Variant::reference(const Variant &p_variant) { } break; case OBJECT: { - memnew_placement(_data._mem, ObjData(p_variant._get_obj())); + memnew_placement(_data._mem, ObjData); + + if (p_variant._get_obj().obj && p_variant._get_obj().id.is_reference()) { + Reference *reference = static_cast<Reference *>(p_variant._get_obj().obj); + if (!reference->reference()) { + _get_obj().obj = nullptr; + _get_obj().id = ObjectID(); + break; + } + } + + _get_obj().obj = const_cast<Object *>(p_variant._get_obj().obj); + _get_obj().id = p_variant._get_obj().id; + } break; case NODE_PATH: { @@ -1114,8 +1135,15 @@ void Variant::clear() { } break; case OBJECT: { + if (_get_obj().id.is_reference()) { + //we are safe that there is a reference here + Reference *reference = static_cast<Reference *>(_get_obj().obj); + if (reference->unreference()) { + memdelete(reference); + } + } _get_obj().obj = NULL; - _get_obj().ref.unref(); + _get_obj().id = ObjectID(); } break; case _RID: { // not much need probably @@ -1589,14 +1617,11 @@ String Variant::stringify(List<const void *> &stack) const { case OBJECT: { if (_get_obj().obj) { -#ifdef DEBUG_ENABLED - if (ScriptDebugger::get_singleton() && _get_obj().ref.is_null()) { - //only if debugging! - if (!ObjectDB::instance_validate(_get_obj().obj)) { - return "[Deleted Object]"; - }; + + if (!_get_obj().id.is_reference() && ObjectDB::get_instance(_get_obj().id) == nullptr) { + return "[Freed Object]"; }; -#endif + return _get_obj().obj->to_string(); } else return "[Object:null]"; @@ -1739,24 +1764,16 @@ Variant::operator NodePath() const { return NodePath(); } -Variant::operator RefPtr() const { - - if (type == OBJECT) - return _get_obj().ref; - else - return RefPtr(); -} - Variant::operator RID() const { if (type == _RID) return *reinterpret_cast<const RID *>(_data._mem); - else if (type == OBJECT && !_get_obj().ref.is_null()) { - return _get_obj().ref.get_rid(); + else if (type == OBJECT && _get_obj().obj == nullptr) { + return RID(); } else if (type == OBJECT && _get_obj().obj) { #ifdef DEBUG_ENABLED if (ScriptDebugger::get_singleton()) { - ERR_FAIL_COND_V_MSG(!ObjectDB::instance_validate(_get_obj().obj), RID(), "Invalid pointer (object was deleted)."); + ERR_FAIL_COND_V_MSG(ObjectDB::get_instance(_get_obj().id) == nullptr, RID(), "Invalid pointer (object was freed)."); }; #endif Variant::CallError ce; @@ -1777,6 +1794,25 @@ Variant::operator Object *() const { else return NULL; } + +Object *Variant::get_validated_object_with_check(bool &r_previously_freed) const { + if (type == OBJECT) { + Object *instance = ObjectDB::get_instance(_get_obj().id); + r_previously_freed = !instance && _get_obj().id != ObjectID(); + return instance; + } else { + r_previously_freed = false; + return NULL; + } +} + +Object *Variant::get_validated_object() const { + if (type == OBJECT) + return ObjectDB::get_instance(_get_obj().id); + else + return NULL; +} + Variant::operator Node *() const { if (type == OBJECT) @@ -2289,15 +2325,6 @@ Variant::Variant(const NodePath &p_node_path) { memnew_placement(_data._mem, NodePath(p_node_path)); } -Variant::Variant(const RefPtr &p_resource) { - - type = OBJECT; - memnew_placement(_data._mem, ObjData); - REF *ref = reinterpret_cast<REF *>(p_resource.get_data()); - _get_obj().obj = ref->ptr(); - _get_obj().ref = p_resource; -} - Variant::Variant(const RID &p_rid) { type = _RID; @@ -2309,7 +2336,24 @@ Variant::Variant(const Object *p_object) { type = OBJECT; memnew_placement(_data._mem, ObjData); - _get_obj().obj = const_cast<Object *>(p_object); + + if (p_object) { + + if (p_object->is_reference()) { + Reference *reference = const_cast<Reference *>(static_cast<const Reference *>(p_object)); + if (!reference->init_ref()) { + _get_obj().obj = nullptr; + _get_obj().id = ObjectID(); + return; + } + } + + _get_obj().obj = const_cast<Object *>(p_object); + _get_obj().id = p_object->get_instance_id(); + } else { + _get_obj().obj = nullptr; + _get_obj().id = ObjectID(); + } } Variant::Variant(const Dictionary &p_dictionary) { @@ -2620,7 +2664,26 @@ void Variant::operator=(const Variant &p_variant) { } break; case OBJECT: { - *reinterpret_cast<ObjData *>(_data._mem) = p_variant._get_obj(); + if (_get_obj().id.is_reference()) { + //we are safe that there is a reference here + Reference *reference = static_cast<Reference *>(_get_obj().obj); + if (reference->unreference()) { + memdelete(reference); + } + } + + if (p_variant._get_obj().obj && p_variant._get_obj().id.is_reference()) { + Reference *reference = static_cast<Reference *>(p_variant._get_obj().obj); + if (!reference->reference()) { + _get_obj().obj = nullptr; + _get_obj().id = ObjectID(); + break; + } + } + + _get_obj().obj = const_cast<Object *>(p_variant._get_obj().obj); + _get_obj().id = p_variant._get_obj().id; + } break; case NODE_PATH: { @@ -3131,7 +3194,7 @@ bool Variant::hash_compare(const Variant &p_variant) const { bool Variant::is_ref() const { - return type == OBJECT && !_get_obj().ref.is_null(); + return type == OBJECT && _get_obj().id.is_reference(); } Vector<Variant> varray() { diff --git a/core/variant.h b/core/variant.h index d8007f9e12..bb3840932d 100644 --- a/core/variant.h +++ b/core/variant.h @@ -46,11 +46,9 @@ #include "core/node_path.h" #include "core/object_id.h" #include "core/pool_vector.h" -#include "core/ref_ptr.h" #include "core/rid.h" #include "core/ustring.h" -class RefPtr; class Object; class Node; // helper class Control; // helper @@ -128,12 +126,12 @@ private: struct ObjData { + ObjectID id; Object *obj; - RefPtr ref; }; - _FORCE_INLINE_ ObjData &_get_obj(); - _FORCE_INLINE_ const ObjData &_get_obj() const; + _ALWAYS_INLINE_ ObjData &_get_obj(); + _ALWAYS_INLINE_ const ObjData &_get_obj() const; union { bool _bool; @@ -162,6 +160,7 @@ public: bool is_shared() const; bool is_zero() const; bool is_one() const; + bool is_null() const; operator bool() const; operator signed int() const; @@ -197,7 +196,6 @@ public: operator Color() const; operator NodePath() const; - operator RefPtr() const; operator RID() const; operator Object *() const; @@ -235,6 +233,9 @@ public: operator IP_Address() const; + Object *get_validated_object() const; + Object *get_validated_object_with_check(bool &r_previously_freed) const; + Variant(bool p_bool); Variant(signed int p_int); // real one Variant(unsigned int p_int); @@ -267,7 +268,6 @@ public: Variant(const Transform &p_transform); Variant(const Color &p_color); Variant(const NodePath &p_node_path); - Variant(const RefPtr &p_resource); Variant(const RID &p_rid); Variant(const Object *p_object); Variant(const Dictionary &p_dictionary); diff --git a/core/variant_call.cpp b/core/variant_call.cpp index f088705cdd..ac995d1c78 100644 --- a/core/variant_call.cpp +++ b/core/variant_call.cpp @@ -1099,12 +1099,9 @@ void Variant::call_ptr(const StringName &p_method, const Variant **p_args, int p return; } #ifdef DEBUG_ENABLED - if (ScriptDebugger::get_singleton() && _get_obj().ref.is_null()) { - //only if debugging! - if (!ObjectDB::instance_validate(obj)) { - r_error.error = CallError::CALL_ERROR_INSTANCE_IS_NULL; - return; - } + if (ScriptDebugger::get_singleton() && !_get_obj().id.is_reference() && ObjectDB::get_instance(_get_obj().id) == nullptr) { + r_error.error = CallError::CALL_ERROR_INSTANCE_IS_NULL; + return; } #endif @@ -1274,18 +1271,11 @@ Variant Variant::construct(const Variant::Type p_type, const Variant **p_args, i bool Variant::has_method(const StringName &p_method) const { if (type == OBJECT) { - Object *obj = operator Object *(); + Object *obj = get_validated_object(); if (!obj) return false; -#ifdef DEBUG_ENABLED - if (ScriptDebugger::get_singleton()) { - if (ObjectDB::instance_validate(obj)) { -#endif - return obj->has_method(p_method); -#ifdef DEBUG_ENABLED - } - } -#endif + + return obj->has_method(p_method); } const _VariantCall::TypeFunc &tf = _VariantCall::type_funcs[type]; diff --git a/core/variant_op.cpp b/core/variant_op.cpp index 6caa224cfe..c7a52b0347 100644 --- a/core/variant_op.cpp +++ b/core/variant_op.cpp @@ -1515,7 +1515,7 @@ void Variant::set_named(const StringName &p_index, const Variant &p_value, bool #ifdef DEBUG_ENABLED if (!_get_obj().obj) { break; - } else if (ScriptDebugger::get_singleton() && _get_obj().ref.is_null() && !ObjectDB::instance_validate(_get_obj().obj)) { + } else if (ScriptDebugger::get_singleton() && ObjectDB::get_instance(_get_obj().id) == nullptr) { break; } @@ -1684,7 +1684,7 @@ Variant Variant::get_named(const StringName &p_index, bool *r_valid) const { return "Instance base is null."; } else { - if (ScriptDebugger::get_singleton() && _get_obj().ref.is_null() && !ObjectDB::instance_validate(_get_obj().obj)) { + if (ScriptDebugger::get_singleton() && !_get_obj().id.is_reference() && ObjectDB::get_instance(_get_obj().id) == nullptr) { if (r_valid) *r_valid = false; return "Attempted use of stray pointer object."; @@ -2172,13 +2172,11 @@ void Variant::set(const Variant &p_index, const Variant &p_value, bool *r_valid) if (obj) { #ifdef DEBUG_ENABLED - if (ScriptDebugger::get_singleton() && _get_obj().ref.is_null()) { + if (ScriptDebugger::get_singleton() && !_get_obj().id.is_reference() && ObjectDB::get_instance(_get_obj().id) == nullptr) { - if (!ObjectDB::instance_validate(obj)) { - WARN_PRINT("Attempted use of stray pointer object."); - valid = false; - return; - } + WARN_PRINT("Attempted use of previously freed pointer object."); + valid = false; + return; } #endif @@ -2546,12 +2544,10 @@ Variant Variant::get(const Variant &p_index, bool *r_valid) const { if (obj) { #ifdef DEBUG_ENABLED - if (ScriptDebugger::get_singleton() && _get_obj().ref.is_null()) { - //only if debugging! - if (!ObjectDB::instance_validate(obj)) { - valid = false; - return "Attempted get on stray pointer."; - } + + if (ScriptDebugger::get_singleton() && !_get_obj().id.is_reference() && ObjectDB::get_instance(_get_obj().id) == nullptr) { + valid = false; + return "Attempted get on previously freed instance."; } #endif @@ -2611,15 +2607,14 @@ bool Variant::in(const Variant &p_index, bool *r_valid) const { bool valid = false; #ifdef DEBUG_ENABLED - if (ScriptDebugger::get_singleton() && _get_obj().ref.is_null()) { - //only if debugging! - if (!ObjectDB::instance_validate(obj)) { - if (r_valid) { - *r_valid = false; - } - return true; // Attempted get on stray pointer. + + if (ScriptDebugger::get_singleton() && !_get_obj().id.is_reference() && ObjectDB::get_instance(_get_obj().id) == nullptr) { + if (r_valid) { + *r_valid = false; } + return true; // Attempted get on stray pointer. } + #endif if (p_index.get_type() != Variant::STRING) { @@ -2883,13 +2878,12 @@ void Variant::get_property_list(List<PropertyInfo> *p_list) const { Object *obj = _get_obj().obj; if (obj) { #ifdef DEBUG_ENABLED - if (ScriptDebugger::get_singleton() && _get_obj().ref.is_null()) { - //only if debugging! - if (!ObjectDB::instance_validate(obj)) { - WARN_PRINT("Attempted get_property list on stray pointer."); - return; - } + + if (ScriptDebugger::get_singleton() && !_get_obj().id.is_reference() && ObjectDB::get_instance(_get_obj().id) == nullptr) { + WARN_PRINT("Attempted get_property list on previously freed instance."); + return; } + #endif obj->get_property_list(p_list); @@ -2961,16 +2955,18 @@ bool Variant::iter_init(Variant &r_iter, bool &valid) const { } break; case OBJECT: { -#ifdef DEBUG_ENABLED if (!_get_obj().obj) { valid = false; return false; } - if (ScriptDebugger::get_singleton() && _get_obj().ref.is_null() && !ObjectDB::instance_validate(_get_obj().obj)) { +#ifdef DEBUG_ENABLED + + if (ScriptDebugger::get_singleton() && !_get_obj().id.is_reference() && ObjectDB::get_instance(_get_obj().id) == nullptr) { valid = false; return false; } + #endif Variant::CallError ce; ce.error = Variant::CallError::CALL_OK; @@ -3129,16 +3125,18 @@ bool Variant::iter_next(Variant &r_iter, bool &valid) const { } break; case OBJECT: { -#ifdef DEBUG_ENABLED if (!_get_obj().obj) { valid = false; return false; } - if (ScriptDebugger::get_singleton() && _get_obj().ref.is_null() && !ObjectDB::instance_validate(_get_obj().obj)) { +#ifdef DEBUG_ENABLED + + if (ScriptDebugger::get_singleton() && !_get_obj().id.is_reference() && ObjectDB::get_instance(_get_obj().id) == nullptr) { valid = false; return false; } + #endif Variant::CallError ce; ce.error = Variant::CallError::CALL_OK; @@ -3288,16 +3286,16 @@ Variant Variant::iter_get(const Variant &r_iter, bool &r_valid) const { } break; case OBJECT: { -#ifdef DEBUG_ENABLED if (!_get_obj().obj) { r_valid = false; return Variant(); } - - if (ScriptDebugger::get_singleton() && _get_obj().ref.is_null() && !ObjectDB::instance_validate(_get_obj().obj)) { +#ifdef DEBUG_ENABLED + if (ScriptDebugger::get_singleton() && !_get_obj().id.is_reference() && ObjectDB::get_instance(_get_obj().id) == nullptr) { r_valid = false; return Variant(); } + #endif Variant::CallError ce; ce.error = Variant::CallError::CALL_OK; diff --git a/editor/editor_autoload_settings.cpp b/editor/editor_autoload_settings.cpp index dba8c2ec8c..549b15d6f9 100644 --- a/editor/editor_autoload_settings.cpp +++ b/editor/editor_autoload_settings.cpp @@ -361,7 +361,7 @@ Node *EditorAutoloadSettings::_create_autoload(const String &p_path) { ERR_FAIL_COND_V_MSG(obj == NULL, NULL, "Cannot instance script for autoload, expected 'Node' inheritance, got: " + String(ibt) + "."); n = Object::cast_to<Node>(obj); - n->set_script(s.get_ref_ptr()); + n->set_script(s); } ERR_FAIL_COND_V_MSG(!n, NULL, "Path in autoload not a node or script: " + p_path + "."); diff --git a/editor/editor_data.cpp b/editor/editor_data.cpp index 5cb7720170..1468b8fc35 100644 --- a/editor/editor_data.cpp +++ b/editor/editor_data.cpp @@ -506,7 +506,7 @@ Object *EditorData::instance_custom_type(const String &p_type, const String &p_i if (ob->is_class("Node")) { ob->call("set_name", p_type); } - ob->set_script(script.get_ref_ptr()); + ob->set_script(script); return ob; } } @@ -907,7 +907,7 @@ Object *EditorData::script_class_instance(const String &p_class) { if (obj) { Ref<Script> script = script_class_load_script(p_class); if (script.is_valid()) - obj->set_script(script.get_ref_ptr()); + obj->set_script(script); return obj; } } diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 56581d671a..24656410e8 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -3107,7 +3107,7 @@ void EditorNode::set_addon_plugin_enabled(const String &p_addon, bool p_enabled, } EditorPlugin *ep = memnew(EditorPlugin); - ep->set_script(script.get_ref_ptr()); + ep->set_script(script); plugin_addons[p_addon] = ep; add_editor_plugin(ep, p_config_changed); diff --git a/editor/import/resource_importer_scene.cpp b/editor/import/resource_importer_scene.cpp index 2c2b05d6fc..4b0bfa7222 100644 --- a/editor/import/resource_importer_scene.cpp +++ b/editor/import/resource_importer_scene.cpp @@ -1473,7 +1473,7 @@ Error ResourceImporterScene::import(const String &p_source_file, const String &p } else { post_import_script = Ref<EditorScenePostImport>(memnew(EditorScenePostImport)); - post_import_script->set_script(scr.get_ref_ptr()); + post_import_script->set_script(scr); if (!post_import_script->get_script_instance()) { EditorNode::add_io_error(TTR("Invalid/broken script for post-import (check console):") + " " + post_import_script_path); post_import_script.unref(); diff --git a/editor/plugins/animation_blend_tree_editor_plugin.cpp b/editor/plugins/animation_blend_tree_editor_plugin.cpp index 2de224c043..a100525d10 100644 --- a/editor/plugins/animation_blend_tree_editor_plugin.cpp +++ b/editor/plugins/animation_blend_tree_editor_plugin.cpp @@ -312,7 +312,7 @@ void AnimationNodeBlendTreeEditor::_add_node(int p_idx) { AnimationNode *an = Object::cast_to<AnimationNode>(ClassDB::instance(base_type)); ERR_FAIL_COND(!an); anode = Ref<AnimationNode>(an); - anode->set_script(add_options[p_idx].script.get_ref_ptr()); + anode->set_script(add_options[p_idx].script); base_name = add_options[p_idx].name; } diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp index b8c1ba2e96..76312df20a 100644 --- a/editor/plugins/script_editor_plugin.cpp +++ b/editor/plugins/script_editor_plugin.cpp @@ -1257,7 +1257,7 @@ void ScriptEditor::_menu_option(int p_option) { } Ref<EditorScript> es = memnew(EditorScript); - es->set_script(scr.get_ref_ptr()); + es->set_script(scr); es->set_editor(EditorNode::get_singleton()); es->_run(); diff --git a/editor/plugins/version_control_editor_plugin.cpp b/editor/plugins/version_control_editor_plugin.cpp index 3622ca8d61..e17e6a9d16 100644 --- a/editor/plugins/version_control_editor_plugin.cpp +++ b/editor/plugins/version_control_editor_plugin.cpp @@ -124,7 +124,7 @@ void VersionControlEditorPlugin::_initialize_vcs() { ERR_FAIL_COND_MSG(!addon_script_instance, "Failed to create addon script instance."); // The addon is attached as a script to the VCS interface as a proxy end-point - vcs_interface->set_script_and_instance(script.get_ref_ptr(), addon_script_instance); + vcs_interface->set_script_and_instance(script, addon_script_instance); EditorVCSInterface::set_singleton(vcs_interface); EditorFileSystem::get_singleton()->connect("filesystem_changed", this, "_refresh_stage_area"); diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp index d9bccc35f4..ecc140d7d2 100644 --- a/editor/plugins/visual_shader_editor_plugin.cpp +++ b/editor/plugins/visual_shader_editor_plugin.cpp @@ -216,7 +216,7 @@ void VisualShaderEditor::update_custom_nodes() { Ref<VisualShaderNodeCustom> ref; ref.instance(); - ref->set_script(script.get_ref_ptr()); + ref->set_script(script); String name; if (ref->has_method("_get_name")) { @@ -1415,7 +1415,7 @@ VisualShaderNode *VisualShaderEditor::_add_node(int p_idx, int p_op_idx) { VisualShaderNode *vsn = Object::cast_to<VisualShaderNode>(ClassDB::instance(base_type)); ERR_FAIL_COND_V(!vsn, NULL); vsnode = Ref<VisualShaderNode>(vsn); - vsnode->set_script(add_options[p_idx].script.get_ref_ptr()); + vsnode->set_script(add_options[p_idx].script); } Point2 position = graph->get_scroll_ofs(); diff --git a/editor/property_editor.cpp b/editor/property_editor.cpp index 1691ce3a63..e6128f255d 100644 --- a/editor/property_editor.cpp +++ b/editor/property_editor.cpp @@ -176,9 +176,9 @@ void CustomPropertyEditor::_menu_option(int p_which) { case OBJ_MENU_EDIT: { - RefPtr RefPtr = v; + REF r = v; - if (!RefPtr.is_null()) { + if (!r.is_null()) { emit_signal("resource_edit_request"); hide(); @@ -193,8 +193,7 @@ void CustomPropertyEditor::_menu_option(int p_which) { case OBJ_MENU_MAKE_UNIQUE: { - RefPtr RefPtr = v; - Ref<Resource> res_orig = RefPtr; + Ref<Resource> res_orig = v; if (res_orig.is_null()) return; @@ -229,7 +228,7 @@ void CustomPropertyEditor::_menu_option(int p_which) { res->set(p.first, p.second); } - v = res.get_ref_ptr(); + v = res; emit_signal("variant_changed"); hide(); } break; @@ -311,7 +310,7 @@ void CustomPropertyEditor::_menu_option(int p_which) { res->call("set_instance_base_type", owner->get_class()); } - v = Ref<Resource>(res).get_ref_ptr(); + v = res; emit_signal("variant_changed"); } break; @@ -1103,7 +1102,7 @@ void CustomPropertyEditor::_file_selected(String p_file) { error->popup_centered_minsize(); break; } - v = res.get_ref_ptr(); + v = res; emit_signal("variant_changed"); hide(); } break; @@ -1168,7 +1167,7 @@ void CustomPropertyEditor::_type_create_selected(int p_idx) { Resource *res = Object::cast_to<Resource>(obj); ERR_FAIL_COND(!res); - v = Ref<Resource>(res).get_ref_ptr(); + v = res; emit_signal("variant_changed"); hide(); } @@ -1373,7 +1372,7 @@ void CustomPropertyEditor::_action_pressed(int p_which) { Resource *res = Object::cast_to<Resource>(obj); ERR_BREAK(!res); - v = Ref<Resource>(res).get_ref_ptr(); + v = res; emit_signal("variant_changed"); hide(); } @@ -1395,9 +1394,9 @@ void CustomPropertyEditor::_action_pressed(int p_which) { } else if (p_which == 2) { - RefPtr RefPtr = v; + RES r = v; - if (!RefPtr.is_null()) { + if (!r.is_null()) { emit_signal("resource_edit_request"); hide(); @@ -1410,8 +1409,7 @@ void CustomPropertyEditor::_action_pressed(int p_which) { hide(); } else if (p_which == 4) { - RefPtr RefPtr = v; - Ref<Resource> res_orig = RefPtr; + Ref<Resource> res_orig = v; if (res_orig.is_null()) return; @@ -1442,7 +1440,7 @@ void CustomPropertyEditor::_action_pressed(int p_which) { res->set(p.first, p.second); } - v = res.get_ref_ptr(); + v = res; emit_signal("variant_changed"); hide(); } diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp index 34d6d0580e..784791d40c 100644 --- a/editor/scene_tree_dock.cpp +++ b/editor/scene_tree_dock.cpp @@ -972,7 +972,7 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { new_node = Object::cast_to<Node>(ClassDB::instance(ScriptServer::get_global_class_native_base(name))); Ref<Script> script = ResourceLoader::load(ScriptServer::get_global_class_path(name), "Script"); if (new_node && script.is_valid()) { - new_node->set_script(script.get_ref_ptr()); + new_node->set_script(script); new_node->set_name(name); } } else { @@ -1725,7 +1725,7 @@ void SceneTreeDock::_script_created(Ref<Script> p_script) { for (List<Node *>::Element *E = selected.front(); E; E = E->next()) { Ref<Script> existing = E->get()->get_script(); - editor_data->get_undo_redo().add_do_method(E->get(), "set_script", p_script.get_ref_ptr()); + editor_data->get_undo_redo().add_do_method(E->get(), "set_script", p_script); editor_data->get_undo_redo().add_undo_method(E->get(), "set_script", existing); editor_data->get_undo_redo().add_do_method(this, "_update_script_button"); editor_data->get_undo_redo().add_undo_method(this, "_update_script_button"); diff --git a/editor/scene_tree_editor.cpp b/editor/scene_tree_editor.cpp index a0b846beb0..0e8a9146e1 100644 --- a/editor/scene_tree_editor.cpp +++ b/editor/scene_tree_editor.cpp @@ -70,10 +70,9 @@ void SceneTreeEditor::_cell_button_pressed(Object *p_item, int p_column, int p_i emit_signal("open", n->get_filename()); } } else if (p_id == BUTTON_SCRIPT) { - RefPtr script = n->get_script(); - Ref<Script> script_typed = script; + Ref<Script> script_typed = n->get_script(); if (!script_typed.is_null()) - emit_signal("open_script", script); + emit_signal("open_script", script_typed); } else if (p_id == BUTTON_VISIBILITY) { undo_redo->create_action(TTR("Toggle Visible")); diff --git a/editor/script_create_dialog.cpp b/editor/script_create_dialog.cpp index 6327f30eb4..959bb67e12 100644 --- a/editor/script_create_dialog.cpp +++ b/editor/script_create_dialog.cpp @@ -332,7 +332,7 @@ void ScriptCreateDialog::_load_exist() { return; } - emit_signal("script_created", p_script.get_ref_ptr()); + emit_signal("script_created", p_script); hide(); } diff --git a/editor/script_editor_debugger.cpp b/editor/script_editor_debugger.cpp index 2b28aa87a3..88d45d5dde 100644 --- a/editor/script_editor_debugger.cpp +++ b/editor/script_editor_debugger.cpp @@ -619,7 +619,7 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da if (pinfo.hint_string == "Script") { if (debugObj->get_script() != var) { - debugObj->set_script(RefPtr()); + debugObj->set_script(REF()); Ref<Script> script(var); if (!script.is_null()) { ScriptInstance *script_instance = script->placeholder_instance_create(debugObj); diff --git a/main/main.cpp b/main/main.cpp index 00ce8c6f7b..9f1d9ce5fe 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -1719,7 +1719,7 @@ bool Main::start() { ERR_CONTINUE_MSG(obj == NULL, "Cannot instance script for autoload, expected 'Node' inheritance, got: " + String(ibt)); n = Object::cast_to<Node>(obj); - n->set_script(script_res.get_ref_ptr()); + n->set_script(script_res); } ERR_CONTINUE_MSG(!n, "Path in autoload not a node or script: " + path); diff --git a/modules/gdnative/gdnative/gdnative.cpp b/modules/gdnative/gdnative/gdnative.cpp index bb868d3b52..018a613724 100644 --- a/modules/gdnative/gdnative/gdnative.cpp +++ b/modules/gdnative/gdnative/gdnative.cpp @@ -166,10 +166,6 @@ void _gdnative_report_loading_error(const godot_object *p_library, const char *p _err_print_error("gdnative_init", library->get_current_library_path().utf8().ptr(), 0, message.utf8().ptr()); } -bool GDAPI godot_is_instance_valid(const godot_object *p_object) { - return ObjectDB::instance_validate((Object *)p_object); -} - godot_object GDAPI *godot_instance_from_id(godot_int p_instance_id) { return (godot_object *)ObjectDB::get_instance(ObjectID(p_instance_id)); } diff --git a/modules/gdnative/gdnative/variant.cpp b/modules/gdnative/gdnative/variant.cpp index 11b6448e34..33b378d9cc 100644 --- a/modules/gdnative/gdnative/variant.cpp +++ b/modules/gdnative/gdnative/variant.cpp @@ -178,7 +178,7 @@ void GDAPI godot_variant_new_object(godot_variant *r_dest, const godot_object *p ref = REF(reference); } if (!ref.is_null()) { - memnew_placement_custom(dest, Variant, Variant(ref.get_ref_ptr())); + memnew_placement_custom(dest, Variant, Variant(ref)); } else { #if defined(DEBUG_METHODS_ENABLED) if (reference) { diff --git a/modules/gdnative/gdnative_api.json b/modules/gdnative/gdnative_api.json index 44e407218b..6004b07965 100644 --- a/modules/gdnative/gdnative_api.json +++ b/modules/gdnative/gdnative_api.json @@ -404,13 +404,6 @@ ] }, { - "name": "godot_is_instance_valid", - "return_type": "bool", - "arguments": [ - ["const godot_object *", "p_object"] - ] - }, - { "name": "godot_quat_new_with_basis", "return_type": "void", "arguments": [ diff --git a/modules/gdnative/include/gdnative/gdnative.h b/modules/gdnative/include/gdnative/gdnative.h index 6fd0bdc87f..6fdca30122 100644 --- a/modules/gdnative/include/gdnative/gdnative.h +++ b/modules/gdnative/include/gdnative/gdnative.h @@ -282,9 +282,7 @@ void GDAPI godot_print_error(const char *p_description, const char *p_function, void GDAPI godot_print_warning(const char *p_description, const char *p_function, const char *p_file, int p_line); void GDAPI godot_print(const godot_string *p_message); -// GDNATIVE CORE 1.0.1 - -bool GDAPI godot_is_instance_valid(const godot_object *p_object); +// GDNATIVE CORE 1.0.2? //tags used for safe dynamic casting void GDAPI *godot_get_class_tag(const godot_string_name *p_class); diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp index c71ec6ec76..07c74a2e26 100644 --- a/modules/gdscript/gdscript.cpp +++ b/modules/gdscript/gdscript.cpp @@ -93,6 +93,7 @@ GDScriptInstance *GDScript::_create_instance(const Variant **p_args, int p_argco instance->members.resize(member_indices.size()); instance->script = Ref<GDScript>(this); instance->owner = p_owner; + instance->owner_id = p_owner->get_instance_id(); #ifdef DEBUG_ENABLED //needed for hot reloading for (Map<StringName, MemberInfo>::Element *E = member_indices.front(); E; E = E->next()) { @@ -1792,7 +1793,7 @@ void GDScriptLanguage::reload_tool_script(const Ref<Script> &p_script, bool p_so obj->get_script_instance()->get_property_state(state); map[obj->get_instance_id()] = state; - obj->set_script(RefPtr()); + obj->set_script(Variant()); } } @@ -1808,7 +1809,7 @@ void GDScriptLanguage::reload_tool_script(const Ref<Script> &p_script, bool p_so map.insert(obj->get_instance_id(), List<Pair<StringName, Variant> >()); List<Pair<StringName, Variant> > &state = map[obj->get_instance_id()]; obj->get_script_instance()->get_property_state(state); - obj->set_script(RefPtr()); + obj->set_script(Variant()); } else { // no instance found. Let's remove it so we don't loop forever E->get()->placeholders.erase(E->get()->placeholders.front()->get()); @@ -1839,9 +1840,9 @@ void GDScriptLanguage::reload_tool_script(const Ref<Script> &p_script, bool p_so if (!p_soft_reload) { //clear it just in case (may be a pending reload state) - obj->set_script(RefPtr()); + obj->set_script(Variant()); } - obj->set_script(scr.get_ref_ptr()); + obj->set_script(scr); ScriptInstance *script_instance = obj->get_script_instance(); diff --git a/modules/gdscript/gdscript.h b/modules/gdscript/gdscript.h index 4af574cd9d..3d24f9b3f5 100644 --- a/modules/gdscript/gdscript.h +++ b/modules/gdscript/gdscript.h @@ -241,6 +241,7 @@ class GDScriptInstance : public ScriptInstance { friend class GDScriptFunctions; friend class GDScriptCompiler; + ObjectID owner_id; Object *owner; Ref<GDScript> script; #ifdef DEBUG_ENABLED diff --git a/modules/gdscript/gdscript_function.cpp b/modules/gdscript/gdscript_function.cpp index 7392bbc10a..cbf7d81a61 100644 --- a/modules/gdscript/gdscript_function.cpp +++ b/modules/gdscript/gdscript_function.cpp @@ -137,18 +137,19 @@ static String _get_var_type(const Variant *p_var) { String basestr; if (p_var->get_type() == Variant::OBJECT) { - Object *bobj = *p_var; + bool was_freed; + Object *bobj = p_var->get_validated_object_with_check(was_freed); if (!bobj) { - basestr = "null instance"; - } else { - if (ObjectDB::instance_validate(bobj)) { - if (bobj->get_script_instance()) - basestr = bobj->get_class() + " (" + bobj->get_script_instance()->get_script()->get_path().get_file() + ")"; - else - basestr = bobj->get_class(); + if (was_freed) { + basestr = "null instance"; } else { - basestr = "previously freed instance"; + basestr = "previously freed"; } + } else { + if (bobj->get_script_instance()) + basestr = bobj->get_class() + " (" + bobj->get_script_instance()->get_script()->get_path().get_file() + ")"; + else + basestr = bobj->get_class(); } } else { @@ -497,14 +498,26 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a bool extends_ok = false; if (a->get_type() == Variant::OBJECT && a->operator Object *() != NULL) { - Object *obj_A = *a; - Object *obj_B = *b; #ifdef DEBUG_ENABLED - if (!ObjectDB::instance_validate(obj_A)) { - err_text = "Left operand of 'is' was already freed."; + bool was_freed; + Object *obj_A = a->get_validated_object_with_check(was_freed); + + if (was_freed) { + err_text = "Left operand of 'is' is a previously freed instance."; OPCODE_BREAK; } + + Object *obj_B = b->get_validated_object_with_check(was_freed); + + if (was_freed) { + err_text = "Right operand of 'is' is a previously freed instance."; + OPCODE_BREAK; + } +#else + + Object *obj_A = *a; + Object *obj_B = *b; #endif // DEBUG_ENABLED GDScript *scr_B = Object::cast_to<GDScript>(obj_B); @@ -1298,20 +1311,20 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a } #endif - Object *obj = argobj->operator Object *(); +#ifdef DEBUG_ENABLED + bool was_freed; + Object *obj = argobj->get_validated_object_with_check(was_freed); String signal = argname->operator String(); -#ifdef DEBUG_ENABLED + if (was_freed) { + err_text = "First argument of yield() is a previously freed instance."; + OPCODE_BREAK; + } + if (!obj) { err_text = "First argument of yield() is null."; OPCODE_BREAK; } - if (ScriptDebugger::get_singleton()) { - if (!ObjectDB::instance_validate(obj)) { - err_text = "First argument of yield() is a previously freed instance."; - OPCODE_BREAK; - } - } if (signal.length() == 0) { err_text = "Second argument of yield() is an empty string (for signal name)."; @@ -1324,6 +1337,9 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a OPCODE_BREAK; } #else + Object *obj = argobj->operator Object *(); + String signal = argname->operator String(); + obj->connect(signal, gdfs.ptr(), "_signal_callback", varray(gdfs), Object::CONNECT_ONESHOT); #endif } @@ -1565,14 +1581,14 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a //error // function, file, line, error, explanation String err_file; - if (p_instance && ObjectDB::instance_validate(p_instance->owner) && p_instance->script->is_valid() && p_instance->script->path != "") + if (p_instance && ObjectDB::get_instance(p_instance->owner_id) != nullptr && p_instance->script->is_valid() && p_instance->script->path != "") err_file = p_instance->script->path; else if (script) err_file = script->path; if (err_file == "") err_file = "<built-in>"; String err_func = name; - if (p_instance && ObjectDB::instance_validate(p_instance->owner) && p_instance->script->is_valid() && p_instance->script->name != "") + if (p_instance && ObjectDB::get_instance(p_instance->owner_id) != nullptr && p_instance->script->is_valid() && p_instance->script->name != "") err_func = p_instance->script->name + "." + err_func; int err_line = line; if (err_text == "") { diff --git a/modules/gdscript/gdscript_function.h b/modules/gdscript/gdscript_function.h index ad95ebc543..7b7bcbaac9 100644 --- a/modules/gdscript/gdscript_function.h +++ b/modules/gdscript/gdscript_function.h @@ -77,8 +77,8 @@ struct GDScriptDataType { return false; } - Object *obj = p_variant.operator Object *(); - if (!obj || !ObjectDB::instance_validate(obj)) { + Object *obj = p_variant.get_validated_object(); + if (!obj) { return false; } @@ -100,8 +100,8 @@ struct GDScriptDataType { return false; } - Object *obj = p_variant.operator Object *(); - if (!obj || !ObjectDB::instance_validate(obj)) { + Object *obj = p_variant.get_validated_object(); + if (!obj) { return false; } diff --git a/modules/gdscript/gdscript_functions.cpp b/modules/gdscript/gdscript_functions.cpp index 1a5087eb4d..a46337d7dd 100644 --- a/modules/gdscript/gdscript_functions.cpp +++ b/modules/gdscript/gdscript_functions.cpp @@ -1441,8 +1441,8 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ if (p_args[0]->get_type() != Variant::OBJECT) { r_ret = false; } else { - Object *obj = *p_args[0]; - r_ret = ObjectDB::instance_validate(obj); + Object *obj = p_args[0]->get_validated_object(); + r_ret = obj != nullptr; } } break; diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp index 43cdd19411..c722076fe2 100644 --- a/modules/mono/csharp_script.cpp +++ b/modules/mono/csharp_script.cpp @@ -854,7 +854,7 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) { while (script->instances.front()) { Object *obj = script->instances.front()->get(); - obj->set_script(RefPtr()); // Remove script and existing script instances (placeholder are not removed before domain reload) + obj->set_script(REF()); // Remove script and existing script instances (placeholder are not removed before domain reload) } script->_clear(); @@ -877,7 +877,7 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) { // Use a placeholder for now to avoid losing the state when saving a scene - obj->set_script(scr.get_ref_ptr()); + obj->set_script(scr); PlaceHolderScriptInstance *placeholder = scr->placeholder_instance_create(obj); obj->set_script_instance(placeholder); @@ -1003,7 +1003,7 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) { CRASH_COND(si != NULL); #endif // Re-create script instance - obj->set_script(script.get_ref_ptr()); // will create the script instance as well + obj->set_script(script); // will create the script instance as well } } diff --git a/modules/mono/mono_gd/gd_mono_internals.cpp b/modules/mono/mono_gd/gd_mono_internals.cpp index 75aa77c7b0..74ffa90cb3 100644 --- a/modules/mono/mono_gd/gd_mono_internals.cpp +++ b/modules/mono/mono_gd/gd_mono_internals.cpp @@ -107,7 +107,7 @@ void tie_managed_to_unmanaged(MonoObject *managed, Object *unmanaged) { ScriptInstance *si = CSharpInstance::create_for_managed_type(unmanaged, script.ptr(), gchandle); - unmanaged->set_script_and_instance(script.get_ref_ptr(), si); + unmanaged->set_script_and_instance(script, si); } void unhandled_exception(MonoException *p_exc) { diff --git a/modules/visual_script/visual_script_editor.cpp b/modules/visual_script/visual_script_editor.cpp index 18851e6ab6..9a1125c375 100644 --- a/modules/visual_script/visual_script_editor.cpp +++ b/modules/visual_script/visual_script_editor.cpp @@ -4963,7 +4963,7 @@ Ref<VisualScriptNode> _VisualScriptEditor::create_node_custom(const String &p_na } _VisualScriptEditor *_VisualScriptEditor::singleton = NULL; -Map<String, RefPtr> _VisualScriptEditor::custom_nodes; +Map<String, REF> _VisualScriptEditor::custom_nodes; _VisualScriptEditor::_VisualScriptEditor() { singleton = this; @@ -4975,7 +4975,7 @@ _VisualScriptEditor::~_VisualScriptEditor() { void _VisualScriptEditor::add_custom_node(const String &p_name, const String &p_category, const Ref<Script> &p_script) { String node_name = "custom/" + p_category + "/" + p_name; - custom_nodes.insert(node_name, p_script.get_ref_ptr()); + custom_nodes.insert(node_name, p_script); VisualScriptLanguage::singleton->add_register_func(node_name, &_VisualScriptEditor::create_node_custom); emit_signal("custom_nodes_updated"); } diff --git a/modules/visual_script/visual_script_editor.h b/modules/visual_script/visual_script_editor.h index 40e9e1cc98..9f52d87b6a 100644 --- a/modules/visual_script/visual_script_editor.h +++ b/modules/visual_script/visual_script_editor.h @@ -341,7 +341,7 @@ protected: static void _bind_methods(); static _VisualScriptEditor *singleton; - static Map<String, RefPtr> custom_nodes; + static Map<String, REF> custom_nodes; static Ref<VisualScriptNode> create_node_custom(const String &p_name); public: diff --git a/scene/animation/animation_player.cpp b/scene/animation/animation_player.cpp index 740dad9a1a..ceee0529c2 100644 --- a/scene/animation/animation_player.cpp +++ b/scene/animation/animation_player.cpp @@ -106,7 +106,7 @@ bool AnimationPlayer::_get(const StringName &p_name, Variant &r_ret) const { } else if (name.begins_with("anims/")) { String which = name.get_slicec('/', 1); - r_ret = get_animation(which).get_ref_ptr(); + r_ret = get_animation(which); } else if (name.begins_with("next/")) { diff --git a/scene/animation/tween.cpp b/scene/animation/tween.cpp index 331a6c769c..a7f3794a05 100644 --- a/scene/animation/tween.cpp +++ b/scene/animation/tween.cpp @@ -1227,7 +1227,6 @@ bool Tween::_build_interpolation(InterpolateType p_interpolation_type, Object *p // Give it the object ERR_FAIL_COND_V_MSG(p_object == NULL, false, "Invalid object provided to Tween."); - ERR_FAIL_COND_V_MSG(!ObjectDB::instance_validate(p_object), false, "Invalid object provided to Tween."); data.id = p_object->get_instance_id(); // Validate the initial and final values @@ -1328,7 +1327,6 @@ bool Tween::interpolate_callback(Object *p_object, real_t p_duration, String p_c // Check that the target object is valid ERR_FAIL_COND_V(p_object == NULL, false); - ERR_FAIL_COND_V(!ObjectDB::instance_validate(p_object), false); // Duration cannot be negative ERR_FAIL_COND_V(p_duration < 0, false); @@ -1387,7 +1385,6 @@ bool Tween::interpolate_deferred_callback(Object *p_object, real_t p_duration, S // Check that the target object is valid ERR_FAIL_COND_V(p_object == NULL, false); - ERR_FAIL_COND_V(!ObjectDB::instance_validate(p_object), false); // No negative durations allowed ERR_FAIL_COND_V(p_duration < 0, false); @@ -1457,9 +1454,7 @@ bool Tween::follow_property(Object *p_object, NodePath p_property, Variant p_ini // Confirm the source and target objects are valid ERR_FAIL_COND_V(p_object == NULL, false); - ERR_FAIL_COND_V(!ObjectDB::instance_validate(p_object), false); ERR_FAIL_COND_V(p_target == NULL, false); - ERR_FAIL_COND_V(!ObjectDB::instance_validate(p_target), false); // No negative durations ERR_FAIL_COND_V(p_duration < 0, false); @@ -1521,9 +1516,7 @@ bool Tween::follow_method(Object *p_object, StringName p_method, Variant p_initi // Verify the source and target objects are valid ERR_FAIL_COND_V(p_object == NULL, false); - ERR_FAIL_COND_V(!ObjectDB::instance_validate(p_object), false); ERR_FAIL_COND_V(p_target == NULL, false); - ERR_FAIL_COND_V(!ObjectDB::instance_validate(p_target), false); // No negative durations ERR_FAIL_COND_V(p_duration < 0, false); @@ -1587,9 +1580,7 @@ bool Tween::targeting_property(Object *p_object, NodePath p_property, Object *p_ // Verify both objects are valid ERR_FAIL_COND_V(p_object == NULL, false); - ERR_FAIL_COND_V(!ObjectDB::instance_validate(p_object), false); ERR_FAIL_COND_V(p_initial == NULL, false); - ERR_FAIL_COND_V(!ObjectDB::instance_validate(p_initial), false); // No negative durations ERR_FAIL_COND_V(p_duration < 0, false); @@ -1655,9 +1646,7 @@ bool Tween::targeting_method(Object *p_object, StringName p_method, Object *p_in // Make sure the given objects are valid ERR_FAIL_COND_V(p_object == NULL, false); - ERR_FAIL_COND_V(!ObjectDB::instance_validate(p_object), false); ERR_FAIL_COND_V(p_initial == NULL, false); - ERR_FAIL_COND_V(!ObjectDB::instance_validate(p_initial), false); // No negative durations ERR_FAIL_COND_V(p_duration < 0, false); diff --git a/scene/debugger/script_debugger_remote.cpp b/scene/debugger/script_debugger_remote.cpp index 3608a11ed7..80972ba3d1 100644 --- a/scene/debugger/script_debugger_remote.cpp +++ b/scene/debugger/script_debugger_remote.cpp @@ -106,7 +106,7 @@ void ScriptDebuggerRemote::_put_variable(const String &p_name, const Variant &p_ packet_peer_stream->put_var(p_name); Variant var = p_variable; - if (p_variable.get_type() == Variant::OBJECT && !ObjectDB::instance_validate(p_variable)) { + if (p_variable.get_type() == Variant::OBJECT && p_variable.get_validated_object() == nullptr) { var = Variant(); } diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp index 0c686296b3..6d8be469bd 100644 --- a/scene/gui/rich_text_label.cpp +++ b/scene/gui/rich_text_label.cpp @@ -2664,7 +2664,7 @@ void RichTextLabel::set_effects(const Vector<Variant> &effects) { Vector<Variant> RichTextLabel::get_effects() { Vector<Variant> r; for (int i = 0; i < custom_effects.size(); i++) { - r.push_back(custom_effects[i].get_ref_ptr()); + r.push_back(custom_effects[i]); } return r; } diff --git a/scene/resources/font.cpp b/scene/resources/font.cpp index 663ae5d45d..872d6a043c 100644 --- a/scene/resources/font.cpp +++ b/scene/resources/font.cpp @@ -192,7 +192,7 @@ Vector<Variant> BitmapFont::_get_textures() const { Vector<Variant> rtextures; for (int i = 0; i < textures.size(); i++) - rtextures.push_back(textures[i].get_ref_ptr()); + rtextures.push_back(textures[i]); return rtextures; } diff --git a/scene/resources/resource_format_text.cpp b/scene/resources/resource_format_text.cpp index 9779f9c9ca..a5475776a7 100644 --- a/scene/resources/resource_format_text.cpp +++ b/scene/resources/resource_format_text.cpp @@ -1377,7 +1377,7 @@ void ResourceFormatSaverTextInstance::_find_resources(const Variant &p_variant, switch (p_variant.get_type()) { case Variant::OBJECT: { - RES res = p_variant.operator RefPtr(); + RES res = p_variant; if (res.is_null() || external_resources.has(res)) return; |