@@ -587,6 +587,29 @@ class Object {
587587 CONNECT_INHERITED = 32 , // Used in editor builds.
588588 };
589589
590+ // Store on each object a bitfield to quickly test whether it is derived from some "key" classes
591+ // that are commonly tested in performance sensitive code.
592+ // Ensure unsigned to bitpack.
593+ enum class AncestralClass : unsigned int {
594+ REF_COUNTED = 1 << 0 ,
595+ NODE = 1 << 1 ,
596+ RESOURCE = 1 << 2 ,
597+ SCRIPT = 1 << 3 ,
598+
599+ CANVAS_ITEM = 1 << 4 ,
600+ CONTROL = 1 << 5 ,
601+ NODE_2D = 1 << 6 ,
602+ COLLISION_OBJECT_2D = 1 << 7 ,
603+ AREA_2D = 1 << 8 ,
604+
605+ NODE_3D = 1 << 9 ,
606+ VISUAL_INSTANCE_3D = 1 << 10 ,
607+ GEOMETRY_INSTANCE_3D = 1 << 11 ,
608+ COLLISION_OBJECT_3D = 1 << 12 ,
609+ PHYSICS_BODY_3D = 1 << 13 ,
610+ MESH_INSTANCE_3D = 1 << 14 ,
611+ };
612+
590613 struct Connection {
591614 ::Signal signal;
592615 Callable callable;
@@ -628,16 +651,19 @@ class Object {
628651#ifdef DEBUG_ENABLED
629652 SafeRefCount _lock_index;
630653#endif // DEBUG_ENABLED
631- bool _block_signals = false ;
632654 int _predelete_ok = 0 ;
633655 ObjectID _instance_id;
634656 bool _predelete ();
635657 void _initialize ();
636658 void _postinitialize ();
637- bool _can_translate = true ;
638- bool _emitting = false ;
659+
660+ uint32_t _ancestry : 15 ;
661+
662+ bool _block_signals : 1 ;
663+ bool _can_translate : 1 ;
664+ bool _emitting : 1 ;
639665#ifdef TOOLS_ENABLED
640- bool _edited = false ;
666+ bool _edited : 1 ;
641667 uint32_t _edited_version = 0 ;
642668 HashSet<String> editor_section_folding;
643669#endif
@@ -663,7 +689,6 @@ class Object {
663689 _FORCE_INLINE_ void _construct_object (bool p_reference);
664690
665691 friend class RefCounted ;
666- bool type_is_reference = false ;
667692
668693 BinaryMutex _instance_binding_mutex;
669694 struct InstanceBinding {
@@ -769,6 +794,7 @@ class Object {
769794 static void _get_property_list_from_classdb (const StringName &p_class, List<PropertyInfo> *p_list, bool p_no_inheritance, const Object *p_validator);
770795
771796 bool _disconnect (const StringName &p_signal, const Callable &p_callable, bool p_force = false );
797+ void _define_ancestry (AncestralClass p_class) { _ancestry |= (uint32_t )p_class; }
772798
773799 virtual bool _uses_signal_mutex () const ;
774800
@@ -845,6 +871,8 @@ class Object {
845871 }
846872 virtual bool is_class_ptr (void *p_ptr) const { return get_class_ptr_static () == p_ptr; }
847873
874+ bool has_ancestry (AncestralClass p_class) const { return _ancestry & (uint32_t )p_class; }
875+
848876 const StringName &get_class_name () const ;
849877
850878 StringName get_class_name_for_extension (const GDExtension *p_library) const ;
@@ -1003,7 +1031,7 @@ class Object {
10031031
10041032 void clear_internal_resource_paths ();
10051033
1006- _ALWAYS_INLINE_ bool is_ref_counted () const { return type_is_reference ; }
1034+ _ALWAYS_INLINE_ bool is_ref_counted () const { return has_ancestry (AncestralClass::REF_COUNTED) ; }
10071035
10081036 void cancel_free ();
10091037
0 commit comments