custom arg types - WIP

This commit is contained in:
gnembon committed 2020-11-03 06:30:49 -04:00
1 parent 741edf1465
commit af668bfdbc
3 files changed
+58 -19

No files matched your search

@@ -3,6 +3,7 @@ package carpet.script;
import carpet.CarpetServer;
import carpet.script.api.Auxiliary;
import carpet.script.bundled.Module;
import carpet.script.command.CommandArgument;
import carpet.script.exception.CarpetExpressionException;
import carpet.script.exception.ExpressionException;
import carpet.script.exception.InternalExpressionException;
@@ -26,8 +27,10 @@ import net.minecraft.util.math.BlockPos;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import static java.lang.Math.max;
@@ -41,8 +44,9 @@ public class CarpetScriptHost extends ScriptHost
public boolean persistenceRequired;
public Map<Value, Value> appConfig;
public Map<String, CommandArgument> appArgTypes;
private CarpetScriptHost(CarpetScriptServer server, Module code, boolean perUser, ScriptHost parent, Map<Value, Value> config)
private CarpetScriptHost(CarpetScriptServer server, Module code, boolean perUser, ScriptHost parent, Map<Value, Value> config, Map<String, CommandArgument> argTypes)
{
super(code, perUser, parent);
this.saveTimeout = 0;
@@ -58,11 +62,12 @@ public class CarpetScriptHost extends ScriptHost
persistenceRequired = ((CarpetScriptHost)parent).persistenceRequired;
}
appConfig = config;
appArgTypes = argTypes;
}
public static CarpetScriptHost create(CarpetScriptServer scriptServer, Module module, boolean perPlayer, ServerCommandSource source)
{
CarpetScriptHost host = new CarpetScriptHost(scriptServer, module, perPlayer, null, Collections.emptyMap() );
CarpetScriptHost host = new CarpetScriptHost(scriptServer, module, perPlayer, null, Collections.emptyMap(), new HashMap<>());
// parse code and convert to expression
if (module != null)
{
@@ -97,7 +102,7 @@ public class CarpetScriptHost extends ScriptHost
@Override
protected ScriptHost duplicate()
{
return new CarpetScriptHost(scriptServer, main, false, this, appConfig);
return new CarpetScriptHost(scriptServer, main, false, this, appConfig, appArgTypes);
}
@Override
@@ -132,7 +137,22 @@ public class CarpetScriptHost extends ScriptHost
Map<Value, Value> config = ((MapValue) ret).getMap();
setPerPlayer(config.getOrDefault(new StringValue("scope"), new StringValue("player")).getString().equalsIgnoreCase("player"));
persistenceRequired = config.getOrDefault(new StringValue("stay_loaded"), Value.FALSE).getBoolean();
this.appConfig = config;
// read custom arguments
Value arguments = config.get(StringValue.of("arguments"));
if (arguments != null)
{
if (!(arguments instanceof MapValue))
throw new InternalExpressionException("'arguments' element in config should be a map");
for (Map.Entry<Value, Value> typeData : ((MapValue)arguments).getMap().entrySet())
{
String argument = typeData.getKey().getString();
Value spec = typeData.getValue();
if (!(spec instanceof MapValue)) throw new InternalExpressionException("Spec for '"+argument+"' should be a map");
Map<String, Value> specData = ((MapValue) spec).getMap().entrySet().stream().collect(Collectors.toMap(e -> e.getKey().getString(), Map.Entry::getValue));
appArgTypes.put(argument, CommandArgument.buildFromConfig(argument, specData));
}
}
appConfig = config;
}
catch (NullPointerException | InvalidCallbackException ignored)
{
@@ -315,14 +315,14 @@ public class CarpetScriptServer
List<Value> args = new ArrayList<>(argNames.size());
for (String s : paramNames)
{
args.add(CommandArgument.getValue(ctx, s));
args.add(CommandArgument.getValue(ctx, s, cHost));
}
Value response = cHost.handleCommand(ctx.getSource(), function, args);
if (!response.isNull()) Messenger.m(ctx.getSource(), "gi " + response.getString());
return (int) response.readInteger();
}
private LiteralArgumentBuilder<ServerCommandSource> getFancyCommand(LiteralArgumentBuilder<ServerCommandSource> command, ScriptHost host, FunctionValue function )
private LiteralArgumentBuilder<ServerCommandSource> getFancyCommand(LiteralArgumentBuilder<ServerCommandSource> command, CarpetScriptHost host, FunctionValue function )
{
List<String> argNames = function.getArguments();
String hostName = host.getName();
@@ -336,10 +336,10 @@ public class CarpetScriptServer
{
List<String> reversedArgs = new ArrayList<>(argNames);
Collections.reverse(reversedArgs);
RequiredArgumentBuilder<ServerCommandSource, ?> argChain = CommandArgument.argumentNode(reversedArgs.get(0)).executes(c -> execute(c, hostName, function, argNames));
RequiredArgumentBuilder<ServerCommandSource, ?> argChain = CommandArgument.argumentNode(reversedArgs.get(0), host).executes(c -> execute(c, hostName, function, argNames));
for (int i = 1; i < reversedArgs.size(); i++)
{
argChain = CommandArgument.argumentNode(reversedArgs.get(i)).then(argChain);
argChain = CommandArgument.argumentNode(reversedArgs.get(i), host).then(argChain);
}
return command.then(literal(function.getString()).
requires((player) -> modules.containsKey(hostName)).
@@ -1,5 +1,6 @@
package carpet.script.command;
import carpet.script.CarpetScriptHost;
import carpet.script.exception.InternalExpressionException;
import carpet.script.value.ListValue;
import carpet.script.value.NumericValue;
@@ -42,21 +43,25 @@ public abstract class CommandArgument
public static final Map<String, CommandArgument> builtIns = baseTypes.stream().collect(Collectors.toMap(CommandArgument::getTypeSuffix, a -> a));
private static CommandArgument getTypeForArgument(String argument)
public static final CommandArgument DEFAULT = baseTypes.get(0);
private static CommandArgument getTypeForArgument(String argument, CarpetScriptHost host)
{
String[] components = argument.split("_");
String suffix = components[components.length-1].toLowerCase(Locale.ROOT);
return builtIns.getOrDefault(suffix, builtIns.get("string"));
CommandArgument arg = host.appArgTypes.get(suffix);
if (arg != null) return arg;
return builtIns.getOrDefault(suffix, DEFAULT);
}
public static RequiredArgumentBuilder<ServerCommandSource, ?> argumentNode(String param)
public static RequiredArgumentBuilder<ServerCommandSource, ?> argumentNode(String param, CarpetScriptHost host)
{
CommandArgument arg = getTypeForArgument(param);
CommandArgument arg = getTypeForArgument(param, host);
return arg.needsMatching? argument(param, arg.getArgumentType()).suggests(arg::suggest) : argument(param, arg.getArgumentType());
}
private String suffix;
private final Collection<String> examples;
private Collection<String> examples;
protected boolean needsMatching = false;
protected CommandArgument(
@@ -69,17 +74,17 @@ public abstract class CommandArgument
this.needsMatching = needsMatching;
}
public static ArgumentType<?> getArgument(String param)
public static ArgumentType<?> getArgument(String param, CarpetScriptHost host)
{
return getTypeForArgument(param).getArgumentType();
return getTypeForArgument(param, host).getArgumentType();
}
protected abstract ArgumentType<?> getArgumentType();
public static Value getValue(CommandContext<ServerCommandSource> context, String param) throws CommandSyntaxException
public static Value getValue(CommandContext<ServerCommandSource> context, String param, CarpetScriptHost host) throws CommandSyntaxException
{
return getTypeForArgument(param).getValueFromContext(context, param);
return getTypeForArgument(param, host).getValueFromContext(context, param);
}
protected abstract Value getValueFromContext(CommandContext<ServerCommandSource> context, String param) throws CommandSyntaxException;
@@ -108,9 +113,20 @@ public abstract class CommandArgument
variant.configure(config);
variant.suffix = suffix;
return variant;
};
}
protected abstract void configure(Map<String, Value> config);
protected void configure(Map<String, Value> config)
{
if (config.containsKey("suggest"))
{
Value suggestionValue = config.get("suggest");
if (!(suggestionValue instanceof ListValue)) throw new InternalExpressionException("Argument suggestions needs to be a list");
examples = ((ListValue) suggestionValue).getItems().stream()
.map(Value::getString)
.collect(Collectors.toSet());
if (!examples.isEmpty()) needsMatching = true;
}
};
public CompletableFuture<Suggestions> suggest(
CommandContext<ServerCommandSource> context,
@@ -177,6 +193,7 @@ public abstract class CommandArgument
@Override
protected void configure(Map<String, Value> config)
{
super.configure(config);
caseSensitive = config.getOrDefault("case_sensitive", Value.FALSE).getBoolean();
if (config.containsKey("options"))
{
@@ -222,6 +239,7 @@ public abstract class CommandArgument
@Override
protected void configure(Map<String, Value> config)
{
super.configure(config);
mustBeLoaded = config.getOrDefault("loaded", Value.FALSE).getBoolean();
}
@@ -264,6 +282,7 @@ public abstract class CommandArgument
@Override
protected void configure(Map<String, Value> config)
{
super.configure(config);
if (config.containsKey("min"))
{
min = NumericValue.asNumber(config.get("min"), "min").getDouble();