Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <cstdio>
- #include <lua.hpp>
- #include <cerrno>
- #include <cstring>
- #include <stdlib.h>
- #include <new>
- void lua_stack_dump(lua_State *L);
- #define _strify(str) #str
- #define _concat(str1, str2) str1 ## str2
- #define register_class(state, class_name, meta_table, class_table) do { \
- luaL_newmetatable(state, #class_name); \
- lua_pushvalue(state, -1); \
- lua_setfield(state, -2, "__index"); \
- luaL_setfuncs(state, class_table, 0); \
- luaL_newlib(state, meta_table); \
- /* lua_pushvalue(state, -1);*/ \
- lua_setglobal(state, #class_name); \
- lua_stack_dump(state); \
- } while(0)
- #define create_lua_object(state, class_name, obj) do { \
- void *udata__ = lua_newuserdata(state, sizeof(_concat(Lua,class_name))); \
- _concat(Lua,class_name) *obj__ = ::new (udata__) _concat(Lua,class_name)(state, obj); \
- \
- luaL_getmetatable(state, #class_name); \
- lua_setmetatable(state, -2); \
- lua_stack_dump(state); \
- } while(0)
- #define get_lua_object(state, class_name) *(_concat(Lua,class_name) **)luaL_checkudata(state, 1, #class_name)
- #define destroy_lua_object(state, class_name) do { \
- _concat(Lua, class_name) *udata__ = *(_concat(Lua, class_name) **)luaL_checkudata(state, 1, #class_name); \
- udata__->~_concat(Lua, class_name)(); \
- } while(0)
- class Test
- {
- public:
- Test() { printf("new Test!\n"); }
- ~Test() { printf("delete Test!\n"); }
- void it() { printf("TEST IT!\n"); }
- };
- class LuaTest
- {
- public:
- LuaTest(lua_State *, Test *test) : test(test) { printf("new LuaTest!\n"); }
- ~LuaTest() { printf("delete LuaTest!\n"); }
- void it() { test->it(); }
- private:
- Test *test;
- };
- static int Test_destroy(lua_State *state)
- {
- printf("Test_destroy\n");
- destroy_lua_object(state, Test);
- return 0;
- }
- static int Test_it(lua_State *state)
- {
- printf("Test_it\n");
- LuaTest *test = get_lua_object(state, Test);
- test->it();
- return 0;
- }
- static int Test_new(lua_State *state)
- {
- printf("Test_new begin\n");
- Test *newTest = new Test();
- create_lua_object(state, Test, newTest);
- printf("Test_new end\n");
- return 1;
- }
- static const luaL_Reg test_meta_methods[] = {
- { "new", &Test_new },
- { "__gc", &Test_destroy },
- { 0, 0 }
- };
- static const luaL_Reg test_methods[] = {
- { "it", &Test_it },
- { 0, 0 }
- };
- int main(int argc, char **argv)
- {
- printf("start\n");
- lua_State *state = luaL_newstate();
- luaL_openlibs(state);
- printf("call register_class\n");
- register_class(state, Test, test_meta_methods, test_methods);
- printf("open lua file\n");
- FILE *fh = fopen("luaobjtest.lua", "r");
- if(!fh)
- {
- printf("failed to open luaobjtest.lua: %s\n", strerror(errno));
- return 0;
- }
- fseek(fh, 0, SEEK_END);
- long len = ftell(fh);
- fseek(fh, 0, SEEK_SET);
- char *script = (char *)malloc(len+1);
- if(!script)
- {
- printf("failed to allocate enough memory to load luaobjtest.lua\n");
- return 0;
- }
- script[len] = 0;
- size_t ret = fread(script, 1, len, fh);
- if(ret != (size_t)len)
- {
- printf("failed to read entire luaobjtest.lua file, read %li bytes, expected %li bytes.\n", ret, len);
- return 0;
- }
- fclose(fh);
- printf("call luaL_loadstring\n");
- if(luaL_loadstring(state, script) != LUA_OK)
- {
- const char *errstr = luaL_checklstring(state, 1, 0);
- printf("failed to load luaobjtest.lua: %s\n", errstr);
- free(script);
- return 0;
- }
- printf("call lua_pcall\n");
- if(lua_pcall(state, 0, LUA_MULTRET, 0) != LUA_OK)
- {
- const char *errstr = luaL_checklstring(state, 1, 0);
- printf("failed to run luaobjtest.lua: %s\n", errstr);
- free(script);
- return 0;
- }
- printf("done!\n");
- return 0;
- }
- void lua_stack_dump(lua_State *L)
- {
- int i;
- int top = lua_gettop(L);
- for (i = 1; i <= top; i++) { /* repeat for each level */
- int t = lua_type(L, i);
- switch (t) {
- case LUA_TSTRING: /* strings */
- printf("`%s'", lua_tostring(L, i));
- break;
- case LUA_TBOOLEAN: /* booleans */
- printf(lua_toboolean(L, i) ? "true" : "false");
- break;
- case LUA_TNUMBER: /* numbers */
- printf("%g", lua_tonumber(L, i));
- break;
- default: /* other values */
- printf("%s", lua_typename(L, t));
- break;
- }
- printf(" "); /* put a separator */
- }
- printf("\n"); /* end the listing */
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement