Made suggestions async

This commit is contained in:
Nathan Adams 2017-11-08 14:50:25 +01:00
parent b48dbe7916
commit 4f7c6d4e32
13 changed files with 66 additions and 67 deletions

View file

@ -23,6 +23,12 @@ import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.function.Predicate;
import java.util.stream.Collectors;
@ -285,11 +291,8 @@ public class CommandDispatcher<S> {
return self;
}
public CommandSuggestions getCompletionSuggestions(final ParseResults<S> parse) {
public CompletableFuture<CommandSuggestions> getCompletionSuggestions(final ParseResults<S> parse) {
final CommandContextBuilder<S> context = parse.getContext();
final Set<String> suggestions = new LinkedHashSet<>();
final CommandNode<S> parent;
final int start;
@ -309,13 +312,24 @@ public class CommandDispatcher<S> {
start = 0;
}
@SuppressWarnings("unchecked") final CompletableFuture<Collection<String>>[] futures = new CompletableFuture[parent.getChildren().size()];
int i = 0;
for (final CommandNode<S> node : parent.getChildren()) {
node.listSuggestions(parse.getReader().getString().substring(start), suggestions, context);
futures[i++] = node.listSuggestions(parse.getReader().getString().substring(start));
}
final List<String> result = new ArrayList<>(suggestions);
Collections.sort(result);
return new CommandSuggestions(new StringRange(start, parse.getReader().getTotalLength()), result);
final CompletableFuture<CommandSuggestions> result = new CompletableFuture<>();
CompletableFuture.allOf(futures).thenRun(() -> {
final Set<String> suggestions = Sets.newHashSet();
for (final CompletableFuture<Collection<String>> future : futures) {
suggestions.addAll(future.join());
}
final List<String> sorted = new ArrayList<>(suggestions);
Collections.sort(sorted);
result.complete(new CommandSuggestions(new StringRange(start, parse.getReader().getTotalLength()), sorted));
});
return result;
}
public RootCommandNode<S> getRoot() {

View file

@ -4,11 +4,14 @@ import com.mojang.brigadier.StringReader;
import com.mojang.brigadier.context.CommandContextBuilder;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import java.util.Set;
import java.util.Collection;
import java.util.Collections;
import java.util.concurrent.CompletableFuture;
public interface ArgumentType<T> {
<S> T parse(StringReader reader, CommandContextBuilder<S> contextBuilder) throws CommandSyntaxException;
default <S> void listSuggestions(final String command, final Set<String> output, final CommandContextBuilder<S> contextBuilder) {
default <S> CompletableFuture<Collection<String>> listSuggestions(final String command) {
return CompletableFuture.completedFuture(Collections.emptyList());
}
}

View file

@ -5,14 +5,12 @@ import com.mojang.brigadier.RedirectModifier;
import com.mojang.brigadier.StringReader;
import com.mojang.brigadier.arguments.ArgumentType;
import com.mojang.brigadier.builder.RequiredArgumentBuilder;
import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.context.CommandContextBuilder;
import com.mojang.brigadier.context.ParsedArgument;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import java.util.Collection;
import java.util.Set;
import java.util.function.Function;
import java.util.concurrent.CompletableFuture;
import java.util.function.Predicate;
public class ArgumentCommandNode<S, T> extends CommandNode<S> {
@ -57,8 +55,8 @@ public class ArgumentCommandNode<S, T> extends CommandNode<S> {
}
@Override
public void listSuggestions(final String command, final Set<String> output, final CommandContextBuilder<S> contextBuilder) {
type.listSuggestions(command, output, contextBuilder);
public CompletableFuture<Collection<String>> listSuggestions(final String command) {
return type.listSuggestions(command);
}
@Override

View file

@ -14,6 +14,8 @@ import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Future;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
@ -97,7 +99,7 @@ public abstract class CommandNode<S> implements Comparable<CommandNode<S>> {
public abstract void parse(StringReader reader, CommandContextBuilder<S> contextBuilder) throws CommandSyntaxException;
public abstract void listSuggestions(String command, Set<String> output, CommandContextBuilder<S> contextBuilder);
public abstract CompletableFuture<Collection<String>> listSuggestions(String command);
public abstract ArgumentBuilder<S, ?> createBuilder();

View file

@ -4,15 +4,16 @@ import com.mojang.brigadier.Command;
import com.mojang.brigadier.RedirectModifier;
import com.mojang.brigadier.StringReader;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.context.CommandContextBuilder;
import com.mojang.brigadier.context.StringRange;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.mojang.brigadier.exceptions.ParameterizedCommandExceptionType;
import java.util.Collection;
import java.util.Collections;
import java.util.Set;
import java.util.function.Function;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Future;
import java.util.function.Predicate;
public class LiteralCommandNode<S> extends CommandNode<S> {
@ -50,9 +51,11 @@ public class LiteralCommandNode<S> extends CommandNode<S> {
}
@Override
public void listSuggestions(final String command, final Set<String> output, final CommandContextBuilder<S> contextBuilder) {
public CompletableFuture<Collection<String>> listSuggestions(final String command) {
if (literal.startsWith(command)) {
output.add(literal);
return CompletableFuture.completedFuture(Collections.singleton(literal));
} else {
return CompletableFuture.completedFuture(Collections.emptyList());
}
}

View file

@ -5,8 +5,9 @@ import com.mojang.brigadier.builder.ArgumentBuilder;
import com.mojang.brigadier.context.CommandContextBuilder;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import java.util.Collection;
import java.util.Collections;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
public class RootCommandNode<S> extends CommandNode<S> {
public RootCommandNode() {
@ -28,7 +29,8 @@ public class RootCommandNode<S> extends CommandNode<S> {
}
@Override
public void listSuggestions(final String command, final Set<String> output, final CommandContextBuilder<S> contextBuilder) {
public CompletableFuture<Collection<String>> listSuggestions(final String command) {
return CompletableFuture.completedFuture(Collections.emptyList());
}
@Override

View file

@ -29,7 +29,7 @@ public class CommandSuggestionsTest {
subject.register(literal("bar"));
subject.register(literal("baz"));
final CommandSuggestions result = subject.getCompletionSuggestions(subject.parse("", source));
final CommandSuggestions result = subject.getCompletionSuggestions(subject.parse("", source)).join();
assertThat(result.getRange(), equalTo(new StringRange(0, 0)));
assertThat(result.getSuggestions(), equalTo(Lists.newArrayList("bar", "baz", "foo")));
@ -41,7 +41,7 @@ public class CommandSuggestionsTest {
subject.register(literal("bar"));
subject.register(literal("baz"));
final CommandSuggestions result = subject.getCompletionSuggestions(subject.parse("b", source));
final CommandSuggestions result = subject.getCompletionSuggestions(subject.parse("b", source)).join();
assertThat(result.getRange(), equalTo(new StringRange(0, 1)));
assertThat(result.getSuggestions(), equalTo(Lists.newArrayList("bar", "baz")));
@ -56,7 +56,7 @@ public class CommandSuggestionsTest {
.then(literal("baz"))
);
final CommandSuggestions result = subject.getCompletionSuggestions(subject.parse("parent ", source));
final CommandSuggestions result = subject.getCompletionSuggestions(subject.parse("parent ", source)).join();
assertThat(result.getRange(), equalTo(new StringRange(7, 7)));
assertThat(result.getSuggestions(), equalTo(Lists.newArrayList("bar", "baz", "foo")));
@ -71,7 +71,7 @@ public class CommandSuggestionsTest {
.then(literal("baz"))
);
final CommandSuggestions result = subject.getCompletionSuggestions(subject.parse("parent b", source));
final CommandSuggestions result = subject.getCompletionSuggestions(subject.parse("parent b", source)).join();
assertThat(result.getRange(), equalTo(new StringRange(7, 8)));
assertThat(result.getSuggestions(), equalTo(Lists.newArrayList("bar", "baz")));

View file

@ -67,14 +67,6 @@ public class FloatArgumentTypeTest {
}
}
@Test
public void testSuggestions() throws Exception {
final Set<String> set = Sets.newHashSet();
@SuppressWarnings("unchecked") final CommandContextBuilder<Object> context = Mockito.mock(CommandContextBuilder.class);
type.listSuggestions("", set, context);
assertThat(set, is(empty()));
}
@Test
public void testEquals() throws Exception {
new EqualsTester()

View file

@ -13,6 +13,7 @@ import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.runners.MockitoJUnitRunner;
import java.util.Collection;
import java.util.Set;
import static com.mojang.brigadier.arguments.IntegerArgumentType.integer;
@ -69,10 +70,8 @@ public class IntegerArgumentTypeTest {
@Test
public void testSuggestions() throws Exception {
final Set<String> set = Sets.newHashSet();
@SuppressWarnings("unchecked") final CommandContextBuilder<Object> context = Mockito.mock(CommandContextBuilder.class);
type.listSuggestions("", set, context);
assertThat(set, is(empty()));
final Collection<String> result = type.listSuggestions("").join();
assertThat(result, is(empty()));
}
@Test

View file

@ -51,13 +51,6 @@ public class StringArgumentTypeTest {
assertThat(reader.canRead(), is(false));
}
@Test
public void testSuggestions() throws Exception {
final Set<String> set = Sets.newHashSet();
string().listSuggestions("", set, context);
assertThat(set, is(empty()));
}
@Test
public void testToString() throws Exception {
assertThat(string(), hasToString("string()"));

View file

@ -12,6 +12,7 @@ import org.junit.Before;
import org.junit.Test;
import org.mockito.Mockito;
import java.util.Collection;
import java.util.Set;
import static com.mojang.brigadier.arguments.IntegerArgumentType.integer;
@ -53,10 +54,8 @@ public class ArgumentCommandNodeTest extends AbstractCommandNodeTest {
@Test
public void testSuggestions() throws Exception {
final Set<String> set = Sets.newHashSet();
@SuppressWarnings("unchecked") final CommandContextBuilder<Object> context = Mockito.mock(CommandContextBuilder.class);
node.listSuggestions("", set, context);
assertThat(set, is(empty()));
final Collection<String> result = node.listSuggestions("").join();
assertThat(result, is(empty()));
}
@Test

View file

@ -13,6 +13,7 @@ import org.junit.Before;
import org.junit.Test;
import org.mockito.Mockito;
import java.util.Collection;
import java.util.Set;
import static com.mojang.brigadier.builder.LiteralArgumentBuilder.literal;
@ -80,23 +81,17 @@ public class LiteralCommandNodeTest extends AbstractCommandNodeTest {
@Test
public void testSuggestions() throws Exception {
final Set<String> set = Sets.newHashSet();
@SuppressWarnings("unchecked") final CommandContextBuilder<Object> context = Mockito.mock(CommandContextBuilder.class);
final Collection<String> empty = node.listSuggestions("").join();
assertThat(empty, equalTo(Sets.newHashSet("foo")));
node.listSuggestions("", set, context);
assertThat(set, equalTo(Sets.newHashSet("foo")));
final Collection<String> foo = node.listSuggestions("foo").join();
assertThat(foo, equalTo(Sets.newHashSet("foo")));
set.clear();
node.listSuggestions("foo", set, context);
assertThat(set, equalTo(Sets.newHashSet("foo")));
final Collection<String> food = node.listSuggestions("food").join();
assertThat(food, is(empty()));
set.clear();
node.listSuggestions("food", set, context);
assertThat(set, is(empty()));
set.clear();
node.listSuggestions("b", set, context);
assertThat(set, is(empty()));
final Collection<String> b = node.listSuggestions("b").join();
assertThat(b, is(empty()));
}
@Test

View file

@ -9,6 +9,7 @@ import org.junit.Before;
import org.junit.Test;
import org.mockito.Mockito;
import java.util.Collection;
import java.util.Set;
import static com.mojang.brigadier.builder.LiteralArgumentBuilder.literal;
@ -48,10 +49,8 @@ public class RootCommandNodeTest extends AbstractCommandNodeTest {
@Test
public void testSuggestions() throws Exception {
final Set<String> set = Sets.newHashSet();
@SuppressWarnings("unchecked") final CommandContextBuilder<Object> context = Mockito.mock(CommandContextBuilder.class);
node.listSuggestions("", set, context);
assertThat(set, is(empty()));
final Collection<String> result = node.listSuggestions("").join();
assertThat(result, is(empty()));
}
@Test(expected = IllegalStateException.class)