Add support for registering subcommands by instance.
This commit introduces a new `register()` method on the CommandHandler class to allow registering pre-instantiated subcommands. This means that subcommands are no longer restricted in terms of instantiation, so they can have their dependencies injected at creation, rather than having to resort to Singleton anti-pattern means. Also refactors the existing internal MobArena command registration to use the new method to "drink our own champagne" and to reuse the code. Fixes #675
This commit is contained in:
parent
614da20df8
commit
903752d23a
|
@ -11,6 +11,9 @@ These changes will (most likely) be included in the next version.
|
|||
|
||||
|
||||
## [Unreleased]
|
||||
### Added
|
||||
- (API) MobArena's internal command handler now supports registering pre-instantiated subcommand instances. This should make it easier for extensions to avoid the Singleton anti-pattern for command dependencies.
|
||||
|
||||
### Changed
|
||||
- The regex pattern for the player list command is now less greedy, so it will only match on `/ma players`, `/ma playerlist`, and `/ma player-list`. The previous pattern matched on anything that starts with `player`, which rendered the `/ma player-stats` command in MobArenaStats impossible to invoke.
|
||||
|
||||
|
|
|
@ -349,14 +349,34 @@ public class CommandHandler implements CommandExecutor, TabCompleter
|
|||
* @param c a Command
|
||||
*/
|
||||
public void register(Class<? extends Command> c) {
|
||||
CommandInfo info = c.getAnnotation(CommandInfo.class);
|
||||
if (info == null) return;
|
||||
|
||||
try {
|
||||
commands.put(info.pattern(), c.newInstance());
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Command command = c.newInstance();
|
||||
register(command);
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new IllegalArgumentException("Failed to instantiate Command class: " + c.getName(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a command instance.
|
||||
* <p>
|
||||
* Adds the given command to MobArena's internal command handler as a
|
||||
* subcommand, overwriting any existing subcommand mappings. This means
|
||||
* that the method is safe to call on reloads as long as a reload does
|
||||
* not change the pattern of a registered command.
|
||||
*
|
||||
* @param command the Command instance to register
|
||||
* @throws IllegalArgumentException if the CommandInfo annotation is
|
||||
* missing from the class of the Command instance
|
||||
*/
|
||||
public void register(Command command) {
|
||||
Class<?> cls = command.getClass();
|
||||
CommandInfo info = cls.getAnnotation(CommandInfo.class);
|
||||
if (info == null) {
|
||||
throw new IllegalArgumentException("Missing CommandInfo annotation on class " + cls.getName());
|
||||
}
|
||||
|
||||
commands.put(info.pattern(), command);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue