From e7f087b91a28645b3dee873dd0aef70ca5a393a1 Mon Sep 17 00:00:00 2001 From: Lukas Tenbrink Date: Sun, 6 Apr 2025 16:53:57 +0200 Subject: [PATCH] Fix caching of objects' class name pointer in `Object` instances. Use `get_class_name` for `get_class` calls. Merge `get_parent_class_static` into `get_class_static`. --- core/object/object.cpp | 20 +++++++++++++++++--- core/object/object.h | 37 ++++++------------------------------- 2 files changed, 23 insertions(+), 34 deletions(-) diff --git a/core/object/object.cpp b/core/object/object.cpp index 317b062ebe4..1617342886d 100644 --- a/core/object/object.cpp +++ b/core/object/object.cpp @@ -249,9 +249,9 @@ void Object::cancel_free() { } void Object::_initialize() { - _class_name_ptr = _get_class_namev(); // Set the direct pointer, which is much faster to obtain, but can only happen after _initialize. + // Cache the class name in the object for quick reference. + _class_name_ptr = _get_class_namev(); _initialize_classv(); - _class_name_ptr = nullptr; // May have been called from a constructor. } void Object::_postinitialize() { @@ -1590,7 +1590,7 @@ void Object::initialize_class() { if (initialized) { return; } - _add_class_to_classdb(get_class_static(), get_parent_class_static()); + _add_class_to_classdb(get_class_static(), StringName()); _bind_methods(); _bind_compatibility_methods(); initialized = true; @@ -1969,6 +1969,20 @@ uint32_t Object::get_edited_version() const { } #endif +const StringName &Object::get_class_name() const { + if (_extension) { + // Can't put inside the unlikely as constructor can run it. + return _extension->class_name; + } + + if (unlikely(!_class_name_ptr)) { + // While class is initializing / deinitializing, constructors and destructors + // need access to the proper class at the proper stage. + return *_get_class_namev(); + } + return *_class_name_ptr; +} + StringName Object::get_class_name_for_extension(const GDExtension *p_library) const { #ifdef TOOLS_ENABLED // If this is the library this extension comes from and it's a placeholder, we diff --git a/core/object/object.h b/core/object/object.h index 9e7616b7c3d..55c0e06d25e 100644 --- a/core/object/object.h +++ b/core/object/object.h @@ -398,7 +398,8 @@ struct ObjectGDExtension { // so that they can support the `Object::cast_to()` method. #define GDSOFTCLASS(m_class, m_inherits) \ public: \ - typedef m_class self_type; \ + using self_type = m_class; \ + using super_type = m_inherits; \ static _FORCE_INLINE_ void *get_class_ptr_static() { \ static int ptr; \ return &ptr; \ @@ -417,12 +418,6 @@ private: \ public: \ static constexpr bool _class_is_enabled = !bool(GD_IS_DEFINED(ClassDB_Disable_##m_class)) && m_inherits::_class_is_enabled; \ - virtual String get_class() const override { \ - if (_get_extension()) { \ - return _get_extension()->class_name.operator String(); \ - } \ - return String(#m_class); \ - } \ virtual const StringName *_get_class_namev() const override { \ static StringName _class_name_static; \ if (unlikely(!_class_name_static)) { \ @@ -433,9 +428,6 @@ public: static _FORCE_INLINE_ String get_class_static() { \ return String(#m_class); \ } \ - static _FORCE_INLINE_ String get_parent_class_static() { \ - return m_inherits::get_class_static(); \ - } \ virtual bool is_class(const String &p_class) const override { \ if (_get_extension() && _get_extension()->is_class(p_class)) { \ return true; \ @@ -458,7 +450,7 @@ public: return; \ } \ m_inherits::initialize_class(); \ - _add_class_to_classdb(get_class_static(), get_parent_class_static()); \ + _add_class_to_classdb(get_class_static(), super_type::get_class_static()); \ if (m_class::_get_bind_methods() != m_inherits::_get_bind_methods()) { \ _bind_methods(); \ } \ @@ -821,14 +813,9 @@ public: /* TYPE API */ static String get_class_static() { return "Object"; } - static String get_parent_class_static() { return String(); } - virtual String get_class() const { - if (_extension) { - return _extension->class_name.operator String(); - } - return "Object"; - } + _FORCE_INLINE_ String get_class() const { return get_class_name(); } + virtual String get_save_class() const { return get_class(); } //class stored when saving virtual bool is_class(const String &p_class) const { @@ -839,19 +826,7 @@ public: } virtual bool is_class_ptr(void *p_ptr) const { return get_class_ptr_static() == p_ptr; } - _FORCE_INLINE_ const StringName &get_class_name() const { - if (_extension) { - // Can't put inside the unlikely as constructor can run it - return _extension->class_name; - } - - if (unlikely(!_class_name_ptr)) { - // While class is initializing / deinitializing, constructors and destructurs - // need access to the proper class at the proper stage. - return *_get_class_namev(); - } - return *_class_name_ptr; - } + const StringName &get_class_name() const; StringName get_class_name_for_extension(const GDExtension *p_library) const;