-
Notifications
You must be signed in to change notification settings - Fork 0
03) Adding Commands
The preferred way of adding commands is via a supplier and the BreadBotBuilder#addCommand method.
builder = new BreadBotBuilder();
...
builder.addCommand(MyCommand::new);
When a command is added using its class such as builder.addCommand(MyCommand.class)
the constructor is accessed through reflection. Thus, it is more efficient to provide direct access to the default constructor via MyCommand::new
.
Commands can be created from a Consumer<CommandEvent>
.
builder.addCommand(event -> event.reply("123"), command -> command.setKeys("test"));
public class TestCommand {
@MainCommand
public String test() {
return "123";
}
}
builder.addCommand(TestCommand.class);
Here we register a command using it's class. In order to create a command from a class, It must be public and there should be a public method that is annotated with @MainCommand
or @Command
. There also needs to be a public no-args constructor that the Client can use to instantiate the class. The class must be a concrete class and cannot be Abstract or an Interface.
Note that each time the command is called by a user, the class is instantiated each time. If you would like to only use 1 instance of the class, you can either register the command with an object-Adding-Commands#adding-commands-with-an-object). or set the persistence field of the commandbuilder to true
builder.createCommand(TestCommand.class).setPersistent(true);
// or
builder.createCommand(new TestCommand());
Commands can also be registered with a Supplier.
builder.addCommand(TestCommand::new)
The supplier will be invoked once to set the default values of builder and invoked again each time the command is called.
Commands can be registered with an Object. The difference here is that the Object is reused each time the command is called.
builder.addCommand(new TestCommand());
Each method has a bulk add option that accepts a collection of those objects.
One other way of adding commands is to provide the package in which the command classes are located in via BreadBotBuilder#addCommands(String packageName)
. This will scan all the classes in that package for a public concrete class that contains any methods annotated with @Command
or @MainCommand
.
builder.addCommands("com.github.breadmoirai.testbot.commands");
Both methods will inspect the passed object to set default values of the Command.
createCommand()
returns the CommandHandleBuilder
while addCommand()
returns the BreadBotClientBuilder
for chaining.
addCommand()
has overloaded methods which allow a Consumer
to be passed as the 2nd parameter to configure the builder.
builder.addCommand(event -> event.reply("123"), command -> command.setKeys("test"));
CommandHandleBuilder command = builder.createCommand(event -> event.reply("123"));
command.setKeys("test");
One class can contain multiple commands.
public class TestCommands {
@Command
public String test1() {
return "1";
}
@Command
public String test2() {
return "2";
}
}
When the following is invoked builder.addCommand(TestCommands.class)
2 commands will be created with keys "test1"
and "test2"
respectively. If the 'addCommand()' method is passed a Consumer to configure the builder, the Consumer will be applied to both commands.
The TestCommands.class
cannot be created with createCommand()
. It must be passed to createCommands()
which returns a List<CommandHandleBuilder>
that contains each command in the class.
Sub commands may be created like so:
command = builder.createCommand(event -> event.reply("1")).setKeys("main");
subcommand = command.createCommand(event -> event.reply("2")).setKeys("sub");
Where an input of "!main"
would produce "1"
and "!main sub"
, "2"
.
To achieve this behavior in a class, one method must be marked as @MainCommand
and other methods marked with @Command
as sub-commands.
public class MyCommand {
@MainCommand
public String main() {
return "1";
}
@Command
public String sub() {
return "2";
}
}
public class MyCommand {
@MainCommand
public String main() {
return "1";
}
@Command
public String sub() {
return "2";
}
public static class InnerCommand {
@MainCommand
public String isub() {
return "A";
}
@Command
public String isubsub() {
return "B";
}
}
}
builder.addCommand(MyCommand::new)
The class above results in the following.
Input | Output |
---|---|
!main | 1 |
!main sub | 2 |
!main isub | A |
!main isub isubsub | B |
The inner class must be public
and may be static
or non-static
. If the inner class does not require an instance of the enclosing class, static
is preferred.