Files
2026-09-16 14:07:40 +08:00

157 lines
6.6 KiB
Markdown
Vendored
Raw Permalink 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.
# AI Skilldl 引擎开发指南
本文档面向开发者与 AI,记录 dl 引擎的整体架构、代码风格、通用易错点与常规使用方法,便于快速上手并保持一致。
## 一、整体架构
### 1. 项目定位
dldrawing 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()` 之前)。