docs: rebuild Debug API content

This commit is contained in:
2026-03-26 17:21:44 +08:00
parent 122495e581
commit 2e2316aa55
69 changed files with 2371 additions and 1092 deletions

View File

@@ -2,15 +2,15 @@
## 目标
本规范用于 `XCEngine` 生成和维护一套唯一的 canonical API 文档
本规范用于维护 `XCEngine` 的唯一正式 API 文档树,并约束后续所有模块级重构的工作方式
硬性要求:
1. `docs/api/XCEngine/**` 必须与 `engine/include/XCEngine/**` 严格平行。
2. 模块、子模块、类型、方法的命名必须稳定并贴近源码符号名
3. 不保留第二套正式文档树。历史文档只允许作为迁移过程中的临时材料,迁移完成后必须删除
在编写任何 API 文档之前,必须先阅读对应头文件与相关实现,理解职责、边界、生命周期、线程语义、错误条件和依赖关系。禁止只根据函数名猜测含义
1. `docs/api/XCEngine/**` 必须与 `engine/include/XCEngine/**` 保持平行。
2. canonical API 文档只保留一套;迁移完成后必须删除旧目录与旧入口
3. 每个 public header 对应一个独立文档目录,每个类型页都使用 `{TypeName}/{TypeName}.md`
4. 方法页优先使用源码中的原始函数名;不要改成 kebab-case、全小写或其它再命名形式。
5. API 文档必须以源码、实现、测试和真实调用点为依据,禁止只根据名字猜测行为
## Canonical 目录结构
@@ -23,48 +23,43 @@ docs/api/
│ │ ├── Debug.md
│ │ ├── Logger/
│ │ │ ├── Logger.md
│ │ │ ├── Log.md
│ │ │ ├── SetLevel.md
│ │ │ ── Constructor.md
│ │ │ └── Destructor.md
│ │ │ ├── Get.md
│ │ │ ├── Initialize.md
│ │ │ ── Log.md
│ │ └── RenderDocCapture/
│ │ ├── RenderDocCapture.md
│ │ └── TriggerCapture.md
│ ├── Core/
│ │ ├── Core.md
│ │ ├── Asset/
│ │ │ ├── Asset.md
│ │ │ └── ResourceManager/
│ │ │ ├── ResourceManager.md
│ │ │ └── Load.md
│ │ └── Math/
│ │ └── Math.md
│ │ └── BeginCapture.md
│ └── ...
├── _meta/
└── _tools/
├── _guides/
│ └── Debug/
└── _meta/
```
说明:
- `docs/api/XCEngine/**` 是唯一 canonical API 树。
- `docs/api/_guides/**` 用于概念、教程、设计理念和工作流说明,不是第二套 API 树。
- `README.md` 不用于 canonical 模块索引页;模块索引页统一使用 `{DirName}.md`
## 强制命名规则
### 1. 目录总览
### 1. 目录索引
-目录总览页必须是 `docs/api/XCEngine/XCEngine.md`
- 模块总览页必须使用 `{ModuleName}.md`
- 子模块总览页必须使用 `{SubmoduleName}.md`
- canonical 目录下禁止使用 `README.md` 作为模块或子模块总览页
-索引页:`docs/api/XCEngine/XCEngine.md`
- 模块索引页:`docs/api/XCEngine/{ModuleName}/{ModuleName}.md`
- 子模块索引页:`docs/api/XCEngine/{ModuleName}/{SubmoduleName}/{SubmoduleName}.md`
示例:
- `docs/api/XCEngine/Debug/Debug.md`
- `docs/api/XCEngine/Core/Core.md`
- `docs/api/XCEngine/Core/Asset/Asset.md`
- `docs/api/XCEngine/RHI/D3D12/D3D12.md`
### 2. 类型目录
- 每个 public 类型或以 header 为单位的主声明,都必须是一个独立文件夹
- 文件夹名必须与源码中的类型名或 header stem 保持一致
- 保留原始大小写
- 每个 public header 对应一个独立文件夹
- 文件夹名必须与 header stem 或主要类型名一致
- 保留源码中的大小写,不做风格改写。
示例:
@@ -74,77 +69,225 @@ docs/api/
### 3. 类型总览页
- 类型总览页固定为 `{TypeName}/{TypeName}.md`
- 不允许把类型总览页直接平铺在模块目录
- 固定为 `{TypeName}/{TypeName}.md`
- 不允许把类型总览页直接平铺在模块目录
### 4. 方法详情页
- 方法详情页必须放在所属类型文件夹内
- 方法页文件名优先使用原函数名
- 保留 PascalCase / camelCase / 全大写缩写
- 禁止改成 lowercase kebab-case
- 同名重载共用一个方法页
- 方法放在所属类型目录内。
- 文件名优先使用原函数名
- 重载共享同一页,在页内按签名分节说明。
示例:
- `Get.md`
- `CreateBuffer.md`
- `SetRenderTarget.md`
- `Initialize.md`
- `SetCaptureFilePath.md`
- `LoadSceneAsync.md`
- `GetCPUHandle.md`
### 5. 特殊方法命名
### 5. 特殊命名
- 构造函数使用 `Constructor.md`
- 析构函数使用 `Destructor.md`
- 运算符重载使用可读的 PascalCase 名称
- 构造函数`Constructor.md`
- 析构函数`Destructor.md`
- 运算符使用可读的 PascalCase 名称
推荐映射:
建议映射:
- `operator=` -> `OperatorAssign.md`
- `operator+=` -> `OperatorPlusAssign.md`
- `operator[]` -> `OperatorSubscript.md`
- `operator()` -> `OperatorCall.md`
- `operator bool` -> `OperatorBool.md`
## 写作前的取证流程
在编写任何 API 页之前,必须完成下面的最小取证:
1. 阅读对应 public header。
2. 阅读对应 `.cpp` 或内联实现。
3. 搜索测试、示例和真实调用点。
4. 确认生命周期、线程语义、所有权、失败路径和平台限制。
至少回答以下问题后才能落文:
- 这个类型解决什么问题,边界在哪里?
- 调用前需要什么前置条件?
- 调用失败时返回什么,或者会静默失败?
- 谁拥有对象,谁负责释放资源?
- 多线程下哪些调用安全,哪些只能在初始化阶段使用?
- 当前实现是不是完整的?有没有空实现、占位实现或只做轻量封装?
禁止行为:
- 只根据 `Get``Create``Set` 之类的前缀写模板句。
- 把“设计意图”当成“当前实现行为”来写。
- 把测试里假设成立的场景,误写成通用保证。
## 契约分层规则
文档必须明确区分下面三层信息:
### 1. 接口契约
来自 public header属于使用者可以依赖的 API 形状。
例如:
- 函数签名
- 参数和返回值
- 可见的数据结构
- 明确暴露的枚举值和宏
### 2. 当前实现行为
来自 `.cpp`、内联实现、测试和调用点,描述当前版本的真实行为。
例如:
- 是否自动初始化
- 是否加锁
- 是否会写日志、刷新文件、拉起窗口焦点
- 是否只是 no-op 或 stub
这一层必须使用明确表述,例如:
- “当前实现中……”
- “按 `engine/src/...` 的实现……”
- “当前版本会……”
### 3. 合理推断
只在确实有必要时使用,而且必须标明是推断。
例如:
- “从 API 形状看,设计上显然是为后续 Chrome Trace 导出预留扩展点。”
如果不能证明,就不要写。
## 页面职责
### 1. 目录总览
### 1. 模块页 / 子模块
负责:
- 说明模块或子模块的职责边界
- 列出直接子目录
- 列出当前目录下的 public headers 对应类型入口
- 提供父级目录和 `docs/api/main.md` 的导航
- 说明模块职责边界和典型使用场景
- 列出子目录与 public headers
- 给出与相邻模块的关系
- 链接相关 guide 页
不负责:
- 展开详细方法级说明
- 复制头文件全部声明
- 保留迁移说明、旧入口跳转或双轨文档提示
- 展开所有方法细节
- 重复 header 全量声明
### 2. 类型总览
### 2. 类型页
负责
必须包含
- 标识命名空间、类型、头文件、职责
- 给出声明概览
- 列出公开字段、枚举值或公开方法
- 作为该类型所有方法详情页的稳定入口
- 命名空间
- 类型分类
- 头文件
- 角色概述
- 生命周期
- 线程语义
- 所有权 / 资源管理方式
- 当前实现限制
- 与相关方法页、guide 页的跳转
### 3. 方法详情页
如果类型是枚举或结构体,还应补充:
负责:
- 字段或枚举值说明
- 值之间的语义关系
- 典型使用方式
- 给出准确签名
- 按重载分节
- 说明参数、返回值、生命周期、线程语义和关键约束
- 给出最小但可信的示例
### 3. 方法页
## 推荐页面模板
必须包含:
### 1. 目录总览页模板
- 准确签名
- 调用目的
- 前置条件
- 参数说明
- 返回值说明
- 副作用
- 线程语义
- 失败路径或 no-op 条件
- 最小可信示例
方法页不能只写“获取对象”“设置状态”这种空描述。
## 内容深度要求
### 1. 解释“是什么”
说明类型或方法的职责,而不是简单复述名字。
### 2. 解释“怎么用”
给出最小可运行或最小可信的使用顺序,让用户知道放在初始化、运行时还是销毁阶段。
### 3. 解释“为什么这样设计”
结合引擎架构解释:
- 为什么做成 singleton、service、interface、sink、builder、handle
- 这样做的收益是什么
- 有哪些代价或约束
### 4. 解释“当前实现做到哪一步”
商业级 API 文档不能假装所有接口都同样成熟。
对于未完成能力,必须明确说明:
- 当前是占位接口
- 当前只有基础实现
- 当前只覆盖某个平台 / 某条后端路径
## 教程与概念页规范
当某个模块仅靠 API 页不足以让用户理解时,应增加 `_guides` 页。
适合写 guide 的内容:
- 前置知识
- 架构设计理念
- 推荐工作流
- 和 Unity / Unreal / RenderDoc 等常见工具的概念对照
- 最佳实践与反模式
guide 页不是第二套 API 参考,它们负责回答:
- 为什么要这样组织模块
- 用户第一次接触时该从哪里开始
- 这套 API 与常见引擎的对应关系是什么
guide 页应尽量包含:
- 问题背景
- 设计目标
- 推荐流程
- 优点与代价
- 与现有 API 页的链接
## Unity 风格的解释性要求
当模块涉及常见引擎概念时,可以增加 Unity 对照,但必须克制且准确。
推荐写法:
- “可以把 `Logger` 理解为比 Unity Console 更底层的日志分发中心。”
- “当前 `Profiler` 只覆盖轻量 CPU 埋点,不等同于 Unity Profiler 的完整时间线分析。”
-`RenderDocCapture` 更接近引擎内置的 RenderDoc 工作流桥接,而不是 Unity Frame Debugger 的替代品。”
禁止写法:
- “和 Unity 完全一样”
- “等价于某商业引擎的完整系统”
## 页面模板
### 1. 模块页模板
```markdown
# {DirName}
@@ -155,27 +298,26 @@ docs/api/
**描述**: {一句话说明当前目录职责}
## 概
## 概
{说明该目录在整个引擎中的职责边界、使用场景和相邻模块关系}
{解释职责边界、典型场景和相邻模块关系}
## 子目录
## 设计要点
- [ChildA](ChildA/ChildA.md)
- [ChildB](ChildB/ChildB.md)
- {要点 1}
- {要点 2}
## 头文件
- [TypeA](TypeA/TypeA.md) - `TypeA.h`
- [TypeB](TypeB/TypeB.md) - `TypeB.h`
## 相关文档
## 相关指南
- [上级目录](../{ParentDir}.md)
- [API 总索引](../../main.md)
- [GuideA](../../_guides/.../GuideA.md)
```
### 2. 类型总览页模板
### 2. 类型页模板
```markdown
# {TypeName}
@@ -188,29 +330,27 @@ docs/api/
**描述**: {一句话说明}
## 概
## 概
{描述该类型的职责、拥有关系、状态约束、典型使用方式}
{说明角色、状态、边界、典型使用方式}
## 声明概览
## 生命周期
| 声明 | 类型 | 说明 |
|------|------|------|
| `{TypeName}` | `class` | {说明} |
- {初始化与销毁方式}
## 公共方法
## 线程语义
| 方法 | 描述 |
- {线程安全说明}
## 公开成员
| 成员 | 说明 |
|------|------|
| [Initialize](Initialize.md) | {描述} |
| [Shutdown](Shutdown.md) | {描述} |
## 相关文档
- [当前目录](../{DirName}.md)
| [Initialize](Initialize.md) | {说明} |
| [Shutdown](Shutdown.md) | {说明} |
```
### 3. 方法详情页模板
### 3. 方法页模板
```markdown
# {TypeName}::{MethodName}
@@ -221,57 +361,37 @@ docs/api/
{完整签名}
```
{方法行为说明,包括前置条件、后置条件、副作用和失败语义}
## 行为说明
{说明前置条件、后置状态、副作用和当前实现细节}
## 参数
**参数**
- `param` - {描述}
**返回**
## 返回值
- `{Type}` - {描述}
**线程语义**
- {线程安全 / 只能主线程 / 调用方同步等}
## 线程语义
**示例**
- {线程安全、只建议初始化阶段调用、或必须同线程配对等}
## 示例
```cpp
{}
```
## 相关文档
- [返回类型总览]({TypeName}.md)
- [返回模块目录](../{DirName}.md)
```
## 文风与质量要求
- 使用工程化、可审阅、可维护的描述,不写空话
- 描述职责边界,而不是复述函数名
- 线程、生命周期、资源所有权、错误条件必须明确
- 示例必须与当前 public API 一致,不允许伪代码式胡写
- 信息应放在正确层级,避免模块页和类型页职责混淆
- 禁止生成双轨入口或保留旧目录跳转
## 重构与生成流程
1. 扫描 `engine/include/XCEngine/**`
2. 建立与源码平行的 `docs/api/XCEngine/**` 目录树
3. 为每个源码目录生成 `{DirName}.md` 目录总览页
4. 为每个 public header 生成 `{TypeName}/{TypeName}.md`
5. 为每个公开方法生成 `{TypeName}/{MethodName}.md`
6. 清理旧的 lowercase kebab-case 方法页和旧的 flat header 页面
7. 删除迁移完成后的历史文档
8. 审计链接、头文件引用覆盖率和目录索引完整性
## 验收清单
- `docs/api/XCEngine/**` 与 `engine/include/XCEngine/**` 目录结构平行
- canonical 目录下没有模块级 `README.md`
- 每个类型都是一个独立文件夹
- 每个类型总览页都 `{TypeName}/{TypeName}.md`
- 方法页文件名使用原函数名或规范化运算符名
- `docs/api/main.md` 指向 `docs/api/XCEngine/XCEngine.md`
- 所有 canonical `.md` 链接可解析
- 所有 public headers 都有对应 canonical 文档入口
- 仓库中不存在第二套正式 API 文档树
- `docs/api/XCEngine/**` 与 `engine/include/XCEngine/**` 目录平行
- canonical 下没有模块级 `README.md`
- 每个 public header 都有对应类型目录
- 每个类型总览页都位于 `{TypeName}/{TypeName}.md`
- 方法页使用原函数名或规范化运算符名
- 所有链接都指向真实存在的 `.md` 页面
- 文档中明确区分接口契约、当前实现和合理推断
- 重要模块拥有必要的 guide 页
- 重要限制、stub、平台条件和线程语义都已写清