Skip to content

Commit b16f841

Browse files
authoredJun 9, 2020
LuaItemStack: Add __tostring metamethod (#8785)
* LuaItemStack: Add __tostring metamethod * Clean up LuaItemStack::checkobject
1 parent 09e285f commit b16f841

File tree

5 files changed

+41
-22
lines changed

5 files changed

+41
-22
lines changed
 

‎builtin/common/misc_helpers.lua

+2
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ local function basic_dump(o)
2020
-- dump's output is intended for humans.
2121
--elseif tp == "function" then
2222
-- return string.format("loadstring(%q)", string.dump(o))
23+
elseif tp == "userdata" then
24+
return tostring(o)
2325
else
2426
return string.format("<%s>", tp)
2527
end

‎src/inventory.cpp

+16-13
Original file line numberDiff line numberDiff line change
@@ -56,28 +56,31 @@ ItemStack::ItemStack(const std::string &name_, u16 count_,
5656
count = 1;
5757
}
5858

59-
void ItemStack::serialize(std::ostream &os) const
59+
void ItemStack::serialize(std::ostream &os, bool serialize_meta) const
6060
{
6161
if (empty())
6262
return;
6363

6464
// Check how many parts of the itemstring are needed
6565
int parts = 1;
66-
if(count != 1)
67-
parts = 2;
68-
if(wear != 0)
69-
parts = 3;
7066
if (!metadata.empty())
7167
parts = 4;
68+
else if (wear != 0)
69+
parts = 3;
70+
else if (count != 1)
71+
parts = 2;
7272

73-
os<<serializeJsonStringIfNeeded(name);
74-
if(parts >= 2)
75-
os<<" "<<count;
76-
if(parts >= 3)
77-
os<<" "<<wear;
73+
os << serializeJsonStringIfNeeded(name);
74+
if (parts >= 2)
75+
os << " " << count;
76+
if (parts >= 3)
77+
os << " " << wear;
7878
if (parts >= 4) {
7979
os << " ";
80-
metadata.serialize(os);
80+
if (serialize_meta)
81+
metadata.serialize(os);
82+
else
83+
os << "<metadata size=" << metadata.size() << ">";
8184
}
8285
}
8386

@@ -240,10 +243,10 @@ void ItemStack::deSerialize(const std::string &str, IItemDefManager *itemdef)
240243
deSerialize(is, itemdef);
241244
}
242245

243-
std::string ItemStack::getItemString() const
246+
std::string ItemStack::getItemString(bool include_meta) const
244247
{
245248
std::ostringstream os(std::ios::binary);
246-
serialize(os);
249+
serialize(os, include_meta);
247250
return os.str();
248251
}
249252

‎src/inventory.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,13 @@ struct ItemStack
4040
~ItemStack() = default;
4141

4242
// Serialization
43-
void serialize(std::ostream &os) const;
43+
void serialize(std::ostream &os, bool serialize_meta = true) const;
4444
// Deserialization. Pass itemdef unless you don't want aliases resolved.
4545
void deSerialize(std::istream &is, IItemDefManager *itemdef = NULL);
4646
void deSerialize(const std::string &s, IItemDefManager *itemdef = NULL);
4747

4848
// Returns the string used for inventory
49-
std::string getItemString() const;
49+
std::string getItemString(bool include_meta = true) const;
5050
// Returns the tooltip
5151
std::string getDescription(IItemDefManager *itemdef) const;
5252

‎src/script/lua_api/l_item.cpp

+18-7
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,15 @@ int LuaItemStack::gc_object(lua_State *L)
3737
return 0;
3838
}
3939

40+
// __tostring metamethod
41+
int LuaItemStack::mt_tostring(lua_State *L)
42+
{
43+
LuaItemStack *o = checkobject(L, 1);
44+
std::string itemstring = o->m_stack.getItemString(false);
45+
lua_pushfstring(L, "ItemStack(\"%s\")", itemstring.c_str());
46+
return 1;
47+
}
48+
4049
// is_empty(self) -> true/false
4150
int LuaItemStack::l_is_empty(lua_State *L)
4251
{
@@ -433,12 +442,9 @@ int LuaItemStack::create(lua_State *L, const ItemStack &item)
433442
return 1;
434443
}
435444

436-
LuaItemStack* LuaItemStack::checkobject(lua_State *L, int narg)
445+
LuaItemStack *LuaItemStack::checkobject(lua_State *L, int narg)
437446
{
438-
luaL_checktype(L, narg, LUA_TUSERDATA);
439-
void *ud = luaL_checkudata(L, narg, className);
440-
if(!ud) luaL_typerror(L, narg, className);
441-
return *(LuaItemStack**)ud; // unbox pointer
447+
return *(LuaItemStack **)luaL_checkudata(L, narg, className);
442448
}
443449

444450
void LuaItemStack::Register(lua_State *L)
@@ -448,9 +454,10 @@ void LuaItemStack::Register(lua_State *L)
448454
luaL_newmetatable(L, className);
449455
int metatable = lua_gettop(L);
450456

457+
// hide metatable from Lua getmetatable()
451458
lua_pushliteral(L, "__metatable");
452459
lua_pushvalue(L, methodtable);
453-
lua_settable(L, metatable); // hide metatable from Lua getmetatable()
460+
lua_settable(L, metatable);
454461

455462
lua_pushliteral(L, "__index");
456463
lua_pushvalue(L, methodtable);
@@ -460,12 +467,16 @@ void LuaItemStack::Register(lua_State *L)
460467
lua_pushcfunction(L, gc_object);
461468
lua_settable(L, metatable);
462469

470+
lua_pushliteral(L, "__tostring");
471+
lua_pushcfunction(L, mt_tostring);
472+
lua_settable(L, metatable);
473+
463474
lua_pop(L, 1); // drop metatable
464475

465476
luaL_openlib(L, 0, methods, 0); // fill methodtable
466477
lua_pop(L, 1); // drop methodtable
467478

468-
// Can be created from Lua (LuaItemStack(itemstack or itemstring or table or nil))
479+
// Can be created from Lua (ItemStack(itemstack or itemstring or table or nil))
469480
lua_register(L, className, create_object);
470481
}
471482

‎src/script/lua_api/l_item.h

+3
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ class LuaItemStack : public ModApiBase {
3434
// garbage collector
3535
static int gc_object(lua_State *L);
3636

37+
// __tostring metamethod
38+
static int mt_tostring(lua_State *L);
39+
3740
// is_empty(self) -> true/false
3841
static int l_is_empty(lua_State *L);
3942

0 commit comments

Comments
 (0)
Please sign in to comment.