Use AncestralClass to speed up Object::cast_to when possible.
This commit is contained in:
@ -54,6 +54,8 @@ class Resource : public RefCounted {
|
||||
GDCLASS(Resource, RefCounted);
|
||||
|
||||
public:
|
||||
static constexpr AncestralClass static_ancestral_class = AncestralClass::RESOURCE;
|
||||
|
||||
static void register_custom_data_to_otdb() { ClassDB::add_resource_base_extension("res", get_class_static()); }
|
||||
virtual String get_base_extension() const { return "res"; }
|
||||
|
||||
|
||||
@ -605,6 +605,8 @@ public:
|
||||
MESH_INSTANCE_3D = 1 << 14,
|
||||
};
|
||||
|
||||
static constexpr AncestralClass static_ancestral_class = (AncestralClass)0;
|
||||
|
||||
struct Connection {
|
||||
::Signal signal;
|
||||
Callable callable;
|
||||
@ -790,6 +792,8 @@ protected:
|
||||
|
||||
bool _disconnect(const StringName &p_signal, const Callable &p_callable, bool p_force = false);
|
||||
void _define_ancestry(AncestralClass p_class) { _ancestry |= (uint32_t)p_class; }
|
||||
// Prefer using derives_from.
|
||||
bool _has_ancestry(AncestralClass p_class) const { return _ancestry & (uint32_t)p_class; }
|
||||
|
||||
virtual bool _uses_signal_mutex() const;
|
||||
|
||||
@ -821,16 +825,12 @@ public:
|
||||
static T *cast_to(Object *p_object) {
|
||||
// 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");
|
||||
static_assert(std::is_same_v<std::decay_t<T>, typename T::self_type>, "T must use GDCLASS or GDSOFTCLASS");
|
||||
return p_object && p_object->is_class_ptr(T::get_class_ptr_static()) ? static_cast<T *>(p_object) : nullptr;
|
||||
return p_object && p_object->derives_from<T>() ? static_cast<T *>(p_object) : nullptr;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static const T *cast_to(const Object *p_object) {
|
||||
static_assert(std::is_base_of_v<Object, T>, "T must be derived from Object");
|
||||
static_assert(std::is_same_v<std::decay_t<T>, typename T::self_type>, "T must use GDCLASS or GDSOFTCLASS");
|
||||
return p_object && p_object->is_class_ptr(T::get_class_ptr_static()) ? static_cast<const T *>(p_object) : nullptr;
|
||||
return p_object && p_object->derives_from<T>() ? static_cast<const T *>(p_object) : nullptr;
|
||||
}
|
||||
|
||||
enum {
|
||||
@ -864,7 +864,8 @@ public:
|
||||
}
|
||||
virtual bool is_class_ptr(void *p_ptr) const { return get_class_ptr_static() == p_ptr; }
|
||||
|
||||
bool has_ancestry(AncestralClass p_class) const { return _ancestry & (uint32_t)p_class; }
|
||||
template <typename T>
|
||||
bool derives_from() const;
|
||||
|
||||
const StringName &get_class_name() const;
|
||||
|
||||
@ -1024,7 +1025,7 @@ public:
|
||||
|
||||
void clear_internal_resource_paths();
|
||||
|
||||
_ALWAYS_INLINE_ bool is_ref_counted() const { return has_ancestry(AncestralClass::REF_COUNTED); }
|
||||
_ALWAYS_INLINE_ bool is_ref_counted() const { return _has_ancestry(AncestralClass::REF_COUNTED); }
|
||||
|
||||
void cancel_free();
|
||||
|
||||
@ -1035,6 +1036,29 @@ public:
|
||||
bool predelete_handler(Object *p_object);
|
||||
void postinitialize_handler(Object *p_object);
|
||||
|
||||
template <typename T>
|
||||
bool Object::derives_from() const {
|
||||
static_assert(std::is_base_of_v<Object, T>, "T must be derived from Object.");
|
||||
static_assert(std::is_same_v<std::decay_t<T>, typename T::self_type>, "T must use GDCLASS or GDSOFTCLASS.");
|
||||
|
||||
// If there is an explicitly set ancestral class on the type, we can use that.
|
||||
if constexpr (T::static_ancestral_class != T::super_type::static_ancestral_class) {
|
||||
return _has_ancestry(T::static_ancestral_class);
|
||||
} else {
|
||||
return is_class_ptr(T::get_class_ptr_static());
|
||||
}
|
||||
}
|
||||
|
||||
template <>
|
||||
inline bool Object::derives_from<Object>() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline bool Object::derives_from<const Object>() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
class ObjectDB {
|
||||
// This needs to add up to 63, 1 bit is for reference.
|
||||
#define OBJECTDB_VALIDATOR_BITS 39
|
||||
|
||||
@ -42,6 +42,8 @@ protected:
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
static constexpr AncestralClass static_ancestral_class = AncestralClass::REF_COUNTED;
|
||||
|
||||
_FORCE_INLINE_ bool is_referenced() const { return refcount_init.get() != 1; }
|
||||
bool init_ref();
|
||||
bool reference(); // returns false if refcount is at zero and didn't get increased
|
||||
|
||||
@ -140,6 +140,8 @@ protected:
|
||||
}
|
||||
|
||||
public:
|
||||
static constexpr AncestralClass static_ancestral_class = AncestralClass::SCRIPT;
|
||||
|
||||
virtual void reload_from_file() override;
|
||||
|
||||
virtual bool can_instantiate() const = 0;
|
||||
|
||||
@ -55,6 +55,8 @@ protected:
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
static constexpr AncestralClass static_ancestral_class = AncestralClass::NODE_2D;
|
||||
|
||||
#ifdef TOOLS_ENABLED
|
||||
virtual Dictionary _edit_get_state() const override;
|
||||
virtual void _edit_set_state(const Dictionary &p_state) override;
|
||||
|
||||
@ -37,6 +37,8 @@ class Area2D : public CollisionObject2D {
|
||||
GDCLASS(Area2D, CollisionObject2D);
|
||||
|
||||
public:
|
||||
static constexpr AncestralClass static_ancestral_class = AncestralClass::AREA_2D;
|
||||
|
||||
enum SpaceOverride {
|
||||
SPACE_OVERRIDE_DISABLED,
|
||||
SPACE_OVERRIDE_COMBINE,
|
||||
|
||||
@ -39,6 +39,8 @@ class CollisionObject2D : public Node2D {
|
||||
GDCLASS(CollisionObject2D, Node2D);
|
||||
|
||||
public:
|
||||
static constexpr AncestralClass static_ancestral_class = AncestralClass::COLLISION_OBJECT_2D;
|
||||
|
||||
enum DisableMode {
|
||||
DISABLE_MODE_REMOVE,
|
||||
DISABLE_MODE_MAKE_STATIC,
|
||||
|
||||
@ -70,6 +70,8 @@ protected:
|
||||
bool _property_get_revert(const StringName &p_name, Variant &r_property) const;
|
||||
|
||||
public:
|
||||
static constexpr AncestralClass static_ancestral_class = AncestralClass::MESH_INSTANCE_3D;
|
||||
|
||||
void set_mesh(const Ref<Mesh> &p_mesh);
|
||||
Ref<Mesh> get_mesh() const;
|
||||
|
||||
|
||||
@ -54,6 +54,8 @@ class Node3D : public Node {
|
||||
friend class SceneTreeFTITests;
|
||||
|
||||
public:
|
||||
static constexpr AncestralClass static_ancestral_class = AncestralClass::NODE_3D;
|
||||
|
||||
// Edit mode for the rotation.
|
||||
// THIS MODE ONLY AFFECTS HOW DATA IS EDITED AND SAVED
|
||||
// IT DOES _NOT_ AFFECT THE TRANSFORM LOGIC (see comment in TransformDirty).
|
||||
|
||||
@ -37,6 +37,8 @@ class CollisionObject3D : public Node3D {
|
||||
GDCLASS(CollisionObject3D, Node3D);
|
||||
|
||||
public:
|
||||
static constexpr AncestralClass static_ancestral_class = AncestralClass::COLLISION_OBJECT_3D;
|
||||
|
||||
enum DisableMode {
|
||||
DISABLE_MODE_REMOVE,
|
||||
DISABLE_MODE_MAKE_STATIC,
|
||||
|
||||
@ -49,6 +49,8 @@ protected:
|
||||
Ref<KinematicCollision3D> _move(const Vector3 &p_motion, bool p_test_only = false, real_t p_margin = 0.001, bool p_recovery_as_collision = false, int p_max_collisions = 1);
|
||||
|
||||
public:
|
||||
static constexpr AncestralClass static_ancestral_class = AncestralClass::PHYSICS_BODY_3D;
|
||||
|
||||
PackedStringArray get_configuration_warnings() const override;
|
||||
|
||||
bool move_and_collide(const PhysicsServer3D::MotionParameters &p_parameters, PhysicsServer3D::MotionResult &r_result, bool p_test_only = false, bool p_cancel_sliding = true);
|
||||
|
||||
@ -53,6 +53,8 @@ protected:
|
||||
|
||||
GDVIRTUAL0RC(AABB, _get_aabb)
|
||||
public:
|
||||
static constexpr AncestralClass static_ancestral_class = AncestralClass::VISUAL_INSTANCE_3D;
|
||||
|
||||
enum GetFacesFlags {
|
||||
FACES_SOLID = 1, // solid geometry
|
||||
FACES_ENCLOSING = 2,
|
||||
@ -86,6 +88,8 @@ class GeometryInstance3D : public VisualInstance3D {
|
||||
GDCLASS(GeometryInstance3D, VisualInstance3D);
|
||||
|
||||
public:
|
||||
static constexpr AncestralClass static_ancestral_class = AncestralClass::GEOMETRY_INSTANCE_3D;
|
||||
|
||||
enum ShadowCastingSetting {
|
||||
SHADOW_CASTING_SETTING_OFF = RS::SHADOW_CASTING_SETTING_OFF,
|
||||
SHADOW_CASTING_SETTING_ON = RS::SHADOW_CASTING_SETTING_ON,
|
||||
|
||||
@ -50,6 +50,8 @@ class Control : public CanvasItem {
|
||||
#endif //TOOLS_ENABLED
|
||||
|
||||
public:
|
||||
static constexpr AncestralClass static_ancestral_class = AncestralClass::CONTROL;
|
||||
|
||||
enum Anchor {
|
||||
ANCHOR_BEGIN = 0,
|
||||
ANCHOR_END = 1
|
||||
|
||||
@ -45,6 +45,8 @@ class CanvasItem : public Node {
|
||||
friend class CanvasLayer;
|
||||
|
||||
public:
|
||||
static constexpr AncestralClass static_ancestral_class = AncestralClass::CANVAS_ITEM;
|
||||
|
||||
enum TextureFilter {
|
||||
TEXTURE_FILTER_PARENT_NODE,
|
||||
TEXTURE_FILTER_NEAREST,
|
||||
|
||||
@ -67,6 +67,8 @@ protected:
|
||||
};
|
||||
|
||||
public:
|
||||
static constexpr AncestralClass static_ancestral_class = AncestralClass::NODE;
|
||||
|
||||
// N.B. Any enum stored as a bitfield should be specified as UNSIGNED to work around
|
||||
// some compilers trying to store it as signed, and requiring 1 more bit than necessary.
|
||||
enum ProcessMode : unsigned int {
|
||||
|
||||
Reference in New Issue
Block a user