| [7702] | 1 | /* | 
|---|
 | 2 |  * Lenny Palozzi - lenny.palozzi@home.com | 
|---|
 | 3 |  */ | 
|---|
 | 4 |  | 
|---|
 | 5 | #include <string> | 
|---|
| [7703] | 6 | #include <iostream> | 
|---|
| [7702] | 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 */ | 
|---|
| [7820] | 21 |    struct RegType { | 
|---|
 | 22 |       const char* name; | 
|---|
| [7702] | 23 |       int(T::*mfunc)(lua_State*); | 
|---|
| [7820] | 24 |    }; | 
|---|
| [7702] | 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 |  | 
|---|
| [7808] | 30 |  | 
|---|
| [7702] | 31 |      /* if (otag == 0) { | 
|---|
| [7820] | 32 |         otag = lua_newtag(L); | 
|---|
 | 33 |         lua_pushcfunction(L, &Luna<T>::gc_obj); | 
|---|
 | 34 |         lua_settagmethod(L, otag, "gc"); /* tm to release objects | 
|---|
| [7702] | 35 |       }*/ | 
|---|
 | 36 |    } | 
|---|
 | 37 |  | 
|---|
 | 38 |  private: | 
|---|
 | 39 |    static int otag; /* object tag */ | 
|---|
| [7820] | 40 |  | 
|---|
| [7702] | 41 |    /* member function dispatcher */ | 
|---|
 | 42 |    static int thunk(lua_State* L) { | 
|---|
 | 43 |       /* stack = closure(-1), [args...], 'self' table(1) */ | 
|---|
| [7808] | 44 |       //int i = static_cast<int>(lua_tonumber(L,-1)); | 
|---|
| [7820] | 45 |  | 
|---|
| [7815] | 46 |        int i = lua_upvalueindex (1); | 
|---|
 | 47 |  | 
|---|
| [7808] | 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)); | 
|---|
| [7815] | 52 |       lua_pop(L, 1); /* pop closure value and obj */ | 
|---|
| [7808] | 53 |  | 
|---|
| [7820] | 54 |         printf("FUNCTION:: %d\n", i ); | 
|---|
| [7808] | 55 |         printf("OBJECT %p\n", obj); | 
|---|
 | 56 |  | 
|---|
 | 57 |  | 
|---|
| [7702] | 58 |       return (obj->*(T::Register[i].mfunc))(L); | 
|---|
 | 59 |    } | 
|---|
 | 60 |  | 
|---|
| [7820] | 61 |  | 
|---|
| [7702] | 62 |     static int setScriptable(T* obj) | 
|---|
 | 63 |      { | 
|---|
 | 64 |      //return registerObject(obj); | 
|---|
 | 65 |      } | 
|---|
| [7820] | 66 |  | 
|---|
| [7702] | 67 |    static int setScriptable(const std::string& objectName) | 
|---|
 | 68 |     { | 
|---|
| [7820] | 69 |    //#warning 'implement do not use' | 
|---|
| [7702] | 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 */ | 
|---|
| [7808] | 76 |        printf("OBJECT CREATED %p\n", obj); | 
|---|
 | 77 |  | 
|---|
| [7702] | 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 |    } | 
|---|
| [7820] | 88 |  protected: | 
|---|
| [7702] | 89 |    Luna(); /* hide default constructor */ | 
|---|
 | 90 |  | 
|---|
 | 91 |  private: | 
|---|
| [7815] | 92 |  | 
|---|
| [7702] | 93 |    static int registerObject(T* obj, lua_State* L) | 
|---|
 | 94 |     { | 
|---|
 | 95 |       lua_newtable(L); /* new table object */ | 
|---|
| [7815] | 96 |       //int  objRef = luaL_ref (L, LUA_REGISTRYINDEX); | 
|---|
| [7808] | 97 |  | 
|---|
 | 98 |       //lua_pushnumber(L, 0); /* userdata obj at index 0 */ | 
|---|
| [7815] | 99 |       //lua_rawgeti(L, LUA_REGISTRYINDEX, objRef); | 
|---|
| [7808] | 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 |  | 
|---|
| [7820] | 106 |     /* Set up garbage collection | 
|---|
| [7702] | 107 |       if(lua_getmetatable(L, objRef) != 0) | 
|---|
 | 108 |        { | 
|---|
| [7808] | 109 |         //std::cout<<"test"<<std::endl; | 
|---|
| [7703] | 110 |         lua_pushstring (L, "__gc"); | 
|---|
| [7702] | 111 |         lua_pushcfunction(L, &Luna<T>::gc_obj); | 
|---|
| [7808] | 112 |         lua_settable(L,-3); | 
|---|
| [7702] | 113 |        } | 
|---|
| [7815] | 114 |     */ | 
|---|
 | 115 |       //lua_rawgeti (L, LUA_REGISTRYINDEX, objRef); | 
|---|
| [7702] | 116 |       /* register the member functions */ | 
|---|
| [7820] | 117 |       for (int i=0; T::Register[i].name; i++) | 
|---|
| [7815] | 118 |       { | 
|---|
| [7820] | 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); | 
|---|
| [7702] | 123 |       } | 
|---|
 | 124 |       return 1; /* return the table object */ | 
|---|
 | 125 | } | 
|---|
 | 126 |  | 
|---|
 | 127 |  | 
|---|
 | 128 | }; | 
|---|
 | 129 | template <class T> | 
|---|
 | 130 | int Luna<T>::otag = 0; | 
|---|