Skip to content

Commit 0d11d24

Browse files
committed
Implement helpful __tostring for all userdata-based classes
1 parent a662caa commit 0d11d24

22 files changed

+103
-66
lines changed

src/script/lua_api/l_areastore.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,7 @@ void LuaAreaStore::Register(lua_State *L)
330330
{"__gc", gc_object},
331331
{0, 0}
332332
};
333-
registerClass(L, className, methods, metamethods);
333+
registerClass<LuaAreaStore>(L, methods, metamethods);
334334

335335
// Can be created from Lua (AreaStore())
336336
lua_register(L, className, create_object);

src/script/lua_api/l_base.cpp

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -90,29 +90,6 @@ bool ModApiBase::registerFunction(lua_State *L, const char *name,
9090
return true;
9191
}
9292

93-
void ModApiBase::registerClass(lua_State *L, const char *name,
94-
const luaL_Reg *methods,
95-
const luaL_Reg *metamethods)
96-
{
97-
luaL_newmetatable(L, name);
98-
luaL_register(L, NULL, metamethods);
99-
int metatable = lua_gettop(L);
100-
101-
lua_newtable(L);
102-
luaL_register(L, NULL, methods);
103-
int methodtable = lua_gettop(L);
104-
105-
lua_pushvalue(L, methodtable);
106-
lua_setfield(L, metatable, "__index");
107-
108-
// Protect the real metatable.
109-
lua_pushvalue(L, methodtable);
110-
lua_setfield(L, metatable, "__metatable");
111-
112-
// Pop methodtable and metatable.
113-
lua_pop(L, 2);
114-
}
115-
11693
int ModApiBase::l_deprecated_function(lua_State *L, const char *good, const char *bad, lua_CFunction func)
11794
{
11895
thread_local std::vector<u64> deprecated_logged;

src/script/lua_api/l_base.h

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -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
};

src/script/lua_api/l_camera.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ void LuaCamera::Register(lua_State *L)
175175
{"__gc", gc_object},
176176
{0, 0}
177177
};
178-
registerClass(L, className, methods, metamethods);
178+
registerClass<LuaCamera>(L, methods, metamethods);
179179
}
180180

181181
const char LuaCamera::className[] = "Camera";

src/script/lua_api/l_env.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ void LuaRaycast::Register(lua_State *L)
124124
{"__gc", gc_object},
125125
{0, 0}
126126
};
127-
registerClass(L, className, methods, metamethods);
127+
registerClass<LuaRaycast>(L, methods, metamethods);
128128

129129
lua_register(L, className, create_object);
130130
}

src/script/lua_api/l_inventory.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,7 @@ void InvRef::Register(lua_State *L)
410410
{"__gc", gc_object},
411411
{0, 0}
412412
};
413-
registerClass(L, className, methods, metamethods);
413+
registerClass<InvRef>(L, methods, metamethods);
414414

415415
// Cannot be created from Lua
416416
//lua_register(L, className, create_object);

src/script/lua_api/l_item.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -524,7 +524,7 @@ void LuaItemStack::Register(lua_State *L)
524524
{"__eq", l_equals},
525525
{0, 0}
526526
};
527-
registerClass(L, className, methods, metamethods);
527+
registerClass<LuaItemStack>(L, methods, metamethods);
528528

529529
// Can be created from Lua (ItemStack(itemstack or itemstring or table or nil))
530530
lua_register(L, className, create_object);

src/script/lua_api/l_itemstackmeta.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ void ItemStackMetaRef::create(lua_State *L, LuaItemStack *istack)
8181

8282
void ItemStackMetaRef::Register(lua_State *L)
8383
{
84-
registerMetadataClass(L, className, methods);
84+
registerMetadataClass<ItemStackMetaRef>(L, methods);
8585
}
8686

8787
const char ItemStackMetaRef::className[] = "ItemStackMetaRef";

src/script/lua_api/l_localplayer.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -464,7 +464,7 @@ void LuaLocalPlayer::Register(lua_State *L)
464464
{"__gc", gc_object},
465465
{0, 0}
466466
};
467-
registerClass(L, className, methods, metamethods);
467+
registerClass<LuaLocalPlayer>(L, methods, metamethods);
468468
}
469469

470470
const char LuaLocalPlayer::className[] = "LocalPlayer";

src/script/lua_api/l_metadata.cpp

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -312,20 +312,3 @@ int MetaDataRef::l_equals(lua_State *L)
312312
lua_pushboolean(L, *data1 == *data2);
313313
return 1;
314314
}
315-
316-
void MetaDataRef::registerMetadataClass(lua_State *L, const char *name,
317-
const luaL_Reg *methods)
318-
{
319-
const luaL_Reg metamethods[] = {
320-
{"__eq", l_equals},
321-
{"__gc", gc_object},
322-
{0, 0}
323-
};
324-
registerClass(L, name, methods, metamethods);
325-
326-
// Set metadata_class in the metatable for MetaDataRef::checkAnyMetadata.
327-
luaL_getmetatable(L, name);
328-
lua_pushstring(L, name);
329-
lua_setfield(L, -2, "metadata_class");
330-
lua_pop(L, 1);
331-
}

0 commit comments

Comments
 (0)