You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-04 12:00:25 +00:00
Optimize Object::cast_to by assuming no virtual and multiple inheritance, gaining 8x throughput over dynamic_cast.
Add `-Wvirtual-inheritance` to compiler warnings as a sanity check.
This commit is contained in:
@@ -860,7 +860,12 @@ else: # GCC, Clang
|
|||||||
common_warnings = []
|
common_warnings = []
|
||||||
|
|
||||||
if methods.using_gcc(env):
|
if methods.using_gcc(env):
|
||||||
common_warnings += ["-Wshadow", "-Wno-misleading-indentation"]
|
common_warnings += [
|
||||||
|
"-Wshadow",
|
||||||
|
"-Wno-misleading-indentation",
|
||||||
|
# For optimized Object::cast_to / object.inherits_from()
|
||||||
|
"-Wvirtual-inheritance",
|
||||||
|
]
|
||||||
if cc_version_major < 11:
|
if cc_version_major < 11:
|
||||||
# Regression in GCC 9/10, spams so much in our variadic templates
|
# Regression in GCC 9/10, spams so much in our variadic templates
|
||||||
# that we need to outright disable it.
|
# that we need to outright disable it.
|
||||||
|
|||||||
@@ -440,6 +440,9 @@ public:
|
|||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
protected: \
|
protected: \
|
||||||
|
virtual bool _derives_from(const std::type_info &p_type_info) const override { \
|
||||||
|
return typeid(m_class) == p_type_info || m_inherits::_derives_from(p_type_info); \
|
||||||
|
} \
|
||||||
_FORCE_INLINE_ static void (*_get_bind_methods())() { \
|
_FORCE_INLINE_ static void (*_get_bind_methods())() { \
|
||||||
return &m_class::_bind_methods; \
|
return &m_class::_bind_methods; \
|
||||||
} \
|
} \
|
||||||
@@ -768,6 +771,12 @@ protected:
|
|||||||
mutable VirtualMethodTracker *virtual_method_list = nullptr;
|
mutable VirtualMethodTracker *virtual_method_list = nullptr;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
virtual bool _derives_from(const std::type_info &p_type_info) const {
|
||||||
|
// This could just be false because nobody would reasonably ask if an Object subclass derives from Object,
|
||||||
|
// but it would be wrong if somebody actually does ask. It's not too slow to check anyway.
|
||||||
|
return typeid(Object) == p_type_info;
|
||||||
|
}
|
||||||
|
|
||||||
public: // Should be protected, but bug in clang++.
|
public: // Should be protected, but bug in clang++.
|
||||||
static void initialize_class();
|
static void initialize_class();
|
||||||
_FORCE_INLINE_ static void register_custom_data_to_otdb() {}
|
_FORCE_INLINE_ static void register_custom_data_to_otdb() {}
|
||||||
@@ -787,12 +796,26 @@ public:
|
|||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
static T *cast_to(Object *p_object) {
|
static T *cast_to(Object *p_object) {
|
||||||
return p_object ? dynamic_cast<T *>(p_object) : nullptr;
|
// This is like dynamic_cast, but faster.
|
||||||
|
// The reason is that we can assume no virtual and multiple inheritance.
|
||||||
|
static_assert(std::is_base_of_v<Object, T>, "T must be derived from Object");
|
||||||
|
if constexpr (std::is_same_v<std::decay_t<T>, typename T::self_type>) {
|
||||||
|
return p_object && p_object->_derives_from(typeid(T)) ? static_cast<T *>(p_object) : nullptr;
|
||||||
|
} else {
|
||||||
|
// T does not use GDCLASS, must fall back to dynamic_cast.
|
||||||
|
return p_object ? dynamic_cast<T *>(p_object) : nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
static const T *cast_to(const Object *p_object) {
|
static const T *cast_to(const Object *p_object) {
|
||||||
return p_object ? dynamic_cast<const T *>(p_object) : nullptr;
|
static_assert(std::is_base_of_v<Object, T>, "T must be derived from Object");
|
||||||
|
if constexpr (std::is_same_v<std::decay_t<T>, typename T::self_type>) {
|
||||||
|
return p_object && p_object->_derives_from(typeid(T)) ? static_cast<const T *>(p_object) : nullptr;
|
||||||
|
} else {
|
||||||
|
// T does not use GDCLASS, must fall back to dynamic_cast.
|
||||||
|
return p_object ? dynamic_cast<const T *>(p_object) : nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
|||||||
@@ -30,6 +30,8 @@
|
|||||||
|
|
||||||
#ifndef DISABLE_DEPRECATED
|
#ifndef DISABLE_DEPRECATED
|
||||||
|
|
||||||
|
#include "scene/gui/line_edit.h"
|
||||||
|
|
||||||
void AcceptDialog::_register_text_enter_bind_compat_89419(Control *p_line_edit) {
|
void AcceptDialog::_register_text_enter_bind_compat_89419(Control *p_line_edit) {
|
||||||
register_text_enter(Object::cast_to<LineEdit>(p_line_edit));
|
register_text_enter(Object::cast_to<LineEdit>(p_line_edit));
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user