aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author alemi <me@alemi.dev>2023-11-13 04:24:49 +0100
committer alemi <me@alemi.dev>2023-11-13 04:24:49 +0100
commitbfc6d4fef6804b0050537228ffdabc63b0f6683b (patch)
treefddc396bee763b2fb303e8077e9e8e34a2ea1faa
parentadd2ea794516533b80db830eab34bc4e8dfc620b (diff)
feat: added Many setting for collections
still very raw and not super helpful but kind of usable?
-rw-r--r--src/main/java/ftbsc/bscv/tools/Setting.java196
1 files changed, 153 insertions, 43 deletions
diff --git a/src/main/java/ftbsc/bscv/tools/Setting.java b/src/main/java/ftbsc/bscv/tools/Setting.java
index 99f5480..427e22e 100644
--- a/src/main/java/ftbsc/bscv/tools/Setting.java
+++ b/src/main/java/ftbsc/bscv/tools/Setting.java
@@ -1,23 +1,28 @@
package ftbsc.bscv.tools;
+import com.google.common.collect.Lists;
import com.mojang.brigadier.arguments.*;
+
import ftbsc.bscv.api.IModule;
import net.minecraft.command.Commands;
import net.minecraftforge.common.ForgeConfigSpec;
import net.minecraftforge.server.command.EnumArgument;
+import java.io.Serializable;
+import java.util.List;
import java.util.Optional;
import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.Predicate;
import static ftbsc.bscv.Boscovicino.log;
-public abstract class Setting<T> {
+public abstract class Setting<T, I> {
protected Optional<String> name;
protected Optional<String> comment;
protected Optional<T> fallback;
- protected Optional<Consumer<T>> callback;
-
+ protected Optional<Consumer<I>> callback;
Setting() {
this.name = Optional.empty();
@@ -26,68 +31,75 @@ public abstract class Setting<T> {
this.callback = Optional.empty();
}
- public Setting<T> name(String name) {
+ public Setting<T, I> name(String name) {
this.name = Optional.of(name);
return this;
}
- public Setting<T> comment(String comment) {
+ public Setting<T, I> comment(String comment) {
this.comment = Optional.of(comment);
return this;
}
- public Setting<T> fallback(T fallback) {
+ public Setting<T, I> fallback(T fallback) {
this.fallback = Optional.of(fallback);
return this;
}
- public Setting<T> callback(Consumer<T> callback) {
+ public Setting<T, I> callback(Consumer<I> callback) {
this.callback = Optional.of(callback);
return this;
}
abstract ForgeConfigSpec.ConfigValue<T> value(ForgeConfigSpec.Builder builder);
- abstract ArgumentType<T> argument();
+ abstract ArgumentType<I> argument();
+
+ public abstract ForgeConfigSpec.ConfigValue<T> build(IModule module);
+
- abstract Class<T> clazz();
- public ForgeConfigSpec.ConfigValue<T> build(IModule module) {
- ForgeConfigSpec.ConfigValue<T> conf = this.value(module.getConfigBuilder());
+ private static abstract class ValueSetting<T> extends Setting<T, T> {
+
+ abstract Class<T> clazz();
- String optName = this.name.get();
- Class<T> clazz = this.clazz();
- ArgumentType<T> arg = this.argument();
- Consumer<T> cb = this.callback.isPresent() ? this.callback.get() : null;
+ public ForgeConfigSpec.ConfigValue<T> build(IModule module) {
+ ForgeConfigSpec.ConfigValue<T> conf = this.value(module.getConfigBuilder());
- module.getDispatcher().register(
- Commands.literal(module.getName().toLowerCase())
- .then(
- Commands.literal(optName)
+ String optName = this.name.get();
+ Class<T> clazz = this.clazz();
+ ArgumentType<T> arg = this.argument();
+ Consumer<T> cb = this.callback.isPresent() ? this.callback.get() : null;
+
+ module.getDispatcher().register(
+ Commands.literal(module.getName().toLowerCase())
.then(
- Commands.argument(optName, arg)
- .executes( ctx -> {
- T value = ctx.getArgument(optName, clazz);
- if (cb != null) {
- cb.accept(value);
- }
- conf.set(value);
- conf.save();
- log(String.format("> %s -> %s <", String.join(".", conf.getPath()), conf.get().toString()));
- return 1;
- }))
- .executes(ctx -> {
- log(String.format("> %s: %s <", optName, conf.get().toString()));
- return 1;
- })
- )
- );
-
- return conf;
+ Commands.literal(optName)
+ .then(
+ Commands.argument(optName, arg)
+ .executes( ctx -> {
+ T value = ctx.getArgument(optName, clazz);
+ if (cb != null) {
+ cb.accept(value);
+ }
+ conf.set(value);
+ conf.save();
+ log(String.format("> %s -> %s <", String.join(".", conf.getPath()), conf.get().toString()));
+ return 1;
+ }))
+ .executes(ctx -> {
+ log(String.format("> %s: %s <", optName, conf.get().toString()));
+ return 1;
+ })
+ )
+ );
+
+ return conf;
+ }
}
- public static class Bool extends Setting<Boolean> {
+ public static class Bool extends ValueSetting<Boolean> {
public static Bool builder() { return new Bool(); }
public Class<Boolean> clazz() { return Boolean.class; }
@@ -101,7 +113,7 @@ public abstract class Setting<T> {
}
- public static class Decimal extends Setting<Double> {
+ public static class Decimal extends ValueSetting<Double> {
protected Optional<Double> min;
protected Optional<Double> max;
@@ -133,7 +145,7 @@ public abstract class Setting<T> {
}
- public static class Number extends Setting<Integer> {
+ public static class Number extends ValueSetting<Integer> {
protected Optional<Integer> min;
protected Optional<Integer> max;
@@ -165,7 +177,7 @@ public abstract class Setting<T> {
}
- public static class Str extends Setting<String> {
+ public static class Str extends ValueSetting<String> {
public static Str builder() { return new Str(); }
protected boolean greedy = false;
@@ -190,7 +202,7 @@ public abstract class Setting<T> {
}
- public static class Switch<T extends Enum<T>> extends Setting<T> {
+ public static class Switch<T extends Enum<T>> extends ValueSetting<T> {
private final Class<T> enumClazz;
public static<T extends Enum<T>> Switch<T> builder(Class<T> type) { return new Switch<T>(type); }
@@ -214,4 +226,102 @@ public abstract class Setting<T> {
}
}
+ public static class Many<T, S extends Serializable> extends Setting<List<? extends S>, T> {
+ private Predicate<Object> validator;
+ private Function<T, S> writer;
+ private final ArgumentType<T> argument_type;
+ private final Class<T> clazz;
+
+ // TODO can we infer clazz from the argument type without needing the second argument???
+ public Many(ArgumentType<T> argument, Class<T> clazz) {
+ super();
+ this.validator = x -> true;
+ this.writer = x -> (S) x; // TODO this works ootb if it's just the same type but crashes at runtime for everything else
+ this.argument_type = argument;
+ this.clazz = clazz;
+ }
+
+ public static<T, S extends Serializable> Many<T, S> builder(ArgumentType<T> argument, Class<T> clazz) { return new Many<T, S>(argument, clazz); }
+
+ public Many<T, S> validator(Predicate<Object> validator) {
+ this.validator = validator;
+ return this;
+ }
+
+ public Many<T, S> writer(Function<T, S> writer) {
+ this.writer = writer;
+ return this;
+ }
+
+ public ArgumentType<T> argument() {
+ return this.argument_type;
+ }
+
+ public ForgeConfigSpec.ConfigValue<List<? extends S>> value(ForgeConfigSpec.Builder builder) {
+ return builder
+ .comment(this.comment.get())
+ .defineList(
+ this.name.get(),
+ this.fallback.get(),
+ this.validator
+ );
+ }
+
+ public ForgeConfigSpec.ConfigValue<List<? extends S>> build(IModule module) {
+ ForgeConfigSpec.ConfigValue<List<? extends S>> conf = this.value(module.getConfigBuilder());
+
+ String optName = this.name.get();
+ ArgumentType<T> arg = this.argument();
+ Consumer<T> cb = this.callback.isPresent() ? this.callback.get() : null;
+
+ module.getDispatcher().register(
+ Commands.literal(module.getName().toLowerCase())
+ .then(
+ Commands.literal(optName)
+ .then(
+ Commands.literal("add")
+ .then(
+ Commands.argument(optName, arg)
+ .executes( ctx -> {
+ T value = ctx.getArgument(optName, this.clazz);
+ if (cb != null) {
+ cb.accept(value);
+ }
+ List<S> botch = Lists.newArrayList(conf.get());
+ botch.add(this.writer.apply(value));
+ conf.set(botch);
+ conf.save();
+ log(String.format("> %s -++> %s <", String.join(".", conf.getPath()), conf.get().toString()));
+ return 1;
+ })
+ )
+ )
+ .then(
+ Commands.literal("remove")
+ .then(
+ Commands.argument(optName, arg)
+ .executes( ctx -> {
+ T value = ctx.getArgument(optName, clazz);
+ if (cb != null) {
+ cb.accept(value);
+ }
+ List<S> botch = Lists.newArrayList(conf.get());
+ boolean removed = botch.remove(this.writer.apply(value));
+ conf.set(botch);
+ conf.save();
+ log(String.format("> %s -%s> %s <", String.join(".", conf.getPath()), removed ? "//" : "--", conf.get().toString()));
+ return 1;
+ })
+ )
+ )
+ .executes(ctx -> {
+ log(String.format("> %s: %s <", optName, conf.get().toString()));
+ return 1;
+ })
+ )
+ );
+
+ return conf;
+ }
+ }
}