HEngine
  • 引擎编译
  • 未来工作
  • 使用文档
    • 代码规范
    • Shader规范
    • config 配置
  • Python脚本系统
    • 技术分析
    • 使用api
  • Cpp脚本系统
    • 技术分析
  • 技术文档 & 心得体会
    • 数学
      • 坐标系、UV与深度范围
      • 行主序 与 列主序
    • 路径管理
    • 构建系统
    • 自定义资源格式
    • UI
      • undo/redo
      • 分辨率处理
    • ECS 系统
    • 插件系统
    • 数学库
    • Ref Counted
    • 音频
    • ChatGPT
    • Mesh、Vertex 等组织关系
    • 编辑器热更新方案
    • Profile
    • NLP
    • RenderDoc
    • CodeGen与反射系统
    • 安装包
    • 物理引擎
      • PhysX集成
      • Bullet集成
    • 动画
  • 图形后端
    • 坐标系差异
    • Feature差异
    • RHI 封装
    • Shader与Constant Buffer
    • DX12
    • Vulkan
    • Render Graph
    • 渲染整体架构
  • 图形Feature
    • 毛发
    • 鼠标拾取
    • 实例化渲染
  • Shader
    • Shader 交叉编译
    • Shader Toy
    • Shader 热更新
    • PBR
  • 打包
    • 打包
  • Bug 记录 & 解决过程
    • 闪退记录汇总
    • 导入图片显示混乱
    • D3D下glfw+imgui失效
  • 其他资料
    • 总结集合
Powered by GitBook
On this page
  • 使用
  • 原理分析
  1. 技术文档 & 心得体会

CodeGen与反射系统

反射系统主要参考:

https://github.com/AustinBrunkHorst/CPP-Reflection

https://github.com/BoomingTech/Piccolo

核心是做codegen,codegen的内容除了有反射,还有序列化反序列化、py脚本api的注册。

使用

反射有别于ue的保守式标记,我们可以标记 WhiteListFields,一些示例:

REFLECTION_TYPE(BaseTest)
CLASS(BaseTest, Fields)
{
    REFLECTION_BODY(BaseTest);

public:
    int               m_int;
    std::vector<int>  m_int_vector;
};

REFLECTION_TYPE(Test1)
CLASS(Test1 : public BaseTest, WhiteListFields)
{
    REFLECTION_BODY(Test1);

public:
    PROPERTY(Enable)
    char m_char;
};

REFLECTION_TYPE(Test2)
CLASS(Test2 : public BaseTest, , Fields)
{
    REFLECTION_BODY(Test2);

public:
    std::vector<BaseTest> m_test_base_array;
};
REFLECTION_TYPE(SoundComponent)
CLASS(SoundComponent : public ComponentBase, Fields)
{
    REFLECTION_COMPONENT_BODY(SoundComponent);
public:
    SoundComponent() = default;
    SoundComponent(const SoundComponent&) = default;
    SoundComponent(const std::string& path)
        : Path(path)
    {}

    std::string Path = "None";
    bool Play;

    PROPERTY(Disable)
    FMOD::Sound* Sound;
    PROPERTY(Disable)
    FMOD::Channel* Channel = nullptr;
};
REGISTER_COMPONENT_TYPE(SoundComponent)

可以用 PROPERTY(Disable) 标注无需加入codegen流程的变量;当然与之对应的用 WhiteListFields 标记的时候也可以用 PROPERTY(Enable) 单独把一个变量加入流程中。

原理分析

  1. cmake编译HEngineParser,生成 HEngineParser.exe

  2. cmake阶段收集引擎头文件。核心位于 Cmake/HEngineParser.cmake 中,用 configure_file 指令把这些头文件路径写入到一个json中。这个json最终输出在 Engine\Binaries\Win64\Programs\HEngineParser\precompile.json (需要注意的是,我们需要额外加入一些头文件,例如ThirdParty/glm/glm/glm.hpp,否则libclang不知道这是一个类型) 我们需要定义 CPP_CODE_GEN 才行。例如 cmake -B build -DCPP_CODE_GEN=ON

  3. 这个json作为参数传给 HEngineParser,HEngineParser使用libclang去解析这些头文件,获取到相应的信息,再用mustache去根据这些信息做codegen。这些信息主要指的是被我们的反射宏包裹的类型。

PreviousRenderDocNext安装包

Last updated 2 years ago