From 244b9c8c4b7629ef9033fb3277de651eaae8c098 Mon Sep 17 00:00:00 2001 From: Mqzn Date: Sun, 15 Sep 2024 14:53:20 +0300 Subject: [PATCH] Finished Annotations --- docs/Imperat/Command Processors.md | 3 - docs/Imperat/Dispatcher API.md | 32 ++++++++++- docs/Imperat/Processors.md | 55 +++++++++++++++++++ .../command-api/Annotations Command API.md | 23 +++++++- .../command-api/Classic Command API.md | 9 ++- 5 files changed, 112 insertions(+), 10 deletions(-) delete mode 100644 docs/Imperat/Command Processors.md create mode 100644 docs/Imperat/Processors.md diff --git a/docs/Imperat/Command Processors.md b/docs/Imperat/Command Processors.md deleted file mode 100644 index a42365a..0000000 --- a/docs/Imperat/Command Processors.md +++ /dev/null @@ -1,3 +0,0 @@ ---- -sidebar_position: 9 ---- diff --git a/docs/Imperat/Dispatcher API.md b/docs/Imperat/Dispatcher API.md index 15fbbc6..ee0f84c 100644 --- a/docs/Imperat/Dispatcher API.md +++ b/docs/Imperat/Dispatcher API.md @@ -13,6 +13,7 @@ The `Imperat` interface is made of several components that are flexible *(change - AnnotationParser - PermissionResolver - ContextFactory +- [Processors](Processors.md) - [Value Resolver](Value%20Resolver.md) - [Context Resolver](Context%20Resolver.md) - [Suggestion Resolver](Suggestion%20Resolver.md) @@ -77,7 +78,32 @@ class MyPlugin extends JavaPlugin { It holds the information that must be processed and resolved to execute the command with the proper argument values and order(including flags) ::: -### Life Cycle of the context object in command execution: + +There are 3 main types of `Context` +- **Context** (plain) +- **SuggestionContext** +- **ResolvedContext** + +### Plain Context +It's the context object created during the beginning of the command execution +it's used to hold all the necessary information regarding the command to execute. + +### SuggestionContext +It's the context object created during tab-completion of a command, it holds t he necessary information +that would assist you in creating suggestions for arguments using [SuggestionResolver](Suggestion%20Resolver) + +### ResolvedContext +It's the context object created to resolve the arguments input by the user into values to be used during `CommandExecution` +It's also used in `CommandPostProcessors` + +:::info[Advanced%20Detail] +There's a 4th type of context which is `ExecutionContext` it acts as a middle interface between the plain +context and the ResolvedContext, it's used inside of `CommandExecution` to provide you with the methods you need +for executing your command properly. + +::: + +### Life Cycle of Context: 1. The context is created during the execution process of a command, to cache the raw input by the command source/sender into `ArgumentQueue` and the command being executed. @@ -87,9 +113,9 @@ class MyPlugin extends JavaPlugin { ## Context Factory -Simply, It's a built-in interface that defines how the `Context` and the `ResolvedContext` instances are created during the command-execution lifecycle +Simply, It's a built-in interface that defines how the `Context`, `SuggestionContext` and the `ResolvedContext` instances are created during the command-execution lifecycle -Creating and injecting your own `ContextFactory` is easy , you just create a new class that implements `ContextFactory` then implement its two methods that define the creation of both `Context` and `ResolvedContext`, then you inject/register your context factory instance by calling `dispatcher#setContextFactory` +Creating and injecting your own `ContextFactory` is easy , you just create a new class that implements `ContextFactory` then implement its three methods that define the creation of `Context` , `SuggestionContext`, and `ResolvedContext`, then you inject/register your context factory instance by calling `dispatcher#setContextFactory` ***Quick example:*** ```java diff --git a/docs/Imperat/Processors.md b/docs/Imperat/Processors.md new file mode 100644 index 0000000..b4562a1 --- /dev/null +++ b/docs/Imperat/Processors.md @@ -0,0 +1,55 @@ +--- +sidebar_position: 9 +--- +# Processors + +:::caution[WARNING] +We have already talked about the life cycle of `Context` object during the command's execution +If you haven't read that yet, please try reading about the [Context-LifeCycle](Dispatcher%20API#Life%20Cycle%20of%20Context). +as the explanation below will be fully based on this. + +::: + + + +**Frequently asked question:** What are Processors in Imperat ? +**Answer:-** +They are interfaces that define processes to happen right before the command execution. +These processes can be validations such as permission checking or cooldown checks. + +Processors are classified into : +- **Global processors** +- **Command processors** + +**Global** means that they for every command in general, while `Command processors` means that the processors are processing for specific command only. + +There are 2 types of processors (whether global or not) : +- **Pre-processors** +- **Post-processors** + +## Preprocessors +The prefix in their name `Pre` means `Before` which indicates the fact that the process happens **BEFORE** context resolving. +and that's why it has just `Context` inside of it's method. + +## Postprocessors +The prefix in their name `Post` means `AFTER` which indicates the fact that the process happens **AFTER** context resolving +therefore, it has `ResolvedContext` instead of just `Context` inside of it's method. + + + +:::tip[Pro%20Tip] +You can create a validation check , and when it fails you can stop the runtime of the command execution +by throwing a exception. +for more details on exceptions, check [Throwables](Throwables.md) + +::: + +## Registering processors +All registrations are within the `Imperat` api/dispatcher object. + +### Registering Global processors +you can register processors globally by calling `imperat#registerGlobalPreProcessor` for registering pre processors and/or +`imperat#registerGlobalPostProcessor` for registering post processors. + +### Registering Command processors +We have already discussed that in [Classic Command API](command-api/Classic%20Command%20API.md) and for annotations in [Annotations Command API](command-api/Annotations%20Command%20API.md). \ No newline at end of file diff --git a/docs/Imperat/command-api/Annotations Command API.md b/docs/Imperat/command-api/Annotations Command API.md index dce1f98..574fdad 100644 --- a/docs/Imperat/command-api/Annotations Command API.md +++ b/docs/Imperat/command-api/Annotations Command API.md @@ -21,13 +21,30 @@ can be a class, a method, or even a parameter. ## Class-level annotations: -`@Command` Declares a root command, and it has 2 main components: -- `String[] values` -> an array of names for the command, the first element is treated as the unique name for this command, while the rest (if present) is treated as aliases -- `boolean ignoreAutoCompletionPermission` -> if false (by default), it will always check if the player auto-completing any of the usages of this command , has the permission for this command or not, if he doesn't have the permission, it will not auto-complete for him. +- `@Command` Declares a root command, and it has 2 main components: + - `String[] values` -> an array of names for the command, the first element is treated as the unique name for this command, while the rest (if present) is treated as aliases + - `boolean ignoreAutoCompletionPermission` -> if false (by default), it will always check if the player auto-completing any of the usages of this command , has the permission for this command or not, if he doesn't have the permission, it will not auto-complete for him. + +- `@SubCommand` Declares a subcommand-class + - same as `@Command` but with extra option `boolean attachDirectly` which decides whether this sub command will be attached directly to the parent-command or not. + +- `@Inherit` Declares that the current command class , inherits a subcommand class as it's child, +it's made for developers who would prefer their subcommands to be separated into different classes. + +:::info[Advanced%Detail] +Inner classes are also parsed by default as commands and/or subcommands +without the need for @Inherit. + +::: + ## Method-level annotations We currently have six built-in annotations that are meant to be used on methods only, which are: +- `@Command` -> declares a standalone command separately from the root command (as the root command doesn't have to be present) + +- `@PreProcessor` -> declares a pre-processor to be added to the command +- `@PostProcessor` -> declares a post-processor to be added to the command - `@Usage` -> Declares a command usage - `@SubCommand` -> Declares a subcommand usage method - `@Cooldown` -> Declares a cooldown for this usage diff --git a/docs/Imperat/command-api/Classic Command API.md b/docs/Imperat/command-api/Classic Command API.md index a4f8b89..a09fd32 100644 --- a/docs/Imperat/command-api/Classic Command API.md +++ b/docs/Imperat/command-api/Classic Command API.md @@ -103,10 +103,17 @@ command.subCommand("sub1", After the example above, a new usage internally will be created and shall look like `/example sub1 [value]`. + +### Setting processors +It's easy just follow your instinct and you will find the following example useful. +```java +command.preProcessor(new MyPreProcessor()).postProcessor(new MyPostProcessor()); +``` + #### Extras There are multiple extra options to consider when adding a subcommand to a command :- - `aliases` -- `attachDirectly` -> Whether the subcommand usage will be merged with the command's default usage (not main usage), and it's false by default, as it will cause some ambiguity +- `attachDirectly`(false by default) -> Whether the subcommand usage will be merged with the command's default usage (not main usage), so if true it will be `/example sub1 [value]` - You can also declare a usage to be executed asynchronously by using the method CommandUsage.Builder#coordinator which takes a CommandCoordinator instance. as shown below: