Pessoas...
Estou tentando fazer um comportamento parecido com uma classe no LUA porem sem sucesso.
Basicamente tenho um vetor (x, y, z) e quero simular como se fosse uma classe assim:
No exemplo que havia feito em outro tópico eu não utiliza __index no código c++.
E lá os métodos funcionam perfeitamente. Porem que que a meta-table do lua funciona para os dois casos como descrevi acima.
Segue o código C++ que estou utilizando:
extern "C"
{
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
}
struct VEC3
{
float x,y,z;
};
static void printStack (lua_State * lua,int n)
{
int top = lua_gettop(lua);
printf( "\n**********************************"
"\nEstado da pilha na linha %d\n",n);
for (int i = 1, k= top; i <= top; i++, k--)
{
int type = lua_type(lua, i);
printf("\t%d| %8s |%d\n", -k , lua_typename(lua, type), i);
}
printf("**********************************\n\n");
}
static VEC3* getVec3(lua_State * lua, int n)
{
return *(VEC3** )luaL_checkudata(lua, n, "_luaVEC3");
}
static int onNewVec3Lua(lua_State* lua)
{
VEC3 ** udata = (VEC3 ** )lua_newuserdata(lua, sizeof(VEC3*));
VEC3* vec3 = new VEC3();
vec3->x = 0.0f;
vec3->y = 0.0f;
vec3->z = 0.0f;
*udata = new VEC3();
luaL_getmetatable(lua, "_luaVEC3");
lua_setmetatable(lua, -2);
return 1;
}
static int onMulVec3(lua_State * lua)
{
printStack(lua,__LINE__);
VEC3 * vec3 = getVec3(lua, 1);
const char* param = luaL_checkstring(lua,2);
printf("Param %s",param);
float result = vec3->x * vec3->y * vec3->z;
lua_pushnumber(lua,result);
return 1;
}
static int onDestroyVec3Lua(lua_State * lua)
{
VEC3 * vec3 = getVec3(lua, 1);
delete vec3;
return 0;
}
static int onNewIndexVec3(lua_State * lua)//escrita
{
/*
**********************************
Estado da pilha
-3| userdata |1
-2| string |2
-1| number |3
**********************************
*/
VEC3* vec3 = getVec3(lua,1);
const char* what = luaL_checkstring(lua,2);
switch(what[0])
{
case 'x':
vec3->x = luaL_checknumber(lua,3);
break;
case 'y':
vec3->y = luaL_checknumber(lua,3);
break;
case 'z':
vec3->z = luaL_checknumber(lua,3);
break;
default:
{
printf("__newindex %s inexistente!!!",what);
printStack(lua,__LINE__);
}
}
return 0;
}
static int onIndexVec3(lua_State * lua)//leitura
{
printStack(lua,__LINE__);
/*
**********************************
Estado da pilha
-2| userdata |1
-1| string |2
**********************************
*/
VEC3* vec3 = getVec3(lua,1);
const char* what = luaL_checkstring(lua,2);
switch(what[0])
{
case 'x':
lua_pushnumber(lua,vec3->x);
break;
case 'y':
lua_pushnumber(lua,vec3->y);
break;
case 'z':
lua_pushnumber(lua,vec3->z);
break;
default:
{
printf("__index %s inexistente!!!",what);
printStack(lua,__LINE__);
lua_pushnil(lua);
}
}
return 1;
}
static void registerClassVec3(lua_State * lua)
{
luaL_Reg regVec3Methods[] =
{
{ "__gc", onDestroyVec3Lua},
{ "__index", onIndexVec3},
{ "__newindex", onNewIndexVec3},
{ "mul", onMulVec3},
{ "new", onNewVec3Lua},
{ NULL, NULL}
};
luaL_newmetatable(lua, "_luaVEC3");
luaL_setfuncs(lua, regVec3Methods,0);
lua_pushvalue(lua, -1);
lua_setfield(lua, -2, "__self");
lua_setglobal(lua, "vec3");
}
int main()
{
lua_State * lua = luaL_newstate();
luaL_openlibs(lua);
registerClassVec3(lua);
printf("Executando script teste.lua (C++)\n");
int erred = luaL_dofile(lua, "teste.lua");
if (erred)
printf("Lua error: %s\n",luaL_checkstring(lua, -1));
printf("Fim ...(C++)\n");
lua_close(lua);
return 0;
}
Então pessoas...
Já tentei de varias formas mas não consegui que a meta-table funcione acessando as propriedades e seus métodos.