Estoy tratando de cargar tablas de Lua a C++ pero estoy teniendo problemas para hacerlo bien. Estoy repasando la primera iteración, pero luego en la segunda llamada al lua_next falla. ¿Algunas ideas? archivoIterar a través de una tabla Lua de C++?
Lua:
archivolevel = { 1, 2, 3, }
C++ - Primero hice esto:
lua_getglobal(L, "level");
for(lua_pushnil(L); lua_next(L, 1); lua_pop(L, -2))
{
if(lua_isnumber(L, -1)) {
int i = (int)lua_tonumber(L, -1);
//use number
}
}
lua_pop(L, 1);
Luego he intentado desde el reference manual:
lua_getglobal(L, "level");
int t = 1;
lua_pushnil(L);
while(lua_next(L, t)) {
printf("%s - %s",
lua_typename(L, lua_type(L, -2)),
lua_typename(L, lua_type(L, -1)));
lua_pop(L, 1);
}
lua_pop(L, 1);
Y finalmente esto:
lua_getglobal(L, "level");
lua_pushnil(L);
lua_next(L, 1);
if(lua_isnumber(L, -1)) {
int i = (int)lua_tonumber(L, -1);
//use number fine
}
lua_pop(L, 1);
lua_next(L, 1); //crashes
etc...
Naturally L es un lua_State * y lo estoy inicializando y analizando bien el archivo.
Editar: En respuesta a la respuesta Jesse Beder yo probamos este código, con un registrador, pero todavía no puede conseguir que funcione.
Que dio este resultado:
stack size: 0
-1 is a table
-1 is now nil
-2 is now table
pred: 1
loop stuff
num: 1
stack size: 3
-3 is now table
stack size: 2
-2 is now table
Todo lo que dijo, Jesse, parece ser verdad. Pero aún no pasa a la siguiente iteración.
Edit2: He intentado copiar el código exacto en un nuevo proyecto, saltándose todas las clases de los alrededores y cosas que no se molestan en incluir aquí y allí funciona. Pero aquí no es así, y sobrevivirá a una llamada al lua_next.
Edit3: me he reducido un poco más ahora. Estoy usando hge como mi motor 2D. pongo todo el código anterior en la prueba de funcionamiento:
test(); //works
if(hge->System_Initiate())
{
test(); //fails
hge->System_Start();
}
Por lo que yo entiendo hge no hace nada con lua. Here es el código fuente de una pequeña prueba que realicé. La fuente de hge 1.81 es here.
Edit4: tamaño La pregunta se está saliendo de control, pero no se puede evitar. Este es el código más pequeño al que he podido reducirlo.
extern "C"
{
#include <lua/lua.h>
#include <lua/lualib.h>
#include <lua/lauxlib.h>
}
#include <hge\hge.h>
bool frame_func()
{
return true;
}
bool render_func()
{
return false;
}
void test()
{
lua_State *L = lua_open();
luaL_openlibs(L);
if(luaL_dofile(L, "levels.lua")) {
lua_pop(L, -1);
return;
}
lua_getglobal(L, "level");
lua_pushnil(L);
while(lua_next(L, -2)) {
if(lua_isnumber(L, -1)) {
int i = (int)lua_tonumber(L, -1);
//use number
}
lua_pop(L, 1);
}
lua_pop(L, 1);
lua_close(L);
}
int main()
{
HGE *hge = hgeCreate(HGE_VERSION);
hge->System_SetState(HGE_FRAMEFUNC, frame_func);
hge->System_SetState(HGE_RENDERFUNC, render_func);
hge->System_SetState(HGE_WINDOWED, true);
hge->System_SetState(HGE_SCREENWIDTH, 800);
hge->System_SetState(HGE_SCREENHEIGHT, 600);
hge->System_SetState(HGE_SCREENBPP, 32);
//test(); //works
if(hge->System_Initiate())
{
test(); //fails
hge->System_Start();
}
hge->Release();
return 0;
}
¿Entonces la segunda llamada a 'lua_next' se bloquea? Esto es raro ... ¿tienes alguna información de depuración en el bloqueo (como donde se bloquea exactamente)? Además, para asegurarse de que las cosas funcionen correctamente, debe registrar la clave en cada paso (también debe ser un número) y editar esta respuesta –
Agregué el valor de retorno de lua_next. No tengo ninguna información de depuración y tampoco sé cómo agregarlo ... – Jonas
Esa segunda edición es una pista: revisa la edición en mi respuesta –