Skip to content

Commit d3a31a8

Browse files
committed
Provide quick access to Object ancestry
1 parent 6c3f393 commit d3a31a8

File tree

7 files changed

+34
-9
lines changed

7 files changed

+34
-9
lines changed

core/object.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1937,6 +1937,7 @@ Object::Object() {
19371937
_can_translate = true;
19381938
_is_queued_for_deletion = false;
19391939
_emitting = false;
1940+
_ancestry = 0;
19401941
memset(_script_instance_bindings, 0, sizeof(void *) * MAX_SCRIPT_INSTANCE_BINDINGS);
19411942
script_instance = nullptr;
19421943
_rc.store(nullptr, std::memory_order_release);

core/object.h

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -428,6 +428,16 @@ class Object {
428428
CONNECT_REFERENCE_COUNTED = 8,
429429
};
430430

431+
// Store on each object a bitfield to quickly test whether it is derived from some "key" classes
432+
// that are commonly tested in performance sensitive code.
433+
// Ensure unsigned to bitpack.
434+
enum class AncestralClass : unsigned int {
435+
REFERENCE = 1 << 0,
436+
SPATIAL = 1 << 1,
437+
CANVAS_ITEM = 1 << 2,
438+
VISUAL_INSTANCE = 1 << 3
439+
};
440+
431441
struct Connection {
432442
Object *source;
433443
StringName signal;
@@ -491,20 +501,24 @@ class Object {
491501
#ifdef DEBUG_ENABLED
492502
SafeRefCount _lock_index;
493503
#endif
494-
bool _block_signals;
495504
int _predelete_ok;
496505
Set<Object *> change_receptors;
497506
ObjectID _instance_id;
498507
std::atomic<ObjectRC *> _rc;
499-
bool _predelete();
500-
void _postinitialize();
501-
bool _can_translate;
502-
bool _emitting;
508+
509+
uint32_t _ancestry : 4;
510+
bool _block_signals : 1;
511+
bool _can_translate : 1;
512+
bool _emitting : 1;
503513
#ifdef TOOLS_ENABLED
504-
bool _edited;
514+
bool _edited : 1;
505515
uint32_t _edited_version;
506516
Set<String> editor_section_folding;
507517
#endif
518+
519+
bool _predelete();
520+
void _postinitialize();
521+
508522
ScriptInstance *script_instance;
509523
RefPtr script;
510524
Dictionary metadata;
@@ -586,6 +600,7 @@ class Object {
586600
virtual void _validate_property(PropertyInfo &property) const;
587601

588602
void _disconnect(const StringName &p_signal, Object *p_to_object, const StringName &p_to_method, bool p_force = false);
603+
void _define_ancestry(AncestralClass p_class) { _ancestry |= (uint32_t)p_class; }
589604

590605
public: //should be protected, but bug in clang++
591606
static void initialize_class();
@@ -660,6 +675,8 @@ class Object {
660675
virtual bool is_class(const String &p_class) const { return (p_class == "Object"); }
661676
virtual bool is_class_ptr(void *p_ptr) const { return get_class_ptr_static() == p_ptr; }
662677

678+
bool has_ancestry(AncestralClass p_class) const { return _ancestry & (uint32_t)p_class; }
679+
663680
_FORCE_INLINE_ const StringName &get_class_name() const {
664681
if (!_class_ptr) {
665682
return *_get_class_namev();

core/reference.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ bool Reference::unreference() {
9797
}
9898

9999
Reference::Reference() {
100+
_define_ancestry(AncestralClass::REFERENCE);
100101
refcount.init();
101102
refcount_init.init();
102103
}

core/variant.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2160,9 +2160,9 @@ Variant::Variant(const Object *p_object) {
21602160
Object *obj = const_cast<Object *>(p_object);
21612161

21622162
memnew_placement(_data._mem, ObjData);
2163-
Reference *ref = Object::cast_to<Reference>(obj);
2164-
if (unlikely(ref)) {
2165-
*reinterpret_cast<Ref<Reference> *>(_get_obj().ref.get_data()) = Ref<Reference>(ref);
2163+
2164+
if (obj && obj->has_ancestry(Object::AncestralClass::REFERENCE)) {
2165+
*reinterpret_cast<Ref<Reference> *>(_get_obj().ref.get_data()) = Ref<Reference>((Reference *)obj);
21662166
_get_obj().rc = nullptr;
21672167
} else {
21682168
_get_obj().rc = likely(obj) ? obj->_use_rc() : nullptr;

scene/2d/canvas_item.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1346,6 +1346,8 @@ int CanvasItem::get_canvas_layer() const {
13461346

13471347
CanvasItem::CanvasItem() :
13481348
xform_change(this) {
1349+
_define_ancestry(AncestralClass::CANVAS_ITEM);
1350+
13491351
canvas_item = RID_PRIME(VisualServer::get_singleton()->canvas_item_create());
13501352
visible = true;
13511353
pending_update = false;

scene/3d/spatial.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1248,6 +1248,8 @@ void Spatial::_bind_methods() {
12481248

12491249
Spatial::Spatial() :
12501250
xform_change(this), _client_physics_interpolation_spatials_list(this) {
1251+
_define_ancestry(AncestralClass::SPATIAL);
1252+
12511253
data.dirty = DIRTY_NONE;
12521254
data.children_lock = 0;
12531255

scene/3d/visual_instance.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,8 @@ RID VisualInstance::get_base() const {
208208
}
209209

210210
VisualInstance::VisualInstance() {
211+
_define_ancestry(AncestralClass::VISUAL_INSTANCE);
212+
211213
instance = RID_PRIME(VisualServer::get_singleton()->instance_create());
212214
VisualServer::get_singleton()->instance_attach_object_instance_id(instance, get_instance_id());
213215
layers = 1;

0 commit comments

Comments
 (0)