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

6.6 KiB
Vendored
Raw Permalink Blame History

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.hdl_io.hdl_render.hdl_ui.hdl_range.h)。
  • 模块聚合头位于 dl/ 根目录,具体类头位于各子目录。

4. 程序入口

  • 平台入口已统一封装在 dl_main.h:根据平台自动生成 main / WinMain / android_main,用户只需实现 int Main()
  • 入口内部会调用 dl_main_init(初始化崩溃采集、解析命令行参数)与 dl_main_release

5. 全局对象约定

  • 各子系统通过 extern 全局指针暴露,命名统一 g_ 前缀:g_systemg_factoryg_gfxg_inputg_logg_audiog_luag_asg_netg_httpg_uig_physicsg_timeg_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. 基础类型与编码

  • 优先使用 intunsignedfloat;字节流用 std::byte(配合 Buffer 类)。
  • 字符串统一 UTF-8std::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. 最小入口

#include <dl.h>

int Main()
{
    // 可选:配置引擎,如 dl::Engine::GetParamRef()._useAudio = false;
    dl::Engine::Init();
    // ...
    dl::Engine::Release();
    return 0;
}

2. 进入游戏循环

#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 = Point4RectF = Position4
  • Float = floatFloatTime = float
  • 字面量后缀:_fFloat)、_ftFloatTime)、_zusize_t)。

5. 单元测试

  • 使用 googletest,测试入口为 project/dl_unit_test/test_main.cpp
  • dl_unit_test 目标开启 USE_RENDER,会链接渲染相关依赖。
  • 测试完成后可调用 g_system->Pause() 暂停观察结果(注意需在 Engine::Release() 之前)。