157 lines
6.6 KiB
Markdown
Vendored
157 lines
6.6 KiB
Markdown
Vendored
# AI Skill:dl 引擎开发指南
|
||
|
||
本文档面向开发者与 AI,记录 dl 引擎的整体架构、代码风格、通用易错点与常规使用方法,便于快速上手并保持一致。
|
||
|
||
## 一、整体架构
|
||
|
||
### 1. 项目定位
|
||
dl(drawing library)是基于 C++23 的开发框架/游戏引擎,命名空间统一为 `dl`,集成了大量 C/C++ 开源库。
|
||
|
||
### 2. 目录结构
|
||
|
||
| 目录 | 职责 |
|
||
| :--- | :--- |
|
||
| `base/` | 基础类型与容器(Array、String、Color、Vector 等) |
|
||
| `io/` | 输入输出(日志、文件、网络、JSON/XML/XLSX、数据库) |
|
||
| `math/` | 数学与物理(Mesh、Guid、Physics) |
|
||
| `memory/` | 内存管理(Buffer、加密、流、对象复用) |
|
||
| `misc/` | 杂项(Mod、JsonConfig、Tilemap、AStar) |
|
||
| `render/` | 渲染(Graphics、Factory、Action、Animation、粒子) |
|
||
| `script/` | 脚本(Lua、AngelScript) |
|
||
| `system/` | 系统(Engine、System 窗口、音频、线程、硬件信息) |
|
||
| `tool/` | 工具(DebugInfo、Archiver 等) |
|
||
| `ui/` | UI 系统(Manager、Scene) |
|
||
| `vk/` | Vulkan 渲染底层 |
|
||
|
||
### 3. 头文件组织
|
||
- 总头文件为 `dl.h`,也可按模块单独包含(`dl_type.h`、`dl_io.h`、`dl_render.h`、`dl_ui.h`、`dl_range.h`)。
|
||
- 模块聚合头位于 `dl/` 根目录,具体类头位于各子目录。
|
||
|
||
### 4. 程序入口
|
||
- 平台入口已统一封装在 `dl_main.h`:根据平台自动生成 `main` / `WinMain` / `android_main`,用户只需实现 `int Main()`。
|
||
- 入口内部会调用 `dl_main_init`(初始化崩溃采集、解析命令行参数)与 `dl_main_release`。
|
||
|
||
### 5. 全局对象约定
|
||
- 各子系统通过 `extern` 全局**指针**暴露,命名统一 `g_` 前缀:`g_system`、`g_factory`、`g_gfx`、`g_input`、`g_log`、`g_audio`、`g_lua`、`g_as`、`g_net`、`g_http`、`g_ui`、`g_physics`、`g_time`、`g_thread` 等。
|
||
- 用指针而非全局对象,是为了控制生命周期、不占用全局空间。
|
||
- 这些对象的生命周期由 `Engine::Init` / `Engine::Release` 统一管理,`Release` 之后不可再访问。
|
||
|
||
## 二、代码风格
|
||
|
||
### 1. 命名规范
|
||
- 全局函数:小写 + 下划线,如 `calc_n`。
|
||
- 非通用型全局函数:仅首字母小写,如 `createQuad`。
|
||
- `dl` 命名空间内的全局函数:大写开头,如 `Math::SetSeed`。
|
||
- 宏:无命名空间,必须 `DL_` 开头防止冲突。
|
||
- 类/类型:首字母大写;缩写只首字母大写(如 `UI`);除 `dl` 外的其他命名空间也首字母大写。
|
||
- 成员变量:下划线前缀,如 `_mulSpr`。
|
||
|
||
### 2. 常用语义区分
|
||
- `init`:不需要外部资源的初始化;`load`:需要使用外部资源的初始化。
|
||
- `Add`:添加一个**已有**对象,而非创建。
|
||
- `func`:回调函数;`fn`:局部 lambda。
|
||
- `Refresh`:刷新(不保存数据);`Set`:设置。
|
||
- `Update`:时间片逻辑;`Render`:绘制;`Run`:前二者合一(一般不使用)。
|
||
- `Reset`:重置;`Delete`:删除(不可逆);`Clear`:清除;`Release`:释放。
|
||
- `Clone`:新建元素复制;`Copy`:把属性复制到已有元素。
|
||
- `GetBuffer`:返回字节流;`GetData`:返回实际类型指针。
|
||
- 多个元素不加复数,用 `mul` 修饰(如 `_mulSpr`,可为数组或链表)。
|
||
|
||
### 3. 命名约定补充
|
||
- 加减乘除:`add` / `sub` / `mul` / `div`。
|
||
- 冒号 `:` 用作特殊对象的隐含命名,如默认精灵/默认演员名为 `":"`。
|
||
- 资源名中 `/` 不能作文件名,用 `.` 替换。
|
||
|
||
### 4. 基础类型与编码
|
||
- 优先使用 `int`、`unsigned`、`float`;字节流用 `std::byte`(配合 `Buffer` 类)。
|
||
- 字符串统一 UTF-8(`std::string`),需要拆分字符时再转 UTF-32(用 iconv)。
|
||
- 文件优先 `fstream`;接口统一 UTF-8。
|
||
- 优先使用枚举类(`enum class`)。
|
||
|
||
### 5. 类成员顺序
|
||
嵌套类 → 构造函数 → 操作符重载 → 主要函数 → Set 函数 → Get 函数 → 功能性函数 → 析构函数 → 私有成员 → 私有函数。
|
||
|
||
### 6. 对象创建与释放
|
||
- 特殊对象通过 `g_factory` 创建,用户层一般情况不出现 `new`。
|
||
|
||
## 三、通用易错点
|
||
|
||
### 1. 生命周期顺序
|
||
`Engine::Release()` 会释放(`delete`)所有 `g_` 全局对象。任何对全局对象的操作(如 `g_system->Pause()`)必须在 `Release()` **之前**,否则出现悬空指针。
|
||
|
||
### 2. 越界判断语义(易搞反)
|
||
- `IsOutRange` 越界返回 **true**。
|
||
- `CheckRange` 越界返回 **false**。
|
||
|
||
两者语义相反,注意区分。
|
||
|
||
### 3. init 与 load 的区别
|
||
`init` 不依赖外部资源,`load` 依赖外部资源。命名用错会导致对资源加载时机的误解。
|
||
|
||
### 4. 全局对象是裸指针
|
||
`g_system` 等是裸指针而非引用,使用前需确认已初始化;`Release` 后立即失效。
|
||
|
||
### 5. 资源路径与命名
|
||
- 资源名中的 `/` 需用 `.` 替换(`/` 不能作文件名)。
|
||
- `Factory::SetPath` 只能在 `System::Start` 之前调用一次。
|
||
|
||
## 四、常规使用方法
|
||
|
||
### 1. 最小入口
|
||
```cpp
|
||
#include <dl.h>
|
||
|
||
int Main()
|
||
{
|
||
// 可选:配置引擎,如 dl::Engine::GetParamRef()._useAudio = false;
|
||
dl::Engine::Init();
|
||
// ...
|
||
dl::Engine::Release();
|
||
return 0;
|
||
}
|
||
```
|
||
|
||
### 2. 进入游戏循环
|
||
```cpp
|
||
#include <dl.h>
|
||
|
||
void OnInit() { /* 初始化资源 */ }
|
||
void OnRun() { /* 每帧逻辑 */ }
|
||
|
||
int Main()
|
||
{
|
||
dl::Engine::Init();
|
||
dl::g_system->SetFuncInit(OnInit);
|
||
dl::g_system->SetFuncRun(OnRun);
|
||
dl::g_system->Start(); // 创建窗口并进入游戏循环
|
||
dl::Engine::Release();
|
||
return 0;
|
||
}
|
||
```
|
||
|
||
### 3. 常用全局对象
|
||
|
||
| 对象 | 用途 |
|
||
| :--- | :--- |
|
||
| `g_system` | 窗口、游戏循环、暂停、剪贴板、截屏 |
|
||
| `g_factory` | 资源工厂(精灵/模型/字体等的加载与创建) |
|
||
| `g_gfx` | 绘图 |
|
||
| `g_input` | 输入(鼠标/键盘) |
|
||
| `g_log` | 日志 |
|
||
| `g_audio` / `g_midi` | 音频 / MIDI |
|
||
| `g_lua` / `g_as` | Lua / AngelScript 脚本 |
|
||
| `g_net` / `g_http` | 网络 / HTTP |
|
||
| `g_physics` | 物理 |
|
||
| `g_time` | 时间 |
|
||
|
||
### 4. 基础类型速查
|
||
- `Point` = `Array<int,2>`,`Size` = `Array<unsigned,2>`,`Position` = `Array<float,2>`,`Color` = `Array<float,4>`(rgba)。
|
||
- `Rect` = `Point4`,`RectF` = `Position4`。
|
||
- `Float = float`,`FloatTime = float`。
|
||
- 字面量后缀:`_f`(Float)、`_ft`(FloatTime)、`_zu`(size_t)。
|
||
|
||
### 5. 单元测试
|
||
- 使用 googletest,测试入口为 `project/dl_unit_test/test_main.cpp`。
|
||
- `dl_unit_test` 目标开启 `USE_RENDER`,会链接渲染相关依赖。
|
||
- 测试完成后可调用 `g_system->Pause()` 暂停观察结果(注意需在 `Engine::Release()` 之前)。
|