Skip to content

Provide quick access to Object ancestry #107868

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion core/io/resource.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -752,7 +752,9 @@ void Resource::_bind_methods() {
}

Resource::Resource() :
remapped_list(this) {}
remapped_list(this) {
_define_ancestry(AncestralClass::RESOURCE);
}

Resource::~Resource() {
if (unlikely(path_cache.is_empty())) {
Expand Down
13 changes: 12 additions & 1 deletion core/object/object.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2204,9 +2204,20 @@ void Object::reset_internal_extension(ObjectGDExtension *p_extension) {
#endif

void Object::_construct_object(bool p_reference) {
type_is_reference = p_reference;
_block_signals = false;
_can_translate = true;
_emitting = false;

// ObjectDB::add_instance relies on AncestralClass::REF_COUNTED
// being already set in the case of references.
Comment on lines +2211 to +2212
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This has always irked me. I'm very unconvinced an Object should add itself to the DB before it's even done self-constructing. But it's not for this PR to fix.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Absolutely, I thought the same thing. There's also the possibility that other things haven't finished setting up before this call.

_ancestry = p_reference ? (uint32_t)AncestralClass::REF_COUNTED : 0;

_instance_id = ObjectDB::add_instance(this);

#ifdef TOOLS_ENABLED
_edited = false;
#endif

#ifdef DEBUG_ENABLED
_lock_index.init(1);
#endif
Expand Down
40 changes: 34 additions & 6 deletions core/object/object.h
Original file line number Diff line number Diff line change
Expand Up @@ -587,6 +587,29 @@ class Object {
CONNECT_INHERITED = 32, // Used in editor builds.
};

// Store on each object a bitfield to quickly test whether it is derived from some "key" classes
// that are commonly tested in performance sensitive code.
// Ensure unsigned to bitpack.
enum class AncestralClass : unsigned int {
REF_COUNTED = 1 << 0,
NODE = 1 << 1,
RESOURCE = 1 << 2,
SCRIPT = 1 << 3,

CANVAS_ITEM = 1 << 4,
CONTROL = 1 << 5,
NODE_2D = 1 << 6,
COLLISION_OBJECT_2D = 1 << 7,
AREA_2D = 1 << 8,

NODE_3D = 1 << 9,
VISUAL_INSTANCE_3D = 1 << 10,
GEOMETRY_INSTANCE_3D = 1 << 11,
COLLISION_OBJECT_3D = 1 << 12,
PHYSICS_BODY_3D = 1 << 13,
MESH_INSTANCE_3D = 1 << 14,
};

struct Connection {
::Signal signal;
Callable callable;
Expand Down Expand Up @@ -628,16 +651,19 @@ class Object {
#ifdef DEBUG_ENABLED
SafeRefCount _lock_index;
#endif // DEBUG_ENABLED
bool _block_signals = false;
int _predelete_ok = 0;
ObjectID _instance_id;
bool _predelete();
void _initialize();
void _postinitialize();
bool _can_translate = true;
bool _emitting = false;

uint32_t _ancestry : 15;

bool _block_signals : 1;
bool _can_translate : 1;
bool _emitting : 1;
#ifdef TOOLS_ENABLED
bool _edited = false;
bool _edited : 1;
uint32_t _edited_version = 0;
HashSet<String> editor_section_folding;
#endif
Expand All @@ -663,7 +689,6 @@ class Object {
_FORCE_INLINE_ void _construct_object(bool p_reference);

friend class RefCounted;
bool type_is_reference = false;

BinaryMutex _instance_binding_mutex;
struct InstanceBinding {
Expand Down Expand Up @@ -769,6 +794,7 @@ class Object {
static void _get_property_list_from_classdb(const StringName &p_class, List<PropertyInfo> *p_list, bool p_no_inheritance, const Object *p_validator);

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; }

virtual bool _uses_signal_mutex() const;

Expand Down Expand Up @@ -845,6 +871,8 @@ class Object {
}
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; }

const StringName &get_class_name() const;

StringName get_class_name_for_extension(const GDExtension *p_library) const;
Expand Down Expand Up @@ -1003,7 +1031,7 @@ class Object {

void clear_internal_resource_paths();

_ALWAYS_INLINE_ bool is_ref_counted() const { return type_is_reference; }
_ALWAYS_INLINE_ bool is_ref_counted() const { return has_ancestry(AncestralClass::REF_COUNTED); }

void cancel_free();

Expand Down
1 change: 1 addition & 0 deletions core/object/ref_counted.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ bool RefCounted::unreference() {

RefCounted::RefCounted() :
Object(true) {
_define_ancestry(AncestralClass::REF_COUNTED);
refcount.init();
refcount_init.init();
}
Expand Down
4 changes: 3 additions & 1 deletion core/object/script_language.h
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,9 @@ class Script : public Resource {

virtual const Variant get_rpc_config() const = 0;

Script() {}
Script() {
_define_ancestry(AncestralClass::SCRIPT);
}
};

class ScriptLanguage : public Object {
Expand Down
4 changes: 4 additions & 0 deletions scene/2d/node_2d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -510,3 +510,7 @@ void Node2D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "global_skew", PROPERTY_HINT_NONE, "radians_as_degrees", PROPERTY_USAGE_NONE), "set_global_skew", "get_global_skew");
ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM2D, "global_transform", PROPERTY_HINT_NONE, "suffix:px", PROPERTY_USAGE_NONE), "set_global_transform", "get_global_transform");
}

Node2D::Node2D() {
_define_ancestry(AncestralClass::NODE_2D);
}
2 changes: 2 additions & 0 deletions scene/2d/node_2d.h
Original file line number Diff line number Diff line change
Expand Up @@ -115,4 +115,6 @@ class Node2D : public CanvasItem {
Transform2D get_relative_transform_to_parent(const Node *p_parent) const;

Transform2D get_transform() const override;

Node2D();
};
2 changes: 2 additions & 0 deletions scene/2d/physics/area_2d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -678,6 +678,8 @@ void Area2D::_bind_methods() {

Area2D::Area2D() :
CollisionObject2D(PhysicsServer2D::get_singleton()->area_create(), true) {
_define_ancestry(AncestralClass::AREA_2D);

set_gravity(980);
set_gravity_direction(Vector2(0, 1));
set_monitoring(true);
Expand Down
3 changes: 3 additions & 0 deletions scene/2d/physics/collision_object_2d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -655,6 +655,8 @@ void CollisionObject2D::_bind_methods() {
}

CollisionObject2D::CollisionObject2D(RID p_rid, bool p_area) {
_define_ancestry(AncestralClass::COLLISION_OBJECT_2D);

rid = p_rid;
area = p_area;
pickable = true;
Expand All @@ -672,6 +674,7 @@ CollisionObject2D::CollisionObject2D(RID p_rid, bool p_area) {
}

CollisionObject2D::CollisionObject2D() {
_define_ancestry(AncestralClass::COLLISION_OBJECT_2D);
//owner=

set_notify_transform(true);
Expand Down
1 change: 1 addition & 0 deletions scene/3d/mesh_instance_3d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -925,6 +925,7 @@ void MeshInstance3D::_bind_methods() {
}

MeshInstance3D::MeshInstance3D() {
_define_ancestry(AncestralClass::MESH_INSTANCE_3D);
}

MeshInstance3D::~MeshInstance3D() {
Expand Down
2 changes: 2 additions & 0 deletions scene/3d/node_3d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1529,6 +1529,8 @@ void Node3D::_bind_methods() {

Node3D::Node3D() :
xform_change(this), _client_physics_interpolation_node_3d_list(this) {
_define_ancestry(AncestralClass::NODE_3D);

// Default member initializer for bitfield is a C++20 extension, so:

data.top_level = false;
Expand Down
4 changes: 4 additions & 0 deletions scene/3d/physics/collision_object_3d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -746,13 +746,17 @@ PackedStringArray CollisionObject3D::get_configuration_warnings() const {
}

CollisionObject3D::CollisionObject3D() {
_define_ancestry(AncestralClass::COLLISION_OBJECT_3D);

set_notify_transform(true);
//owner=

//set_transform_notify(true);
}

CollisionObject3D::~CollisionObject3D() {
_define_ancestry(AncestralClass::COLLISION_OBJECT_3D);

ERR_FAIL_NULL(PhysicsServer3D::get_singleton());
PhysicsServer3D::get_singleton()->free(rid);
}
4 changes: 4 additions & 0 deletions scene/3d/physics/physics_body_3d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,10 @@ PackedStringArray PhysicsBody3D::get_configuration_warnings() const {
return warnings;
}

PhysicsBody3D::PhysicsBody3D() {
_define_ancestry(AncestralClass::PHYSICS_BODY_3D);
}

///////////////////////////////////////

//so, if you pass 45 as limit, avoid numerical precision errors when angle is 45.
Expand Down
2 changes: 2 additions & 0 deletions scene/3d/physics/physics_body_3d.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,4 +65,6 @@ class PhysicsBody3D : public CollisionObject3D {
TypedArray<PhysicsBody3D> get_collision_exceptions();
void add_collision_exception_with(Node *p_node); //must be physicsbody
void remove_collision_exception_with(Node *p_node);

PhysicsBody3D();
};
3 changes: 3 additions & 0 deletions scene/3d/visual_instance_3d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,8 @@ RID VisualInstance3D::get_base() const {
}

VisualInstance3D::VisualInstance3D() {
_define_ancestry(AncestralClass::VISUAL_INSTANCE_3D);

instance = RenderingServer::get_singleton()->instance_create();
RenderingServer::get_singleton()->instance_attach_object_instance_id(instance, get_instance_id());
_set_notify_transform_when_fti_off(true);
Expand Down Expand Up @@ -645,6 +647,7 @@ void GeometryInstance3D::_bind_methods() {
}

GeometryInstance3D::GeometryInstance3D() {
_define_ancestry(AncestralClass::GEOMETRY_INSTANCE_3D);
}

GeometryInstance3D::~GeometryInstance3D() {
Expand Down
2 changes: 2 additions & 0 deletions scene/gui/control.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4399,6 +4399,8 @@ void Control::_bind_methods() {
}

Control::Control() {
_define_ancestry(AncestralClass::CONTROL);

data.theme_owner = memnew(ThemeOwner(this));

set_physics_interpolation_mode(Node::PHYSICS_INTERPOLATION_MODE_OFF);
Expand Down
2 changes: 2 additions & 0 deletions scene/main/canvas_item.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1727,6 +1727,8 @@ CanvasItem::TextureRepeat CanvasItem::get_texture_repeat_in_tree() const {

CanvasItem::CanvasItem() :
xform_change(this) {
_define_ancestry(AncestralClass::CANVAS_ITEM);

canvas_item = RenderingServer::get_singleton()->canvas_item_create();
}

Expand Down
2 changes: 2 additions & 0 deletions scene/main/node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4031,6 +4031,8 @@ String Node::_get_name_num_separator() {
}

Node::Node() {
_define_ancestry(AncestralClass::NODE);

orphan_node_count++;

// Default member initializer for bitfield is a C++20 extension, so:
Expand Down