This commit is contained in:
kepler155c
2018-10-24 19:12:03 -04:00
parent 55653aa494
commit 3687df3d36
11 changed files with 333 additions and 38 deletions

View File

@@ -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 <monitor>')
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

View File

@@ -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)

193
milo/MiloRemote.lua Normal file
View File

@@ -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()

View File

@@ -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)

View File

@@ -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

View File

@@ -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()

View File

@@ -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)

View File

@@ -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()

View File

@@ -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)

View File

@@ -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',

52
milo/plugins/remote.lua Normal file
View File

@@ -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