@@ -582,6 +582,29 @@ class Object {
582582 CONNECT_INHERITED = 32 , // Used in editor builds.
583583 };
584584
585+ // Store on each object a bitfield to quickly test whether it is derived from some "key" classes
586+ // that are commonly tested in performance sensitive code.
587+ // Ensure unsigned to bitpack.
588+ enum class AncestralClass : unsigned int {
589+ REF_COUNTED = 1 << 0 ,
590+ NODE = 1 << 1 ,
591+ RESOURCE = 1 << 2 ,
592+ SCRIPT = 1 << 3 ,
593+
594+ CANVAS_ITEM = 1 << 4 ,
595+ CONTROL = 1 << 5 ,
596+ NODE_2D = 1 << 6 ,
597+ COLLISION_OBJECT_2D = 1 << 7 ,
598+ AREA_2D = 1 << 8 ,
599+
600+ NODE_3D = 1 << 9 ,
601+ VISUAL_INSTANCE_3D = 1 << 10 ,
602+ GEOMETRY_INSTANCE_3D = 1 << 11 ,
603+ COLLISION_OBJECT_3D = 1 << 12 ,
604+ PHYSICS_BODY_3D = 1 << 13 ,
605+ MESH_INSTANCE_3D = 1 << 14 ,
606+ };
607+
585608 struct Connection {
586609 ::Signal signal;
587610 Callable callable;
@@ -623,16 +646,19 @@ class Object {
623646#ifdef DEBUG_ENABLED
624647 SafeRefCount _lock_index;
625648#endif // DEBUG_ENABLED
626- bool _block_signals = false ;
627649 int _predelete_ok = 0 ;
628650 ObjectID _instance_id;
629651 bool _predelete ();
630652 void _initialize ();
631653 void _postinitialize ();
632- bool _can_translate = true ;
633- bool _emitting = false ;
654+
655+ uint32_t _ancestry : 15 ;
656+
657+ bool _block_signals : 1 ;
658+ bool _can_translate : 1 ;
659+ bool _emitting : 1 ;
634660#ifdef TOOLS_ENABLED
635- bool _edited = false ;
661+ bool _edited : 1 ;
636662 uint32_t _edited_version = 0 ;
637663 HashSet<String> editor_section_folding;
638664#endif
@@ -658,7 +684,6 @@ class Object {
658684 _FORCE_INLINE_ void _construct_object (bool p_reference);
659685
660686 friend class RefCounted ;
661- bool type_is_reference = false ;
662687
663688 BinaryMutex _instance_binding_mutex;
664689 struct InstanceBinding {
@@ -764,6 +789,7 @@ class Object {
764789 static void _get_property_list_from_classdb (const StringName &p_class, List<PropertyInfo> *p_list, bool p_no_inheritance, const Object *p_validator);
765790
766791 bool _disconnect (const StringName &p_signal, const Callable &p_callable, bool p_force = false );
792+ void _define_ancestry (AncestralClass p_class) { _ancestry |= (uint32_t )p_class; }
767793
768794 virtual bool _uses_signal_mutex () const ;
769795
@@ -838,6 +864,8 @@ class Object {
838864 }
839865 virtual bool is_class_ptr (void *p_ptr) const { return get_class_ptr_static () == p_ptr; }
840866
867+ bool has_ancestry (AncestralClass p_class) const { return _ancestry & (uint32_t )p_class; }
868+
841869 const StringName &get_class_name () const ;
842870
843871 StringName get_class_name_for_extension (const GDExtension *p_library) const ;
@@ -996,7 +1024,7 @@ class Object {
9961024
9971025 void clear_internal_resource_paths ();
9981026
999- _ALWAYS_INLINE_ bool is_ref_counted () const { return type_is_reference ; }
1027+ _ALWAYS_INLINE_ bool is_ref_counted () const { return has_ancestry (AncestralClass::REF_COUNTED) ; }
10001028
10011029 void cancel_free ();
10021030
0 commit comments