From f8a8c57c7f530d619f7d97b0155217a04478dfa9 Mon Sep 17 00:00:00 2001 From: Ethan Green Date: Thu, 22 Jan 2026 04:04:25 +0200 Subject: [PATCH] Use map lookups for localmodlist --- .../views/LocalModList/LocalModCard.vue | 18 ++-- src/r2mm/mods/Dependants.ts | 82 ++++++++++++------- src/store/modules/ProfileModule.ts | 8 ++ 3 files changed, 68 insertions(+), 40 deletions(-) diff --git a/src/components/views/LocalModList/LocalModCard.vue b/src/components/views/LocalModList/LocalModCard.vue index 33a6af0c1..26c028207 100644 --- a/src/components/views/LocalModList/LocalModCard.vue +++ b/src/components/views/LocalModList/LocalModCard.vue @@ -32,32 +32,30 @@ const canBeDisabled = computed(() => !store.getters['isModLoader'](props.mod.get const isDeprecated = computed(() => store.state.tsMods.deprecated.get(props.mod.getName()) || false); const isLatestVersion = computed(() => store.getters['tsMods/isLatestVersion'](props.mod)); const localModList = computed(() => store.state.profile.modList); +const modMap = computed((): Map => store.getters['profile/modMap']); const tsMod = computed(() => store.getters['tsMods/tsMod'](props.mod)); -async function updateDependencies() { +function updateDependencies() { if (props.mod.getDependencies().length === 0) { return; } const dependencies = props.mod.getDependencies(); - const dependencyNames = dependencies.map(dependencyStringToModName); const foundDependencies: ManifestV2[] = []; - for (const mod of localModList.value) { - if (foundDependencies.length === dependencyNames.length) { - break; - } - - if (dependencyNames.includes(mod.getName())) { + for (const depString of dependencies) { + const depName = dependencyStringToModName(depString); + const mod = modMap.value.get(depName); + if (mod !== undefined) { foundDependencies.push(mod); } } - const foundNames = foundDependencies.map((mod) => mod.getName()); + const foundNames = new Set(foundDependencies.map((mod) => mod.getName())); disabledDependencies.value = foundDependencies.filter((d) => !d.isEnabled()); missingDependencies.value = dependencies.filter( - (d) => !foundNames.includes(dependencyStringToModName(d)) + (d) => !foundNames.has(dependencyStringToModName(d)) ); } diff --git a/src/r2mm/mods/Dependants.ts b/src/r2mm/mods/Dependants.ts index 82fbad991..d11141c40 100644 --- a/src/r2mm/mods/Dependants.ts +++ b/src/r2mm/mods/Dependants.ts @@ -2,42 +2,64 @@ import ManifestV2 from '../../model/ManifestV2'; export default class Dependants { - public static getDependantList(manifestMod: ManifestV2, modList: ManifestV2[], dependantSet?: Set): Set { + private static buildDependantIndex(modList: ManifestV2[]): Map { + const index = new Map(); + for (const mod of modList) { + for (const dep of mod.getDependencies()) { + const depName = dep.substring(0, dep.lastIndexOf('-')); + if (!index.has(depName)) { + index.set(depName, []); + } + index.get(depName)!.push(mod); + } + } + return index; + } + + private static buildModMap(modList: ManifestV2[]): Map { + const map = new Map(); + for (const mod of modList) { + map.set(mod.getName(), mod); + } + return map; + } + + public static getDependantList( + manifestMod: ManifestV2, + modList: ManifestV2[], + dependantSet?: Set, + dependantIndex?: Map + ): Set { const dependants = dependantSet || new Set(); + const index = dependantIndex || this.buildDependantIndex(modList); - // For all mods - modList.forEach(mod => { - // Get mod dependencies - mod.getDependencies().forEach(dependency => { - // If mod name equals mod trying to get dependants - if (dependency.startsWith(manifestMod.getName() + "-")) { - if (!dependants.has(mod)) { - dependants.add(mod); - // Get dependants of new mod - this.getDependantList(mod, modList, dependants).forEach(recursive => { - dependants.add(recursive); - }) - } - } - }) - }) + const directDependants = index.get(manifestMod.getName()) || []; + for (const mod of directDependants) { + if (!dependants.has(mod)) { + dependants.add(mod); + this.getDependantList(mod, modList, dependants, index); + } + } return dependants; } - public static getDependencyList(manifestMod: ManifestV2, modList: ManifestV2[], dependencySet?: Set): Set { + public static getDependencyList( + manifestMod: ManifestV2, + modList: ManifestV2[], + dependencySet?: Set, + modMap?: Map + ): Set { const dependencies = dependencySet || new Set(); - manifestMod.getDependencies().forEach(dependant => { - modList.forEach(mod => { - if (dependant.startsWith(mod.getName() + "-")) { - if (!dependencies.has(mod)) { - dependencies.add(mod); - this.getDependencyList(mod, modList, dependencies).forEach(recursive => { - dependencies.add(recursive); - }) - } - } - }) - }) + const map = modMap || this.buildModMap(modList); + + for (const depString of manifestMod.getDependencies()) { + const depName = depString.substring(0, depString.lastIndexOf('-')); + const mod = map.get(depName); + if (mod !== undefined && !dependencies.has(mod)) { + dependencies.add(mod); + this.getDependencyList(mod, modList, dependencies, map); + } + } return dependencies; } diff --git a/src/store/modules/ProfileModule.ts b/src/store/modules/ProfileModule.ts index 3ee0212d4..33235324c 100644 --- a/src/store/modules/ProfileModule.ts +++ b/src/store/modules/ProfileModule.ts @@ -89,6 +89,14 @@ export default { return state.modList; }, + modMap(state): Map { + const map = new Map(); + for (const mod of state.modList) { + map.set(mod.getName(), mod); + } + return map; + }, + // Swap the ManifestV2s to ThunderstoreMods as the latter knows the version number // of the latest version, which we need when showing how mods will be updated. modsWithUpdates(state, _getters, _rootState, rootGetters): ThunderstoreMod[] {