我使用LUA作为脚本文件,生成一些数据,C ++调用特定的LUA函数,获取返回表(一个数据数组),并获取其中的所有数据,然后呈现内容。
当c ++获取表时,会发生问题。我在c ++中使用了包装结构来保存LUA表。结构以向量形式返回。当将结构emplace_back返回到向量时,一切都很好。在每个数据(正如我所说的,LUA函数返回一个数据数组)被emplace_back到向量之后,函数返回。在函数外部,我再次检查,这一次,在某些数据中缺少“大小”字段。
困难的部分是,此错误偶尔发生。无法预测,因此很难追踪。
其中“ size”字段适合的C ++代码:
int TimeLine::NextRandom(std::vector<RandomParam>& container)
{
//check bake table first
if(!_bakedTimeline.IsNil()) //_backedTimeline is a LuaTable
{
LuaTable ret;
if(_bakedTimeline.GetTable(_currentPtr, ret))
{
int retLength = ret.GetArraySize();
for(int i = 0; i < retLength; i++)
{
LuaTable item;
if(ret.GetTable(i + 1, item))
{
container.emplace_back(CreateRandomParamFromLuaTable(item)); //CreateRandomParamFromLuaTable is just some method create a RandomParam struct from a LuaTable
if(container.back().type == 0)
{
double size;
container.back().luaParam.GetReal("size", size, 999999);
if(size > 99999)
{
//no size, this log never printed out
CCLOG("[SIZE_PROBLEM]TimeLine::NextRandom ----> find no size");
}
}
}
}
return retLength;
}
}
....
缺少大小的c ++代码:
int Game::_ExecuteCurrentTimeline()
{
int delta = _timeLine->NextRandom(_objects);
for(int i = 0; i < delta; i++)
{
if(_objects[_objects.size() - 1 - i].type == 0)
{
double size;
_objects[_objects.size() - 1 - i].luaParam.GetReal("size", size, 999999);
if(size > 99999)
{
//no size , occasionally, this log is printed out
CCLOG("[SIZE_PROBLEM]GAME::_ExecuteCurrentTimeline ----> find no size");
}
}
}
return delta;
}
结构RandomParam:
struct RandomStarParam
{
int type;
...
LuaTable luaParam;
RandomStarParam(){}
RandomStarParam(const RandomStarParam& him) noexcept:type(him.type), luaParam(him.luaParam)
{
}
RandomStarParam(RandomStarParam&& him) noexcept:type(him.type), luaParam(std::move(him.luaParam))
{
}
}
供参考,LuaTable的move构造函数和GetReal函数
LuaTable::LuaTable(LuaTable&& lua) noexcept
{
if(lua._ownner)
{
_vm = lua._vm; //_vm field is a wrapper for lua state
_ref = lua._ref; //_ref field is the index of table in LUA_REGISTRYINDEX
if(_vm)
_vm->AddRef();
_ownner = true;
lua._ownner = false;
}
else
{
_vm = lua._vm;
_ref = lua._ref;
if(_vm)
_vm->AddRef();
_ownner = false;
}
}
bool LuaTable::GetReal(const char* field, double& val, double defval)
{
if(!IsNil())
{
Push();
lua_pushstring(_vm->GetLuaState(), field);
lua_getintable;
if (lua_isnumber(_vm->GetLuaState(), -1))
{
val = lua_tonumber(_vm->GetLuaState(), -1);
lua_pop(_vm->GetLuaState(), 2);
return true;
}
lua_pop(_vm->GetLuaState(), 2);
}
val = defval;
return false;
}