文档记录

This commit is contained in:
JSD\13999
2026-05-15 15:38:40 +08:00
parent d7b09891dc
commit 019703d2a8
18 changed files with 4221 additions and 1 deletions

View File

@@ -0,0 +1,170 @@
# P0-8: UIManager 需求详细文档
## 对齐说明
本文档以 `docs/requirements/p0-requirements-set.md` 为准。P0 UIManager 支持可配置层级和层内 LIFO 栈,但不做完整导航路由系统。`UIPanelAttribute` 明确包含 `path` 参数。
## 目标
提供 MVVM Panel 生命周期管理、运行时层级注册、层内栈式打开关闭、手写 Bind/Unbind 和基础缓存/销毁策略。
## 层级注册
```csharp
public sealed class UIManager
{
public void RegisterLayer(
string name,
Canvas canvas,
int sortOrder,
PanelStrategy strategy = PanelStrategy.Destroy);
}
public enum PanelStrategy
{
Destroy,
Cache
}
```
规则:
- P0 不强制固定 `Bottom/Middle/Top`
- 推荐默认层级为 `background / hud / popup / dialog / system`
- 项目可只注册部分层级。
- 未注册层级打开 Panel 时抛异常。
## Panel Attribute
```csharp
[AttributeUsage(AttributeTargets.Class)]
public sealed class UIPanelAttribute : Attribute
{
public string Layer { get; }
public string Path { get; }
public PanelStrategy? OverrideStrategy { get; }
public UIPanelAttribute(
string layer,
string path = null,
PanelStrategy? overrideStrategy = null)
{
Layer = layer;
Path = path;
OverrideStrategy = overrideStrategy;
}
}
```
规则:
- `Layer` 必填。
- `Path` 可选;未填时按命名约定推导。
- `OverrideStrategy` 可选,优先于层级默认策略。
## Panel 基类
```csharp
public abstract class UIPanelBase<TViewModel> : MonoBehaviour
{
protected TViewModel ViewModel { get; private set; }
protected CompositeDisposable Disposables { get; } = new();
public void Bind(TViewModel viewModel)
{
ViewModel = viewModel;
OnBind(viewModel);
}
public virtual void Unbind()
{
Disposables.Clear();
}
protected abstract void OnBind(TViewModel viewModel);
}
```
## 打开与关闭接口
```csharp
public sealed class UIManager
{
public Task<TPanel> OpenAsync<TPanel, TViewModel>(
TViewModel viewModel,
CancellationToken cancellationToken)
where TPanel : UIPanelBase<TViewModel>;
public void Close<TPanel>();
public void CloseLayer(string layerName);
public void CloseAll();
public bool IsOpen<TPanel>();
}
```
## 生命周期
```text
OpenAsync:
1. 读取 UIPanelAttribute
2. 校验层级已注册
3. 解析资源路径
4. IResourceService.LoadAsync<GameObject>
5. Instantiate 到目标 Canvas
6. Bind(viewModel)
7. SetActive(true)
8. 压入层内栈
Close:
1. 校验目标 Panel 是所在层级栈顶
2. 从栈弹出
3. Unbind()
4. Destroy 策略Destroy GameObject 并释放资源 handle
5. Cache 策略SetActive(false),保留实例和资源 handle
```
路径约定:
```text
ShopPanel -> UI/Shop/Prefab
ConfirmPanel -> UI/Confirm/Prefab
MainHudPanel -> UI/MainHud/Prefab
```
## 暂不做
- 自动 UI 绑定。
- 导航路由系统。
- 跨 Feature 页面恢复。
- Panel 预加载。
- SafeArea。
- 多语言 UI 切换。
- 红点/通知系统。
- 复杂转场动画。
## 验收标准
| # | 标准 | 通过条件 |
|---|------|---------|
| 1 | 注册层级 | RegisterLayer 后 Panel 可挂载到对应 Canvas |
| 2 | Attribute 层级 | Panel 通过 UIPanelAttribute 找到层级 |
| 3 | path 参数 | Attribute 指定 path 时按指定路径加载 |
| 4 | 路径约定 | 未指定 path 时按命名约定加载 |
| 5 | Open | 异步加载 Prefab、实例化、Bind、入栈 |
| 6 | Close | 栈顶 Panel Unbind 并按策略关闭 |
| 7 | LIFO | 关闭非栈顶 Panel 抛异常 |
| 8 | Cache | Cache Panel 再次打开时复用并重新 Bind |
| 9 | Destroy | Destroy Panel 关闭后释放资源 handle |
| 10 | CloseLayer | 只关闭指定层级 |
| 11 | CloseAll | 关闭所有层级 |
| 12 | Bind 失败 | 清理已创建对象和资源 handle 后抛异常 |
## 依赖关系
```text
UIManager
├── IResourceService
├── R3
├── Unity Canvas / GameObject / MonoBehaviour
└── CancellationToken
```