-
-
Notifications
You must be signed in to change notification settings - Fork 48
Context resolvers
Context resolvers are resolvers for command parameters that only get their value from the command's execution context, and do not need the command's input arguments.
They are mostly useful when we need a shorter way of computing certain values which are context-aware and do not need access to the input. Context resolvers may also be used to return singletons, which can be helpful in reducing the code required to access these values.
All context resolvers must inherit from ContextResolver, and need to be registered using any of the CommandHandler#registerContext...
methods.
We can register a context resolver that returns the JDA user's current guild:
registerContextResolver(Guild.class, new ContextResolver<Guild>() {
@Override public Guild resolve(@NotNull CommandActor actor, @NotNull CommandParameter parameter, @NotNull ExecutableCommand command) throws Throwable {
return actor.as(JDAActor.class).checkInGuild(command).getGuild();
}
});
Or, as a lambda:
registerContextResolver(Guild.class, (actor, parameter, command) -> actor.as(JDAActor.class).checkInGuild(command).getGuild());
Sometimes we may need to use or return the same ContextResolver for more than one type, for example, those parameters with a specific annotation, or subclasses of an interface or class. For this, we can use ContextResolverFactories.
For example, we may want to register a factory for parameters annotated with @LookingLocation
for org.bukkit.Location
as the player's looking location value, otherwise we want to return their own location:
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface LookingLocation {}
Then create our
public class LocationFactory implements ContextResolverFactory {
@Override public @Nullable ContextResolver<?> create(@NotNull CommandParameter parameter) {
if (parameter.getType() != Location.class) return null;
if (parameter.hasAnnotation(LookingLocation.class)) {
return (actor, param, command) -> {
Player player = actor.as(BukkitCommandActor.class).requirePlayer();
return player.getTargetBlock(null, 200).getLocation();
};
}
return (actor, param, command) -> actor.as(BukkitCommandActor.class).requirePlayer().getLocation();
}
}
👋 If you're having trouble, need support, or just feel like chatting, feel free to hop by our Discord server!