From d6cdeca1c3835e2e1807aa5fc8fde19532cb6158 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20S=C3=B6derberg?= Date: Sat, 17 Oct 2020 18:58:31 +0200 Subject: [PATCH] :books: Improve the Bukkit and PaperCommandManager documentation --- .../bukkit/BukkitCommandManager.java | 26 ++++++++++++-- .../paper/PaperCommandManager.java | 34 +++++++++++++++++-- 2 files changed, 55 insertions(+), 5 deletions(-) diff --git a/cloud-minecraft/cloud-bukkit/src/main/java/cloud/commandframework/bukkit/BukkitCommandManager.java b/cloud-minecraft/cloud-bukkit/src/main/java/cloud/commandframework/bukkit/BukkitCommandManager.java index 8e841858..bb615383 100644 --- a/cloud-minecraft/cloud-bukkit/src/main/java/cloud/commandframework/bukkit/BukkitCommandManager.java +++ b/cloud-minecraft/cloud-bukkit/src/main/java/cloud/commandframework/bukkit/BukkitCommandManager.java @@ -85,8 +85,24 @@ public class BukkitCommandManager extends CommandManager { /** * Construct a new Bukkit command manager * - * @param owningPlugin Plugin that is constructing the manager - * @param commandExecutionCoordinator Coordinator provider + * @param owningPlugin Plugin that is constructing the manager. This will be used when registering the + * commands to the Bukkit command map. + * @param commandExecutionCoordinator Execution coordinator instance. The coordinator is in charge of executing incoming + * commands. Some considerations must be made when picking a suitable execution + * coordinator. For example, an entirely asynchronous coordinator is not suitable + * when the parsers used in your commands are not thread safe. If you have + * commands that perform blocking operations, however, it might not be a good idea to + * use a synchronous execution coordinator. In most cases you will want to pick between + * {@link CommandExecutionCoordinator#simpleCoordinator()} and + * {@link cloud.commandframework.execution.AsynchronousCommandExecutionCoordinator}. + *

+ * A word of caution: When using the asynchronous command executor in Bukkit, it is very + * likely that you will have to perform manual synchronization when executing the commands + * in many cases, as Bukkit makes no guarantees of thread safety in common classes. To + * make this easier, {@link #taskRecipe()} is provided. Furthermore, it may be unwise to + * use asynchronous command parsing, especially when dealing with things such as players + * and entities. To make this more safe, the asynchronous command execution allows you + * to state that you want synchronous command parsing. * @param commandSenderMapper Function that maps {@link CommandSender} to the command sender type * @param backwardsCommandSenderMapper Function that maps the command sender type to {@link CommandSender} * @throws Exception If the construction of the manager fails @@ -219,6 +235,12 @@ public class BukkitCommandManager extends CommandManager { this.splitAliases = value; } + /** + * Check whether or not Brigadier can be used on the server instance + * + * @throws BrigadierFailureException An exception is thrown if Brigadier isn't available. The exception + * will contain the reason for this. + */ protected final void checkBrigadierCompatibility() throws BrigadierFailureException { if (!this.queryCapability(CloudBukkitCapabilities.BRIGADIER)) { throw new BrigadierFailureException( diff --git a/cloud-minecraft/cloud-paper/src/main/java/cloud/commandframework/paper/PaperCommandManager.java b/cloud-minecraft/cloud-paper/src/main/java/cloud/commandframework/paper/PaperCommandManager.java index 5f07996b..5d5920e8 100644 --- a/cloud-minecraft/cloud-paper/src/main/java/cloud/commandframework/paper/PaperCommandManager.java +++ b/cloud-minecraft/cloud-paper/src/main/java/cloud/commandframework/paper/PaperCommandManager.java @@ -44,8 +44,32 @@ public class PaperCommandManager extends BukkitCommandManager { /** * Construct a new Paper command manager * - * @param owningPlugin Plugin that is constructing the manager - * @param commandExecutionCoordinator Coordinator provider + * @param owningPlugin Plugin that is constructing the manager. This will be used when registering the + * commands to the Bukkit command map. + * @param commandExecutionCoordinator Execution coordinator instance. The coordinator is in charge of executing incoming + * commands. Some considerations must be made when picking a suitable execution + * coordinator. For example, an entirely asynchronous coordinator is not suitable + * when the parsers used in your commands are not thread safe. If you have + * commands that perform blocking operations, however, it might not be a good idea to + * use a synchronous execution coordinator. In most cases you will want to pick between + * {@link CommandExecutionCoordinator#simpleCoordinator()} and + * {@link cloud.commandframework.execution.AsynchronousCommandExecutionCoordinator}. + *

+ * A word of caution: When using the asynchronous command executor in Bukkit, it is very + * likely that you will have to perform manual synchronization when executing the commands + * in many cases, as Bukkit makes no guarantees of thread safety in common classes. To + * make this easier, {@link #taskRecipe()} is provided. Furthermore, it may be unwise to + * use asynchronous command parsing, especially when dealing with things such as players + * and entities. To make this more safe, the asynchronous command execution allows you + * to state that you want synchronous command parsing. + *

+ * The execution coordinator will not have an impact on command suggestions. More + * specifically, using an asynchronous command executor does not mean that command + * suggestions will be provided asynchronously. Instead, use + * {@link #registerAsynchronousCompletions()} to register asynchronous completions. This + * will only work on Paper servers. Be aware that cloud does not synchronize the command + * suggestions for you, and this should only be used if your command suggestion providers + * are thread safe. * @param commandSenderMapper Function that maps {@link CommandSender} to the command sender type * @param backwardsCommandSenderMapper Function that maps the command sender type to {@link CommandSender} * @throws Exception If the construction of the manager fails @@ -89,12 +113,16 @@ public class PaperCommandManager extends BukkitCommandManager { * is up to the caller to guarantee that such is the case * * @throws IllegalStateException when the server does not support asynchronous completions. + * @see #queryCapability(CloudBukkitCapabilities) Check if the capability is present */ public void registerAsynchronousCompletions() throws IllegalStateException { if (!this.queryCapability(CloudBukkitCapabilities.ASYNCHRONOUS_COMPLETION)) { throw new IllegalStateException("Failed to register asynchronous command completion listener."); } - Bukkit.getServer().getPluginManager().registerEvents(new AsyncCommandSuggestionsListener<>(this), this.getOwningPlugin()); + Bukkit.getServer().getPluginManager().registerEvents( + new AsyncCommandSuggestionsListener<>(this), + this.getOwningPlugin() + ); } }