Try to enforce better encapsulation with getters

This commit is contained in:
Gabriel Tofvesson 2024-12-03 22:36:23 +01:00
parent 7dca84b128
commit 147dc40365

View File

@ -19,7 +19,7 @@ function ItemStack:fromDetail(inv, detail, slot)
obj.damage = detail.damage
obj.maxDamage = detail.maxDamage
obj.count = detail.count
obj.maxCount = detail.maxCount
obj.maxCount = detail.maxCount or 64
obj.enchantments = detail.enchantments
obj.displayName = detail.displayName
obj.nbt = detail.nbt
@ -33,16 +33,16 @@ end
function ItemStack:clone(withSlot)
local obj = {
slot = withSlot or self.slot,
inv = self.inv,
name = self.name,
damage = self.damage,
maxDamage = self.maxDamage,
count = self.count,
maxCount = self.maxCount,
enchantments = self.enchantments,
displayName = self.displayName,
nbt = self.nbt
slot = withSlot or self:getSlot(),
inv = self:getInventory(),
name = self:getName(),
damage = self:getDamage(),
maxDamage = self:getMaxDamage(),
count = self:getCount(),
maxCount = self:getMaxCount(),
enchantments = self:getEnchantments(),
displayName = self:getDisplayName(),
nbt = self:getNBT()
}
setmetatable(obj, self)
@ -53,19 +53,19 @@ end
function ItemStack:toSerializable()
local ser = {
slot = self.slot,
maxCount = self.maxCount
slot = self:getSlot(),
maxCount = self:getMaxCount()
}
if not self:isEmpty() then
-- Not empty
ser.name = self.name
ser.damage = self.damage
ser.maxDamage = self.maxDamage
ser.count = self.count
ser.enchantments = self.enchantments
ser.displayName = self.displayName
ser.nbt = self.nbt
ser.name = self:getName()
ser.damage = self:getDamage()
ser.maxDamage = self:getMaxDamage()
ser.count = self:getCount()
ser.enchantments = self:getEnchantments()
ser.displayName = self:getDisplayName()
ser.nbt = self:getNBT()
end
return ser
@ -149,12 +149,14 @@ function ItemStack:getSimpleName()
end
function ItemStack:hasChanged(listObj, thorough)
local listItem = listObj[self.slot]
if listItem == nil or listItem.name ~= self.name or listItem.count ~= self.count then
local listItem = listObj[self:getSlot()]
if listItem == nil or listItem.name ~= self.name or listItem.count ~= self:getCount() then
return true
end
return thorough and (self ~= self:fromDetail(self.inv, self.inv.getItemDetail(self.slot), self.slot))
local inv = self:getInventory()
local slot = self:getSlot()
return thorough and (self ~= self:fromDetail(inv, inv.getItemDetail(slot), slot))
end
function ItemStack:_modify(countDelta, stack)
@ -176,14 +178,13 @@ function ItemStack:_modify(countDelta, stack)
else
-- If stack is empty, copy stack data from source
if self:isEmpty() then
self.maxCount = stack.maxCount
self.name = stack.name
self.damage = stack.damage
self.maxDamage = stack.maxDamage
self.maxCount = stack.maxCount
self.enchantments = stack.enchantments
self.displayName = stack.displayName
self.nbt = stack.nbt
self.name = stack:getName()
self.damage = stack:getDamage()
self.maxDamage = stack:getMaxDamage()
self.maxCount = stack:getMaxCount()
self.enchantments = stack:getEnchantments()
self.displayName = stack:getDisplayName()
self.nbt = stack:getNBT()
end
self.count = newCount
@ -244,23 +245,45 @@ local function objEquals(o1, o2)
end
end
function ItemStack:__eq(other)
return type(other) == "table" and
self.count == other.count and
self.maxCount == other.maxCount and
self:canTransfer(other)
local function runGetter(obj, name)
local fun = obj[name]
if type(fun) ~= "function" then
return false, ("Function '%s' cannot be found in object"):format(name)
end
return pcall(fun, obj)
end
local function checkEqual(obj1, obj2, funcName)
local result1 = { runGetter(obj1, funcName) }
local result2 = { runGetter(obj2, funcName) }
return result1[1] and result2[2] and (result1[2] == result2[2])
end
local function checkEnchantments(obj1, obj2)
local GETTER_FUNC_NAME = "getEnchantments"
local result1 = { runGetter(obj1, GETTER_FUNC_NAME) }
local result2 = { runGetter(obj2, GETTER_FUNC_NAME) }
return result1[1] and result2[1] and objEquals(result1[2], result2[2])
end
function ItemStack:__eq(other)
return type(other) == "table" and
checkEqual(self, other, "getCount") and
checkEqual(self, other, "getMaxCount") and
self:canTransfer(other)
end
-- Determines if two stacks can be transferred to eachother
-- Empty stacks are always valid transfer nodes
function ItemStack:canTransfer(stack)
return self:isEmpty() or stack:isEmpty() or (self.name == stack.name and
self.damage == stack.damage and
self.maxDamage == stack.maxDamage and
self.displayName == stack.displayName and
self.nbt == stack.nbt and
objEquals(self.enchantments, stack.enchantments))
return self:isEmpty() or stack:isEmpty() or (
checkEqual(self, stack, "getName") and
checkEqual(self, stack, "getDamage") and
checkEqual(self, stack, "getMaxDamage") and
checkEqual(self, stack, "getDisplayName") and
checkEqual(self, stack, "getNBT") and
checkEnchantments(self, stack)
)
end
local function queryField(query, field)
@ -283,14 +306,14 @@ function ItemStack:matches(query)
return query(self)
end
return queryField(query.name, self.name) and
queryField(query.damage, self.damage) and
queryField(query.count, self.count) and
queryField(query.maxDamage, self.maxDamage) and
queryField(query.enchantments, self.enchantments) and
queryField(query.maxCount, self.maxCount) and
queryField(query.nbt, self.nbt) and
queryField(query.displayName, self.displayName)
return queryField(query.name, self:getName()) and
queryField(query.damage, self:getDamage()) and
queryField(query.count, self:getCount()) and
queryField(query.maxDamage, self:getMaxDamage()) and
queryField(query.enchantments, self:getEnchantments()) and
queryField(query.maxCount, self:getMaxCount()) and
queryField(query.nbt, self:getNBT()) and
queryField(query.displayName, self:getDisplayName())
end
return ItemStack