From 699d0f3ad174fde5e7f09955960cd6c9ee201748 Mon Sep 17 00:00:00 2001 From: yg-ong Date: Sun, 27 Jul 2025 16:08:24 +0800 Subject: [PATCH 1/5] Add deduplication logic for gui/mod-manager --- gui/mod-manager.lua | 60 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 47 insertions(+), 13 deletions(-) diff --git a/gui/mod-manager.lua b/gui/mod-manager.lua index 12029661b..7a52ed8ad 100644 --- a/gui/mod-manager.lua +++ b/gui/mod-manager.lua @@ -74,7 +74,7 @@ end ---@return boolean # true if the mod entry was moved; false if the mod or mod version was not found. ---@return string|nil # loaded version - DISPLAYED_VERSION from the mod's info.txt -local function move_mod_entry(viewscreen, to, from, mod_id, mod_version) +local function copy_mod_entry(viewscreen, to, from, mod_id, mod_version) local to_fields = get_modlist_fields(to, viewscreen) local from_fields = get_modlist_fields(from, viewscreen) @@ -106,23 +106,51 @@ local function move_mod_entry(viewscreen, to, from, mod_id, mod_version) end end - for _, v in pairs(from_fields) do - v:erase(mod_index) - end - return true, loaded_version end ---@return boolean # true if the mod entry was moved; false if the mod or mod version was not found. ---@return string|nil # loaded version - DISPLAYED_VERSION from the mod's info.txt local function enable_mod(viewscreen, mod_id, mod_version) - return move_mod_entry(viewscreen, "object_load_order", "available", mod_id, mod_version) + return copy_mod_entry(viewscreen, "object_load_order", "base_available", mod_id, mod_version) end ---@return boolean # true if the mod entry was moved; false if the mod or mod version was not found. ---@return string|nil # loaded version - DISPLAYED_VERSION from the mod's info.txt -local function disable_mod(viewscreen, mod_id, mod_version) - return move_mod_entry(viewscreen, "available", "object_load_order", mod_id, mod_version) +local function make_available_mod(viewscreen, mod_id, mod_version) + return copy_mod_entry(viewscreen, "available", "base_available", mod_id, mod_version) +end + +local function clear_mods(viewscreen) + local active_modlist = get_modlist_fields('object_load_order', viewscreen) + local avail_modlist = get_modlist_fields('available', viewscreen) + for _, modlist in ipairs({active_modlist, avail_modlist}) do + for _, v in pairs(modlist) do + for i = #v - 1, 0, -1 do + v:erase(i) + end + end + end +end + +local function set_available_mods(viewscreen, loaded) + local base_avail = get_modlist_fields('base_available', viewscreen) + local unused = {} + for i, id in ipairs(base_avail.id) do + local j = utils.linear_index(loaded, id.value) + if j then goto continue end + + local version = base_avail.numeric_version[i] + table.insert(unused, { id= id.value, version= version }) + ::continue:: + end + + for _, v in ipairs(unused) do + local success, _ = make_available_mod(viewscreen, v.id, v.version) + if not success then + dfhack.printerr('failed to show '..v.id..' in available list') + end + end end local function get_active_modlist(viewscreen) @@ -138,21 +166,27 @@ end --- @return string[] --- @return { id: string, new: string }[] local function swap_modlist(viewscreen, modlist) - local current = get_active_modlist(viewscreen) - for _, v in ipairs(current) do - disable_mod(viewscreen, v.id, v.version) - end + clear_mods(viewscreen) local failures = {} local changed = {} + local loaded = {} for _, v in ipairs(modlist) do local success, version = enable_mod(viewscreen, v.id, v.version) if not success then table.insert(failures, v.id) - elseif version then + goto continue + end + + table.insert(loaded, v.id) + if version then table.insert(changed, { id= v.id, new= version }) end + + ::continue:: end + + set_available_mods(viewscreen, loaded) return failures, changed end From f0d1be15f41a4317f69ae0911ef1e63d69a1cc21 Mon Sep 17 00:00:00 2001 From: yg-ong Date: Sun, 27 Jul 2025 16:12:34 +0800 Subject: [PATCH 2/5] Update changelog --- changelog.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/changelog.txt b/changelog.txt index 1094ea67d..8a95feac9 100644 --- a/changelog.txt +++ b/changelog.txt @@ -17,6 +17,7 @@ Template for new versions: ## New Features ## Fixes +- `gui/mod-manager`: hide other versions of loaded mods and unhides them when unloaded ## Misc Improvements From 8321e37d6e9b1e551678f50b7c8b3ad1033689e6 Mon Sep 17 00:00:00 2001 From: yg-ong Date: Sun, 27 Jul 2025 16:17:32 +0800 Subject: [PATCH 3/5] Update docstrings in gui/mod-manager --- gui/mod-manager.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gui/mod-manager.lua b/gui/mod-manager.lua index 7a52ed8ad..5eac49d0f 100644 --- a/gui/mod-manager.lua +++ b/gui/mod-manager.lua @@ -72,7 +72,7 @@ function get_modlist_fields(kind, viewscreen) end end ----@return boolean # true if the mod entry was moved; false if the mod or mod version was not found. +---@return boolean # true if the mod entry was copied over; false if the mod or mod version was not found. ---@return string|nil # loaded version - DISPLAYED_VERSION from the mod's info.txt local function copy_mod_entry(viewscreen, to, from, mod_id, mod_version) local to_fields = get_modlist_fields(to, viewscreen) @@ -109,13 +109,13 @@ local function copy_mod_entry(viewscreen, to, from, mod_id, mod_version) return true, loaded_version end ----@return boolean # true if the mod entry was moved; false if the mod or mod version was not found. +---@return boolean # true if the mod entry was copied over; false if the mod or mod version was not found. ---@return string|nil # loaded version - DISPLAYED_VERSION from the mod's info.txt local function enable_mod(viewscreen, mod_id, mod_version) return copy_mod_entry(viewscreen, "object_load_order", "base_available", mod_id, mod_version) end ----@return boolean # true if the mod entry was moved; false if the mod or mod version was not found. +---@return boolean # true if the mod entry was copied over; false if the mod or mod version was not found. ---@return string|nil # loaded version - DISPLAYED_VERSION from the mod's info.txt local function make_available_mod(viewscreen, mod_id, mod_version) return copy_mod_entry(viewscreen, "available", "base_available", mod_id, mod_version) From aae344e11df950b050e40aa2d857e3b3e9f09a38 Mon Sep 17 00:00:00 2001 From: yg-ong Date: Sun, 27 Jul 2025 21:37:32 +0800 Subject: [PATCH 4/5] Update gui/mod-manager --- gui/mod-manager.lua | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/gui/mod-manager.lua b/gui/mod-manager.lua index 5eac49d0f..476d8afc7 100644 --- a/gui/mod-manager.lua +++ b/gui/mod-manager.lua @@ -137,8 +137,7 @@ local function set_available_mods(viewscreen, loaded) local base_avail = get_modlist_fields('base_available', viewscreen) local unused = {} for i, id in ipairs(base_avail.id) do - local j = utils.linear_index(loaded, id.value) - if j then goto continue end + if loaded[id.value] then goto continue end local version = base_avail.numeric_version[i] table.insert(unused, { id= id.value, version= version }) @@ -178,7 +177,7 @@ local function swap_modlist(viewscreen, modlist) goto continue end - table.insert(loaded, v.id) + loaded[v.id] = true if version then table.insert(changed, { id= v.id, new= version }) end From b021bc08626e85eceae8ed7f829c61a683e1ee08 Mon Sep 17 00:00:00 2001 From: yg-ong Date: Sun, 27 Jul 2025 23:35:26 +0800 Subject: [PATCH 5/5] Apply code review suggestions --- changelog.txt | 2 +- gui/mod-manager.lua | 22 +++++++++------------- 2 files changed, 10 insertions(+), 14 deletions(-) diff --git a/changelog.txt b/changelog.txt index 8a95feac9..6139a0d00 100644 --- a/changelog.txt +++ b/changelog.txt @@ -17,7 +17,6 @@ Template for new versions: ## New Features ## Fixes -- `gui/mod-manager`: hide other versions of loaded mods and unhides them when unloaded ## Misc Improvements @@ -32,6 +31,7 @@ Template for new versions: ## New Features ## Fixes +- `gui/mod-manager`: hide other versions of loaded mods and unhides them when unloaded ## Misc Improvements diff --git a/gui/mod-manager.lua b/gui/mod-manager.lua index 476d8afc7..a3a745963 100644 --- a/gui/mod-manager.lua +++ b/gui/mod-manager.lua @@ -137,11 +137,10 @@ local function set_available_mods(viewscreen, loaded) local base_avail = get_modlist_fields('base_available', viewscreen) local unused = {} for i, id in ipairs(base_avail.id) do - if loaded[id.value] then goto continue end - - local version = base_avail.numeric_version[i] - table.insert(unused, { id= id.value, version= version }) - ::continue:: + if not loaded[id.value] then + local version = base_avail.numeric_version[i] + table.insert(unused, { id= id.value, version= version }) + end end for _, v in ipairs(unused) do @@ -174,15 +173,12 @@ local function swap_modlist(viewscreen, modlist) local success, version = enable_mod(viewscreen, v.id, v.version) if not success then table.insert(failures, v.id) - goto continue - end - - loaded[v.id] = true - if version then - table.insert(changed, { id= v.id, new= version }) + else + if version then + table.insert(changed, { id= v.id, new= version }) + end + loaded[v.id] = true end - - ::continue:: end set_available_mods(viewscreen, loaded)