Skip to content

生命周期管理

GFramework.Core 的生命周期由 Architecture 统一编排,而不是让每个组件各自决定初始化时机。

你真正需要关注的是:

  • 阶段枚举 ArchitecturePhase
  • 组件初始化顺序
  • 逆序销毁语义
  • IArchitectureLifecycleHook

阶段模型

当前公开阶段如下:

阶段含义
None尚未开始初始化
BeforeUtilityInit即将初始化工具
AfterUtilityInit工具初始化完成
BeforeModelInit即将初始化模型
AfterModelInit模型初始化完成
BeforeSystemInit即将初始化系统
AfterSystemInit系统初始化完成
Ready架构已完成初始化并可供稳定使用
Destroying正在销毁
Destroyed已销毁
FailedInitialization初始化流程失败

正常路径:

text
None
-> BeforeUtilityInit
-> AfterUtilityInit
-> BeforeModelInit
-> AfterModelInit
-> BeforeSystemInit
-> AfterSystemInit
-> Ready
-> Destroying
-> Destroyed

初始化顺序

注册顺序和初始化顺序不是一回事。当前框架会按组件类别统一推进:

  1. Utility
  2. Model
  3. System

这保证了大多数系统在初始化时,可以安全依赖已经就绪的工具与模型。

启动方式:

csharp
var architecture = new GameArchitecture();
await architecture.InitializeAsync();
await architecture.WaitUntilReadyAsync();

注册逻辑仍然写在 OnInitialize()

csharp
protected override void OnInitialize()
{
    RegisterUtility(new SaveUtility());
    RegisterModel(new PlayerModel());
    RegisterSystem(new CombatSystem());
}

销毁语义

销毁由 DestroyAsync() 统一触发,框架会按逆序回收组件。

如果组件实现了异步销毁接口,框架会优先走异步路径。也就是说,新代码应优先实现:

  • IAsyncDestroyable
  • 或其他已有的异步销毁基类路径

同步 Destroy() 主要是兼容入口。

组件自己的生命周期

大多数组件不需要手写 Initialize();继承框架基类即可。

这里的 OnInit() 是组件级入口,用来初始化单个 Model / System;上面的 OnInitialize() 则用于架构级注册:

csharp
public sealed class PlayerModel : AbstractModel
{
    protected override void OnInit()
    {
    }
}
csharp
public sealed class CombatSystem : AbstractSystem
{
    protected override void OnInit()
    {
    }
}

如果你的组件需要真正的异步初始化或销毁,再补对应接口。

生命周期钩子

当你需要做横切阶段逻辑时,优先实现 IArchitectureLifecycleHook,而不是把这些逻辑分散到某个具体 System 里。

csharp
public sealed class MetricsHook : IArchitectureLifecycleHook
{
    public void OnPhase(ArchitecturePhase phase, IArchitecture architecture)
    {
        if (phase == ArchitecturePhase.Ready)
        {
            Console.WriteLine("Architecture ready.");
        }
    }
}

注册方式:

csharp
architecture.RegisterLifecycleHook(new MetricsHook());

阶段监听

如果你只需要观察阶段变化,也可以直接订阅:

如果你从旧版本的 PhaseChanged 迁移过来,需要把旧写法 phase => ... 改成 (_, args) => ..., 并通过 ArchitecturePhaseChangedEventArgs.Phase 读取阶段值。

csharp
architecture.PhaseChanged += (_, args) =>
{
    Console.WriteLine($"Phase changed: {args.Phase}");
};

什么时候会进入 FailedInitialization

如果初始化流程中抛出异常,架构会切到 FailedInitialization。这意味着:

  • Ready 不会被触发
  • 后续诊断应先回到启动路径
  • 文档示例不应假设“只要 new 了 Architecture 就一定能跑到 Ready”

推荐做法

  • 新代码优先使用 InitializeAsync() / DestroyAsync()
  • 把架构级注册逻辑放在 OnInitialize();组件自己的初始化仍然使用 OnInit(),不要再尝试重写 Init() 这类旧入口
  • Utility 承载底层能力,让 Model 承载状态,再让 System 消费两者
  • 跨组件阶段逻辑优先写成 IArchitectureLifecycleHook

继续阅读

基于 Apache 2.0 许可证发布