maybe smoother mobile scroll on installed mods

This commit is contained in:
bryanthaboi
2026-08-21 09:17:06 -04:00
parent a56add6d17
commit 5c1837b1eb
3 changed files with 142 additions and 114 deletions
+9 -6
View File
@@ -2142,16 +2142,20 @@ local function buildModsPanel(imp, x, y, w, availH, m)
+ math.floor(8 * m.s)
local listTop = cy
-- One continuous list: every row is laid out, the region scroll moves
-- through all of it, and only rows inside the region's viewport draw --
-- so the per-frame cost stays bounded by the window, not the list.
-- One continuous list: derive the rows that can touch the viewport before
-- entering the loop. Drawing was already culled, but scanning every
-- installed row to discover that defeats the point on a large mod library.
local view = imp._tabRegionRect
local viewTop = view and view.y or listTop
local viewBot = view and (view.y + view.h) or (listTop + availH)
for i = 1, #mods do
local stride = rowH + gap
local first = math.max(1,
math.ceil((viewTop - rowH - listTop) / stride) + 1)
local last = math.min(#mods,
math.floor((viewBot - listTop) / stride) + 1)
for i = first, last do
local mod = mods[i]
local ry = listTop + (i - 1) * (rowH + gap)
if ry + rowH >= viewTop and ry <= viewBot then
local rowKey = rowKeyFor(imp, "mod-row-", mod.id)
local isFullyDisabled = true
if mod.enabledByVersion then
@@ -2261,7 +2265,6 @@ local function buildModsPanel(imp, x, y, w, availH, m)
px, ly, PAL.detail)
end
end
end
local contentH = #mods * rowH + (#mods - 1) * gap
return (listTop + contentH + gap) - y
+6 -10
View File
@@ -4154,7 +4154,6 @@ function RomImporter:_refreshMods()
end
self.mods = kept
end
self:_syncModUpdateInfo(false)
end
-- Point the MODS panel at one game (or nil for all of them) and relist, so
@@ -4168,15 +4167,12 @@ function RomImporter:_ensureMods()
if not self.mods then self:_refreshMods() end
end
-- Resolve cached (or freshly fetched) GitHub status for every mod that
-- declares a github field. force=true bypasses the 6h cache on every repo.
-- Results live on self.modUpdateInfo[id] = { status, latest, best, releases }.
-- ASYNC (was synchronous). This runs on every _refreshMods -- boot, and any
-- toggle or install -- and used to make one blocking curl call per mod with a
-- github field, in a loop, on the render thread. A handful of mods was a
-- multi-second freeze of the whole launcher. Now each mod gets a handle and
-- they resolve together across later frames; a mod whose cache is still fresh
-- resolves on the first pump with no network at all.
-- Resolve GitHub status for every installed mod that declares a github field.
-- This is deliberately opt-in: only the explicit "Check for updates" action
-- calls it. Opening, scrolling, toggling, or relisting the MODS tab must not
-- create a burst of release work behind the list. force=true bypasses the 6h
-- cache on every repo. Results live on self.modUpdateInfo[id] = {
-- status, latest, best, releases } and resolve asynchronously across frames.
function RomImporter:_syncModUpdateInfo(force)
local ModUpdate = require("src.mods.ModUpdate")
self.modUpdateInfo = self.modUpdateInfo or {}
+29
View File
@@ -388,6 +388,35 @@ mdown = false
LauncherView.update(gameImp, 0.016)
love.mouse.isDown = nil
-- Opening or relisting MODS is display work only. Release checks are an
-- explicit action, otherwise each installed GitHub mod creates background
-- work exactly when the player starts scrolling the panel.
do
local savedMods = package.loaded["src.mods.LauncherMods"]
local savedSaveData = package.loaded["src.core.SaveData"]
local listCalls, updateCalls = 0, 0
package.loaded["src.mods.LauncherMods"] = {
list = function()
listCalls = listCalls + 1
return { { id = "test", github = "owner/repo" } }
end,
}
package.loaded["src.core.SaveData"] = {
loadOptions = function() return {} end,
isSafeMode = function() return false end,
}
local refreshImp = setmetatable({
modStraysChecked = true,
_syncModUpdateInfo = function() updateCalls = updateCalls + 1 end,
}, RomImporter)
refreshImp:_refreshMods()
eq(listCalls, 1, "relisting MODS still obtains its installed rows")
eq(updateCalls, 0,
"relisting MODS does not start release checks without the explicit button")
package.loaded["src.mods.LauncherMods"] = savedMods
package.loaded["src.core.SaveData"] = savedSaveData
end
local function read(path)
local f = assert(io.open(path, "r"))
local src = f:read("*a")