简化 Task (#5365)
This commit is contained in:
@@ -92,7 +92,7 @@ public final class AsyncTaskExecutor extends TaskExecutor {
|
||||
throw new IllegalStateException("Cannot cancel a not started TaskExecutor");
|
||||
}
|
||||
|
||||
cancelled.set(true);
|
||||
cancelled = true;
|
||||
}
|
||||
|
||||
private CompletableFuture<?> executeTasksExceptionally(Task<?> parentTask, Collection<? extends Task<?>> tasks) {
|
||||
@@ -101,8 +101,6 @@ public final class AsyncTaskExecutor extends TaskExecutor {
|
||||
|
||||
return CompletableFuture.completedFuture(null)
|
||||
.thenComposeAsync(unused -> {
|
||||
totTask.addAndGet(tasks.size());
|
||||
|
||||
if (isCancelled()) {
|
||||
for (Task<?> task : tasks) task.setException(new CancellationException());
|
||||
return CompletableFuture.runAsync(this::checkCancellation);
|
||||
@@ -164,7 +162,7 @@ public final class AsyncTaskExecutor extends TaskExecutor {
|
||||
}
|
||||
|
||||
task.setResult(result);
|
||||
task.onDone().fireEvent(new TaskEvent(this, task, false));
|
||||
task.fireDoneEvent(this, false);
|
||||
taskListeners.forEach(it -> it.onFinished(task));
|
||||
|
||||
task.setState(Task.TaskState.SUCCEEDED);
|
||||
@@ -173,14 +171,13 @@ public final class AsyncTaskExecutor extends TaskExecutor {
|
||||
})
|
||||
.exceptionally(throwable -> {
|
||||
Throwable resolved = resolveException(throwable);
|
||||
if (resolved instanceof Exception) {
|
||||
Exception e = (Exception) resolved;
|
||||
if (resolved instanceof Exception e) {
|
||||
if (e instanceof InterruptedException || e instanceof CancellationException) {
|
||||
task.setException(null);
|
||||
if (task.getSignificance().shouldLog()) {
|
||||
LOG.trace("Task aborted: " + task.getName());
|
||||
}
|
||||
task.onDone().fireEvent(new TaskEvent(this, task, true));
|
||||
task.fireDoneEvent(this, true);
|
||||
taskListeners.forEach(it -> it.onFailed(task, e));
|
||||
} else {
|
||||
task.setException(e);
|
||||
@@ -188,7 +185,7 @@ public final class AsyncTaskExecutor extends TaskExecutor {
|
||||
if (task.getSignificance().shouldLog()) {
|
||||
LOG.trace("Task failed: " + task.getName(), e);
|
||||
}
|
||||
task.onDone().fireEvent(new TaskEvent(this, task, true));
|
||||
task.fireDoneEvent(this, true);
|
||||
taskListeners.forEach(it -> it.onFailed(task, e));
|
||||
}
|
||||
|
||||
@@ -278,7 +275,7 @@ public final class AsyncTaskExecutor extends TaskExecutor {
|
||||
LOG.trace("Task finished: " + task.getName());
|
||||
}
|
||||
|
||||
task.onDone().fireEvent(new TaskEvent(this, task, false));
|
||||
task.fireDoneEvent(this, false);
|
||||
taskListeners.forEach(it -> it.onFinished(task));
|
||||
|
||||
task.setState(Task.TaskState.SUCCEEDED);
|
||||
@@ -300,7 +297,7 @@ public final class AsyncTaskExecutor extends TaskExecutor {
|
||||
LOG.trace("Task failed: " + task.getName(), e);
|
||||
}
|
||||
}
|
||||
task.onDone().fireEvent(new TaskEvent(this, task, true));
|
||||
task.fireDoneEvent(this, true);
|
||||
taskListeners.forEach(it -> it.onFailed(task, e));
|
||||
|
||||
task.setState(Task.TaskState.FAILED);
|
||||
@@ -311,8 +308,8 @@ public final class AsyncTaskExecutor extends TaskExecutor {
|
||||
}
|
||||
|
||||
private <T> CompletableFuture<T> executeTask(Task<?> parentTask, Task<T> task) {
|
||||
if (task instanceof CompletableFutureTask<?>) {
|
||||
return executeCompletableFutureTask(parentTask, (CompletableFutureTask<T>) task);
|
||||
if (task instanceof CompletableFutureTask<T> completableFutureTask) {
|
||||
return executeCompletableFutureTask(parentTask, completableFutureTask);
|
||||
} else {
|
||||
return executeNormalTask(parentTask, task);
|
||||
}
|
||||
|
||||
@@ -18,18 +18,18 @@
|
||||
package org.jackhuang.hmcl.task;
|
||||
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.property.DoubleProperty;
|
||||
import javafx.beans.property.ReadOnlyDoubleProperty;
|
||||
import javafx.beans.property.ReadOnlyDoubleWrapper;
|
||||
import javafx.beans.property.ReadOnlyStringProperty;
|
||||
import javafx.beans.property.ReadOnlyStringWrapper;
|
||||
import javafx.beans.property.SimpleDoubleProperty;
|
||||
import org.jackhuang.hmcl.event.EventManager;
|
||||
import org.jackhuang.hmcl.util.InvocationDispatcher;
|
||||
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 org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.invoke.VarHandle;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
@@ -47,8 +47,6 @@ import static org.jackhuang.hmcl.util.logging.Logger.LOG;
|
||||
*/
|
||||
public abstract class Task<T> {
|
||||
|
||||
private final EventManager<TaskEvent> onDone = new EventManager<>();
|
||||
|
||||
/**
|
||||
* True if not logging when executing this task.
|
||||
*/
|
||||
@@ -64,9 +62,9 @@ public abstract class Task<T> {
|
||||
}
|
||||
|
||||
// cancel
|
||||
private Supplier<Boolean> cancelled;
|
||||
private BooleanSupplier cancelled;
|
||||
|
||||
final void setCancelled(Supplier<Boolean> cancelled) {
|
||||
final void setCancelled(BooleanSupplier cancelled) {
|
||||
this.cancelled = cancelled;
|
||||
}
|
||||
|
||||
@@ -76,7 +74,7 @@ public abstract class Task<T> {
|
||||
return true;
|
||||
}
|
||||
|
||||
return cancelled != null ? cancelled.get() : false;
|
||||
return cancelled != null && cancelled.getAsBoolean();
|
||||
}
|
||||
|
||||
// stage
|
||||
@@ -92,6 +90,7 @@ public abstract class Task<T> {
|
||||
|
||||
/**
|
||||
* You must initialize stage in constructor.
|
||||
*
|
||||
* @param stage the stage
|
||||
*/
|
||||
protected final void setStage(String stage) {
|
||||
@@ -211,10 +210,10 @@ public abstract class Task<T> {
|
||||
}
|
||||
|
||||
// name
|
||||
private String name = getClass().getName();
|
||||
private String name;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
return name != null ? name : getClass().getName();
|
||||
}
|
||||
|
||||
public Task<T> setName(String name) {
|
||||
@@ -236,7 +235,7 @@ public abstract class Task<T> {
|
||||
|
||||
/**
|
||||
* Returns the result of this task.
|
||||
*
|
||||
* <p>
|
||||
* The result will be generated only if the execution is completed.
|
||||
*/
|
||||
public T getResult() {
|
||||
@@ -270,7 +269,8 @@ public abstract class Task<T> {
|
||||
* @throws InterruptedException if current thread is interrupted
|
||||
* @see Thread#isInterrupted()
|
||||
*/
|
||||
public void preExecute() throws Exception {}
|
||||
public void preExecute() throws Exception {
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws InterruptedException if current thread is interrupted
|
||||
@@ -284,7 +284,7 @@ public abstract class Task<T> {
|
||||
|
||||
/**
|
||||
* This method will be called after dependency tasks terminated all together.
|
||||
*
|
||||
* <p>
|
||||
* You can check whether dependencies succeed in this method by calling
|
||||
* {@link Task#isDependenciesSucceeded()} no matter when
|
||||
* {@link Task#isRelyingOnDependencies()} returns true or false.
|
||||
@@ -293,7 +293,8 @@ public abstract class Task<T> {
|
||||
* @see Thread#isInterrupted()
|
||||
* @see Task#isDependenciesSucceeded()
|
||||
*/
|
||||
public void postExecute() throws Exception {}
|
||||
public void postExecute() throws Exception {
|
||||
}
|
||||
|
||||
/**
|
||||
* The collection of sub-tasks that should execute **before** this task running.
|
||||
@@ -310,44 +311,74 @@ public abstract class Task<T> {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
private volatile EventManager<TaskEvent> onDone;
|
||||
|
||||
public EventManager<TaskEvent> onDone() {
|
||||
EventManager<TaskEvent> onDone = this.onDone;
|
||||
if (onDone == null) {
|
||||
synchronized (this) {
|
||||
onDone = this.onDone;
|
||||
if (onDone == null) {
|
||||
this.onDone = onDone = new EventManager<>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return onDone;
|
||||
}
|
||||
|
||||
protected long getProgressInterval() {
|
||||
return 1000L;
|
||||
void fireDoneEvent(Object source, boolean failed) {
|
||||
EventManager<TaskEvent> onDone = this.onDone;
|
||||
if (onDone != null)
|
||||
onDone.fireEvent(new TaskEvent(source, this, failed));
|
||||
}
|
||||
|
||||
private long lastTime = Long.MIN_VALUE;
|
||||
private final ReadOnlyDoubleWrapper progress = new ReadOnlyDoubleWrapper(this, "progress", -1);
|
||||
private final InvocationDispatcher<Double> progressUpdate = InvocationDispatcher.runOn(Platform::runLater, progress::set);
|
||||
private final DoubleProperty progress = new SimpleDoubleProperty(this, "progress", -1);
|
||||
|
||||
public ReadOnlyDoubleProperty progressProperty() {
|
||||
return progress.getReadOnlyProperty();
|
||||
return progress;
|
||||
}
|
||||
|
||||
private long lastUpdateProgressTime = 0L;
|
||||
|
||||
protected void updateProgress(long progress, long total) {
|
||||
updateProgress(1.0 * progress / total);
|
||||
}
|
||||
|
||||
protected void updateProgress(double progress) {
|
||||
if (progress < 0 || progress > 1.0)
|
||||
throw new IllegalArgumentException("Progress is must between 0 and 1.");
|
||||
if (progress < 0 || progress > 1.0 || Double.isNaN(progress))
|
||||
throw new IllegalArgumentException("Progress must be between 0 and 1.");
|
||||
|
||||
long now = System.currentTimeMillis();
|
||||
if (lastTime == Long.MIN_VALUE || now - lastTime >= getProgressInterval()) {
|
||||
if (progress == 1.0 || now - lastUpdateProgressTime >= 1000L) {
|
||||
updateProgressImmediately(progress);
|
||||
lastTime = now;
|
||||
lastUpdateProgressTime = now;
|
||||
}
|
||||
}
|
||||
|
||||
protected void updateProgressImmediately(double progress) {
|
||||
progressUpdate.accept(progress);
|
||||
//region Helpers for updateProgressImmediately
|
||||
|
||||
@SuppressWarnings("FieldMayBeFinal")
|
||||
private volatile double pendingProgress = -1.0;
|
||||
|
||||
/// @see Task#pendingProgress
|
||||
private static final VarHandle PENDING_PROGRESS_HANDLE;
|
||||
|
||||
static {
|
||||
try {
|
||||
PENDING_PROGRESS_HANDLE = MethodHandles.lookup()
|
||||
.findVarHandle(Task.class, "pendingProgress", double.class);
|
||||
} catch (NoSuchFieldException | IllegalAccessException e) {
|
||||
throw new ExceptionInInitializerError(e);
|
||||
}
|
||||
}
|
||||
//endregion updateProgressImmediately
|
||||
|
||||
private final ReadOnlyStringWrapper message = new ReadOnlyStringWrapper(this, "message", null);
|
||||
|
||||
public final ReadOnlyStringProperty messageProperty() {
|
||||
return message.getReadOnlyProperty();
|
||||
protected void updateProgressImmediately(double progress) {
|
||||
// assert progress >= 0 && progress <= 1.0;
|
||||
if ((double) PENDING_PROGRESS_HANDLE.getAndSet(this, progress) == -1.0) {
|
||||
Platform.runLater(() -> this.progress.set((double) PENDING_PROGRESS_HANDLE.getAndSet(this, -1.0)));
|
||||
}
|
||||
}
|
||||
|
||||
public final T run() throws Exception {
|
||||
@@ -359,16 +390,14 @@ public abstract class Task<T> {
|
||||
execute();
|
||||
for (Task<?> task : getDependencies())
|
||||
doSubTask(task);
|
||||
onDone.fireEvent(new TaskEvent(this, this, false));
|
||||
fireDoneEvent(this, false);
|
||||
|
||||
return getResult();
|
||||
}
|
||||
|
||||
private void doSubTask(Task<?> task) throws Exception {
|
||||
message.bind(task.message);
|
||||
progress.bind(task.progress);
|
||||
task.run();
|
||||
message.unbind();
|
||||
progress.unbind();
|
||||
}
|
||||
|
||||
@@ -402,7 +431,7 @@ public abstract class Task<T> {
|
||||
* normally, is executed using the default Executor, with this
|
||||
* task's result as the argument to the supplied function.
|
||||
*
|
||||
* @param fn the function to use to compute the value of the returned Task
|
||||
* @param fn the function to use to compute the value of the returned Task
|
||||
* @param <U> the function's return type
|
||||
* @return the new Task
|
||||
*/
|
||||
@@ -416,8 +445,8 @@ public abstract class Task<T> {
|
||||
* task's result as the argument to the supplied function.
|
||||
*
|
||||
* @param executor the executor to use for asynchronous execution
|
||||
* @param fn the function to use to compute the value of the returned Task
|
||||
* @param <U> the function's return type
|
||||
* @param fn the function to use to compute the value of the returned Task
|
||||
* @param <U> the function's return type
|
||||
* @return the new Task
|
||||
*/
|
||||
public <U, E extends Exception> Task<U> thenApplyAsync(Executor executor, ExceptionalFunction<T, U, E> fn) {
|
||||
@@ -429,10 +458,10 @@ public abstract class Task<T> {
|
||||
* normally, is executed using the supplied Executor, with this
|
||||
* task's result as the argument to the supplied function.
|
||||
*
|
||||
* @param name the name of this new Task for displaying
|
||||
* @param name the name of this new Task for displaying
|
||||
* @param executor the executor to use for asynchronous execution
|
||||
* @param fn the function to use to compute the value of the returned Task
|
||||
* @param <U> the function's return type
|
||||
* @param fn the function to use to compute the value of the returned Task
|
||||
* @param <U> the function's return type
|
||||
* @return the new Task
|
||||
*/
|
||||
public <U, E extends Exception> Task<U> thenApplyAsync(String name, Executor executor, ExceptionalFunction<T, U, E> fn) {
|
||||
@@ -445,7 +474,7 @@ public abstract class Task<T> {
|
||||
* task's result as the argument to the supplied action.
|
||||
*
|
||||
* @param action the action to perform before completing the
|
||||
* returned Task
|
||||
* returned Task
|
||||
* @return the new Task
|
||||
*/
|
||||
public <E extends Exception> Task<Void> thenAcceptAsync(ExceptionalConsumer<T, E> action) {
|
||||
@@ -457,7 +486,7 @@ public abstract class Task<T> {
|
||||
* normally, is executed using the supplied Executor, with this
|
||||
* task's result as the argument to the supplied action.
|
||||
*
|
||||
* @param action the action to perform before completing the returned Task
|
||||
* @param action the action to perform before completing the returned Task
|
||||
* @param executor the executor to use for asynchronous execution
|
||||
* @return the new Task
|
||||
*/
|
||||
@@ -470,8 +499,8 @@ public abstract class Task<T> {
|
||||
* normally, is executed using the supplied Executor, with this
|
||||
* task's result as the argument to the supplied action.
|
||||
*
|
||||
* @param name the name of this new Task for displaying
|
||||
* @param action the action to perform before completing the returned Task
|
||||
* @param name the name of this new Task for displaying
|
||||
* @param action the action to perform before completing the returned Task
|
||||
* @param executor the executor to use for asynchronous execution
|
||||
* @return the new Task
|
||||
*/
|
||||
@@ -487,7 +516,7 @@ public abstract class Task<T> {
|
||||
* normally, executes the given action using the default Executor.
|
||||
*
|
||||
* @param action the action to perform before completing the
|
||||
* returned Task
|
||||
* returned Task
|
||||
* @return the new Task
|
||||
*/
|
||||
public <E extends Exception> Task<Void> thenRunAsync(ExceptionalRunnable<E> action) {
|
||||
@@ -498,8 +527,8 @@ public abstract class Task<T> {
|
||||
* Returns a new Task that, when this task completes
|
||||
* normally, executes the given action using the supplied Executor.
|
||||
*
|
||||
* @param action the action to perform before completing the
|
||||
* returned Task
|
||||
* @param action the action to perform before completing the
|
||||
* returned Task
|
||||
* @param executor the executor to use for asynchronous execution
|
||||
* @return the new Task
|
||||
*/
|
||||
@@ -511,9 +540,9 @@ public abstract class Task<T> {
|
||||
* Returns a new Task that, when this task completes
|
||||
* normally, executes the given action using the supplied Executor.
|
||||
*
|
||||
* @param name the name of this new Task for displaying
|
||||
* @param action the action to perform before completing the
|
||||
* returned Task
|
||||
* @param name the name of this new Task for displaying
|
||||
* @param action the action to perform before completing the
|
||||
* returned Task
|
||||
* @param executor the executor to use for asynchronous execution
|
||||
* @return the new Task
|
||||
*/
|
||||
@@ -528,7 +557,7 @@ public abstract class Task<T> {
|
||||
* Returns a new Task that, when this task completes
|
||||
* normally, is executed using the default Executor.
|
||||
*
|
||||
* @param fn the function to use to compute the value of the returned Task
|
||||
* @param fn the function to use to compute the value of the returned Task
|
||||
* @param <U> the function's return type
|
||||
* @return the new Task
|
||||
*/
|
||||
@@ -541,8 +570,8 @@ public abstract class Task<T> {
|
||||
* normally, is executed using the default Executor.
|
||||
*
|
||||
* @param name the name of this new Task for displaying
|
||||
* @param fn the function to use to compute the value of the returned Task
|
||||
* @param <U> the function's return type
|
||||
* @param fn the function to use to compute the value of the returned Task
|
||||
* @param <U> the function's return type
|
||||
* @return the new Task
|
||||
*/
|
||||
public final <U> Task<U> thenSupplyAsync(String name, Callable<U> fn) {
|
||||
@@ -554,7 +583,7 @@ public abstract class Task<T> {
|
||||
* normally, is executed.
|
||||
*
|
||||
* @param other the another Task
|
||||
* @param <U> the type of the returned Task's result
|
||||
* @param <U> the type of the returned Task's result
|
||||
* @return the Task
|
||||
*/
|
||||
public final <U> Task<U> thenComposeAsync(Task<U> other) {
|
||||
@@ -565,7 +594,7 @@ public abstract class Task<T> {
|
||||
* Returns a new Task that, when this task completes
|
||||
* normally, is executed.
|
||||
*
|
||||
* @param fn the function returning a new Task
|
||||
* @param fn the function returning a new Task
|
||||
* @param <U> the type of the returned Task's result
|
||||
* @return the Task
|
||||
*/
|
||||
@@ -577,9 +606,9 @@ public abstract class Task<T> {
|
||||
* Returns a new Task that, when this task completes
|
||||
* normally, is executed.
|
||||
*
|
||||
* @param fn the function returning a new Task
|
||||
* @param fn the function returning a new Task
|
||||
* @param executor the executor to use for asynchronous execution
|
||||
* @param <U> the type of the returned Task's result
|
||||
* @param <U> the type of the returned Task's result
|
||||
* @return the Task
|
||||
*/
|
||||
public final <U> Task<U> thenComposeAsync(Executor executor, ExceptionalSupplier<Task<U>, ?> fn) {
|
||||
@@ -591,7 +620,7 @@ public abstract class Task<T> {
|
||||
* normally, is executed with result of this task as the argument
|
||||
* to the supplied function.
|
||||
*
|
||||
* @param fn the function returning a new Task
|
||||
* @param fn the function returning a new Task
|
||||
* @param <U> the type of the returned Task's result
|
||||
* @return the Task
|
||||
*/
|
||||
@@ -604,9 +633,9 @@ public abstract class Task<T> {
|
||||
* normally, is executed with result of this task as the argument
|
||||
* to the supplied function.
|
||||
*
|
||||
* @param fn the function returning a new Task
|
||||
* @param fn the function returning a new Task
|
||||
* @param executor the executor to use for asynchronous execution
|
||||
* @param <U> the type of the returned Task's result
|
||||
* @param <U> the type of the returned Task's result
|
||||
* @return the Task
|
||||
*/
|
||||
public <U, E extends Exception> Task<U> thenComposeAsync(Executor executor, ExceptionalFunction<T, Task<U>, E> fn) {
|
||||
@@ -626,7 +655,7 @@ public abstract class Task<T> {
|
||||
* normally, executes the given action using the default Executor.
|
||||
*
|
||||
* @param action the action to perform before completing the
|
||||
* returned Task
|
||||
* returned Task
|
||||
* @return the new Task
|
||||
*/
|
||||
public <E extends Exception> Task<Void> withRunAsync(ExceptionalRunnable<E> action) {
|
||||
@@ -637,8 +666,8 @@ public abstract class Task<T> {
|
||||
* Returns a new Task that, when this task completes
|
||||
* normally, executes the given action using the supplied Executor.
|
||||
*
|
||||
* @param action the action to perform before completing the
|
||||
* returned Task
|
||||
* @param action the action to perform before completing the
|
||||
* returned Task
|
||||
* @param executor the executor to use for asynchronous execution
|
||||
* @return the new Task
|
||||
*/
|
||||
@@ -650,9 +679,9 @@ public abstract class Task<T> {
|
||||
* Returns a new Task that, when this task completes
|
||||
* normally, executes the given action using the supplied Executor.
|
||||
*
|
||||
* @param name the name of this new Task for displaying
|
||||
* @param action the action to perform before completing the
|
||||
* returned Task
|
||||
* @param name the name of this new Task for displaying
|
||||
* @param action the action to perform before completing the
|
||||
* returned Task
|
||||
* @param executor the executor to use for asynchronous execution
|
||||
* @return the new Task
|
||||
*/
|
||||
@@ -690,7 +719,7 @@ public abstract class Task<T> {
|
||||
* encounters an exception, then the returned task exceptionally completes
|
||||
* with this exception unless this task also completed exceptionally.
|
||||
*
|
||||
* @param action the action to perform
|
||||
* @param action the action to perform
|
||||
* @param executor the executor to use for asynchronous execution
|
||||
* @return the new Task
|
||||
*/
|
||||
@@ -994,10 +1023,12 @@ public abstract class Task<T> {
|
||||
FAILED
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface FinalizedCallback {
|
||||
void execute(Exception exception) throws Exception;
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface FinalizedCallbackWithResult<T> {
|
||||
void execute(T result, Exception exception) throws Exception;
|
||||
}
|
||||
@@ -1063,7 +1094,7 @@ public abstract class Task<T> {
|
||||
/**
|
||||
* A task that combines two tasks and make sure pred runs before succ.
|
||||
*
|
||||
* @param fn 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 fn 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.
|
||||
*/
|
||||
UniCompose(ExceptionalSupplier<Task<U>, ?> fn, boolean relyingOnDependents) {
|
||||
@@ -1073,7 +1104,7 @@ public abstract class Task<T> {
|
||||
/**
|
||||
* A task that combines two tasks and make sure pred runs before succ.
|
||||
*
|
||||
* @param fn 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 fn 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.
|
||||
*/
|
||||
UniCompose(ExceptionalFunction<T, Task<U>, ?> fn, boolean relyingOnDependents) {
|
||||
|
||||
@@ -20,20 +20,17 @@ package org.jackhuang.hmcl.task;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
public abstract class TaskExecutor {
|
||||
protected final Task<?> firstTask;
|
||||
protected final List<TaskListener> taskListeners = new ArrayList<>();
|
||||
protected final AtomicInteger totTask = new AtomicInteger(0);
|
||||
protected final AtomicBoolean cancelled = new AtomicBoolean(false);
|
||||
protected final List<TaskListener> taskListeners = new ArrayList<>(0);
|
||||
protected volatile boolean cancelled = false;
|
||||
protected Exception exception;
|
||||
private final List<String> stages;
|
||||
|
||||
public TaskExecutor(Task<?> task) {
|
||||
this.firstTask = task;
|
||||
this.stages = task instanceof Task.StagesHintTask ? ((Task<?>.StagesHintTask) task).getStages() : Collections.emptyList();
|
||||
this.stages = task instanceof Task<?>.StagesHintTask hintTask ? hintTask.getStages() : Collections.emptyList();
|
||||
}
|
||||
|
||||
public void addTaskListener(TaskListener taskListener) {
|
||||
@@ -59,11 +56,7 @@ public abstract class TaskExecutor {
|
||||
public abstract void cancel();
|
||||
|
||||
public boolean isCancelled() {
|
||||
return cancelled.get();
|
||||
}
|
||||
|
||||
public int getTaskCount() {
|
||||
return totTask.get();
|
||||
return cancelled;
|
||||
}
|
||||
|
||||
public List<String> getStages() {
|
||||
|
||||
Reference in New Issue
Block a user