summaryrefslogtreecommitdiff
path: root/src/scripting/luautil.h
diff options
context:
space:
mode:
authorThorbjørn Lindeijer <thorbjorn@lindeijer.nl>2012-01-30 22:16:40 +0100
committerThorbjørn Lindeijer <thorbjorn@lindeijer.nl>2012-01-31 21:50:49 +0100
commit4cd1957231605e976c5cf001eddea80d5e49272f (patch)
tree1fd13522adeb62c408562a4ff76c98ee2e254342 /src/scripting/luautil.h
parentbc291713c56a2bc27ec10cef52dd3a52a0579c7d (diff)
downloadmanaserv-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.h66
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 */