Added WIP ArgumentLoop (no parsing yet)

This commit is contained in:
themode 2021-02-11 20:36:02 +01:00
parent f639ac83f7
commit f0105d7058
4 changed files with 162 additions and 6 deletions

View File

@ -195,7 +195,7 @@ public final class CommandManager {
*
* @see #execute(CommandSender, String)
*/
@Nullable
@NotNull
public CommandResult executeServerCommand(@NotNull String command) {
return execute(serverSender, command);
}
@ -469,10 +469,13 @@ public final class CommandManager {
final List<DeclareCommandsPacket.Node[]> nodesLayer = nodeMaker.getNodes();
storedArgumentsNodes.put(argument, nodesLayer);
for (int nodeIndex = lastArgumentNodeIndex; nodeIndex < nodesLayer.size(); nodeIndex++) {
final NodeMaker.ConfiguredNodes configuredNodes = nodeMaker.getConfiguredNodes().get(nodeIndex);
final NodeMaker.Options options = configuredNodes.getOptions();
final DeclareCommandsPacket.Node[] argumentNodes = nodesLayer.get(nodeIndex);
for (DeclareCommandsPacket.Node argumentNode : argumentNodes) {
final int childId = nodes.size();
nodeMaker.getNodeIdsMap().put(argumentNode, childId);
argChildren.add(childId);
// Append to the last node
@ -488,8 +491,13 @@ public final class CommandManager {
nodes.add(argumentNode);
}
lastNodes = argumentNodes;
argChildren = new IntArrayList();
if (options.shouldUpdateLastNode()) {
// 'previousNodes' used if the nodes options require to overwrite the parent
final DeclareCommandsPacket.Node[] previousNodes = options.getPreviousNodes();
lastNodes = previousNodes != null ? previousNodes : argumentNodes;
argChildren = new IntArrayList();
}
}
// Used to do not re-compute the previous arguments

View File

@ -1,27 +1,120 @@
package net.minestom.server.command.builder;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
import net.minestom.server.network.packet.server.play.DeclareCommandsPacket;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
public class NodeMaker {
private final List<ConfiguredNodes> configuredNodes = new ArrayList<>(2);
private final List<DeclareCommandsPacket.Node[]> nodes = new ArrayList<>(2);
private final Object2IntMap<DeclareCommandsPacket.Node> nodeIdsMap = new Object2IntOpenHashMap<>();
private Rule rule;
private int ruleCount;
public ConfiguredNodes getLatestConfiguredNodes() {
if (configuredNodes.isEmpty())
return null;
return configuredNodes.get(configuredNodes.size() - 1);
}
public DeclareCommandsPacket.Node[] getLatestNodes() {
if (nodes.isEmpty())
return null;
return nodes.get(nodes.size() - 1);
ConfiguredNodes configuredNodes = getLatestConfiguredNodes();
return configuredNodes != null ? configuredNodes.nodes : null;
}
public void addNodes(@NotNull DeclareCommandsPacket.Node[] nodes) {
Options options = null;
if (rule != null) {
options = rule.listen(nodes, ruleCount++);
}
if (options == null) {
options = new Options();
}
this.configuredNodes.add(ConfiguredNodes.of(nodes, options));
this.nodes.add(nodes);
}
public void setRule(@NotNull Rule rule) {
this.rule = rule;
}
public void resetRule() {
this.rule = null;
this.ruleCount = 0;
}
@NotNull
public List<ConfiguredNodes> getConfiguredNodes() {
return configuredNodes;
}
public List<DeclareCommandsPacket.Node[]> getNodes() {
return nodes;
}
@NotNull
public Object2IntMap<DeclareCommandsPacket.Node> getNodeIdsMap() {
return nodeIdsMap;
}
public static class ConfiguredNodes {
private DeclareCommandsPacket.Node[] nodes;
private Options options;
private static ConfiguredNodes of(DeclareCommandsPacket.Node[] nodes, Options options) {
ConfiguredNodes configuredNodes = new ConfiguredNodes();
configuredNodes.nodes = nodes;
configuredNodes.options = options;
return configuredNodes;
}
public DeclareCommandsPacket.Node[] getNodes() {
return nodes;
}
public Options getOptions() {
return options;
}
}
public interface Rule {
@Nullable
Options listen(DeclareCommandsPacket.Node[] nodes, int count);
}
public static class Options {
private boolean updateLastNode = true;
private DeclareCommandsPacket.Node[] previousNodes;
public static Options init() {
return new Options();
}
public boolean shouldUpdateLastNode() {
return updateLastNode;
}
public Options updateLastNode(boolean updateLastNode) {
this.updateLastNode = updateLastNode;
return this;
}
public DeclareCommandsPacket.Node[] getPreviousNodes() {
return previousNodes;
}
public Options setPreviousNodes(DeclareCommandsPacket.Node[] previousNodes) {
this.previousNodes = previousNodes;
return this;
}
}
}

View File

@ -0,0 +1,50 @@
package net.minestom.server.command.builder.arguments;
import net.minestom.server.command.builder.NodeMaker;
import net.minestom.server.command.builder.exception.ArgumentSyntaxException;
import net.minestom.server.network.packet.server.play.DeclareCommandsPacket;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class ArgumentLoop<T> extends Argument<List<T>> {
private final List<Argument<T>> arguments = new ArrayList<>();
@SafeVarargs
public ArgumentLoop(@NotNull String id, @NotNull Argument<T>... arguments) {
super(id, true, true);
this.arguments.addAll(Arrays.asList(arguments));
}
@NotNull
@Override
public List<T> parse(@NotNull String input) throws ArgumentSyntaxException {
// TODO
return null;
}
@Override
public void processNodes(@NotNull NodeMaker nodeMaker, boolean executable) {
DeclareCommandsPacket.Node[] latestNodes = nodeMaker.getLatestNodes();
for (DeclareCommandsPacket.Node latestNode : latestNodes) {
final int id = nodeMaker.getNodeIdsMap().getInt(latestNode);
for (Argument<T> argument : arguments) {
DeclareCommandsPacket.Node[] latestCache = nodeMaker.getLatestNodes();
argument.processNodes(nodeMaker, executable);
NodeMaker.ConfiguredNodes configuredNodes = nodeMaker.getLatestConfiguredNodes();
// For the next loop argument to start at the same place
configuredNodes.getOptions().setPreviousNodes(latestCache);
for (DeclareCommandsPacket.Node lastArgumentNode : configuredNodes.getNodes()) {
lastArgumentNode.flags |= 0x08;
lastArgumentNode.redirectedNode = id;
}
}
}
}
}

View File

@ -26,6 +26,11 @@ public class ArgumentType {
return new ArgumentGroup(id, arguments);
}
@SafeVarargs
public static <T> ArgumentLoop<T> Loop(@NotNull String id, @NotNull Argument<T>... arguments) {
return new ArgumentLoop<>(id, arguments);
}
public static ArgumentBoolean Boolean(@NotNull String id) {
return new ArgumentBoolean(id);
}