00001
00002
00003
00004
00005
00006 #ifndef CLUAUTIL_H
00007 #define CLUAUTIL_H
00008
00009 extern "C" {
00010 #include <lua.h>
00011 #include <lauxlib.h>
00012 #include <lualib.h>
00013 }
00014
00015
00016
00017
00018
00019 #define LUAFN(name) static int name(lua_State *ls)
00020 #define LUAWRAP(name, wrapexpr) \
00021 static int name(lua_State *ls) \
00022 { \
00023 wrapexpr; \
00024 return (0); \
00025 }
00026 #define PLUARET(type, val) \
00027 lua_push##type(ls, val); \
00028 return (1);
00029 #define LUARET1(name, type, val) \
00030 static int name(lua_State *ls) \
00031 { \
00032 lua_push##type(ls, val); \
00033 return (1); \
00034 }
00035 #define LUARET2(name, type, val1, val2) \
00036 static int name(lua_State *ls) \
00037 { \
00038 lua_push##type(ls, val1); \
00039 lua_push##type(ls, val2); \
00040 return (2); \
00041 }
00042
00043 #define ASSERT_DLUA \
00044 do { \
00045 if (CLua::get_vm(ls).managed_vm) \
00046 luaL_error(ls, "Operation forbidden in end-user script"); \
00047 } while (false)
00048
00049
00050
00051 void luaopen_setmeta(lua_State *ls,
00052 const char *global,
00053 const luaL_reg *lua_lib,
00054 const char *meta);
00055
00056 void clua_register_metatable(lua_State *ls, const char *tn,
00057 const luaL_reg *lr,
00058 int (*gcfn)(lua_State *ls) = NULL);
00059
00060 int clua_stringtable(lua_State *ls, const std::vector<std::string> &s);
00061
00062
00063
00064
00065
00066
00067 template <class T>
00068 inline static T *clua_get_lightuserdata(lua_State *ls, int ndx)
00069 {
00070 return (lua_islightuserdata(ls, ndx))?
00071 static_cast<T *>(lua_touserdata(ls, ndx))
00072 : NULL;
00073 }
00074
00075 template <class T>
00076 inline static T *clua_get_userdata(lua_State *ls, const char *mt, int ndx = 1)
00077 {
00078 return static_cast<T*>(luaL_checkudata(ls, ndx, mt));
00079 }
00080
00081 template <class T>
00082 static int lua_object_gc(lua_State *ls)
00083 {
00084 T **pptr = static_cast<T**>(lua_touserdata(ls, 1));
00085 if (pptr)
00086 delete *pptr;
00087 return (0);
00088 }
00089
00090 template <class T> T *clua_new_userdata(
00091 lua_State *ls, const char *mt)
00092 {
00093 void *udata = lua_newuserdata(ls, sizeof(T));
00094 luaL_getmetatable(ls, mt);
00095 lua_setmetatable(ls, -2);
00096 return static_cast<T*>(udata);
00097 }
00098
00099 template <typename T>
00100 inline void dlua_push_userdata(lua_State *ls, T udata, const char *meta)
00101 {
00102 T *de = clua_new_userdata<T>(ls, meta);
00103 *de = udata;
00104 }
00105
00106 template <class T>
00107 static int dlua_push_object_type(lua_State *ls, const char *meta, const T &data)
00108 {
00109 T **ptr = clua_new_userdata<T*>(ls, meta);
00110 if (ptr)
00111 *ptr = new T(data);
00112 else
00113 lua_pushnil(ls);
00114 return (1);
00115 }
00116
00117
00118
00119
00120 struct activity_interrupt_data;
00121 int push_activity_interrupt(lua_State *ls, activity_interrupt_data *t);
00122
00123 class map_def;
00124 void clua_push_map(lua_State *ls, map_def *map);
00125
00126 void clua_push_coord(lua_State *ls, const coord_def &c);
00127
00128 class dgn_event;
00129 void clua_push_dgn_event(lua_State *ls, const dgn_event *devent);
00130
00131 class monster;
00132 struct MonsterWrap
00133 {
00134 monster* mons;
00135 long turn;
00136 };
00137
00138
00139 void push_monster(lua_State *ls, monster* mons);
00140 void clua_push_item(lua_State *ls, item_def *item);
00141 item_def *clua_get_item(lua_State *ls, int ndx);
00142 void lua_push_floor_items(lua_State *ls, int link);
00143 dungeon_feature_type check_lua_feature(lua_State *ls, int idx);
00144 unsigned int get_tile_idx(lua_State *ls, int arg);
00145 level_id dlua_level_id(lua_State *ls, int ndx);
00146 void push_item(lua_State *ls, item_def *item);
00147
00148 #define GETCOORD(c, p1, p2, boundfn) \
00149 coord_def c; \
00150 c.x = luaL_checkint(ls, p1); \
00151 c.y = luaL_checkint(ls, p2); \
00152 if (!boundfn(c)) \
00153 luaL_error( \
00154 ls, \
00155 make_stringf("Point (%d,%d) is out of bounds", \
00156 c.x, c.y).c_str()); \
00157 else ;
00158
00159
00160 #define COORDS(c, p1, p2) \
00161 GETCOORD(c, p1, p2, in_bounds)
00162
00163 #define COORDSHOW(c, p1, p2) \
00164 GETCOORD(c, p1, p2, in_show_bounds)
00165
00166 #define FEAT(f, pos) \
00167 dungeon_feature_type f = check_lua_feature(ls, pos)
00168
00169 #define LEVEL(lev, br, pos) \
00170 const char *level_name = luaL_checkstring(ls, pos); \
00171 level_area_type lev = str_to_level_area_type(level_name); \
00172 if (lev == NUM_LEVEL_AREA_TYPES) \
00173 luaL_error(ls, "Expected level name"); \
00174 const char *branch_name = luaL_checkstring(ls, pos); \
00175 branch_type br = str_to_branch(branch_name); \
00176 if (lev == LEVEL_DUNGEON && br == NUM_BRANCHES) \
00177 luaL_error(ls, "Expected branch name");
00178
00179 #define MAP(ls, n, var) \
00180 map_def *var = *(map_def **) luaL_checkudata(ls, n, MAP_METATABLE)
00181 #define LINES(ls, n, var) \
00182 map_lines &var = (*(map_def **) luaL_checkudata(ls, n, MAP_METATABLE))->map
00183 #define DEVENT(ls, n, var) \
00184 dgn_event *var = *(dgn_event **) luaL_checkudata(ls, n, DEVENT_METATABLE)
00185 #define MAPMARKER(ls, n, var) \
00186 map_marker *var = *(map_marker **) luaL_checkudata(ls, n, MAPMARK_METATABLE)
00187 #define LUA_ITEM(ls, name, n) \
00188 item_def *item = *(item_def **) luaL_checkudata(ls, n, ITEM_METATABLE)
00189
00190 template <typename list, typename lpush>
00191 static int clua_gentable(lua_State *ls, const list &strings, lpush push)
00192 {
00193 lua_newtable(ls);
00194 for (int i = 0, size = strings.size(); i < size; ++i)
00195 {
00196 push(ls, strings[i]);
00197 lua_rawseti(ls, -2, i + 1);
00198 }
00199 return (1);
00200 }
00201
00202 int clua_pushcxxstring(lua_State *ls, const std::string &s);
00203 int clua_pushpoint(lua_State *ls, const coord_def &pos);
00204
00205 #endif