So uhh, yeah, the looped getItemMeta calls cost me a LOT of time. Figured out most of the relevant data I wanted was already being provided elsewhere, no extra calls to make, it's as fast as I can make it now. Now it's dependent on the storage optimizations as they stand, this does not speed anything up, just makes it more accurate.
112 lines
3.4 KiB
Lua
112 lines
3.4 KiB
Lua
local itemDB = require('core.itemDB')
|
|
local Milo = require('milo')
|
|
local Tasks = require('milo.taskRunner')
|
|
local Util = require('opus.util')
|
|
|
|
local ExportTask = {
|
|
name = 'exporter',
|
|
priority = 40,
|
|
}
|
|
|
|
local function filter(a)
|
|
return a.exports
|
|
end
|
|
|
|
function ExportTask:cycle(context)
|
|
local tasks = Tasks({
|
|
errorMsg = 'EXPORTER error: ',
|
|
})
|
|
|
|
for node in context.storage:filterActive('machine', filter) do
|
|
tasks:add(function()
|
|
for _, entry in pairs(node.exports) do
|
|
if not entry.filter then
|
|
-- exports must have a filter
|
|
-- TODO: validate in exportView
|
|
break
|
|
end
|
|
|
|
local function exportSingleSlot()
|
|
local slot = node.adapter.getItemMeta(entry.slot)
|
|
|
|
if slot and slot.count == slot.maxCount then
|
|
return
|
|
end
|
|
|
|
if slot then
|
|
-- something is in the slot, find what we can export
|
|
for key in pairs(entry.filter) do
|
|
local filterItem = itemDB:splitKey(key)
|
|
if (slot.name == filterItem.name and
|
|
(entry.ignoreDamage or slot.damage == filterItem.damage) and
|
|
(entry.ignoreNbtHash or slot.nbtHash == filterItem.nbtHash)) then
|
|
|
|
local items = Milo:getMatches(filterItem, entry)
|
|
local _, item = next(items)
|
|
if item then
|
|
local count = math.min(item.count, slot.maxCount - slot.count)
|
|
context.storage:export(node, entry.slot, count, item)
|
|
end
|
|
break
|
|
end
|
|
end
|
|
return
|
|
end
|
|
|
|
-- slot is empty - export first matching item we have in storage
|
|
for key in pairs(entry.filter) do
|
|
local items = Milo:getMatches(itemDB:splitKey(key), entry)
|
|
local _, item = next(items)
|
|
if item then
|
|
local count = math.min(item.count, itemDB:getMaxCount(item))
|
|
context.storage:export(node, entry.slot, count, item)
|
|
break
|
|
end
|
|
end
|
|
end
|
|
|
|
local function exportItems()
|
|
local cache,size={node.adapter.list(),node.adapter.size()} -- Make single calls, not repeat
|
|
local cacheSize=Util.size(cache) -- Same, though this call doesn't hurt as bad
|
|
for key in pairs(entry.filter) do
|
|
local items = Milo:getMatches(itemDB:splitKey(key), entry)
|
|
for _,item in pairs(items) do
|
|
if size ~= cacheSize then
|
|
-- Here we have a storage which has at least 1 unpopulated slot, we can fire'n'forget into this
|
|
if context.storage:export(node, nil, item.count, item) == 0 then
|
|
-- TODO: really shouldn't break here as there may be room in other slots
|
|
-- leaving for now for performance reasons
|
|
break
|
|
end
|
|
else
|
|
-- Here we have a storage with all slots occupied, sort through and find open spaces
|
|
for iNum=1,size do
|
|
local slot = cache[i]
|
|
if slot then
|
|
if (slot.name == item.name and slot.count ~= item.maxCount and
|
|
(entry.ignoreDamage or slot.damage == item.damage) and
|
|
(entry.ignoreNbtHash or slot.nbtHash == item.nbtHash)) then
|
|
-- We found a slot that matches, and is not full, let's export to it!
|
|
-- Reworked to use item's .maxCount against the existing .list()[slot].count instead of repeat .getItemMeta calls
|
|
context.storage:export(node, iNum, math.min(item.maxCount-slot.count,item.count), item)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
if type(entry.slot) == 'number' then
|
|
exportSingleSlot()
|
|
else
|
|
exportItems()
|
|
end
|
|
end
|
|
end)
|
|
end
|
|
|
|
tasks:run()
|
|
end
|
|
|
|
Milo:registerTask(ExportTask)
|