From 8da50b0b0dcdb4c442fbbe151b0959720f779510 Mon Sep 17 00:00:00 2001 From: Aikar Date: Sat, 31 Mar 2018 13:49:16 -0400 Subject: [PATCH] Current work on removing some SetMultimap - Broken atm Seems to be breaking things and mutating state undesirably for help system? Not sure whats going on yet --- .../aikar/commands/BukkitCommandManager.java | 2 +- .../co/aikar/commands/BukkitRootCommand.java | 11 ++---- .../aikar/commands/BungeeCommandManager.java | 2 +- .../co/aikar/commands/BungeeRootCommand.java | 9 ++--- core/pom.xml | 12 ++++++ .../main/java/co/aikar/commands/ACFUtil.java | 4 ++ .../java/co/aikar/commands/BaseCommand.java | 38 ++++++++++--------- .../java/co/aikar/commands/CommandHelp.java | 16 ++++---- .../java/co/aikar/commands/RootCommand.java | 16 +++----- .../co/aikar/commands/JDARootCommand.java | 9 ++--- .../co/aikar/commands/SpongeRootCommand.java | 9 ++--- 11 files changed, 67 insertions(+), 61 deletions(-) diff --git a/bukkit/src/main/java/co/aikar/commands/BukkitCommandManager.java b/bukkit/src/main/java/co/aikar/commands/BukkitCommandManager.java index ab913bff..b216f7aa 100644 --- a/bukkit/src/main/java/co/aikar/commands/BukkitCommandManager.java +++ b/bukkit/src/main/java/co/aikar/commands/BukkitCommandManager.java @@ -220,7 +220,7 @@ public class BukkitCommandManager extends CommandManager< public void unregisterCommand(BaseCommand command) { for (RootCommand rootcommand : command.registeredCommands.values()) { BukkitRootCommand bukkitCommand = (BukkitRootCommand) rootcommand; - bukkitCommand.getSubCommands().values().removeAll(command.subCommands.values()); + bukkitCommand.getSubCommands().removeAll(command.subCommands.allValues()); if (bukkitCommand.isRegistered && bukkitCommand.getSubCommands().isEmpty()) { unregisterCommand(bukkitCommand); bukkitCommand.isRegistered = false; diff --git a/bukkit/src/main/java/co/aikar/commands/BukkitRootCommand.java b/bukkit/src/main/java/co/aikar/commands/BukkitRootCommand.java index db658455..4d93e73a 100644 --- a/bukkit/src/main/java/co/aikar/commands/BukkitRootCommand.java +++ b/bukkit/src/main/java/co/aikar/commands/BukkitRootCommand.java @@ -23,10 +23,7 @@ package co.aikar.commands; -import co.aikar.commands.annotation.Description; -import co.aikar.commands.annotation.Syntax; -import com.google.common.collect.HashMultimap; -import com.google.common.collect.SetMultimap; +import co.aikar.util.MapSet; import org.bukkit.command.Command; import org.bukkit.command.CommandSender; @@ -38,7 +35,7 @@ public class BukkitRootCommand extends Command implements RootCommand { private final BukkitCommandManager manager; private final String name; private BaseCommand defCommand; - private SetMultimap subCommands = HashMultimap.create(); + private MapSet subCommands = new MapSet<>(); private List children = new ArrayList<>(); boolean isRegistered = false; @@ -65,7 +62,7 @@ public class BukkitRootCommand extends Command implements RootCommand { } public void addChild(BaseCommand command) { - if (this.defCommand == null || !command.subCommands.get(BaseCommand.DEFAULT).isEmpty()) { + if (this.defCommand == null || command.subCommands.has(BaseCommand.DEFAULT)) { this.defCommand = command; this.setPermission(command.permission); //this.setDescription(command.getDescription()); @@ -80,7 +77,7 @@ public class BukkitRootCommand extends Command implements RootCommand { } @Override - public SetMultimap getSubCommands() { + public MapSet getSubCommands() { return this.subCommands; } diff --git a/bungee/src/main/java/co/aikar/commands/BungeeCommandManager.java b/bungee/src/main/java/co/aikar/commands/BungeeCommandManager.java index c8a14347..0749b53e 100644 --- a/bungee/src/main/java/co/aikar/commands/BungeeCommandManager.java +++ b/bungee/src/main/java/co/aikar/commands/BungeeCommandManager.java @@ -134,7 +134,7 @@ public class BungeeCommandManager extends CommandManager< for (Map.Entry entry : command.registeredCommands.entrySet()) { String commandName = entry.getKey().toLowerCase(); BungeeRootCommand bungeeCommand = (BungeeRootCommand) entry.getValue(); - bungeeCommand.getSubCommands().values().removeAll(command.subCommands.values()); + bungeeCommand.getSubCommands().removeAll(command.subCommands.allValues()); if (bungeeCommand.getSubCommands().isEmpty() && bungeeCommand.isRegistered) { unregisterCommand(bungeeCommand); bungeeCommand.isRegistered = false; diff --git a/bungee/src/main/java/co/aikar/commands/BungeeRootCommand.java b/bungee/src/main/java/co/aikar/commands/BungeeRootCommand.java index b93d173b..a721971e 100644 --- a/bungee/src/main/java/co/aikar/commands/BungeeRootCommand.java +++ b/bungee/src/main/java/co/aikar/commands/BungeeRootCommand.java @@ -23,8 +23,7 @@ package co.aikar.commands; -import com.google.common.collect.HashMultimap; -import com.google.common.collect.SetMultimap; +import co.aikar.util.MapSet; import net.md_5.bungee.api.CommandSender; import net.md_5.bungee.api.plugin.Command; import net.md_5.bungee.api.plugin.TabExecutor; @@ -37,7 +36,7 @@ public class BungeeRootCommand extends Command implements RootCommand, TabExecut private final BungeeCommandManager manager; private final String name; private BaseCommand defCommand; - private SetMultimap subCommands = HashMultimap.create(); + private MapSet subCommands = new MapSet<>(); private List children = new ArrayList<>(); boolean isRegistered = false; @@ -54,7 +53,7 @@ public class BungeeRootCommand extends Command implements RootCommand, TabExecut @Override public void addChild(BaseCommand command) { - if (this.defCommand == null || !command.subCommands.get(BaseCommand.DEFAULT).isEmpty()) { + if (this.defCommand == null || command.subCommands.has(BaseCommand.DEFAULT)) { this.defCommand = command; } @@ -67,7 +66,7 @@ public class BungeeRootCommand extends Command implements RootCommand, TabExecut } @Override - public SetMultimap getSubCommands() { + public MapSet getSubCommands() { return subCommands; } diff --git a/core/pom.xml b/core/pom.xml index ab832454..b132c420 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -46,6 +46,18 @@ 1.0.0-SNAPSHOT compile + + co.aikar + MapSet + 1.0.0-SNAPSHOT + compile + + + co.aikar + MapList + 1.0.0-SNAPSHOT + compile + co.aikar locales diff --git a/core/src/main/java/co/aikar/commands/ACFUtil.java b/core/src/main/java/co/aikar/commands/ACFUtil.java index 3e6cc071..10ad0046 100644 --- a/core/src/main/java/co/aikar/commands/ACFUtil.java +++ b/core/src/main/java/co/aikar/commands/ACFUtil.java @@ -576,6 +576,10 @@ public final class ACFUtil { throw (T) t; } + public static T getFirstElement(Iterable col) { + return col.iterator().next(); + } + private static class ApplyModifierToNumber { private String num; private boolean suffixes; diff --git a/core/src/main/java/co/aikar/commands/BaseCommand.java b/core/src/main/java/co/aikar/commands/BaseCommand.java index 9b2502d3..7d260b50 100644 --- a/core/src/main/java/co/aikar/commands/BaseCommand.java +++ b/core/src/main/java/co/aikar/commands/BaseCommand.java @@ -34,13 +34,11 @@ import co.aikar.commands.annotation.PreCommand; import co.aikar.commands.annotation.Subcommand; import co.aikar.commands.annotation.UnknownHandler; import co.aikar.commands.apachecommonslang.ApacheCommonsLangUtil; -import com.google.common.collect.HashMultimap; +import co.aikar.util.MapSet; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import com.google.common.collect.Maps; -import com.google.common.collect.SetMultimap; import com.google.common.collect.Sets; import java.lang.reflect.Constructor; @@ -66,7 +64,7 @@ public abstract class BaseCommand { public static final String CATCHUNKNOWN = "__catchunknown"; public static final String DEFAULT = "__default"; - final SetMultimap subCommands = HashMultimap.create(); + final MapSet subCommands = new MapSet<>(); final Map, String> contextFlags = Maps.newHashMap(); private Method preCommandHandler; @@ -93,6 +91,10 @@ public abstract class BaseCommand { this.commandName = cmd; } + static boolean isSpecial(String key) { + return key.equals(BaseCommand.DEFAULT) || key.equals(BaseCommand.CATCHUNKNOWN); + } + /** * Gets the root command name that the user actually typed * @return Name @@ -211,7 +213,7 @@ public abstract class BaseCommand { if (isParentEmpty && (def || (!foundDefault && helpCommand != null))) { if (!foundDefault) { if (def) { - this.subCommands.get(DEFAULT).clear(); + this.subCommands.remove(DEFAULT); foundDefault = true; } registerSubcommand(method, DEFAULT); @@ -236,7 +238,7 @@ public abstract class BaseCommand { if (hasCatchUnknown || (!foundCatchUnknown && helpCommand != null)) { if (!foundCatchUnknown) { if (hasCatchUnknown) { - this.subCommands.get(CATCHUNKNOWN).clear(); + this.subCommands.remove(CATCHUNKNOWN); foundCatchUnknown = true; } registerSubcommand(method, CATCHUNKNOWN); @@ -308,7 +310,7 @@ public abstract class BaseCommand { RegisteredCommand cmd = manager.createRegisteredCommand(this, cmdName, method, prefSubCommand); for (String subcmd : cmdList) { - subCommands.put(subcmd, cmd); + subCommands.add(subcmd, cmd); } cmd.addSubcommands(cmdList); @@ -372,13 +374,13 @@ public abstract class BaseCommand { } } - if (subCommands.get(DEFAULT) != null && args.length == 0) { + if (subCommands.has(DEFAULT) && args.length == 0) { executeSubcommand(commandContext, DEFAULT, issuer, args); - } else if (subCommands.get(CATCHUNKNOWN) != null) { + } else if (subCommands.has(CATCHUNKNOWN)) { if (!executeSubcommand(commandContext, CATCHUNKNOWN, issuer, args)) { help(issuer, args); } - } else if (subCommands.get(DEFAULT) != null) { + } else if (subCommands.has(DEFAULT)) { executeSubcommand(commandContext, DEFAULT, issuer, args); } @@ -429,13 +431,13 @@ public abstract class BaseCommand { if (!cmds.isEmpty()) { RegisteredCommand cmd = null; if (cmds.size() == 1) { - cmd = Iterables.getOnlyElement(cmds); + cmd = ACFUtil.getFirstElement(cmds); } else { Optional optCmd = cmds.stream().filter(c -> { int required = c.requiredResolvers; int optional = c.optionalResolvers; return extraArgs <= required + optional && (completion || extraArgs >= required); - }).sorted((c1, c2) -> { + }).min((c1, c2) -> { int a = c1.consumeInputResolvers; int b = c2.consumeInputResolvers; @@ -443,7 +445,7 @@ public abstract class BaseCommand { return 0; } return a < b ? 1 : -1; - }).findFirst(); + }); if (optCmd.isPresent()) { cmd = optCmd.get(); } @@ -494,10 +496,10 @@ public abstract class BaseCommand { if (search != null) { cmds.addAll(completeCommand(issuer, search.cmd, Arrays.copyOfRange(args, search.argIndex, args.length), commandLabel, isAsync)); - } else if (subCommands.get(CATCHUNKNOWN).size() == 1) { - cmds.addAll(completeCommand(issuer, Iterables.getOnlyElement(subCommands.get(CATCHUNKNOWN)), args, commandLabel, isAsync)); - } else if (subCommands.get(DEFAULT).size() == 1) { - cmds.addAll(completeCommand(issuer, Iterables.getOnlyElement(subCommands.get(DEFAULT)), args, commandLabel, isAsync)); + } else if (subCommands.size(CATCHUNKNOWN) == 1) { + cmds.addAll(completeCommand(issuer, ACFUtil.getFirstElement(subCommands.get(CATCHUNKNOWN)), args, commandLabel, isAsync)); + } else if (subCommands.size(DEFAULT) == 1) { + cmds.addAll(completeCommand(issuer, ACFUtil.getFirstElement(subCommands.get(DEFAULT)), args, commandLabel, isAsync)); } return filterTabComplete(args[args.length - 1], cmds); @@ -510,7 +512,7 @@ public abstract class BaseCommand { final Set cmds = new HashSet<>(); final int cmdIndex = Math.max(0, args.length - 1); String argString = ApacheCommonsLangUtil.join(args, " ").toLowerCase(); - for (Map.Entry entry : subCommands.entries()) { + for (MapSet.Entry entry : subCommands) { final String key = entry.getKey(); if (key.startsWith(argString) && !CATCHUNKNOWN.equals(key) && !DEFAULT.equals(key)) { final RegisteredCommand value = entry.getValue(); diff --git a/core/src/main/java/co/aikar/commands/CommandHelp.java b/core/src/main/java/co/aikar/commands/CommandHelp.java index 1d91aab4..f953ee5f 100644 --- a/core/src/main/java/co/aikar/commands/CommandHelp.java +++ b/core/src/main/java/co/aikar/commands/CommandHelp.java @@ -23,7 +23,7 @@ package co.aikar.commands; -import com.google.common.collect.SetMultimap; +import co.aikar.util.MapSet; import java.util.ArrayList; import java.util.Comparator; @@ -56,18 +56,16 @@ public class CommandHelp { this.commandName = rootCommand.getCommandName(); - SetMultimap subCommands = rootCommand.getSubCommands(); + MapSet subCommands = rootCommand.getSubCommands(); Set seen = new HashSet<>(); - subCommands.entries().forEach(e -> { - String key = e.getKey(); - if (key.equals(BaseCommand.DEFAULT) || key.equals(BaseCommand.CATCHUNKNOWN)) { + subCommands.forEachEntry((key, command) -> { + if (BaseCommand.isSpecial(key)) { return; } - RegisteredCommand regCommand = e.getValue(); - if (regCommand.hasPermission(issuer) && !seen.contains(regCommand)) { - this.helpEntries.add(new HelpEntry(this, regCommand)); - seen.add(regCommand); + if (command.hasPermission(issuer) && !seen.contains(command)) { + this.helpEntries.add(new HelpEntry(this, command)); + seen.add(command); } }); } diff --git a/core/src/main/java/co/aikar/commands/RootCommand.java b/core/src/main/java/co/aikar/commands/RootCommand.java index 2266a359..c4a3dff6 100644 --- a/core/src/main/java/co/aikar/commands/RootCommand.java +++ b/core/src/main/java/co/aikar/commands/RootCommand.java @@ -23,10 +23,8 @@ package co.aikar.commands; -import co.aikar.commands.annotation.Description; -import co.aikar.commands.annotation.Syntax; import co.aikar.commands.apachecommonslang.ApacheCommonsLangUtil; -import com.google.common.collect.SetMultimap; +import co.aikar.util.MapSet; import java.util.ArrayList; import java.util.HashSet; @@ -37,15 +35,13 @@ interface RootCommand { void addChild(BaseCommand command); CommandManager getManager(); - SetMultimap getSubCommands(); + MapSet getSubCommands(); List getChildren(); String getCommandName(); - default void addChildShared(List children, SetMultimap subCommands, BaseCommand command) { - command.subCommands.entries().forEach(e -> { - String key = e.getKey(); - RegisteredCommand registeredCommand = e.getValue(); - if (key.equals(BaseCommand.DEFAULT) || key.equals(BaseCommand.CATCHUNKNOWN)) { + default void addChildShared(List children, MapSet subCommands, BaseCommand command) { + command.subCommands.forEachEntry((key, registeredCommand) -> { + if (BaseCommand.isSpecial(key)) { return; } Set registered = subCommands.get(key); @@ -57,7 +53,7 @@ interface RootCommand { return; } } - subCommands.put(key, registeredCommand); + subCommands.add(key, registeredCommand); }); children.add(command); diff --git a/jda/src/main/java/co/aikar/commands/JDARootCommand.java b/jda/src/main/java/co/aikar/commands/JDARootCommand.java index 5c48c408..a475f887 100644 --- a/jda/src/main/java/co/aikar/commands/JDARootCommand.java +++ b/jda/src/main/java/co/aikar/commands/JDARootCommand.java @@ -1,7 +1,6 @@ package co.aikar.commands; -import com.google.common.collect.HashMultimap; -import com.google.common.collect.SetMultimap; +import co.aikar.util.MapSet; import java.util.ArrayList; import java.util.List; @@ -12,7 +11,7 @@ public class JDARootCommand implements RootCommand { boolean isRegistered = false; private JDACommandManager manager; private BaseCommand defCommand; - private SetMultimap subCommands = HashMultimap.create(); + private MapSet subCommands = new MapSet<>(); private List children = new ArrayList<>(); JDARootCommand(JDACommandManager manager, String name) { @@ -23,7 +22,7 @@ public class JDARootCommand implements RootCommand { @Override public void addChild(BaseCommand command) { - if (this.defCommand == null || !command.subCommands.get(BaseCommand.DEFAULT).isEmpty()) { + if (this.defCommand == null || command.subCommands.has(BaseCommand.DEFAULT)) { this.defCommand = command; } addChildShared(this.children, this.subCommands, command); @@ -35,7 +34,7 @@ public class JDARootCommand implements RootCommand { } @Override - public SetMultimap getSubCommands() { + public MapSet getSubCommands() { return this.subCommands; } diff --git a/sponge/src/main/java/co/aikar/commands/SpongeRootCommand.java b/sponge/src/main/java/co/aikar/commands/SpongeRootCommand.java index 6764ba7b..6f4cec38 100644 --- a/sponge/src/main/java/co/aikar/commands/SpongeRootCommand.java +++ b/sponge/src/main/java/co/aikar/commands/SpongeRootCommand.java @@ -23,8 +23,7 @@ package co.aikar.commands; -import com.google.common.collect.HashMultimap; -import com.google.common.collect.SetMultimap; +import co.aikar.util.MapSet; import org.jetbrains.annotations.NotNull; import org.spongepowered.api.command.CommandCallable; import org.spongepowered.api.command.CommandException; @@ -44,7 +43,7 @@ public class SpongeRootCommand implements CommandCallable, RootCommand { private final SpongeCommandManager manager; private final String name; private BaseCommand defCommand; - private SetMultimap subCommands = HashMultimap.create(); + private MapSet subCommands = new MapSet<>(); private List children = new ArrayList<>(); boolean isRegistered = false; @@ -98,7 +97,7 @@ public class SpongeRootCommand implements CommandCallable, RootCommand { } public void addChild(BaseCommand command) { - if (this.defCommand == null || !command.subCommands.get(BaseCommand.DEFAULT).isEmpty()) { + if (this.defCommand == null || command.subCommands.has(BaseCommand.DEFAULT)) { this.defCommand = command; } addChildShared(this.children, this.subCommands, command); @@ -115,7 +114,7 @@ public class SpongeRootCommand implements CommandCallable, RootCommand { } @Override - public SetMultimap getSubCommands() { + public MapSet getSubCommands() { return subCommands; }