Added a 'source' for commands that may be passed around in the context
This commit is contained in:
parent
6a8d067cf9
commit
2114f086cb
10 changed files with 60 additions and 41 deletions
|
@ -10,7 +10,7 @@ import net.minecraft.commands.exceptions.UnknownCommandException;
|
||||||
import net.minecraft.commands.tree.CommandNode;
|
import net.minecraft.commands.tree.CommandNode;
|
||||||
import net.minecraft.commands.tree.RootCommandNode;
|
import net.minecraft.commands.tree.RootCommandNode;
|
||||||
|
|
||||||
public class CommandDispatcher {
|
public class CommandDispatcher<T> {
|
||||||
public static final String ARGUMENT_SEPARATOR = " ";
|
public static final String ARGUMENT_SEPARATOR = " ";
|
||||||
|
|
||||||
private final RootCommandNode root = new RootCommandNode();
|
private final RootCommandNode root = new RootCommandNode();
|
||||||
|
@ -19,17 +19,17 @@ public class CommandDispatcher {
|
||||||
root.addChild(command.build());
|
root.addChild(command.build());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void execute(String command) throws CommandException {
|
public void execute(String command, T source) throws CommandException {
|
||||||
CommandContext context = parseNodes(root, command, new CommandContextBuilder());
|
CommandContext<T> context = parseNodes(root, command, new CommandContextBuilder<T>(source));
|
||||||
context.getCommand().run(context);
|
context.getCommand().run(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected CommandContext parseNodes(CommandNode node, String command, CommandContextBuilder contextBuilder) throws IllegalArgumentSyntaxException, ArgumentValidationException, UnknownCommandException {
|
protected CommandContext<T> parseNodes(CommandNode node, String command, CommandContextBuilder<T> contextBuilder) throws IllegalArgumentSyntaxException, ArgumentValidationException, UnknownCommandException {
|
||||||
IllegalArgumentSyntaxException exception = null;
|
IllegalArgumentSyntaxException exception = null;
|
||||||
|
|
||||||
for (CommandNode child : node.getChildren()) {
|
for (CommandNode child : node.getChildren()) {
|
||||||
try {
|
try {
|
||||||
CommandContextBuilder context = contextBuilder.copy();
|
CommandContextBuilder<T> context = contextBuilder.copy();
|
||||||
String remaining = child.parse(command, context);
|
String remaining = child.parse(command, context);
|
||||||
if (child.getCommand() != null) {
|
if (child.getCommand() != null) {
|
||||||
context.withCommand(child.getCommand());
|
context.withCommand(child.getCommand());
|
||||||
|
|
|
@ -30,7 +30,7 @@ public class IntegerArgumentType implements CommandArgumentType<Integer> {
|
||||||
return new IntegerArgumentType(min, max);
|
return new IntegerArgumentType(min, max);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getInteger(CommandContext context, String name) {
|
public static int getInteger(CommandContext<?> context, String name) {
|
||||||
return context.getArgument(name, int.class).getResult();
|
return context.getArgument(name, int.class).getResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,11 +5,13 @@ import net.minecraft.commands.Command;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public class CommandContext {
|
public class CommandContext<T> {
|
||||||
|
private final T source;
|
||||||
private final Map<String, ParsedArgument<?>> arguments;
|
private final Map<String, ParsedArgument<?>> arguments;
|
||||||
private final Command command;
|
private final Command command;
|
||||||
|
|
||||||
public CommandContext(Map<String, ParsedArgument<?>> arguments, Command command) {
|
public CommandContext(T source, Map<String, ParsedArgument<?>> arguments, Command command) {
|
||||||
|
this.source = source;
|
||||||
this.arguments = arguments;
|
this.arguments = arguments;
|
||||||
this.command = command;
|
this.command = command;
|
||||||
}
|
}
|
||||||
|
@ -18,8 +20,12 @@ public class CommandContext {
|
||||||
return command;
|
return command;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public T getSource() {
|
||||||
|
return source;
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public <T> ParsedArgument<T> getArgument(String name, Class<T> clazz) {
|
public <V> ParsedArgument<V> getArgument(String name, Class<V> clazz) {
|
||||||
ParsedArgument<?> argument = arguments.get(name);
|
ParsedArgument<?> argument = arguments.get(name);
|
||||||
|
|
||||||
if (argument == null) {
|
if (argument == null) {
|
||||||
|
@ -27,7 +33,7 @@ public class CommandContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Primitives.wrap(clazz).isAssignableFrom(argument.getResult().getClass())) {
|
if (Primitives.wrap(clazz).isAssignableFrom(argument.getResult().getClass())) {
|
||||||
return (ParsedArgument<T>) argument;
|
return (ParsedArgument<V>) argument;
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalArgumentException("Argument '" + name + "' is defined as " + argument.getResult().getClass().getSimpleName() + ", not " + clazz);
|
throw new IllegalArgumentException("Argument '" + name + "' is defined as " + argument.getResult().getClass().getSimpleName() + ", not " + clazz);
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,14 +5,16 @@ import net.minecraft.commands.Command;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public class CommandContextBuilder {
|
public class CommandContextBuilder<T> {
|
||||||
private final Map<String, ParsedArgument<?>> arguments = Maps.newHashMap();
|
private final Map<String, ParsedArgument<?>> arguments = Maps.newHashMap();
|
||||||
|
private final T source;
|
||||||
private Command command;
|
private Command command;
|
||||||
|
|
||||||
public CommandContextBuilder() {
|
public CommandContextBuilder(T source) {
|
||||||
|
this.source = source;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CommandContextBuilder withArgument(String name, ParsedArgument<?> argument) {
|
public CommandContextBuilder<T> withArgument(String name, ParsedArgument<?> argument) {
|
||||||
this.arguments.put(name, argument);
|
this.arguments.put(name, argument);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -21,19 +23,19 @@ public class CommandContextBuilder {
|
||||||
return arguments;
|
return arguments;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CommandContextBuilder withCommand(Command command) {
|
public CommandContextBuilder<T> withCommand(Command command) {
|
||||||
this.command = command;
|
this.command = command;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CommandContextBuilder copy() {
|
public CommandContextBuilder<T> copy() {
|
||||||
CommandContextBuilder copy = new CommandContextBuilder();
|
CommandContextBuilder<T> copy = new CommandContextBuilder<T>(source);
|
||||||
copy.command = this.command;
|
copy.command = this.command;
|
||||||
copy.arguments.putAll(this.arguments);
|
copy.arguments.putAll(this.arguments);
|
||||||
return copy;
|
return copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CommandContext build() {
|
public CommandContext<T> build() {
|
||||||
return new CommandContext(arguments, command);
|
return new CommandContext<T>(source, arguments, command);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,19 +19,20 @@ import static org.mockito.Mockito.verify;
|
||||||
|
|
||||||
@RunWith(MockitoJUnitRunner.class)
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
public class CommandDispatcherTest {
|
public class CommandDispatcherTest {
|
||||||
CommandDispatcher subject;
|
CommandDispatcher<Object> subject;
|
||||||
@Mock Command command;
|
@Mock Command command;
|
||||||
|
@Mock Object source;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
subject = new CommandDispatcher();
|
subject = new CommandDispatcher<Object>();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCreateAndExecuteCommand() throws Exception {
|
public void testCreateAndExecuteCommand() throws Exception {
|
||||||
subject.register(literal("foo").executes(command));
|
subject.register(literal("foo").executes(command));
|
||||||
|
|
||||||
subject.execute("foo");
|
subject.execute("foo", source);
|
||||||
verify(command).run(any(CommandContext.class));
|
verify(command).run(any(CommandContext.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,8 +41,8 @@ public class CommandDispatcherTest {
|
||||||
subject.register(literal("base").then(literal("foo")).executes(command));
|
subject.register(literal("base").then(literal("foo")).executes(command));
|
||||||
subject.register(literal("base").then(literal("bar")).executes(command));
|
subject.register(literal("base").then(literal("bar")).executes(command));
|
||||||
|
|
||||||
subject.execute("base foo");
|
subject.execute("base foo", source);
|
||||||
subject.execute("base bar");
|
subject.execute("base bar", source);
|
||||||
verify(command, times(2)).run(any(CommandContext.class));
|
verify(command, times(2)).run(any(CommandContext.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,25 +68,25 @@ public class CommandDispatcherTest {
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
subject.execute("foo 1 one");
|
subject.execute("foo 1 one", source);
|
||||||
verify(one).run(any(CommandContext.class));
|
verify(one).run(any(CommandContext.class));
|
||||||
|
|
||||||
subject.execute("foo 2 two");
|
subject.execute("foo 2 two", source);
|
||||||
verify(two).run(any(CommandContext.class));
|
verify(two).run(any(CommandContext.class));
|
||||||
|
|
||||||
subject.execute("foo 3 three");
|
subject.execute("foo 3 three", source);
|
||||||
verify(three).run(any(CommandContext.class));
|
verify(three).run(any(CommandContext.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = UnknownCommandException.class)
|
@Test(expected = UnknownCommandException.class)
|
||||||
public void testExecuteUnknownCommand() throws Exception {
|
public void testExecuteUnknownCommand() throws Exception {
|
||||||
subject.execute("foo");
|
subject.execute("foo", source);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = UnknownCommandException.class)
|
@Test(expected = UnknownCommandException.class)
|
||||||
public void testExecuteUnknownSubcommand() throws Exception {
|
public void testExecuteUnknownSubcommand() throws Exception {
|
||||||
subject.register(literal("foo").executes(command));
|
subject.register(literal("foo").executes(command));
|
||||||
subject.execute("foo bar");
|
subject.execute("foo bar", source);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -100,7 +101,7 @@ public class CommandDispatcherTest {
|
||||||
literal("c")
|
literal("c")
|
||||||
).executes(command));
|
).executes(command));
|
||||||
|
|
||||||
subject.execute("foo b");
|
subject.execute("foo b", source);
|
||||||
verify(subCommand).run(any(CommandContext.class));
|
verify(subCommand).run(any(CommandContext.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,6 +111,6 @@ public class CommandDispatcherTest {
|
||||||
argument("bar", integer())
|
argument("bar", integer())
|
||||||
).executes(command));
|
).executes(command));
|
||||||
|
|
||||||
subject.execute("foo bar");
|
subject.execute("foo bar", source);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -63,7 +63,7 @@ public class IntegerArgumentTypeTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGetInteger() throws Exception {
|
public void testGetInteger() throws Exception {
|
||||||
CommandContext context = new CommandContextBuilder().withArgument("foo", type.parse("100")).build();
|
CommandContext context = new CommandContextBuilder<Object>(new Object()).withArgument("foo", type.parse("100")).build();
|
||||||
|
|
||||||
assertThat(IntegerArgumentType.getInteger(context, "foo"), is(100));
|
assertThat(IntegerArgumentType.getInteger(context, "foo"), is(100));
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,32 +3,42 @@ package net.minecraft.commands.context;
|
||||||
import net.minecraft.commands.arguments.IntegerArgumentType;
|
import net.minecraft.commands.arguments.IntegerArgumentType;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.runners.MockitoJUnitRunner;
|
||||||
|
|
||||||
import static org.hamcrest.Matchers.is;
|
import static org.hamcrest.Matchers.is;
|
||||||
import static org.junit.Assert.assertThat;
|
import static org.junit.Assert.assertThat;
|
||||||
|
|
||||||
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
public class CommandContextTest {
|
public class CommandContextTest {
|
||||||
CommandContext context;
|
CommandContextBuilder<Object> builder;
|
||||||
|
@Mock Object source;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
context = new CommandContextBuilder().build();
|
builder = new CommandContextBuilder<Object>(source);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = IllegalArgumentException.class)
|
@Test(expected = IllegalArgumentException.class)
|
||||||
public void testGetArgument_nonexistent() throws Exception {
|
public void testGetArgument_nonexistent() throws Exception {
|
||||||
context.getArgument("foo", Object.class);
|
builder.build().getArgument("foo", Object.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = IllegalArgumentException.class)
|
@Test(expected = IllegalArgumentException.class)
|
||||||
public void testGetArgument_wrongType() throws Exception {
|
public void testGetArgument_wrongType() throws Exception {
|
||||||
context = new CommandContextBuilder().withArgument("foo", IntegerArgumentType.integer().parse("123")).build();
|
CommandContext<Object> context = builder.withArgument("foo", IntegerArgumentType.integer().parse("123")).build();
|
||||||
context.getArgument("foo", String.class);
|
context.getArgument("foo", String.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGetArgument() throws Exception {
|
public void testGetArgument() throws Exception {
|
||||||
context = new CommandContextBuilder().withArgument("foo", IntegerArgumentType.integer().parse("123")).build();
|
CommandContext<Object> context = builder.withArgument("foo", IntegerArgumentType.integer().parse("123")).build();
|
||||||
assertThat(context.getArgument("foo", int.class).getResult(), is(123));
|
assertThat(context.getArgument("foo", int.class).getResult(), is(123));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSource() throws Exception {
|
||||||
|
assertThat(builder.build().getSource(), is(source));
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -15,7 +15,7 @@ import static org.mockito.Mockito.mock;
|
||||||
|
|
||||||
public class ArgumentCommandNodeTest extends AbstractCommandNodeTest {
|
public class ArgumentCommandNodeTest extends AbstractCommandNodeTest {
|
||||||
ArgumentCommandNode node;
|
ArgumentCommandNode node;
|
||||||
CommandContextBuilder contextBuilder;
|
CommandContextBuilder<Object> contextBuilder;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected CommandNode getCommandNode() {
|
protected CommandNode getCommandNode() {
|
||||||
|
@ -25,7 +25,7 @@ public class ArgumentCommandNodeTest extends AbstractCommandNodeTest {
|
||||||
@Before
|
@Before
|
||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
node = argument("foo", integer()).build();
|
node = argument("foo", integer()).build();
|
||||||
contextBuilder = new CommandContextBuilder();
|
contextBuilder = new CommandContextBuilder<Object>(new Object());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -14,7 +14,7 @@ import static org.mockito.Mockito.mock;
|
||||||
|
|
||||||
public class LiteralCommandNodeTest extends AbstractCommandNodeTest {
|
public class LiteralCommandNodeTest extends AbstractCommandNodeTest {
|
||||||
LiteralCommandNode node;
|
LiteralCommandNode node;
|
||||||
CommandContextBuilder contextBuilder;
|
CommandContextBuilder<Object> contextBuilder;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected CommandNode getCommandNode() {
|
protected CommandNode getCommandNode() {
|
||||||
|
@ -24,7 +24,7 @@ public class LiteralCommandNodeTest extends AbstractCommandNodeTest {
|
||||||
@Before
|
@Before
|
||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
node = literal("foo").build();
|
node = literal("foo").build();
|
||||||
contextBuilder = new CommandContextBuilder();
|
contextBuilder = new CommandContextBuilder<Object>(new Object());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -24,7 +24,7 @@ public class RootCommandNodeTest extends AbstractCommandNodeTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testParse() throws Exception {
|
public void testParse() throws Exception {
|
||||||
assertThat(node.parse("foo bar baz", new CommandContextBuilder()), is("foo bar baz"));
|
assertThat(node.parse("foo bar baz", new CommandContextBuilder<Object>(new Object())), is("foo bar baz"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = UnsupportedOperationException.class)
|
@Test(expected = UnsupportedOperationException.class)
|
||||||
|
|
Loading…
Reference in a new issue