最近在做副本的脚本复用机制,之前想到的是用fork 这种方式从副本的静态数据里的state下得到一个一模一样的state,从此一来省掉 open 基础的脚本库和脚本文件的操作。 实现这种方案的时候发现能省的操作还真少,网上提到的lua rings这个库事实上只能给新建了个带 基础库 的new state ,并不是和已有state 一样的clone , 脚本环境初始化的操作还是得重新做。 转头一想这种clone 的state 里面实际只是对变量有分开存取的需求,只需要一个类似_G的数据包,在每个副本对应一个,宿主语言切进脚本前,能对当前的环境做出和副本对应的设置就行。按这种思路实现一个脚本变量环境管理器,只用在C这边对接口调用的时候管理一下包及其流水号映射关系。
实现上面提到的东西比较简单,这里就不详细说了,重点说一下访问脚本定义的变量。 在脚本里面定义的副本变量包含很多 表嵌套的格式,这种方式访问起来颇为麻烦,如果按标准的lua api接口,得一层层得提取出表来。 而luatinker::get 和 set 很不幸的是只能读取全局的一级变量,对于这种 xxx.ooo.1 的变量无法支持。没办法自己写一个吧,因为需要支持类变量,所以还得用到 luatinker的push 和pop 函数(这两个函数的作用是把userdata类型的传递加入一个tinker的壳,好在以后的push和pop时能找得到对应的类型做安全检查及其注册到metatable里的元方法)。具体实现如下
写入
template<typename T>
void setsub(lua_State* L, const char* name, T object)
{
std::string strSrc(name);
if(strSrc.empty())
return ;
std: