MacroFunction.java

net.minecraft.commands.functions.MacroFunction

信息

  • 全限定名:net.minecraft.commands.functions.MacroFunction
  • 类型:public class
  • 包:net.minecraft.commands.functions
  • 源码路径:src/main/java/net/minecraft/commands/functions/MacroFunction.java
  • 起始行号:L31
  • 实现:CommandFunction
  • 职责:

    TODO

字段/常量

  • DECIMAL_FORMAT

    • 类型: DecimalFormat
    • 修饰符: private static final
    • 源码定位: L32
    • 说明:

      TODO

  • MAX_CACHE_ENTRIES

    • 类型: int
    • 修饰符: private static final
    • 源码定位: L35
    • 说明:

      TODO

  • parameters

    • 类型: List<String>
    • 修饰符: private final
    • 源码定位: L36
    • 说明:

      TODO

  • cache

    • 类型: Object2ObjectLinkedOpenHashMap<List<String>,InstantiatedFunction<T>>
    • 修饰符: private final
    • 源码定位: L37
    • 说明:

      TODO

  • id

    • 类型: Identifier
    • 修饰符: private final
    • 源码定位: L38
    • 说明:

      TODO

  • entries

    • 类型: List<MacroFunction.Entry<T>>
    • 修饰符: private final
    • 源码定位: L39
    • 说明:

      TODO

内部类/嵌套类型

  • net.minecraft.commands.functions.MacroFunction.Entry

    • 类型: interface
    • 修饰符: package-private
    • 源码定位: L141
    • 说明:

      TODO

  • net.minecraft.commands.functions.MacroFunction.MacroEntry

    • 类型: class
    • 修饰符: static
    • 源码定位: L147
    • 说明:

      TODO

  • net.minecraft.commands.functions.MacroFunction.PlainTextEntry

    • 类型: class
    • 修饰符: static
    • 源码定位: L177
    • 说明:

      TODO

构造器

public MacroFunction(Identifier id, List<MacroFunction.Entry<T>> entries, List<String> parameters) @ L41

  • 构造器名:MacroFunction
  • 源码定位:L41
  • 修饰符:public

参数:

  • id: Identifier
  • entries: List<MacroFunction.Entry>
  • parameters: List

说明:

TODO

方法

下面的方法块按源码顺序生成。

public Identifier id() @ L47

  • 方法名:id
  • 源码定位:L47
  • 返回类型:Identifier
  • 修饰符:public

参数:

说明:

TODO

public InstantiatedFunction<T> instantiate(CompoundTag arguments, CommandDispatcher<T> dispatcher) @ L52

  • 方法名:instantiate
  • 源码定位:L52
  • 返回类型:InstantiatedFunction
  • 修饰符:public

参数:

  • arguments: CompoundTag
  • dispatcher: CommandDispatcher

说明:

TODO

private static String stringify(Tag tag) @ L85

  • 方法名:stringify
  • 源码定位:L85
  • 返回类型:String
  • 修饰符:private static

参数:

  • tag: Tag

说明:

TODO

private static void lookupValues(List<String> values, IntList indicesToSelect, List<String> selectedValuesOutput) @ L124

  • 方法名:lookupValues
  • 源码定位:L124
  • 返回类型:void
  • 修饰符:private static

参数:

  • values: List
  • indicesToSelect: IntList
  • selectedValuesOutput: List

说明:

TODO

private InstantiatedFunction<T> substituteAndParse(List<String> keys, List<String> values, CommandDispatcher<T> dispatcher) @ L129

  • 方法名:substituteAndParse
  • 源码定位:L129
  • 返回类型:InstantiatedFunction
  • 修饰符:private

参数:

  • keys: List
  • values: List
  • dispatcher: CommandDispatcher

说明:

TODO

代码

public class MacroFunction<T extends ExecutionCommandSource<T>> implements CommandFunction<T> {
    private static final DecimalFormat DECIMAL_FORMAT = Util.make(
        new DecimalFormat("#", DecimalFormatSymbols.getInstance(Locale.ROOT)), format -> format.setMaximumFractionDigits(15)
    );
    private static final int MAX_CACHE_ENTRIES = 8;
    private final List<String> parameters;
    private final Object2ObjectLinkedOpenHashMap<List<String>, InstantiatedFunction<T>> cache = new Object2ObjectLinkedOpenHashMap<>(8, 0.25F);
    private final Identifier id;
    private final List<MacroFunction.Entry<T>> entries;
 
    public MacroFunction(Identifier id, List<MacroFunction.Entry<T>> entries, List<String> parameters) {
        this.id = id;
        this.entries = entries;
        this.parameters = parameters;
    }
 
    @Override
    public Identifier id() {
        return this.id;
    }
 
