Add support for suspending functions
This also changes CommandExecutionHandler to return futures instead. The old method is still supported, and the new future-returning method will delegate to the old non-returning method.
This commit is contained in:
parent
c16ee8049b
commit
7bb5e63dc7
12 changed files with 556 additions and 249 deletions
|
|
@ -910,6 +910,15 @@ public abstract class CommandManager<C> {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the command execution coordinator used in this manager
|
||||
*
|
||||
* @return Command execution coordinator
|
||||
*/
|
||||
public @NonNull CommandExecutionCoordinator<C> commandExecutionCoordinator() {
|
||||
return this.commandExecutionCoordinator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Transition from the {@code in} state to the {@code out} state, if the manager is not already in that state.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -81,13 +81,15 @@ public final class AsynchronousCommandExecutionCoordinator<C> extends CommandExe
|
|||
|
||||
final Consumer<Command<C>> commandConsumer = command -> {
|
||||
if (this.commandManager.postprocessContext(commandContext, command) == State.ACCEPTED) {
|
||||
try {
|
||||
command.getCommandExecutionHandler().execute(commandContext);
|
||||
} catch (final CommandExecutionException exception) {
|
||||
resultFuture.completeExceptionally(exception);
|
||||
} catch (final Exception exception) {
|
||||
resultFuture.completeExceptionally(new CommandExecutionException(exception, commandContext));
|
||||
}
|
||||
command.getCommandExecutionHandler().executeFuture(commandContext).whenComplete((result, throwable) -> {
|
||||
if (throwable != null) {
|
||||
if (throwable instanceof CommandExecutionException) {
|
||||
resultFuture.completeExceptionally(throwable);
|
||||
} else {
|
||||
resultFuture.completeExceptionally(new CommandExecutionException(throwable, commandContext));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -118,7 +118,7 @@ public abstract class CommandExecutionCoordinator<C> {
|
|||
final Command<C> command = Objects.requireNonNull(pair.getFirst());
|
||||
if (this.getCommandTree().getCommandManager().postprocessContext(commandContext, command) == State.ACCEPTED) {
|
||||
try {
|
||||
command.getCommandExecutionHandler().execute(commandContext);
|
||||
command.getCommandExecutionHandler().executeFuture(commandContext).get();
|
||||
} catch (final CommandExecutionException exception) {
|
||||
completableFuture.completeExceptionally(exception);
|
||||
} catch (final Exception exception) {
|
||||
|
|
|
|||
|
|
@ -25,7 +25,11 @@ package cloud.commandframework.execution;
|
|||
|
||||
import cloud.commandframework.Command;
|
||||
import cloud.commandframework.context.CommandContext;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
/**
|
||||
* Handler that is invoked whenever a {@link Command} is executed
|
||||
|
|
@ -43,6 +47,23 @@ public interface CommandExecutionHandler<C> {
|
|||
*/
|
||||
void execute(@NonNull CommandContext<C> commandContext);
|
||||
|
||||
/**
|
||||
* Handle command execution
|
||||
*
|
||||
* @param commandContext Command context
|
||||
* @return future that completes when the command has finished execution
|
||||
*/
|
||||
default CompletableFuture<@Nullable Object> executeFuture(@NonNull CommandContext<C> commandContext) {
|
||||
final CompletableFuture<Object> future = new CompletableFuture<>();
|
||||
try {
|
||||
execute(commandContext);
|
||||
/* The command executed successfully */
|
||||
future.complete(null);
|
||||
} catch (final Throwable throwable) {
|
||||
future.completeExceptionally(throwable);
|
||||
}
|
||||
return future;
|
||||
}
|
||||
|
||||
/**
|
||||
* Command execution handler that does nothing
|
||||
|
|
@ -57,4 +78,27 @@ public interface CommandExecutionHandler<C> {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* Handler that is invoked whenever a {@link Command} is executed
|
||||
* by a command sender
|
||||
*
|
||||
* @param <C> Command sender type
|
||||
*/
|
||||
@FunctionalInterface
|
||||
interface FutureCommandExecutionHandler<C> extends CommandExecutionHandler<C> {
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("FunctionalInterfaceMethodChanged")
|
||||
default void execute(
|
||||
@NonNull CommandContext<C> commandContext
|
||||
) {
|
||||
}
|
||||
|
||||
@Override
|
||||
CompletableFuture<@Nullable Object> executeFuture(
|
||||
@NonNull CommandContext<C> commandContext
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
package cloud.commandframework.extra.confirmation;
|
||||
|
||||
import cloud.commandframework.CommandManager;
|
||||
import cloud.commandframework.context.CommandContext;
|
||||
import cloud.commandframework.execution.CommandExecutionHandler;
|
||||
import cloud.commandframework.execution.postprocessor.CommandPostprocessingContext;
|
||||
import cloud.commandframework.execution.postprocessor.CommandPostprocessor;
|
||||
|
|
@ -31,6 +32,9 @@ import cloud.commandframework.meta.CommandMeta;
|
|||
import cloud.commandframework.meta.SimpleCommandMeta;
|
||||
import cloud.commandframework.services.types.ConsumerService;
|
||||
import cloud.commandframework.types.tuples.Pair;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
|
|
@ -158,20 +162,20 @@ public class CommandConfirmationManager<C> {
|
|||
* @return Handler for a confirmation command
|
||||
*/
|
||||
public @NonNull CommandExecutionHandler<C> createConfirmationExecutionHandler() {
|
||||
return context -> {
|
||||
return (CommandExecutionHandler.FutureCommandExecutionHandler<C>) context -> {
|
||||
final Optional<CommandPostprocessingContext<C>> pending = this.getPending(context.getSender());
|
||||
if (pending.isPresent()) {
|
||||
final CommandPostprocessingContext<C> postprocessingContext = pending.get();
|
||||
postprocessingContext.getCommand()
|
||||
return postprocessingContext.getCommand()
|
||||
.getCommandExecutionHandler()
|
||||
.execute(postprocessingContext.getCommandContext());
|
||||
.executeFuture(postprocessingContext.getCommandContext());
|
||||
} else {
|
||||
this.errorNotifier.accept(context.getSender());
|
||||
}
|
||||
return CompletableFuture.completedFuture(null);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
private final class CommandConfirmationPostProcessor implements CommandPostprocessor<C> {
|
||||
|
||||
@Override
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue