/* * Lenny Palozzi - lenny.palozzi@home.com */ #include #include #include "luaincl.h" /*extern "C" { #include } */ template class Luna { public: /* member function map */ struct RegType { const char* name; int(T::*mfunc)(lua_State*); }; /* register class T */ static void Register(lua_State* L) { lua_pushcfunction(L, &Luna::constructor); lua_setglobal(L, T::className); /* if (otag == 0) { otag = lua_newtag(L); lua_pushcfunction(L, &Luna::gc_obj); lua_settagmethod(L, otag, "gc"); /* tm to release objects }*/ } private: static int otag; /* object tag */ /* member function dispatcher */ static int thunk(lua_State* L) { /* stack = closure(-1), [args...], 'self' table(1) */ //int i = static_cast(lua_tonumber(L,-1)); int i = lua_upvalueindex (1); //lua_pushnumber(L, 0); /* userdata object at index 0 */ //lua_gettable(L, 1); lua_rawgeti (L, 1, 0); T* obj = (T*)(lua_touserdata(L,-1)); lua_pop(L, 1); /* pop closure value and obj */ printf("FUNCTION:: %d\n", i ); printf("OBJECT %p\n", obj); return (obj->*(T::Register[i].mfunc))(L); } static int setScriptable(T* obj) { //return registerObject(obj); } static int setScriptable(const std::string& objectName) { #warning 'implement do not use' // return registerObject(obj); } /* constructs T objects */ static int constructor(lua_State* L) { T* obj= new T(L); /* new T */ printf("OBJECT CREATED %p\n", obj); return registerObject(obj, L); } /* releases objects */ static int gc_obj(lua_State* L) { T* obj = static_cast(lua_touserdata(L, -1)); delete obj; return 0; } protected: Luna(); /* hide default constructor */ private: static int registerObject(T* obj, lua_State* L) { lua_newtable(L); /* new table object */ //int objRef = luaL_ref (L, LUA_REGISTRYINDEX); //lua_pushnumber(L, 0); /* userdata obj at index 0 */ //lua_rawgeti(L, LUA_REGISTRYINDEX, objRef); lua_pushlightuserdata(L, obj); lua_rawseti(L,-2,0); //lua_pushusertag(L, obj, otag); /* have gc call tm */ //lua_settable(L, -3); //std::cout<<"test"<::gc_obj); lua_settable(L,-3); } */ //lua_rawgeti (L, LUA_REGISTRYINDEX, objRef); /* register the member functions */ for (int i=0; T::Register[i].name; i++) { lua_pushstring(L, T::Register[i].name); lua_pushnumber(L, i); lua_pushcclosure(L, &Luna::thunk, 1); lua_settable(L,-3); } return 1; /* return the table object */ } }; template int Luna::otag = 0;