Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c9e7bf7ca5 | ||
|
|
8d1e335abf | ||
|
|
c76bcb5d15 |
No files matched your search
@@ -20,10 +20,7 @@ package org.jackhuang.hmcl.game;
|
||||
import com.jfoenix.concurrency.JFXUtilities;
|
||||
import javafx.application.Platform;
|
||||
import org.jackhuang.hmcl.Main;
|
||||
import org.jackhuang.hmcl.auth.Account;
|
||||
import org.jackhuang.hmcl.auth.AuthInfo;
|
||||
import org.jackhuang.hmcl.auth.AuthenticationException;
|
||||
import org.jackhuang.hmcl.auth.SpecificCharacterSelector;
|
||||
import org.jackhuang.hmcl.auth.*;
|
||||
import org.jackhuang.hmcl.download.DefaultDependencyManager;
|
||||
import org.jackhuang.hmcl.launch.*;
|
||||
import org.jackhuang.hmcl.mod.CurseCompletionTask;
|
||||
@@ -91,6 +88,11 @@ public final class LauncherHelper {
|
||||
.then(Task.of(Main.i18n("account.methods"), variables -> {
|
||||
try {
|
||||
variables.set("account", account.logIn(new SpecificCharacterSelector(Accounts.getCurrentCharacter(account)), Settings.INSTANCE.getProxy()));
|
||||
} catch (ServerDisconnectException e) {
|
||||
if (account.canPlayOffline())
|
||||
variables.set("account", account.playOffline());
|
||||
else
|
||||
throw e;
|
||||
} catch (AuthenticationException e) {
|
||||
variables.set("account", DialogController.logIn(account));
|
||||
JFXUtilities.runInFX(() -> Controllers.dialog(launchingStepsPane));
|
||||
|
||||
@@ -23,6 +23,7 @@ import org.jackhuang.hmcl.mod.*;
|
||||
import org.jackhuang.hmcl.setting.EnumGameDirectory;
|
||||
import org.jackhuang.hmcl.setting.Profile;
|
||||
import org.jackhuang.hmcl.setting.VersionSetting;
|
||||
import org.jackhuang.hmcl.task.FinalizedCallback;
|
||||
import org.jackhuang.hmcl.task.Task;
|
||||
import org.jackhuang.hmcl.util.Constants;
|
||||
import org.jackhuang.hmcl.util.FileUtils;
|
||||
@@ -84,13 +85,13 @@ public final class ModpackHelper {
|
||||
public static Task getInstallTask(Profile profile, File zipFile, String name, Modpack modpack) {
|
||||
profile.getRepository().markVersionAsModpack(name);
|
||||
|
||||
Task finalizeTask = Task.of(() -> {
|
||||
FinalizedCallback finalizeTask = (variables, isDependentsSucceeded) -> {
|
||||
profile.getRepository().refreshVersions();
|
||||
VersionSetting vs = profile.specializeVersionSetting(name);
|
||||
profile.getRepository().undoMark(name);
|
||||
if (vs != null)
|
||||
vs.setGameDirType(EnumGameDirectory.VERSION_FOLDER);
|
||||
});
|
||||
};
|
||||
|
||||
if (modpack.getManifest() instanceof CurseManifest)
|
||||
return new CurseInstallTask(profile.getDependency(), zipFile, ((CurseManifest) modpack.getManifest()), name)
|
||||
|
||||
@@ -64,7 +64,7 @@ public final class DownloadWizardProvider implements WizardProvider {
|
||||
if (settings.containsKey("optifine"))
|
||||
builder.version("optifine", (String) settings.get("optifine"));
|
||||
|
||||
return builder.buildAsync();
|
||||
return builder.buildAsync().finalized((a, b) -> profile.getRepository().refreshVersions());
|
||||
}
|
||||
|
||||
private Task finishModpackInstallingAsync(Map<String, Object> settings) {
|
||||
|
||||
@@ -17,14 +17,20 @@
|
||||
*/
|
||||
package org.jackhuang.hmcl.ui.download;
|
||||
|
||||
import com.jfoenix.controls.JFXCheckBox;
|
||||
import com.jfoenix.controls.JFXListView;
|
||||
import com.jfoenix.controls.JFXSpinner;
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.InvalidationListener;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.layout.StackPane;
|
||||
import javafx.scene.layout.VBox;
|
||||
import org.jackhuang.hmcl.download.DownloadProvider;
|
||||
import org.jackhuang.hmcl.download.RemoteVersion;
|
||||
import org.jackhuang.hmcl.download.VersionList;
|
||||
import org.jackhuang.hmcl.task.Schedulers;
|
||||
import org.jackhuang.hmcl.download.game.GameRemoteVersionTag;
|
||||
import org.jackhuang.hmcl.download.game.GameVersionList;
|
||||
import org.jackhuang.hmcl.task.TaskExecutor;
|
||||
import org.jackhuang.hmcl.ui.FXUtils;
|
||||
import org.jackhuang.hmcl.ui.animation.ContainerAnimations;
|
||||
@@ -33,7 +39,10 @@ import org.jackhuang.hmcl.ui.wizard.Refreshable;
|
||||
import org.jackhuang.hmcl.ui.wizard.WizardController;
|
||||
import org.jackhuang.hmcl.ui.wizard.WizardPage;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public final class VersionsPage extends StackPane implements WizardPage, Refreshable {
|
||||
private final WizardController controller;
|
||||
@@ -45,7 +54,20 @@ public final class VersionsPage extends StackPane implements WizardPage, Refresh
|
||||
|
||||
@FXML
|
||||
private JFXListView<VersionsPageItem> list;
|
||||
@FXML private JFXSpinner spinner;
|
||||
@FXML
|
||||
private JFXSpinner spinner;
|
||||
@FXML
|
||||
private StackPane failedPane;
|
||||
@FXML
|
||||
private JFXCheckBox chkRelease;
|
||||
@FXML
|
||||
private JFXCheckBox chkSnapshot;
|
||||
@FXML
|
||||
private JFXCheckBox chkOld;
|
||||
@FXML
|
||||
private HBox checkPane;
|
||||
@FXML
|
||||
private VBox centrePane;
|
||||
|
||||
private final TransitionHandler transitionHandler = new TransitionHandler(this);
|
||||
private final VersionList<?> versionList;
|
||||
@@ -58,11 +80,20 @@ public final class VersionsPage extends StackPane implements WizardPage, Refresh
|
||||
this.downloadProvider = downloadProvider;
|
||||
this.libraryId = libraryId;
|
||||
this.callback = callback;
|
||||
|
||||
this.versionList = downloadProvider.getVersionListById(libraryId);
|
||||
|
||||
FXUtils.loadFXML(this, "/assets/fxml/download/versions.fxml");
|
||||
getChildren().setAll(spinner);
|
||||
|
||||
if (versionList instanceof GameVersionList) {
|
||||
centrePane.getChildren().setAll(checkPane, list);
|
||||
} else
|
||||
centrePane.getChildren().setAll(list);
|
||||
|
||||
InvalidationListener listener = o -> list.getItems().setAll(loadVersions());
|
||||
chkRelease.selectedProperty().addListener(listener);
|
||||
chkSnapshot.selectedProperty().addListener(listener);
|
||||
chkOld.selectedProperty().addListener(listener);
|
||||
|
||||
list.getSelectionModel().selectedItemProperty().addListener((a, b, newValue) -> {
|
||||
controller.getSettings().put(libraryId, newValue.getRemoteVersion().getSelfVersion());
|
||||
callback.run();
|
||||
@@ -70,17 +101,42 @@ public final class VersionsPage extends StackPane implements WizardPage, Refresh
|
||||
refresh();
|
||||
}
|
||||
|
||||
private List<VersionsPageItem> loadVersions() {
|
||||
boolean isGameVersionList = versionList instanceof GameVersionList;
|
||||
return versionList.getVersions(gameVersion).stream()
|
||||
.filter(it -> {
|
||||
if (isGameVersionList)
|
||||
switch (((GameRemoteVersionTag) it.getTag()).getType()) {
|
||||
case RELEASE:
|
||||
return chkRelease.isSelected();
|
||||
case SNAPSHOT:
|
||||
return chkSnapshot.isSelected();
|
||||
default:
|
||||
return chkOld.isSelected();
|
||||
}
|
||||
else return true;
|
||||
})
|
||||
.sorted()
|
||||
.map(VersionsPageItem::new).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refresh() {
|
||||
executor = versionList.refreshAsync(downloadProvider).subscribe(Schedulers.javafx(), () -> {
|
||||
versionList.getVersions(gameVersion).stream()
|
||||
.sorted(RemoteVersion.RemoteVersionComparator.INSTANCE)
|
||||
.forEach(version -> {
|
||||
list.getItems().add(new VersionsPageItem(version));
|
||||
});
|
||||
getChildren().setAll(spinner);
|
||||
executor = versionList.refreshAsync(downloadProvider).finalized((variables, isDependentsSucceeded) -> {
|
||||
if (isDependentsSucceeded) {
|
||||
List<VersionsPageItem> items = loadVersions();
|
||||
|
||||
transitionHandler.setContent(list, ContainerAnimations.FADE.getAnimationProducer());
|
||||
});
|
||||
Platform.runLater(() -> {
|
||||
list.getItems().setAll(items);
|
||||
transitionHandler.setContent(centrePane, ContainerAnimations.FADE.getAnimationProducer());
|
||||
});
|
||||
} else {
|
||||
Platform.runLater(() -> {
|
||||
transitionHandler.setContent(failedPane, ContainerAnimations.FADE.getAnimationProducer());
|
||||
});
|
||||
}
|
||||
}).executor().start();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -94,4 +150,9 @@ public final class VersionsPage extends StackPane implements WizardPage, Refresh
|
||||
if (executor != null)
|
||||
executor.cancel();
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void onRefresh() {
|
||||
refresh();
|
||||
}
|
||||
}
|
||||
@@ -20,7 +20,9 @@ package org.jackhuang.hmcl.ui.download;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.layout.StackPane;
|
||||
import org.jackhuang.hmcl.Main;
|
||||
import org.jackhuang.hmcl.download.RemoteVersion;
|
||||
import org.jackhuang.hmcl.download.game.GameRemoteVersionTag;
|
||||
import org.jackhuang.hmcl.ui.FXUtils;
|
||||
|
||||
/**
|
||||
@@ -38,7 +40,22 @@ public final class VersionsPageItem extends StackPane {
|
||||
|
||||
FXUtils.loadFXML(this, "/assets/fxml/download/versions-list-item.fxml");
|
||||
lblSelfVersion.setText(remoteVersion.getSelfVersion());
|
||||
lblGameVersion.setText(remoteVersion.getGameVersion());
|
||||
|
||||
if (remoteVersion.getTag() instanceof GameRemoteVersionTag) {
|
||||
switch (((GameRemoteVersionTag) remoteVersion.getTag()).getType()) {
|
||||
case RELEASE:
|
||||
lblGameVersion.setText(Main.i18n("version.game.release"));
|
||||
break;
|
||||
case SNAPSHOT:
|
||||
lblGameVersion.setText(Main.i18n("version.game.snapshot"));
|
||||
break;
|
||||
default:
|
||||
lblGameVersion.setText(Main.i18n("version.game.old"));
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
lblGameVersion.setText(remoteVersion.getGameVersion());
|
||||
}
|
||||
}
|
||||
|
||||
public RemoteVersion<?> getRemoteVersion() {
|
||||
|
||||
@@ -899,6 +899,7 @@
|
||||
.jfx-spinner > .arc {
|
||||
-fx-stroke-width: 3.0;
|
||||
-fx-fill: transparent;
|
||||
-fx-stroke: -fx-base-color;
|
||||
}
|
||||
|
||||
.first-spinner {
|
||||
@@ -957,50 +958,6 @@
|
||||
-fx-stroke-width: 5.0;
|
||||
}
|
||||
|
||||
.blue-spinner .arc {
|
||||
-fx-stroke: #4285f4;
|
||||
}
|
||||
|
||||
.red-spinner .arc {
|
||||
-fx-stroke: #db4437;
|
||||
}
|
||||
|
||||
.green-spinner .arc {
|
||||
-fx-stroke: #f4b400;
|
||||
}
|
||||
|
||||
.yellow-spinner .arc {
|
||||
-fx-stroke: -fx-base-check-color;
|
||||
}
|
||||
|
||||
.materialDesign-purple .arc {
|
||||
-fx-stroke: #ab47bc;
|
||||
}
|
||||
|
||||
.materialDesign-blue .arc {
|
||||
-fx-stroke: #2962ff;
|
||||
}
|
||||
|
||||
.materialDesign-cyan .arc {
|
||||
-fx-stroke: #00b8d4;
|
||||
}
|
||||
|
||||
.materialDesign-green .arc {
|
||||
-fx-stroke: #00c853;
|
||||
}
|
||||
|
||||
.materialDesign-yellow .arc {
|
||||
-fx-stroke: #ffd600;
|
||||
}
|
||||
|
||||
.materialDesign-orange .arc {
|
||||
-fx-stroke: #ff6d00;
|
||||
}
|
||||
|
||||
.materialDesign-red .arc {
|
||||
-fx-stroke: #d50000;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* *
|
||||
* JFX Combo Box *
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
</JFXListView>
|
||||
</StackPane>
|
||||
|
||||
<HBox alignment="BOTTOM_CENTER" style="-fx-padding: 20;">
|
||||
<HBox alignment="BOTTOM_CENTER" style="-fx-padding: 20;" pickOnBounds="false">
|
||||
<Label text="%modpack.introduction" />
|
||||
</HBox>
|
||||
</fx:root>
|
||||
@@ -3,11 +3,25 @@
|
||||
<?import com.jfoenix.controls.JFXListView?>
|
||||
<?import com.jfoenix.controls.JFXSpinner?>
|
||||
<?import javafx.scene.layout.StackPane?>
|
||||
<?import javafx.scene.control.Label?>
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
<?import javafx.scene.layout.HBox?>
|
||||
<?import com.jfoenix.controls.JFXCheckBox?>
|
||||
<fx:root xmlns="http://javafx.com/javafx"
|
||||
xmlns:fx="http://javafx.com/fxml"
|
||||
type="StackPane"
|
||||
prefHeight="400.0" prefWidth="600.0">
|
||||
<JFXSpinner fx:id="spinner" style="-fx-radius:16" styleClass="materialDesign-purple, first-spinner" />
|
||||
<JFXListView fx:id="list" styleClass="jfx-list-view">
|
||||
</JFXListView>
|
||||
<JFXSpinner fx:id="spinner" styleClass="first-spinner" />
|
||||
<VBox fx:id="centrePane">
|
||||
<HBox fx:id="checkPane" spacing="10" style="-fx-padding: 10;">
|
||||
<JFXCheckBox fx:id="chkRelease" text="%version.game.release" selected="true" />
|
||||
<JFXCheckBox fx:id="chkSnapshot" text="%version.game.snapshot" />
|
||||
<JFXCheckBox fx:id="chkOld" text="%version.game.old" />
|
||||
</HBox>
|
||||
<JFXListView fx:id="list" styleClass="jfx-list-view" VBox.vgrow="ALWAYS">
|
||||
</JFXListView>
|
||||
</VBox>
|
||||
<StackPane fx:id="failedPane">
|
||||
<Label onMouseClicked="#onRefresh" style="-fx-text-fill: #0079FF; -fx-font-size: 20;" text="%download.failed.refresh" />
|
||||
</StackPane>
|
||||
</fx:root>
|
||||
@@ -105,6 +105,7 @@ crash.user_fault=Your OS or Java environment may not be properly installed resul
|
||||
download=Download
|
||||
download.BMCL=BMCLAPI (bangbang93, http://bmclapi.bangbang93.com/)
|
||||
download.failed=Failed to download
|
||||
download.failed.refresh=Unable to load version list. Click here to retry.
|
||||
download.mojang=Mojang
|
||||
download.not_200=Failed to download, the response code is %s.
|
||||
download.source=Download Source
|
||||
@@ -381,8 +382,7 @@ update.tooltip=Update
|
||||
|
||||
version.cannot_read=Unable to gather the game version. Cannot continue auto-installing.
|
||||
version.forbidden_name=Forbidden name, do not use this.
|
||||
version.game.old_alpha=Old Alpha
|
||||
version.game.old_beta=Beta
|
||||
version.game.old=Old
|
||||
version.game.release=Release
|
||||
version.game.snapshot=Snapshot
|
||||
version.launch=Play
|
||||
|
||||
@@ -105,6 +105,7 @@ crash.user_fault=您的系统或Java环境可能安装不当导致本软件崩
|
||||
download=下载
|
||||
download.BMCL=BMCLAPI (bangbang93, http://bmclapi.bangbang93.com/)
|
||||
download.failed=下载失败
|
||||
download.failed.refresh=加载版本列表失败,点击此处重试。
|
||||
download.mojang=官方
|
||||
download.not_200=下载失败,HTTP状态码:%s.
|
||||
download.source=下载源
|
||||
@@ -381,10 +382,9 @@ update.tooltip=更新
|
||||
|
||||
version.cannot_read=读取游戏版本失败,无法进行自动安装
|
||||
version.forbidden_name=此版本名称不受支持,请换一个名字
|
||||
version.game.old_alpha=远古版
|
||||
version.game.old_beta=测试版
|
||||
version.game.old=远古版
|
||||
version.game.release=稳定版
|
||||
version.game.snapshot=快照版
|
||||
version.game.snapshot=测试版
|
||||
version.launch=启动游戏
|
||||
version.launch_script=生成启动脚本
|
||||
version.launch_script.failed=生成启动脚本失败
|
||||
|
||||
@@ -57,6 +57,14 @@ public abstract class Account {
|
||||
*/
|
||||
public abstract AuthInfo logIn(MultiCharacterSelector selector, Proxy proxy) throws AuthenticationException;
|
||||
|
||||
public abstract boolean canPlayOffline();
|
||||
|
||||
/**
|
||||
* Play offline.
|
||||
* @return the specific offline player's info.
|
||||
*/
|
||||
public abstract AuthInfo playOffline();
|
||||
|
||||
public abstract void logOut();
|
||||
|
||||
protected abstract Map<Object, Object> toStorageImpl();
|
||||
|
||||
@@ -69,6 +69,16 @@ public class OfflineAccount extends Account {
|
||||
// Offline account need not log out.
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canPlayOffline() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AuthInfo playOffline() {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Object, Object> toStorageImpl() {
|
||||
return Lang.mapOf(
|
||||
|
||||
@@ -171,6 +171,19 @@ public final class YggdrasilAccount extends Account {
|
||||
userProperties.putAll(user.getProperties());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canPlayOffline() {
|
||||
return isLoggedIn() && getSelectedProfile() != null && !canPlayOnline();
|
||||
}
|
||||
|
||||
@Override
|
||||
public AuthInfo playOffline() {
|
||||
if (!canPlayOffline())
|
||||
throw new IllegalStateException("Current account " + this + " cannot play offline.");
|
||||
|
||||
return new AuthInfo(selectedProfile, accessToken, userType, GSON.toJson(userProperties));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logOut() {
|
||||
password = null;
|
||||
|
||||
@@ -62,7 +62,7 @@ public class DefaultGameBuilder extends GameBuilder {
|
||||
downloadGameAsync(gameVersion, version),
|
||||
new GameLibrariesTask(dependencyManager, version) // Game libraries will be downloaded for multiple times partly, this time is for vanilla libraries.
|
||||
).with(new VersionJsonSaveTask(dependencyManager.getGameRepository(), version)); // using [with] because download failure here are tolerant.
|
||||
|
||||
|
||||
if (toolVersions.containsKey("forge"))
|
||||
result = result.then(libraryTaskHelper(gameVersion, "forge"));
|
||||
if (toolVersions.containsKey("liteloader"))
|
||||
@@ -70,12 +70,9 @@ public class DefaultGameBuilder extends GameBuilder {
|
||||
if (toolVersions.containsKey("optifine"))
|
||||
result = result.then(libraryTaskHelper(gameVersion, "optifine"));
|
||||
return result;
|
||||
}).finalized(new Task() {
|
||||
@Override
|
||||
public void execute() {
|
||||
if (!isDependentsSucceeded())
|
||||
dependencyManager.getGameRepository().getVersionRoot(name).delete();
|
||||
}
|
||||
}).finalized((variables, isDependentsSucceeded) -> {
|
||||
if (!isDependentsSucceeded)
|
||||
dependencyManager.getGameRepository().getVersionRoot(name).delete();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -78,20 +78,6 @@ public class RemoteVersion<T> implements Comparable<RemoteVersion<T>> {
|
||||
@Override
|
||||
public int compareTo(RemoteVersion<T> o) {
|
||||
// newer versions are smaller than older versions
|
||||
return -selfVersion.compareTo(o.selfVersion);
|
||||
}
|
||||
|
||||
public static class RemoteVersionComparator implements Comparator<RemoteVersion<?>> {
|
||||
|
||||
public static final RemoteVersionComparator INSTANCE = new RemoteVersionComparator();
|
||||
|
||||
private RemoteVersionComparator() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compare(RemoteVersion<?> o1, RemoteVersion<?> o2) {
|
||||
return -VersionNumber.asVersion(o1.selfVersion).compareTo(VersionNumber.asVersion(o2.selfVersion));
|
||||
}
|
||||
|
||||
return -VersionNumber.asVersion(selfVersion).compareTo(VersionNumber.asVersion(o.selfVersion));
|
||||
}
|
||||
}
|
||||
@@ -56,10 +56,7 @@ public final class GameVersionList extends VersionList<GameRemoteVersionTag> {
|
||||
|
||||
GameRemoteVersions root = Constants.GSON.fromJson(task.getResult(), GameRemoteVersions.class);
|
||||
for (GameRemoteVersion remoteVersion : root.getVersions()) {
|
||||
Optional<String> gameVersion = VersionNumber.parseVersion(remoteVersion.getGameVersion());
|
||||
if (!gameVersion.isPresent())
|
||||
continue;
|
||||
versions.put(gameVersion.get(), new RemoteVersion<>(
|
||||
versions.put(remoteVersion.getGameVersion(), new RemoteVersionGame(
|
||||
remoteVersion.getGameVersion(),
|
||||
remoteVersion.getGameVersion(),
|
||||
remoteVersion.getUrl(),
|
||||
@@ -70,4 +67,14 @@ public final class GameVersionList extends VersionList<GameRemoteVersionTag> {
|
||||
};
|
||||
}
|
||||
|
||||
private static class RemoteVersionGame extends RemoteVersion<GameRemoteVersionTag> {
|
||||
public RemoteVersionGame(String gameVersion, String selfVersion, String url, GameRemoteVersionTag tag) {
|
||||
super(gameVersion, selfVersion, url, tag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(RemoteVersion<GameRemoteVersionTag> o) {
|
||||
return -getTag().getTime().compareTo(o.getTag().getTime());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2017 huangyuhui <[email protected]>
|
||||
*
|
||||
* 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 {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hmcl.task;
|
||||
|
||||
import org.jackhuang.hmcl.util.AutoTypingMap;
|
||||
|
||||
public interface FinalizedCallback {
|
||||
void execute(AutoTypingMap<String> variables, boolean isDependentsSucceeded) throws Exception;
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2017 huangyuhui <[email protected]>
|
||||
*
|
||||
* 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 {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hmcl.task;
|
||||
|
||||
import org.jackhuang.hmcl.util.AutoTypingMap;
|
||||
import org.jackhuang.hmcl.util.ExceptionalFunction;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A task that combines two tasks and make sure [pred] runs before succ.
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
final class FinalizedTask extends Task {
|
||||
|
||||
private final Collection<Task> dependents;
|
||||
private final FinalizedCallback callback;
|
||||
private final Scheduler scheduler;
|
||||
|
||||
/**
|
||||
* A task that combines two tasks and make sure pred runs before succ.
|
||||
*
|
||||
* @param pred the task that runs before succ.
|
||||
* @param callback a callback that returns the task runs after pred, succ will be executed asynchronously. You can do something that relies on the result of pred.
|
||||
*/
|
||||
public FinalizedTask(Task pred, Scheduler scheduler, FinalizedCallback callback) {
|
||||
this.dependents = Collections.singleton(pred);
|
||||
this.scheduler = scheduler;
|
||||
this.callback = callback;
|
||||
|
||||
setSignificance(TaskSignificance.MODERATE);
|
||||
setName(callback.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Scheduler getScheduler() {
|
||||
return scheduler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() throws Exception {
|
||||
setName(callback.toString());
|
||||
callback.execute(getVariables(), isDependentsSucceeded());
|
||||
|
||||
if (!isDependentsSucceeded())
|
||||
throw new SilentException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Task> getDependents() {
|
||||
return dependents;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRelyingOnDependents() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -260,12 +260,12 @@ public abstract class Task {
|
||||
return new CoupleTask<>(this, b, false, false);
|
||||
}
|
||||
|
||||
public final Task finalized(Task b) {
|
||||
return finalized(convert(b));
|
||||
public final Task finalized(FinalizedCallback b) {
|
||||
return finalized(Schedulers.defaultScheduler(), b);
|
||||
}
|
||||
|
||||
public final Task finalized(ExceptionalFunction<AutoTypingMap<String>, Task, ?> b) {
|
||||
return new CoupleTask<>(this, b, false, true);
|
||||
public final Task finalized(Scheduler scheduler, FinalizedCallback b) {
|
||||
return new FinalizedTask(this, scheduler, b);
|
||||
}
|
||||
|
||||
public static Task empty() {
|
||||
|
||||
Reference in new issue
Block a user