feat: support string entries

While these are not as useful, they are supported as native types in muScript and take no effort to support
This commit is contained in:
Johannes Frohnmeyer 2024-05-18 18:54:38 +02:00
parent 08a205f828
commit 3078a4d7fa
Signed by: Johannes
GPG Key ID: E76429612C2929F4
6 changed files with 119 additions and 1 deletions

View File

@ -10,6 +10,12 @@ Every entry can contain the following properties, regardless of its type:
| default | yes | The default value for this entry. This is what you would specify in a normal config entry (except for enums, where this is just the default entries name) |
| reloadType | no | `"Resource"` or `"Simple"`, specifies whether resources have to be reloaded if this is changed. Frex shaders will be reloaded anyways |
## Strings
These entries will be displayed as text boxes. They can be used to drive any in-game text you might want to make configurable.
Their type is `string` or `text`.
They are most useful in combination with [Resource Expansion](../additional/ResourceExpansion.md), but you can also access them in your conditions.
See the muScript standard library documentation for more info on how to use and manipulate them.
## Numbers
There are two ways to display numbers: input boxes and sliders.
Any number input that provides a minimum and maximum value will be displayed as a slider instead of a box.

View File

@ -2,7 +2,7 @@
"conditions": "lumi.subcategoryTest.enableLang & (!subcategoryTest.enableLangForceDisable) & version('respackopts', '*')",
"fallback": "assets/minecraft/lang/en_us_joke.json",
"expansions": {
"Lights": "lumi.subcategoryTest.enableLang",
"Lights": "lumi.subcategoryTest.enableLang || lumi.someString",
"Mode": "lumi.debugMode",
"Normal": "lumi.numTest * lumi.subcategoryTest.numberInSub",
"Lumi": "'model'",

View File

@ -18,6 +18,10 @@
"normal",
"viewDir"
],
someString: {
type: "string",
default: "This is a Value?"
},
waterVertexWavy: false,
numTest: 15.4,
oakFence: {

View File

@ -12,6 +12,7 @@ import io.gitlab.jfronny.respackopts.Respackopts;
import io.gitlab.jfronny.respackopts.gson.entry.BooleanEntrySerializer;
import io.gitlab.jfronny.respackopts.gson.entry.EnumEntrySerializer;
import io.gitlab.jfronny.respackopts.gson.entry.NumericEntrySerializer;
import io.gitlab.jfronny.respackopts.gson.entry.StringEntrySerializer;
import io.gitlab.jfronny.respackopts.model.tree.*;
@SerializerFor(targets = ConfigEntry.class)
@ -23,6 +24,7 @@ public class ConfigEntryTypeAdapter extends TypeAdapter<ConfigEntry<?>> {
case ConfigNumericEntry num -> GC_ConfigNumericEntry.serialize(num, writer);
case ConfigEnumEntry en -> GC_ConfigEnumEntry.serialize(en, writer);
case ConfigBranch br -> GC_ConfigBranch.serialize(br, writer);
case ConfigStringEntry str -> GC_ConfigStringEntry.serialize(str, writer);
default -> throw new MalformedDataException("Unknown entry type: " + entry.getClass().getName());
}
}
@ -58,6 +60,8 @@ public class ConfigEntryTypeAdapter extends TypeAdapter<ConfigEntry<?>> {
entry = NumericEntrySerializer.INT_TYPES.contains(type) ? e.asInteger() : e;
} else if (EnumEntrySerializer.TYPES.contains(type)) {
entry = GC_ConfigEnumEntry.deserialize(new EmulatedReader(de));
} else if (StringEntrySerializer.TYPES.contains(type)) {
entry = GC_ConfigStringEntry.deserialize(new EmulatedReader(de));
} else {
throw new MalformedDataException("Invalid type for entry: " + type);
}

View File

@ -0,0 +1,53 @@
package io.gitlab.jfronny.respackopts.gson.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.commons.serialize.Token;
import io.gitlab.jfronny.commons.serialize.databind.api.SerializerFor;
import io.gitlab.jfronny.commons.serialize.databind.api.TypeAdapter;
import io.gitlab.jfronny.respackopts.model.enums.PackReloadType;
import io.gitlab.jfronny.respackopts.model.tree.ConfigBooleanEntry;
import io.gitlab.jfronny.respackopts.model.tree.ConfigEntry;
import io.gitlab.jfronny.respackopts.model.tree.ConfigStringEntry;
import java.util.Set;
@SerializerFor(targets = ConfigBooleanEntry.class)
public class StringEntrySerializer extends TypeAdapter<ConfigStringEntry> {
public static final Set<String> TYPES = Set.of("string", "text");
@Override
public <TEx extends Exception, Writer extends SerializeWriter<TEx, Writer>> void serialize(ConfigStringEntry configBooleanEntry, Writer writer) throws TEx, MalformedDataException {
writer.value(configBooleanEntry.getValue());
}
@Override
public <TEx extends Exception, Reader extends SerializeReader<TEx, Reader>> ConfigStringEntry deserialize(Reader reader) throws TEx, MalformedDataException {
if (reader.peek() == Token.BEGIN_OBJECT) {
reader.beginObject();
ConfigStringEntry result = new ConfigStringEntry("");
while (reader.hasNext()) {
String key = reader.nextName();
switch (key) {
case "type" -> {
if (!TYPES.contains(reader.nextString())) {
throw new MalformedDataException("Invalid type for string entry");
}
}
case "default" -> {
String value = reader.nextString();
result.setDefault(value);
result.setValue(value);
}
case "reloadType" -> result.setReloadType(PackReloadType.valueOf(reader.nextString()));
default -> throw new MalformedDataException("Unknown key in string entry: " + key);
};
}
reader.endObject();
return result;
} else {
throw new MalformedDataException("Invalid data type for string entry");
}
}
}

View File

@ -0,0 +1,51 @@
package io.gitlab.jfronny.respackopts.model.tree;
import io.gitlab.jfronny.commons.serialize.databind.api.SerializeWithAdapter;
import io.gitlab.jfronny.libjf.config.api.v2.dsl.CategoryBuilder;
import io.gitlab.jfronny.muscript.data.dynamic.DString;
import io.gitlab.jfronny.respackopts.Respackopts;
import io.gitlab.jfronny.respackopts.RespackoptsConfig;
import io.gitlab.jfronny.respackopts.gson.entry.StringEntrySerializer;
import java.util.Objects;
@SerializeWithAdapter(adapter = StringEntrySerializer.class)
public class ConfigStringEntry extends ConfigEntry<String> implements DString {
public ConfigStringEntry(String v) {
super(String.class);
setValue(v);
setDefault(v);
}
@Override
public ConfigEntry<String> clone() {
ConfigStringEntry be = new ConfigStringEntry(getValue());
be.setDefault(getDefault());
return be;
}
@Override
public void buildShader(StringBuilder sb, String valueName) {
}
@Override
public CategoryBuilder<?> buildEntry(GuiEntryBuilderParam args) {
return args.builder().value(args.name(), getDefault(), this::getValue, v -> {
if (!Objects.equals(getValue(), v)) {
if (RespackoptsConfig.debugLogs) Respackopts.LOGGER.info("ConfigStringEntry SaveCallback");
args.saveCallback();
}
setValue(v);
});
}
@Override
public boolean equals(Object o) {
return super.equals(o) && o instanceof ConfigStringEntry cb && getValue().equals(cb.getValue()) && getDefault().equals(cb.getDefault());
}
@Override
public int hashCode() {
return Objects.hash(super.hashCode(), getValue(), getDefault());
}
}