Desarrollo: Programando con Lua
by egyware on Ene.08, 2012, under Desarrollo, EGa2Dengine, Engine
Hoy dia, evitando mis quehaceres como siempre.
Me dedique a programar un ratito con Lua, no hice la gran cosa pero vamos bien encaminado.
template
class LuaType {
protected:
private:
T valor; //!< Contiene el valor que estamos Wrappeando
public:
/**
* \brief Crea una nueva variable lista, para ser pasada a Lua
*/
LuaType(const T t):valor(t) {};
/**
* \brief Extrae un valor en la pila, pero sin borrarlo
*/
LuaType(lua_State *L,int i = -1);
/**
* \brief Pone este valor en la sima de la pila de Lua
*
* \param L estado actual de Lua
*/
void pushValue(lua_State *L);
/**
* \brief Esta funcion permite recuperar el tipo original de la variable
*
* Ejemplo:
* <code>
* LuaType entero(5);
* int variable_normal = (int)entero;
* </code>
* <code>
* LuaType cadena("Hola Lua");
* char *string = (char *)cadena;
* </code>
* \return el valor de la variable del tipo de este template
*/
operator T() const {
return valor;
}
};
Primero lo que fue es crear una plantilla de una clase Wrapper, la cual me permitira extraer y colocar variables entre Lua y C++.
Usando especialización de templates (plantillas) podemos especificar como agregaremos cada tipo de variable en lua.
template<> LuaType::LuaType(lua_State *L,int i) {
if(!lua_isnumber(L,i)) {
luaL_error(L,"Argumento incorrecto");
}
valor = lua_tointeger(L,i);
};
template<> LuaType::LuaType(lua_State *L,int i) {
if(!lua_isnumber(L,i)) {
luaL_error(L,"Argumento incorrecto");
}
valor = static_cast(lua_tonumber(L,i)); // -1 top stack
};
template<> LuaType::LuaType(lua_State *L,int i) {
if(!lua_isnumber(L,i)) {
luaL_error(L,"Argumento incorrecto");
}
valor = lua_tonumber(L,i); // -1 top stack
};
template<> LuaType::LuaType(lua_State *L,int i) {
if(!lua_isstring(L,i)) {
luaL_error(L,"Argumento incorrecto");
}
valor = const_cast(lua_tostring(L,i)); // -1 top stack
};
template<> LuaType::LuaType(lua_State *L,int i) {
if(!lua_isuserdata(L,i)) {
luaL_error(L,"Argumento incorrecto");
}
valor = lua_touserdata(L,i);
};
Conviertiendo valores de la Pila de Lua a variables en C++
template<> void LuaType::pushValue(lua_State *L) {
lua_pushinteger(L,valor);
}
template<> void LuaType::pushValue(lua_State *L) {
lua_pushnumber(L,valor);
}
template<> void LuaType::pushValue(lua_State *L) {
lua_pushnumber(L,valor);
}
template<> void LuaType::pushValue(lua_State *L) {
lua_pushstring(L,valor);
}
template<> void LuaType::pushValue(lua_State *L) {
lua_pushlightuserdata(L,valor);
}
Pasando las variables a Lua.
Parece que todo este código es muy engorroso, pero sin embargo nos facilitará más adelante para programar una clase proxy (la que nos facilitará el uso de estructuras o clases definidas en C++ en Lua)
Ejemplo:
#include <cstdio>
#include <cstdlib>
#include <EGa2D/Lua/Type.h>
#include <EGa2D/Lua/Member.h>
using namespace EGa2D;
using namespace Lua;
char *script = "print(string,entero)\nfuncion(entero,string)";
int funcion(lua_State *L){
int n = lua_gettop(L); /* number of arguments */
LuaType<int> v1(L,1);
LuaType<char *> v2(L,2);
lua_settop(L,0); //borramos todo
printf("%d %s",(int)v1,(char *)v2);
return 0;
};
int main(int argc,char **argv){
lua_State *L;
L = lua_open();//abrimos lua
luaL_openlibs(L); //con todas sus bibliotecas
LuaType<int> entero = 5;
entero.pushValue(L);
lua_setglobal(L, "entero");
LuaType<char*> string = "Holaaa";
string.pushValue(L);
lua_setglobal(L, "string");
lua_pushcfunction(L,funcion);
lua_setglobal(L, "funcion");
if(luaL_dostring(L,script)){
printf("Error %s\n",lua_tostring(L, -1));
}
if(L) {
lua_gc(L, LUA_GCCOLLECT, 0); // collected garbage
lua_close(L);
}
return 0;
}
La idea de usar un Wrapper de los tipos de variables en C++ no es idea mía pero, lo vi programado en codigo que hacia lo mismo pero para una versión vieja de Lua. Así que quise probarlo y hasta el momento me ha traído algunos beneficios al programar (el código se vuelve más sencillo), y bueno espero poder terminar rápido, para poder implementarle scripting al juego y así volverlo más flexible a la hora de programar
Saludos










