add: stages of modpack installation
This commit is contained in:
@@ -35,6 +35,8 @@ import java.io.File;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
public final class HMCLModpackInstallTask extends Task<Void> {
|
public final class HMCLModpackInstallTask extends Task<Void> {
|
||||||
private final File zipFile;
|
private final File zipFile;
|
||||||
@@ -102,7 +104,15 @@ public final class HMCLModpackInstallTask extends Task<Void> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies.add(libraryTask.thenComposeAsync(repository::save));
|
dependencies.add(libraryTask.thenComposeAsync(repository::save));
|
||||||
dependencies.add(new MinecraftInstanceTask<>(zipFile, modpack.getEncoding(), "/minecraft", modpack, MODPACK_TYPE, repository.getModpackConfiguration(name)));
|
dependencies.add(new MinecraftInstanceTask<>(zipFile, modpack.getEncoding(), "/minecraft", modpack, MODPACK_TYPE, repository.getModpackConfiguration(name)).withStage("hmcl.modpack"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> getStages() {
|
||||||
|
return Stream.concat(
|
||||||
|
dependents.stream().flatMap(task -> task.getStages().stream()),
|
||||||
|
Stream.of("hmcl.modpack")
|
||||||
|
).collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final String MODPACK_TYPE = "HMCL";
|
public static final String MODPACK_TYPE = "HMCL";
|
||||||
|
|||||||
@@ -49,7 +49,6 @@ import org.jackhuang.hmcl.ui.construct.MessageDialogPane.MessageType;
|
|||||||
import org.jackhuang.hmcl.ui.construct.TaskExecutorDialogPane;
|
import org.jackhuang.hmcl.ui.construct.TaskExecutorDialogPane;
|
||||||
import org.jackhuang.hmcl.util.*;
|
import org.jackhuang.hmcl.util.*;
|
||||||
import org.jackhuang.hmcl.util.gson.UUIDTypeAdapter;
|
import org.jackhuang.hmcl.util.gson.UUIDTypeAdapter;
|
||||||
import org.jackhuang.hmcl.util.i18n.LocalizedTaskStages;
|
|
||||||
import org.jackhuang.hmcl.util.io.ResponseCodeException;
|
import org.jackhuang.hmcl.util.io.ResponseCodeException;
|
||||||
import org.jackhuang.hmcl.util.platform.CommandBuilder;
|
import org.jackhuang.hmcl.util.platform.CommandBuilder;
|
||||||
import org.jackhuang.hmcl.util.platform.JavaVersion;
|
import org.jackhuang.hmcl.util.platform.JavaVersion;
|
||||||
@@ -128,28 +127,26 @@ public final class LauncherHelper {
|
|||||||
Version version = MaintainTask.maintain(repository, repository.getResolvedVersion(selectedVersion));
|
Version version = MaintainTask.maintain(repository, repository.getResolvedVersion(selectedVersion));
|
||||||
Optional<String> gameVersion = GameVersion.minecraftVersion(repository.getVersionJar(version));
|
Optional<String> gameVersion = GameVersion.minecraftVersion(repository.getVersionJar(version));
|
||||||
|
|
||||||
TaskExecutor executor = Task.runAsync(() -> {
|
TaskExecutor executor = Task.allOf(
|
||||||
})
|
Task.composeAsync(null, () -> {
|
||||||
.thenComposeAsync(() -> Task.allOf(
|
if (setting.isNotCheckGame())
|
||||||
Task.composeAsync(null, () -> {
|
return null;
|
||||||
if (setting.isNotCheckGame())
|
else
|
||||||
return null;
|
return dependencyManager.checkGameCompletionAsync(version, repository.unmarkVersionLaunchedAbnormally(selectedVersion));
|
||||||
else
|
}), Task.composeAsync(null, () -> {
|
||||||
return dependencyManager.checkGameCompletionAsync(version, repository.unmarkVersionLaunchedAbnormally(selectedVersion));
|
try {
|
||||||
}), Task.composeAsync(null, () -> {
|
ModpackConfiguration<?> configuration = ModpackHelper.readModpackConfiguration(repository.getModpackConfiguration(selectedVersion));
|
||||||
try {
|
if ("Curse".equals(configuration.getType()))
|
||||||
ModpackConfiguration<?> configuration = ModpackHelper.readModpackConfiguration(repository.getModpackConfiguration(selectedVersion));
|
return new CurseCompletionTask(dependencyManager, selectedVersion);
|
||||||
if ("Curse".equals(configuration.getType()))
|
else if ("Server".equals(configuration.getType()))
|
||||||
return new CurseCompletionTask(dependencyManager, selectedVersion);
|
return new ServerModpackCompletionTask(dependencyManager, selectedVersion);
|
||||||
else if ("Server".equals(configuration.getType()))
|
else
|
||||||
return new ServerModpackCompletionTask(dependencyManager, selectedVersion);
|
return null;
|
||||||
else
|
} catch (IOException e) {
|
||||||
return null;
|
return null;
|
||||||
} catch (IOException e) {
|
}
|
||||||
return null;
|
})).withStage("launch.state.dependencies")
|
||||||
}
|
.thenComposeAsync(Task.supplyAsync((String) null, () -> {
|
||||||
})).withStage("launch.state.dependencies"))
|
|
||||||
.thenComposeAsync(() -> Task.supplyAsync((String) null, () -> {
|
|
||||||
try {
|
try {
|
||||||
return account.logIn();
|
return account.logIn();
|
||||||
} catch (CredentialExpiredException e) {
|
} catch (CredentialExpiredException e) {
|
||||||
@@ -199,11 +196,11 @@ public final class LauncherHelper {
|
|||||||
launchingLatch = new CountDownLatch(1);
|
launchingLatch = new CountDownLatch(1);
|
||||||
launchingLatch.await();
|
launchingLatch.await();
|
||||||
}).withStage("launch.state.waiting_launching"))
|
}).withStage("launch.state.waiting_launching"))
|
||||||
|
.withStagesHint(Lang.immutableListOf(
|
||||||
|
"launch.state.dependencies",
|
||||||
|
"launch.state.logging_in",
|
||||||
|
"launch.state.waiting_launching"))
|
||||||
.cancellableExecutor();
|
.cancellableExecutor();
|
||||||
executor.setStages(new LocalizedTaskStages(Lang.immutableListOf(
|
|
||||||
"launch.state.dependencies",
|
|
||||||
"launch.state.logging_in",
|
|
||||||
"launch.state.waiting_launching")));
|
|
||||||
launchingStepsPane.setExecutor(executor, false);
|
launchingStepsPane.setExecutor(executor, false);
|
||||||
executor.addTaskListener(new TaskListener() {
|
executor.addTaskListener(new TaskListener() {
|
||||||
|
|
||||||
|
|||||||
@@ -46,9 +46,10 @@ import org.jackhuang.hmcl.setting.Theme;
|
|||||||
import org.jackhuang.hmcl.task.Task;
|
import org.jackhuang.hmcl.task.Task;
|
||||||
import org.jackhuang.hmcl.task.TaskExecutor;
|
import org.jackhuang.hmcl.task.TaskExecutor;
|
||||||
import org.jackhuang.hmcl.task.TaskListener;
|
import org.jackhuang.hmcl.task.TaskListener;
|
||||||
import org.jackhuang.hmcl.task.TaskStages;
|
|
||||||
import org.jackhuang.hmcl.ui.FXUtils;
|
import org.jackhuang.hmcl.ui.FXUtils;
|
||||||
import org.jackhuang.hmcl.ui.SVG;
|
import org.jackhuang.hmcl.ui.SVG;
|
||||||
|
import org.jackhuang.hmcl.util.Lang;
|
||||||
|
import org.jackhuang.hmcl.util.StringUtils;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@@ -72,7 +73,7 @@ public final class TaskListPane extends StackPane {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void setExecutor(TaskExecutor executor) {
|
public void setExecutor(TaskExecutor executor) {
|
||||||
TaskStages stages = executor.getStages();
|
List<String> stages = Lang.removingDuplicates(executor.getStages());
|
||||||
this.executor = executor;
|
this.executor = executor;
|
||||||
executor.addTaskListener(new TaskListener() {
|
executor.addTaskListener(new TaskListener() {
|
||||||
@Override
|
@Override
|
||||||
@@ -80,10 +81,10 @@ public final class TaskListPane extends StackPane {
|
|||||||
Platform.runLater(() -> {
|
Platform.runLater(() -> {
|
||||||
stageNodes.clear();
|
stageNodes.clear();
|
||||||
listBox.clear();
|
listBox.clear();
|
||||||
stageNodes.addAll(stages.getStages().stream().map(StageNode::new).collect(Collectors.toList()));
|
stageNodes.addAll(stages.stream().map(StageNode::new).collect(Collectors.toList()));
|
||||||
stageNodes.forEach(listBox::add);
|
stageNodes.forEach(listBox::add);
|
||||||
|
|
||||||
if (stages.getStages().isEmpty()) progressNodePadding.setValue(new Insets(0, 0, 8, 0));
|
if (stages.isEmpty()) progressNodePadding.setValue(new Insets(0, 0, 8, 0));
|
||||||
else progressNodePadding.setValue(new Insets(0, 0, 8, 26));
|
else progressNodePadding.setValue(new Insets(0, 0, 8, 26));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -182,7 +183,25 @@ public final class TaskListPane extends StackPane {
|
|||||||
public StageNode(String stage) {
|
public StageNode(String stage) {
|
||||||
this.stage = stage;
|
this.stage = stage;
|
||||||
|
|
||||||
title.setText(executor.getStages().localize(stage));
|
String stageKey = StringUtils.substringBefore(stage, ':');
|
||||||
|
String stageValue = StringUtils.substringAfter(stage, ':');
|
||||||
|
String message;
|
||||||
|
|
||||||
|
// @formatter:off
|
||||||
|
switch (stageKey) {
|
||||||
|
case "hmcl.modpack": message = i18n("install.modpack"); break;
|
||||||
|
case "hmcl.modpack.download": message = i18n("launch.state.modpack"); break;
|
||||||
|
case "hmcl.install.assets": message = i18n("assets.download"); break;
|
||||||
|
case "hmcl.install.game": message = i18n("install.installer.install", i18n("install.installer.game") + " " + stageValue); break;
|
||||||
|
case "hmcl.install.forge": message = i18n("install.installer.install", i18n("install.installer.forge") + " " + stageValue); break;
|
||||||
|
case "hmcl.install.liteloader": message = i18n("install.installer.install", i18n("install.installer.liteloader") + " " + stageValue); break;
|
||||||
|
case "hmcl.install.optifine": message = i18n("install.installer.install", i18n("install.installer.optifine") + " " + stageValue); break;
|
||||||
|
case "hmcl.install.fabric": message = i18n("install.installer.install", i18n("install.installer.fabric") + " " + stageValue); break;
|
||||||
|
default: message = i18n(stageKey); break;
|
||||||
|
}
|
||||||
|
// @formatter:on
|
||||||
|
|
||||||
|
title.setText(message);
|
||||||
BorderPane.setAlignment(title, Pos.CENTER_LEFT);
|
BorderPane.setAlignment(title, Pos.CENTER_LEFT);
|
||||||
BorderPane.setMargin(title, new Insets(0, 0, 0, 8));
|
BorderPane.setMargin(title, new Insets(0, 0, 0, 8));
|
||||||
setPadding(new Insets(0, 0, 8, 4));
|
setPadding(new Insets(0, 0, 8, 4));
|
||||||
@@ -210,7 +229,7 @@ public final class TaskListPane extends StackPane {
|
|||||||
private final Label title = new Label();
|
private final Label title = new Label();
|
||||||
private final Label state = new Label();
|
private final Label state = new Label();
|
||||||
private final DoubleBinding binding = Bindings.createDoubleBinding(() ->
|
private final DoubleBinding binding = Bindings.createDoubleBinding(() ->
|
||||||
getWidth() - getPadding().getLeft() - getPadding().getRight() - 100,
|
getWidth() - getPadding().getLeft() - getPadding().getRight(),
|
||||||
paddingProperty(), widthProperty());
|
paddingProperty(), widthProperty());
|
||||||
|
|
||||||
public ProgressListNode(Task<?> task) {
|
public ProgressListNode(Task<?> task) {
|
||||||
|
|||||||
@@ -30,7 +30,6 @@ import org.jackhuang.hmcl.game.Version;
|
|||||||
import org.jackhuang.hmcl.setting.Profile;
|
import org.jackhuang.hmcl.setting.Profile;
|
||||||
import org.jackhuang.hmcl.task.DownloadException;
|
import org.jackhuang.hmcl.task.DownloadException;
|
||||||
import org.jackhuang.hmcl.task.Task;
|
import org.jackhuang.hmcl.task.Task;
|
||||||
import org.jackhuang.hmcl.task.TaskStages;
|
|
||||||
import org.jackhuang.hmcl.ui.Controllers;
|
import org.jackhuang.hmcl.ui.Controllers;
|
||||||
import org.jackhuang.hmcl.ui.construct.MessageDialogPane.MessageType;
|
import org.jackhuang.hmcl.ui.construct.MessageDialogPane.MessageType;
|
||||||
import org.jackhuang.hmcl.ui.wizard.WizardController;
|
import org.jackhuang.hmcl.ui.wizard.WizardController;
|
||||||
@@ -41,6 +40,8 @@ import org.jackhuang.hmcl.util.io.ResponseCodeException;
|
|||||||
|
|
||||||
import java.net.SocketTimeoutException;
|
import java.net.SocketTimeoutException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
||||||
@@ -77,35 +78,18 @@ public final class InstallerWizardProvider implements WizardProvider {
|
|||||||
settings.put("title", i18n("install.installer.install_online"));
|
settings.put("title", i18n("install.installer.install_online"));
|
||||||
settings.put("success_message", i18n("install.success"));
|
settings.put("success_message", i18n("install.success"));
|
||||||
settings.put("failure_callback", (FailureCallback) (settings1, exception, next) -> alertFailureMessage(exception, next));
|
settings.put("failure_callback", (FailureCallback) (settings1, exception, next) -> alertFailureMessage(exception, next));
|
||||||
settings.put("stages", new TaskStages() {
|
|
||||||
{
|
|
||||||
if (settings.containsKey("forge")) {
|
|
||||||
RemoteVersion forge = (RemoteVersion) settings.get("forge");
|
|
||||||
addStage("hmcl.install.forge", i18n("install.installer.install", i18n("install.installer.forge") + " " + forge.getSelfVersion()));
|
|
||||||
}
|
|
||||||
if (settings.containsKey("liteloader")) {
|
|
||||||
RemoteVersion liteloader = (RemoteVersion) settings.get("liteloader");
|
|
||||||
addStage("hmcl.install.liteloader", i18n("install.installer.install", i18n("install.installer.liteloader") + " " + liteloader.getSelfVersion()));
|
|
||||||
}
|
|
||||||
if (settings.containsKey("optifine")) {
|
|
||||||
RemoteVersion optifine = (RemoteVersion) settings.get("optifine");
|
|
||||||
addStage("hmcl.install.optifine", i18n("install.installer.install", i18n("install.installer.optifine") + " " + optifine.getSelfVersion()));
|
|
||||||
}
|
|
||||||
if (settings.containsKey("fabric")) {
|
|
||||||
RemoteVersion fabric = (RemoteVersion) settings.get("fabric");
|
|
||||||
addStage("hmcl.install.fabric", i18n("install.installer.install", i18n("install.installer.fabric") + " " + fabric.getSelfVersion()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Task<Version> ret = Task.supplyAsync(() -> version);
|
Task<Version> ret = Task.supplyAsync(() -> version);
|
||||||
|
List<String> stages = new ArrayList<>();
|
||||||
for (Object value : settings.values()) {
|
for (Object value : settings.values()) {
|
||||||
if (value instanceof RemoteVersion)
|
if (value instanceof RemoteVersion) {
|
||||||
ret = ret.thenComposeAsync(version -> profile.getDependency().installLibraryAsync(version, (RemoteVersion) value));
|
RemoteVersion remoteVersion = (RemoteVersion) value;
|
||||||
|
ret = ret.thenComposeAsync(version -> profile.getDependency().installLibraryAsync(version, remoteVersion));
|
||||||
|
stages.add(String.format("hmcl.install.%s:%s", remoteVersion.getLibraryId(), remoteVersion.getSelfVersion()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret.thenComposeAsync(profile.getRepository().refreshVersionsAsync());
|
return ret.thenComposeAsync(profile.getRepository().refreshVersionsAsync()).withStagesHint(stages);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ import org.jackhuang.hmcl.download.DownloadProvider;
|
|||||||
import org.jackhuang.hmcl.download.RemoteVersion;
|
import org.jackhuang.hmcl.download.RemoteVersion;
|
||||||
import org.jackhuang.hmcl.game.Version;
|
import org.jackhuang.hmcl.game.Version;
|
||||||
import org.jackhuang.hmcl.setting.Profile;
|
import org.jackhuang.hmcl.setting.Profile;
|
||||||
import org.jackhuang.hmcl.task.TaskStages;
|
|
||||||
import org.jackhuang.hmcl.ui.Controllers;
|
import org.jackhuang.hmcl.ui.Controllers;
|
||||||
import org.jackhuang.hmcl.ui.wizard.WizardController;
|
import org.jackhuang.hmcl.ui.wizard.WizardController;
|
||||||
import org.jackhuang.hmcl.ui.wizard.WizardProvider;
|
import org.jackhuang.hmcl.ui.wizard.WizardProvider;
|
||||||
@@ -57,26 +56,6 @@ public final class UpdateInstallerWizardProvider implements WizardProvider {
|
|||||||
settings.put("title", i18n("install.change_version"));
|
settings.put("title", i18n("install.change_version"));
|
||||||
settings.put("success_message", i18n("install.success"));
|
settings.put("success_message", i18n("install.success"));
|
||||||
settings.put("failure_callback", (FailureCallback) (settings1, exception, next) -> alertFailureMessage(exception, next));
|
settings.put("failure_callback", (FailureCallback) (settings1, exception, next) -> alertFailureMessage(exception, next));
|
||||||
settings.put("stages", new TaskStages() {
|
|
||||||
{
|
|
||||||
if (settings.containsKey("forge")) {
|
|
||||||
RemoteVersion forge = (RemoteVersion) settings.get("forge");
|
|
||||||
addStage("hmcl.install.forge", i18n("install.installer.install", i18n("install.installer.forge") + " " + forge.getSelfVersion()));
|
|
||||||
}
|
|
||||||
if (settings.containsKey("liteloader")) {
|
|
||||||
RemoteVersion liteloader = (RemoteVersion) settings.get("liteloader");
|
|
||||||
addStage("hmcl.install.liteloader", i18n("install.installer.install", i18n("install.installer.liteloader") + " " + liteloader.getSelfVersion()));
|
|
||||||
}
|
|
||||||
if (settings.containsKey("optifine")) {
|
|
||||||
RemoteVersion optifine = (RemoteVersion) settings.get("optifine");
|
|
||||||
addStage("hmcl.install.optifine", i18n("install.installer.install", i18n("install.installer.optifine") + " " + optifine.getSelfVersion()));
|
|
||||||
}
|
|
||||||
if (settings.containsKey("fabric")) {
|
|
||||||
RemoteVersion fabric = (RemoteVersion) settings.get("fabric");
|
|
||||||
addStage("hmcl.install.fabric", i18n("install.installer.install", i18n("install.installer.fabric") + " " + fabric.getSelfVersion()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// We remove library but not save it,
|
// We remove library but not save it,
|
||||||
// so if installation failed will not break down current version.
|
// so if installation failed will not break down current version.
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ import org.jackhuang.hmcl.download.RemoteVersion;
|
|||||||
import org.jackhuang.hmcl.setting.Profile;
|
import org.jackhuang.hmcl.setting.Profile;
|
||||||
import org.jackhuang.hmcl.task.Schedulers;
|
import org.jackhuang.hmcl.task.Schedulers;
|
||||||
import org.jackhuang.hmcl.task.Task;
|
import org.jackhuang.hmcl.task.Task;
|
||||||
import org.jackhuang.hmcl.task.TaskStages;
|
|
||||||
import org.jackhuang.hmcl.ui.wizard.WizardController;
|
import org.jackhuang.hmcl.ui.wizard.WizardController;
|
||||||
import org.jackhuang.hmcl.ui.wizard.WizardProvider;
|
import org.jackhuang.hmcl.ui.wizard.WizardProvider;
|
||||||
|
|
||||||
@@ -64,31 +63,6 @@ public final class VanillaInstallWizardProvider implements WizardProvider {
|
|||||||
settings.put("title", i18n("install.new_game"));
|
settings.put("title", i18n("install.new_game"));
|
||||||
settings.put("success_message", i18n("install.success"));
|
settings.put("success_message", i18n("install.success"));
|
||||||
settings.put("failure_callback", (FailureCallback) (settings1, exception, next) -> InstallerWizardProvider.alertFailureMessage(exception, next));
|
settings.put("failure_callback", (FailureCallback) (settings1, exception, next) -> InstallerWizardProvider.alertFailureMessage(exception, next));
|
||||||
settings.put("stages", new TaskStages() {
|
|
||||||
{
|
|
||||||
if (settings.containsKey("game")) {
|
|
||||||
RemoteVersion game = (RemoteVersion) settings.get("game");
|
|
||||||
addStage("hmcl.install.game", i18n("install.installer.install", i18n("install.installer.game") + " " + game.getSelfVersion()));
|
|
||||||
addStage("hmcl.install.assets", i18n("assets.download"));
|
|
||||||
}
|
|
||||||
if (settings.containsKey("forge")) {
|
|
||||||
RemoteVersion forge = (RemoteVersion) settings.get("forge");
|
|
||||||
addStage("hmcl.install.forge", i18n("install.installer.install", i18n("install.installer.forge") + " " + forge.getSelfVersion()));
|
|
||||||
}
|
|
||||||
if (settings.containsKey("liteloader")) {
|
|
||||||
RemoteVersion liteloader = (RemoteVersion) settings.get("liteloader");
|
|
||||||
addStage("hmcl.install.liteloader", i18n("install.installer.install", i18n("install.installer.liteloader") + " " + liteloader.getSelfVersion()));
|
|
||||||
}
|
|
||||||
if (settings.containsKey("optifine")) {
|
|
||||||
RemoteVersion optifine = (RemoteVersion) settings.get("optifine");
|
|
||||||
addStage("hmcl.install.optifine", i18n("install.installer.install", i18n("install.installer.optifine") + " " + optifine.getSelfVersion()));
|
|
||||||
}
|
|
||||||
if (settings.containsKey("fabric")) {
|
|
||||||
RemoteVersion fabric = (RemoteVersion) settings.get("fabric");
|
|
||||||
addStage("hmcl.install.fabric", i18n("install.installer.install", i18n("install.installer.fabric") + " " + fabric.getSelfVersion()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return finishVersionDownloadingAsync(settings);
|
return finishVersionDownloadingAsync(settings);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ import javafx.beans.property.StringProperty;
|
|||||||
import org.jackhuang.hmcl.task.Task;
|
import org.jackhuang.hmcl.task.Task;
|
||||||
import org.jackhuang.hmcl.task.TaskExecutor;
|
import org.jackhuang.hmcl.task.TaskExecutor;
|
||||||
import org.jackhuang.hmcl.task.TaskListener;
|
import org.jackhuang.hmcl.task.TaskListener;
|
||||||
import org.jackhuang.hmcl.task.TaskStages;
|
|
||||||
import org.jackhuang.hmcl.ui.Controllers;
|
import org.jackhuang.hmcl.ui.Controllers;
|
||||||
import org.jackhuang.hmcl.ui.construct.DialogCloseEvent;
|
import org.jackhuang.hmcl.ui.construct.DialogCloseEvent;
|
||||||
import org.jackhuang.hmcl.ui.construct.MessageDialogPane.MessageType;
|
import org.jackhuang.hmcl.ui.construct.MessageDialogPane.MessageType;
|
||||||
@@ -76,8 +75,6 @@ public interface TaskExecutorDialogWizardDisplayer extends AbstractWizardDisplay
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (settings.containsKey("stages"))
|
|
||||||
executor.setStages((TaskStages) settings.get("stages"));
|
|
||||||
pane.setExecutor(executor);
|
pane.setExecutor(executor);
|
||||||
Controllers.dialog(pane);
|
Controllers.dialog(pane);
|
||||||
executor.start();
|
executor.start();
|
||||||
|
|||||||
@@ -1,32 +0,0 @@
|
|||||||
/*
|
|
||||||
* Hello Minecraft! Launcher
|
|
||||||
* Copyright (C) 2020 huangyuhui <huanghongxun2008@126.com> and contributors
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package org.jackhuang.hmcl.util.i18n;
|
|
||||||
|
|
||||||
import org.jackhuang.hmcl.task.TaskStages;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
|
||||||
|
|
||||||
public class LocalizedTaskStages extends TaskStages {
|
|
||||||
public LocalizedTaskStages(List<String> stages) {
|
|
||||||
for (String stage : stages) {
|
|
||||||
addStage(stage, i18n(stage));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -102,7 +102,7 @@ public class DefaultDependencyManager extends AbstractDependencyManager {
|
|||||||
return versionList.loadAsync(gameVersion)
|
return versionList.loadAsync(gameVersion)
|
||||||
.thenComposeAsync(() -> installLibraryAsync(baseVersion, versionList.getVersion(gameVersion, libraryVersion)
|
.thenComposeAsync(() -> installLibraryAsync(baseVersion, versionList.getVersion(gameVersion, libraryVersion)
|
||||||
.orElseThrow(() -> new IOException("Remote library " + libraryId + " has no version " + libraryVersion))))
|
.orElseThrow(() -> new IOException("Remote library " + libraryId + " has no version " + libraryVersion))))
|
||||||
.withStage("hmcl.install." + libraryId);
|
.withStage(String.format("hmcl.install.%s:%s", libraryId, libraryVersion));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -112,7 +112,7 @@ public class DefaultDependencyManager extends AbstractDependencyManager {
|
|||||||
return removeLibraryAsync(baseVersion.resolvePreservingPatches(repository), libraryVersion.getLibraryId())
|
return removeLibraryAsync(baseVersion.resolvePreservingPatches(repository), libraryVersion.getLibraryId())
|
||||||
.thenComposeAsync(version -> libraryVersion.getInstallTask(this, version))
|
.thenComposeAsync(version -> libraryVersion.getInstallTask(this, version))
|
||||||
.thenApplyAsync(baseVersion::addPatch)
|
.thenApplyAsync(baseVersion::addPatch)
|
||||||
.thenComposeAsync(repository::save).withStage("hmcl.install." + libraryVersion.getLibraryId());
|
.thenComposeAsync(repository::save).withStage(String.format("hmcl.install.%s:%s", libraryVersion.getLibraryId(), libraryVersion.getSelfVersion()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<Version> installLibraryAsync(Version oldVersion, Path installer) {
|
public Task<Version> installLibraryAsync(Version oldVersion, Path installer) {
|
||||||
|
|||||||
@@ -21,6 +21,8 @@ import org.jackhuang.hmcl.game.Version;
|
|||||||
import org.jackhuang.hmcl.task.Task;
|
import org.jackhuang.hmcl.task.Task;
|
||||||
import org.jackhuang.hmcl.util.function.ExceptionalFunction;
|
import org.jackhuang.hmcl.util.function.ExceptionalFunction;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -47,19 +49,27 @@ public class DefaultGameBuilder extends GameBuilder {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Task<?> buildAsync() {
|
public Task<?> buildAsync() {
|
||||||
|
List<String> stages = new ArrayList<>();
|
||||||
|
|
||||||
Task<Version> libraryTask = Task.supplyAsync(() -> new Version(name));
|
Task<Version> libraryTask = Task.supplyAsync(() -> new Version(name));
|
||||||
libraryTask = libraryTask.thenComposeAsync(libraryTaskHelper(gameVersion, "game", gameVersion));
|
libraryTask = libraryTask.thenComposeAsync(libraryTaskHelper(gameVersion, "game", gameVersion));
|
||||||
|
stages.add("hmcl.install.game:" + gameVersion);
|
||||||
|
stages.add("hmcl.install.assets");
|
||||||
|
|
||||||
for (Map.Entry<String, String> entry : toolVersions.entrySet())
|
for (Map.Entry<String, String> entry : toolVersions.entrySet()) {
|
||||||
libraryTask = libraryTask.thenComposeAsync(libraryTaskHelper(gameVersion, entry.getKey(), entry.getValue()));
|
libraryTask = libraryTask.thenComposeAsync(libraryTaskHelper(gameVersion, entry.getKey(), entry.getValue()));
|
||||||
|
stages.add(String.format("hmcl.install.%s:%s", entry.getKey(), entry.getValue()));
|
||||||
|
}
|
||||||
|
|
||||||
for (RemoteVersion remoteVersion : remoteVersions)
|
for (RemoteVersion remoteVersion : remoteVersions) {
|
||||||
libraryTask = libraryTask.thenComposeAsync(version -> dependencyManager.installLibraryAsync(version, remoteVersion));
|
libraryTask = libraryTask.thenComposeAsync(version -> dependencyManager.installLibraryAsync(version, remoteVersion));
|
||||||
|
stages.add(String.format("hmcl.install.%s:%s", remoteVersion.getLibraryId(), remoteVersion.getSelfVersion()));
|
||||||
|
}
|
||||||
|
|
||||||
return libraryTask.whenComplete(exception -> {
|
return libraryTask.whenComplete(exception -> {
|
||||||
if (exception != null)
|
if (exception != null)
|
||||||
dependencyManager.getGameRepository().removeVersionFromDisk(name);
|
dependencyManager.getGameRepository().removeVersionFromDisk(name);
|
||||||
});
|
}).withStagesHint(stages);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ExceptionalFunction<Version, Task<Version>, ?> libraryTaskHelper(String gameVersion, String libraryId, String libraryVersion) {
|
private ExceptionalFunction<Version, Task<Version>, ?> libraryTaskHelper(String gameVersion, String libraryId, String libraryVersion) {
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ import java.util.LinkedList;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Task to download Minecraft jar
|
||||||
* @author huangyuhui
|
* @author huangyuhui
|
||||||
*/
|
*/
|
||||||
public final class GameDownloadTask extends Task<Void> {
|
public final class GameDownloadTask extends Task<Void> {
|
||||||
|
|||||||
@@ -69,11 +69,13 @@ public class GameInstallTask extends Task<Version> {
|
|||||||
setResult(patch);
|
setResult(patch);
|
||||||
|
|
||||||
Version version = new Version(this.version.getId()).addPatch(patch);
|
Version version = new Version(this.version.getId()).addPatch(patch);
|
||||||
dependencies.add(new GameDownloadTask(dependencyManager, remote.getGameVersion(), version)
|
dependencies.add(Task.allOf(
|
||||||
.thenComposeAsync(Task.allOf(
|
new GameDownloadTask(dependencyManager, remote.getGameVersion(), version),
|
||||||
|
Task.allOf(
|
||||||
new GameAssetDownloadTask(dependencyManager, version, GameAssetDownloadTask.DOWNLOAD_INDEX_FORCIBLY, true),
|
new GameAssetDownloadTask(dependencyManager, version, GameAssetDownloadTask.DOWNLOAD_INDEX_FORCIBLY, true),
|
||||||
new GameLibrariesTask(dependencyManager, version, true)
|
new GameLibrariesTask(dependencyManager, version, true)
|
||||||
).withStage("hmcl.install.assets").withComposeAsync(gameRepository.save(version))));
|
).withStage("hmcl.install.assets")
|
||||||
|
).withComposeAsync(gameRepository.save(version)));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,11 +32,12 @@ import org.jackhuang.hmcl.util.gson.JsonUtils;
|
|||||||
import org.jackhuang.hmcl.util.io.FileUtils;
|
import org.jackhuang.hmcl.util.io.FileUtils;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Install a downloaded CurseForge modpack.
|
* Install a downloaded CurseForge modpack.
|
||||||
@@ -105,7 +106,8 @@ public final class CurseInstallTask extends Task<Void> {
|
|||||||
} catch (JsonParseException | IOException ignore) {
|
} catch (JsonParseException | IOException ignore) {
|
||||||
}
|
}
|
||||||
this.config = config;
|
this.config = config;
|
||||||
dependents.add(new ModpackInstallTask<>(zipFile, run, modpack.getEncoding(), manifest.getOverrides(), any -> true, config));
|
dependents.add(new ModpackInstallTask<>(zipFile, run, modpack.getEncoding(), manifest.getOverrides(), any -> true, config).withStage("hmcl.modpack"));
|
||||||
|
dependents.add(new CurseCompletionTask(dependencyManager, name, manifest).withStage("hmcl.modpack.download"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -133,8 +135,15 @@ public final class CurseInstallTask extends Task<Void> {
|
|||||||
File root = repository.getVersionRoot(name);
|
File root = repository.getVersionRoot(name);
|
||||||
FileUtils.writeText(new File(root, "manifest.json"), JsonUtils.GSON.toJson(manifest));
|
FileUtils.writeText(new File(root, "manifest.json"), JsonUtils.GSON.toJson(manifest));
|
||||||
|
|
||||||
dependencies.add(new CurseCompletionTask(dependencyManager, name, manifest).withStage("hmcl.modpack.download"));
|
dependencies.add(new MinecraftInstanceTask<>(zipFile, modpack.getEncoding(), manifest.getOverrides(), manifest, MODPACK_TYPE, repository.getModpackConfiguration(name)).withStage("hmcl.modpack"));
|
||||||
dependencies.add(new MinecraftInstanceTask<>(zipFile, modpack.getEncoding(), manifest.getOverrides(), manifest, MODPACK_TYPE, repository.getModpackConfiguration(name)).withStage("hmcl.modpack.unzip"));
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> getStages() {
|
||||||
|
return Stream.concat(
|
||||||
|
dependents.stream().flatMap(task -> task.getStages().stream()),
|
||||||
|
Stream.of("hmcl.modpack", "hmcl.modpack.download")
|
||||||
|
).collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final String MODPACK_TYPE = "Curse";
|
public static final String MODPACK_TYPE = "Curse";
|
||||||
|
|||||||
@@ -43,6 +43,8 @@ import java.util.ArrayList;
|
|||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@@ -127,9 +129,9 @@ public final class MultiMCModpackInstallTask extends Task<Void> {
|
|||||||
|
|
||||||
try (FileSystem fs = CompressingUtils.readonly(zipFile.toPath()).setEncoding(modpack.getEncoding()).build()) {
|
try (FileSystem fs = CompressingUtils.readonly(zipFile.toPath()).setEncoding(modpack.getEncoding()).build()) {
|
||||||
if (Files.exists(fs.getPath("/" + manifest.getName() + "/.minecraft")))
|
if (Files.exists(fs.getPath("/" + manifest.getName() + "/.minecraft")))
|
||||||
dependents.add(new ModpackInstallTask<>(zipFile, run, modpack.getEncoding(), "/" + manifest.getName() + "/.minecraft", any -> true, config));
|
dependents.add(new ModpackInstallTask<>(zipFile, run, modpack.getEncoding(), "/" + manifest.getName() + "/.minecraft", any -> true, config).withStage("hmcl.modpack"));
|
||||||
else if (Files.exists(fs.getPath("/" + manifest.getName() + "/minecraft")))
|
else if (Files.exists(fs.getPath("/" + manifest.getName() + "/minecraft")))
|
||||||
dependents.add(new ModpackInstallTask<>(zipFile, run, modpack.getEncoding(), "/" + manifest.getName() + "/minecraft", any -> true, config));
|
dependents.add(new ModpackInstallTask<>(zipFile, run, modpack.getEncoding(), "/" + manifest.getName() + "/minecraft", any -> true, config).withStage("hmcl.modpack"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -173,7 +175,15 @@ public final class MultiMCModpackInstallTask extends Task<Void> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies.add(repository.save(version));
|
dependencies.add(repository.save(version));
|
||||||
dependencies.add(new MinecraftInstanceTask<>(zipFile, modpack.getEncoding(), "/" + manifest.getName() + "/minecraft", manifest, MODPACK_TYPE, repository.getModpackConfiguration(name)));
|
dependencies.add(new MinecraftInstanceTask<>(zipFile, modpack.getEncoding(), "/" + manifest.getName() + "/minecraft", manifest, MODPACK_TYPE, repository.getModpackConfiguration(name)).withStage("hmcl.modpack"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> getStages() {
|
||||||
|
return Stream.concat(
|
||||||
|
dependents.stream().flatMap(task -> task.getStages().stream()),
|
||||||
|
Stream.of("hmcl.modpack")
|
||||||
|
).collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final String MODPACK_TYPE = "MultiMC";
|
public static final String MODPACK_TYPE = "MultiMC";
|
||||||
|
|||||||
@@ -34,6 +34,8 @@ import java.io.File;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
public class ServerModpackLocalInstallTask extends Task<Void> {
|
public class ServerModpackLocalInstallTask extends Task<Void> {
|
||||||
|
|
||||||
@@ -79,7 +81,7 @@ public class ServerModpackLocalInstallTask extends Task<Void> {
|
|||||||
}
|
}
|
||||||
} catch (JsonParseException | IOException ignore) {
|
} catch (JsonParseException | IOException ignore) {
|
||||||
}
|
}
|
||||||
dependents.add(new ModpackInstallTask<>(zipFile, run, modpack.getEncoding(), "/overrides", any -> true, config));
|
dependents.add(new ModpackInstallTask<>(zipFile, run, modpack.getEncoding(), "/overrides", any -> true, config).withStage("hmcl.modpack"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -94,7 +96,15 @@ public class ServerModpackLocalInstallTask extends Task<Void> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute() throws Exception {
|
public void execute() throws Exception {
|
||||||
dependencies.add(new MinecraftInstanceTask<>(zipFile, modpack.getEncoding(), "/overrides", manifest, MODPACK_TYPE, repository.getModpackConfiguration(name)));
|
dependencies.add(new MinecraftInstanceTask<>(zipFile, modpack.getEncoding(), "/overrides", manifest, MODPACK_TYPE, repository.getModpackConfiguration(name)).withStage("hmcl.modpack"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> getStages() {
|
||||||
|
return Stream.concat(
|
||||||
|
dependents.stream().flatMap(task -> task.getStages().stream()),
|
||||||
|
Stream.of("hmcl.modpack")
|
||||||
|
).collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final String MODPACK_TYPE = "Server";
|
public static final String MODPACK_TYPE = "Server";
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import javafx.beans.property.ReadOnlyStringProperty;
|
|||||||
import javafx.beans.property.ReadOnlyStringWrapper;
|
import javafx.beans.property.ReadOnlyStringWrapper;
|
||||||
import org.jackhuang.hmcl.event.EventManager;
|
import org.jackhuang.hmcl.event.EventManager;
|
||||||
import org.jackhuang.hmcl.util.InvocationDispatcher;
|
import org.jackhuang.hmcl.util.InvocationDispatcher;
|
||||||
|
import org.jackhuang.hmcl.util.Lang;
|
||||||
import org.jackhuang.hmcl.util.Logging;
|
import org.jackhuang.hmcl.util.Logging;
|
||||||
import org.jackhuang.hmcl.util.ReflectionHelper;
|
import org.jackhuang.hmcl.util.ReflectionHelper;
|
||||||
import org.jackhuang.hmcl.util.function.ExceptionalConsumer;
|
import org.jackhuang.hmcl.util.function.ExceptionalConsumer;
|
||||||
@@ -34,12 +35,15 @@ import org.jackhuang.hmcl.util.function.ExceptionalSupplier;
|
|||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
import java.util.concurrent.Callable;
|
import java.util.concurrent.Callable;
|
||||||
import java.util.concurrent.CancellationException;
|
import java.util.concurrent.CancellationException;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Disposable task.
|
* Disposable task.
|
||||||
@@ -91,13 +95,17 @@ public abstract class Task<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* You must initialize stage in preExecute.
|
* You must initialize stage in constructor.
|
||||||
* @param stage the stage
|
* @param stage the stage
|
||||||
*/
|
*/
|
||||||
final void setStage(String stage) {
|
final void setStage(String stage) {
|
||||||
this.stage = stage;
|
this.stage = stage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<String> getStages() {
|
||||||
|
return getStage() == null ? Collections.emptyList() : Collections.singletonList(getStage());
|
||||||
|
}
|
||||||
|
|
||||||
// state
|
// state
|
||||||
private TaskState state = TaskState.READY;
|
private TaskState state = TaskState.READY;
|
||||||
|
|
||||||
@@ -688,6 +696,11 @@ public abstract class Task<T> {
|
|||||||
public boolean isRelyingOnDependents() {
|
public boolean isRelyingOnDependents() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> getStages() {
|
||||||
|
return Lang.merge(Task.this.getStages(), super.getStages());
|
||||||
|
}
|
||||||
}.setExecutor(executor).setName(getCaller());
|
}.setExecutor(executor).setName(getCaller());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -763,11 +776,31 @@ public abstract class Task<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Task<T> withStage(String stage) {
|
public Task<T> withStage(String stage) {
|
||||||
StageTask<T> task = new StageTask<>(this);
|
StageTask task = new StageTask();
|
||||||
task.setStage(stage);
|
task.setStage(stage);
|
||||||
return task;
|
return task;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Task<T> withStagesHint(List<String> stages) {
|
||||||
|
return new Task<T>() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<Task<?>> getDependents() {
|
||||||
|
return Collections.singleton(Task.this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute() throws Exception {
|
||||||
|
setResult(Task.this.getResult());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> getStages() {
|
||||||
|
return stages;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
public static Task<Void> runAsync(ExceptionalRunnable<?> closure) {
|
public static Task<Void> runAsync(ExceptionalRunnable<?> closure) {
|
||||||
return runAsync(Schedulers.defaultScheduler(), closure);
|
return runAsync(Schedulers.defaultScheduler(), closure);
|
||||||
}
|
}
|
||||||
@@ -803,6 +836,11 @@ public abstract class Task<T> {
|
|||||||
public Collection<Task<?>> getDependencies() {
|
public Collection<Task<?>> getDependencies() {
|
||||||
return then == null ? Collections.emptySet() : Collections.singleton(then);
|
return then == null ? Collections.emptySet() : Collections.singleton(then);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> getStages() {
|
||||||
|
return Lang.merge(super.getStages(), then == null ? null : then.getStages());
|
||||||
|
}
|
||||||
}.setName(name);
|
}.setName(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -862,6 +900,11 @@ public abstract class Task<T> {
|
|||||||
public Collection<Task<?>> getDependents() {
|
public Collection<Task<?>> getDependents() {
|
||||||
return tasks;
|
return tasks;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> getStages() {
|
||||||
|
return tasks.stream().flatMap(task -> task.getStages().stream()).collect(Collectors.toList());
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -929,6 +972,11 @@ public abstract class Task<T> {
|
|||||||
public void execute() throws Exception {
|
public void execute() throws Exception {
|
||||||
setResult(callable.apply(Task.this.getResult()));
|
setResult(callable.apply(Task.this.getResult()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> getStages() {
|
||||||
|
return Lang.merge(Task.this.getStages(), super.getStages());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -988,22 +1036,30 @@ public abstract class Task<T> {
|
|||||||
public boolean isRelyingOnDependents() {
|
public boolean isRelyingOnDependents() {
|
||||||
return relyingOnDependents;
|
return relyingOnDependents;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> getStages() {
|
||||||
|
return Stream.of(Task.this.getStages(), super.getStages(), succ == null ? Collections.<String>emptyList() : succ.getStages())
|
||||||
|
.flatMap(Collection::stream)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class StageTask<T> extends Task<T> {
|
public class StageTask extends Task<T> {
|
||||||
private final Task<T> task;
|
|
||||||
StageTask(Task<T> task) {
|
|
||||||
this.task = task;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<Task<?>> getDependents() {
|
public Collection<Task<?>> getDependents() {
|
||||||
return Collections.singleton(task);
|
return Collections.singleton(Task.this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute() throws Exception {
|
public void execute() throws Exception {
|
||||||
setResult(task.getResult());
|
setResult(Task.this.getResult());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> getStages() {
|
||||||
|
return Lang.merge(Task.this.getStages(), super.getStages());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,10 +30,11 @@ public abstract class TaskExecutor {
|
|||||||
protected final AtomicInteger totTask = new AtomicInteger(0);
|
protected final AtomicInteger totTask = new AtomicInteger(0);
|
||||||
protected final AtomicBoolean cancelled = new AtomicBoolean(false);
|
protected final AtomicBoolean cancelled = new AtomicBoolean(false);
|
||||||
protected Exception exception;
|
protected Exception exception;
|
||||||
private TaskStages stages = TaskStages.EMPTY;
|
private final List<String> stages;
|
||||||
|
|
||||||
public TaskExecutor(Task<?> task) {
|
public TaskExecutor(Task<?> task) {
|
||||||
this.firstTask = task;
|
this.firstTask = task;
|
||||||
|
this.stages = task.getStages();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addTaskListener(TaskListener taskListener) {
|
public void addTaskListener(TaskListener taskListener) {
|
||||||
@@ -66,11 +67,7 @@ public abstract class TaskExecutor {
|
|||||||
return totTask.get();
|
return totTask.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
public TaskStages getStages() {
|
public List<String> getStages() {
|
||||||
return stages;
|
return stages;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setStages(TaskStages stages) {
|
|
||||||
this.stages = stages;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,43 +0,0 @@
|
|||||||
/*
|
|
||||||
* Hello Minecraft! Launcher
|
|
||||||
* Copyright (C) 2020 huangyuhui <huanghongxun2008@126.com> and contributors
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package org.jackhuang.hmcl.task;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class TaskStages {
|
|
||||||
public static final TaskStages EMPTY = new TaskStages();
|
|
||||||
|
|
||||||
private final List<String> stages = new ArrayList<>();
|
|
||||||
private final Map<String, String> localization = new HashMap<>();
|
|
||||||
|
|
||||||
protected void addStage(String stage, String localizedMessage) {
|
|
||||||
stages.add(stage);
|
|
||||||
localization.put(stage, localizedMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<String> getStages() {
|
|
||||||
return stages;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String localize(String stage) {
|
|
||||||
return localization.get(stage);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -112,6 +112,12 @@ public final class Lang {
|
|||||||
return operator.apply(a, b);
|
return operator.apply(a, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static <T> List<T> removingDuplicates(List<T> list) {
|
||||||
|
LinkedHashSet<T> set = new LinkedHashSet<>(list.size());
|
||||||
|
set.addAll(list);
|
||||||
|
return new ArrayList<>(set);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Join two collections into one list.
|
* Join two collections into one list.
|
||||||
*
|
*
|
||||||
|
|||||||
Reference in New Issue
Block a user