文档记录
This commit is contained in:
156
docs/requirements/p0-gameflow.md
Normal file
156
docs/requirements/p0-gameflow.md
Normal file
@@ -0,0 +1,156 @@
|
||||
# P0-2: GameFlow 需求详细文档
|
||||
|
||||
## 对齐说明
|
||||
|
||||
本文档以 `docs/requirements/p0-requirements-set.md` 为准。GameFlow 是全局生命周期所有者,负责创建 Feature scope、FeatureContext,并编排 Feature 的进入、切换和关闭。
|
||||
|
||||
## 目标
|
||||
|
||||
提供游戏启动、Feature 切换和关闭流程的编排器,保证生命周期顺序、失败清理、取消和非法状态防护。
|
||||
|
||||
## 状态机
|
||||
|
||||
```csharp
|
||||
public enum GameFlowState
|
||||
{
|
||||
Idle,
|
||||
Starting,
|
||||
Running,
|
||||
Switching,
|
||||
NoActiveFeature,
|
||||
ShuttingDown,
|
||||
Disposed
|
||||
}
|
||||
```
|
||||
|
||||
状态转换:
|
||||
|
||||
```text
|
||||
Idle -> Starting -> Running <-> Switching
|
||||
\-> NoActiveFeature
|
||||
Running -> ShuttingDown -> Disposed
|
||||
NoActiveFeature -> Switching -> Running
|
||||
NoActiveFeature -> ShuttingDown -> Disposed
|
||||
```
|
||||
|
||||
非法状态调用抛 `InvalidOperationException`,错误必须包含当前状态和操作名。
|
||||
|
||||
## 接口
|
||||
|
||||
```csharp
|
||||
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);
|
||||
}
|
||||
```
|
||||
|
||||
## 启动流程
|
||||
|
||||
```text
|
||||
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 切换流程
|
||||
|
||||
```text
|
||||
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` 失败:清理新 Feature,State = NoActiveFeature,抛异常。
|
||||
- 新 Feature `EnterAsync` 失败:调用新 Feature Dispose,State = NoActiveFeature,抛异常。
|
||||
- 切换期间再次调用 `SwitchToAsync`:P0 抛 `InvalidOperationException`,不排队。
|
||||
|
||||
## 关闭流程
|
||||
|
||||
```text
|
||||
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 中可拿到同一个取消信号 |
|
||||
|
||||
## 依赖关系
|
||||
|
||||
```text
|
||||
GameFlow
|
||||
├── Container
|
||||
├── IFeature
|
||||
├── FeatureContext
|
||||
├── IConfigProvider
|
||||
├── ISaveService
|
||||
└── IResourceService
|
||||
```
|
||||
Reference in New Issue
Block a user