Initial item controller implementation

This commit is contained in:
Gabriel Tofvesson 2024-10-04 00:33:55 +02:00
parent 552c19db47
commit 3f0487bb48

146
itemcontroller.lua Normal file
View File

@ -0,0 +1,146 @@
local Chest = require("storage.chest")
local Storage = require("storage")
local Text = require("gfx.text")
local List = require("gfx.list")
local Padding = require("gfx.padding")
local CACHE_FILE = ".storage.cache"
local LOCK_FILE = ".storage.lock"
local function lock()
if fs.exists(LOCK_FILE) then
return false
end
-- Create lock file
return fs.open(LOCK_FILE, "w+").close()
end
local function unlock()
if not fs.exists(LOCK_FILE) then
return false
end
-- Delete lock file
local result, reason = pcall(fs.delete, LOCK_FILE)
if not result then
print("ERROR: Lock file could not be deleted: " .. reason)
end
return result
end
local function isLocked()
return fs.exists(LOCK_FILE)
end
local function saveState(fname, ctrl)
local ser = ctrl:toSerializable()
local file = fs.open(fname, "w+")
file.write(textutils.serialize(ser))
file.close()
end
local function loadState(fname, node)
local controller = nil
if not isLocked() then
local file = fs.open(fname, "r")
if file ~= nil then
local ser = textutils.unserialize(file.readAll())
file.close()
return Storage:fromSerializable(ser)
end
controller = loadState(CACHE_FILE)
end
if controller == nil then
local nodeName = peripheral.getName(node)
local storageChests = {peripheral.find("inventory")}
for i,v in ipairs(storageChests) do
if peripheral.getName(v) == nodeName then
table.remove(storageChests, i)
break
end
end
controller = Storage:fromPeripherals(Storage.assumeHomogeneous(storageChests))
saveState(controller, CACHE_FILE)
end
return controller
end
local accessNode = Chest:fromPeripheral("minecraft:trapped_chest")
local controller = loadState(CACHE_FILE, accessNode)
local monitor = peripheral.find("monitor")
local width, height = monitor.getSize()
local function itemList(stacks, wBudget)
local bgColors = {
colors.gray,
colors.black
}
local entries = {}
for i=1,#stacks do
local stack = stacks[i]
local text = stack:getDisplayName()
local count = tostring(stack:getCount())
-- Fit text inside of width budget
local countLen = #count
if countLen + 2 > wBudget then
error("Width budget is too small")
end
local textBudget = wBudget - 2 - countLen
if #text > textBudget then
-- Truncate to available budget
text = text:sub(1,textBudget)
end
local textLabel = Text:new{ text = text, bgColor = bgColors[i % 2] }
local countLabel = Text:new{ text = count, bgColor = bgColors[i % 2] }
local paddedText = Padding:new{
left = 0,
right = wBudget - #count - #text,
top = 0,
bottom = 0,
bgColor = bgColors[i % 2],
element = textLabel
}
local list = List:new{
children = {
paddedText,
countLabel
},
vertical = false,
onClick = function(table, x, y, source)
print("Clicked: "..stack:getDisplayName())
end
}
table.insert(entries, list)
end
return List:new{
children = entries,
vertical = true
}
end
local count = 0
local found = controller:find(function(stack)
local match = not stack:isEmpty()
if match then
count = count + 1
end
return match and count <= 10
end)
local listResult = itemList(found, width)
listResult:setParent(monitor)
listResult:draw()