Open JorelAli opened 3 years ago
This is currently being worked on for the annotation update.
Is this still planned? Today I tried your api for the first time, using the annotations and I like them, would really appreciate this functionality.
Is this still planned? Today I tried your api for the first time, using the annotations and I like them, would really appreciate this functionality.
Yes, this feature is still planned! A formal specification of the new annotation system, along with the new suggestions format, is currently visible available to view here:
@Command("mycommand")
public class MyCommand {
@AStringArgument
@Suggests(ListOfNames.class)
String name;
@Executes
public void myExecutor(Player player) {
// ...
}
@Suggestion
class ListOfNames implements Supplier<ArgumentSuggestions> {
@Override
public ArgumentSuggestions get() {
return ArgumentSuggestions.strings("Player1", "Player2", "Player3");
}
}
}
We don't have a dedicated ETA for this feature, but we do have a dedicated milestone (10.0.0). Our original ETA was late August, but due to various reasons, our current outlook doesn't appear to be able to reach this deadline. I'm hoping to get some snapshot builds by August, but we could be looking towards October - December for some beta releases of this new annotation system.
Cool, than you for detailed response. But isn't creating an entire class and a separate field an overkill / too much boilerplate? Or is it possible to don't create the global argument?
For example I think something like this would be way simpler (inspired by the original spec misc/annotation-suggestions/ )
@Command("warp")
public class WarpCommand {
// List of warp names and their locations
static Map<String, Location> warps = new HashMap<>();
@Default
@Arg(name = "warp", type = StringArgument.class, suggest = this::warpNames) // Suggestion reference here
public void warp(Player player, String warpName) {
player.teleport(warps.get(warpName));
}
@Suggestion
public String[] warpNames() {
return warps.keySet().toArray(new String[0]);
}
}
Overall I not sure if this api based on the new spec isn't too complicated, but I just gave it a quick look and I would need to try it on a real case to see if it works for me or not. Also if told what to do I probably could contribute some code.
@Default @Arg(name = "warp", type = StringArgument.class, suggest = this::warpNames) // Suggestion reference here public void warp(Player player, String warpName) { player.teleport(warps.get(warpName)); }
Annotations can't use method references. Their values can only consist of primitives, Strings, Classes, Enums, Annotations or arrays of any of the preceding types.
It could be possible to use a string-based method reference, but I would rather avoid specifying method references by strings to allow users to have "referenced code" in their IDEs. For example, if you make a method warpNames()
and a suggestion like this:
@Arg(name = "warp", type = StringArgument.class, suggest = "WarpCommand.warpNames")
If you then attempt to refactor the method in an IDE, it can't refactor the string, whereas if you used a direct reference (e.g. class reference), an IDE can refactor it properly. Of course, the spec is still in its infancy and suggestions are always welcome!
Or is it possible to don't create the global argument?
@SzczurekYT Yes, it's possible to not create global arguments. Global arguments are a feature, not a replacement for normal command arguments - they're designed to be shared across multiple command execution implementations. In the spec, there's an example of this:
@Command("mycommand")
public class MyCommand {
@AStringArgument
String name; // Global argument
@Subcommand("subcommand")
class Subcommand {
@Executes
public void myMethod(Player player, @AIntegerArgument int value) { // Local argument, still supported here
// ...
}
}
}
isn't creating an entire class ... overkill / too much boilerplate?
Possibly, however it's worth noting that functional interfaces (classes that implement a @FunctionalInterface
) is effectively no different than a lambda that does the same thing (there's a few minor bytecode optimizations and semantics, but the effective result is still identical). This implementation also lets you share suggestions across multiple command arguments.
When I was writing my previous comment I was a bit quick with judging, forgot about few things and overall I was a bit rude I think. Sorry for that. I agree with what you have said in your replies, and it definitely makes sense to do that the way you do it. I would need to spend some time (that I currently don't have) reading the entire spec to form more constructive opinion. but overall I think this is going to be a great api, and I want to thank you for what you already did, it's a huge time saver when you don't have to parse the command yourself and try to predict every stupid thing someone might type.
Edit: also I think you should change the for 9.0.0 annotations
label to for 10.0.0 annotations
so it's correct
Please describe your suggestion Annotation suggestions
Please supply examples of the desired inputs and outputs See
misc/annotation-suggestions/
folder.