Files
FlowScope/docs/requirements/p0-gameflow.md
2026-05-15 15:38:40 +08:00

4.4 KiB
Raw Permalink Blame History

P0-2: GameFlow 需求详细文档

对齐说明

本文档以 docs/requirements/p0-requirements-set.md 为准。GameFlow 是全局生命周期所有者,负责创建 Feature scope、FeatureContext并编排 Feature 的进入、切换和关闭。

目标

提供游戏启动、Feature 切换和关闭流程的编排器,保证生命周期顺序、失败清理、取消和非法状态防护。

状态机

public enum GameFlowState
{
    Idle,
    Starting,
    Running,
    Switching,
    NoActiveFeature,
    ShuttingDown,
    Disposed
}

状态转换:

Idle -> Starting -> Running <-> Switching
                         \-> NoActiveFeature
Running -> ShuttingDown -> Disposed
NoActiveFeature -> Switching -> Running
NoActiveFeature -> ShuttingDown -> Disposed

非法状态调用抛 InvalidOperationException,错误必须包含当前状态和操作名。

接口

public sealed class GameFlow
{
    public GameFlowState State { get; }

    public Task StartupAsync<TInitialFeature>(
        Container root,
        CancellationToken cancellationToken)
        where TInitialFeature : IFeature;

    public Task SwitchToAsync<TFeature>(
        CancellationToken cancellationToken)
        where TFeature : IFeature;

    public Task ShutdownAsync(CancellationToken cancellationToken);
}

启动流程

StartupAsync:
  1. State = Starting
  2. Resolve IConfigProvider
  3. await config.LoadAllAsync(ct)
  4. Resolve ISaveService
  5. 加载或创建 P0 Sample 所需 Data
  6. 注册 Data 到 root Container
  7. 创建 TInitialFeature
  8. 创建 Feature scope
  9. 创建 FeatureContext
 10. await feature.LoadAsync(context)
 11. await feature.EnterAsync(context)
 12. State = Running

失败规则:

  • 配置加载失败清理已创建对象State 回到 Idle抛异常。
  • 存档加载失败:使用默认 Data记录警告继续启动。
  • Feature Load/Enter 失败:调用 Dispose 清理State 回到 Idle抛异常。

Feature 切换流程

SwitchToAsync:
  1. State = Switching
  2. await current.ExitAsync(currentContext)
  3. current.Dispose()
  4. Dispose current FeatureContext / scope / resources
  5. 创建新 Feature、scope、FeatureContext
  6. await next.LoadAsync(nextContext)
  7. await next.EnterAsync(nextContext)
  8. State = Running

失败规则:

  • 旧 Feature ExitAsync 失败:记录错误,继续 Dispose。
  • 旧 Feature Dispose 失败:记录错误,继续创建新 Feature。
  • 新 Feature LoadAsync 失败:清理新 FeatureState = NoActiveFeature抛异常。
  • 新 Feature EnterAsync 失败:调用新 Feature DisposeState = NoActiveFeature抛异常。
  • 切换期间再次调用 SwitchToAsyncP0 抛 InvalidOperationException,不排队。

关闭流程

ShutdownAsync:
  1. State = ShuttingDown
  2. best-effort 调用当前 Feature ExitAsync
  3. best-effort 调用当前 Feature Dispose
  4. best-effort 保存必要 Data
  5. Dispose root Container
  6. State = Disposed

规则:

  • ShutdownAsync 一旦进入关闭流程,必须尽量执行到底。
  • 保存失败记录错误,不阻塞退出。
  • Feature 退出/释放失败记录错误,不阻塞退出。
  • Container 释放失败记录错误,不阻塞退出。

暂不做

  • Feature 栈。
  • 并行 Feature。
  • Feature 预加载。
  • 可配置启动任务列表。
  • 切换请求队列。
  • Starting/Switching 中断式 Shutdown。

验收标准

# 标准 通过条件
1 正常启动 Startup 完成后 State == Running初始 Feature 已 Load + Enter
2 启动配置失败 State 回到 Idle异常向上传播
3 启动存档失败 使用默认 Data记录警告继续启动
4 正常切换 旧 Feature 已 Exit/Dispose新 Feature 已 Load/Enter
5 新 Feature Load 失败 State == NoActiveFeature已清理新 Feature
6 新 Feature Enter 失败 State == NoActiveFeature已 Dispose 新 Feature
7 关闭 best-effort 保存或释放失败时仍进入 Disposed
8 非法状态防护 非法调用抛异常并包含当前状态
9 CancellationToken 传递 FeatureContext 中可拿到同一个取消信号

依赖关系

GameFlow
├── Container
├── IFeature
├── FeatureContext
├── IConfigProvider
├── ISaveService
└── IResourceService