diff --git a/src/de/steamwar/command/AbstractTypeMapper.java b/src/de/steamwar/command/AbstractTypeMapper.java index 0363cd0..040f303 100644 --- a/src/de/steamwar/command/AbstractTypeMapper.java +++ b/src/de/steamwar/command/AbstractTypeMapper.java @@ -50,4 +50,13 @@ public interface AbstractTypeMapper extends AbstractValidator { default Collection tabCompletes(K sender, PreviousArguments previousArguments, String s) { return tabCompletes(sender, previousArguments.userArgs, s); } + + /** + * Normalize the cache key by sender and user provided argument.
+ * Note: The CommandSender can be null!
+ * Returning null and the empty string are equivalent. + */ + default String normalize(K sender, String s) { + return null; + } } diff --git a/src/de/steamwar/command/CommandPart.java b/src/de/steamwar/command/CommandPart.java index 5a056d2..926ad2a 100644 --- a/src/de/steamwar/command/CommandPart.java +++ b/src/de/steamwar/command/CommandPart.java @@ -165,7 +165,7 @@ class CommandPart { } private Collection tabCompletes(T sender, String[] args, List mappedArgs, int startIndex) { - return TabCompletionCache.tabComplete(sender, typeMapper, command, () -> { + return TabCompletionCache.tabComplete(sender, args[startIndex], (AbstractTypeMapper) typeMapper, command, () -> { try { return typeMapper.tabCompletes(sender, new PreviousArguments(Arrays.copyOf(args, startIndex), mappedArgs.toArray()), args[startIndex]); } catch (Throwable e) { diff --git a/src/de/steamwar/command/TabCompletionCache.java b/src/de/steamwar/command/TabCompletionCache.java index 6f2d0ff..4e50a18 100644 --- a/src/de/steamwar/command/TabCompletionCache.java +++ b/src/de/steamwar/command/TabCompletionCache.java @@ -51,6 +51,7 @@ public class TabCompletionCache { @AllArgsConstructor private static class Key { private Object sender; + private String arg; private AbstractTypeMapper typeMapper; } @@ -61,9 +62,11 @@ public class TabCompletionCache { private Collection tabCompletions; } - Collection tabComplete(Object sender, AbstractTypeMapper typeMapper, AbstractSWCommand command, Supplier> tabCompleteSupplier) { + Collection tabComplete(Object sender, String arg, AbstractTypeMapper typeMapper, AbstractSWCommand command, Supplier> tabCompleteSupplier) { if (!cached.contains(typeMapper)) return tabCompleteSupplier.get(); - Key key = global.contains(typeMapper) ? new Key(null, typeMapper) : new Key(sender, typeMapper); + String normalizedArg = typeMapper.normalize(sender, arg); + if (normalizedArg == null) normalizedArg = ""; + Key key = global.contains(typeMapper) ? new Key(null, normalizedArg, typeMapper) : new Key(sender, normalizedArg, typeMapper); TabCompletions tabCompletions = tabCompletionCache.computeIfAbsent(key, ignore -> { return new TabCompletions(command, System.currentTimeMillis(), tabCompleteSupplier.get()); }); diff --git a/testsrc/de/steamwar/command/CacheCommand.java b/testsrc/de/steamwar/command/CacheCommand.java index 5057ffd..7cfdb72 100644 --- a/testsrc/de/steamwar/command/CacheCommand.java +++ b/testsrc/de/steamwar/command/CacheCommand.java @@ -41,7 +41,6 @@ public class CacheCommand extends TestSWCommand { @Cached @Mapper(value = "int", local = true) public AbstractTypeMapper typeMapper() { - System.out.println("TypeMapper register"); return new TestTypeMapper() { @Override public Integer map(String sender, PreviousArguments previousArguments, String s) { diff --git a/testsrc/de/steamwar/command/CacheCommandTest.java b/testsrc/de/steamwar/command/CacheCommandTest.java index 122528f..4a6e183 100644 --- a/testsrc/de/steamwar/command/CacheCommandTest.java +++ b/testsrc/de/steamwar/command/CacheCommandTest.java @@ -36,6 +36,14 @@ public class CacheCommandTest { assertThat(tabCompletions1, is(equalTo(tabCompletions2))); } + @Test + public void testCachingWithDifferentMessages() { + CacheCommand cmd = new CacheCommand(); + List tabCompletions1 = cmd.tabComplete("test", "", new String[]{""}); + List tabCompletions2 = cmd.tabComplete("test", "", new String[]{"0"}); + assertThat(tabCompletions1, is(equalTo(tabCompletions2))); + } + @Test public void testCachingWithDifferentSenders() { CacheCommand cmd = new CacheCommand();