Nuke some generics

This commit is contained in:
skippyall
2025-10-11 00:41:47 +02:00
parent da4351cff2
commit cc1320d5c6
21 changed files with 182 additions and 306 deletions
@@ -2,9 +2,8 @@ package io.github.skippyall.minions;
import com.mojang.serialization.Lifecycle; import com.mojang.serialization.Lifecycle;
import io.github.skippyall.minions.minion.MinionRuntime; import io.github.skippyall.minions.minion.MinionRuntime;
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
import io.github.skippyall.minions.minion.skin.SkinProvider; import io.github.skippyall.minions.minion.skin.SkinProvider;
import io.github.skippyall.minions.program.argument.GenericArgumentType; import io.github.skippyall.minions.program.argument.ArgumentType;
import io.github.skippyall.minions.program.instruction.InstructionType; import io.github.skippyall.minions.program.instruction.InstructionType;
import io.github.skippyall.minions.program.value.ValueType; import io.github.skippyall.minions.program.value.ValueType;
import net.minecraft.registry.Registry; import net.minecraft.registry.Registry;
@@ -14,8 +13,8 @@ import net.minecraft.util.Identifier;
public class MinionRegistries { public class MinionRegistries {
public static final Registry<ValueType<?>> VALUE_TYPES = registry("value_type"); public static final Registry<ValueType<?>> VALUE_TYPES = registry("value_type");
public static final Registry<GenericArgumentType<MinionRuntime>> GENERIC_ARGUMENT_TYPE_REGISTRY = registry("generic_argument_type"); public static final Registry<ArgumentType<MinionRuntime>> ARGUMENT_TYPE_REGISTRY = registry("argument_type");
public static final Registry<InstructionType<?>> INSTRUCTION_TYPES = registry("instruction_type"); public static final Registry<InstructionType<MinionRuntime>> INSTRUCTION_TYPES = registry("instruction_type");
public static final Registry<SkinProvider> SKIN_PROVIDERS = registry("skin_providers"); public static final Registry<SkinProvider> SKIN_PROVIDERS = registry("skin_providers");
private static <T> Registry<T> registry(String id) { private static <T> Registry<T> registry(String id) {
@@ -4,11 +4,13 @@ import eu.pb4.sgui.api.elements.GuiElementBuilder;
import eu.pb4.sgui.api.gui.SimpleGui; import eu.pb4.sgui.api.gui.SimpleGui;
import io.github.skippyall.minions.MinionRegistries; import io.github.skippyall.minions.MinionRegistries;
import io.github.skippyall.minions.input.TextInput; import io.github.skippyall.minions.input.TextInput;
import io.github.skippyall.minions.minion.MinionRuntime;
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer; import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
import io.github.skippyall.minions.module.MinionModule; import io.github.skippyall.minions.module.MinionModule;
import io.github.skippyall.minions.program.argument.Argument; import io.github.skippyall.minions.program.argument.Argument;
import io.github.skippyall.minions.program.argument.GenericArgumentType; import io.github.skippyall.minions.program.argument.GenericArgumentType;
import io.github.skippyall.minions.program.argument.SpecificArgumentType; import io.github.skippyall.minions.program.argument.SpecificArgumentType;
import io.github.skippyall.minions.program.dingenskirchen.SpecificDingenskirchenType;
import io.github.skippyall.minions.program.instruction.ConfiguredInstruction; import io.github.skippyall.minions.program.instruction.ConfiguredInstruction;
import io.github.skippyall.minions.program.instruction.InstructionType; import io.github.skippyall.minions.program.instruction.InstructionType;
import io.github.skippyall.minions.program.argument.Parameter; import io.github.skippyall.minions.program.argument.Parameter;
@@ -112,7 +114,7 @@ public class InstructionGui {
} }
} }
public static <T, A extends Argument<T, ? extends SpecificArgumentType<T, A, MinionFakePlayer>, MinionFakePlayer>> void configureArgumentMenu(String name, ConfiguredInstruction<?> instruction, Parameter<T> parameter, MinionFakePlayer minion, ServerPlayerEntity player) { public static <T, A extends Argument<T, ? extends SpecificDingenskirchenType<T, A, MinionRuntime>, MinionRuntime>> void configureArgumentMenu(String name, ConfiguredInstruction<?> instruction, Parameter<T> parameter, MinionFakePlayer minion, ServerPlayerEntity player) {
if(!checkInstructionExists(name, instruction, minion, player)) { if(!checkInstructionExists(name, instruction, minion, player)) {
return; return;
} }
@@ -3,27 +3,28 @@ package io.github.skippyall.minions.program;
import com.mojang.serialization.Codec; import com.mojang.serialization.Codec;
import io.github.skippyall.minions.program.argument.Argument; import io.github.skippyall.minions.program.argument.Argument;
import io.github.skippyall.minions.program.argument.ArgumentList; import io.github.skippyall.minions.program.argument.ArgumentList;
import io.github.skippyall.minions.program.argument.ArgumentType;
import io.github.skippyall.minions.program.argument.Arguments; import io.github.skippyall.minions.program.argument.Arguments;
import io.github.skippyall.minions.program.argument.GenericArgumentType; import io.github.skippyall.minions.program.instruction.InstructionType;
import io.github.skippyall.minions.program.argument.SpecificArgumentType; import io.github.skippyall.minions.program.returnvalue.ValueConsumerType;
import net.minecraft.registry.Registry; import net.minecraft.registry.Registry;
public interface InstructionRuntime<R extends InstructionRuntime<R>> { public interface InstructionRuntime<R extends InstructionRuntime<R>> {
Registry<GenericArgumentType<R>> getGenericArgumentTypeRegistry(); Registry<ArgumentType<R>> getArgumentTypeRegistry();
default Codec<GenericArgumentType<R>> getGenericArgumentTypeCodec() { Registry<InstructionType<R>> getInstructionTypeRegistry();
return getGenericArgumentTypeRegistry().getCodec();
Registry<ValueConsumerType<R>> getValueConsumerRegistry();
default Codec<ArgumentType<R>> getArgumentTypeCodec() {
return getArgumentTypeRegistry().getCodec();
} }
default Codec<SpecificArgumentType<?,?,R>> getSpecificArgumentTypeCodec() { default Codec<Argument<?,R>> getArgumentCodec() {
return Arguments.createSpecificTypeCodec(getGenericArgumentTypeCodec()); return Arguments.createArgumentCodec(getArgumentTypeCodec());
}
default Codec<Argument<?,?,R>> getArgumentCodec() {
return Arguments.createArgumentCodec(getGenericArgumentTypeCodec());
} }
default Codec<ArgumentList<R>> getArgumentListCodec() { default Codec<ArgumentList<R>> getArgumentListCodec() {
return ArgumentList.getCodec(getGenericArgumentTypeCodec()); return ArgumentList.getCodec(getArgumentTypeCodec());
} }
} }
@@ -10,20 +10,17 @@ import org.jetbrains.annotations.Nullable;
* Its value is resolved at runtime and can vary between executions. * Its value is resolved at runtime and can vary between executions.
* <code>Argument</code>s are created exclusively by <code>SpecificArgumentType</code>s. * <code>Argument</code>s are created exclusively by <code>SpecificArgumentType</code>s.
* @param <T> The type of the <code>Argument</code>'s value * @param <T> The type of the <code>Argument</code>'s value
* @param <S> The <code>SpecificArgumentType</code>
*/ */
public interface Argument<T, S extends SpecificArgumentType<T, ? extends Argument<T, S, R>, R>, R extends InstructionRuntime<R>> { public interface Argument<T, R extends InstructionRuntime<R>> {
T resolve(R minion); T resolve(R minion);
default ValueType<T> getValueType() {
return getType().getValueType();
}
GuiDisplay getDisplay(); GuiDisplay getDisplay();
S getType(); ValueType<T> getValueType();
default <U, A extends Argument<U, ? extends SpecificArgumentType<U,A,R>, R>> @Nullable A cast(ValueType<U> type) { ArgumentType<R> getType();
default <U,A extends Argument<U,R>> @Nullable A cast(ValueType<U> type) {
if(getValueType() == type) { if(getValueType() == type) {
//noinspection unchecked //noinspection unchecked
return (A) this; return (A) this;
@@ -1,8 +1,6 @@
package io.github.skippyall.minions.program.argument; package io.github.skippyall.minions.program.argument;
import com.mojang.serialization.Codec; import com.mojang.serialization.Codec;
import io.github.skippyall.minions.Minions;
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
import io.github.skippyall.minions.program.InstructionRuntime; import io.github.skippyall.minions.program.InstructionRuntime;
import java.util.Collection; import java.util.Collection;
@@ -10,27 +8,27 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
public class ArgumentList<R extends InstructionRuntime<R>> { public class ArgumentList<R extends InstructionRuntime<R>> {
private final Map<String, Argument<?, ?, R>> arguments; private final Map<String, Argument<?, R>> arguments;
public ArgumentList() { public ArgumentList() {
arguments = new HashMap<>(); arguments = new HashMap<>();
} }
public ArgumentList(Map<String, Argument<?,?, R>> arguments) { public ArgumentList(Map<String, Argument<?,R>> arguments) {
this.arguments = new HashMap<>(arguments); this.arguments = new HashMap<>(arguments);
} }
public <T> T getValue(Parameter<T> parameter, R runtime) { public <T> T getValue(Parameter<T> parameter, R runtime) {
Argument<T,?,R> argument = getArgument(parameter); Argument<T,R> argument = getArgument(parameter);
return argument != null ? argument.resolve(runtime) : null; return argument != null ? argument.resolve(runtime) : null;
} }
public <T, A extends Argument<T, ? extends SpecificArgumentType<T,A,R>,R>> A getArgument(Parameter<T> parameter) { public <T, A extends Argument<T,R>> A getArgument(Parameter<T> parameter) {
Argument<?, ?,R> argument = arguments.get(parameter.name()); Argument<?,R> argument = arguments.get(parameter.name());
return argument == null ? null : argument.cast(parameter.type()); return argument == null ? null : argument.cast(parameter.type());
} }
public <T> void setArgument(Parameter<T> parameter, Argument<T,?,R> argument) { public <T> void setArgument(Parameter<T> parameter, Argument<T,R> argument) {
arguments.put(parameter.name(), argument); arguments.put(parameter.name(), argument);
} }
@@ -47,7 +45,7 @@ public class ArgumentList<R extends InstructionRuntime<R>> {
return true; return true;
} }
public static <R extends InstructionRuntime<R>> Codec<ArgumentList<R>> getCodec(Codec<GenericArgumentType<R>> genericCodec) { public static <R extends InstructionRuntime<R>> Codec<ArgumentList<R>> getCodec(Codec<ArgumentType<R>> genericCodec) {
return Codec.unboundedMap(Codec.STRING, Arguments.createArgumentCodec(genericCodec)) return Codec.unboundedMap(Codec.STRING, Arguments.createArgumentCodec(genericCodec))
.xmap(ArgumentList::new, list -> list.arguments); .xmap(ArgumentList::new, list -> list.arguments);
} }
@@ -0,0 +1,15 @@
package io.github.skippyall.minions.program.argument;
import com.mojang.serialization.Codec;
import io.github.skippyall.minions.program.InstructionRuntime;
import io.github.skippyall.minions.program.value.ValueType;
import net.minecraft.server.network.ServerPlayerEntity;
import org.jetbrains.annotations.Nullable;
import java.util.concurrent.CompletableFuture;
public abstract class ArgumentType<R extends InstructionRuntime<R>> {
public abstract <T> Codec<? extends Argument<T,R>> getCodec(ValueType<T> type);
public abstract <T> CompletableFuture<? extends Argument<T,R>> openConfiguration(ServerPlayerEntity player, ValueType<T> valueType, @Nullable Argument<T,R> previous);
}
@@ -2,49 +2,18 @@ package io.github.skippyall.minions.program.argument;
import com.mojang.serialization.Codec; import com.mojang.serialization.Codec;
import io.github.skippyall.minions.MinionRegistries; import io.github.skippyall.minions.MinionRegistries;
import io.github.skippyall.minions.Minions;
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
import io.github.skippyall.minions.program.InstructionRuntime; import io.github.skippyall.minions.program.InstructionRuntime;
import io.github.skippyall.minions.program.value.ValueType;
import net.minecraft.registry.Registry;
import net.minecraft.util.Identifier;
public class Arguments { public class Arguments {
public static final Codec<SpecificArgumentType<?,?, MinionFakePlayer>> SPECIFIC_ARGUMENT_TYPE_CODEC = createSpecificTypeCodec(MinionRegistries.GENERIC_ARGUMENT_TYPE_REGISTRY.getCodec()); public static <R extends InstructionRuntime<R>> Codec<Argument<?,R>> createArgumentCodec(Codec<ArgumentType<R>> codec) {
public static final Codec<Argument<?,?,MinionFakePlayer>> ARGUMENT_CODEC = createArgumentCodecFromSpecific(SPECIFIC_ARGUMENT_TYPE_CODEC); return codec.dispatch(
public static final GenericArgumentType<MinionFakePlayer> VALUE_ARGUMENT = register(Identifier.of(Minions.MOD_ID, "value"), ValueArgumentType::new);
public static <R> Codec<SpecificArgumentType<?,?,R>> createSpecificTypeCodec(Codec<GenericArgumentType<R>> genericCodec) {
return genericCodec.dispatch(
"type", "type",
SpecificArgumentType::getGenericArgumentType, Argument::getType,
generic -> type ->
MinionRegistries.VALUE_TYPES.getCodec().xmap( MinionRegistries.VALUE_TYPES.getCodec().<Argument<?,R>>dispatch(
generic::createTypeSpecific, Argument::getValueType,
SpecificArgumentType::getValueType valueType -> type.getCodec(valueType).fieldOf("valueType")
).fieldOf("valueType") ).fieldOf("valueType")
); );
} }
public static <R extends InstructionRuntime<R>> Codec<Argument<?, ?, R>> createArgumentCodecFromSpecific(Codec<SpecificArgumentType<?,?,R>> specificTypeCodec) {
return specificTypeCodec.dispatch(Argument::getType, specific -> specific.getArgumentCodec().fieldOf("data"));
}
public static <R extends InstructionRuntime<R>> Codec<Argument<?,?,R>> createArgumentCodec(Codec<GenericArgumentType<R>> genericTypeCodec) {
return createArgumentCodecFromSpecific(createSpecificTypeCodec(genericTypeCodec));
}
public static <V> SpecificArgumentType<V, ? extends Argument<V, ?, MinionFakePlayer>, MinionFakePlayer> getArgumentType(Identifier id, ValueType<V> valueType) {
GenericArgumentType<MinionFakePlayer> generic = MinionRegistries.GENERIC_ARGUMENT_TYPE_REGISTRY.get(id);
if(generic != null) {
return generic.createTypeSpecific(valueType);
}
return null;
}
public static GenericArgumentType<MinionFakePlayer> register(Identifier id, GenericArgumentType<MinionFakePlayer> argumentType) {
return Registry.register(MinionRegistries.GENERIC_ARGUMENT_TYPE_REGISTRY, id, argumentType);
}
} }
@@ -1,16 +0,0 @@
package io.github.skippyall.minions.program.argument;
import io.github.skippyall.minions.program.InstructionRuntime;
import io.github.skippyall.minions.program.value.ValueType;
public interface GenericArgumentType<R extends InstructionRuntime<R>> {
default <V> SpecificArgumentType<V, ? extends Argument<V, ?, R>, R> createTypeSpecific(ValueType<V> valueType) {
return createTypeSpecific(valueType, this);
}
<V> SpecificArgumentType<V, ? extends Argument<V, ?, R>, R> createTypeSpecific(ValueType<V> valueType, GenericArgumentType<R> me);
default boolean canCreate(ValueType<?> valueType) {
return true;
}
}
@@ -1,37 +0,0 @@
package io.github.skippyall.minions.program.argument;
import com.mojang.serialization.Codec;
import io.github.skippyall.minions.program.InstructionRuntime;
import io.github.skippyall.minions.program.value.ValueType;
import net.minecraft.server.network.ServerPlayerEntity;
import org.jetbrains.annotations.Nullable;
import java.util.concurrent.CompletableFuture;
/**
* <code>SpecificArgumentType</code>s create <code>Argument</code>s of the specified <code>ValueType</code>.
* They are also responsible for the serialization and user input of arguments.
* @param <V> The value type of the <code>Argument</code>s to create
* @param <A> The type of the <code>Argument</code>s themselves
*/
public abstract class SpecificArgumentType<V, A extends Argument<V, ? extends SpecificArgumentType<V, A, R>, R>, R extends InstructionRuntime<R>> {
public final ValueType<V> valueType;
public final GenericArgumentType<R> genericType;
public SpecificArgumentType(ValueType<V> valueType, GenericArgumentType<R> genericType) {
this.valueType = valueType;
this.genericType = genericType;
}
public abstract Codec<A> getArgumentCodec();
public abstract CompletableFuture<A> openArgumentDialog(ServerPlayerEntity player, @Nullable A previousArgument);
public ValueType<V> getValueType() {
return valueType;
}
public GenericArgumentType<R> getGenericArgumentType() {
return genericType;
}
}
@@ -3,16 +3,19 @@ package io.github.skippyall.minions.program.argument;
import io.github.skippyall.minions.gui.GuiDisplay; import io.github.skippyall.minions.gui.GuiDisplay;
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer; import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
import io.github.skippyall.minions.program.InstructionRuntime; import io.github.skippyall.minions.program.InstructionRuntime;
import io.github.skippyall.minions.program.value.ValueType;
/** /**
* An argument that always resolves to a fixed value * An argument that always resolves to a fixed value
*/ */
public class ValueArgument<T, R extends InstructionRuntime<R>> implements Argument<T, ValueArgumentType<T, R>, R> { public class ValueArgument<T, R extends InstructionRuntime<R>> implements Argument<T, R> {
private final ValueArgumentType<T,R> type; private final ValueArgumentType<R> type;
private final ValueType<T> valueType;
private final T value; private final T value;
public ValueArgument(ValueArgumentType<T,R> valueType, T value) { public ValueArgument(ValueArgumentType<R> type, ValueType<T> valueType, T value) {
this.type = valueType; this.type = type;
this.valueType = valueType;
this.value = value; this.value = value;
} }
@@ -31,7 +34,12 @@ public class ValueArgument<T, R extends InstructionRuntime<R>> implements Argume
} }
@Override @Override
public ValueArgumentType<T,R> getType() { public ValueType<T> getValueType() {
return valueType;
}
@Override
public ValueArgumentType<R> getType() {
return type; return type;
} }
} }
@@ -8,21 +8,17 @@ import org.jetbrains.annotations.Nullable;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
public class ValueArgumentType<V, R extends InstructionRuntime<R>> extends SpecificArgumentType<V, ValueArgument<V,R>, R> { public class ValueArgumentType<R extends InstructionRuntime<R>> extends ArgumentType<R> {
public ValueArgumentType(ValueType<V> valueType, GenericArgumentType<R> genericType) { @Override
super(valueType, genericType); public <T> Codec<ValueArgument<T,R>> getCodec(ValueType<T> valueType) {
return valueType.codec().xmap(value -> new ValueArgument<>(this, valueType, value), ValueArgument::getValue);
} }
@Override @Override
public Codec<ValueArgument<V,R>> getArgumentCodec() { public <V> CompletableFuture<ValueArgument<V,R>> openConfiguration(ServerPlayerEntity player, ValueType<V> valueType, @Nullable Argument<V,R> previousArgument) {
return valueType.codec().xmap(value -> new ValueArgument<>(this, value), ValueArgument::getValue);
}
@Override
public CompletableFuture<ValueArgument<V,R>> openArgumentDialog(ServerPlayerEntity player, @Nullable ValueArgument<V,R> previousArgument) {
return valueType.openValueDialog( return valueType.openValueDialog(
player, player,
previousArgument != null ? previousArgument.getValue() : valueType.defaultValue() previousArgument instanceof ValueArgument<V,R> val ? val.getValue() : valueType.defaultValue()
).thenApply(value -> new ValueArgument<>(this, value)); ).thenApply(value -> new ValueArgument<>(this, valueType, value));
} }
} }
@@ -1,31 +1,30 @@
package io.github.skippyall.minions.program.instruction; package io.github.skippyall.minions.program.instruction;
import io.github.skippyall.minions.MinionRegistries;
import io.github.skippyall.minions.Minions; import io.github.skippyall.minions.Minions;
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer; import io.github.skippyall.minions.program.InstructionRuntime;
import io.github.skippyall.minions.program.argument.ArgumentList; import io.github.skippyall.minions.program.argument.ArgumentList;
import net.minecraft.storage.ReadView; import net.minecraft.storage.ReadView;
import net.minecraft.storage.WriteView; import net.minecraft.storage.WriteView;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
public class ConfiguredInstruction<Return,R> { public class ConfiguredInstruction<R extends InstructionRuntime<R>> {
private final InstructionType<Return,R> instruction; private final InstructionType<R> instruction;
private final ArgumentList<R> arguments; private final ArgumentList<R> arguments;
private @Nullable InstructionExecution<Return, R> execution; private @Nullable InstructionExecution<R> execution;
private final String name; private final String name;
private ConfiguredInstruction(InstructionType<Return,R> instruction, ArgumentList<R> arguments, @Nullable InstructionExecution<Return,R> execution, String name) { private ConfiguredInstruction(InstructionType<R> instruction, ArgumentList<R> arguments, @Nullable InstructionExecution<R> execution, String name) {
this.instruction = instruction; this.instruction = instruction;
this.arguments = arguments; this.arguments = arguments;
this.execution = execution; this.execution = execution;
this.name = name; this.name = name;
} }
public ConfiguredInstruction(InstructionType<Return,R> instruction, String name) { public ConfiguredInstruction(InstructionType<R> instruction, String name) {
this(instruction, new ArgumentList<>(), null, name); this(instruction, new ArgumentList<>(), null, name);
} }
public InstructionType<Return,R> getInstruction() { public InstructionType<R> getInstruction() {
return instruction; return instruction;
} }
@@ -45,7 +44,7 @@ public class ConfiguredInstruction<Return,R> {
return execution != null; return execution != null;
} }
public @Nullable InstructionExecution<Return,R> getExecution() { public @Nullable InstructionExecution<R> getExecution() {
return execution; return execution;
} }
@@ -55,7 +54,7 @@ public class ConfiguredInstruction<Return,R> {
execution = instruction.createExecution(arguments, minion); execution = instruction.createExecution(arguments, minion);
execution.start(minion); execution.start(minion);
} catch (Exception e) { } catch (Exception e) {
Minions.LOGGER.error("An error occurred while executing configured Instruction {} of minion {}", name, minion.getGameProfile().getName(), e); Minions.LOGGER.error("An error occurred while executing configured Instruction {}", name, e);
} }
} }
@@ -82,26 +81,25 @@ public class ConfiguredInstruction<Return,R> {
} }
public void save(WriteView view, R minion) { public void save(WriteView view, R minion) {
view.put("instruction", MinionRegistries.INSTRUCTION_TYPES.getCodec(), instruction); view.put("instruction", minion.getInstructionTypeRegistry().getCodec(), instruction);
view.put("arguments", ArgumentList.CODEC, arguments); view.put("arguments", minion.getArgumentListCodec(), arguments);
view.putBoolean("running", isRunning()); view.putBoolean("running", isRunning());
if(isRunning()) { if(isRunning()) {
execution.save(view.get("execution"), minion); execution.save(view.get("execution"), minion);
} }
} }
public static <Return,R> ConfiguredInstruction<Return,R> load(ReadView view, R minion, String name) { public static <R extends InstructionRuntime<R>> ConfiguredInstruction<R> load(ReadView view, R minion, String name) {
//noinspection unchecked InstructionType<R> instructionType = view.read("instruction", minion.getInstructionTypeRegistry().getCodec()).orElseThrow();
InstructionType<Return,R> instructionType = (InstructionType<Return,R>) view.read("instruction", MinionRegistries.INSTRUCTION_TYPES.getCodec()).orElseThrow();
ArgumentList<R> arguments = view.read("arguments", ArgumentList.get).orElseThrow(); ArgumentList<R> arguments = view.read("arguments", minion.getArgumentListCodec()).orElseThrow();
boolean running = view.getBoolean("running", false); boolean running = view.getBoolean("running", false);
if(running) { if(running) {
ReadView executionView = view.getReadView("execution"); ReadView executionView = view.getReadView("execution");
try { try {
InstructionExecution<Return,R> execution = instructionType.loadExecution(executionView, minion); InstructionExecution<R> execution = instructionType.loadExecution(executionView, minion);
return new ConfiguredInstruction<>(instructionType, arguments, execution, name); return new ConfiguredInstruction<>(instructionType, arguments, execution, name);
} catch (Exception e) { } catch (Exception e) {
@@ -1,5 +1,6 @@
package io.github.skippyall.minions.program.instruction; package io.github.skippyall.minions.program.instruction;
import io.github.skippyall.minions.program.InstructionRuntime;
import io.github.skippyall.minions.program.argument.ArgumentList; import io.github.skippyall.minions.program.argument.ArgumentList;
import net.minecraft.storage.ReadView; import net.minecraft.storage.ReadView;
import net.minecraft.storage.WriteView; import net.minecraft.storage.WriteView;
@@ -10,9 +11,8 @@ import net.minecraft.storage.WriteView;
* <li>A new instance is created using the factory</li> * <li>A new instance is created using the factory</li>
* <li>{@link InstructionExecution#readArguments(ArgumentList, R) readFromParameters} is called</li> * <li>{@link InstructionExecution#readArguments(ArgumentList, R) readFromParameters} is called</li>
* <li>{@link InstructionExecution#start(R) start} is called</li> * <li>{@link InstructionExecution#start(R) start} is called</li>
* @param <Return>
*/ */
public interface InstructionExecution<Return, R> { public interface InstructionExecution<R extends InstructionRuntime<R>> {
/** /**
* Starts the execution. * Starts the execution.
*/ */
@@ -36,9 +36,8 @@ public interface InstructionExecution<Return, R> {
* This should undo changes to the minion unless they are supposed to be permanent. * This should undo changes to the minion unless they are supposed to be permanent.
* *
* @param runtime The runtime that was executing this instruction. * @param runtime The runtime that was executing this instruction.
* @return The return value of the instruction
*/ */
Return stop(R runtime); void stop(R runtime);
/** /**
* Initializes the execution with its arguments. * Initializes the execution with its arguments.
@@ -1,60 +1,51 @@
package io.github.skippyall.minions.program.instruction; package io.github.skippyall.minions.program.instruction;
import io.github.skippyall.minions.gui.GuiDisplay; import io.github.skippyall.minions.gui.GuiDisplay;
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
import io.github.skippyall.minions.program.InstructionRuntime; import io.github.skippyall.minions.program.InstructionRuntime;
import io.github.skippyall.minions.program.argument.Parameter; import io.github.skippyall.minions.program.argument.Parameter;
import io.github.skippyall.minions.program.argument.ArgumentList; import io.github.skippyall.minions.program.argument.ArgumentList;
import io.github.skippyall.minions.program.value.ValueType; import io.github.skippyall.minions.program.value.ValueType;
import net.minecraft.network.codec.PacketCodec;
import net.minecraft.recipe.Recipe;
import net.minecraft.storage.ReadView; import net.minecraft.storage.ReadView;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.function.Supplier; import java.util.function.Supplier;
public class InstructionType<Return, R extends InstructionRuntime<R>> { public class InstructionType<R extends InstructionRuntime<R>> {
private final GuiDisplay display; private final GuiDisplay display;
private final Collection<Parameter<?>> parameters; private final Collection<Parameter<?>> parameters;
private final ValueType<Return> returnType; private final Supplier<InstructionExecution<R>> executionFactory;
private final Supplier<InstructionExecution<Return,R>> executionFactory;
private InstructionType(GuiDisplay display, Supplier<InstructionExecution<Return,R>> executionFactory, ValueType<Return> returnType, Collection<Parameter<?>> parameters) { private InstructionType(GuiDisplay display, Supplier<InstructionExecution<R>> executionFactory, Collection<Parameter<?>> parameters) {
this.display = display; this.display = display;
this.parameters = parameters; this.parameters = parameters;
this.returnType = returnType;
this.executionFactory = executionFactory; this.executionFactory = executionFactory;
} }
public static <Return,R extends InstructionRuntime<R>> InstructionType<Return,R> create(GuiDisplay display, Supplier<InstructionExecution<Return,R>> executionFactory, ValueType<Return> returnType, Collection<Parameter<?>> parameters) { public static <R extends InstructionRuntime<R>> InstructionType<R> create(GuiDisplay display, Supplier<InstructionExecution<R>> executionFactory, Collection<Parameter<?>> parameters) {
return new InstructionType<>(display, executionFactory, returnType, List.copyOf(parameters)); return new InstructionType<>(display, executionFactory, List.copyOf(parameters));
} }
public static <Return,R extends InstructionRuntime<R>> InstructionType<Return,R> create(GuiDisplay display, Supplier<InstructionExecution<Return,R>> executionFactory, ValueType<Return> returnType, Parameter<?>... parameters) { public static <Return,R extends InstructionRuntime<R>> InstructionType<R> create(GuiDisplay display, Supplier<InstructionExecution<R>> executionFactory, ValueType<Return> returnType, Parameter<?>... parameters) {
return new InstructionType<>(display, executionFactory, returnType, List.of(parameters)); return new InstructionType<>(display, executionFactory, List.of(parameters));
} }
public Collection<Parameter<?>> getParameters() { public Collection<Parameter<?>> getParameters() {
return parameters; return parameters;
} }
public ValueType<Return> getReturnType() {
return returnType;
}
public GuiDisplay getDisplay() { public GuiDisplay getDisplay() {
return display; return display;
} }
public InstructionExecution<Return,R> createExecution(ArgumentList<R> parameters, R minion) { public InstructionExecution<R> createExecution(ArgumentList<R> parameters, R minion) {
InstructionExecution<Return,R> execution = executionFactory.get(); InstructionExecution<R> execution = executionFactory.get();
execution.readArguments(parameters, minion); execution.readArguments(parameters, minion);
return execution; return execution;
} }
public InstructionExecution<Return,R> loadExecution(ReadView view, R minion) { public InstructionExecution<R> loadExecution(ReadView view, R minion) {
InstructionExecution<Return,R> execution = executionFactory.get(); InstructionExecution<R> execution = executionFactory.get();
execution.load(view, minion); execution.load(view, minion);
return execution; return execution;
} }
@@ -1,19 +0,0 @@
package io.github.skippyall.minions.program.returnvalue;
import io.github.skippyall.minions.program.InstructionRuntime;
import io.github.skippyall.minions.program.argument.Argument;
import io.github.skippyall.minions.program.argument.SpecificArgumentType;
import io.github.skippyall.minions.program.value.ValueType;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
public interface GenericValueConsumerType<R extends InstructionRuntime<R>> {
default <V> SpecificValueConsumerType<V, ? extends ValueConsumer<V, ?, R>, R> createTypeSpecific(ValueType<V> valueType) {
return createTypeSpecific(valueType, this);
}
<V> SpecificValueConsumerType<V, ? extends Argument<V, ?, R>, R> createTypeSpecific(ValueType<V> valueType, GenericValueConsumerType<R> me);
default boolean canCreate(ValueType<?> valueType) {
return true;
}
}
@@ -1,57 +0,0 @@
package io.github.skippyall.minions.program.returnvalue;
import com.mojang.serialization.Codec;
import io.github.skippyall.minions.program.InstructionRuntime;
import io.github.skippyall.minions.program.argument.Argument;
import io.github.skippyall.minions.program.argument.Arguments;
import io.github.skippyall.minions.program.argument.GenericArgumentType;
import io.github.skippyall.minions.program.argument.Parameter;
import io.github.skippyall.minions.program.argument.SpecificArgumentType;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
public class ReturnValueList<R extends InstructionRuntime<R>> {
private final Map<String, ValueConsumer<?, ?, R>> arguments;
public ReturnValueList() {
arguments = new HashMap<>();
}
public ReturnValueList(Map<String, ValueConsumer<?,?, R>> arguments) {
this.arguments = new HashMap<>(arguments);
}
public <T> T getValue(Parameter<T> parameter, R runtime) {
Argument<T,?,R> argument = getArgument(parameter);
return argument != null ? argument.resolve(runtime) : null;
}
public <T, A extends Argument<T, ? extends SpecificArgumentType<T,A,R>,R>> A getArgument(Parameter<T> parameter) {
Argument<?, ?,R> argument = arguments.get(parameter.name());
return argument == null ? null : argument.cast(parameter.type());
}
public <T> void setArgument(Parameter<T> parameter, Argument<T,?,R> argument) {
arguments.put(parameter.name(), argument);
}
public boolean hasArgumentFor(Parameter<?> parameter) {
return getArgument(parameter) != null;
}
public boolean hasArgumentForAll(Collection<Parameter<?>> checkParameters) {
for(Parameter<?> parameter : checkParameters) {
if(!hasArgumentFor(parameter)) {
return false;
}
}
return true;
}
public static <R extends InstructionRuntime<R>> Codec<ReturnValueList<R>> getCodec(Codec<GenericArgumentType<R>> genericCodec) {
return Codec.unboundedMap(Codec.STRING, Arguments.createArgumentCodec(genericCodec))
.xmap(ReturnValueList::new, list -> list.arguments);
}
}
@@ -1,39 +0,0 @@
package io.github.skippyall.minions.program.returnvalue;
import com.mojang.serialization.Codec;
import io.github.skippyall.minions.program.InstructionRuntime;
import io.github.skippyall.minions.program.argument.Argument;
import io.github.skippyall.minions.program.argument.GenericArgumentType;
import io.github.skippyall.minions.program.value.ValueType;
import net.minecraft.server.network.ServerPlayerEntity;
import org.jetbrains.annotations.Nullable;
import java.util.concurrent.CompletableFuture;
/**
* <code>SpecificArgumentType</code>s create <code>Argument</code>s of the specified <code>ValueType</code>.
* They are also responsible for the serialization and user input of arguments.
* @param <V> The value type of the <code>Argument</code>s to create
* @param <A> The type of the <code>Argument</code>s themselves
*/
public abstract class SpecificValueConsumerType<V, A extends ValueConsumer<V, ? extends SpecificValueConsumerType<V, A, R>, R>, R extends InstructionRuntime<R>> {
public final ValueType<V> valueType;
public final GenericArgumentType<R> genericType;
public SpecificValueConsumerType(ValueType<V> valueType, GenericArgumentType<R> genericType) {
this.valueType = valueType;
this.genericType = genericType;
}
public abstract Codec<A> getValueConsumerCodec();
public abstract CompletableFuture<A> openValueConsumerDialog(ServerPlayerEntity player, @Nullable A previousArgument);
public ValueType<V> getValueType() {
return valueType;
}
public GenericArgumentType<R> getGenericArgumentType() {
return genericType;
}
}
@@ -2,7 +2,7 @@ package io.github.skippyall.minions.program.returnvalue;
import io.github.skippyall.minions.gui.GuiDisplay; import io.github.skippyall.minions.gui.GuiDisplay;
import io.github.skippyall.minions.program.InstructionRuntime; import io.github.skippyall.minions.program.InstructionRuntime;
import io.github.skippyall.minions.program.argument.SpecificArgumentType; import io.github.skippyall.minions.program.argument.ArgumentType;
import io.github.skippyall.minions.program.value.ValueType; import io.github.skippyall.minions.program.value.ValueType;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@@ -11,20 +11,17 @@ import org.jetbrains.annotations.Nullable;
* Its value is resolved at runtime and can vary between executions. * Its value is resolved at runtime and can vary between executions.
* <code>Argument</code>s are created exclusively by <code>SpecificArgumentType</code>s. * <code>Argument</code>s are created exclusively by <code>SpecificArgumentType</code>s.
* @param <T> The type of the <code>Argument</code>'s value * @param <T> The type of the <code>Argument</code>'s value
* @param <S> The <code>SpecificArgumentType</code>
*/ */
public interface ValueConsumer<T, S extends SpecificValueConsumerType<T, ? extends ValueConsumer<T, S, R>, R>, R extends InstructionRuntime<R>> { public interface ValueConsumer<T,R extends InstructionRuntime<R>> {
void consume(T value, R runtime); void consume(T value, R runtime);
default ValueType<T> getValueType() {
return getType().getValueType();
}
GuiDisplay getDisplay(); GuiDisplay getDisplay();
S getType(); ValueType<T> getValueType();
default <U, A extends io.github.skippyall.minions.program.argument.Argument<U, ? extends SpecificArgumentType<U,A,R>, R>> @Nullable A cast(ValueType<U> type) { ValueConsumerType<R> getType();
default <U,A extends ValueConsumer<U,R>> @Nullable A cast(ValueType<U> type) {
if(getValueType() == type) { if(getValueType() == type) {
//noinspection unchecked //noinspection unchecked
return (A) this; return (A) this;
@@ -0,0 +1,34 @@
package io.github.skippyall.minions.program.returnvalue;
import com.mojang.serialization.Codec;
import io.github.skippyall.minions.program.InstructionRuntime;
import io.github.skippyall.minions.program.argument.Parameter;
import java.util.HashMap;
import java.util.Map;
public class ValueConsumerList<R extends InstructionRuntime<R>> {
private final Map<String, ValueConsumer<?, R>> valueConsumers;
public ValueConsumerList() {
valueConsumers = new HashMap<>();
}
public ValueConsumerList(Map<String, ValueConsumer<?,R>> valueConsumers) {
this.valueConsumers = new HashMap<>(valueConsumers);
}
public <T, A extends ValueConsumer<T,R>> A getValueConsumer(Parameter<T> parameter) {
ValueConsumer<?,R> argument = valueConsumers.get(parameter.name());
return argument == null ? null : argument.cast(parameter.type());
}
public <T> void setValueConsumer(Parameter<T> parameter, ValueConsumer<?,R> consumer) {
valueConsumers.put(parameter.name(), consumer);
}
public static <R extends InstructionRuntime<R>> Codec<ValueConsumerList<R>> getCodec(Codec<ValueConsumerType<R>> genericCodec) {
return Codec.unboundedMap(Codec.STRING, ValueConsumers.createValueConsumersCodec(genericCodec))
.xmap(ValueConsumerList::new, list -> list.valueConsumers);
}
}
@@ -0,0 +1,16 @@
package io.github.skippyall.minions.program.returnvalue;
import com.mojang.serialization.Codec;
import io.github.skippyall.minions.program.InstructionRuntime;
import io.github.skippyall.minions.program.argument.Argument;
import io.github.skippyall.minions.program.value.ValueType;
import net.minecraft.server.network.ServerPlayerEntity;
import org.jetbrains.annotations.Nullable;
import java.util.concurrent.CompletableFuture;
public abstract class ValueConsumerType<R extends InstructionRuntime<R>> {
public abstract <T> Codec<? extends ValueConsumer<T,R>> getCodec(ValueType<T> type);
public abstract <T> CompletableFuture<? extends ValueConsumer<T,R>> openConfiguration(ServerPlayerEntity player, ValueType<T> valueType, @Nullable ValueConsumer<T,R> previous);
}
@@ -0,0 +1,24 @@
package io.github.skippyall.minions.program.returnvalue;
import com.mojang.serialization.Codec;
import io.github.skippyall.minions.MinionRegistries;
import io.github.skippyall.minions.Minions;
import io.github.skippyall.minions.minion.MinionRuntime;
import io.github.skippyall.minions.program.InstructionRuntime;
import io.github.skippyall.minions.program.argument.Argument;
import net.minecraft.registry.Registry;
import net.minecraft.util.Identifier;
public class ValueConsumers {
public static <R extends InstructionRuntime<R>> Codec<ValueConsumer<?,R>> createValueConsumersCodec(Codec<ValueConsumerType<R>> codec) {
return codec.dispatch(
"type",
ValueConsumer::getType,
type ->
MinionRegistries.VALUE_TYPES.getCodec().<ValueConsumer<?,R>>dispatch(
ValueConsumer::getValueType,
valueType -> type.getCodec(valueType).fieldOf("valueType")
).fieldOf("valueType")
);
}
}