Immensely reduce lag on sorting large recipe lists
This commit is contained in:
1 parent
fcdfbe33f4
commit
f50cffcf8d
1 file changed
+90
-54
+90
-54
@@ -176,6 +176,22 @@ local lockedRecipes = {}
|
||||
--If the seed changes, the above two tables will be wiped
|
||||
local lastSeedUsed = 0
|
||||
|
||||
--A list of item IDs, sorted by quality, then by name, to help with sorting our recipe list faster
|
||||
local sortedIDs = {}
|
||||
for i = 1, EID.XMLMaxItemID do
|
||||
if EID.XMLItemQualities[i] ~= nil then
|
||||
table.insert(sortedIDs, i)
|
||||
end
|
||||
end
|
||||
|
||||
table.sort(sortedIDs, function(a, b)
|
||||
if EID.XMLItemQualities[a] == EID.XMLItemQualities[b] then
|
||||
return (EID:getObjectName(5, 100, a) < EID:getObjectName(5, 100, b))
|
||||
else
|
||||
return (EID.XMLItemQualities[a] > EID.XMLItemQualities[b])
|
||||
end
|
||||
end)
|
||||
|
||||
local customRNGSeed = 0x77777770
|
||||
local customRNGShift = {0,0,0}
|
||||
|
||||
@@ -457,6 +473,7 @@ end
|
||||
|
||||
local randResultCache = {}
|
||||
local calcResultCache = {}
|
||||
local numResults = 0
|
||||
|
||||
EID.bagOfCraftingOffset = 0
|
||||
EID.bagOfCraftingCurPickupCount = -1
|
||||
@@ -593,6 +610,7 @@ function EID:handleBagOfCraftingRendering()
|
||||
elseif calcResultCache[queryString] == nil or EID.refreshNextTick then
|
||||
--build on top of our previous recipe lists, if possible
|
||||
local randResults = randResultCache[queryString] or {}
|
||||
local newResults = {}
|
||||
local skipRandom = false
|
||||
--check every single possible recipe for our highest value pickups
|
||||
--limit it in the options, since the number of total combinations quickly grows (nCr):
|
||||
@@ -625,7 +643,11 @@ function EID:handleBagOfCraftingRendering()
|
||||
local startPos = startPos or 1
|
||||
local tempResult = tempResult or {}
|
||||
if (length == 0) then
|
||||
randResults[table.concat(tempResult,",")] = {table.unpack(tempResult)}
|
||||
local resultString = table.concat(tempResult,",")
|
||||
if (randResults[resultString] == nil) then
|
||||
randResults[resultString] = {table.unpack(tempResult)}
|
||||
newResults[resultString] = {table.unpack(tempResult)}
|
||||
end
|
||||
return
|
||||
end
|
||||
for i = startPos, #arr-length+1 do
|
||||
@@ -646,49 +668,54 @@ function EID:handleBagOfCraftingRendering()
|
||||
table.remove(tableCopy, pos)
|
||||
end
|
||||
table.sort(newTable, qualitySort)
|
||||
randResults[table.concat(newTable,",")] = newTable
|
||||
local resultString = table.concat(newTable,",")
|
||||
if (randResults[resultString] == nil) then
|
||||
randResults[resultString] = {table.unpack(newTable)}
|
||||
newResults[resultString] = {table.unpack(newTable)}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local calcResults = {}
|
||||
for k, v in pairs(randResults) do
|
||||
|
||||
local sortedResults = {}
|
||||
if (calcResultCache[queryString]) then
|
||||
sortedResults = calcResultCache[queryString]
|
||||
else
|
||||
for k, v in ipairs(sortedIDs) do
|
||||
sortedResults[v] = {}
|
||||
end
|
||||
end
|
||||
|
||||
for k, v in pairs(newResults) do
|
||||
local resultID, lockedAchievementID = EID:calculateBagOfCrafting(v)
|
||||
if resultID ~= lockedAchievementID then
|
||||
table.insert(calcResults, {v, resultID, lockedAchievementID})
|
||||
table.insert(sortedResults[resultID], {v, resultID, lockedAchievementID})
|
||||
else
|
||||
table.insert(calcResults, {v, resultID})
|
||||
table.insert(sortedResults[resultID], {v, resultID})
|
||||
end
|
||||
end
|
||||
calcResultCache[queryString] = calcResults
|
||||
calcResultCache[queryString] = sortedResults
|
||||
randResultCache[queryString] = randResults
|
||||
results = calcResults
|
||||
--sort our final results by quality, then alphabetical item name
|
||||
table.sort(results, function(a, b)
|
||||
if EID.XMLItemQualities[a[2]] == EID.XMLItemQualities[b[2]] then
|
||||
return (EID:getObjectName(5, 100, a[2]) < EID:getObjectName(5, 100, b[2]))
|
||||
else
|
||||
return (EID.XMLItemQualities[a[2]] > EID.XMLItemQualities[b[2]])
|
||||
results = sortedResults
|
||||
|
||||
numResults = 0
|
||||
for k,v in ipairs(sortedIDs) do
|
||||
if (EID.refreshNextTick and EID.bagOfCraftingOffset > 0 and v == EID.refreshPosition) then
|
||||
--jump to the item we were looking at before, so you can more easily refresh for variants of recipes
|
||||
EID.bagOfCraftingOffset = numResults
|
||||
end
|
||||
end)
|
||||
numResults = numResults + #results[v]
|
||||
end
|
||||
|
||||
if not EID.refreshNextTick then
|
||||
EID.bagOfCraftingOffset = 0
|
||||
EID.bagOfCraftingRefreshes = 0
|
||||
--jump to the item we were looking at before, so you can more easily refresh for variants of recipes
|
||||
elseif EID.bagOfCraftingOffset > 0 then
|
||||
for k,v in ipairs(results) do
|
||||
if (v[2] == EID.refreshPosition) then
|
||||
EID.bagOfCraftingOffset = k-1
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
EID.refreshNextTick = false
|
||||
else
|
||||
results = calcResultCache[queryString]
|
||||
end
|
||||
|
||||
if #results == 0 then
|
||||
if numResults == 0 then
|
||||
EID.bagOfCraftingOffset = 0
|
||||
return false
|
||||
end
|
||||
@@ -726,7 +753,7 @@ function EID:handleBagOfCraftingRendering()
|
||||
if Input.IsActionPressed(EID.Config["BagOfCraftingToggleKey"], EID.player.ControllerIndex) then
|
||||
EID.player:SetShootingCooldown(2)
|
||||
if Input.IsActionTriggered(ButtonAction.ACTION_SHOOTDOWN, EID.player.ControllerIndex) then
|
||||
EID.bagOfCraftingOffset = math.min(#results-(#results%EID.Config["BagOfCraftingResults"]), EID.bagOfCraftingOffset + EID.Config["BagOfCraftingResults"])
|
||||
EID.bagOfCraftingOffset = math.min(numResults-(numResults%EID.Config["BagOfCraftingResults"]), EID.bagOfCraftingOffset + EID.Config["BagOfCraftingResults"])
|
||||
EID.downHeld = Isaac.GetTime()
|
||||
elseif Input.IsActionTriggered(ButtonAction.ACTION_SHOOTUP, EID.player.ControllerIndex) then
|
||||
EID.bagOfCraftingOffset = math.max(0, EID.bagOfCraftingOffset - EID.Config["BagOfCraftingResults"])
|
||||
@@ -739,12 +766,11 @@ function EID:handleBagOfCraftingRendering()
|
||||
elseif Input.IsActionTriggered(ButtonAction.ACTION_SHOOTRIGHT, EID.player.ControllerIndex) then
|
||||
if (EID.lockedResults == nil) then
|
||||
EID.refreshNextTick = true
|
||||
if (results[EID.bagOfCraftingOffset+1]) then EID.refreshPosition = results[EID.bagOfCraftingOffset+1][2] end
|
||||
end
|
||||
end
|
||||
--scroll pages quickly if the button is held
|
||||
if Input.IsActionPressed(ButtonAction.ACTION_SHOOTDOWN, EID.player.ControllerIndex) and Isaac.GetTime() - EID.downHeld > 750 then
|
||||
EID.bagOfCraftingOffset = math.min(#results-(#results%EID.Config["BagOfCraftingResults"]), EID.bagOfCraftingOffset + EID.Config["BagOfCraftingResults"])
|
||||
EID.bagOfCraftingOffset = math.min(numResults-(numResults%EID.Config["BagOfCraftingResults"]), EID.bagOfCraftingOffset + EID.Config["BagOfCraftingResults"])
|
||||
EID.downHeld = Isaac.GetTime() - 700
|
||||
elseif Input.IsActionPressed(ButtonAction.ACTION_SHOOTUP, EID.player.ControllerIndex) and Isaac.GetTime() - EID.upHeld > 750 then
|
||||
EID.bagOfCraftingOffset = math.max(0, EID.bagOfCraftingOffset - EID.Config["BagOfCraftingResults"])
|
||||
@@ -752,7 +778,7 @@ function EID:handleBagOfCraftingRendering()
|
||||
end
|
||||
end
|
||||
--fix bug with being allowed to go to an empty page if recipe count = multiple of page size (or if we refresh on last page)
|
||||
if (EID.bagOfCraftingOffset >= #results) then EID.bagOfCraftingOffset = EID.bagOfCraftingOffset - EID.Config["BagOfCraftingResults"] end
|
||||
if (EID.bagOfCraftingOffset >= numResults) then EID.bagOfCraftingOffset = EID.bagOfCraftingOffset - EID.Config["BagOfCraftingResults"] end
|
||||
|
||||
local prevItem = 0
|
||||
|
||||
@@ -762,38 +788,48 @@ function EID:handleBagOfCraftingRendering()
|
||||
prefix = "#{{Trinket159}} "
|
||||
end
|
||||
|
||||
--results is now sorted by quality and item name, and doesn't iterate over the entire table, instead starting at the page offset
|
||||
--results is now a table of tables for each item, so we have to iterate over the table using sortedIDs
|
||||
if (EID.bagOfCraftingOffset > 0) then
|
||||
customDescObj.Description = customDescObj.Description.. prefix .. "...+"..EID.bagOfCraftingOffset.." more"
|
||||
end
|
||||
for i=EID.bagOfCraftingOffset+1,EID.bagOfCraftingOffset+EID.Config["BagOfCraftingResults"] do
|
||||
local v = results[i]
|
||||
if not v then break end
|
||||
|
||||
if not EID.Config["BagOfCraftingDisplayNames"] then
|
||||
customDescObj.Description = customDescObj.Description.."# {{Collectible"..v[2].."}} "
|
||||
--tack on the secondary recipe image to achievement-locked recipes
|
||||
if v[3] then customDescObj.Description = customDescObj.Description.."({{Collectible" .. v[3] .. "}})" end
|
||||
--color the equals sign with the item quality, so the order of the list can make sense
|
||||
customDescObj.Description = customDescObj.Description.. qualities[EID.XMLItemQualities[v[2]]] .. "={{CR}}"
|
||||
--only display the item name if it's the first occurrence
|
||||
local curOffset = 0
|
||||
EID.refreshPosition = -1
|
||||
for k,id in ipairs(sortedIDs) do
|
||||
if (curOffset + #results[id] <= EID.bagOfCraftingOffset) then curOffset = curOffset + #results[id]
|
||||
else
|
||||
if prevItem ~= v[2] then
|
||||
--substring the first 18 characters of the item name so it fits on one line; is there a way to get around desc line length limits?
|
||||
customDescObj.Description = customDescObj.Description.."# {{Collectible"..v[2].."}} ".. qualities[EID.XMLItemQualities[v[2]]] ..
|
||||
string.sub(EID:getObjectName(5, 100, v[2]),1,18).."#"
|
||||
else
|
||||
customDescObj.Description = customDescObj.Description.."#"
|
||||
if (EID.refreshPosition == -1) then EID.refreshPosition = id end
|
||||
for k2, v in ipairs(results[id]) do
|
||||
curOffset = curOffset + 1
|
||||
if (curOffset > EID.bagOfCraftingOffset+EID.Config["BagOfCraftingResults"]) then break end
|
||||
if not v then break end
|
||||
if (curOffset > EID.bagOfCraftingOffset) then
|
||||
if not EID.Config["BagOfCraftingDisplayNames"] then
|
||||
customDescObj.Description = customDescObj.Description.."# {{Collectible"..v[2].."}} "
|
||||
--tack on the secondary recipe image to achievement-locked recipes
|
||||
if v[3] then customDescObj.Description = customDescObj.Description.."({{Collectible" .. v[3] .. "}})" end
|
||||
--color the equals sign with the item quality, so the order of the list can make sense
|
||||
customDescObj.Description = customDescObj.Description.. qualities[EID.XMLItemQualities[v[2]]] .. "={{CR}}"
|
||||
--only display the item name if it's the first occurrence
|
||||
else
|
||||
if prevItem ~= v[2] then
|
||||
--substring the first 18 characters of the item name so it fits on one line; is there a way to get around desc line length limits?
|
||||
customDescObj.Description = customDescObj.Description.."# {{Collectible"..v[2].."}} ".. qualities[EID.XMLItemQualities[v[2]]] ..
|
||||
string.sub(EID:getObjectName(5, 100, v[2]),1,18).."#"
|
||||
else
|
||||
customDescObj.Description = customDescObj.Description.."#"
|
||||
end
|
||||
--replace recipe bulletpoint with the secondary recipe on achievement-locked recipes
|
||||
if v[3] then customDescObj.Description = customDescObj.Description.." {{Collectible" .. v[3] .. "}} " end
|
||||
end
|
||||
|
||||
customDescObj.Description = customDescObj.Description..EID:tableToCraftingIconsMerged(v[1])
|
||||
prevItem = v[2]
|
||||
end
|
||||
end
|
||||
--replace recipe bulletpoint with the secondary recipe on achievement-locked recipes
|
||||
if v[3] then customDescObj.Description = customDescObj.Description.." {{Collectible" .. v[3] .. "}} " end
|
||||
end
|
||||
|
||||
customDescObj.Description = customDescObj.Description..EID:tableToCraftingIconsMerged(v[1])
|
||||
prevItem = v[2]
|
||||
end
|
||||
if (EID.bagOfCraftingOffset + EID.Config["BagOfCraftingResults"] < #results) then
|
||||
customDescObj.Description = customDescObj.Description.. prefix .. "...+"..(#results-EID.Config["BagOfCraftingResults"]-EID.bagOfCraftingOffset).." more"
|
||||
if (EID.bagOfCraftingOffset + EID.Config["BagOfCraftingResults"] < numResults) then
|
||||
customDescObj.Description = customDescObj.Description.. prefix .. "...+"..(numResults-EID.Config["BagOfCraftingResults"]-EID.bagOfCraftingOffset).." more"
|
||||
end
|
||||
|
||||
EID:printDescription(customDescObj)
|
||||
|
||||
Reference in new issue
Block a user