From 047c2cdddbe925586de219286d241d00673b6886 Mon Sep 17 00:00:00 2001 From: kepler155c Date: Fri, 2 Nov 2018 21:42:47 -0400 Subject: [PATCH] milo wip --- apps/farm.lua | 2 +- milo/Milo.lua | 31 +++++++++++++++++-- milo/MiloRemote.lua | 13 ++++---- milo/apis/milo.lua | 59 ++++++++++++++++++++++++------------ milo/plugins/craftTask.lua | 8 ++--- milo/plugins/demandCraft.lua | 6 +++- milo/plugins/remote.lua | 52 +++++++++++++------------------ 7 files changed, 103 insertions(+), 68 deletions(-) diff --git a/apps/farm.lua b/apps/farm.lua index fcbcfdc..901398f 100644 --- a/apps/farm.lua +++ b/apps/farm.lua @@ -109,7 +109,7 @@ turtle.run(function() local facing = scanner.getBlockMeta(0, 0, 0).state.facing turtle.point.heading = Point.facings[facing].heading - turtle.setPolicy('digOnly') + --turtle.setPolicy('digOnly') turtle.setMovementStrategy('goto') repeat local blocks, harvestCount = scan() diff --git a/milo/Milo.lua b/milo/Milo.lua index 62d5093..706381f 100644 --- a/milo/Milo.lua +++ b/milo/Milo.lua @@ -59,6 +59,7 @@ local context = { learnTypes = { }, tasks = { }, + queue = { }, localName = modem.getNameLocal(), storage = Storage(config), @@ -101,10 +102,10 @@ Milo:clearGrid() local page = UI:getPage('listing') UI:setPage(page) -Event.onInterval(5, function() - if not Milo:isCraftingPaused() and context.storage:isOnline() then +Event.on('milo_cycle', function() + if not context.turtleBusy then + context.turtleBusy = true Milo:resetCraftingStatus() - --Milo:refreshItems() for _, task in ipairs(context.tasks) do local s, m = pcall(function() task:cycle(context) end) @@ -114,6 +115,30 @@ Event.onInterval(5, function() error(m) end end + context.turtleBusy = false + if not Util.empty(context.queue) then + os.queueEvent('milo_queue') + end + end +end) + +Event.on('milo_queue', function() + if not context.turtleBusy then + context.turtleBusy = true + + for _, key in pairs(Util.keys(context.queue)) do + local entry = context.queue[key] + entry.callback(entry.request) + context.queue[key] = nil + end + + context.turtleBusy = false + end +end) + +Event.onInterval(5, function() + if not Milo:isCraftingPaused() and context.storage:isOnline() then + os.queueEvent('milo_cycle') end end) diff --git a/milo/MiloRemote.lua b/milo/MiloRemote.lua index 84c7c5a..e24d650 100644 --- a/milo/MiloRemote.lua +++ b/milo/MiloRemote.lua @@ -195,12 +195,13 @@ end function page:transfer(item, count) local response = self:sendRequest({ request = 'transfer', item = item, count = count }) if response then - item.count = response.current - response.transferred + _debug(response) + item.count = response.current - response.count self.grid:draw() if response.craft > 0 then self:setStatus(response.craft .. ' crafting ...') - elseif response.craft + response.available < response.requested then - self:setStatus((response.craft + response.available) .. ' available ...') + elseif response.craft + response.count < response.requested then + self:setStatus((response.craft + response.count) .. ' available ...') end end end @@ -318,22 +319,22 @@ if options.slot.value or options.shield.value then os.sleep(1.5) local neural = device.neuralInterface if not neural or not neural[inv] then - _debug('missing Introspection module') + _G._debug('missing Introspection module') end local method = neural and neural[inv] local item = method and method().getItemMeta(slotNo) if item then - _debug('depositing') local response = page:sendRequest({ request = 'deposit', slot = slotValue, + count = item.count, key = table.concat({ item.name, item.damage, item.nbtHash }, ':') }) if response then local ritem = page.items[response.key] if ritem then - ritem.count = response.current + ritem.count = response.current + item.count end page.grid:draw() page:sync() diff --git a/milo/apis/milo.lua b/milo/apis/milo.lua index c1c2687..87ae054 100644 --- a/milo/apis/milo.lua +++ b/milo/apis/milo.lua @@ -3,6 +3,7 @@ local Craft = require('turtle.craft') local itemDB = require('itemDB') local Util = require('util') +local os = _G.os local turtle = _G.turtle local Milo = { @@ -178,25 +179,37 @@ function Milo:getTurtleInventory() return list end -function Milo:craftAndEject(item, count) - local provided = self:provideItem(item, count, function(amount) - -- eject rest when finished crafted - return self:eject(item, amount) - end) - - -- eject what we currently have - return item.count - self:eject(item, provided.available) +-- queue up an action that reliees on the crafting grid +function Milo:queueRequest(request, callback) + if Util.empty(self.context.queue) then + os.queueEvent('milo_queue') + end + table.insert(self.context.queue, { + request = request, + callback = callback + }) end -function Milo:provideItem(item, count, callback) +function Milo:craftAndEject(item, count) + local request = self:makeRequest(item, count, function(request) + -- eject rest when finished crafted + return self:eject(item, request.count) + end) + + -- predict that we will eject that amount + return request.current - request.count +end + +function Milo:makeRequest(item, count, callback) local current = Milo:getItem(Milo:listItems(), item) or { count = 0 } if count <= 0 then return { requested = 0, craft = 0, - available = 0, + count = 0, current = current.count, + item = item, } end @@ -211,20 +224,26 @@ function Milo:provideItem(item, count, callback) end end - if toCraft > 0 then - item = Util.shallowCopy(item) - item.count = toCraft - item.eject = callback - self:requestCrafting(item) - item.crafted = 0 - end - - return { + local request = { requested = count, craft = toCraft, - available = math.min(count, current.count), + count = math.min(count, current.count), current = current.count, + item = item, } + + if request.count > 0 then + Milo:queueRequest(request, callback) + end + + if request.craft > 0 then + item = Util.shallowCopy(item) + item.count = request.craft + item.callback = callback + self:requestCrafting(item) + end + + return request end function Milo:eject(item, count) diff --git a/milo/plugins/craftTask.lua b/milo/plugins/craftTask.lua index d79e67d..f0e59ee 100644 --- a/milo/plugins/craftTask.lua +++ b/milo/plugins/craftTask.lua @@ -106,12 +106,8 @@ function craftTask:cycle() sync(turtle, function() self:craft(recipe, item) end) - if item.eject and item.crafted >= item.count then - if type(item.eject) == 'boolean' then - Milo:eject(item, item.count) - else - item.eject(item.count) -- invoke callback - end + if item.callback and item.crafted >= item.count then + item.callback(item) -- invoke callback end elseif not context.controllerAdapter then item.status = '(no recipe)' diff --git a/milo/plugins/demandCraft.lua b/milo/plugins/demandCraft.lua index 8bde995..a1afa66 100644 --- a/milo/plugins/demandCraft.lua +++ b/milo/plugins/demandCraft.lua @@ -119,7 +119,11 @@ function craftPage:eventHandler(event) local item = Util.shallowCopy(self.item) item.count = tonumber(self.wizard.pages.quantity.count.value) item.forceCrafting = true - item.eject = self.wizard.pages.quantity.eject.value == true + if self.wizard.pages.quantity.eject.value then + item.callback = function(request) + Milo:eject(item, request.count) + end + end Milo:requestCrafting(item) UI:setPreviousPage() else diff --git a/milo/plugins/remote.lua b/milo/plugins/remote.lua index 323be4b..956e198 100644 --- a/milo/plugins/remote.lua +++ b/milo/plugins/remote.lua @@ -43,36 +43,33 @@ local function client(socket) socket:write(items) elseif data.request == 'deposit' then - if Sync.isLocked(turtle) then - socket:write({ msg = '' }) - else - local count - + local function deposit() Sync.sync(turtle, function() if data.slot == 'shield' then - count = manipulator.getEquipment().pushItems( + manipulator.getEquipment().pushItems( context.localName, SHIELD_SLOT, - 64) + data.count) else - count = manipulator.getInventory().pushItems( + manipulator.getInventory().pushItems( context.localName, data.slot, - 64) + data.count) end Milo:clearGrid() end) - - local list = Milo:listItems() - local current = list[data.key] and list[data.key].count or 0 - - socket:write({ - key = data.key, - count = count, - current = current + count, - }) end + local list = Milo:listItems() + local current = list[data.key] and list[data.key].count or 0 + + socket:write({ + key = data.key, + current = current, + }) + + Milo:queueRequest({ }, deposit) + elseif data.request == 'transfer' then local count = data.count @@ -83,33 +80,26 @@ local function client(socket) count = item and item.count or 0 end - local function transfer(amount) + local function transfer(request) Sync.sync(turtle, function() - amount = context.storage:export( + local transferred = context.storage:export( context.localName, nil, - amount, + request.count, data.item) turtle.eachFilledSlot(function(slot) manipulator.getInventory().pullItems( context.localName, slot.index, - slot.count) + transferred) end) end) - - return amount end - if Sync.isLocked(turtle) then - socket:write({ msg = 'Turtle in use. please wait...' }) - end + local request = Milo:makeRequest(data.item, count, transfer) - local provided = Milo:provideItem(data.item, count, transfer) - provided.transferred = provided.available > 0 and transfer(provided.available) or 0 - - socket:write(provided) + socket:write(request) end until not socket.connected