More efficient way defining command executors?

Discussion in 'Spigot Plugin Development' started by Emperor_Koala, May 28, 2018.

  1. I'm just wondering if there is a more efficient way of defining command executors than just
    Code (Text):
    Bukkit.getPluginCommand("CommandA").setExecutor(new ExecutorA());
    Bukkit.getPluginCommand("CommandB").setExecutor(new ExecutorB());
    Bukkit.getPluginCommand("CommandC").setExecutor(new ExecutorC());
    Is there? My original idea was
    Code (Text):
    public void setExecutors(String[] commands, CommandExecutor[] executors)
    but I realized that you would need a way to associate between the two arrays.

    Is there any more efficient way, or are we just stuck?
     
  2. MiniDigger

    Supporter

    check out acf by aikar (the guy who wrote timings) which greatly improves command handling:
    http://acf.emc.gs
    http://acfspigot.emc.gs/

    generally, your idea doesn't really improve anything. its not more readable and it will also not improve performance. you could use a map which slightly more readable than two arrays but really, its not worth it if you know that something like acf is available.
     
    • Agree Agree x 4
  3. Alright. I was just genuinely curious if there was a better way than writing the same line over and over. Thanks anyways!
     
  4. your command class
    Code (Java):
    public class Commands implements CommandExecutor {

        public Commands(){
            Bukkit.getPluginCommand("CommandA").setExecutor(this);
        }

        @Override
        public boolean onCommand(CommandSender sender, Command command, String s, String[] args) {
            return true;
        }
    }
    your onEnable
    Code (Text):
    public void onEnable(){
        new Commands();
        new CommandsB();
    }
    this does the same thing but it just shorter repetitive lines i guess?
     
  5. that's even worse
     
    • Agree Agree x 1
  6. Mind explaining?
     
  7. you are still using normally CommandExecutor just not in the onEnable
     
  8. Didn't i say its the same thing just it looks shorter?
     
  9. its not even shorter?
     
  10. That just not what you should do. I would do something like:
    Code (Text):
    public void setExecutors(String[] command, CommandExecutor[] executor){
    List<String> commands = Arrays.asList(command);
    List<String> executors = Arrays.asList(executor) ;
    for(int x = 0; i < commands.size(); x++) {
    Bukkit.getPluginCommand(commands.get(x)).setExecutor(executors.get(x));
       }
    }



     
     
  11. Even better,
    Code (Java):
        public HashMap<String, CommandExecutor> commands = null;
       
        public Nutshell() {
            commands = new HashMap<String, CommandExecutor>();
            commands.put("main", new MainCommand());
        }
       
        public void onEnable() {
             for(String s : commands.keySet()) {
              getCommand(s).setExecutor(commands.get(s));
             }
        }
     
    • Like Like x 1
    • Agree Agree x 1
  12. Probably the best way
     
    • Agree Agree x 1
  13. MiniDigger

    Supporter

    Convert that for each loop to a stream call and you get my winner rating ^^
     
    • Agree Agree x 1
  14. JanTuck

    Supporter

    U laek mah code?
    Code (Java):
        private final HashMap<String, CommandExecutor> commands = new HashMap<>();
        public void onEnable() {
            registerCommands();
        }
        private void register(String key, CommandExecutor val){
            getCommand(key).setExecutor(val);
        }
        private void registerCommands(){
            commands.put("main", new MainCommand());
            commands.forEach(this::register);
        }
    This seems stupid though
     
    • Winner Winner x 1
  15. MiniDigger

    Supporter

    Buuut ma java 8!!!!
     
  16. JanTuck

    Supporter

    Code (Java):
        private final HashMap<String, CommandExecutor> commands = new HashMap<>();
        private final String commandPackage = "net.redacted.redacted.commands";

        private void register(String key, CommandExecutor val){
            commands.put(key, val);
            getCommand(key).setExecutor(val);
        }
        private void registerCommands(){
              getDescription().getCommands().entrySet().stream().map(Map.Entry::getKey)
                    .forEach( commandName ->{
                        try {
                            CommandExecutor commandExecutor = (CommandExecutor) Class.forName(commandPackage + ".Command" + StringUtils.capitalize(commandName)).getConstructor().newInstance();
                            register(commandName, commandExecutor);
                        } catch (ClassNotFoundException | IllegalAccessException | InvocationTargetException | InstantiationException e) {
                            e.printStackTrace();
                        }

                    });
        }
    Lol, i'm bored please end my life.
     
    #16 JanTuck, May 28, 2018
    Last edited: May 28, 2018
    • Funny Funny x 1
  17. MiniDigger

    Supporter

    Hey, you should use annotations to make the lookup for easy.
    Uuh wait, then you could reimplement acf :ROFLMAO:
     
  18. JanTuck

    Supporter

  19. You'd still have to get an instance of each command executor though
     
  20. Code (Java):
    private boolean registerCommands(String... commands){
            for (String command: commands) {
                Class clas;
                try {
                    clas = Class.forName("me.minion325.plugin.commands." + command);
                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
                    return false;
                }
                try {
                    Bukkit.getPluginCommand(command.toLowerCase()).setExecutor((CommandExecutor) clas.getDeclaredConstructor(Main.class).newInstance(this));
                    System.out.println(command + "registered");
                } catch (NoSuchMethodException | InvocationTargetException | InstantiationException | IllegalAccessException e) {
                    e.printStackTrace();
                    return false;
                }
            }
            return true;

        }
    Code (Java):
    public void onEnable(){
            registerCommands("CommandA", "CommandB", "CommandC");
        }
     
    #20 minion325, May 29, 2018
    Last edited: May 29, 2018