-
Notifications
You must be signed in to change notification settings - Fork 197
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improve performance when uninstalling multiple mods at once #1155
Conversation
There's three methods that control how mods are uninstalled: uninstallModRequireConfirmation, which calls performUninstallMod directly if the mod has no dependants, and uninstallMod if the mod has dependencies. uninstallMod in turn calls performUninstallMod for the mod and all the dependants separately. This commit does the following changes: - By default, performUninstallMod now calls updateModListAfterChange helper, which differs from the original implementation in that it also calls filterModList method - Since uninstallModRequireConfirmation calls performUninstallMod, it no longer needs to call filterModList directly - performUninstallMod also accepts a new boolean parameter which can be used to prevent it from calling updateModListAfterChange - uninstallMod uses the said parameter to prevent the updateModListAfterChange getting called after each individual mod is uninstalled. It calls updateModListAfterChange itself directly in the end As far as I can tell this has no ill effects to the end result, i.e. the profile files that remain on the disk appear to be identical. The only downside I'm aware of is that the modal that shows the list of mods no longer gets updated during the process, so it might appear to the user that nothing happens. The benefit is that the process takes significantly less time when uninstalling a mod with lots of dependants. Prior to changes uninstalling BepInEx from a profile that contained 109 mods took 147 seconds, while after the changes it "only" takes 24 seconds.
This works as an indicator to the user that something is happening in case the uninstallation of multiple mods takes a bit longer.
If this is seen as good idea, similar optimizations can be done to disabling/enabling mods. |
async uninstallMod(vueMod: any) { | ||
let mod: ManifestV2 = new ManifestV2().fromReactive(vueMod); | ||
try { | ||
for (const dependant of Dependants.getDependantList(mod, this.modifiableModList)) { | ||
const result = await this.performUninstallMod(dependant); | ||
this.modBeingUninstalled = dependant.getName(); | ||
const result = await this.performUninstallMod(dependant, false); | ||
if (result instanceof R2Error) { | ||
this.$emit('error', result); | ||
this.modBeingUninstalled = null; | ||
return; | ||
} | ||
} | ||
const result = await this.performUninstallMod(mod); | ||
this.modBeingUninstalled = mod.getName(); | ||
const result = await this.performUninstallMod(mod, false); | ||
if (result instanceof R2Error) { | ||
this.$emit('error', result); | ||
this.modBeingUninstalled = null; | ||
return; | ||
} | ||
} catch (e) { | ||
// Failed to uninstall mod. | ||
const err: Error = e as Error; | ||
this.$emit('error', err); | ||
this.modBeingUninstalled = null; | ||
LoggerProvider.instance.Log(LogSeverity.ACTION_STOPPED, `${err.name}\n-> ${err.message}`); | ||
} | ||
this.selectedManifestMod = null; | ||
this.modBeingUninstalled = null; | ||
const result: ManifestV2[] | R2Error = await ProfileModList.getModList(this.contextProfile!); | ||
if (result instanceof R2Error) { | ||
this.$emit('error', result); | ||
return; | ||
} | ||
await this.$store.dispatch("updateModList", result); | ||
const err = await ConflictManagementProvider.instance.resolveConflicts(result, this.contextProfile!); | ||
if (err instanceof R2Error) { | ||
this.$emit('error', err); | ||
} | ||
this.filterModList(); | ||
await this.updateModListAfterChange(result); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like there are a handful of code paths here which could in theory apply changes without refreshing the mod list, would it make sense to always refresh it before returning?
I'll push that change on top of this before merging since it seems a bit less prone to state management bugs that way.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done in b64c89c
Make sure the profile mod list is refreshed with the latest information even if the uninstall logic exits midway.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tested this locally and everything seems to work as expected
This is probably best reviewed commit by commit.