    @Override
    public InstantiatedFunction<T> instantiate(@Nullable CompoundTag arguments, CommandDispatcher<T> dispatcher) throws FunctionInstantiationException {
        if (arguments == null) {
            throw new FunctionInstantiationException(Component.translatable("commands.function.error.missing_arguments", Component.translationArg(this.id())));
        } else {
            List<String> parameterValues = new ArrayList<>(this.parameters.size());
 
            for (String argument : this.parameters) {
                Tag argumentValue = arguments.get(argument);
                if (argumentValue == null) {
                    throw new FunctionInstantiationException(
                        Component.translatable("commands.function.error.missing_argument", Component.translationArg(this.id()), argument)
                    );
                }
 
                parameterValues.add(stringify(argumentValue));
            }
 
            InstantiatedFunction<T> cachedFunction = this.cache.getAndMoveToLast(parameterValues);
            if (cachedFunction != null) {
                return cachedFunction;
            } else {
                if (this.cache.size() >= 8) {
                    this.cache.removeFirst();
                }
 
                InstantiatedFunction<T> function = this.substituteAndParse(this.parameters, parameterValues, dispatcher);
                this.cache.put(parameterValues, function);
                return function;
            }
        }
    }
 
    private static String stringify(Tag tag) {
        Objects.requireNonNull(tag);
 
        return switch (tag) {
            case FloatTag(float var41) -> {
                float var25 = var41;
                {
                    yield DECIMAL_FORMAT.format(var25);
                }
            }
            case DoubleTag(double var39) -> {
                double var26 = var39;
                {
                    yield DECIMAL_FORMAT.format(var26);
                }
            }
            case ByteTag(byte var37) -> {
                byte var27 = var37;
                {
                    yield String.valueOf((int)var27);
                }
            }
            case ShortTag(short var35) -> {
                short var28 = var35;
                {
                    yield String.valueOf((int)var28);
                }
            }
            case LongTag(long var33) -> {
                long var29 = var33;
                {
                    yield String.valueOf(var29);
                }
            }
            case StringTag(String var17) -> var17;
            default -> tag.toString();
        };
    }
 
    private static void lookupValues(List<String> values, IntList indicesToSelect, List<String> selectedValuesOutput) {
        selectedValuesOutput.clear();
        indicesToSelect.forEach(index -> selectedValuesOutput.add(values.get(index)));
    }
 
    private InstantiatedFunction<T> substituteAndParse(List<String> keys, List<String> values, CommandDispatcher<T> dispatcher) throws FunctionInstantiationException {
        List<UnboundEntryAction<T>> newEntries = new ArrayList<>(this.entries.size());
        List<String> entryArguments = new ArrayList<>(values.size());
 
        for (MacroFunction.Entry<T> entry : this.entries) {
            lookupValues(values, entry.parameters(), entryArguments);
            newEntries.add(entry.instantiate(entryArguments, dispatcher, this.id));
        }
 
        return new PlainTextFunction<>(this.id().withPath(id -> id + "/" + keys.hashCode()), newEntries);
    }
 
    interface Entry<T> {
        IntList parameters();
 
        UnboundEntryAction<T> instantiate(List<String> substitutions, CommandDispatcher<T> dispatcher, Identifier funtionId) throws FunctionInstantiationException;
    }
 
    static class MacroEntry<T extends ExecutionCommandSource<T>> implements MacroFunction.Entry<T> {
        private final StringTemplate template;
        private final IntList parameters;
        private final T compilationContext;
 
        public MacroEntry(StringTemplate template, IntList parameters, T compilationContext) {
            this.template = template;
            this.parameters = parameters;
            this.compilationContext = compilationContext;
        }
 
        @Override
        public IntList parameters() {
            return this.parameters;
        }
 
        @Override
        public UnboundEntryAction<T> instantiate(List<String> substitutions, CommandDispatcher<T> dispatcher, Identifier functionId) throws FunctionInstantiationException {
            String command = this.template.substitute(substitutions);
 
            try {
                return CommandFunction.parseCommand(dispatcher, this.compilationContext, new StringReader(command));
            } catch (CommandSyntaxException var6) {
                throw new FunctionInstantiationException(
                    Component.translatable("commands.function.error.parse", Component.translationArg(functionId), command, var6.getMessage())
                );
            }
        }
    }
 
    static class PlainTextEntry<T> implements MacroFunction.Entry<T> {
        private final UnboundEntryAction<T> compiledAction;
 
        public PlainTextEntry(UnboundEntryAction<T> compiledAction) {
            this.compiledAction = compiledAction;
        }
 
        @Override
        public IntList parameters() {
            return IntLists.emptyList();
        }
 
        @Override
        public UnboundEntryAction<T> instantiate(List<String> substitutions, CommandDispatcher<T> dispatcher, Identifier functionId) {
            return this.compiledAction;
        }
    }
}

引用的其他类

  • FunctionInstantiationException

    • 引用位置: 构造调用
    • 关联成员: FunctionInstantiationException()
  • CommandFunction

    • 引用位置: 实现/方法调用
    • 关联成员: CommandFunction.parseCommand()
  • InstantiatedFunction

    • 引用位置: 字段/返回值
  • CompoundTag

    • 引用位置: 参数
  • Tag

    • 引用位置: 参数
  • Component

    • 引用位置: 方法调用
    • 关联成员: Component.translatable(), Component.translationArg()
  • Identifier

    • 引用位置: 参数/字段/返回值
  • Util

    • 引用位置: 方法调用
    • 关联成员: Util.make()