Update CC: Tweaked to 1.13
Look, I originally had this split into several commits, but lots of
other cleanups got mixed in. I then backported some of the cleanups to
1.12, did other tidy ups there, and eventually the web of merges was
unreadable.
Yes, this is a horrible mess, but it's still nicer than it was. Anyway,
changes:
- Flatten everything. For instance, there are now three instances of
BlockComputer, two BlockTurtle, ItemPocketComputer. There's also no
more BlockPeripheral (thank heavens) - there's separate block classes
for each peripheral type.
- Remove pretty much all legacy code. As we're breaking world
compatibility anyway, we can remove all the code to load worlds from
1.4 days.
- The command system is largely rewriten to take advantage of 1.13's
new system. It's very fancy!
- WidgetTerminal now uses Minecraft's "GUI listener" system.
- BREAKING CHANGE: All the codes in keys.lua are different, due to the
move to LWJGL 3. Hopefully this won't have too much of an impact.
I don't want to map to the old key codes on the Java side, as there
always ends up being small but slight inconsistencies. IMO it's
better to make a clean break - people should be using keys rather
than hard coding the constants anyway.
- commands.list now allows fetching sub-commands. The ROM has already
been updated to allow fancy usage such as commands.time.set("noon").
- Turtles, modems and cables can be waterlogged.
2019-04-02 12:27:27 +00:00
|
|
|
/*
|
|
|
|
* This file is part of ComputerCraft - http://www.computercraft.info
|
2022-01-01 00:07:26 +00:00
|
|
|
* Copyright Daniel Ratcliffe, 2011-2022. Do not distribute without permission.
|
Update CC: Tweaked to 1.13
Look, I originally had this split into several commits, but lots of
other cleanups got mixed in. I then backported some of the cleanups to
1.12, did other tidy ups there, and eventually the web of merges was
unreadable.
Yes, this is a horrible mess, but it's still nicer than it was. Anyway,
changes:
- Flatten everything. For instance, there are now three instances of
BlockComputer, two BlockTurtle, ItemPocketComputer. There's also no
more BlockPeripheral (thank heavens) - there's separate block classes
for each peripheral type.
- Remove pretty much all legacy code. As we're breaking world
compatibility anyway, we can remove all the code to load worlds from
1.4 days.
- The command system is largely rewriten to take advantage of 1.13's
new system. It's very fancy!
- WidgetTerminal now uses Minecraft's "GUI listener" system.
- BREAKING CHANGE: All the codes in keys.lua are different, due to the
move to LWJGL 3. Hopefully this won't have too much of an impact.
I don't want to map to the old key codes on the Java side, as there
always ends up being small but slight inconsistencies. IMO it's
better to make a clean break - people should be using keys rather
than hard coding the constants anyway.
- commands.list now allows fetching sub-commands. The ROM has already
been updated to allow fancy usage such as commands.time.set("noon").
- Turtles, modems and cables can be waterlogged.
2019-04-02 12:27:27 +00:00
|
|
|
* Send enquiries to dratcliffe@gmail.com
|
|
|
|
*/
|
|
|
|
package dan200.computercraft.shared.command.builder;
|
|
|
|
|
|
|
|
import com.mojang.brigadier.Command;
|
|
|
|
import com.mojang.brigadier.arguments.ArgumentType;
|
|
|
|
import com.mojang.brigadier.builder.ArgumentBuilder;
|
|
|
|
import com.mojang.brigadier.builder.RequiredArgumentBuilder;
|
|
|
|
import com.mojang.brigadier.context.CommandContext;
|
|
|
|
import com.mojang.brigadier.tree.CommandNode;
|
|
|
|
import dan200.computercraft.shared.command.arguments.RepeatArgumentType;
|
2021-08-03 20:46:53 +00:00
|
|
|
import net.minecraft.commands.CommandSourceStack;
|
Update CC: Tweaked to 1.13
Look, I originally had this split into several commits, but lots of
other cleanups got mixed in. I then backported some of the cleanups to
1.12, did other tidy ups there, and eventually the web of merges was
unreadable.
Yes, this is a horrible mess, but it's still nicer than it was. Anyway,
changes:
- Flatten everything. For instance, there are now three instances of
BlockComputer, two BlockTurtle, ItemPocketComputer. There's also no
more BlockPeripheral (thank heavens) - there's separate block classes
for each peripheral type.
- Remove pretty much all legacy code. As we're breaking world
compatibility anyway, we can remove all the code to load worlds from
1.4 days.
- The command system is largely rewriten to take advantage of 1.13's
new system. It's very fancy!
- WidgetTerminal now uses Minecraft's "GUI listener" system.
- BREAKING CHANGE: All the codes in keys.lua are different, due to the
move to LWJGL 3. Hopefully this won't have too much of an impact.
I don't want to map to the old key codes on the Java side, as there
always ends up being small but slight inconsistencies. IMO it's
better to make a clean break - people should be using keys rather
than hard coding the constants anyway.
- commands.list now allows fetching sub-commands. The ROM has already
been updated to allow fancy usage such as commands.time.set("noon").
- Turtles, modems and cables can be waterlogged.
2019-04-02 12:27:27 +00:00
|
|
|
|
2022-11-09 18:58:31 +00:00
|
|
|
import javax.annotation.Nullable;
|
Update CC: Tweaked to 1.13
Look, I originally had this split into several commits, but lots of
other cleanups got mixed in. I then backported some of the cleanups to
1.12, did other tidy ups there, and eventually the web of merges was
unreadable.
Yes, this is a horrible mess, but it's still nicer than it was. Anyway,
changes:
- Flatten everything. For instance, there are now three instances of
BlockComputer, two BlockTurtle, ItemPocketComputer. There's also no
more BlockPeripheral (thank heavens) - there's separate block classes
for each peripheral type.
- Remove pretty much all legacy code. As we're breaking world
compatibility anyway, we can remove all the code to load worlds from
1.4 days.
- The command system is largely rewriten to take advantage of 1.13's
new system. It's very fancy!
- WidgetTerminal now uses Minecraft's "GUI listener" system.
- BREAKING CHANGE: All the codes in keys.lua are different, due to the
move to LWJGL 3. Hopefully this won't have too much of an impact.
I don't want to map to the old key codes on the Java side, as there
always ends up being small but slight inconsistencies. IMO it's
better to make a clean break - people should be using keys rather
than hard coding the constants anyway.
- commands.list now allows fetching sub-commands. The ROM has already
been updated to allow fancy usage such as commands.time.set("noon").
- Turtles, modems and cables can be waterlogged.
2019-04-02 12:27:27 +00:00
|
|
|
import java.util.ArrayList;
|
|
|
|
import java.util.Collections;
|
|
|
|
import java.util.List;
|
|
|
|
import java.util.function.Predicate;
|
|
|
|
import java.util.function.Supplier;
|
|
|
|
|
|
|
|
import static dan200.computercraft.shared.command.Exceptions.ARGUMENT_EXPECTED;
|
|
|
|
import static dan200.computercraft.shared.command.builder.HelpingArgumentBuilder.literal;
|
|
|
|
|
|
|
|
/**
|
2019-11-25 09:15:20 +00:00
|
|
|
* An alternative way of building command nodes, so one does not have to nest.
|
Update CC: Tweaked to 1.13
Look, I originally had this split into several commits, but lots of
other cleanups got mixed in. I then backported some of the cleanups to
1.12, did other tidy ups there, and eventually the web of merges was
unreadable.
Yes, this is a horrible mess, but it's still nicer than it was. Anyway,
changes:
- Flatten everything. For instance, there are now three instances of
BlockComputer, two BlockTurtle, ItemPocketComputer. There's also no
more BlockPeripheral (thank heavens) - there's separate block classes
for each peripheral type.
- Remove pretty much all legacy code. As we're breaking world
compatibility anyway, we can remove all the code to load worlds from
1.4 days.
- The command system is largely rewriten to take advantage of 1.13's
new system. It's very fancy!
- WidgetTerminal now uses Minecraft's "GUI listener" system.
- BREAKING CHANGE: All the codes in keys.lua are different, due to the
move to LWJGL 3. Hopefully this won't have too much of an impact.
I don't want to map to the old key codes on the Java side, as there
always ends up being small but slight inconsistencies. IMO it's
better to make a clean break - people should be using keys rather
than hard coding the constants anyway.
- commands.list now allows fetching sub-commands. The ROM has already
been updated to allow fancy usage such as commands.time.set("noon").
- Turtles, modems and cables can be waterlogged.
2019-04-02 12:27:27 +00:00
|
|
|
* {@link ArgumentBuilder#then(CommandNode)}s.
|
2019-11-25 09:15:20 +00:00
|
|
|
*
|
|
|
|
* @param <S> The command source we consume.
|
Update CC: Tweaked to 1.13
Look, I originally had this split into several commits, but lots of
other cleanups got mixed in. I then backported some of the cleanups to
1.12, did other tidy ups there, and eventually the web of merges was
unreadable.
Yes, this is a horrible mess, but it's still nicer than it was. Anyway,
changes:
- Flatten everything. For instance, there are now three instances of
BlockComputer, two BlockTurtle, ItemPocketComputer. There's also no
more BlockPeripheral (thank heavens) - there's separate block classes
for each peripheral type.
- Remove pretty much all legacy code. As we're breaking world
compatibility anyway, we can remove all the code to load worlds from
1.4 days.
- The command system is largely rewriten to take advantage of 1.13's
new system. It's very fancy!
- WidgetTerminal now uses Minecraft's "GUI listener" system.
- BREAKING CHANGE: All the codes in keys.lua are different, due to the
move to LWJGL 3. Hopefully this won't have too much of an impact.
I don't want to map to the old key codes on the Java side, as there
always ends up being small but slight inconsistencies. IMO it's
better to make a clean break - people should be using keys rather
than hard coding the constants anyway.
- commands.list now allows fetching sub-commands. The ROM has already
been updated to allow fancy usage such as commands.time.set("noon").
- Turtles, modems and cables can be waterlogged.
2019-04-02 12:27:27 +00:00
|
|
|
*/
|
|
|
|
public class CommandBuilder<S> implements CommandNodeBuilder<S, Command<S>> {
|
2021-01-15 16:35:49 +00:00
|
|
|
private final List<ArgumentBuilder<S, ?>> args = new ArrayList<>();
|
2022-11-09 18:58:31 +00:00
|
|
|
private @Nullable Predicate<S> requires;
|
Update CC: Tweaked to 1.13
Look, I originally had this split into several commits, but lots of
other cleanups got mixed in. I then backported some of the cleanups to
1.12, did other tidy ups there, and eventually the web of merges was
unreadable.
Yes, this is a horrible mess, but it's still nicer than it was. Anyway,
changes:
- Flatten everything. For instance, there are now three instances of
BlockComputer, two BlockTurtle, ItemPocketComputer. There's also no
more BlockPeripheral (thank heavens) - there's separate block classes
for each peripheral type.
- Remove pretty much all legacy code. As we're breaking world
compatibility anyway, we can remove all the code to load worlds from
1.4 days.
- The command system is largely rewriten to take advantage of 1.13's
new system. It's very fancy!
- WidgetTerminal now uses Minecraft's "GUI listener" system.
- BREAKING CHANGE: All the codes in keys.lua are different, due to the
move to LWJGL 3. Hopefully this won't have too much of an impact.
I don't want to map to the old key codes on the Java side, as there
always ends up being small but slight inconsistencies. IMO it's
better to make a clean break - people should be using keys rather
than hard coding the constants anyway.
- commands.list now allows fetching sub-commands. The ROM has already
been updated to allow fancy usage such as commands.time.set("noon").
- Turtles, modems and cables can be waterlogged.
2019-04-02 12:27:27 +00:00
|
|
|
|
2021-08-03 20:46:53 +00:00
|
|
|
public static CommandBuilder<CommandSourceStack> args() {
|
Update CC: Tweaked to 1.13
Look, I originally had this split into several commits, but lots of
other cleanups got mixed in. I then backported some of the cleanups to
1.12, did other tidy ups there, and eventually the web of merges was
unreadable.
Yes, this is a horrible mess, but it's still nicer than it was. Anyway,
changes:
- Flatten everything. For instance, there are now three instances of
BlockComputer, two BlockTurtle, ItemPocketComputer. There's also no
more BlockPeripheral (thank heavens) - there's separate block classes
for each peripheral type.
- Remove pretty much all legacy code. As we're breaking world
compatibility anyway, we can remove all the code to load worlds from
1.4 days.
- The command system is largely rewriten to take advantage of 1.13's
new system. It's very fancy!
- WidgetTerminal now uses Minecraft's "GUI listener" system.
- BREAKING CHANGE: All the codes in keys.lua are different, due to the
move to LWJGL 3. Hopefully this won't have too much of an impact.
I don't want to map to the old key codes on the Java side, as there
always ends up being small but slight inconsistencies. IMO it's
better to make a clean break - people should be using keys rather
than hard coding the constants anyway.
- commands.list now allows fetching sub-commands. The ROM has already
been updated to allow fancy usage such as commands.time.set("noon").
- Turtles, modems and cables can be waterlogged.
2019-04-02 12:27:27 +00:00
|
|
|
return new CommandBuilder<>();
|
|
|
|
}
|
|
|
|
|
2021-08-03 20:46:53 +00:00
|
|
|
public static CommandBuilder<CommandSourceStack> command(String literal) {
|
|
|
|
var builder = new CommandBuilder<CommandSourceStack>();
|
Update CC: Tweaked to 1.13
Look, I originally had this split into several commits, but lots of
other cleanups got mixed in. I then backported some of the cleanups to
1.12, did other tidy ups there, and eventually the web of merges was
unreadable.
Yes, this is a horrible mess, but it's still nicer than it was. Anyway,
changes:
- Flatten everything. For instance, there are now three instances of
BlockComputer, two BlockTurtle, ItemPocketComputer. There's also no
more BlockPeripheral (thank heavens) - there's separate block classes
for each peripheral type.
- Remove pretty much all legacy code. As we're breaking world
compatibility anyway, we can remove all the code to load worlds from
1.4 days.
- The command system is largely rewriten to take advantage of 1.13's
new system. It's very fancy!
- WidgetTerminal now uses Minecraft's "GUI listener" system.
- BREAKING CHANGE: All the codes in keys.lua are different, due to the
move to LWJGL 3. Hopefully this won't have too much of an impact.
I don't want to map to the old key codes on the Java side, as there
always ends up being small but slight inconsistencies. IMO it's
better to make a clean break - people should be using keys rather
than hard coding the constants anyway.
- commands.list now allows fetching sub-commands. The ROM has already
been updated to allow fancy usage such as commands.time.set("noon").
- Turtles, modems and cables can be waterlogged.
2019-04-02 12:27:27 +00:00
|
|
|
builder.args.add(literal(literal));
|
|
|
|
return builder;
|
|
|
|
}
|
|
|
|
|
|
|
|
public CommandBuilder<S> requires(Predicate<S> predicate) {
|
|
|
|
requires = requires == null ? predicate : requires.and(predicate);
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
public CommandBuilder<S> arg(String name, ArgumentType<?> type) {
|
|
|
|
args.add(RequiredArgumentBuilder.argument(name, type));
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
public <T> CommandNodeBuilder<S, ArgCommand<S, List<T>>> argManyValue(String name, ArgumentType<T> type, List<T> empty) {
|
|
|
|
return argMany(name, type, () -> empty);
|
|
|
|
}
|
|
|
|
|
|
|
|
public <T> CommandNodeBuilder<S, ArgCommand<S, List<T>>> argManyValue(String name, ArgumentType<T> type, T defaultValue) {
|
|
|
|
return argManyValue(name, type, Collections.singletonList(defaultValue));
|
|
|
|
}
|
|
|
|
|
|
|
|
public <T> CommandNodeBuilder<S, ArgCommand<S, List<T>>> argMany(String name, ArgumentType<T> type, Supplier<List<T>> empty) {
|
|
|
|
return argMany(name, RepeatArgumentType.some(type, ARGUMENT_EXPECTED), empty);
|
|
|
|
}
|
|
|
|
|
|
|
|
public <T> CommandNodeBuilder<S, ArgCommand<S, List<T>>> argManyFlatten(String name, ArgumentType<List<T>> type, Supplier<List<T>> empty) {
|
|
|
|
return argMany(name, RepeatArgumentType.someFlat(type, ARGUMENT_EXPECTED), empty);
|
|
|
|
}
|
|
|
|
|
2023-03-14 18:41:31 +00:00
|
|
|
private <T> CommandNodeBuilder<S, ArgCommand<S, List<T>>> argMany(String name, RepeatArgumentType<T, ?> type, Supplier<List<T>> empty) {
|
Update CC: Tweaked to 1.13
Look, I originally had this split into several commits, but lots of
other cleanups got mixed in. I then backported some of the cleanups to
1.12, did other tidy ups there, and eventually the web of merges was
unreadable.
Yes, this is a horrible mess, but it's still nicer than it was. Anyway,
changes:
- Flatten everything. For instance, there are now three instances of
BlockComputer, two BlockTurtle, ItemPocketComputer. There's also no
more BlockPeripheral (thank heavens) - there's separate block classes
for each peripheral type.
- Remove pretty much all legacy code. As we're breaking world
compatibility anyway, we can remove all the code to load worlds from
1.4 days.
- The command system is largely rewriten to take advantage of 1.13's
new system. It's very fancy!
- WidgetTerminal now uses Minecraft's "GUI listener" system.
- BREAKING CHANGE: All the codes in keys.lua are different, due to the
move to LWJGL 3. Hopefully this won't have too much of an impact.
I don't want to map to the old key codes on the Java side, as there
always ends up being small but slight inconsistencies. IMO it's
better to make a clean break - people should be using keys rather
than hard coding the constants anyway.
- commands.list now allows fetching sub-commands. The ROM has already
been updated to allow fancy usage such as commands.time.set("noon").
- Turtles, modems and cables can be waterlogged.
2019-04-02 12:27:27 +00:00
|
|
|
if (args.isEmpty()) throw new IllegalStateException("Cannot have empty arg chain builder");
|
|
|
|
|
|
|
|
return command -> {
|
|
|
|
// The node for no arguments
|
|
|
|
var tail = tail(ctx -> command.run(ctx, empty.get()));
|
|
|
|
|
|
|
|
// The node for one or more arguments
|
|
|
|
ArgumentBuilder<S, ?> moreArg = RequiredArgumentBuilder
|
|
|
|
.<S, List<T>>argument(name, type)
|
|
|
|
.executes(ctx -> command.run(ctx, getList(ctx, name)));
|
|
|
|
|
|
|
|
// Chain all of them together!
|
|
|
|
tail.then(moreArg);
|
|
|
|
return link(tail);
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
@SuppressWarnings("unchecked")
|
|
|
|
private static <T> List<T> getList(CommandContext<?> context, String name) {
|
|
|
|
return (List<T>) context.getArgument(name, List.class);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public CommandNode<S> executes(Command<S> command) {
|
|
|
|
if (args.isEmpty()) throw new IllegalStateException("Cannot have empty arg chain builder");
|
|
|
|
|
|
|
|
return link(tail(command));
|
|
|
|
}
|
|
|
|
|
|
|
|
private ArgumentBuilder<S, ?> tail(Command<S> command) {
|
|
|
|
var defaultTail = args.get(args.size() - 1);
|
|
|
|
defaultTail.executes(command);
|
|
|
|
if (requires != null) defaultTail.requires(requires);
|
|
|
|
return defaultTail;
|
|
|
|
}
|
|
|
|
|
|
|
|
private CommandNode<S> link(ArgumentBuilder<S, ?> tail) {
|
|
|
|
for (var i = args.size() - 2; i >= 0; i--) tail = args.get(i).then(tail);
|
|
|
|
return tail.build();
|
|
|
|
}
|
|
|
|
}
|