Do not run GameVersion.minecraftVersion on UI thread

This commit is contained in:
yushijinhun 2019-02-24 12:25:19 +08:00
parent 7fcd4d94a6
commit 9f85e4a63b
No known key found for this signature in database
GPG Key ID: 5BC167F73EA558E4
2 changed files with 32 additions and 8 deletions

View File

@ -17,6 +17,7 @@
*/
package org.jackhuang.hmcl.ui.versions;
import javafx.application.Platform;
import javafx.beans.property.*;
import javafx.scene.control.Control;
import javafx.scene.control.Skin;
@ -25,11 +26,20 @@ import org.jackhuang.hmcl.download.LibraryAnalyzer;
import org.jackhuang.hmcl.game.GameVersion;
import org.jackhuang.hmcl.setting.Profile;
import static org.jackhuang.hmcl.util.Lang.handleUncaught;
import static org.jackhuang.hmcl.util.Lang.threadPool;
import static org.jackhuang.hmcl.util.StringUtils.removePrefix;
import static org.jackhuang.hmcl.util.StringUtils.removeSuffix;
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class GameItem extends Control {
private static final ThreadPoolExecutor POOL_VERSION_RESOLVE = threadPool("VersionResolve", true, 1, 1, TimeUnit.SECONDS);
private final Profile profile;
private final String version;
private final StringProperty title = new SimpleStringProperty();
@ -40,16 +50,19 @@ public class GameItem extends Control {
this.profile = profile;
this.version = id;
String game = GameVersion.minecraftVersion(profile.getRepository().getVersionJar(id)).orElse("Unknown");
StringBuilder libraries = new StringBuilder(game);
LibraryAnalyzer analyzer = LibraryAnalyzer.analyze(profile.getRepository().getVersion(id));
analyzer.getForge().ifPresent(library -> libraries.append(", ").append(i18n("install.installer.forge")).append(": ").append(modifyVersion(game, library.getVersion().replaceAll("(?i)forge", ""))));
analyzer.getLiteLoader().ifPresent(library -> libraries.append(", ").append(i18n("install.installer.liteloader")).append(": ").append(modifyVersion(game, library.getVersion().replaceAll("(?i)liteloader", ""))));
analyzer.getOptiFine().ifPresent(library -> libraries.append(", ").append(i18n("install.installer.optifine")).append(": ").append(modifyVersion(game, library.getVersion().replaceAll("(?i)optifine", ""))));
// GameVersion.minecraftVersion() is a time-costing job (up to ~200 ms)
CompletableFuture.supplyAsync(() -> GameVersion.minecraftVersion(profile.getRepository().getVersionJar(id)).orElse("Unknown"), POOL_VERSION_RESOLVE)
.thenAcceptAsync(game -> {
StringBuilder libraries = new StringBuilder(game);
LibraryAnalyzer analyzer = LibraryAnalyzer.analyze(profile.getRepository().getVersion(id));
analyzer.getForge().ifPresent(library -> libraries.append(", ").append(i18n("install.installer.forge")).append(": ").append(modifyVersion(game, library.getVersion().replaceAll("(?i)forge", ""))));
analyzer.getLiteLoader().ifPresent(library -> libraries.append(", ").append(i18n("install.installer.liteloader")).append(": ").append(modifyVersion(game, library.getVersion().replaceAll("(?i)liteloader", ""))));
analyzer.getOptiFine().ifPresent(library -> libraries.append(", ").append(i18n("install.installer.optifine")).append(": ").append(modifyVersion(game, library.getVersion().replaceAll("(?i)optifine", ""))));
subtitle.set(libraries.toString());
}, Platform::runLater)
.exceptionally(handleUncaught);
title.set(id);
subtitle.set(libraries.toString());
image.set(profile.getRepository().getVersionIconImage(version));
}

View File

@ -25,6 +25,7 @@ import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;
import java.util.function.Function;
/**
*
@ -199,6 +200,16 @@ public final class Lang {
return t;
}
/**
* This is a useful function to prevent exceptions being eaten when using CompletableFuture.
* You can write:
* ... .exceptionally(handleUncaught);
*/
public static final Function<Throwable, Void> handleUncaught = e -> {
handleUncaughtException(e);
return null;
};
public static void handleUncaughtException(Throwable e) {
Thread.currentThread().getUncaughtExceptionHandler().uncaughtException(Thread.currentThread(), e);
}