1
0
mirror of https://github.com/godotengine/godot.git synced 2025-11-10 13:00:37 +00:00

Merge pull request #105099 from Ivorforce/object-classname-cache

Fix caching of objects' class name pointer in `Object` instances.
This commit is contained in:
Thaddeus Crews
2025-04-08 12:32:40 -05:00
2 changed files with 23 additions and 34 deletions

View File

@@ -249,9 +249,9 @@ void Object::cancel_free() {
} }
void Object::_initialize() { 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(); _initialize_classv();
_class_name_ptr = nullptr; // May have been called from a constructor.
} }
void Object::_postinitialize() { void Object::_postinitialize() {
@@ -1590,7 +1590,7 @@ void Object::initialize_class() {
if (initialized) { if (initialized) {
return; return;
} }
_add_class_to_classdb(get_class_static(), get_parent_class_static()); _add_class_to_classdb(get_class_static(), StringName());
_bind_methods(); _bind_methods();
_bind_compatibility_methods(); _bind_compatibility_methods();
initialized = true; initialized = true;
@@ -1969,6 +1969,20 @@ uint32_t Object::get_edited_version() const {
} }
#endif #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 { StringName Object::get_class_name_for_extension(const GDExtension *p_library) const {
#ifdef TOOLS_ENABLED #ifdef TOOLS_ENABLED
// If this is the library this extension comes from and it's a placeholder, we // If this is the library this extension comes from and it's a placeholder, we

View File

@@ -398,7 +398,8 @@ struct ObjectGDExtension {
// so that they can support the `Object::cast_to()` method. // so that they can support the `Object::cast_to()` method.
#define GDSOFTCLASS(m_class, m_inherits) \ #define GDSOFTCLASS(m_class, m_inherits) \
public: \ 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 _FORCE_INLINE_ void *get_class_ptr_static() { \
static int ptr; \ static int ptr; \
return &ptr; \ return &ptr; \
@@ -417,12 +418,6 @@ private:
\ \
public: \ public: \
static constexpr bool _class_is_enabled = !bool(GD_IS_DEFINED(ClassDB_Disable_##m_class)) && m_inherits::_class_is_enabled; \ 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 { \ virtual const StringName *_get_class_namev() const override { \
static StringName _class_name_static; \ static StringName _class_name_static; \
if (unlikely(!_class_name_static)) { \ if (unlikely(!_class_name_static)) { \
@@ -433,9 +428,6 @@ public:
static _FORCE_INLINE_ String get_class_static() { \ static _FORCE_INLINE_ String get_class_static() { \
return String(#m_class); \ 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 { \ virtual bool is_class(const String &p_class) const override { \
if (_get_extension() && _get_extension()->is_class(p_class)) { \ if (_get_extension() && _get_extension()->is_class(p_class)) { \
return true; \ return true; \
@@ -458,7 +450,7 @@ public:
return; \ return; \
} \ } \
m_inherits::initialize_class(); \ 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()) { \ if (m_class::_get_bind_methods() != m_inherits::_get_bind_methods()) { \
_bind_methods(); \ _bind_methods(); \
} \ } \
@@ -821,14 +813,9 @@ public:
/* TYPE API */ /* TYPE API */
static String get_class_static() { return "Object"; } static String get_class_static() { return "Object"; }
static String get_parent_class_static() { return String(); }
virtual String get_class() const { _FORCE_INLINE_ String get_class() const { return get_class_name(); }
if (_extension) {
return _extension->class_name.operator String();
}
return "Object";
}
virtual String get_save_class() const { return get_class(); } //class stored when saving virtual String get_save_class() const { return get_class(); } //class stored when saving
virtual bool is_class(const String &p_class) const { 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; } virtual bool is_class_ptr(void *p_ptr) const { return get_class_ptr_static() == p_ptr; }
_FORCE_INLINE_ const StringName &get_class_name() const { 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;
}
StringName get_class_name_for_extension(const GDExtension *p_library) const; StringName get_class_name_for_extension(const GDExtension *p_library) const;