Object(core/object/object.h:411-454)是引擎一切类的根基:场景节点、资源、服务器、脚本宿主都是 Object。核心能力:反射(属性/方法/信号通过名字访问)、通知、脚本挂载、GDExtension 扩展。

Object 关键成员

  • GDType *_gdtype_ptr — 缓存的类型对象,承载类名(此版本无独立 _class_name 成员);GDCLASS 宏(object.h:158-333)生成 get_class_ptr_static() 等,自称 “defines the object model”
  • ScriptInstance *script_instance — 挂载的脚本实例(GDScript/C#),见 gdscript
  • ObjectGDExtension *_extension — GDExtension 原生扩展接入点
  • HashMap<StringName, SignalData> signal_map — 信号槽表
  • HashMap<StringName, Variant> metadata — 任意元数据(set_meta)
  • ObjectID _instance_id — 由 ObjectDB 分配(object.h:880-946):39 位 validator + 24 位 slot 索引 + 1 位引用计数标志,get_instance(ObjectID) 自旋锁校验,用于跨线程/跨 Variant 安全取回对象

属性与方法的动态访问

set() 解析顺序(object.cpp:198-269):

script_instance->set  →  _extension->set  →  set_native(GDType::Property map,经 setter MethodBind)
→  "script" 特例  →  "metadata/" 前缀  →  _setv(用户覆写钩子)

get() 对称(object.cpp:271-347)。方法调用 callp()(object.cpp:840-901):截获 free → script_instance->callp → 查 GDType::get_method_map() 拿 MethodBind。

MethodBind(core/object/method_bind.h:38-138)是 C++ 方法暴露给动态调用的包装:三种调用入口 call()(Variant 动态)、validated_call()(类型已验证)、ptrcall()(类型化指针,GDExtension 用)。D_METHOD/DEFVAL 宏提供参数名与默认值(class_db.h:61-95)。

ClassDB 注册表

ClassDB(core/object/class_db.h:178)是静态 HashMap<StringName, ClassInfo>:

  • ClassInfo(class_db.h:111-141):inherits_ptr、creation_func、gdtype、exposed/is_virtual/is_runtime 标志
  • register_class<T>()(class_db.h:228-241):T::initialize_class() → 设 creation_func=&creator<T>(placement new 后手动 _initialize/_postinitialize);变体:abstract(无创建函数)、internal(不暴露给脚本)、runtime
  • initialize_class()(object.h:289-310):先递归父类 → _bind_methods()(成员指针比较防重复绑定)→ ClassDB::bind_method 注册 MethodBind
  • 宏:GDREGISTER_CLASS、GDREGISTER_ABSTRACT_CLASS、GDREGISTER_INTERNAL_CLASS(class_db.h:558-577)

通知机制(notification)

Object 用整数通知而非大量虚函数传递生命周期事件。notification(n, reversed)(object.cpp:980-1018)经 _notification_forwardv(C++→GDExtension→script)或 _notification_backwardv 分发。

  • 基础通知(object.h:660-666):POSTINITIALIZE=0, PREDELETE=1, EXTENSION_RELOADED=2, PREDELETE_CLEANUP=3
  • 生命周期:_initialize 缓存类型 → _postinitialize 发 POSTINITIALIZE → _predelete 反向发 PREDELETE,按 script→extension→C++ 顺序销毁(object.cpp:138-179)
  • 子类覆写检测用成员指针比较(&m_class::_get != &m_inherits::_get);GDScript 侧由 GDVIRTUAL_CALL/GDVIRTUAL_IS_OVERRIDDEN 宏(object.h:138-148)驱动

场景层大量使用:NOTIFICATION_READY/PROCESS/PHYSICS_PROCESS/ENTER_TREE 等,见 scene-tree。

信号(Signals)

  • connect(signal, callable, flags)(object.cpp:1574-1640):信号不存在时校验类信号/脚本信号后惰性创建;目标对象的 connections 双向登记
  • ConnectFlags(object.h:356-363):DEFERRED=1, PERSIST=2, ONE_SHOT=4, REFERENCE_COUNTED=8, APPEND_SOURCE_OBJECT=16, INHERITED=32
  • SignalData{MethodInfo user; HashMap<Callable,Slot> slot_map}(object.h:414-424),key 用 get_base_comparator()(忽略 bind)
  • emit_signalp(object.cpp:1247-1393):锁内快照全部 slot(栈上 5 个,超出堆分配)→ 先断开 ONE_SHOT → DEFERRED 走 MessageQueue::push_callablep,否则直接调用

Callable(core/variant/callable.h:48-137):16 字节 = StringName method + union{ObjectID, CallableCustom*};lambda/GDScript 函数走 CallableCustom(引用计数,:143-170)。Signal(callable.h:178-206)仅是 16 字节代理(name + ObjectID),注释明确引擎内部不用它,只在放进 Variant 给脚本层时分配。

RefCounted 与 Ref

RefCounted : Object(core/object/ref_counted.h:36-56):SafeRefCount 原子计数 + refcount_init 区分”是否被引用过”。Ref<T>(:58-229)是单指针智能引用:ref_pointer 初次用 init_ref、后续用 reference;unref() 在 unreference() 为真时 memdelete。memnew 对 RefCounted 子类自动返回 Ref<T>。Variant 存储 OBJECT 时对 RefCounted 自动 ref/unref,见 variant。

ScriptLanguage 扩展点

ScriptLanguage : Object(core/object/script_language.h:212-435)是脚本语言插件接口(init/validate/reload_all_scripts/debug 等纯虚);Script : Resource(:117-210)是单个脚本资源;ScriptServer(:50-113)最多注册 16 种语言并管理 class_name 全局类表。GDScript 通过实现这套接口接入,见 gdscript。

相关