Я использую LUA в качестве файла сценария, чтобы сгенерировать некоторые данные, C ++ вызывает определенную функцию LUA, получает таблицу возврата (один массив данных) и получает все данные в ней, а затем визуализирует содержимое.
Проблема возникает, когда c ++ получает таблицу. Я использовал упаковочную структуру в C ++ для хранения таблицы LUA. структуры возвращаются в векторе. Когда структура emplace_back к вектору, все просто отлично. После того, как все данные (как я уже сказал, функция LUA возвращает массив данных) emplace_back к вектору, функция возвращает. А вне функции я проверил еще раз, на этот раз в некоторых данных отсутствует поле «размер».
Трудная часть, эта ошибка случается иногда. Не предсказуемо, поэтому очень трудно отследить.
C ++ код, где поле "size" отлично:
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 и функция 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;
}