From 3687df3d3661cf3f3f56473ac5ce288a924152c0 Mon Sep 17 00:00:00 2001 From: kepler155c Date: Wed, 24 Oct 2018 19:12:03 -0400 Subject: [PATCH] milo wip --- apps/debug.lua | 31 +++-- milo/Milo.lua | 37 ++++-- milo/MiloRemote.lua | 193 +++++++++++++++++++++++++++++++ milo/apis/milo.lua | 6 - milo/apis/networkedAdapter18.lua | 8 +- milo/core/machines.lua | 12 +- milo/plugins/exportTask.lua | 2 +- milo/plugins/exportView.lua | 19 ++- milo/plugins/jobList.lua | 10 +- milo/plugins/listing.lua | 1 + milo/plugins/remote.lua | 52 +++++++++ 11 files changed, 333 insertions(+), 38 deletions(-) create mode 100644 milo/MiloRemote.lua create mode 100644 milo/plugins/remote.lua diff --git a/apps/debug.lua b/apps/debug.lua index 8d11c02..78b032e 100644 --- a/apps/debug.lua +++ b/apps/debug.lua @@ -1,20 +1,33 @@ - -local mon = device.monitor_1 -mon.clear() -mon.setTextScale(.5) _G.requireInjector(_ENV) local Util = require('util') +local device = _G.device +local os = _G.os +local term = _G.term + +local args = { ... } +local mon = device[args[1] or 'monitor'] or error('Syntax: debug ') + +mon.clear() +mon.setTextScale(.5) mon.setCursorPos(1, 1) local oldDebug = _G.debug _G.debug = function(...) - local oldTerm = term.redirect(mon) - Util.print(...) - term.redirect(oldTerm) + local oldTerm = term.redirect(mon) + Util.print(...) + term.redirect(oldTerm) end - -pcall(read) + +repeat + local e, side = os.pullEventRaw('monitor_touch') + if e == 'monitor_touch' and side == mon.side then + mon.clear() + mon.setTextScale(.5) + mon.setCursorPos(1, 1) + end +until e == 'terminate' + _G.debug = oldDebug diff --git a/milo/Milo.lua b/milo/Milo.lua index 5abe8a8..a6478a4 100644 --- a/milo/Milo.lua +++ b/milo/Milo.lua @@ -61,7 +61,7 @@ replenish autocraft ]] -_G.requireInjector() +_G.requireInjector(_ENV) local Config = require('config') local Event = require('event') @@ -108,17 +108,39 @@ local context = { userRecipes = Util.readTable(Milo.RECIPES_FILE) or { }, learnTypes = { }, machineTypes = { }, + localName = modem.getNameLocal(), } -local function initStorage() +local function initStorage(detachedDevice) debug('Initializing storage') local storage = { } + local storageOffline + + -- check to see if any of the storage chests are disconnected for k,v in pairs(config.remoteDefaults) do - if v.mtype == 'storage' and device[v.name] then - storage[k] = v + if v.mtype == 'storage' then + if not device[v.name] or v.name == detachedDevice then + storageOffline = true + else + storage[k] = v + end end end debug(storage) + + if storageOffline then + Milo:pauseCrafting() + debug('Crafting paused') + Milo:showError('A storage chest has gone offline, ctrl-l to continue') + +-- todo: just can't resume crafting - need to use offline flag instead +-- in the case where crafting was paused already when storage went offline +-- ie. in crafting process + elseif Milo:isCraftingPaused() then + debug('resuming') + Milo:resumeCrafting() + end + context.inventoryAdapter = InventoryAdapter.wrap({ remoteDefaults = storage }) if not context.inventoryAdapter then @@ -138,12 +160,7 @@ Event.on({ 'device_detach' }, function(_, dev) debug('detach: ' .. dev) if config.remoteDefaults[dev] and config.remoteDefaults[dev].mtype == 'storage' then - -Milo:pauseCrafting() -debug('Crafting paused') -Milo:showError('Check log') - - initStorage() + initStorage(dev) end end) diff --git a/milo/MiloRemote.lua b/milo/MiloRemote.lua new file mode 100644 index 0000000..8ef6989 --- /dev/null +++ b/milo/MiloRemote.lua @@ -0,0 +1,193 @@ +_G.requireInjector(_ENV) + +local Socket = require('socket') +local UI = require('ui') +local Util = require('util') + +local colors = _G.colors + +local socket, msg = Socket.connect(1, 4242) +if not socket then + error(msg) +end + +local page = UI.Page { + menuBar = UI.MenuBar { + buttons = { + { text = 'Craft', event = 'craft' }, + { text = 'Refresh', event = 'refresh', x = -9 }, + }, + }, + grid = UI.Grid { + y = 2, ey = -2, + columns = { + { heading = ' Qty', key = 'count' , width = 4, justify = 'right' }, + { heading = 'Name', key = 'displayName' }, + }, + sortColumn = 'displayName', + }, + statusBar = UI.StatusBar { + filter = UI.TextEntry { + x = 1, ex = -4, + limit = 50, + shadowText = 'filter', + shadowTextColor = colors.gray, + backgroundColor = colors.cyan, + backgroundFocusColor = colors.cyan, + accelerators = { + [ 'enter' ] = 'craft', + }, + }, + display = UI.Button { + x = -3, + event = 'toggle_display', + value = 0, + text = 'A', + }, + }, + notification = UI.Notification(), + accelerators = { + r = 'refresh', + q = 'quit', + [ 'control-e' ] = 'eject', + [ 'control-r' ] = 'refresh', + [ 'control-s' ] = 'eject_stack', + [ 'control-1' ] = 'eject_1', + [ 'control-2' ] = 'eject_1', + [ 'control-3' ] = 'eject_1', + [ 'control-4' ] = 'eject_1', + [ 'control-5' ] = 'eject_1', + [ 'control-6' ] = 'eject_1', + [ 'control-7' ] = 'eject_1', + [ 'control-8' ] = 'eject_1', + [ 'control-9' ] = 'eject_1', + [ 'control-0' ] = 'eject_1', + [ 'control-m' ] = 'machines', + [ 'control-l' ] = 'resume', + }, + displayMode = 0, +} + +local function filterItems(t, filter, displayMode) + if filter or displayMode > 0 then + local r = { } + if filter then + filter = filter:lower() + end + for _,v in pairs(t) do + if not filter or string.find(v.lname, filter, 1, true) then + if not displayMode or + displayMode == 0 or + displayMode == 1 and v.count > 0 or + displayMode == 2 and v.has_recipe then + table.insert(r, v) + end + end + end + return r + end + return t +end + +function page.statusBar:draw() + return UI.Window.draw(self) +end + +function page.grid:getRowTextColor(row, selected) + if row.is_craftable then + return colors.yellow + end + if row.has_recipe then + return colors.cyan + end + return UI.Grid:getRowTextColor(row, selected) +end + +function page.grid:getDisplayValues(row) + row = Util.shallowCopy(row) + row.count = row.count > 0 and Util.toBytes(row.count) or '' + if row.low then + row.low = Util.toBytes(row.low) + end + if row.limit then + row.limit = Util.toBytes(row.limit) + end + return row +end + +function page:eventHandler(event) + if event.type == 'quit' then + UI:exitPullEvents() + + elseif event.type == 'eject' then + local item = self.grid:getSelected() + if item then + socket:write({ request = 'transfer', item = item, count = 1 }) + end + + elseif event.type == 'eject_stack' then + local item = self.grid:getSelected() + if item then + socket:write({ request = 'transfer', item = item, count = 64 }) + end + + elseif event.type == 'refresh' then + self:refresh() + self.grid:draw() + self.statusBar.filter:focus() + + elseif event.type == 'toggle_display' then + local values = { + [0] = 'A', + [1] = 'I', + [2] = 'C', + } + + event.button.value = (event.button.value + 1) % 3 + self.displayMode = event.button.value + event.button.text = values[event.button.value] + event.button:draw() + self:applyFilter() + self.grid:draw() + + elseif event.type == 'text_change' then + self.filter = event.text + if #self.filter == 0 then + self.filter = nil + end + self:applyFilter() + self.grid:draw() + self.statusBar.filter:focus() + + else + UI.Page.eventHandler(self, event) + end + return true +end + +function page:enable() + self:refresh() + self:setFocus(self.statusBar.filter) + UI.Page.enable(self) +end + +function page:refresh() + socket:write({ request = 'list' }) + self.items = socket:read() + + if not self.items then + UI:exitPullEvents() + else + self:applyFilter() + end +end + +function page:applyFilter() + local t = filterItems(self.items, self.filter, self.displayMode) + self.grid:setValues(t) +end + +UI:setPage(page) +UI:pullEvents() + +socket:close() diff --git a/milo/apis/milo.lua b/milo/apis/milo.lua index 01957bc..f506a3b 100644 --- a/milo/apis/milo.lua +++ b/milo/apis/milo.lua @@ -4,7 +4,6 @@ local itemDB = require('itemDB') local Util = require('util') local os = _G.os -local term = _G.term local turtle = _G.turtle local Milo = { @@ -81,12 +80,7 @@ function Milo:registerTask(task) end function Milo:showError(msg) - --term.clear() self.context.jobList:showError(msg) - --print(msg) - --print('rebooting in 5 secs') - --os.sleep(5) - --os.reboot() end function Milo:getItem(items, inItem, ignoreDamage, ignoreNbtHash) diff --git a/milo/apis/networkedAdapter18.lua b/milo/apis/networkedAdapter18.lua index 4324a00..54546c5 100644 --- a/milo/apis/networkedAdapter18.lua +++ b/milo/apis/networkedAdapter18.lua @@ -118,9 +118,11 @@ function NetworkedAdapter:provide(item, qty, slot, direction) local total = 0 for _, remote in ipairs(self.remotes) do -debug('%s -> slot %d: %d %s', remote.side, slot or -1, qty, item.name) local amount = remote:provide(item, qty, slot, direction) if amount > 0 then +debug('%s(%d): %s -> %s%s', + item.name, amount, remote.side, direction or self.localName, + slot and string.format('[%d]', slot) or '') self.dirty = true remote.dirty = true local entry = self.activity[key] or 0 @@ -170,7 +172,9 @@ function NetworkedAdapter:insert(slot, qty, toSlot, item, source) local function insert(remote) local amount = remote:insert(slot, qty, toSlot, source or self.direction) if amount > 0 then -debug('%s(%d) -> %s: %d', source or self.localName, slot, remote.side, amount) +debug('%s(%d): %s[%d] -> %s', + item.name, amount, + source or self.localName, slot, remote.side) self.dirty = true remote.dirty = true local entry = self.activity[key] or 0 diff --git a/milo/core/machines.lua b/milo/core/machines.lua index 64afc55..18d03b5 100644 --- a/milo/core/machines.lua +++ b/milo/core/machines.lua @@ -230,7 +230,17 @@ function machineWizard:eventHandler(event) v:save(self.machine) end end - context.config.remoteDefaults[self.machine.name] = self.machine + context.config.remoteDefaults[self.machine.name] = + Util.prune(self.machine, function(v) + if type(v) == 'boolean' then + return v + elseif type(v) == 'string' then + return #v > 0 + elseif type(v) == 'table' then + return not Util.empty(v) + end + return true + end) Config.update('milo', context.config) UI:setPreviousPage() diff --git a/milo/plugins/exportTask.lua b/milo/plugins/exportTask.lua index c285dec..4e25ee9 100644 --- a/milo/plugins/exportTask.lua +++ b/milo/plugins/exportTask.lua @@ -25,7 +25,7 @@ function ExportTask:cycle(context) item = Milo:getItemWithQty(item) if item and count > 0 then context.inventoryAdapter:provide( - itemDB:splitKey(entry.name), + item, math.min(count, item.count), entry.slot, target) diff --git a/milo/plugins/exportView.lua b/milo/plugins/exportView.lua index 3d01297..6bd20da 100644 --- a/milo/plugins/exportView.lua +++ b/milo/plugins/exportView.lua @@ -92,9 +92,9 @@ function itemSlideout.grid:enable() UI.Grid.enable(self) end -function itemSlideout:show(machine, entry) - self.machine = machine +function itemSlideout:show(machine, entry, callback) self.entry = entry + self.callback = callback self.form.choices = { } local m = device[machine.name] @@ -131,8 +131,9 @@ function itemSlideout:eventHandler(event) else self.form:save() self.form.values.name = itemDB:makeKey(selected) - table.insert(self.machine.exports, self.form.values) self:hide() + debug('calling cllbck') + self.callback() end elseif event.type == 'cancel' then @@ -194,10 +195,18 @@ end function exportView:eventHandler(event) if event.type == 'grid_select' then - itemSlideout:show(self.machine, self.grid:getSelected()) + itemSlideout:show(self.machine, self.grid:getSelected(), function() + self.grid:update() + self.grid:draw() + end) elseif event.type == 'add_export' then - itemSlideout:show(self.machine, { }) + local export = { } + itemSlideout:show(self.machine, export, function() + table.insert(self.machine.exports, export) + self.grid:update() + self.grid:draw() + end) elseif event.type == 'remove_export' then local row = self.grid:getSelected() diff --git a/milo/plugins/jobList.lua b/milo/plugins/jobList.lua index a320c1d..4b233e8 100644 --- a/milo/plugins/jobList.lua +++ b/milo/plugins/jobList.lua @@ -32,10 +32,12 @@ function jobList:showError(msg) end function jobList:updateList(craftList) - self.grid:setValues(craftList) - self.grid:update() - self:draw() - self:sync() + if not Milo:isCraftingPaused() then + self.grid:setValues(craftList) + self.grid:update() + self:draw() + self:sync() + end end function jobList.grid:getRowTextColor(row, selected) diff --git a/milo/plugins/listing.lua b/milo/plugins/listing.lua index 1e7e33a..c59f7ac 100644 --- a/milo/plugins/listing.lua +++ b/milo/plugins/listing.lua @@ -78,6 +78,7 @@ local listingPage = UI.Page { notification = UI.Notification(), accelerators = { r = 'refresh', + [ 'control-r' ] = 'refresh', q = 'quit', [ 'control-e' ] = 'eject', [ 'control-s' ] = 'eject_stack', diff --git a/milo/plugins/remote.lua b/milo/plugins/remote.lua new file mode 100644 index 0000000..ca3c368 --- /dev/null +++ b/milo/plugins/remote.lua @@ -0,0 +1,52 @@ +local Event = require('event') +local Milo = require('milo') +local Socket = require('socket') + +local device = _G.device +local manipulator = device.manipulator_1 +local turtle = _G.turtle + +local context = Milo:getContext() + +local function client(socket) + repeat + local data = socket:read() + if not data then + break + end + if data.request == 'list' then + local items = Milo:listItems() + Milo:mergeResources(items) + socket:write(items) + + elseif data.request == 'transfer' then + context.inventoryAdapter:provide( + data.item, + data.count, + nil, + context.localName) + + turtle.eachFilledSlot(function(slot) + manipulator.getInventory().pullItems( + context.localName, + slot.index, + slot.count) + end) + end + until not socket.connected +end + +if device.wireless_modem then + Event.addRoutine(function() + debug('Milo: listening on port 4242') + while true do + local socket = Socket.server(4242) + + debug('connection from ' .. socket.dhost) + + Event.addRoutine(function() + client(socket) + end) + end + end) +end