html跟踪修改,云风的 BLOG

lua 和 C/C++ 不同,函数调用的成本相对比较大,为脏标记添加一个 set 方法不仅增加了运行成本而且也不符合 lua 的使用惯例(增加了使用成本)。我考虑用元方法来减少成本。

我们可以给需要跟踪的 Component 创建一个叫修改集 Modify 的结构,例如,如果要跟踪 transform 的修改,就创建一个 transform.modify 的修改集。这是一个特殊的有元方法的对象。对 transform.x 的修改,写作 transform.modify.x = newx 。这是一个更符合 lua 风格的用法。置脏的过程就隐藏在元方法里面。

modify 的实现依赖三张表。

modify 对象本身,里面记录有关联的 entity id ,实际的数据区,元表。

持有修改后的数据的数据表。

元表,用来触发脏的行为。

工作起来是这样的,元表的 __index 关联到数据的数据表;元表先把 __newindex 关联在一个函数上,这个函数负责把 modify 关联的 entity id 添加到脏集合中,在第一次改写关联数据的时候触发。触发之后,修改 __newindex 元方法,直接引用和 __index 相同的数据表。

从第二次修改开始,就不再触发置脏的过程。元方法是有额外成本的,但 __index 和 __newindex 关联到表而不是函数上,性能可以有极大的改善。

注意,读取 modify 结构本身是不触发置脏流程的。通常,业务逻辑只用关心老版本(上一帧)的 transform 状态;如果它必须关心当前帧是否有人修改 transform ,也可以主动查询 transform.modify 。

然后,我们提供 modify 集合的遍历方法,在一个独立的 system 中集中处理这一帧所有的修改集。在遍历之后,我们重置脏集合以及所有的 modify 的元表中的触发器。

我们实现这样一个机制的动机在于解决场景树的更新问题。场景树上的非叶节点的 transform 的修改会导致整个子树,另外,节点还有可能更换父亲,同样会导致整个子树的变化。

但是,整个场景的结构通常是稳定不变的,只有少量节点会经常更新自己的空间位置。我需要一个相对廉价的方案来决定场景树的哪一部分需要更新重算。

下一篇 blog 我将展开这个具体案例。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值