00001
00002
00003
00004
00005
extern "C"
00006 {
00007
#include <lua.h>
00008
#include <lauxlib.h>
00009 }
00010
00011
#include "LuaManager.h"
00012
00013
00014 #define SArg(n) (luaL_checkstring(L,n))
00015 #define IArg(n) (luaL_checkint(L,n))
00016 #define BArg(n) (!!IArg(n))
00017 #define FArg(n) ((float) luaL_checknumber(L,n))
00018
00019
00020 #define LUA_REGISTER_CLASS( T ) \
00021
class Lua##T { \
00022
public: \
00023
Lua##T() { LUA->Register( Register ); } \
00024
static const char className[]; \
00025
static Luna<T,Lua##T>::RegType methods[]; \
00026
static void Register( lua_State* L ) { \
00027
Luna<T,Lua##T>::Register(L); \
00028
} \
00029
LUA_##T##_METHODS( T ) \
00030
}; \
00031
static Lua##T registera; \
00032
const char Lua##T::className[] = #T; \
00033
Luna<T,Lua##T>::RegType Lua##T::methods[] = { \
00034
LUA_##T##_METHODS_MAP( T ) \
00035
{0,0} \
00036
};
00037 #define LUA_METHOD_MAP( T, Method ) { #Method, Lua##T::Method },
00038
00039
00040 template <
typename T,
typename TInfo>
class Luna {
00041 typedef struct {
T *pT; }
userdataType;
00042
public:
00043 typedef int (*
mfp)(
T *p, lua_State *L);
00044 typedef struct {
const char *
name;
mfp mfunc; }
RegType;
00045
00046 static void Register(lua_State *L) {
00047 lua_newtable(L);
00048
int methods = lua_gettop(L);
00049
00050 luaL_newmetatable(L, TInfo::className);
00051
int metatable = lua_gettop(L);
00052
00053
00054
00055 lua_pushstring(L, TInfo::className);
00056 lua_pushvalue(L, methods);
00057 lua_settable(L, LUA_GLOBALSINDEX);
00058
00059 lua_pushliteral(L,
"__metatable");
00060 lua_pushvalue(L, methods);
00061 lua_settable(L, metatable);
00062
00063 lua_pushliteral(L,
"__index");
00064 lua_pushvalue(L, methods);
00065 lua_settable(L, metatable);
00066
00067 lua_pushliteral(L,
"__tostring");
00068 lua_pushcfunction(L,
tostring_T);
00069 lua_settable(L, metatable);
00070
00071
00072
for (
RegType *l = TInfo::methods; l->
name; l++) {
00073 lua_pushstring(L, l->
name);
00074 lua_pushlightuserdata(L, (
void*)l);
00075 lua_pushcclosure(L,
thunk, 1);
00076 lua_settable(L, methods);
00077 }
00078
00079 lua_pop(L, 2);
00080 }
00081
00082
00083 static T *
check(lua_State *L,
int narg) {
00084
userdataType *ud =
00085 static_cast<userdataType*>(luaL_checkudata(L, narg, TInfo::className));
00086
if(!ud) luaL_typerror(L, narg, TInfo::className);
00087
return ud->
pT;
00088 }
00089
00090
private:
00091
Luna();
00092
00093
00094 static int thunk(lua_State *L) {
00095
00096
T *obj = check(L, 1);
00097 lua_remove(L, 1);
00098
00099
RegType *l = static_cast<RegType*>(lua_touserdata(L, lua_upvalueindex(1)));
00100
return (*(l->
mfunc))(obj,L);
00101 }
00102
00103
public:
00104
00105
00106 static int Push(lua_State *L, T* p ) {
00107
userdataType *ud = static_cast<userdataType*>(lua_newuserdata(L,
sizeof(
userdataType)));
00108 ud->
pT = p;
00109 luaL_getmetatable(L, TInfo::className);
00110 lua_setmetatable(L, -2);
00111
return 1;
00112 }
00113
00114
private:
00115
00116 static int tostring_T (lua_State *L) {
00117
char buff[32];
00118
userdataType *ud = static_cast<userdataType*>(lua_touserdata(L, 1));
00119
T *obj = ud->
pT;
00120 sprintf(buff,
"%p", obj);
00121 lua_pushfstring(L,
"%s (%s)", TInfo::className, buff);
00122
return 1;
00123 }
00124 };
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149