summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Ouellette <oue.paul18@gmail.com>2020-06-09 13:37:25 -0400
committerGitHub <noreply@github.com>2020-06-09 19:37:25 +0200
commitb16f841756ef86e83710ad2fddf2cd5bafdf4bcc (patch)
tree777e5dee13e1e2d20a7f8e4a5b8df19a7fad6b85
parent09e285f38cd96b4278b921ab82c5266082bb1a0d (diff)
downloadminetest-b16f841756ef86e83710ad2fddf2cd5bafdf4bcc.tar.gz
minetest-b16f841756ef86e83710ad2fddf2cd5bafdf4bcc.tar.bz2
minetest-b16f841756ef86e83710ad2fddf2cd5bafdf4bcc.zip
LuaItemStack: Add __tostring metamethod (#8785)
* LuaItemStack: Add __tostring metamethod * Clean up LuaItemStack::checkobject
-rw-r--r--builtin/common/misc_helpers.lua2
-rw-r--r--src/inventory.cpp29
-rw-r--r--src/inventory.h4
-rw-r--r--src/script/lua_api/l_item.cpp25
-rw-r--r--src/script/lua_api/l_item.h3
5 files changed, 41 insertions, 22 deletions
diff --git a/builtin/common/misc_helpers.lua b/builtin/common/misc_helpers.lua
index a88adf96d..e29a9f422 100644
--- a/builtin/common/misc_helpers.lua
+++ b/builtin/common/misc_helpers.lua
@@ -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
diff --git a/src/inventory.cpp b/src/inventory.cpp
index 77ecf5876..349ee503d 100644
--- a/src/inventory.cpp
+++ b/src/inventory.cpp
@@ -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();
}
diff --git a/src/inventory.h b/src/inventory.h
index 2828d3e5a..67a7859ed 100644
--- a/src/inventory.h
+++ b/src/inventory.h
@@ -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;
diff --git a/src/script/lua_api/l_item.cpp b/src/script/lua_api/l_item.cpp
index 0a403acbd..d67cab76f 100644
--- a/src/script/lua_api/l_item.cpp
+++ b/src/script/lua_api/l_item.cpp
@@ -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);
}
diff --git a/src/script/lua_api/l_item.h b/src/script/lua_api/l_item.h
index 6fab58045..98744c071 100644
--- a/src/script/lua_api/l_item.h
+++ b/src/script/lua_api/l_item.h
@@ -34,6 +34,9 @@ private:
// 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);