Files
XCEngine/docs/api-skill.md

398 lines
9.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# XCEngine API Documentation Skill
## 目标
本规范用于维护 `XCEngine` 的唯一正式 API 文档树,并约束后续所有模块级重构的工作方式。
硬性要求:
1. `docs/api/XCEngine/**` 必须与 `engine/include/XCEngine/**` 保持平行。
2. canonical API 文档只保留一套;迁移完成后必须删除旧目录与旧入口。
3. 每个 public header 对应一个独立文档目录,每个类型页都使用 `{TypeName}/{TypeName}.md`
4. 方法页优先使用源码中的原始函数名;不要改成 kebab-case、全小写或其它再命名形式。
5. API 文档必须以源码、实现、测试和真实调用点为依据,禁止只根据名字猜测行为。
## Canonical 目录结构
```text
docs/api/
├── main.md
├── XCEngine/
│ ├── XCEngine.md
│ ├── Debug/
│ │ ├── Debug.md
│ │ ├── Logger/
│ │ │ ├── Logger.md
│ │ │ ├── Get.md
│ │ │ ├── Initialize.md
│ │ │ └── Log.md
│ │ └── RenderDocCapture/
│ │ ├── RenderDocCapture.md
│ │ └── BeginCapture.md
│ └── ...
├── _guides/
│ └── Debug/
└── _meta/
```
说明:
- `docs/api/XCEngine/**` 是唯一 canonical API 树。
- `docs/api/_guides/**` 用于概念、教程、设计理念和工作流说明,不是第二套 API 树。
- `README.md` 不用于 canonical 模块索引页;模块索引页统一使用 `{DirName}.md`
## 强制命名规则
### 1. 目录索引页
- 根索引页:`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/RHI/D3D12/D3D12.md`
### 2. 类型目录
- 每个 public header 对应一个独立文件夹。
- 文件夹名必须与 header stem 或主要类型名一致。
- 保留源码中的大小写,不做风格改写。
示例:
- `docs/api/XCEngine/Debug/Logger/`
- `docs/api/XCEngine/Core/Asset/ResourceManager/`
- `docs/api/XCEngine/RHI/D3D12/D3D12Device/`
### 3. 类型总览页
- 固定为 `{TypeName}/{TypeName}.md`
- 不允许把类型总览页直接平铺在模块目录中
### 4. 方法详情页
- 方法页放在所属类型目录内。
- 文件名优先使用原函数名。
- 重载共享同一页,在页内按签名分节说明。
示例:
- `Get.md`
- `Initialize.md`
- `SetCaptureFilePath.md`
- `LoadSceneAsync.md`
### 5. 特殊命名
- 构造函数:`Constructor.md`
- 析构函数:`Destructor.md`
- 运算符使用可读的 PascalCase 名称
建议映射:
- `operator=` -> `OperatorAssign.md`
- `operator+=` -> `OperatorPlusAssign.md`
- `operator[]` -> `OperatorSubscript.md`
- `operator()` -> `OperatorCall.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. 模块页 / 子模块页
负责:
- 说明模块职责、边界和典型使用场景
- 列出子目录与 public headers
- 给出与相邻模块的关系
- 链接相关 guide 页
不负责:
- 展开所有方法细节
- 重复 header 全量声明
### 2. 类型页
必须包含:
- 命名空间
- 类型分类
- 头文件
- 角色概述
- 生命周期
- 线程语义
- 所有权 / 资源管理方式
- 当前实现限制
- 与相关方法页、guide 页的跳转
如果类型是枚举或结构体,还应补充:
- 字段或枚举值说明
- 值之间的语义关系
- 典型使用方式
### 3. 方法页
必须包含:
- 准确签名
- 调用目的
- 前置条件
- 参数说明
- 返回值说明
- 副作用
- 线程语义
- 失败路径或 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}
**命名空间**: `{Namespace}`
**类型**: `module` / `submodule` / `module-root`
**描述**: {一句话说明当前目录职责}
## 概述
{解释职责边界、典型场景和相邻模块关系}
## 设计要点
- {要点 1}
- {要点 2}
## 头文件
- [TypeA](TypeA/TypeA.md) - `TypeA.h`
- [TypeB](TypeB/TypeB.md) - `TypeB.h`
## 相关指南
- [GuideA](../../_guides/.../GuideA.md)
```
### 2. 类型页模板
```markdown
# {TypeName}
**命名空间**: `{Namespace}`
**类型**: `class` / `class (abstract)` / `class (singleton)` / `struct` / `enum class`
**头文件**: `XCEngine/.../{Header}.h`
**描述**: {一句话说明}
## 概述
{说明角色、状态、边界、典型使用方式}
## 生命周期
- {初始化与销毁方式}
## 线程语义
- {线程安全说明}
## 公开成员
| 成员 | 说明 |
|------|------|
| [Initialize](Initialize.md) | {说明} |
| [Shutdown](Shutdown.md) | {说明} |
```
### 3. 方法页模板
```markdown
# {TypeName}::{MethodName}
{一句话说明方法职责}
```cpp
{完整签名}
```
## 行为说明
{说明前置条件、后置状态、副作用和当前实现细节}
## 参数
- `param` - {描述}
## 返回值
- `{Type}` - {描述}
## 线程语义
- {线程安全、只建议初始化阶段调用、或必须同线程配对等}
## 示例
```cpp
{}
```
```
## 验收清单
- `docs/api/XCEngine/**` 与 `engine/include/XCEngine/**` 目录平行
- canonical 树下没有模块级 `README.md`
- 每个 public header 都有对应类型目录
- 每个类型总览页都位于 `{TypeName}/{TypeName}.md`
- 方法页使用原函数名或规范化运算符名
- 所有链接都指向真实存在的 `.md` 页面
- 文档中明确区分接口契约、当前实现和合理推断
- 重要模块拥有必要的 guide 页
- 重要限制、stub、平台条件和线程语义都已写清