All pastes #498211 Raw Edit

nornagon

public cpp v1 · immutable
·published 2007-05-20 07:42 UTC
rendered paste body
template<class T> class Luna {  public:    static void Register(lua_State *L) {      lua_pushcfunction(L, &Luna<T>::constructor);      lua_setglobal(L, T::className);      luaL_newmetatable(L, T::className);      lua_pushstring(L, "__gc");      lua_pushcfunction(L, &Luna<T>::gc_obj);      lua_settable(L, -3);    }    static int constructor(lua_State *L) {      T* obj = new T(L);      lua_newtable(L);      lua_pushnumber(L, 0);      T** a = (T**)lua_newuserdata(L, sizeof(T*));      *a = obj;      luaL_getmetatable(L, T::className);      lua_setmetatable(L, -2);      lua_settable(L, -3); // table[0] = obj;      for (int i = 0; T::Register[i].name; i++) {        lua_pushstring(L, T::Register[i].name);        lua_pushnumber(L, i);        lua_pushcclosure(L, &Luna<T>::thunk, 1);        lua_settable(L, -3);      }      return 1;    }    static int thunk(lua_State *L) {      int i = (int)lua_tonumber(L, lua_upvalueindex(1));      lua_pushnumber(L, 0);      lua_gettable(L, 1);      T** obj = static_cast<T**>(luaL_checkudata(L, -1, T::className));      lua_remove(L, -1);      return ((*obj)->*(T::Register[i].mfunc))(L);    }    static int gc_obj(lua_State *L) {      T** obj = static_cast<T**>(luaL_checkudata(L, -1, T::className));      delete (*obj);      return 0;    }    struct RegType {      const char *name;      int(T::*mfunc)(lua_State*);    };};class Foo {  public:    Foo(lua_State *L) {      printf("in constructor\n");    }    int foo(lua_State *L) {      printf("in foo\n");    }    ~Foo() {      printf("in destructor\n");    }    static const char className[];    static const Luna<Foo>::RegType Register[];};const char Foo::className[] = "Foo";const Luna<Foo>::RegType Foo::Register[] = {  { "foo", &Foo::foo },  { 0 }};Somewhere:Luna<Foo>::Register(L);////////////////////////////////////////////////////now from lua:local foo = Foo()foo:foo()////////////////////////////////////////////////////lua_close(L);results:in constructorin fooin destructor