Skip to content
Permalink
Browse files

LuaItemStack: Add __tostring metamethod (#8785)

* LuaItemStack: Add __tostring metamethod

* Clean up LuaItemStack::checkobject
  • Loading branch information
pauloue committed Jun 9, 2020
1 parent 09e285f commit b16f841756ef86e83710ad2fddf2cd5bafdf4bcc
Showing with 41 additions and 22 deletions.
  1. +2 −0 builtin/common/misc_helpers.lua
  2. +16 −13 src/inventory.cpp
  3. +2 −2 src/inventory.h
  4. +18 −7 src/script/lua_api/l_item.cpp
  5. +3 −0 src/script/lua_api/l_item.h
@@ -20,6 +20,8 @@ local function basic_dump(o)
-- dump's output is intended for humans.
--elseif tp == "function" then
-- return string.format("loadstring(%q)", string.dump(o))
elseif tp == "userdata" then
return tostring(o)
else
return string.format("<%s>", tp)
end
@@ -56,28 +56,31 @@ ItemStack::ItemStack(const std::string &name_, u16 count_,
count = 1;
}

void ItemStack::serialize(std::ostream &os) const
void ItemStack::serialize(std::ostream &os, bool serialize_meta) const
{
if (empty())
return;

// Check how many parts of the itemstring are needed
int parts = 1;
if(count != 1)
parts = 2;
if(wear != 0)
parts = 3;
if (!metadata.empty())
parts = 4;
else if (wear != 0)
parts = 3;
else if (count != 1)
parts = 2;

os<<serializeJsonStringIfNeeded(name);
if(parts >= 2)
os<<" "<<count;
if(parts >= 3)
os<<" "<<wear;
os << serializeJsonStringIfNeeded(name);
if (parts >= 2)
os << " " << count;
if (parts >= 3)
os << " " << wear;
if (parts >= 4) {
os << " ";
metadata.serialize(os);
if (serialize_meta)
metadata.serialize(os);
else
os << "<metadata size=" << metadata.size() << ">";
}
}

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

std::string ItemStack::getItemString() const
std::string ItemStack::getItemString(bool include_meta) const
{
std::ostringstream os(std::ios::binary);
serialize(os);
serialize(os, include_meta);
return os.str();
}

@@ -40,13 +40,13 @@ struct ItemStack
~ItemStack() = default;

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

// Returns the string used for inventory
std::string getItemString() const;
std::string getItemString(bool include_meta = true) const;
// Returns the tooltip
std::string getDescription(IItemDefManager *itemdef) const;

@@ -37,6 +37,15 @@ int LuaItemStack::gc_object(lua_State *L)
return 0;
}

// __tostring metamethod
int LuaItemStack::mt_tostring(lua_State *L)
{
LuaItemStack *o = checkobject(L, 1);
std::string itemstring = o->m_stack.getItemString(false);
lua_pushfstring(L, "ItemStack(\"%s\")", itemstring.c_str());
return 1;
}

// is_empty(self) -> true/false
int LuaItemStack::l_is_empty(lua_State *L)
{
@@ -433,12 +442,9 @@ int LuaItemStack::create(lua_State *L, const ItemStack &item)
return 1;
}

LuaItemStack* LuaItemStack::checkobject(lua_State *L, int narg)
LuaItemStack *LuaItemStack::checkobject(lua_State *L, int narg)
{
luaL_checktype(L, narg, LUA_TUSERDATA);
void *ud = luaL_checkudata(L, narg, className);
if(!ud) luaL_typerror(L, narg, className);
return *(LuaItemStack**)ud; // unbox pointer
return *(LuaItemStack **)luaL_checkudata(L, narg, className);
}

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

// hide metatable from Lua getmetatable()
lua_pushliteral(L, "__metatable");
lua_pushvalue(L, methodtable);
lua_settable(L, metatable); // hide metatable from Lua getmetatable()
lua_settable(L, metatable);

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

lua_pushliteral(L, "__tostring");
lua_pushcfunction(L, mt_tostring);
lua_settable(L, metatable);

lua_pop(L, 1); // drop metatable

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

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

@@ -34,6 +34,9 @@ class LuaItemStack : public ModApiBase {
// garbage collector
static int gc_object(lua_State *L);

// __tostring metamethod
static int mt_tostring(lua_State *L);

// is_empty(self) -> true/false
static int l_is_empty(lua_State *L);

0 comments on commit b16f841

Please sign in to comment.
You can’t perform that action at this time.