| 1 | /* | 
|---|
| 2 |  * Lenny Palozzi - lenny.palozzi@home.com | 
|---|
| 3 |  */ | 
|---|
| 4 |  | 
|---|
| 5 | #include <string> | 
|---|
| 6 | #include <iostream> | 
|---|
| 7 |  | 
|---|
| 8 | #include "luaincl.h" | 
|---|
| 9 |  | 
|---|
| 10 | /*extern "C" { | 
|---|
| 11 | #include <lua.h> | 
|---|
| 12 | } | 
|---|
| 13 | */ | 
|---|
| 14 | template <class T> | 
|---|
| 15 | class Luna | 
|---|
| 16 | { | 
|---|
| 17 |  | 
|---|
| 18 |  | 
|---|
| 19 |  public: | 
|---|
| 20 |    /* member function map */ | 
|---|
| 21 |    struct RegType { | 
|---|
| 22 |       const char* name; | 
|---|
| 23 |       int(T::*mfunc)(lua_State*); | 
|---|
| 24 |    }; | 
|---|
| 25 |    /* register class T */ | 
|---|
| 26 |    static void Register(lua_State* L) { | 
|---|
| 27 |       lua_pushcfunction(L, &Luna<T>::constructor); | 
|---|
| 28 |       lua_setglobal(L, T::className); | 
|---|
| 29 |  | 
|---|
| 30 |  | 
|---|
| 31 |      /* if (otag == 0) { | 
|---|
| 32 |         otag = lua_newtag(L); | 
|---|
| 33 |         lua_pushcfunction(L, &Luna<T>::gc_obj); | 
|---|
| 34 |         lua_settagmethod(L, otag, "gc"); /* tm to release objects | 
|---|
| 35 |       }*/ | 
|---|
| 36 |    } | 
|---|
| 37 |  | 
|---|
| 38 |  private: | 
|---|
| 39 |    static int otag; /* object tag */ | 
|---|
| 40 |  | 
|---|
| 41 |    /* member function dispatcher */ | 
|---|
| 42 |    static int thunk(lua_State* L) { | 
|---|
| 43 |       /* stack = closure(-1), [args...], 'self' table(1) */ | 
|---|
| 44 |       //int i = static_cast<int>(lua_tonumber(L,-1)); | 
|---|
| 45 |  | 
|---|
| 46 |        int i = lua_upvalueindex (1); | 
|---|
| 47 |  | 
|---|
| 48 |       //lua_pushnumber(L, 0); /* userdata object at index 0 */ | 
|---|
| 49 |       //lua_gettable(L, 1); | 
|---|
| 50 |       lua_rawgeti (L, 1, 0); | 
|---|
| 51 |       T* obj = (T*)(lua_touserdata(L,-1)); | 
|---|
| 52 |       lua_pop(L, 1); /* pop closure value and obj */ | 
|---|
| 53 |  | 
|---|
| 54 |         printf("FUNCTION:: %d\n", i ); | 
|---|
| 55 |         printf("OBJECT %p\n", obj); | 
|---|
| 56 |  | 
|---|
| 57 |  | 
|---|
| 58 |       return (obj->*(T::Register[i].mfunc))(L); | 
|---|
| 59 |    } | 
|---|
| 60 |  | 
|---|
| 61 |  | 
|---|
| 62 |     static int setScriptable(T* obj) | 
|---|
| 63 |      { | 
|---|
| 64 |      //return registerObject(obj); | 
|---|
| 65 |      } | 
|---|
| 66 |  | 
|---|
| 67 |    static int setScriptable(const std::string& objectName) | 
|---|
| 68 |     { | 
|---|
| 69 |    //#warning 'implement do not use' | 
|---|
| 70 |   //   return registerObject(obj); | 
|---|
| 71 |     } | 
|---|
| 72 |  | 
|---|
| 73 |    /* constructs T objects */ | 
|---|
| 74 |    static int constructor(lua_State* L) { | 
|---|
| 75 |       T* obj= new T(L); /* new T */ | 
|---|
| 76 |        printf("OBJECT CREATED %p\n", obj); | 
|---|
| 77 |  | 
|---|
| 78 |       return registerObject(obj, L); | 
|---|
| 79 |    } | 
|---|
| 80 |  | 
|---|
| 81 |  | 
|---|
| 82 |    /* releases objects */ | 
|---|
| 83 |    static int gc_obj(lua_State* L) { | 
|---|
| 84 |       T* obj = static_cast<T*>(lua_touserdata(L, -1)); | 
|---|
| 85 |       delete obj; | 
|---|
| 86 |       return 0; | 
|---|
| 87 |    } | 
|---|
| 88 |  protected: | 
|---|
| 89 |    Luna(); /* hide default constructor */ | 
|---|
| 90 |  | 
|---|
| 91 |  private: | 
|---|
| 92 |  | 
|---|
| 93 |    static int registerObject(T* obj, lua_State* L) | 
|---|
| 94 |     { | 
|---|
| 95 |       lua_newtable(L); /* new table object */ | 
|---|
| 96 |       //int  objRef = luaL_ref (L, LUA_REGISTRYINDEX); | 
|---|
| 97 |  | 
|---|
| 98 |       //lua_pushnumber(L, 0); /* userdata obj at index 0 */ | 
|---|
| 99 |       //lua_rawgeti(L, LUA_REGISTRYINDEX, objRef); | 
|---|
| 100 |       lua_pushlightuserdata(L, obj); | 
|---|
| 101 |       lua_rawseti(L,-2,0); | 
|---|
| 102 |       //lua_pushusertag(L, obj, otag); /* have gc call tm */ | 
|---|
| 103 |       //lua_settable(L, -3); | 
|---|
| 104 |       //std::cout<<"test"<<std::endl; | 
|---|
| 105 |  | 
|---|
| 106 |     /* Set up garbage collection | 
|---|
| 107 |       if(lua_getmetatable(L, objRef) != 0) | 
|---|
| 108 |        { | 
|---|
| 109 |         //std::cout<<"test"<<std::endl; | 
|---|
| 110 |         lua_pushstring (L, "__gc"); | 
|---|
| 111 |         lua_pushcfunction(L, &Luna<T>::gc_obj); | 
|---|
| 112 |         lua_settable(L,-3); | 
|---|
| 113 |        } | 
|---|
| 114 |     */ | 
|---|
| 115 |       //lua_rawgeti (L, LUA_REGISTRYINDEX, objRef); | 
|---|
| 116 |       /* register the member functions */ | 
|---|
| 117 |       for (int i=0; T::Register[i].name; i++) | 
|---|
| 118 |       { | 
|---|
| 119 |          lua_pushstring(L, T::Register[i].name); | 
|---|
| 120 |          lua_pushnumber(L, i); | 
|---|
| 121 |          lua_pushcclosure(L, &Luna<T>::thunk, 1); | 
|---|
| 122 |          lua_settable(L,-3); | 
|---|
| 123 |       } | 
|---|
| 124 |       return 1; /* return the table object */ | 
|---|
| 125 | } | 
|---|
| 126 |  | 
|---|
| 127 |  | 
|---|
| 128 | }; | 
|---|
| 129 | template <class T> | 
|---|
| 130 | int Luna<T>::otag = 0; | 
|---|