diff --git a/milo/Milo.lua b/milo/Milo.lua index b9f0273..7b44489 100644 --- a/milo/Milo.lua +++ b/milo/Milo.lua @@ -78,6 +78,7 @@ local context = { config = config, resources = Util.readTable(Milo.RESOURCE_FILE) or { }, + state = { }, craftingQueue = { }, learnTypes = { }, tasks = { }, @@ -92,10 +93,6 @@ device[context.localName] = introspection.getInventory() _G._p = context --debug -Event.on('storage_offline', function() - Milo:showError('A storage chest has gone offline - Review configuration') -end) - Milo:init(context) context.storage:initStorage() @@ -125,9 +122,11 @@ Milo:clearGrid() UI:setPage(UI:getPage('listing')) +local processing + Event.on('milo_cycle', function() - if not context.turtleBusy then - context.turtleBusy = true + if not processing and not Milo:isCraftingPaused() then + processing = true Milo:resetCraftingStatus() for _, task in ipairs(context.tasks) do @@ -139,7 +138,7 @@ Event.on('milo_cycle', function() -- _G.printError(m) end end - context.turtleBusy = false + processing = false if not Util.empty(context.queue) then os.queueEvent('milo_queue') end @@ -147,8 +146,8 @@ Event.on('milo_cycle', function() end) Event.on('milo_queue', function() - if not context.turtleBusy then - context.turtleBusy = true + if not processing and context.storage:isOnline() then + processing = true for _, key in pairs(Util.keys(context.queue)) do local entry = context.queue[key] @@ -156,16 +155,24 @@ Event.on('milo_queue', function() context.queue[key] = nil end - context.turtleBusy = false + processing = false end end) Event.onInterval(5, function() - if not Milo:isCraftingPaused() and context.storage:isOnline() then + if not Milo:isCraftingPaused() then os.queueEvent('milo_cycle') end end) +Event.on({ 'storage_offline', 'storage_online' }, function() + if context.storage:isOnline() then + Milo:resumeCrafting({ key = 'storageOnline' }) + else + Milo:pauseCrafting({ key = 'storageOnline', msg = 'Storage offline' }) + end +end) + os.queueEvent( context.storage:isOnline() and 'storage_online' or 'storage_offline', context.storage:isOnline()) diff --git a/milo/apis/milo.lua b/milo/apis/milo.lua index 039eed0..7ea88fa 100644 --- a/milo/apis/milo.lua +++ b/milo/apis/milo.lua @@ -19,17 +19,29 @@ function Milo:getContext() return self.context end -function Milo:pauseCrafting() - self.craftingPaused = true - Milo:showError('Crafting Paused') +function Milo:pauseCrafting(reason) + local _, key = Util.find(self.context.state, 'key', reason.key) + if not key then + table.insert(self.context.state, reason) + os.queueEvent('milo_pause', reason) + end end -function Milo:resumeCrafting() - self.craftingPaused = false +function Milo:resumeCrafting(reason) + local _, key = Util.find(self.context.state, 'key', reason.key) + if key then + table.remove(self.context.state, key) + local n = self.context.state[#self.context.state] + if n then + os.queueEvent('milo_pause', n) + else + os.queueEvent('milo_resume') + end + end end function Milo:isCraftingPaused() - return self.craftingPaused + return self.context.state[#self.context.state] end function Milo:getState(key) @@ -72,13 +84,6 @@ function Milo:registerTask(task) table.insert(self.context.tasks, task) end -function Milo:showError(msg) - -- TODO: break dependency - if self.context.jobMonitor then - self.context.jobMonitor:showError(msg) - end -end - function Milo:getItem(items, inItem, ignoreDamage, ignoreNbtHash) if not ignoreDamage and not ignoreNbtHash then return items[inItem.key or self:uniqueKey(inItem)] diff --git a/milo/apis/storage.lua b/milo/apis/storage.lua index 5888dc5..2fdc35a 100644 --- a/milo/apis/storage.lua +++ b/milo/apis/storage.lua @@ -114,7 +114,7 @@ function Storage:filterActive(mtype, filter) end) end -function Storage:onlineAdapters(reversed) +function Storage:onlineAdapters() local iter = { } for _, v in pairs(self.nodes) do if v.adapter and v.adapter.online and v.mtype == 'storage' then @@ -122,20 +122,14 @@ function Storage:onlineAdapters(reversed) end end - local function forwardSort(a, b) + table.sort(iter, function(a, b) if not a.priority then return false elseif not b.priority then return true end return a.priority > b.priority - end - - local function backwardSort(a, b) - return not forwardSort(a, b) - end - - table.sort(iter, reversed and backwardSort or forwardSort) + end) local i = 0 return function() @@ -378,12 +372,12 @@ function Storage:import(source, slot, count, item) end -- high to low priority - for remote in self:onlineAdapters() do + for node in self:onlineAdapters() do if count <= 0 then break end - if not remote.lock then - insert(remote.adapter) + if not node.lock then + insert(node.adapter) end end diff --git a/milo/core/machines.lua b/milo/core/machines.lua index 34f931c..60ccc12 100644 --- a/milo/core/machines.lua +++ b/milo/core/machines.lua @@ -59,6 +59,11 @@ local networkPage = UI.Page { help = 'Remove Node', }, statusBar = UI.StatusBar { + ex = -9, + backgroundColor = colors.lightGray, + }, + storageStatus = UI.Text { + x = -8, ex = -1, y = -1, backgroundColor = colors.lightGray, }, notification = UI.Notification { }, @@ -109,16 +114,27 @@ function networkPage:getList() end function networkPage:enable() - self:getList() - self.grid:update() - self:setFocus(self.filter) - UI.Page.enable(self) - self.handler = Event.on({ 'device_attach', 'device_detach'}, function() + local function updateStatus() + local isOnline = context.storage:isOnline() + self.storageStatus.value = isOnline and ' online' or 'offline' + self.storageStatus.textColor = isOnline and colors.lime or colors.red + self.storageStatus:draw() + end + + self.handler = Event.on({ 'device_attach', 'device_detach', 'storage_online', 'storage_offline' }, function() self:getList() - self.grid:update() + self:applyFilter() self.grid:draw() self.grid:sync() + updateStatus() + self:sync() end) + + self:getList() + self:applyFilter() + self:setFocus(self.filter) + UI.Page.enable(self) + updateStatus() end function networkPage:disable() @@ -158,13 +174,16 @@ function networkPage:eventHandler(event) context.config.nodes[node.name] = nil saveConfig() end - self.grid:update() + self:applyFilter() self.grid:draw() elseif event.type == 'text_change' then self:applyFilter() self.grid:draw() + elseif event.type == 'grid_focus_row' then + self.statusBar:setStatus(event.selected.name) + elseif event.type == 'focus_change' then self.statusBar:setStatus(event.focused.help) @@ -298,13 +317,13 @@ function nodeWizard.filter:show(entry, callback, whitelistOnly) UI.SlideOut.show(self) self:setFocus(self.form.scan) - Milo:pauseCrafting() + Milo:pauseCrafting({ key = 'gridInUse', msg = 'Crafting paused' }) sync.lock(turtle) end function nodeWizard.filter:hide() UI.SlideOut.hide(self) - Milo:resumeCrafting() + Milo:resumeCrafting({ key = 'gridInUse' }) sync.release(turtle) end diff --git a/milo/plugins/activityView.lua b/milo/plugins/activityView.lua index 222cd04..67fd7f0 100644 --- a/milo/plugins/activityView.lua +++ b/milo/plugins/activityView.lua @@ -145,20 +145,10 @@ function page:refresh() end function page:update() - if context.storage:isOnline() then - page:refresh() - page:sync() - else - page.grid:clear() - page.grid:centeredWrite(math.ceil(page.height / 2), 'Storage Offline') - page:sync() - end + page:refresh() + page:sync() end -Event.on({ 'storage_offline', 'storage_online' }, function() - page:update() -end) - Event.on('monitor_touch', function(_, side) if side == monitor.adapter.side then page:reset() @@ -166,6 +156,7 @@ Event.on('monitor_touch', function(_, side) end end) +page:enable() page:draw() page:sync() diff --git a/milo/plugins/jobMonitor.lua b/milo/plugins/jobMonitor.lua index 6948bea..f84b5e2 100644 --- a/milo/plugins/jobMonitor.lua +++ b/milo/plugins/jobMonitor.lua @@ -1,14 +1,15 @@ -local Ansi = require('ansi') -local Craft = require('turtle.craft') -local itemDB = require('itemDB') -local Milo = require('milo') -local UI = require('ui') -local Util = require('util') +local Ansi = require('ansi') +local Craft = require('turtle.craft') +local Event = require('event') +local itemDB = require('itemDB') +local Milo = require('milo') +local UI = require('ui') +local Util = require('util') -local colors = _G.colors -local context = Milo:getContext() -local device = _G.device -local monitor = context.storage:getSingleNode('jobs') +local colors = _G.colors +local context = Milo:getContext() +local device = _G.device +local monitor = context.storage:getSingleNode('jobs') --[[ Configuration Screen ]] local template = @@ -16,7 +17,7 @@ local template = %sMilo must be restarted to activate diplay.]] -local jobsWizardPage = UI.Window { +local wizardPage = UI.Window { title = 'Crafting Monitor', index = 2, backgroundColor = colors.cyan, @@ -27,7 +28,7 @@ local jobsWizardPage = UI.Window { }, } -function jobsWizardPage:isValidType(node) +function wizardPage:isValidType(node) local m = device[node.name] return m and m.type == 'monitor' and { name = 'Crafting Monitor', @@ -36,11 +37,11 @@ function jobsWizardPage:isValidType(node) } end -function jobsWizardPage:isValidFor(node) +function wizardPage:isValidFor(node) return node.mtype == 'jobs' end -UI:getPage('nodeWizard').wizard:add({ jobs = jobsWizardPage }) +UI:getPage('nodeWizard').wizard:add({ jobs = wizardPage }) --[[ Display ]] if not monitor then @@ -61,22 +62,16 @@ local jobMonitor = UI.Page { { heading = 'Qty', key = 'remaining', width = 4 }, { heading = 'Crafting', key = 'displayName', }, { heading = 'Status', key = 'status', }, - { heading = 'need', key = 'need', width = 4 }, - { heading = 'total', key = 'total', width = 4 }, - { heading = 'used', key = 'used', width = 4 }, - { heading = 'count', key = 'count', width = 4 }, +-- { heading = 'need', key = 'need', width = 4 }, +-- { heading = 'total', key = 'total', width = 4 }, +-- { heading = 'used', key = 'used', width = 4 }, +-- { heading = 'count', key = 'count', width = 4 }, { heading = 'crafted', key = 'crafted', width = 4 }, -- { heading = 'Progress', key = 'progress', width = 8 }, }, }, } -function jobMonitor:showError(msg) - self.grid:clear() - self.grid:centeredWrite(math.ceil(self.grid.height / 2), msg) - self:sync() -end - function jobMonitor:updateList(craftList) if not Milo:isCraftingPaused() then local t = { } @@ -125,6 +120,16 @@ function jobMonitor.grid:getRowTextColor(row, selected) UI.Grid:getRowTextColor(row, selected) end +Event.on({ 'milo_resume', 'milo_pause' }, function(_, reason) + if reason then + jobMonitor.grid:clear() + jobMonitor.grid:centeredWrite(math.ceil(jobMonitor.grid.height / 2), reason.msg) + else + jobMonitor.grid:draw() + end + jobMonitor:sync() +end) + jobMonitor:enable() jobMonitor:draw() jobMonitor:sync() diff --git a/milo/plugins/learn.lua b/milo/plugins/learn.lua index efb92c0..7172c17 100644 --- a/milo/plugins/learn.lua +++ b/milo/plugins/learn.lua @@ -36,7 +36,7 @@ function learnPage:enable() Milo:getState('learnType') or self.chooser.choices[1].value - Milo:pauseCrafting() + Milo:pauseCrafting({ key = 'gridInUse', msg = 'Crafting paused' }) sync.lock(turtle) self:focusFirst() @@ -50,7 +50,7 @@ end function learnPage:eventHandler(event) if event.type == 'cancel' then sync.release(turtle) - Milo:resumeCrafting() + Milo:resumeCrafting({ key = 'gridInUse' }) UI:setPreviousPage() elseif event.type == 'accept' then diff --git a/milo/plugins/listing.lua b/milo/plugins/listing.lua index aa5a557..b3f5be0 100644 --- a/milo/plugins/listing.lua +++ b/milo/plugins/listing.lua @@ -224,6 +224,7 @@ end function listingPage:enable() self:refresh() self:setFocus(self.statusBar.filter) + self.timer = Event.onInterval(3, function() for _,v in pairs(self.allItems) do local c = context.storage.cache[v.key] @@ -232,11 +233,22 @@ function listingPage:enable() self.grid:draw() self:sync() end) + + self.handler = Event.on({ 'storage_offline', 'storage_online' }, function(_, isOnline) + self.statusBar.storageStatus.value = + isOnline and '' or 'offline' + self.statusBar.storageStatus.textColor = + isOnline and colors.lime or colors.red + self.statusBar.storageStatus:draw() + self:sync() + end) + UI.Page.enable(self) end function listingPage:disable() Event.off(self.timer) + Event.off(self.handler) UI.Page.disable(self) end @@ -250,14 +262,4 @@ function listingPage:applyFilter() self.grid:setValues(t) end -Event.on({ 'storage_offline', 'storage_online' }, function(e, isOnline) - -- TODO: Fix button - listingPage.statusBar.storageStatus.value = - isOnline and '' or 'offline' - listingPage.statusBar.storageStatus.textColor = - isOnline and colors.lime or colors.red - listingPage.statusBar.storageStatus:draw() - listingPage:sync() -end) - UI:addPage('listing', listingPage) diff --git a/milo/plugins/machineLearn.lua b/milo/plugins/machineLearn.lua index 4d33afc..4f1afc6 100644 --- a/milo/plugins/machineLearn.lua +++ b/milo/plugins/machineLearn.lua @@ -135,7 +135,7 @@ function pages.confirmation:validate() end function machineLearnWizard:disable() - Milo:resumeCrafting() + Milo:resumeCrafting({ key = 'gridInUse' }) sync.release(turtle) UI.Page.disable(self) end diff --git a/milo/plugins/turtleLearn.lua b/milo/plugins/turtleLearn.lua index ac5d8ec..3d49455 100644 --- a/milo/plugins/turtleLearn.lua +++ b/milo/plugins/turtleLearn.lua @@ -124,7 +124,7 @@ local turtleLearnWizard = UI.Page { } function turtleLearnWizard:disable() - Milo:resumeCrafting() + Milo:resumeCrafting({ key = 'gridInUse' }) sync.release(turtle) UI.Page.disable(self) end