游戏后台资源表安全加载方案

发表于2015-09-17
评论1 2.8k浏览

    游戏后台开发过程中,需要用到各种各样的资源表,ieg这边基本都是使用TDR组件中的ResConvert.exe程序,将excel表格转换成二进制的bin(和xml文件用于可读)。程序中会将资源bin加载到内存中,供各种逻辑来使用。

    bin资源的加载,是个很容易出错的过程,程序在内存使用的结构体,和bin存储的结构体不一致时,如果继续加载和内存copy,会导致程序出现诡异的内存问题。对于bin结构和内存结构不一致的处理,比较好的方案需要做到:

    1、不影响程序运行,类似程序crash、进程强行exit、数据只部分更新等都是不太友好的方案。

    2、能尽快知道加载失败,需要通知相关同学处理。这个对于通过ci自动更新资源很有用。

    经过一段时间的摸索,酷跑这边实现了一套资源安全加载的方案,大致如下:

    1、封装ResMgr用于存储加载后的大量资源表。

     2、封装ResMgr数组(大小为2)供逻辑上使用,称作GlobalResMgr,其内部使用index表示当前使用的ResMgr下标。例如index=0表示ResMgr[0]逻辑上当前使用,ResMgr[1]用于reload时使用。

     3、reload资源时,使用ResMgr[(index + 1) % 2]来尝试加载,如果发现有任何问题(结构不一致、数据逻辑上有问题等),打印reload错误日志。加载成功则切换index。

     4、运维部署监控,发现reload错误日志时,短信告警,通知开发去跟进处理。

     流程图如下所示:

     

     坑来了要注意!

     坑来了要注意!

     坑来了要注意!

     (重要的事情说三遍)

     为了方便逻辑使用,需要屏蔽业务逻辑层对ResMgr和NextMgr的区分使用,需要封装类似GetResMgr()来取回正确的ResMgr对象。

     1、非reload过程中。GetResMgr()返回m_ResMgr[CurIdx]对象。

     2、load过程中。从load开始到load结束的时间内,可能存在资源表交叉引用的情况,例如资源表A某字段的取值,必须来自表B,那么加载过程中会进行检查。此时A表数据来自m_ResMgr[NextIdx],B表的数据也需要来自m_ResMgr[NextIdx]。所以load过程中GetResMgr()必须返回m_ResMgr[NextIdx]对象。这就是上图“Set Reload Flag”的原因。

    GetResMgr实现:

     

     Reload函数实现:

     上述方案配合ci(hudson/jenkins)环境,能够快速让策划修改资源表,上传到svn后一键部署到测试环境,进行各种数值的调整测试。

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引