跳转至

三阶段初始化

调用 Gf.init() 后,框架会遍历所有模块组件,并依次触发 init()async_init()ready() 三个阶段。默认保持注册顺序;如果模块设置了 lifecycle_priority,同类模块会按数值从高到低初始化,释放时反向处理。

所有 GFModelGFSystemGFUtility 基类都提供这三个虚方法供模块重写。架构生命周期只调用这三个基类的强类型虚方法;普通 Object 或未继承对应基类的对象不能作为框架模块注册,也不会依靠同名方法参与生命周期。

同步初始化

func init() -> void:
    # 同步的初步设置。

init() 会首先遍历并调用所有实例。它适合执行没有外部依赖、立即完成的轻量设置,例如绑定初始响应式属性、设置默认数值等。

此时不能保证其他模块已经完成 init(),因此不建议在这里频繁跨模块调用。

异步等待

func async_init(scope: GFAsyncScope) -> void:
    var asset_utility := Gf.get_utility(GFAssetUtility) as GFAssetUtility
    var load_state := { "done": false, "resource": null }
    asset_utility.load_async("res://data/tables.json", func(resource: Resource) -> void:
        load_state.resource = resource
        load_state.done = true
    )
    while not load_state.done:
        if scope.is_cancel_requested():
            return
        await Engine.get_main_loop().process_frame

async_init(scope) 会在所有 init() 执行完毕后串行运行。它返回 void,但 Godot 4 支持在 void 函数内部使用 await;框架的 Gf.init() 会自动等待每个模块的 async_init(scope) 完成,避免模块在异步资源未就绪前进入 ready() 或 tick。scope 是本轮异步生命周期的协作取消边界,超时、初始化失败或架构释放后会进入取消状态。

async_init(scope) 仍是主线程 coroutine。函数开始到首个 await 之前是同步执行段,框架无法在这段中主动让帧或触发超时;不要把大批量扫描、重型解析或阻塞 IO 放在首个 await 之前。长任务应拆成可让帧的步骤,并在每个 await 或外部回调返回后检查 scope.is_cancel_requested()

就绪完成

func ready() -> void:
    register_simple_event(&"GAME_STARTED", GFEventListener.from_method(self, &"_on_game_started", 1))

ready() 会在所有模块的 async_init() 结束后触发。此时整个架构已经完成挂载,模块可以安全获取其他 Model、System 或 Utility,并注册事件监听。

释放引用

func dispose() -> void:
    _stop_runtime_work()

func release_dependencies() -> void:
    _cached_utility = null
    super.release_dependencies()

架构注销模块或整体 dispose() 时,会先调用模块的 dispose(),再调用 release_dependencies()dispose() 负责停止模块自身工作、断开业务监听和释放本模块拥有的对象;release_dependencies() 只负责清空模块缓存的外部 Model/System/Utility 引用,并释放框架注入作用域。

GF 不会自动扫描并清空模块的任意成员变量。需要释放哪些引用由模块自己声明,避免在错误生命周期点破坏模块自己的 dispose 逻辑。