@@ -60,9 +60,37 @@ class ModApiBase : protected LuaHelper {
6060 lua_CFunction func,
6161 int top);
6262
63- static void registerClass (lua_State *L, const char *name,
63+ template <typename T>
64+ static void registerClass (lua_State *L,
6465 const luaL_Reg *methods,
65- const luaL_Reg *metamethods);
66+ const luaL_Reg *metamethods)
67+ {
68+ luaL_newmetatable (L, T::className);
69+ luaL_register (L, NULL , metamethods);
70+ int metatable = lua_gettop (L);
71+
72+ lua_newtable (L);
73+ luaL_register (L, NULL , methods);
74+ int methodtable = lua_gettop (L);
75+
76+ lua_pushvalue (L, methodtable);
77+ lua_setfield (L, metatable, " __index" );
78+
79+ lua_getfield (L, metatable, " __tostring" );
80+ bool default_tostring = lua_isnil (L, -1 );
81+ lua_pop (L, 1 );
82+ if (default_tostring) {
83+ lua_pushcfunction (L, ModApiBase::defaultToString<T>);
84+ lua_setfield (L, metatable, " __tostring" );
85+ }
86+
87+ // Protect the real metatable.
88+ lua_pushvalue (L, methodtable);
89+ lua_setfield (L, metatable, " __metatable" );
90+
91+ // Pop methodtable and metatable.
92+ lua_pop (L, 2 );
93+ }
6694
6795 template <typename T>
6896 static inline T *checkObject (lua_State *L, int narg)
@@ -84,4 +112,14 @@ class ModApiBase : protected LuaHelper {
84112 * @return value from `func`
85113 */
86114 static int l_deprecated_function (lua_State *L, const char *good, const char *bad, lua_CFunction func);
115+
116+ private:
117+
118+ template <typename T>
119+ static int defaultToString (lua_State *L)
120+ {
121+ auto *t = checkObject<T>(L, 1 );
122+ lua_pushfstring (L, " %s: %p" , T::className, t);
123+ return 1 ;
124+ }
87125};
0 commit comments