133 lines
4.6 KiB
Markdown
133 lines
4.6 KiB
Markdown
# 项目约定规范(接口层 / 实现层)
|
||
|
||
what every programmer should know about memory
|
||
|
||
本文档用于统一本项目在 `EngineAPI`、`Components`、`Platform`、`Utilities` 等目录下的设计与编码约定,重点规范“接口层与实现层分离”。
|
||
|
||
## 1. 分层职责约定
|
||
|
||
### 1.1 EngineAPI 层(对外契约层)
|
||
|
||
- 只暴露稳定接口:强类型 ID、句柄类、对外可调用的 API。
|
||
- 不暴露内部容器与存储细节,不暴露运行时池结构。
|
||
- 允许声明行为,不实现复杂运行逻辑。
|
||
- 头文件应可被上层模块直接 include,尽量减少内部依赖。
|
||
|
||
示例:
|
||
- `Engine/EngineAPI/ScriptComponent.h`:仅定义 `script_id` 与 `script::component` 句柄。
|
||
|
||
### 1.2 Components 层(运行时实现层)
|
||
|
||
- 实现组件生命周期:`create/remove/update`。
|
||
- 管理内部存储:数组、映射、空闲队列、代数校验。
|
||
- 对外只通过 API 层句柄交互,不向外泄露内部布局。
|
||
- 允许高性能实现细节(如 `erase_unordered`、缓存表、延迟提交)。
|
||
|
||
示例:
|
||
- `Engine/Components/Script.h/.cpp`:实现脚本创建、删除、逐帧更新和注册表逻辑。
|
||
|
||
### 1.3 Platform 层(平台适配层)
|
||
|
||
- 只处理操作系统相关对象与流程(如 Win32 `HWND`、消息循环、窗口样式)。
|
||
- 上层通过抽象类型访问,不直接依赖平台原生类型。
|
||
- 平台特有分支必须受平台宏保护(如 `_WIN64`)。
|
||
|
||
### 1.4 Utilities 层(通用基础层)
|
||
|
||
- 提供与业务无关的数学、容器、IO、工具函数。
|
||
- 不耦合具体业务组件,不反向依赖高层模块。
|
||
|
||
## 2. 文件组织约定
|
||
|
||
### 2.1 命名与位置
|
||
|
||
- 对外契约放 `EngineAPI`,运行时实现放 `Components`。
|
||
- 头文件与实现文件成对组织:`Xxx.h` / `Xxx.cpp`。
|
||
- 公共依赖入口统一放在模块公共头(如 `ComponentsCommon.h`)。
|
||
|
||
### 2.2 include 方向
|
||
|
||
- 允许 `Components -> EngineAPI` 依赖。
|
||
- 禁止 `EngineAPI -> Components` 反向依赖实现细节。
|
||
- `Utilities` 不应依赖 `Components` 或 `Platform`。
|
||
|
||
### 2.3 前向声明优先
|
||
|
||
- 能前向声明时不直接 include 重头文件。
|
||
- 对外头文件避免引入不必要实现依赖,控制编译扇出。
|
||
|
||
## 3. 类型与句柄约定
|
||
|
||
### 3.1 强类型 ID
|
||
|
||
- 所有核心对象 ID 使用强类型封装(`DEFINE_TYPED_ID`)。
|
||
- 禁止在模块边界裸传 `u32` 作为对象标识。
|
||
- 必须通过 `is_valid` / `generation` 做有效性校验。
|
||
|
||
### 3.2 句柄对象
|
||
|
||
- 对外使用轻量句柄(如 `script::component`、`game_entity::entity`)。
|
||
- 句柄仅保存 ID,不保存大对象数据。
|
||
- 句柄方法可转发到实现层查询真实数据。
|
||
|
||
## 4. 生命周期与存储约定
|
||
|
||
### 4.1 创建与删除
|
||
|
||
- `create` 负责分配 ID、构造实例、建立映射。
|
||
- `remove` 必须清理映射、回收槽位、更新空闲队列。
|
||
- 必须保证删除后旧句柄不可通过代数校验。
|
||
|
||
### 4.2 映射一致性
|
||
|
||
- 使用 `id_mapping` 时必须保证:
|
||
- `id -> 索引` 映射存在且越界受保护;
|
||
- 交换删除后映射及时回填;
|
||
- 无效 ID 显式写回 `invalid_id`。
|
||
|
||
### 4.3 批处理更新
|
||
|
||
- 高频写入优先使用缓存并批量提交(如脚本修改 Transform 后统一提交)。
|
||
- 帧内缓存必须在提交后清空,避免跨帧污染。
|
||
|
||
## 5. 脚本系统专项约定
|
||
|
||
### 5.1 注册机制
|
||
|
||
- 脚本类型通过统一宏注册(`REGISTER_SCRIPT(TYPE)`)。
|
||
- 注册信息至少包含:类型名哈希、工厂函数指针。
|
||
- 编辑器模式下可额外导出脚本名列表。
|
||
|
||
### 5.2 工厂机制
|
||
|
||
- 统一使用 `script_creator` 创建脚本实例。
|
||
- 禁止外部直接 new 并绕过组件创建流程。
|
||
- 工厂函数签名保持稳定,避免跨模块 ABI 漂移。
|
||
|
||
## 6. 注释与文档约定
|
||
|
||
### 6.1 文件头注释
|
||
|
||
- 使用 `@file` + `@brief` + `@details`。
|
||
- `@details` 需说明职责边界、数据流、关键约束。
|
||
|
||
### 6.2 函数注释
|
||
|
||
- 对核心函数标注参数、返回值、副作用。
|
||
- 对平台参数表、结构体字段允许保留逐行行尾注释。
|
||
- 禁止乱码注释;统一 UTF-8 编码保存。
|
||
|
||
## 7. 可维护性与扩展性约定
|
||
|
||
- 先保证接口稳定,再演进实现细节。
|
||
- 扩展新组件时,优先复用现有 ID/句柄/生命周期模式。
|
||
- 变更跨层关系时必须先更新本规范文档与对应模块分析文档。
|
||
|
||
## 8. 变更检查清单(提交前)
|
||
|
||
- 是否保持 `EngineAPI` 与 `Components` 的边界不反转。
|
||
- 是否新增了不必要 include 或扩大了依赖扇出。
|
||
- 是否破坏了 ID 代数校验与映射一致性。
|
||
- 是否补齐了注释并确保无乱码。
|
||
- 是否与现有目录结构与命名风格一致。
|