diff options
author | Thorbjørn Lindeijer <thorbjorn@lindeijer.nl> | 2012-01-30 22:16:40 +0100 |
---|---|---|
committer | Thorbjørn Lindeijer <thorbjorn@lindeijer.nl> | 2012-01-31 21:50:49 +0100 |
commit | 4cd1957231605e976c5cf001eddea80d5e49272f (patch) | |
tree | 1fd13522adeb62c408562a4ff76c98ee2e254342 /src/scripting/luautil.h | |
parent | bc291713c56a2bc27ec10cef52dd3a52a0579c7d (diff) | |
download | manaserv-4cd1957231605e976c5cf001eddea80d5e49272f.tar.gz manaserv-4cd1957231605e976c5cf001eddea80d5e49272f.tar.bz2 manaserv-4cd1957231605e976c5cf001eddea80d5e49272f.tar.xz manaserv-4cd1957231605e976c5cf001eddea80d5e49272f.zip |
Use a full user data object for MapObject references
Based on a templated helper class, MapObject references in Lua scripts are now
full user data objects. Using the '__index' member of their metatable, a
library is associated with it so that member functions can be called directly
on the object.
Reviewed-by: Yohann Ferreira
Reviewed-by: Erik Schilling
Diffstat (limited to 'src/scripting/luautil.h')
-rw-r--r-- | src/scripting/luautil.h | 66 |
1 files changed, 64 insertions, 2 deletions
diff --git a/src/scripting/luautil.h b/src/scripting/luautil.h index ee3f1142..4f456ab6 100644 --- a/src/scripting/luautil.h +++ b/src/scripting/luautil.h @@ -44,19 +44,81 @@ void raiseScriptError(lua_State *s, const char *format, ...); void raiseWarning(lua_State *s, const char *format, ...); +/** + * A helper class for pushing and checking custom Lua user data types. + */ +template <typename T> +class LuaUserData +{ +public: + /** + * Creates a metatable to be used for the user data associated with the + * type. Then, registers the \a members with a library named \a typeName, + * and sets the '__index' member of the metatable to this library. + */ + static void registerType(lua_State *s, + const char *typeName, + const luaL_Reg *members) + { + mTypeName = typeName; + + luaL_newmetatable(s, mTypeName); // metatable + lua_pushstring(s, "__index"); // metatable, "__index" + luaL_register(s, typeName, members); // metatable, "__index", {} + lua_rawset(s, -3); // metatable + lua_pop(s, 1); // -empty- + } + + /** + * Pushes a userdata reference to the given object on the stack. Either by + * creating one, or reusing an existing one. + */ + static int push(lua_State *L, T *object) + { + T **userData = static_cast<T**>(lua_newuserdata(L, sizeof(T*))); + *userData = object; + + luaL_newmetatable(L, mTypeName); + lua_setmetatable(L, -2); + + return 1; + } + + /** + * Returns the argument at position \a narg when it is of the right type, + * and raises a Lua error otherwise. + */ + static T *check(lua_State *L, int narg) + { + void *userData = luaL_checkudata(L, narg, mTypeName); + return *(static_cast<T**>(userData)); + } + +private: + static const char *mTypeName; +}; + +template <typename T> const char * LuaUserData<T>::mTypeName; + +typedef LuaUserData<MapObject> LuaMapObject; + + NPC *getNPC(lua_State *s, int p); Character *getCharacter(lua_State *s, int p); Monster *getMonster(lua_State *s, int p); Being *getBeing(lua_State *s, int p); - /* Polymorphic wrapper for pushing variables. Useful for templates.*/ void push(lua_State *s, int val); void push(lua_State *s, const std::string &val); void push(lua_State *s, Thing *val); void push(lua_State *s, double val); -void push(lua_State *s, MapObject *val); + +inline void push(lua_State *s, MapObject *val) +{ + LuaMapObject::push(s, val); +} /* Pushes an STL LIST */ |