From 87da95ca0530459acdc9ce5ccf8a9ebd7e14a8a3 Mon Sep 17 00:00:00 2001 From: kepler155c Date: Fri, 26 Oct 2018 18:44:42 -0400 Subject: [PATCH] milo wip --- milo/apis/storage.lua | 116 ++++++++++++++++++++++------------------- milo/core/machines.lua | 29 +++++++++++ 2 files changed, 92 insertions(+), 53 deletions(-) diff --git a/milo/apis/storage.lua b/milo/apis/storage.lua index 66f45d9..8a9d8f3 100644 --- a/milo/apis/storage.lua +++ b/milo/apis/storage.lua @@ -11,7 +11,6 @@ local NetworkedAdapter = class() function NetworkedAdapter:init(args) local defaults = { - remotes = { }, remoteDefaults = { }, dirty = true, listCount = 0, @@ -25,7 +24,6 @@ listCount = 0, self.localName = modem.getNameLocal() Event.on({ 'device_attach' }, function(_, dev) - --debug('attach: ' .. dev) if self.remoteDefaults[dev] then if self.remoteDefaults[dev].mtype == 'storage' then self:initStorage() @@ -37,7 +35,6 @@ listCount = 0, end) Event.on({ 'device_detach' }, function(_, dev) - --debug('detach: ' .. dev) if self.remoteDefaults[dev] then if self.remoteDefaults[dev].mtype == 'storage' then self:initStorage(dev) @@ -67,56 +64,69 @@ function NetworkedAdapter:initTrashcan(detachedDevice) if (detachedDevice and self.trashcan and self.trashcan.name == detachedDevice) or (trashcan and not device[trashcan.name]) then self.trashcan = nil -debug('Trashcan: none') +debug(' Trashcan: none') elseif trashcan and device[trashcan.name] then if not self.trashcan or (self.trashcan and self.trashcan.name ~= trashcan.name) then -debug('Trashcan: ' .. trashcan.name) +debug(' Trashcan: ' .. trashcan.name) self.trashcan = device[trashcan.name] end end end -function NetworkedAdapter:initStorage(detachedDevice) - local storage = { } +function NetworkedAdapter:initStorage() local online = true - -- check to see if any of the storage chests are disconnected - for k,v in pairs(self.remoteDefaults) do - if v.mtype == 'storage' then - if not device[v.name] or v.name == detachedDevice then - online = false - else - storage[k] = v - end - end - end - debug('Initializing storage') - debug(storage) - - self.remotes = { } - for k in pairs(storage) do - local remote = Peripheral.get({ name = k }) - if remote and remote.size and remote.list then - local adapter = InventoryAdapter.wrap({ side = k, direction = self.localName }) - if adapter then - table.insert(self.remotes, adapter) - Util.merge(remote, self.remoteDefaults[remote.side]) + for k,v in pairs(self.remoteDefaults) do + if v.adapter then + v.adapter.online = not not device[k] + if v.mtype == 'storage' then + online = online and v.adapter.online end + elseif v.mtype == 'storage' then + v.adapter = InventoryAdapter.wrap({ side = k }) + v.adapter.online = true + end + if v.mtype == 'storage' then + debug(' %s: %s', v.adapter.online and ' online' or 'offline', k) end end - table.sort(self.remotes, function(a, b) + self:setOnline(online) +end + +function NetworkedAdapter:onlineAdapters(reversed) + local iter = { } + for _, v in pairs(self.remoteDefaults) do + if v.adapter and v.adapter.online and v.mtype == 'storage' then + table.insert(iter, v) + end + end + + local function forwardSort(a, b) if not a.priority then return false elseif not b.priority then return true end return a.priority > b.priority - end) + end - self:setOnline(online) + local function backwardSort(a, b) + return not forwardSort(a, b) + end + + table.sort(iter, reversed and backwardSort or forwardSort) + + local i = 0 + return function() + i = i + 1 + local a = iter[i] + if a then + return a, a.adapter + end + end end function NetworkedAdapter:refresh(throttle) @@ -138,9 +148,9 @@ self.listCount = self.listCount + 1 local items = { } throttle = throttle or Util.throttle() - for _, remote in pairs(self.remotes) do - remote:listItems(throttle) - local rcache = remote.cache or { } + for _, adapter in self:onlineAdapters() do + adapter:listItems(throttle) + local rcache = adapter.cache or { } -- TODO: add a method in each adapter that only updates a passed cache for key,v in pairs(rcache) do @@ -173,14 +183,14 @@ end function NetworkedAdapter:provide(item, qty, slot, direction) local total = 0 - for _, remote in ipairs(self.remotes) do - local amount = remote:provide(item, qty, slot, direction) + for _, adapter in self:onlineAdapters() do + local amount = adapter:provide(item, qty, slot, direction) if amount > 0 then --debug('EXT: %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 + adapter.dirty = true end qty = qty - amount total = total + amount @@ -193,11 +203,11 @@ function NetworkedAdapter:provide(item, qty, slot, direction) end function NetworkedAdapter:trash(source, slot, count) - if not self.trashcan then - return + if self.trashcan then + debug('TRA: %s[%d] (%d)', source, slot, count) + return self.trashcan.pullItems(source, slot, count) end -debug('TRA: %s[%d] (%d)', source, slot, count) - return self.trashcan.pullItems(source, slot, count) + return 0 end function NetworkedAdapter:import(source, slot, count, item) @@ -218,14 +228,14 @@ function NetworkedAdapter:insert(slot, qty, toSlot, item, source) self:listItems() end - local function insert(remote) - local amount = remote:insert(slot, qty, toSlot, source or self.localName) + local function insert(adapter) + local amount = adapter:insert(slot, qty, toSlot, source or self.localName) if amount > 0 then debug('INS: %s(%d): %s[%d] -> %s', item.name, amount, - source or self.localName, slot, remote.side) + source or self.localName, slot, adapter.side) self.dirty = true - remote.dirty = true + adapter.dirty = true local entry = self.activity[key] or 0 self.activity[key] = entry + amount end @@ -233,11 +243,11 @@ debug('INS: %s(%d): %s[%d] -> %s', total = total + amount end - -- found a chest locked with this item - for _, remote in pairs(self.remotes) do + -- find a chest locked with this item + for remote in self:onlineAdapters() do -- TODO: proper checking using ignore dmg/nbt if remote.lock == key or remote.lock == item.name then - insert(remote) + insert(remote.adapter) if qty > 0 then -- TODO: only if void flag set total = total + self:trash(source, slot, qty) end @@ -247,23 +257,23 @@ debug('INS: %s(%d): %s[%d] -> %s', 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 + for _, adapter in self:onlineAdapters(true --[[ reversed ]]) do if qty <= 0 then break end - if remote.cache and remote.cache[key] and not remote.lockWith then - insert(remote) + if adapter.cache and adapter.cache[key] and not adapter.lockWith then + insert(adapter) end end end -- high to low priority - for _, remote in ipairs(self.remotes) do + for remote in self:onlineAdapters() do if qty <= 0 then break end if not remote.lockWith then - insert(remote) + insert(remote.adapter) end end diff --git a/milo/core/machines.lua b/milo/core/machines.lua index ef1394f..be7f3c0 100644 --- a/milo/core/machines.lua +++ b/milo/core/machines.lua @@ -197,7 +197,11 @@ function machineWizard.wizard:eventHandler(event) end function machineWizard:enable(machine) + local adapter = machine.adapter + machine.adapter = nil -- don't deep copy the adapter self.machine = Util.deepCopy(machine) + machine.adapter = adapter + self.wizard.pages.general.form:setValues(self.machine) self.wizard.pages.general.form[1].shadowText = machine.name @@ -224,12 +228,26 @@ function machineWizard:eventHandler(event) elseif event.type == 'accept' then +_G._p2 = self.machine +debug(1) + -- todo: no need for calling this function - use validate instead for _, v in pairs(self.wizard.pages) do if v.save and v.index then -- only save if the page was valid for this mtype v:save(self.machine) end end +debug(2) + + local adapter = self.machine.adapter + self.machine.adapter = nil + +local t = { } +for k,v in pairs(context.config.remoteDefaults) do + t[k] = v.adapter + v.adapter = nil +end + context.config.remoteDefaults[self.machine.name] = Util.prune(self.machine, function(v) if type(v) == 'boolean' then @@ -243,6 +261,17 @@ function machineWizard:eventHandler(event) end) Config.update('milo', context.config) +for k,v in pairs(t) do + context.config.remoteDefaults[k].adapter = v +end + +debug(3) + Util.clear(context.config.remoteDefaults[self.machine.name]) +debug(4) + Util.merge(context.config.remoteDefaults[self.machine.name], self.machine) +debug(5) + context.config.remoteDefaults[self.machine.name].adapter = adapter + UI:setPreviousPage() elseif event.type == 'enable_view' then