Skip to content

Commit 0ddd566

Browse files
Simplify download logic by omitting callback
1 parent 24dcf1a commit 0ddd566

File tree

3 files changed

+98
-93
lines changed

3 files changed

+98
-93
lines changed

Diff for: src/components/views/DownloadModModal.vue

+44-35
Original file line numberDiff line numberDiff line change
@@ -60,31 +60,30 @@ import ProfileModList from '../../r2mm/mods/ProfileModList';
6060
store: Store<any>
6161
): Promise<void> {
6262
return new Promise(async (resolve, reject) => {
63-
const tsMod = combo.getMod();
64-
const tsVersion = combo.getVersion();
6563
6664
const assignId = await store.dispatch(
6765
'download/addDownload',
68-
[`${tsMod.getName()} (${tsVersion.getVersionNumber().toString()})`]
66+
[`${combo.getMod().getName()} (${combo.getVersion().getVersionNumber().toString()})`]
6967
);
7068
71-
setTimeout(() => {
72-
ThunderstoreDownloaderProvider.instance.download(profile.asImmutableProfile(), tsMod, tsVersion, ignoreCache, (progress: number, modName: string, status: number, err: R2Error | null) => {
73-
try {
74-
if (status === StatusEnum.FAILURE) {
75-
store.commit('download/updateDownload', {assignId, failed: true});
76-
if (err !== null) {
77-
DownloadMixin.addSolutionsToError(err);
78-
return reject(err);
69+
setTimeout(async () => {
70+
try {
71+
const downloadedMods = await ThunderstoreDownloaderProvider.instance.download(profile.asImmutableProfile(), combo, ignoreCache, (progress: number, modName: string, status: number, err: R2Error | null) => {
72+
try {
73+
if (status === StatusEnum.FAILURE) {
74+
store.commit('download/updateDownload', {assignId, failed: true});
75+
if (err !== null) {
76+
DownloadMixin.addSolutionsToError(err);
77+
return reject(err);
78+
}
79+
} else if (status === StatusEnum.PENDING) {
80+
store.commit('download/updateDownload', {assignId, progress, modName});
7981
}
80-
} else if (status === StatusEnum.PENDING) {
81-
store.commit('download/updateDownload', {assignId, progress, modName});
82+
} catch (e) {
83+
return reject(e);
8284
}
83-
} catch (e) {
84-
return reject(e);
85-
}
86-
}, async (downloadedMods: ThunderstoreCombo[]) => {
87-
ProfileModList.requestLock(async () => {
85+
});
86+
await ProfileModList.requestLock(async () => {
8887
for (const combo of downloadedMods) {
8988
try {
9089
await DownloadModModal.installModAfterDownload(profile, combo.getMod(), combo.getVersion());
@@ -103,7 +102,9 @@ import ProfileModList from '../../r2mm/mods/ProfileModList';
103102
}
104103
return resolve();
105104
});
106-
});
105+
} catch (e) {
106+
store.commit('error/handleError', R2Error.fromThrownValue(e));
107+
}
107108
}, 1);
108109
});
109110
}
@@ -117,26 +118,34 @@ import ProfileModList from '../../r2mm/mods/ProfileModList';
117118
);
118119
119120
this.$store.commit('download/setIsModProgressModalOpen', true);
120-
setTimeout(() => {
121-
ThunderstoreDownloaderProvider.instance.download(this.profile.asImmutableProfile(), tsMod, tsVersion, this.ignoreCache, (progress: number, modName: string, status: number, err: R2Error | null) => {
122-
try {
123-
if (status === StatusEnum.FAILURE) {
124-
this.$store.commit('download/setIsModProgressModalOpen', false);
125-
this.$store.commit('download/updateDownload', {assignId, failed: true});
126-
if (err !== null) {
127-
DownloadMixin.addSolutionsToError(err);
128-
throw err;
121+
122+
const tsCombo = new ThunderstoreCombo();
123+
tsCombo.setMod(tsMod);
124+
tsCombo.setVersion(tsVersion);
125+
126+
setTimeout(async () => {
127+
try {
128+
const downloadedMods = await ThunderstoreDownloaderProvider.instance.download(this.profile.asImmutableProfile(), tsCombo, this.ignoreCache, (progress: number, modName: string, status: number, err: R2Error | null) => {
129+
try {
130+
if (status === StatusEnum.FAILURE) {
131+
this.$store.commit('download/setIsModProgressModalOpen', false);
132+
this.$store.commit('download/updateDownload', {assignId, failed: true});
133+
if (err !== null) {
134+
DownloadMixin.addSolutionsToError(err);
135+
throw err;
136+
}
137+
} else if (status === StatusEnum.PENDING) {
138+
this.$store.commit('download/updateDownload', {assignId, progress, modName});
129139
}
130-
} else if (status === StatusEnum.PENDING) {
131-
this.$store.commit('download/updateDownload', {assignId, progress, modName});
140+
} catch (e) {
141+
this.$store.commit('error/handleError', R2Error.fromThrownValue(e));
132142
}
133-
} catch (e) {
134-
this.$store.commit('error/handleError', R2Error.fromThrownValue(e));
135-
}
136-
}, async (downloadedMods) => {
143+
});
137144
await this.downloadCompletedCallback(downloadedMods);
138145
this.$store.commit('download/setIsModProgressModalOpen', false);
139-
});
146+
} catch (e) {
147+
this.$store.commit('error/handleError', R2Error.fromThrownValue(e));
148+
}
140149
}, 1);
141150
}
142151

Diff for: src/providers/ror2/downloading/ThunderstoreDownloaderProvider.ts

+10-10
Original file line numberDiff line numberDiff line change
@@ -49,17 +49,17 @@ export default abstract class ThunderstoreDownloaderProvider {
4949
/**
5050
* A top-level method to download the latest version of a mod including its dependencies.
5151
*
52-
* @param profile The profile the mod is downloaded for (needed to prevent dependencies from updating existing mods).
53-
* @param mod The mod to be downloaded.
54-
* @param modVersion The version of the mod to download.
55-
* @param ignoreCache Download mod even if it already exists in the cache.
56-
* @param callback Callback to show the current state of the downloads.
57-
* @param completedCallback Callback to perform final actions against. Only called if {@param callback} has not returned a failed status.
52+
* @param profile The profile the mod is downloaded for (needed to prevent dependencies from updating existing mods).
53+
* @param combo The combo to be downloaded.
54+
* @param ignoreCache Download mod even if it already exists in the cache.
55+
* @param totalProgressCallback Callback to show the combined state of all the downloads.
5856
*/
59-
public abstract download(profile: ImmutableProfile, mod: ThunderstoreMod, modVersion: ThunderstoreVersion,
60-
ignoreCache: boolean,
61-
callback: (progress: number, modName: string, status: number, err: R2Error | null) => void,
62-
completedCallback: (modList: ThunderstoreCombo[]) => void): void;
57+
public abstract download(
58+
profile: ImmutableProfile,
59+
combo: ThunderstoreCombo,
60+
ignoreCache: boolean,
61+
totalProgressCallback: (progress: number, modName: string, status: number, err: R2Error | null) => void
62+
): Promise<ThunderstoreCombo[]>;
6363

6464
/**
6565
* A top-level method to download exact versions of exported mods.

Diff for: src/r2mm/downloading/BetterThunderstoreDownloader.ts

+44-48
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
import ManifestV2 from "src/model/ManifestV2";
21
import ThunderstoreVersion from '../../model/ThunderstoreVersion';
32
import ThunderstoreMod from '../../model/ThunderstoreMod';
43
import StatusEnum from '../../model/enums/StatusEnum';
54
import axios, { AxiosResponse } from 'axios';
5+
import ManifestV2 from "../../model/ManifestV2";
66
import ThunderstoreCombo from '../../model/ThunderstoreCombo';
77
import ZipExtract from '../installing/ZipExtract';
88
import R2Error from '../../model/errors/R2Error';
@@ -83,68 +83,64 @@ export default class BetterThunderstoreDownloader extends ThunderstoreDownloader
8383
});
8484
}
8585

86-
public async download(profile: ImmutableProfile, mod: ThunderstoreMod, modVersion: ThunderstoreVersion,
87-
ignoreCache: boolean,
88-
callback: (progress: number, modName: string, status: number, err: R2Error | null) => void,
89-
completedCallback: (modList: ThunderstoreCombo[]) => void) {
86+
public async download(
87+
profile: ImmutableProfile,
88+
combo: ThunderstoreCombo,
89+
ignoreCache: boolean,
90+
totalProgressCallback: (progress: number, modName: string, status: number, err: R2Error | null) => void
91+
): Promise<ThunderstoreCombo[]> {
9092

9193
const modList = await ProfileModList.getModList(profile);
9294
if (modList instanceof R2Error) {
93-
return callback(0, mod.getName(), StatusEnum.FAILURE, modList);
95+
totalProgressCallback(0, combo.getMod().getName(), StatusEnum.FAILURE, modList);
96+
throw modList;
9497
}
9598

96-
let dependencies: ThunderstoreCombo[] = [];
97-
await this.buildDependencySet(modVersion, dependencies, DependencySetBuilderMode.USE_EXACT_VERSION);
98-
this.sortDependencyOrder(dependencies);
99-
const combo = new ThunderstoreCombo();
100-
combo.setMod(mod);
101-
combo.setVersion(modVersion);
102-
103-
dependencies = await this.determineDependencyVersions(dependencies, combo, modVersion, modList);
104-
let downloadableDependencySize = this.calculateInitialDownloadSize(dependencies);
99+
let dependencies = await this.getDependenciesWithCorrectVersions(combo, modList);
100+
const allModsToDownload = [...dependencies, combo];
105101

106102
let downloadCount = 0;
107-
await this.downloadAndSave(combo, ignoreCache, async (progress: number, status: number, err: R2Error | null) => {
103+
const singleModProgressCallback = (progress: number, status: number, err: R2Error | null) => {
108104
if (status === StatusEnum.FAILURE) {
109-
callback(0, mod.getName(), status, err);
110-
} else if (status === StatusEnum.PENDING) {
111-
callback(this.generateProgressPercentage(progress, downloadCount, downloadableDependencySize + 1), mod.getName(), status, err);
105+
throw err;
106+
}
107+
108+
let totalProgress: number;
109+
if (status === StatusEnum.PENDING) {
110+
totalProgress = this.generateProgressPercentage(progress, downloadCount, allModsToDownload.length);
112111
} else if (status === StatusEnum.SUCCESS) {
112+
totalProgress = this.generateProgressPercentage(100, downloadCount, allModsToDownload.length);
113113
downloadCount += 1;
114-
// If no dependencies, end here.
115-
if (dependencies.length === 0) {
116-
callback(100, mod.getName(), StatusEnum.PENDING, err);
117-
completedCallback([combo]);
118-
return;
119-
}
114+
} else {
115+
console.error(`Ignore unknown status code "${status}"`);
116+
return;
117+
}
118+
totalProgressCallback(totalProgress, combo.getMod().getName(), status, err);
119+
}
120120

121-
// If dependencies, queue and download.
122-
await this.queueDownloadDependencies(dependencies.entries(), ignoreCache, (progress: number, modName: string, status: number, err: R2Error | null) => {
123-
if (status === StatusEnum.FAILURE) {
124-
callback(0, modName, status, err);
125-
} else if (status === StatusEnum.PENDING) {
126-
callback(this.generateProgressPercentage(progress, downloadCount, downloadableDependencySize + 1), modName, status, err);
127-
} else if (status === StatusEnum.SUCCESS) {
128-
callback(this.generateProgressPercentage(progress, downloadCount, downloadableDependencySize + 1), modName, StatusEnum.PENDING, err);
129-
downloadCount += 1;
130-
if (downloadCount >= dependencies.length + 1) {
131-
callback(100, modName, StatusEnum.PENDING, err);
132-
completedCallback([...dependencies, combo]);
133-
}
134-
}
135-
});
121+
for (const combo of allModsToDownload) {
122+
if (!ignoreCache && await this.isVersionAlreadyDownloaded(combo)) {
123+
totalProgressCallback(100, combo.getMod().getName(), StatusEnum.SUCCESS, null);
124+
continue;
136125
}
137-
})
126+
127+
try {
128+
const response = await this._downloadCombo(combo, singleModProgressCallback);
129+
await this._saveDownloadResponse(response, combo, singleModProgressCallback);
130+
} catch(e) {
131+
throw R2Error.fromThrownValue(e, `Failed to download mod ${combo.getVersion().getFullName()}`);
132+
}
133+
}
134+
return allModsToDownload;
138135
}
139136

140137
// If combo is a modpack, use the modpack's dependency versions. If it isn't, get the latest versions.
141-
public async determineDependencyVersions(dependencies: ThunderstoreCombo[], combo: ThunderstoreCombo, modVersion: ThunderstoreVersion, modList: ManifestV2[]) {
142-
let isModpack = combo.getMod().getCategories().find(value => value === "Modpacks") !== undefined;
143-
if (isModpack) {
144-
return dependencies;
145-
}
146-
dependencies = [];
147-
await this.buildDependencySet(modVersion, dependencies, DependencySetBuilderMode.USE_LATEST_VERSION);
138+
private async getDependenciesWithCorrectVersions(combo: ThunderstoreCombo, modList: ManifestV2[]) {
139+
let dependencies: ThunderstoreCombo[] = [];
140+
const isModpack = combo.getMod().getCategories().find(value => value === "Modpacks") !== undefined;
141+
const versionMode = isModpack ? DependencySetBuilderMode.USE_EXACT_VERSION : DependencySetBuilderMode.USE_LATEST_VERSION;
142+
143+
await this.buildDependencySet(combo.getVersion(), dependencies, versionMode);
148144
this.sortDependencyOrder(dependencies);
149145
// #270: Remove already-installed dependencies to prevent updating.
150146
return dependencies.filter(dep => modList.find(installed => installed.getName() === dep.getMod().getFullName()) === undefined);

0 commit comments

Comments
 (0)