From a388450f941c088352c69400f13daeb2eb4204be Mon Sep 17 00:00:00 2001 From: huanghongxun Date: Sat, 23 Feb 2019 22:44:52 +0800 Subject: [PATCH] Remove AutoTypingMap --- .../jackhuang/hmcl/game/LauncherHelper.java | 59 ++++------ .../jackhuang/hmcl/ui/LeftPaneController.java | 3 +- .../ui/download/InstallerWizardProvider.java | 9 +- .../hmcl/ui/versions/InstallerListPage.java | 2 +- .../hmcl/ui/versions/ModListPage.java | 7 +- .../hmcl/ui/versions/VersionSettingsPage.java | 13 +-- .../download/DefaultDependencyManager.java | 34 +++--- .../hmcl/download/DefaultGameBuilder.java | 26 +++-- .../jackhuang/hmcl/download/MaintainTask.java | 13 --- .../jackhuang/hmcl/download/VersionList.java | 4 +- .../hmcl/download/forge/ForgeInstallTask.java | 5 - .../download/forge/ForgeNewInstallTask.java | 5 - .../download/forge/ForgeOldInstallTask.java | 5 - .../download/game/LibrariesUniqueTask.java | 11 -- .../game/VersionJsonDownloadTask.java | 7 +- .../download/game/VersionJsonSaveTask.java | 5 +- .../liteloader/LiteLoaderInstallTask.java | 6 - .../optifine/OptiFineInstallTask.java | 5 - .../hmcl/mod/MultiMCModpackInstallTask.java | 2 +- .../org/jackhuang/hmcl/task/CoupleTask.java | 34 +++--- .../jackhuang/hmcl/task/FinalizedTask.java | 3 +- .../java/org/jackhuang/hmcl/task/GetTask.java | 5 - .../org/jackhuang/hmcl/task/SimpleTask.java | 13 +-- .../jackhuang/hmcl/task/SimpleTaskResult.java | 30 +++-- .../java/org/jackhuang/hmcl/task/Task.java | 109 ++++++++---------- .../org/jackhuang/hmcl/task/TaskCallable.java | 52 --------- .../org/jackhuang/hmcl/task/TaskExecutor.java | 14 --- .../org/jackhuang/hmcl/task/TaskResult.java | 67 ++++++++--- .../jackhuang/hmcl/util/ReflectionHelper.java | 15 ++- 29 files changed, 233 insertions(+), 330 deletions(-) delete mode 100644 HMCLCore/src/main/java/org/jackhuang/hmcl/task/TaskCallable.java diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/game/LauncherHelper.java b/HMCL/src/main/java/org/jackhuang/hmcl/game/LauncherHelper.java index de641b771..b5d17988e 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/game/LauncherHelper.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/game/LauncherHelper.java @@ -122,14 +122,14 @@ public final class LauncherHelper { Optional gameVersion = GameVersion.minecraftVersion(repository.getVersionJar(version)); TaskExecutor executor = Task.of(Schedulers.javafx(), () -> emitStatus(LoadingState.DEPENDENCIES)) - .then(variables -> { + .then(() -> { if (setting.isNotCheckGame()) return null; else return dependencyManager.checkGameCompletionAsync(version); }) .then(Task.of(Schedulers.javafx(), () -> emitStatus(LoadingState.MODS))) - .then(var -> { + .then(() -> { try { ModpackConfiguration configuration = ModpackHelper.readModpackConfiguration(repository.getModpackConfiguration(selectedVersion)); if ("Curse".equals(configuration.getType())) @@ -141,44 +141,42 @@ public final class LauncherHelper { } }) .then(Task.of(Schedulers.javafx(), () -> emitStatus(LoadingState.LOGGING_IN))) - .then(Task.of(i18n("account.methods"), variables -> { + .thenTaskResult(() -> Task.ofResult(i18n("account.methods"), () -> { try { - variables.set("account", account.logIn()); + return account.logIn(); } catch (CredentialExpiredException e) { LOG.info("Credential has expired: " + e); - variables.set("account", DialogController.logIn(account)); + return DialogController.logIn(account); } catch (AuthenticationException e) { LOG.warning("Authentication failed, try playing offline: " + e); - variables.set("account", - account.playOffline().orElseThrow(() -> e)); + return account.playOffline().orElseThrow(() -> e); } })) - .then(Task.of(Schedulers.javafx(), () -> emitStatus(LoadingState.LAUNCHING))) - .then(Task.of(variables -> { - variables.set("launcher", new HMCLGameLauncher( - repository, - selectedVersion, - variables.get("account"), - setting.toLaunchOptions(profile.getGameDir()), - launcherVisibility == LauncherVisibility.CLOSE - ? null // Unnecessary to start listening to game process output when close launcher immediately after game launched. - : new HMCLProcessListener(variables.get("account"), setting, gameVersion.isPresent()) - )); - })) - .then(variables -> { - DefaultLauncher launcher = variables.get("launcher"); + .thenResult(Schedulers.javafx(), authInfo -> { + emitStatus(LoadingState.LAUNCHING); + return authInfo; + }) + .thenResult(authInfo -> new HMCLGameLauncher( + repository, + selectedVersion, + authInfo, + setting.toLaunchOptions(profile.getGameDir()), + launcherVisibility == LauncherVisibility.CLOSE + ? null // Unnecessary to start listening to game process output when close launcher immediately after game launched. + : new HMCLProcessListener(authInfo, setting, gameVersion.isPresent()) + )) + .thenTaskResult(launcher -> { // launcher is prev task's result if (scriptFile == null) { return new LaunchTask<>(launcher::launch).setName(i18n("version.launch")); } else { - return new LaunchTask<>(() -> { + return new LaunchTask(() -> { launcher.makeLaunchScript(scriptFile); return null; }).setName(i18n("version.launch_script")); } }) - .then(Task.of(variables -> { + .thenVoid(process -> { // process is LaunchTask's result if (scriptFile == null) { - ManagedProcess process = variables.get(LaunchTask.LAUNCH_ID); PROCESSES.add(process); if (launcherVisibility == LauncherVisibility.CLOSE) Launcher.stopApplication(); @@ -187,13 +185,13 @@ public final class LauncherHelper { process.stop(); it.fireEvent(new DialogCloseEvent()); }); - } else + } else { Platform.runLater(() -> { launchingStepsPane.fireEvent(new DialogCloseEvent()); Controllers.dialog(i18n("version.launch_script.success", scriptFile.getAbsolutePath())); }); - - })) + } + }) .executor(); launchingStepsPane.setExecutor(executor, false); @@ -429,13 +427,6 @@ public final class LauncherHelper { public void execute() throws Exception { setResult(supplier.get()); } - - @Override - public String getId() { - return LAUNCH_ID; - } - - static final String LAUNCH_ID = "launch"; } /** diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/LeftPaneController.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/LeftPaneController.java index bda00a079..0479f27d0 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/LeftPaneController.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/LeftPaneController.java @@ -121,13 +121,12 @@ public final class LeftPaneController extends AdvancedListBox { if (modpackFile.exists()) { Task.ofResult(() -> CompressingUtils.findSuitableEncoding(modpackFile.toPath())) .thenResult(encoding -> ModpackHelper.readModpackManifest(modpackFile.toPath(), encoding)) - .thenResult(modpack -> { + .thenVoid(modpack -> { AtomicReference region = new AtomicReference<>(); TaskExecutor executor = ModpackHelper.getInstallTask(repository.getProfile(), modpackFile, modpack.getName(), modpack) .with(Task.of(Schedulers.javafx(), this::checkAccount)).executor(); region.set(Controllers.taskDialog(executor, i18n("modpack.installing"))); executor.start(); - return null; }).start(); } } diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/download/InstallerWizardProvider.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/download/InstallerWizardProvider.java index 87f1360f5..a38ad5f80 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/download/InstallerWizardProvider.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/download/InstallerWizardProvider.java @@ -27,6 +27,7 @@ import org.jackhuang.hmcl.game.Version; import org.jackhuang.hmcl.setting.Profile; import org.jackhuang.hmcl.task.DownloadException; import org.jackhuang.hmcl.task.Task; +import org.jackhuang.hmcl.task.TaskResult; import org.jackhuang.hmcl.ui.Controllers; import org.jackhuang.hmcl.ui.construct.MessageBox; import org.jackhuang.hmcl.ui.wizard.WizardController; @@ -89,16 +90,16 @@ public final class InstallerWizardProvider implements WizardProvider { settings.put("success_message", i18n("install.success")); settings.put("failure_callback", (FailureCallback) (settings1, exception, next) -> alertFailureMessage(exception, next)); - Task ret = Task.ofResult("version", () -> version); + TaskResult ret = Task.ofResult(() -> version); if (settings.containsKey("forge")) - ret = ret.then(profile.getDependency().installLibraryAsync((RemoteVersion) settings.get("forge"))); + ret = ret.thenTaskResult(profile.getDependency().installLibraryAsync((RemoteVersion) settings.get("forge"))); if (settings.containsKey("liteloader")) - ret = ret.then(profile.getDependency().installLibraryAsync((RemoteVersion) settings.get("liteloader"))); + ret = ret.thenTaskResult(profile.getDependency().installLibraryAsync((RemoteVersion) settings.get("liteloader"))); if (settings.containsKey("optifine")) - ret = ret.then(profile.getDependency().installLibraryAsync((RemoteVersion) settings.get("optifine"))); + ret = ret.thenTaskResult(profile.getDependency().installLibraryAsync((RemoteVersion) settings.get("optifine"))); return ret.then(profile.getRepository().refreshVersionsAsync()); } diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/InstallerListPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/InstallerListPage.java index 2b45437a4..020ff62de 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/InstallerListPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/InstallerListPage.java @@ -54,7 +54,7 @@ public class InstallerListPage extends ListPage { LinkedList newList = new LinkedList<>(version.getLibraries()); newList.remove(library); new MaintainTask(version.setLibraries(newList)) - .then(variables -> new VersionJsonSaveTask(profile.getRepository(), variables.get(MaintainTask.ID))) + .then(maintainedVersion -> new VersionJsonSaveTask(profile.getRepository(), maintainedVersion)) .with(profile.getRepository().refreshVersionsAsync()) .with(Task.of(Schedulers.javafx(), () -> loadVersion(this.profile, this.versionId))) .start(); diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/ModListPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/ModListPage.java index 97f7e1b44..c420c5d5d 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/ModListPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/ModListPage.java @@ -36,7 +36,6 @@ import org.jackhuang.hmcl.task.Schedulers; import org.jackhuang.hmcl.task.Task; import org.jackhuang.hmcl.ui.Controllers; import org.jackhuang.hmcl.ui.FXUtils; -import org.jackhuang.hmcl.ui.ListPage; import org.jackhuang.hmcl.util.Logging; import org.jackhuang.hmcl.util.io.FileUtils; @@ -86,7 +85,7 @@ public final class ModListPage extends Control { public void loadMods(ModManager modManager) { this.modManager = modManager; - Task.ofResult("list", variables -> { + Task.ofResult(() -> { synchronized (ModListPage.this) { JFXUtilities.runInFX(() -> loadingProperty().set(true)); modManager.refreshMods(); @@ -112,7 +111,7 @@ public final class ModListPage extends Control { List succeeded = new LinkedList<>(); List failed = new LinkedList<>(); if (res == null) return; - Task.of(variables -> { + Task.of(() -> { for (File file : res) { try { modManager.addMod(file); @@ -124,7 +123,7 @@ public final class ModListPage extends Control { // Actually addMod will not throw exceptions because FileChooser has already filtered files. } } - }).with(Task.of(Schedulers.javafx(), variables -> { + }).with(Task.of(Schedulers.javafx(), () -> { List prompt = new LinkedList<>(); if (!succeeded.isEmpty()) prompt.add(i18n("mods.add.success", String.join(", ", succeeded))); diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/VersionSettingsPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/VersionSettingsPage.java index b5b0b45e7..971caed19 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/VersionSettingsPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/VersionSettingsPage.java @@ -57,7 +57,7 @@ import java.io.IOException; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Arrays; -import java.util.List; +import java.util.Optional; import java.util.logging.Level; import java.util.stream.Collectors; @@ -113,14 +113,13 @@ public final class VersionSettingsPage extends StackPane implements DecoratorPag FXUtils.smoothScrolling(scroll); - Task.ofResult(JavaVersion::getJavas).thenResult(Schedulers.javafx(), list -> { + Task.ofResult(JavaVersion::getJavas).thenVoid(Schedulers.javafx(), list -> { javaItem.loadChildren(list.stream() .map(javaVersion -> javaItem.createChildren(javaVersion.getVersion() + i18n("settings.game.java_directory.bit", javaVersion.getPlatform().getBit()), javaVersion.getBinary().toString(), javaVersion)) .collect(Collectors.toList())); javaItemsLoaded = true; initializeSelectedJava(); - return null; }).start(); javaItem.setSelectedData(null); @@ -268,10 +267,10 @@ public final class VersionSettingsPage extends StackPane implements DecoratorPag } private void initJavaSubtitle(VersionSetting versionSetting) { - Task.of(variables -> variables.set("java", versionSetting.getJavaVersion())) - .subscribe(Task.of(Schedulers.javafx(), - variables -> javaItem.setSubtitle(variables.getOptional("java") - .map(JavaVersion::getBinary).map(Path::toString).orElse("Invalid Java Directory")))); + Task.ofResult(versionSetting::getJavaVersion) + .thenVoid(Schedulers.javafx(), javaVersion -> javaItem.setSubtitle(Optional.ofNullable(javaVersion) + .map(JavaVersion::getBinary).map(Path::toString).orElse("Invalid Java Directory"))) + .start(); } @FXML diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/DefaultDependencyManager.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/DefaultDependencyManager.java index d121b4b33..c094c719c 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/DefaultDependencyManager.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/DefaultDependencyManager.java @@ -28,7 +28,7 @@ import org.jackhuang.hmcl.game.DefaultGameRepository; import org.jackhuang.hmcl.game.Version; import org.jackhuang.hmcl.task.ParallelTask; import org.jackhuang.hmcl.task.Task; -import org.jackhuang.hmcl.util.AutoTypingMap; +import org.jackhuang.hmcl.task.TaskResult; import org.jackhuang.hmcl.util.function.ExceptionalFunction; /** @@ -71,7 +71,7 @@ public class DefaultDependencyManager extends AbstractDependencyManager { @Override public Task checkGameCompletionAsync(Version version) { return new ParallelTask( - Task.ofThen(var -> { + Task.ofThen(() -> { if (!repository.getVersionJar(version).exists()) return new GameDownloadTask(this, null, version); else @@ -88,36 +88,32 @@ public class DefaultDependencyManager extends AbstractDependencyManager { } @Override - public Task installLibraryAsync(String gameVersion, Version version, String libraryId, String libraryVersion) { + public TaskResult installLibraryAsync(String gameVersion, Version version, String libraryId, String libraryVersion) { VersionList versionList = getVersionList(libraryId); return versionList.loadAsync(gameVersion, getDownloadProvider()) - .then(variables -> installLibraryAsync(version, versionList.getVersion(gameVersion, libraryVersion) + .thenTaskResult(() -> installLibraryAsync(version, versionList.getVersion(gameVersion, libraryVersion) .orElseThrow(() -> new IllegalStateException("Remote library " + libraryId + " has no version " + libraryVersion)))); } @Override - public Task installLibraryAsync(Version version, RemoteVersion libraryVersion) { + public TaskResult installLibraryAsync(Version oldVersion, RemoteVersion libraryVersion) { + TaskResult task; if (libraryVersion instanceof ForgeRemoteVersion) - return new ForgeInstallTask(this, version, (ForgeRemoteVersion) libraryVersion) - .then(variables -> new LibrariesUniqueTask(variables.get("version"))) - .then(variables -> new MaintainTask(variables.get("version"))) - .then(variables -> new VersionJsonSaveTask(repository, variables.get("version"))); + task = new ForgeInstallTask(this, oldVersion, (ForgeRemoteVersion) libraryVersion); else if (libraryVersion instanceof LiteLoaderRemoteVersion) - return new LiteLoaderInstallTask(this, version, (LiteLoaderRemoteVersion) libraryVersion) - .then(variables -> new LibrariesUniqueTask(variables.get("version"))) - .then(variables -> new MaintainTask(variables.get("version"))) - .then(variables -> new VersionJsonSaveTask(repository, variables.get("version"))); + task = new LiteLoaderInstallTask(this, oldVersion, (LiteLoaderRemoteVersion) libraryVersion); else if (libraryVersion instanceof OptiFineRemoteVersion) - return new OptiFineInstallTask(this, version, (OptiFineRemoteVersion) libraryVersion) - .then(variables -> new LibrariesUniqueTask(variables.get("version"))) - .then(variables -> new MaintainTask(variables.get("version"))) - .then(variables -> new VersionJsonSaveTask(repository, variables.get("version"))); + task = new OptiFineInstallTask(this, oldVersion, (OptiFineRemoteVersion) libraryVersion); else throw new IllegalArgumentException("Remote library " + libraryVersion + " is unrecognized."); + return task + .thenTaskResult(LibrariesUniqueTask::new) + .thenTaskResult(MaintainTask::new) + .thenTaskResult(newVersion -> new VersionJsonSaveTask(repository, newVersion)); } - public ExceptionalFunction, Task, ?> installLibraryAsync(RemoteVersion libraryVersion) { - return var -> installLibraryAsync(var.get("version"), libraryVersion); + public ExceptionalFunction, ?> installLibraryAsync(RemoteVersion libraryVersion) { + return version -> installLibraryAsync(version, libraryVersion); } } diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/DefaultGameBuilder.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/DefaultGameBuilder.java index 111d5f8c7..885517422 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/DefaultGameBuilder.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/DefaultGameBuilder.java @@ -21,6 +21,7 @@ import org.jackhuang.hmcl.download.game.*; import org.jackhuang.hmcl.game.Version; import org.jackhuang.hmcl.task.ParallelTask; import org.jackhuang.hmcl.task.Task; +import org.jackhuang.hmcl.task.TaskResult; import org.jackhuang.hmcl.util.AutoTypingMap; import org.jackhuang.hmcl.util.function.ExceptionalFunction; import org.jackhuang.hmcl.util.gson.JsonUtils; @@ -49,34 +50,35 @@ public class DefaultGameBuilder extends GameBuilder { @Override public Task buildAsync() { - return new VersionJsonDownloadTask(gameVersion, dependencyManager).then(variables -> { - Version version = JsonUtils.GSON.fromJson(variables.get(VersionJsonDownloadTask.ID), Version.class); - version = version.setId(name).setJar(null); - variables.set("version", version); - Task result = downloadGameAsync(gameVersion, version).then(new ParallelTask( + return new VersionJsonDownloadTask(gameVersion, dependencyManager).thenTaskResult(rawJson -> { + Version original = JsonUtils.GSON.fromJson(rawJson, Version.class); + Version version = original.setId(name).setJar(null); + Task vanillaTask = downloadGameAsync(gameVersion, version).then(new ParallelTask( new GameAssetDownloadTask(dependencyManager, version, GameAssetDownloadTask.DOWNLOAD_INDEX_FORCIBLY), 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. + TaskResult libraryTask = vanillaTask.thenResult(() -> version); + if (toolVersions.containsKey("forge")) - result = result.then(libraryTaskHelper(gameVersion, "forge")); + libraryTask = libraryTask.thenTaskResult(libraryTaskHelper(gameVersion, "forge")); if (toolVersions.containsKey("liteloader")) - result = result.then(libraryTaskHelper(gameVersion, "liteloader")); + libraryTask = libraryTask.thenTaskResult(libraryTaskHelper(gameVersion, "liteloader")); if (toolVersions.containsKey("optifine")) - result = result.then(libraryTaskHelper(gameVersion, "optifine")); + libraryTask = libraryTask.thenTaskResult(libraryTaskHelper(gameVersion, "optifine")); for (RemoteVersion remoteVersion : remoteVersions) - result = result.then(dependencyManager.installLibraryAsync(remoteVersion)); + libraryTask = libraryTask.thenTaskResult(dependencyManager.installLibraryAsync(remoteVersion)); - return result; + return libraryTask; }).finalized((isDependentsSucceeded, exception) -> { if (!isDependentsSucceeded) dependencyManager.getGameRepository().getVersionRoot(name).delete(); }); } - private ExceptionalFunction, Task, ?> libraryTaskHelper(String gameVersion, String libraryId) { - return variables -> dependencyManager.installLibraryAsync(gameVersion, variables.get("version"), libraryId, toolVersions.get(libraryId)); + private ExceptionalFunction, ?> libraryTaskHelper(String gameVersion, String libraryId) { + return version -> dependencyManager.installLibraryAsync(gameVersion, version, libraryId, toolVersions.get(libraryId)); } protected Task downloadGameAsync(String gameVersion, Version version) { diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/MaintainTask.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/MaintainTask.java index 919998665..c0a58dcbc 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/MaintainTask.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/MaintainTask.java @@ -23,15 +23,9 @@ import org.jackhuang.hmcl.task.TaskResult; public class MaintainTask extends TaskResult { private final Version version; - private final String id; public MaintainTask(Version version) { - this(version, ID); - } - - public MaintainTask(Version version, String id) { this.version = version; - this.id = id; } @Override @@ -76,11 +70,4 @@ public class MaintainTask extends TaskResult { return builder.build(); } - - @Override - public String getId() { - return id; - } - - public static final String ID = "version"; } diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/VersionList.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/VersionList.java index e00a8abc5..da4cc8780 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/VersionList.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/VersionList.java @@ -74,7 +74,7 @@ public abstract class VersionList { } public Task loadAsync(DownloadProvider downloadProvider) { - return Task.ofThen(variables -> { + return Task.ofThen(() -> { lock.readLock().lock(); boolean loaded; @@ -88,7 +88,7 @@ public abstract class VersionList { } public Task loadAsync(String gameVersion, DownloadProvider downloadProvider) { - return Task.ofThen(variables -> { + return Task.ofThen(() -> { lock.readLock().lock(); boolean loaded; diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/forge/ForgeInstallTask.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/forge/ForgeInstallTask.java index 2843c56b3..c29de94a5 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/forge/ForgeInstallTask.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/forge/ForgeInstallTask.java @@ -82,11 +82,6 @@ public final class ForgeInstallTask extends TaskResult { return Collections.singleton(dependency); } - @Override - public String getId() { - return "version"; - } - @Override public boolean isRelyingOnDependencies() { return false; diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/forge/ForgeNewInstallTask.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/forge/ForgeNewInstallTask.java index 8dc7f8a9f..fe1250485 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/forge/ForgeNewInstallTask.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/forge/ForgeNewInstallTask.java @@ -89,11 +89,6 @@ public class ForgeNewInstallTask extends TaskResult { return dependencies; } - @Override - public String getId() { - return "version"; - } - @Override public boolean doPreExecute() { return true; diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/forge/ForgeOldInstallTask.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/forge/ForgeOldInstallTask.java index fca62abec..1c961c91d 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/forge/ForgeOldInstallTask.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/forge/ForgeOldInstallTask.java @@ -49,11 +49,6 @@ public class ForgeOldInstallTask extends TaskResult { return dependencies; } - @Override - public String getId() { - return "version"; - } - @Override public boolean doPreExecute() { return true; diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/game/LibrariesUniqueTask.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/game/LibrariesUniqueTask.java index fcc33b137..23d586c1e 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/game/LibrariesUniqueTask.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/game/LibrariesUniqueTask.java @@ -33,15 +33,9 @@ import java.util.stream.Collectors; public class LibrariesUniqueTask extends TaskResult { private final Version version; - private final String id; public LibrariesUniqueTask(Version version) { - this(version, "version"); - } - - public LibrariesUniqueTask(Version version, String id) { this.version = version; - this.id = id; } @Override @@ -99,9 +93,4 @@ public class LibrariesUniqueTask extends TaskResult { setResult(version.setLibraries(multimap.values().stream().sorted().collect(Collectors.toList()))); } - - @Override - public String getId() { - return id; - } } diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/game/VersionJsonDownloadTask.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/game/VersionJsonDownloadTask.java index d60b52927..d24bc5a6a 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/game/VersionJsonDownloadTask.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/game/VersionJsonDownloadTask.java @@ -22,6 +22,7 @@ import org.jackhuang.hmcl.download.RemoteVersion; import org.jackhuang.hmcl.download.VersionList; import org.jackhuang.hmcl.task.GetTask; import org.jackhuang.hmcl.task.Task; +import org.jackhuang.hmcl.task.TaskResult; import org.jackhuang.hmcl.util.io.NetworkUtils; import java.util.Collection; @@ -32,7 +33,7 @@ import java.util.List; * * @author huangyuhui */ -public final class VersionJsonDownloadTask extends Task { +public final class VersionJsonDownloadTask extends TaskResult { private final String gameVersion; private final DefaultDependencyManager dependencyManager; private final List dependents = new LinkedList<>(); @@ -65,8 +66,6 @@ public final class VersionJsonDownloadTask extends Task { RemoteVersion remoteVersion = gameVersionList.getVersions(gameVersion).stream().findFirst() .orElseThrow(() -> new IllegalStateException("Cannot find specific version " + gameVersion + " in remote repository")); String jsonURL = dependencyManager.getDownloadProvider().injectURL(remoteVersion.getUrl()); - dependencies.add(new GetTask(NetworkUtils.toURL(jsonURL), ID)); + dependencies.add(new GetTask(NetworkUtils.toURL(jsonURL)).storeTo(this::setResult)); } - - public static final String ID = "raw_version_json"; } diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/game/VersionJsonSaveTask.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/game/VersionJsonSaveTask.java index d1031742b..d404994b5 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/game/VersionJsonSaveTask.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/game/VersionJsonSaveTask.java @@ -19,7 +19,7 @@ package org.jackhuang.hmcl.download.game; import org.jackhuang.hmcl.game.DefaultGameRepository; import org.jackhuang.hmcl.game.Version; -import org.jackhuang.hmcl.task.Task; +import org.jackhuang.hmcl.task.TaskResult; import org.jackhuang.hmcl.util.gson.JsonUtils; import org.jackhuang.hmcl.util.io.FileUtils; @@ -31,7 +31,7 @@ import java.io.IOException; * * @author huangyuhui */ -public final class VersionJsonSaveTask extends Task { +public final class VersionJsonSaveTask extends TaskResult { private final DefaultGameRepository repository; private final Version version; @@ -47,6 +47,7 @@ public final class VersionJsonSaveTask extends Task { this.version = version; setSignificance(TaskSignificance.MODERATE); + setResult(version); } @Override diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/liteloader/LiteLoaderInstallTask.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/liteloader/LiteLoaderInstallTask.java index f62c77c17..558714f95 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/liteloader/LiteLoaderInstallTask.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/liteloader/LiteLoaderInstallTask.java @@ -18,7 +18,6 @@ package org.jackhuang.hmcl.download.liteloader; import org.jackhuang.hmcl.download.DefaultDependencyManager; -import org.jackhuang.hmcl.download.game.GameLibrariesTask; import org.jackhuang.hmcl.game.LibrariesDownloadInfo; import org.jackhuang.hmcl.game.Library; import org.jackhuang.hmcl.game.LibraryDownloadInfo; @@ -61,11 +60,6 @@ public final class LiteLoaderInstallTask extends TaskResult { return dependencies; } - @Override - public String getId() { - return "version"; - } - @Override public void execute() { Library library = new Library( diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/optifine/OptiFineInstallTask.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/optifine/OptiFineInstallTask.java index e9c10ea6d..716ddfad4 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/optifine/OptiFineInstallTask.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/optifine/OptiFineInstallTask.java @@ -59,11 +59,6 @@ public final class OptiFineInstallTask extends TaskResult { return dependencies; } - @Override - public String getId() { - return "version"; - } - @Override public boolean isRelyingOnDependencies() { return false; diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/MultiMCModpackInstallTask.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/MultiMCModpackInstallTask.java index b9c6b06ea..c453ce859 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/MultiMCModpackInstallTask.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/MultiMCModpackInstallTask.java @@ -156,7 +156,7 @@ public final class MultiMCModpackInstallTask extends Task { } } - dependencies.add(new MaintainTask(version).then(var -> new VersionJsonSaveTask(repository, var.get(MaintainTask.ID)))); + dependencies.add(new MaintainTask(version).thenTaskResult(maintainedVersion -> new VersionJsonSaveTask(repository, maintainedVersion))); dependencies.add(new MinecraftInstanceTask<>(zipFile, modpack.getEncoding(), "/" + manifest.getName() + "/minecraft", manifest, MODPACK_TYPE, repository.getModpackConfiguration(name))); } diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/task/CoupleTask.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/task/CoupleTask.java index c32705491..f9d87efe7 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/task/CoupleTask.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/task/CoupleTask.java @@ -18,57 +18,53 @@ package org.jackhuang.hmcl.task; import org.jackhuang.hmcl.util.AutoTypingMap; -import org.jackhuang.hmcl.util.function.ExceptionalFunction; +import org.jackhuang.hmcl.util.function.ExceptionalSupplier; 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 CoupleTask

extends Task { +final class CoupleTask extends Task { private final boolean relyingOnDependents; - private final Collection dependents; - private final List dependencies = new LinkedList<>(); - private final ExceptionalFunction, Task, ?> succ; + private final Task pred; + private Task succ; + private final ExceptionalSupplier supplier; /** * A task that combines two tasks and make sure pred runs before succ. * - * @param pred the task that runs before succ. - * @param succ 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. + * @param pred the task that runs before supplier. + * @param supplier 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. * @param relyingOnDependents true if this task chain will be broken when task pred fails. */ - public CoupleTask(P pred, ExceptionalFunction, Task, ?> succ, boolean relyingOnDependents) { - this.dependents = pred == null ? Collections.emptySet() : Collections.singleton(pred); - this.succ = succ; + CoupleTask(Task pred, ExceptionalSupplier supplier, boolean relyingOnDependents) { + this.pred = pred; + this.supplier = supplier; this.relyingOnDependents = relyingOnDependents; setSignificance(TaskSignificance.MODERATE); - setName(succ.toString()); + setName(supplier.toString()); } @Override public void execute() throws Exception { - setName(succ.toString()); - Task task = succ.apply(getVariables()); - if (task != null) - dependencies.add(task); + setName(supplier.toString()); + succ = supplier.get(); } @Override public Collection getDependents() { - return dependents; + return pred == null ? Collections.emptySet() : Collections.singleton(pred); } @Override public Collection getDependencies() { - return dependencies; + return succ == null ? Collections.emptySet() : Collections.singleton(succ); } @Override diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/task/FinalizedTask.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/task/FinalizedTask.java index fd37f20e7..a060d0d7c 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/task/FinalizedTask.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/task/FinalizedTask.java @@ -37,13 +37,12 @@ final class FinalizedTask extends Task { * @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, String name) { + public FinalizedTask(Task pred, Scheduler scheduler, FinalizedCallback callback) { this.pred = pred; this.scheduler = scheduler; this.callback = callback; setSignificance(TaskSignificance.MODERATE); - setName(name); } @Override diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/task/GetTask.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/task/GetTask.java index d391b65df..376d3914a 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/task/GetTask.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/task/GetTask.java @@ -72,11 +72,6 @@ public final class GetTask extends TaskResult { return Schedulers.io(); } - @Override - public String getId() { - return id; - } - public GetTask setCacheRepository(CacheRepository repository) { this.repository = repository; return this; diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/task/SimpleTask.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/task/SimpleTask.java index 6386aba09..f8bd7f3d9 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/task/SimpleTask.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/task/SimpleTask.java @@ -17,8 +17,7 @@ */ package org.jackhuang.hmcl.task; -import org.jackhuang.hmcl.util.AutoTypingMap; -import org.jackhuang.hmcl.util.function.ExceptionalConsumer; +import org.jackhuang.hmcl.util.function.ExceptionalRunnable; /** * @@ -26,16 +25,16 @@ import org.jackhuang.hmcl.util.function.ExceptionalConsumer; */ class SimpleTask extends Task { - private final ExceptionalConsumer, ?> consumer; + private final ExceptionalRunnable closure; private final Scheduler scheduler; - public SimpleTask(String name, ExceptionalConsumer, ?> consumer, Scheduler scheduler) { - this.consumer = consumer; + public SimpleTask(String name, ExceptionalRunnable closure, Scheduler scheduler) { + this.closure = closure; this.scheduler = scheduler; if (name == null) { setSignificance(TaskSignificance.MINOR); - setName(consumer.toString()); + setName(closure.toString()); } else { setName(name); } @@ -48,6 +47,6 @@ class SimpleTask extends Task { @Override public void execute() throws Exception { - consumer.accept(getVariables()); + closure.run(); } } diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/task/SimpleTaskResult.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/task/SimpleTaskResult.java index 393a3272c..22111f654 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/task/SimpleTaskResult.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/task/SimpleTaskResult.java @@ -17,24 +17,30 @@ */ package org.jackhuang.hmcl.task; +import org.jackhuang.hmcl.util.AutoTypingMap; +import org.jackhuang.hmcl.util.function.ExceptionalFunction; import org.jackhuang.hmcl.util.function.ExceptionalSupplier; -public final class SimpleTaskResult extends TaskResult { - private final String id; - private final ExceptionalSupplier supplier; +import java.util.concurrent.Callable; - public SimpleTaskResult(String id, ExceptionalSupplier supplier) { - this.id = id; - this.supplier = supplier; +/** + * + * @author huangyuhui + */ +class SimpleTaskResult extends TaskResult { + + private final Callable callable; + + public SimpleTaskResult(Callable callable) { + this.callable = callable; + } + + public SimpleTaskResult(ExceptionalSupplier supplier) { + this.callable = supplier.toCallable(); } @Override public void execute() throws Exception { - setResult(supplier.get()); - } - - @Override - public String getId() { - return id; + setResult(callable.call()); } } diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/task/Task.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/task/Task.java index b719b0a67..c43ab0d3b 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/task/Task.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/task/Task.java @@ -23,13 +23,12 @@ import javafx.beans.property.ReadOnlyDoubleWrapper; import javafx.beans.property.ReadOnlyStringProperty; import javafx.beans.property.ReadOnlyStringWrapper; import org.jackhuang.hmcl.event.EventManager; -import org.jackhuang.hmcl.util.AutoTypingMap; import org.jackhuang.hmcl.util.InvocationDispatcher; import org.jackhuang.hmcl.util.Logging; import org.jackhuang.hmcl.util.ReflectionHelper; import org.jackhuang.hmcl.util.function.ExceptionalConsumer; -import org.jackhuang.hmcl.util.function.ExceptionalFunction; import org.jackhuang.hmcl.util.function.ExceptionalRunnable; +import org.jackhuang.hmcl.util.function.ExceptionalSupplier; import java.util.Collection; import java.util.Collections; @@ -134,16 +133,6 @@ public abstract class Task { return this; } - private AutoTypingMap variables = null; - - public AutoTypingMap getVariables() { - return variables; - } - - void setVariables(AutoTypingMap variables) { - this.variables = variables; - } - public boolean doPreExecute() { return false; } @@ -280,16 +269,8 @@ public abstract class Task { new TaskExecutor(then(subscriber)).start(); } - public final void subscribe(Scheduler scheduler, ExceptionalConsumer, ?> closure) { - subscribe(of(scheduler, closure)); - } - public final void subscribe(Scheduler scheduler, ExceptionalRunnable closure) { - subscribe(of(scheduler, ExceptionalConsumer.fromRunnable(closure))); - } - - public final void subscribe(ExceptionalConsumer, ?> closure) { - subscribe(of(closure)); + subscribe(of(scheduler, closure)); } public final void subscribe(ExceptionalRunnable closure) { @@ -300,16 +281,36 @@ public abstract class Task { return then(convert(b)); } - public final Task then(ExceptionalFunction, Task, ?> b) { - return new CoupleTask<>(this, b, true); + public final Task then(ExceptionalSupplier b) { + return new CoupleTask(this, b, true); + } + + public final TaskResult thenResult(Callable supplier) { + return thenTaskResult(() -> Task.ofResult(supplier)); + } + + public final TaskResult thenTaskResult(ExceptionalSupplier, ?> taskSupplier) { + return new TaskResult() { + TaskResult then; + + @Override + public void execute() throws Exception { + then = taskSupplier.get().storeTo(this::setResult); + } + + @Override + public Collection getDependencies() { + return then == null ? Collections.emptyList() : Collections.singleton(then); + } + }; } public final Task with(Task b) { return with(convert(b)); } - public final Task with(ExceptionalFunction, Task, E> b) { - return new CoupleTask<>(this, b, false); + public final Task with(ExceptionalSupplier b) { + return new CoupleTask(this, b, false); } public final Task finalized(FinalizedCallback b) { @@ -317,7 +318,7 @@ public abstract class Task { } public final Task finalized(Scheduler scheduler, FinalizedCallback b) { - return new FinalizedTask(this, scheduler, b, ReflectionHelper.getCaller().toString()); + return new FinalizedTask(this, scheduler, b).setName(getCaller()); } // T, K here is necessary, or javac cannot infer type of failure @@ -339,58 +340,38 @@ public abstract class Task { }); } - public static Task of(String name, ExceptionalRunnable runnable) { - return of(name, ExceptionalConsumer.fromRunnable(runnable)); - } - - public static Task of(ExceptionalRunnable runnable) { - return of(ExceptionalConsumer.fromRunnable(runnable)); - } - - public static Task of(String name, ExceptionalConsumer, ?> closure) { - return of(name, Schedulers.defaultScheduler(), closure); - } - - public static Task of(ExceptionalConsumer, ?> closure) { + public static Task of(ExceptionalRunnable closure) { return of(Schedulers.defaultScheduler(), closure); } - public static Task of(String name, Scheduler scheduler, ExceptionalConsumer, ?> closure) { - return new SimpleTask(name, closure, scheduler); - } - - public static Task of(Scheduler scheduler, ExceptionalConsumer, ?> closure) { - return of(ReflectionHelper.getCaller().toString(), scheduler, closure); - } - - public static Task of(String name, Scheduler scheduler, ExceptionalRunnable closure) { - return new SimpleTask(name, ExceptionalConsumer.fromRunnable(closure), scheduler); + public static Task of(String name, ExceptionalRunnable closure) { + return of(name, Schedulers.defaultScheduler(), closure); } public static Task of(Scheduler scheduler, ExceptionalRunnable closure) { - return of(ReflectionHelper.getCaller().toString(), scheduler, closure); + return of(getCaller(), scheduler, closure); } - public static Task ofThen(ExceptionalFunction, Task, ?> b) { - return new CoupleTask<>(null, b, true); + public static Task of(String name, Scheduler scheduler, ExceptionalRunnable closure) { + return new SimpleTask(name, closure, scheduler); + } + + public static Task ofThen(ExceptionalSupplier b) { + return new CoupleTask(null, b, true); } public static TaskResult ofResult(Callable callable) { - return ofResult("", callable); + return ofResult(getCaller(), callable); } - public static TaskResult ofResult(String id, Callable callable) { - return new TaskCallable<>(id, callable); + public static TaskResult ofResult(String name, Callable callable) { + return new SimpleTaskResult<>(callable).setName(name); } - public static TaskResult ofResult(String id, ExceptionalFunction, V, ?> closure) { - return new TaskCallable<>(id, closure); - } - - private static ExceptionalFunction, Task, ?> convert(Task t) { - return new ExceptionalFunction, Task, Exception>() { + private static ExceptionalSupplier convert(Task t) { + return new ExceptionalSupplier() { @Override - public Task apply(AutoTypingMap autoTypingMap) { + public Task get() { return t; } @@ -426,4 +407,8 @@ public abstract class Task { public interface FinalizedCallback { void execute(boolean isDependentsSucceeded, Exception exception) throws Exception; } + + static String getCaller() { + return ReflectionHelper.getCaller(packageName -> !"org.jackhuang.hmcl.task".equals(packageName)).toString(); + } } diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/task/TaskCallable.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/task/TaskCallable.java deleted file mode 100644 index 1b7e85432..000000000 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/task/TaskCallable.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Hello Minecraft! Launcher - * Copyright (C) 2019 huangyuhui 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 . - */ -package org.jackhuang.hmcl.task; - -import org.jackhuang.hmcl.util.AutoTypingMap; -import org.jackhuang.hmcl.util.function.ExceptionalFunction; - -import java.util.concurrent.Callable; - -/** - * - * @author huangyuhui - */ -class TaskCallable extends TaskResult { - - private final String id; - private final ExceptionalFunction, V, ?> callable; - - public TaskCallable(String id, Callable callable) { - this(id, variables -> callable.call()); - } - - public TaskCallable(String id, ExceptionalFunction, V, ?> callable) { - this.id = id; - this.callable = callable; - } - - @Override - public String getId() { - return id; - } - - @Override - public void execute() throws Exception { - setResult(callable.apply(getVariables())); - } -} diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/task/TaskExecutor.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/task/TaskExecutor.java index 074e1c161..12587b715 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/task/TaskExecutor.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/task/TaskExecutor.java @@ -38,7 +38,6 @@ public final class TaskExecutor { private Exception lastException; private final AtomicInteger totTask = new AtomicInteger(0); private final ConcurrentLinkedQueue> workerQueue = new ConcurrentLinkedQueue<>(); - private final AutoTypingMap variables = new AutoTypingMap<>(new HashMap<>()); private Scheduler scheduler = Schedulers.newThread(); public TaskExecutor(Task task) { @@ -147,8 +146,6 @@ public final class TaskExecutor { boolean flag = false; try { - task.setVariables(variables); - if (task.doPreExecute()) { try { task.getScheduler().schedule(task::preExecute).get(); @@ -186,11 +183,6 @@ public final class TaskExecutor { task.setState(Task.TaskState.EXECUTED); } - if (task instanceof TaskResult) { - TaskResult taskResult = (TaskResult) task; - variables.set(taskResult.getId(), taskResult.getResult()); - } - Collection dependencies = task.getDependencies(); boolean doDependenciesSucceeded = executeTasks(dependencies); Exception dependenciesException = dependencies.stream().map(Task::getLastException).filter(Objects::nonNull).findAny().orElse(null); @@ -238,8 +230,6 @@ public final class TaskExecutor { } task.onDone().fireEvent(new TaskEvent(this, task, true)); taskListeners.forEach(it -> it.onFailed(task, e)); - } finally { - task.setVariables(null); } task.setState(flag ? Task.TaskState.SUCCEEDED : Task.TaskState.FAILED); return flag; @@ -249,10 +239,6 @@ public final class TaskExecutor { return totTask.get(); } - public AutoTypingMap getVariables() { - return variables; - } - private class Invoker implements ExceptionalRunnable { private final Task task; diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/task/TaskResult.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/task/TaskResult.java index 46f2ecc55..5f9185ae0 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/task/TaskResult.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/task/TaskResult.java @@ -17,12 +17,12 @@ */ package org.jackhuang.hmcl.task; -import org.jackhuang.hmcl.util.ReflectionHelper; import org.jackhuang.hmcl.util.function.ExceptionalConsumer; import org.jackhuang.hmcl.util.function.ExceptionalFunction; import java.util.Collection; import java.util.Collections; +import java.util.function.Consumer; /** * A task that has a result. @@ -32,6 +32,13 @@ import java.util.Collections; public abstract class TaskResult extends Task { private V result; + private Consumer resultConsumer; + + @Override + public TaskResult setName(String name) { + super.setName(name); + return this; + } public V getResult() { return result; @@ -39,20 +46,59 @@ public abstract class TaskResult extends Task { public void setResult(V result) { this.result = result; + if (resultConsumer != null) + resultConsumer.accept(result); } - public abstract String getId(); + public TaskResult storeTo(Consumer resultConsumer) { + this.resultConsumer = resultConsumer; + return this; + } + + public TaskResult thenTaskResult(ExceptionalFunction, E> taskSupplier) { + return new TaskResult() { + TaskResult then; + + @Override + public Collection getDependents() { + return Collections.singleton(TaskResult.this); + } + + @Override + public void execute() throws Exception { + then = taskSupplier.apply(TaskResult.this.getResult()).storeTo(this::setResult); + } + + @Override + public Collection getDependencies() { + return then == null ? Collections.emptyList() : Collections.singleton(then); + } + }; + } + + public Task then(ExceptionalFunction taskSupplier) { + return new CoupleTask(this, () -> taskSupplier.apply(getResult()), true); + } public TaskResult thenResult(ExceptionalFunction task) { return thenResult(Schedulers.defaultScheduler(), task); } public TaskResult thenResult(Scheduler scheduler, ExceptionalFunction task) { - return thenResult(ReflectionHelper.getCaller().toString(), scheduler, task); + return thenResult(getCaller(), scheduler, task); } - public TaskResult thenResult(String id, Scheduler scheduler, ExceptionalFunction task) { - return new Subtask<>(id, scheduler, task); + public TaskResult thenResult(String name, Scheduler scheduler, ExceptionalFunction task) { + return new Subtask<>(name, scheduler, task); + } + + // stupid javac stop us from renaming thenVoid to thenResult + public Task thenVoid(ExceptionalConsumer task) { + return thenVoid(Schedulers.defaultScheduler(), task); + } + + public Task thenVoid(Scheduler scheduler, ExceptionalConsumer task) { + return new CoupleTask(this, () -> Task.of(scheduler, () -> task.accept(getResult())), true); } public Task finalized(Scheduler scheduler, ExceptionalConsumer success, ExceptionalConsumer failure) { @@ -64,14 +110,14 @@ public abstract class TaskResult extends Task { } private class Subtask extends TaskResult { - private final String id; private final Scheduler scheduler; private final ExceptionalFunction callable; - public Subtask(String id, Scheduler scheduler, ExceptionalFunction callable) { - this.id = id; + public Subtask(String name, Scheduler scheduler, ExceptionalFunction callable) { this.scheduler = scheduler; this.callable = callable; + + setName(name); } @Override @@ -79,11 +125,6 @@ public abstract class TaskResult extends Task { return Collections.singleton(TaskResult.this); } - @Override - public String getId() { - return id; - } - @Override public Scheduler getScheduler() { return scheduler; diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/util/ReflectionHelper.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/util/ReflectionHelper.java index aa497f936..12e24507e 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/util/ReflectionHelper.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/util/ReflectionHelper.java @@ -17,17 +17,28 @@ */ package org.jackhuang.hmcl.util; +import java.util.function.Predicate; + /** * * @author huangyuhui */ public final class ReflectionHelper { - public static StackTraceElement getCaller() { + /** + * Get caller, this method is caller sensitive. + * @param packageFilter returns false if we consider the given package is internal calls, not the caller + * @return the caller, method name, source file, line number + */ + public static StackTraceElement getCaller(Predicate packageFilter) { StackTraceElement[] elements = Thread.currentThread().getStackTrace(); + // element[0] is Thread.currentThread().getStackTrace() + // element[1] is ReflectionHelper.getCaller(packageFilter) + // so element[2] is caller of this method. StackTraceElement caller = elements[2]; for (int i = 3; i < elements.length; ++i) { - if (!caller.getClassName().equals(elements[i].getClassName())) + if (packageFilter.test(StringUtils.substringBeforeLast(elements[i].getClassName(), '.')) && + !caller.getClassName().equals(elements[i].getClassName())) return elements[i]; } return caller;