【ZeloEngine】反射系统填坑小结

【ZeloEngine】反射系统填坑小结

总结一下反射系统,下称ZHT

ZHT架构/数据流图
架构
今天是入行两周年,本想写个入行小结,想想还是踏实点把坑填完,写个DevLog

本文接续之前一篇文章的原理描述,主要讲讲开发后的反思

另外说明,ZHT当然是下班时间开发的,所以进度会慢很多,好在能每天坚持写一点,代码也就攒起来了

【ZeloEngine】重写反射和对象系统_zoloypzuo的博客-CSDN博客

Demo

cyclone

生成代码位于__ZHT/

zoloypzuo/cyclone: 《游戏物理引擎开发》源码魔改

ogre

编译通过,ZHT运行5.5s

PropertySheet

PropertySheet,类似Unity的MonoBehavior,自动在Inspector上画界面编辑数据
在这里插入图片描述

特性列表

  1. 对标Swig,生成Lua脚本绑定
  2. 对标Moc,UBT的元信息标记机制meta.cs
  3. 对标C#,完全自动反射,生成RTTR绑定
  4. 生成imgui界面
  5. 丰富完整的C++信息收集,可以扩展后端,是通用的代码生成方案

语法特性

支持

  1. 全局函数
  2. 全局变量
  3. namespace
  4. struct/class // 统一为class
  5. enum
  6. 嵌套的class和enum

不支持

  1. C++模板 // 需要实例化
  2. C# property // 没必要

meta.cs不支持 // 用静态成员代替,因为C#语法不支持全局

  1. 全局函数
  2. 全局变量

特色:meta.cs

理解moc:是一种标记语言

moc的缺点

  1. moc标记,都是宏,缺乏IDE支持,重构,报错等
  2. moc标记,淹没在大量moc编译器不关心的代码中
  3. 不支持给第三方库打moc标记

meta.cs解决了以上问题

  1. 标记是C#语法,可以报错
  2. 标记与源码分离,容易统计分析和定位
  3. 支持第三方库

UBT vs ZHT
在这里插入图片描述

应用

  1. PropertySheet,配置表编辑器
  2. 替代Ver1的手工Lua脚本绑定,写脚本胶水从此无摩擦
  3. C++反射,可以走RTTR反射来调用了,更加动态的C++
  4. 对象模型中的其他子模块,GC,序列化,都依赖于反射系统

懒人模式

对标C#,最好不要写标记,正常写C++,然后就自带反射和导出Lua

这是目前努力的方向

这样做的好处

  1. 把ZHT隐藏起来,用户不需要操心怎么标记导出反射
  2. 便于单元测试,不需要费心维护测试用例

单元测试

由于程序的特点+懒人模式,可以很低成本地scale测试用例,来保证程序的健壮性

测试用例

  1. 重写Ver1的Lua驱动配置文件绑定,保证功能一致
  2. UHT,QtMoc,以及cocos的binding-generator,一些非真实的test-case,主要是覆盖C++语法
  3. 真实的项目:cyclone,ogre

如果能完整地反射一个ogre体量的引擎,基本ZHT就比较可用了

反思

  1. 基本思路清楚,快速搭建出第一个能跑的原型,只花了一周
  2. 实际填坑,实现规格(spec)以及自动化到铺量可用,花了一个月,细节很多
  3. 反复问自己几个问题
    • 是什么?解决了什么问题?
    • 重点难点是什么?
    • 竞品方案对比

ZHT是什么?

  1. 解析C++代码结构到反射信息(中间表示),然后再生成多种目标代码
  2. 使用C#为C++标记上元信息,为ZHT和游戏/编辑器运行时提供元信息

重点和难点是什么?

  1. 理解源语言,也就是C++编译器
  2. 理解目标语言
  3. 代码生成是一种优化方法/自动化方法,要切实地自动化

对于反射系统而言,我们在乎声明,结构,类型,不在乎函数体里的计算代码

这块把重点放在了C++上,增进对C++编译器的理解对我目前的作用很大

竞品方案

  • Lua脚本绑定
    • 对标Swig,Swig的问题是黑盒不好控制,但是C++特性支持丰富
    • cocos的binding-generator
  • moc,UBT

奇怪的case清单

其实每个代码库都有自己的编程风格,ogre,ois,cyclone已经算是非常规范的OOP代码库了,至少保证内部风格统一

ZHT也主要是为我自己服务,所以不必去兼容所有库的写法,只是利用其他库作为测试用例来增强健壮性

不处理template

template<typename T, size_t Alignment>
struct AlignedAllocator : public std::allocator<T>

两个类互相依赖,ctor可以定义在类外面,问题是这样就需要去找这个类的引用,ZHT目前是直接从栈顶拿一个class,懒得搞搜索了,corner case

// these functions could not be defined within the class definition of class
// Radian because they required class Degree to be defined
inline Radian::Radian ( const Degree& d ) : mRad(d.valueRadians()) {}

指针不处理

std::vector<Plane>* planes;

const需要只读,目前先忽略const,建议封装成get函数

const OIS_ERROR eType;
const int eLine;
const MouseState& state;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值