Async count updates
This commit is contained in:
+146
-26
@@ -53,6 +53,8 @@ local fallbackIcon = false
|
||||
local backButton = false
|
||||
local scrollUpButton = false
|
||||
local scrollDownButton = false
|
||||
local overviewCachedCounts = {}
|
||||
local overviewCachedSortedItemIds = nil
|
||||
local overviewScrollCurrentRow = 0
|
||||
local overviewScrollTargetRow = 0
|
||||
local drawOverview
|
||||
@@ -330,6 +332,42 @@ local function getMeItemCounts(itemIds)
|
||||
return counts
|
||||
end
|
||||
|
||||
local function makeZeroCounts(itemIds)
|
||||
local counts = {}
|
||||
|
||||
for i = 1, #itemIds do
|
||||
counts[itemIds[i]] = 0
|
||||
end
|
||||
|
||||
return counts
|
||||
end
|
||||
|
||||
local function createAsyncMeItemCountsJob(itemIds, batchSize)
|
||||
local counts = makeZeroCounts(itemIds)
|
||||
local index = 1
|
||||
|
||||
batchSize = math.max(1, math.floor(tonumber(batchSize) or 1))
|
||||
|
||||
return {
|
||||
step = function()
|
||||
local bridge = ensureStorageBridge()
|
||||
|
||||
if not bridge then
|
||||
return true, counts
|
||||
end
|
||||
|
||||
local lastIndex = math.min(#itemIds, index + batchSize - 1)
|
||||
|
||||
for i = index, lastIndex do
|
||||
counts[itemIds[i]] = getMeItemCount(itemIds[i])
|
||||
end
|
||||
|
||||
index = lastIndex + 1
|
||||
return index > #itemIds, counts
|
||||
end,
|
||||
}
|
||||
end
|
||||
|
||||
local function getFallbackIcon()
|
||||
if fallbackIcon == false then
|
||||
fallbackIcon = parseNfpImage(table.concat({
|
||||
@@ -566,8 +604,8 @@ local function drawItem(img, cellX, cellY, count, offsetY)
|
||||
end
|
||||
|
||||
local function runScrollableGrid(options)
|
||||
local entries = {}
|
||||
local counts = {}
|
||||
local entries = options.getInitialEntries()
|
||||
local counts = options.getInitialCounts(entries)
|
||||
local visibleItemCount = 0
|
||||
local totalRows = 0
|
||||
local maxScrollRow = 0
|
||||
@@ -575,6 +613,9 @@ local function runScrollableGrid(options)
|
||||
local targetScrollRow = 0
|
||||
local refreshTimer
|
||||
local animationTimer
|
||||
local refreshJob
|
||||
local refreshJobTimer
|
||||
local queuedRefresh = false
|
||||
|
||||
local columns = 3
|
||||
local rowsPerView = 3
|
||||
@@ -645,8 +686,19 @@ local function runScrollableGrid(options)
|
||||
end
|
||||
end
|
||||
|
||||
local function refreshGridData()
|
||||
entries, counts = options.getEntriesAndCounts()
|
||||
local function startRefreshJob()
|
||||
if refreshJob then
|
||||
return false
|
||||
end
|
||||
|
||||
refreshJob = options.createRefreshJob(entries, counts)
|
||||
|
||||
if not refreshJob then
|
||||
return false
|
||||
end
|
||||
|
||||
refreshJobTimer = os.startTimer(options.refreshStepSeconds or 0.05)
|
||||
return true
|
||||
end
|
||||
|
||||
local function renderGrid()
|
||||
@@ -704,18 +756,41 @@ local function runScrollableGrid(options)
|
||||
frame:drawBuffer()
|
||||
end
|
||||
|
||||
refreshGridData()
|
||||
renderGrid()
|
||||
startRefreshJob()
|
||||
refreshTimer = os.startTimer(options.refreshSeconds or 30)
|
||||
|
||||
while true do
|
||||
local event, p1, x, y = os.pullEvent()
|
||||
|
||||
if event == "timer" and p1 == refreshTimer then
|
||||
refreshGridData()
|
||||
renderGrid()
|
||||
if refreshJob then
|
||||
queuedRefresh = true
|
||||
else
|
||||
startRefreshJob()
|
||||
end
|
||||
refreshTimer = os.startTimer(options.refreshSeconds or 30)
|
||||
scheduleAnimation()
|
||||
elseif event == "timer" and p1 == refreshJobTimer then
|
||||
local isDone, newEntries, newCounts = refreshJob.step()
|
||||
|
||||
if isDone then
|
||||
refreshJob = nil
|
||||
refreshJobTimer = nil
|
||||
|
||||
if newEntries and newCounts then
|
||||
entries = newEntries
|
||||
counts = newCounts
|
||||
renderGrid()
|
||||
end
|
||||
|
||||
if queuedRefresh then
|
||||
queuedRefresh = false
|
||||
startRefreshJob()
|
||||
end
|
||||
else
|
||||
refreshJobTimer = os.startTimer(options.refreshStepSeconds or 0.05)
|
||||
end
|
||||
elseif event == "timer" and p1 == animationTimer then
|
||||
local delta = targetScrollRow - currentScrollRow
|
||||
|
||||
@@ -799,8 +874,26 @@ local function drawPage(base_id)
|
||||
|
||||
runScrollableGrid({
|
||||
refreshSeconds = 5,
|
||||
getEntriesAndCounts = function()
|
||||
return pageItems, getMeItemCounts(pageItemIds)
|
||||
getInitialEntries = function()
|
||||
return pageItems
|
||||
end,
|
||||
getInitialCounts = function()
|
||||
return makeZeroCounts(pageItemIds)
|
||||
end,
|
||||
createRefreshJob = function(currentEntries)
|
||||
local job = createAsyncMeItemCountsJob(pageItemIds, 3)
|
||||
|
||||
return {
|
||||
step = function()
|
||||
local isDone, itemCounts = job.step()
|
||||
|
||||
if isDone then
|
||||
return true, currentEntries, itemCounts
|
||||
end
|
||||
|
||||
return false
|
||||
end,
|
||||
}
|
||||
end,
|
||||
getId = function(entry)
|
||||
return entry.id
|
||||
@@ -829,8 +922,39 @@ drawOverview = function()
|
||||
local items = getBaseItemIds()
|
||||
local defaultIcon = getFallbackIcon()
|
||||
|
||||
local function sortOverviewItems(itemCounts)
|
||||
local sortedItemIds = {}
|
||||
|
||||
for i = 1, #items do
|
||||
sortedItemIds[i] = items[i]
|
||||
end
|
||||
|
||||
table.sort(sortedItemIds, function(a, b)
|
||||
local countA = itemCounts[a] or 0
|
||||
local countB = itemCounts[b] or 0
|
||||
|
||||
if countA ~= countB then
|
||||
return countA > countB
|
||||
end
|
||||
|
||||
return a < b
|
||||
end)
|
||||
|
||||
return sortedItemIds
|
||||
end
|
||||
|
||||
runScrollableGrid({
|
||||
refreshSeconds = 30,
|
||||
getInitialEntries = function()
|
||||
if overviewCachedSortedItemIds and #overviewCachedSortedItemIds > 0 then
|
||||
return overviewCachedSortedItemIds
|
||||
end
|
||||
|
||||
return sortOverviewItems(overviewCachedCounts)
|
||||
end,
|
||||
getInitialCounts = function()
|
||||
return overviewCachedCounts
|
||||
end,
|
||||
getInitialScrollState = function()
|
||||
return overviewScrollCurrentRow, overviewScrollTargetRow
|
||||
end,
|
||||
@@ -838,26 +962,22 @@ drawOverview = function()
|
||||
overviewScrollCurrentRow = currentRow
|
||||
overviewScrollTargetRow = targetRow
|
||||
end,
|
||||
getEntriesAndCounts = function()
|
||||
local itemCounts = getMeItemCounts(items)
|
||||
local sortedItemIds = {}
|
||||
createRefreshJob = function()
|
||||
local job = createAsyncMeItemCountsJob(items, 6)
|
||||
|
||||
for i = 1, #items do
|
||||
sortedItemIds[i] = items[i]
|
||||
end
|
||||
return {
|
||||
step = function()
|
||||
local isDone, itemCounts = job.step()
|
||||
|
||||
table.sort(sortedItemIds, function(a, b)
|
||||
local countA = itemCounts[a] or 0
|
||||
local countB = itemCounts[b] or 0
|
||||
if isDone then
|
||||
overviewCachedCounts = itemCounts
|
||||
overviewCachedSortedItemIds = sortOverviewItems(overviewCachedCounts)
|
||||
return true, overviewCachedSortedItemIds, overviewCachedCounts
|
||||
end
|
||||
|
||||
if countA ~= countB then
|
||||
return countA > countB
|
||||
end
|
||||
|
||||
return a < b
|
||||
end)
|
||||
|
||||
return sortedItemIds, itemCounts
|
||||
return false
|
||||
end,
|
||||
}
|
||||
end,
|
||||
getId = function(entry)
|
||||
return entry
|
||||
|
||||
Reference in New Issue
Block a user