Simplify EventTask. Add custom handler support.

Additionally support for continuation adapters (will be used by the kotlin language plugin).
This commit is contained in:
Seppe Volkaerts
2021-05-17 21:01:17 +02:00
parent 0ddadc90e2
commit c30575ec44
8 changed files with 355 additions and 214 deletions

View File

@@ -17,13 +17,10 @@ import java.util.function.Consumer;
* be suspended and resumed at a later time, and executing event handlers completely or partially
* asynchronously.
*
* <p>By default will all event handlers be executed on the thread the event was posted, using
* event tasks this behavior can be altered.</p>
* <p>By default will all event handlers be executed on the thread the event was posted, this
* behavior can be altered by using event tasks.</p>
*/
public abstract class EventTask {
EventTask() {
}
public interface EventTask {
/**
* Whether this {@link EventTask} is required to be called asynchronously.
@@ -34,65 +31,22 @@ public abstract class EventTask {
*
* @return Requires async
*/
public abstract boolean requiresAsync();
boolean requiresAsync();
/**
* Represents a basic {@link EventTask}. The execution of the event handlers will resume after
* this basic task is executed using {@link #run()}.
*/
public abstract static class Basic extends EventTask {
/**
* Runs the task.
*/
public abstract void run();
}
/**
* Represents an {@link EventTask} which receives a {@link Continuation} through
* {@link #run(Continuation)}. The continuation must be notified when the task is
* completed, either with {@link Continuation#resume()} if the task was successful or
* {@link Continuation#resumeWithException(Throwable)} if an exception occurred.
* Runs this event task with the given {@link Continuation}. The continuation must be notified
* when the task is completed, either with {@link Continuation#resume()} if the task was
* successful or {@link Continuation#resumeWithException(Throwable)} if an exception occurred.
*
* <p>The {@link Continuation} may only be resumed once, or an
* {@link IllegalStateException} is expected.</p>
* {@link IllegalStateException} will be thrown.</p>
*
* <p>The {@link Continuation} doesn't need to be notified during the execution of
* {@link #run(Continuation)}, this can happen at a later point in time and from another
* thread.</p>
*/
public abstract static class WithContinuation extends EventTask {
/**
* Runs this async task with the given continuation.
*
* @param continuation The continuation
*/
public abstract void run(Continuation continuation);
}
/**
* Creates a basic {@link EventTask} from the given {@link Runnable}. The task isn't guaranteed
* to be executed asynchronously ({@link #requiresAsync()} always returns {@code false}).
* <p>The {@link Continuation} doesn't need to be notified during the execution of this method,
* this can happen at a later point in time and from another thread.</p>
*
* @param task The task
* @return The event task
* @param continuation The continuation
*/
public static EventTask.Basic of(final Runnable task) {
requireNonNull(task, "task");
return new Basic() {
@Override
public void run() {
task.run();
}
@Override
public boolean requiresAsync() {
return false;
}
};
}
void execute(Continuation continuation);
/**
* Creates a basic async {@link EventTask} from the given {@link Runnable}. The task is guaranteed
@@ -101,13 +55,14 @@ public abstract class EventTask {
* @param task The task
* @return The async event task
*/
public static EventTask.Basic async(final Runnable task) {
static EventTask async(final Runnable task) {
requireNonNull(task, "task");
return new Basic() {
return new EventTask() {
@Override
public void run() {
public void execute(Continuation continuation) {
task.run();
continuation.resume();
}
@Override
@@ -125,13 +80,12 @@ public abstract class EventTask {
* @param task The task to execute
* @return The event task
*/
public static EventTask.WithContinuation withContinuation(
final Consumer<Continuation> task) {
static EventTask withContinuation(final Consumer<Continuation> task) {
requireNonNull(task, "task");
return new WithContinuation() {
return new EventTask() {
@Override
public void run(final Continuation continuation) {
public void execute(final Continuation continuation) {
task.accept(continuation);
}
@@ -142,31 +96,6 @@ public abstract class EventTask {
};
}
/**
* Creates an async continuation based {@link EventTask} from the given {@link Consumer}. The task
* is guaranteed to be executed asynchronously ({@link #requiresAsync()} always returns
* {@code false}).
*
* @param task The task to execute
* @return The event task
*/
public static EventTask.WithContinuation asyncWithContinuation(
final Consumer<Continuation> task) {
requireNonNull(task, "task");
return new WithContinuation() {
@Override
public void run(final Continuation continuation) {
task.accept(continuation);
}
@Override
public boolean requiresAsync() {
return true;
}
};
}
/**
* Creates an continuation based {@link EventTask} for the given {@link CompletableFuture}. The
* continuation will be notified once the given future is completed.
@@ -177,8 +106,7 @@ public abstract class EventTask {
// The Error Prone annotation here is spurious. The Future is handled via the CompletableFuture
// API, which does NOT use the traditional blocking model.
@SuppressWarnings("FutureReturnValueIgnored")
public static EventTask.WithContinuation resumeWhenComplete(
final CompletableFuture<?> future) {
static EventTask resumeWhenComplete(final CompletableFuture<?> future) {
requireNonNull(future, "future");
return withContinuation(continuation -> future.whenComplete((result, cause) -> {
if (cause != null) {