forked from Mirrorlandia_minetest/minetest
add an 'equals' method to ItemStack and compatibility w/ lua '==' (#12771)
Co-authored-by: rubenwardy <rw@rubenwardy.com> Co-authored-by: sfan5 <sfan5@live.de>
This commit is contained in:
parent
b2a3f53b29
commit
440d966b93
@ -6811,6 +6811,23 @@ an itemstring, a table or `nil`.
|
|||||||
* `peek_item(n)`: returns taken `ItemStack`
|
* `peek_item(n)`: returns taken `ItemStack`
|
||||||
* Copy (don't remove) up to `n` items from this stack
|
* Copy (don't remove) up to `n` items from this stack
|
||||||
* `n`: number, default: `1`
|
* `n`: number, default: `1`
|
||||||
|
* `equals(other)`:
|
||||||
|
* returns `true` if this stack is identical to `other`.
|
||||||
|
* Note: `stack1:to_string() == stack2:to_string()` is not reliable,
|
||||||
|
as stack metadata can be serialized in arbitrary order.
|
||||||
|
* Note: if `other` is an itemstring or table representation of an
|
||||||
|
ItemStack, this will always return false, even if it is
|
||||||
|
"equivalent".
|
||||||
|
|
||||||
|
### Operators
|
||||||
|
|
||||||
|
* `stack1 == stack2`:
|
||||||
|
* Returns whether `stack1` and `stack2` are identical.
|
||||||
|
* Note: `stack1:to_string() == stack2:to_string()` is not reliable,
|
||||||
|
as stack metadata can be serialized in arbitrary order.
|
||||||
|
* Note: if `stack2` is an itemstring or table representation of an
|
||||||
|
ItemStack, this will always return false, even if it is
|
||||||
|
"equivalent".
|
||||||
|
|
||||||
`ItemStackMetaRef`
|
`ItemStackMetaRef`
|
||||||
------------------
|
------------------
|
||||||
|
@ -91,7 +91,7 @@ function unittests.run_one(idx, counters, out_callback, player, pos)
|
|||||||
done(status, err)
|
done(status, err)
|
||||||
out_callback(true)
|
out_callback(true)
|
||||||
end
|
end
|
||||||
|
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -178,6 +178,7 @@ dofile(modpath .. "/crafting.lua")
|
|||||||
dofile(modpath .. "/itemdescription.lua")
|
dofile(modpath .. "/itemdescription.lua")
|
||||||
dofile(modpath .. "/async_env.lua")
|
dofile(modpath .. "/async_env.lua")
|
||||||
dofile(modpath .. "/entity.lua")
|
dofile(modpath .. "/entity.lua")
|
||||||
|
dofile(modpath .. "/itemstack_equals.lua")
|
||||||
dofile(modpath .. "/content_ids.lua")
|
dofile(modpath .. "/content_ids.lua")
|
||||||
dofile(modpath .. "/metadata.lua")
|
dofile(modpath .. "/metadata.lua")
|
||||||
|
|
||||||
|
74
games/devtest/mods/unittests/itemstack_equals.lua
Normal file
74
games/devtest/mods/unittests/itemstack_equals.lua
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
local function test_itemstack_equals_non_stack()
|
||||||
|
local i1 = ItemStack("basenodes:stone")
|
||||||
|
local i2 = { foo = "bar" }
|
||||||
|
|
||||||
|
assert(not i1:equals(i2))
|
||||||
|
assert(i1 ~= i2)
|
||||||
|
assert(i2 ~= i1)
|
||||||
|
end
|
||||||
|
|
||||||
|
unittests.register("test_itemstack_equals_non_stack", test_itemstack_equals_non_stack)
|
||||||
|
|
||||||
|
local function test_itemstack_equals_name()
|
||||||
|
local i1 = ItemStack("basenodes:stone")
|
||||||
|
local i2 = ItemStack("basenodes:desert_stone")
|
||||||
|
|
||||||
|
assert(not i1:equals(i2))
|
||||||
|
assert(i1 ~= i2)
|
||||||
|
end
|
||||||
|
|
||||||
|
unittests.register("test_itemstack_equals_name", test_itemstack_equals_name)
|
||||||
|
|
||||||
|
local function test_itemstack_equals_count()
|
||||||
|
local i1 = ItemStack("basenodes:stone")
|
||||||
|
local i2 = ItemStack("basenodes:stone 2")
|
||||||
|
|
||||||
|
assert(not i1:equals(i2))
|
||||||
|
assert(i1 ~= i2)
|
||||||
|
end
|
||||||
|
|
||||||
|
unittests.register("test_itemstack_equals_count", test_itemstack_equals_count)
|
||||||
|
|
||||||
|
local function test_itemstack_equals_wear()
|
||||||
|
local i1 = ItemStack("basetools:axe_stone")
|
||||||
|
local i2 = ItemStack("basetools:axe_stone")
|
||||||
|
|
||||||
|
i2:add_wear(1)
|
||||||
|
|
||||||
|
assert(not i1:equals(i2))
|
||||||
|
assert(i1 ~= i2)
|
||||||
|
end
|
||||||
|
|
||||||
|
unittests.register("test_itemstack_equals_wear", test_itemstack_equals_wear)
|
||||||
|
|
||||||
|
local function test_itemstack_equals_metadata()
|
||||||
|
local i1 = ItemStack("basenodes:stone")
|
||||||
|
local i2 = ItemStack("basenodes:stone")
|
||||||
|
local i3 = ItemStack("basenodes:stone")
|
||||||
|
|
||||||
|
local m1 = i1:get_meta()
|
||||||
|
local m2 = i2:get_meta()
|
||||||
|
local m3 = i3:get_meta()
|
||||||
|
|
||||||
|
local keys = {"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p"}
|
||||||
|
local values = {}
|
||||||
|
|
||||||
|
for i, key in pairs(keys) do
|
||||||
|
m1:set_int(key, i)
|
||||||
|
m3:set_int(key, i)
|
||||||
|
values[key] = i
|
||||||
|
end
|
||||||
|
|
||||||
|
m3:set_int("a", 999)
|
||||||
|
|
||||||
|
for key, i in pairs(values) do
|
||||||
|
m2:set_int(key, i)
|
||||||
|
end
|
||||||
|
|
||||||
|
assert(i1:equals(i2))
|
||||||
|
assert(i1 == i2)
|
||||||
|
assert(not i1:equals(i3))
|
||||||
|
assert(i1 ~= i3)
|
||||||
|
end
|
||||||
|
|
||||||
|
unittests.register("test_itemstack_equals_metadata", test_itemstack_equals_metadata)
|
@ -433,6 +433,38 @@ int LuaItemStack::l_peek_item(lua_State *L)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// equals(self, other) -> bool
|
||||||
|
int LuaItemStack::l_equals(lua_State *L)
|
||||||
|
{
|
||||||
|
NO_MAP_LOCK_REQUIRED;
|
||||||
|
LuaItemStack *o1 = checkObject<LuaItemStack>(L, 1);
|
||||||
|
|
||||||
|
// checks for non-userdata argument
|
||||||
|
if (!lua_isuserdata(L, 2)) {
|
||||||
|
lua_pushboolean(L, false);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check that the argument is an ItemStack
|
||||||
|
if (!lua_getmetatable(L, 2)) {
|
||||||
|
lua_pushboolean(L, false);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
lua_getfield(L, LUA_REGISTRYINDEX, className);
|
||||||
|
if (!lua_rawequal(L, -1, -2)) {
|
||||||
|
lua_pushboolean(L, false);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
LuaItemStack *o2 = checkObject<LuaItemStack>(L, 2);
|
||||||
|
|
||||||
|
ItemStack &item1 = o1->m_stack;
|
||||||
|
ItemStack &item2 = o2->m_stack;
|
||||||
|
|
||||||
|
lua_pushboolean(L, item1 == item2);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
LuaItemStack::LuaItemStack(const ItemStack &item):
|
LuaItemStack::LuaItemStack(const ItemStack &item):
|
||||||
m_stack(item)
|
m_stack(item)
|
||||||
{
|
{
|
||||||
@ -483,6 +515,7 @@ void LuaItemStack::Register(lua_State *L)
|
|||||||
static const luaL_Reg metamethods[] = {
|
static const luaL_Reg metamethods[] = {
|
||||||
{"__tostring", mt_tostring},
|
{"__tostring", mt_tostring},
|
||||||
{"__gc", gc_object},
|
{"__gc", gc_object},
|
||||||
|
{"__eq", l_equals},
|
||||||
{0, 0}
|
{0, 0}
|
||||||
};
|
};
|
||||||
registerClass(L, className, methods, metamethods);
|
registerClass(L, className, methods, metamethods);
|
||||||
@ -522,6 +555,7 @@ const luaL_Reg LuaItemStack::methods[] = {
|
|||||||
luamethod(LuaItemStack, item_fits),
|
luamethod(LuaItemStack, item_fits),
|
||||||
luamethod(LuaItemStack, take_item),
|
luamethod(LuaItemStack, take_item),
|
||||||
luamethod(LuaItemStack, peek_item),
|
luamethod(LuaItemStack, peek_item),
|
||||||
|
luamethod(LuaItemStack, equals),
|
||||||
{0,0}
|
{0,0}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -140,6 +140,9 @@ private:
|
|||||||
// peek_item(self, peekcount=1) -> itemstack
|
// peek_item(self, peekcount=1) -> itemstack
|
||||||
static int l_peek_item(lua_State *L);
|
static int l_peek_item(lua_State *L);
|
||||||
|
|
||||||
|
// equals(self, other) -> bool
|
||||||
|
static int l_equals(lua_State *L);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DISABLE_CLASS_COPY(LuaItemStack)
|
DISABLE_CLASS_COPY(LuaItemStack)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user