chore(config-core): plumb TypeTokens throughout internal representation
This commit is contained in:
parent
64f0f38668
commit
d579c19f6b
|
@ -174,7 +174,7 @@ public class ConfigProcessor extends AbstractProcessor2 {
|
|||
default -> {
|
||||
code.add("$L, $L, ", e.min(), e.max());
|
||||
if (tm instanceof DeclaredType dt && !dt.getTypeArguments().isEmpty()) {
|
||||
code.add("$T.ofClass(new $T<$T>() {}.getType())", Type.class, TypeToken.class, tm);
|
||||
code.add("$T.ofToken(new $T<$T>() {})", Type.class, TypeToken.class, tm);
|
||||
} else code.add("$T.class", tm);
|
||||
code.add(", $L, () -> $T.$L, value -> $T.$L = value", e.width(), source, name, source, name);
|
||||
}
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
package io.gitlab.jfronny.libjf.config.api.v2;
|
||||
|
||||
import io.gitlab.jfronny.commons.serialize.MalformedDataException;
|
||||
import io.gitlab.jfronny.commons.serialize.SerializeReader;
|
||||
import io.gitlab.jfronny.commons.serialize.SerializeWriter;
|
||||
import io.gitlab.jfronny.commons.serialize.databind.api.TypeToken;
|
||||
import io.gitlab.jfronny.libjf.LibJf;
|
||||
import io.gitlab.jfronny.libjf.config.api.v2.type.Type;
|
||||
import io.gitlab.jfronny.libjf.config.impl.dsl.DslEntryInfo;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
public interface EntryInfo<T> {
|
||||
|
@ -77,6 +79,18 @@ public interface EntryInfo<T> {
|
|||
*/
|
||||
<TEx extends Exception, Writer extends SerializeWriter<TEx, Writer>> void writeTo(Writer writer, String translationPrefix) throws TEx, IllegalAccessException;
|
||||
|
||||
default <TEx extends Exception, Reader extends SerializeReader<TEx, Reader>> T deserializeOneFrom(Reader reader) throws TEx, MalformedDataException {
|
||||
return LibJf.MAPPER.getAdapter(getTypeToken()).deserialize(reader);
|
||||
}
|
||||
|
||||
default <TEx extends Exception, Writer extends SerializeWriter<TEx, Writer>> void serializeOneTo(T value, String translationPrefix, Writer writer) throws TEx, MalformedDataException {
|
||||
LibJf.MAPPER.getAdapter(getTypeToken()).serialize(value, writer);
|
||||
}
|
||||
|
||||
default TypeToken<T> getTypeToken() {
|
||||
return (TypeToken<T>) getValueType().asToken();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Get the width for this entry
|
||||
*/
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package io.gitlab.jfronny.libjf.config.api.v2.type;
|
||||
|
||||
import io.gitlab.jfronny.commons.serialize.databind.api.TypeToken;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
|
@ -14,7 +15,19 @@ public sealed interface Type {
|
|||
else if (klazz == String.class) return TString.INSTANCE;
|
||||
else if (klazz == boolean.class || klazz == Boolean.class) return TBool.INSTANCE;
|
||||
else if (klazz instanceof Class<?> k && k.isEnum()) return new TEnum<>(k);
|
||||
else return new TUnknown(klazz);
|
||||
else return new TUnknown(klazz, TypeToken.get(klazz));
|
||||
}
|
||||
|
||||
static Type ofToken(TypeToken<?> token) {
|
||||
java.lang.reflect.Type klazz = token.getRawType();
|
||||
if (klazz == int.class || klazz == Integer.class) return TInt.INSTANCE;
|
||||
else if (klazz == long.class || klazz == Long.class) return TLong.INSTANCE;
|
||||
else if (klazz == float.class || klazz == Float.class) return TFloat.INSTANCE;
|
||||
else if (klazz == double.class || klazz == Double.class) return TDouble.INSTANCE;
|
||||
else if (klazz == String.class) return TString.INSTANCE;
|
||||
else if (klazz == boolean.class || klazz == Boolean.class) return TBool.INSTANCE;
|
||||
else if (klazz instanceof Class<?> k && k.isEnum()) return new TEnum<>(k);
|
||||
else return new TUnknown(klazz, token);
|
||||
}
|
||||
|
||||
default boolean isInt() {
|
||||
|
@ -45,6 +58,10 @@ public sealed interface Type {
|
|||
}
|
||||
|
||||
@Nullable java.lang.reflect.Type asClass();
|
||||
@Nullable default TypeToken<?> asToken() {
|
||||
java.lang.reflect.Type type = asClass();
|
||||
return type == null ? null : TypeToken.get(type);
|
||||
}
|
||||
|
||||
String getName();
|
||||
|
||||
|
@ -162,13 +179,13 @@ public sealed interface Type {
|
|||
}
|
||||
}
|
||||
|
||||
record TEnum<T>(@Nullable Class<T> klazz, String name, T[] options) implements Type {
|
||||
record TEnum<T>(@Nullable Class<T> klazz, TypeToken<T> token, String name, T[] options) implements Type {
|
||||
public TEnum(Class<T> klazz) {
|
||||
this(klazz, klazz.getSimpleName(), klazz.getEnumConstants());
|
||||
this(klazz, TypeToken.get(klazz), klazz.getSimpleName(), klazz.getEnumConstants());
|
||||
}
|
||||
|
||||
public static TEnum<String> create(String name, String[] options) {
|
||||
return new TEnum<>(null, name, options);
|
||||
return new TEnum<>(null, null, name, options);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -181,6 +198,11 @@ public sealed interface Type {
|
|||
return klazz;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable TypeToken<?> asToken() {
|
||||
return token;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
|
@ -194,12 +216,17 @@ public sealed interface Type {
|
|||
}
|
||||
}
|
||||
|
||||
record TUnknown(java.lang.reflect.Type klazz) implements Type {
|
||||
record TUnknown(java.lang.reflect.Type klazz, TypeToken<?> token) implements Type {
|
||||
@Override
|
||||
public @Nullable java.lang.reflect.Type asClass() {
|
||||
return klazz;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable TypeToken<?> asToken() {
|
||||
return token;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return klazz instanceof Class<?> k ? k.getSimpleName() : klazz.getTypeName();
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package io.gitlab.jfronny.libjf.config.impl.dsl;
|
||||
|
||||
import io.gitlab.jfronny.commons.Serializer;
|
||||
import io.gitlab.jfronny.commons.serialize.MalformedDataException;
|
||||
import io.gitlab.jfronny.commons.serialize.SerializeReader;
|
||||
import io.gitlab.jfronny.commons.serialize.SerializeWriter;
|
||||
|
@ -63,12 +62,12 @@ public class DslEntryInfo<T> implements EntryInfo<T> {
|
|||
} catch (IllegalAccessException ignored) {
|
||||
}
|
||||
//noinspection unchecked,rawtypes
|
||||
return new DslEntryInfo<Object>(
|
||||
return new DslEntryInfo<>(
|
||||
field.getName(),
|
||||
defaultValue,
|
||||
() -> field.get(null),
|
||||
v -> field.set(null, v),
|
||||
(Type) Type.ofClass(field.getGenericType()),
|
||||
Type.ofClass(field.getGenericType()),
|
||||
entry == null ? 100 : entry.width(),
|
||||
entry == null ? Double.NEGATIVE_INFINITY : entry.min(),
|
||||
entry == null ? Double.POSITIVE_INFINITY : entry.max()
|
||||
|
@ -122,7 +121,7 @@ public class DslEntryInfo<T> implements EntryInfo<T> {
|
|||
}
|
||||
if (valueOriginal != value) {
|
||||
try {
|
||||
setUnchecked(value);
|
||||
setValue(cast(value));
|
||||
} catch (IllegalAccessException e) {
|
||||
LibJf.LOGGER.error("Could not write value", e);
|
||||
}
|
||||
|
@ -131,53 +130,66 @@ public class DslEntryInfo<T> implements EntryInfo<T> {
|
|||
|
||||
@Override
|
||||
public <TEx extends Exception, Reader extends SerializeReader<TEx, Reader>> void loadFromJson(Reader reader) throws TEx, IllegalAccessException {
|
||||
try {
|
||||
setValue(deserializeOneFrom(reader));
|
||||
} catch (MalformedDataException e) {
|
||||
LibJf.LOGGER.error("Could not read " + name, e);
|
||||
} catch (NothingSerializedException ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <TEx extends Exception, Reader extends SerializeReader<TEx, Reader>> T deserializeOneFrom(Reader reader) throws TEx, MalformedDataException {
|
||||
var next = reader.peek();
|
||||
if (type.isBool()) {
|
||||
if (next == Token.BOOLEAN) setUnchecked(reader.nextBoolean());
|
||||
if (next == Token.BOOLEAN) return cast(reader.nextBoolean());
|
||||
else LibJf.LOGGER.error("Unexpected value for " + name + ": expected boolean but got " + next);
|
||||
} else if (type.isString()) {
|
||||
if (next == Token.STRING || next == Token.NUMBER) setUnchecked(reader.nextString());
|
||||
else if (next == Token.BOOLEAN) setUnchecked(Boolean.toString(reader.nextBoolean()));
|
||||
if (next == Token.STRING || next == Token.NUMBER) return cast(reader.nextString());
|
||||
else if (next == Token.BOOLEAN) return cast(Boolean.toString(reader.nextBoolean()));
|
||||
else if (next == Token.NULL) {
|
||||
reader.nextNull();
|
||||
setUnchecked(null);
|
||||
return cast(null);
|
||||
} else LibJf.LOGGER.error("Unexpected value for " + name + ": expected string but got " + next);
|
||||
} else if (type.isInt()) {
|
||||
if (next == Token.NUMBER) setUnchecked(reader.nextInt());
|
||||
if (next == Token.NUMBER) return cast(reader.nextInt());
|
||||
else LibJf.LOGGER.error("Unexpected value for " + name + ": expected number but got " + next);
|
||||
} else if (type.isLong()) {
|
||||
if (next == Token.NUMBER) setUnchecked(reader.nextLong());
|
||||
if (next == Token.NUMBER) return cast(reader.nextLong());
|
||||
else LibJf.LOGGER.error("Unexpected value for " + name + ": expected number but got " + next);
|
||||
} else if (type.isDouble()) {
|
||||
if (next == Token.NUMBER) {
|
||||
setUnchecked(reader.nextDouble());
|
||||
return cast(reader.nextDouble());
|
||||
}
|
||||
else LibJf.LOGGER.error("Unexpected value for " + name + ": expected number but got " + next);
|
||||
} else if (type.isFloat()) {
|
||||
if (next == Token.NUMBER) setUnchecked((float) reader.nextDouble());
|
||||
if (next == Token.NUMBER) return cast((float) reader.nextDouble());
|
||||
else LibJf.LOGGER.error("Unexpected value for " + name + ": expected number but got " + next);
|
||||
} else if (type.isEnum()) {
|
||||
Type.TEnum<T> e = (Type.TEnum<T>) type;
|
||||
if (next == Token.STRING) setUnchecked(e.optionForString(reader.nextString()));
|
||||
if (next == Token.STRING) return cast(e.optionForString(reader.nextString()));
|
||||
else LibJf.LOGGER.error("Unexpected value for " + name + ": expected string but got " + next);
|
||||
} else {
|
||||
try {
|
||||
setValue((T) LibJf.MAPPER.getAdapter(TypeToken.get(type.asClass())).deserialize(reader));
|
||||
return cast((T) LibJf.MAPPER.getAdapter(type.asToken()).deserialize(reader));
|
||||
} catch (MalformedDataException e) {
|
||||
LibJf.LOGGER.error("Could not read " + name, e);
|
||||
}
|
||||
}
|
||||
throw new NothingSerializedException();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void setUnchecked(Object object) throws IllegalAccessException {
|
||||
if (object == null) return;
|
||||
setValue((T) object);
|
||||
private T cast(Object object) {
|
||||
return (T) object;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <TEx extends Exception, Writer extends SerializeWriter<TEx, Writer>> void writeTo(Writer writer, String translationPrefix) throws TEx, IllegalAccessException {
|
||||
T value = getValue();
|
||||
serializeOneTo(getValue(), translationPrefix, writer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <TEx extends Exception, Writer extends SerializeWriter<TEx, Writer>> void serializeOneTo(T value, String translationPrefix, Writer writer) throws TEx {
|
||||
String commentText;
|
||||
if ((commentText = JfConfigSafe.TRANSLATION_SUPPLIER.apply(translationPrefix + getName() + ".tooltip")) != null) {
|
||||
writer.comment(commentText);
|
||||
|
@ -187,7 +199,7 @@ public class DslEntryInfo<T> implements EntryInfo<T> {
|
|||
}
|
||||
writer.name(name);
|
||||
try {
|
||||
LibJf.MAPPER.getAdapter((TypeToken<T>) TypeToken.get(Objects.requireNonNullElse(type.asClass(), String.class))).serialize(value, writer);
|
||||
LibJf.MAPPER.getAdapter((TypeToken<T>) Objects.requireNonNullElse(type.asToken(), TypeToken.get(String.class))).serialize(value, writer);
|
||||
} catch (MalformedDataException e) {
|
||||
LibJf.LOGGER.error("Could not write " + name, e);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
package io.gitlab.jfronny.libjf.config.impl.dsl;
|
||||
|
||||
public class NothingSerializedException extends RuntimeException {
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
package io.gitlab.jfronny.libjf.config.impl.network.rci.entry;
|
||||
|
||||
import io.gitlab.jfronny.commons.serialize.MalformedDataException;
|
||||
import io.gitlab.jfronny.commons.serialize.SerializeReader;
|
||||
import io.gitlab.jfronny.commons.serialize.SerializeWriter;
|
||||
import io.gitlab.jfronny.libjf.config.api.v2.EntryInfo;
|
||||
|
@ -39,6 +40,16 @@ public abstract class MirrorEntryInfoBase<T> extends MirrorObject implements Ent
|
|||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <TEx extends Exception, Reader extends SerializeReader<TEx, Reader>> T deserializeOneFrom(Reader reader) throws TEx, MalformedDataException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <TEx extends Exception, Writer extends SerializeWriter<TEx, Writer>> void serializeOneTo(T value, String translationPrefix, Writer writer) throws TEx, MalformedDataException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fix() {
|
||||
PacketByteBuf buf = PacketByteBufs.create();
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
package io.gitlab.jfronny.libjf.config.impl.ui.tiny;
|
||||
|
||||
import io.gitlab.jfronny.commons.Serializer;
|
||||
import io.gitlab.jfronny.commons.serialize.Transport;
|
||||
import io.gitlab.jfronny.commons.serialize.databind.api.TypeToken;
|
||||
import io.gitlab.jfronny.commons.serialize.json.JsonReader;
|
||||
import io.gitlab.jfronny.libjf.LibJf;
|
||||
import io.gitlab.jfronny.libjf.config.api.v2.ConfigInstance;
|
||||
|
@ -26,47 +24,48 @@ public class TinyConfigScreenFactory implements ConfigScreenFactory<Screen, Tiny
|
|||
&& config.getPresets().keySet().stream().allMatch(s -> s.equals(CategoryBuilder.CONFIG_PRESET_DEFAULT))
|
||||
&& config.getReferencedConfigs().isEmpty()
|
||||
&& config.getCategories().isEmpty()) {
|
||||
EntryInfo entry = config.getEntries().getFirst();
|
||||
EntryInfo<?> entry = config.getEntries().getFirst();
|
||||
Type type = entry.supportsRepresentation() ? entry.getValueType() : null;
|
||||
if (type != null && !type.isInt() && !type.isLong() && !type.isFloat() && !type.isDouble() && !type.isString() && !type.isBool() && !type.isEnum()) {
|
||||
final String jsonified;
|
||||
try {
|
||||
var value = entry.getValue();
|
||||
jsonified = LibJf.LENIENT_TRANSPORT.write(writer -> LibJf.MAPPER.serialize(value, writer));
|
||||
} catch (IllegalAccessException | IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
String key = config.getTranslationPrefix() + entry.getName();
|
||||
return new Built(new EditorScreen(
|
||||
Text.translatable(key),
|
||||
I18n.hasTranslation(key + ".tooltip") ? Text.translatable(key + ".tooltip") : null,
|
||||
parent,
|
||||
jsonified,
|
||||
json -> {
|
||||
try {
|
||||
entry.setValue(LibJf.LENIENT_TRANSPORT.read(
|
||||
json,
|
||||
(Transport.Returnable<JsonReader, ? extends Object, IOException>) reader -> LibJf.MAPPER
|
||||
.getAdapter(TypeToken.get(type.asClass()))
|
||||
.deserialize(reader)));
|
||||
entry.setValue(Serializer.getInstance().deserialize(json, type.asClass()));
|
||||
config.write();
|
||||
} catch (Throwable e) {
|
||||
LibJf.LOGGER.error("Could not write element", e);
|
||||
SystemToast.add(
|
||||
MinecraftClient.getInstance().getToastManager(),
|
||||
SystemToast.Type.PACK_LOAD_FAILURE,
|
||||
Text.translatable("libjf-config-ui-tiny.entry.json.write.fail.title"),
|
||||
Text.translatable("libjf-config-ui-tiny.entry.json.write.fail.description")
|
||||
);
|
||||
}
|
||||
}
|
||||
));
|
||||
return createJson(config, parent, entry);
|
||||
}
|
||||
}
|
||||
return new Built(new TinyConfigScreen(config, parent));
|
||||
}
|
||||
|
||||
private <T> Built createJson(ConfigInstance config, Screen parent, EntryInfo<T> entry) {
|
||||
final String jsonified;
|
||||
try {
|
||||
var value = entry.getValue();
|
||||
jsonified = LibJf.LENIENT_TRANSPORT.write(writer -> entry.serializeOneTo(value, config.getTranslationPrefix(), writer));
|
||||
} catch (IllegalAccessException | IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
String key = config.getTranslationPrefix() + entry.getName();
|
||||
return new Built(new EditorScreen(
|
||||
Text.translatable(key),
|
||||
I18n.hasTranslation(key + ".tooltip") ? Text.translatable(key + ".tooltip") : null,
|
||||
parent,
|
||||
jsonified,
|
||||
json -> {
|
||||
try {
|
||||
entry.setValue(LibJf.LENIENT_TRANSPORT.read(
|
||||
json,
|
||||
(Transport.Returnable<JsonReader, ? extends T, IOException>) entry::deserializeOneFrom));
|
||||
config.write();
|
||||
} catch (Throwable e) {
|
||||
LibJf.LOGGER.error("Could not write element", e);
|
||||
SystemToast.add(
|
||||
MinecraftClient.getInstance().getToastManager(),
|
||||
SystemToast.Type.PACK_LOAD_FAILURE,
|
||||
Text.translatable("libjf-config-ui-tiny.entry.json.write.fail.title"),
|
||||
Text.translatable("libjf-config-ui-tiny.entry.json.write.fail.description")
|
||||
);
|
||||
}
|
||||
}
|
||||
));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPriority() {
|
||||
return 0;
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
package io.gitlab.jfronny.libjf.config.impl.ui.tiny.entry;
|
||||
|
||||
import io.gitlab.jfronny.commons.Serializer;
|
||||
import io.gitlab.jfronny.commons.ref.R;
|
||||
import io.gitlab.jfronny.commons.serialize.Transport;
|
||||
import io.gitlab.jfronny.commons.serialize.databind.api.TypeToken;
|
||||
import io.gitlab.jfronny.commons.serialize.json.JsonReader;
|
||||
import io.gitlab.jfronny.commons.throwable.Try;
|
||||
import io.gitlab.jfronny.libjf.LibJf;
|
||||
|
@ -175,7 +173,7 @@ public class EntryInfoWidgetBuilder {
|
|||
final String jsonified;
|
||||
if (state.tempValue == null) {
|
||||
try {
|
||||
jsonified = LibJf.LENIENT_TRANSPORT.write(writer -> LibJf.MAPPER.serialize(state.cachedValue, writer));
|
||||
jsonified = LibJf.LENIENT_TRANSPORT.write(writer -> info.serializeOneTo(state.cachedValue, config.getTranslationPrefix(), writer));
|
||||
} catch (Throwable e) {
|
||||
LibJf.LOGGER.error("Could not stringify element", e);
|
||||
SystemToast.add(
|
||||
|
@ -199,9 +197,8 @@ public class EntryInfoWidgetBuilder {
|
|||
try {
|
||||
state.updateCache(LibJf.LENIENT_TRANSPORT.read(
|
||||
json,
|
||||
(Transport.Returnable<JsonReader, ? extends T, IOException>) reader -> LibJf.MAPPER
|
||||
.getAdapter((TypeToken<T>) TypeToken.get(info.getValueType().asClass()))
|
||||
.deserialize(reader)));
|
||||
(Transport.Returnable<JsonReader, ? extends T, IOException>) info::deserializeOneFrom
|
||||
));
|
||||
state.tempValue = null;
|
||||
} catch (Throwable e) {
|
||||
LibJf.LOGGER.error("Could not write element", e);
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
{
|
||||
"libjf-config-ui-tiny.entry.json.read.fail.title": "Could not read",
|
||||
"libjf-config-ui-tiny.entry.json.read.fail.description": "The given entry could not be stringified. Please edit the config manually"
|
||||
"libjf-config-ui-tiny.entry.json.read.fail.description": "The given entry could not be read from a string. Please edit the config manually",
|
||||
"libjf-config-ui-tiny.entry.json.write.fail.title": "Could not write",
|
||||
"libjf-config-ui-tiny.entry.json.write.fail.description": "The given entry could not be stringified. Please edit the config manually"
|
||||
}
|
|
@ -1,7 +1,10 @@
|
|||
package io.gitlab.jfronny.libjf.config.test.tiny;
|
||||
|
||||
import io.gitlab.jfronny.commons.data.String2ObjectMap;
|
||||
import io.gitlab.jfronny.commons.serialize.databind.api.TypeToken;
|
||||
import io.gitlab.jfronny.libjf.config.api.v2.JfCustomConfig;
|
||||
import io.gitlab.jfronny.libjf.config.api.v2.dsl.DSL;
|
||||
import io.gitlab.jfronny.libjf.config.api.v2.type.Type;
|
||||
|
||||
public class TestConfig implements JfCustomConfig {
|
||||
private int value1 = 0;
|
||||
|
@ -12,6 +15,7 @@ public class TestConfig implements JfCustomConfig {
|
|||
private int value4 = 0;
|
||||
private String value5 = "";
|
||||
private boolean value6 = false;
|
||||
private String2ObjectMap<String> map = new String2ObjectMap<>();
|
||||
|
||||
@Override
|
||||
public void register(DSL.Defaulted dsl) {
|
||||
|
@ -30,6 +34,8 @@ public class TestConfig implements JfCustomConfig {
|
|||
.value("value5", value5, () -> value5, v -> value5 = v)
|
||||
).category("ca6", builder1 -> builder1
|
||||
.value("value6", value6, () -> value6, v -> value6 = v)
|
||||
).category("ca7", builder1 -> builder1
|
||||
.value("mappy", map, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, Type.ofToken(new TypeToken<String2ObjectMap<String>>() {}), 100, () -> map, v -> map = v)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue