# 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