From d5c102054acee5481537adae05240ef55a024de0 Mon Sep 17 00:00:00 2001 From: kepler155c Date: Sat, 20 Oct 2018 23:53:49 -0400 Subject: [PATCH] plethora networked autocrafting --- apis/chestAdapter18.lua | 3 +- inventoryManager/apis/craft.lua | 22 +++--- inventoryManager/apis/networkedAdapter18.lua | 73 ++++++++++++++++---- inventoryManager/apps/inventoryManager.lua | 47 ++++++++++--- 4 files changed, 109 insertions(+), 36 deletions(-) diff --git a/apis/chestAdapter18.lua b/apis/chestAdapter18.lua index 3053aa4..d749ecf 100644 --- a/apis/chestAdapter18.lua +++ b/apis/chestAdapter18.lua @@ -8,6 +8,7 @@ local ChestAdapter = class() function ChestAdapter:init(args) local defaults = { name = 'chest', + adapter = 'ChestAdapter18' } Util.merge(self, defaults) Util.merge(self, args) @@ -124,7 +125,7 @@ end function ChestAdapter:provide(item, qty, slot, direction) local total = 0 - local s, m = pcall(function() + local _, m = pcall(function() local stacks = self.list() for key,stack in Util.rpairs(stacks) do if stack.name == item.name and diff --git a/inventoryManager/apis/craft.lua b/inventoryManager/apis/craft.lua index 1b7b676..549fde2 100644 --- a/inventoryManager/apis/craft.lua +++ b/inventoryManager/apis/craft.lua @@ -10,17 +10,17 @@ local USER_RECIPES = 'usr/config/recipes.db' local Craft = { } local function clearGrid(inventoryAdapter) - for i = 1, 16 do - local count = turtle.getItemCount(i) - if count > 0 then - inventoryAdapter:insert(i, count) - if turtle.getItemCount(i) ~= 0 then - -- inventory is possibly full - return false - end - end - end - return true + turtle.eachFilledSlot(function(slot) + inventoryAdapter:insert(slot.index, slot.count, nil, slot) + end) + + for i = 1, 16 do + if turtle.getItemCount(i) ~= 0 then + return false + end + end + + return true end local function splitKey(key) diff --git a/inventoryManager/apis/networkedAdapter18.lua b/inventoryManager/apis/networkedAdapter18.lua index 2e3305f..9ea368c 100644 --- a/inventoryManager/apis/networkedAdapter18.lua +++ b/inventoryManager/apis/networkedAdapter18.lua @@ -1,7 +1,6 @@ local class = require('class') local Util = require('util') local InventoryAdapter = require('inventoryAdapter') -local itemDB = require('itemDB') local Peripheral = require('peripheral') local NetworkedAdapter = class() @@ -10,19 +9,23 @@ function NetworkedAdapter:init(args) local defaults = { name = 'Networked Adapter', remotes = { }, + remoteDefaults = { }, } Util.merge(self, defaults) Util.merge(self, args) if not self.side or self.side == 'network' then - self.chests = { } self.modem = Peripheral.get('wired_modem') if self.modem and self.modem.getNameLocal then self.localName = self.modem.getNameLocal() for _, v in pairs(self.modem.getNamesRemote()) do local remote = Peripheral.get({ name = v }) - if remote and remote.size and remote.size() >= 27 and remote.list then + if remote and + remote.size and + remote.size() >= 27 and + remote.list and + not (self.remoteDefaults[v] and self.remoteDefaults[v].ignore) then local adapter = InventoryAdapter.wrap({ side = v, direction = self.localName }) if adapter then @@ -31,9 +34,22 @@ function NetworkedAdapter:init(args) end end end + + for _, remote in pairs(self.remotes) do + Util.merge(remote, self.remoteDefaults[remote.side]) + end + + table.sort(self.remotes, function(a, b) + if not a.priority then + return false + elseif not b.priority then + return true + end + return a.priority < b.priority + end) end - _G._p = self +_G._p = self --------------------------------------------- DEBUG end function NetworkedAdapter:isValid() @@ -50,13 +66,13 @@ function NetworkedAdapter:listItems(throttle) local items = { } throttle = throttle or Util.throttle() - for _, v in pairs(self.remotes) do - v.__cache = v:listItems(throttle) + for _, remote in pairs(self.remotes) do + remote:listItems(throttle) + local rcache = remote.cache or { } - for k,v in pairs(v.__cache) do +-- TODO: add a method in each adapter that only updates a passed cache + for key,v in pairs(rcache) do if v.count > 0 then - local key = table.concat({ v.name, v.damage, v.nbtHash }, ':') - local entry = cache[key] if not entry then entry = Util.shallowCopy(v) @@ -97,9 +113,9 @@ end function NetworkedAdapter:provide(item, qty, slot, direction) local total = 0 - for _, remote in pairs(self.remotes) do -debug('%s -> slot %d: %d %s', remote.side, slot, qty, item.name) - local amount = remote:provide(item, qty, slot) + 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) qty = qty - amount total = total + amount if qty <= 0 then @@ -127,16 +143,45 @@ debug('extract %d slot:%d', qty, slot) return total end -function NetworkedAdapter:insert(slot, qty, toSlot) +function NetworkedAdapter:insert(slot, qty, toSlot, item) local total = 0 - for _, remote in pairs(self.remotes) do + + -- toSlot is not really valid with this adapter + if toSlot then + error('NetworkedAdapter: toSlot is not valid') + end + + local key = table.concat({ item.name, item.damage, item.nbtHash }, ':') + + if not self.cache then + self:listItems() + end + + local function insert(remote) debug('slot %d -> %s: %s', slot, remote.side, qty) local amount = remote:insert(slot, qty, toSlot) qty = qty - amount total = total + amount + end + + if self.cache[key] then -- is this item in some chest + -- low to high priority if the chest already contains that item + for _, remote in Util.rpairs(self.remotes) do + if qty <= 0 then + break + end + if remote.cache and remote.cache[key] then + insert(remote) + end + end + end + + -- high to low priority + for _, remote in ipairs(self.remotes) do if qty <= 0 then break end + insert(remote) end return total diff --git a/inventoryManager/apps/inventoryManager.lua b/inventoryManager/apps/inventoryManager.lua index a4808eb..98536e2 100644 --- a/inventoryManager/apps/inventoryManager.lua +++ b/inventoryManager/apps/inventoryManager.lua @@ -76,7 +76,6 @@ local Terminal = require('terminal') local UI = require('ui') local Util = require('util') -local ControllerAdapter = require('controllerAdapter') local InventoryAdapter = require('inventoryAdapter') local colors = _G.colors @@ -94,7 +93,6 @@ local config = { computerFacing = 'north', -- direction turtle is facing inventory = 'network', -- main inventory - controller = 'none', -- AE / RS controller trashDirection = 'up', -- trash/chest in relation to inventory monitor = 'type/monitor', @@ -102,9 +100,8 @@ local config = { Config.loadWithCheck('inventoryManager', config) ---local controllerAdapter = ControllerAdapter.wrap({ side = config.controller, facing = config.computerFacing }) local inventoryAdapter = config.inventory == 'network' and - InventoryAdapter.wrap() or + InventoryAdapter.wrap({ remoteDefaults = config.remoteDefaults }) or InventoryAdapter.wrap({ side = config.inventory, facing = config.computerFacing }) if not inventoryAdapter then @@ -118,6 +115,20 @@ if inventoryAdapter.craft then controllerAdapter = inventoryAdapter end +local feederAdapter + +if config.remoteDefaults then + for k, v in pairs(config.remoteDefaults) do + if v.feeder then + local modem = Peripheral.get('wired_modem') + if modem and modem.getNameLocal then + feederAdapter = InventoryAdapter.wrap({ side = k, direction = modem.getNameLocal() }) + end + break + end + end +end + local STATUS_INFO = 'info' local STATUS_WARNING = 'warning' local STATUS_ERROR = 'error' @@ -224,13 +235,13 @@ end local function clearGrid() local function clear() + turtle.eachFilledSlot(function(slot) + inventoryAdapter:insert(slot.index, slot.count, nil, slot) + end) + for i = 1, 16 do - local count = turtle.getItemCount(i) - if count > 0 then - inventoryAdapter:insert(i, count) - if turtle.getItemCount(i) ~= 0 then - return false - end + if turtle.getItemCount(i) ~= 0 then + return false end end return true @@ -468,6 +479,9 @@ local function eject(item, qty) inventoryAdapter:provide(item, qty) _G.turtle.emptyInventory() end) + if not s and m then + debug(m) + end end end @@ -620,6 +634,17 @@ local function watchResources(items) return craftList end +local function emptyFeederChest() +_G._p2 =feederAdapter + if feederAdapter then + local list = feederAdapter.list() -- raw list ! + for k,v in pairs(list) do + feederAdapter:extract(k, v.count, 1) + inventoryAdapter:insert(1, v.count, nil, v) + end + end +end + local function loadResources() resources = Util.readTable(RESOURCE_FILE) or { } for k,v in pairs(resources) do @@ -1347,6 +1372,8 @@ listingPage:setFocus(listingPage.statusBar.filter) Event.onInterval(5, function() + emptyFeederChest() + if not craftingPaused then local items = listItems() if not items or Util.size(items) == 0 then