From a3721174d95a1fb50f606acd128c604619364c5a Mon Sep 17 00:00:00 2001 From: JFronny Date: Thu, 10 Jun 2021 14:55:03 +0200 Subject: [PATCH] Some more work, still doesn't work --- .../jfronny/respackopts/GuiFactory.java | 40 +++---- .../jfronny/respackopts/Respackopts.java | 10 +- .../respackopts/data/ConfigBooleanEntry.java | 7 +- .../respackopts/data/ConfigBranch.java | 106 +++++++++--------- .../respackopts/data/ConfigEnumEntry.java | 51 ++++++++- .../respackopts/data/ConfigNumericEntry.java | 31 ++++- .../jfronny/respackopts/data/Entry.java | 43 ++++++- .../jfronny/respackopts/data/SyncMode.java | 16 +++ .../gson/BooleanEntrySerializer.java | 2 +- .../gson/ConfigBranchSerializer.java | 9 +- .../respackopts/gson/EnumEntrySerializer.java | 9 +- .../gson/LegacyConfigDeserializer.java | 3 +- .../gson/NumericEntrySerializer.java | 8 +- .../mixin/ResourcePackManagerMixin.java | 5 +- 14 files changed, 233 insertions(+), 107 deletions(-) create mode 100644 src/main/java/io/gitlab/jfronny/respackopts/data/SyncMode.java diff --git a/src/main/java/io/gitlab/jfronny/respackopts/GuiFactory.java b/src/main/java/io/gitlab/jfronny/respackopts/GuiFactory.java index 03b8701..cf2b992 100644 --- a/src/main/java/io/gitlab/jfronny/respackopts/GuiFactory.java +++ b/src/main/java/io/gitlab/jfronny/respackopts/GuiFactory.java @@ -23,7 +23,7 @@ import java.util.Optional; public class GuiFactory { public void buildCategory(ConfigBranch source, String screenId, JfConfigCategory config, ConfigEntryBuilder entryBuilder, String namePrefix) { String b = "respackopts.field." + screenId; - for (Map.Entry> in : source.getEntries()) { + for (Map.Entry> in : source.getValue().entrySet()) { Entry entry = in.getValue(); String n = ("".equals(namePrefix) ? "" : namePrefix + ".") + in.getKey(); if (entry instanceof ConfigBranch e) { @@ -33,50 +33,36 @@ public class GuiFactory { config.addEntry(sc.build()); } else if (entry instanceof ConfigBooleanEntry e) { - config.addEntry(entryBuilder.startBooleanToggle(getText(n, b), e.value) - .setDefaultValue(e.defaultValue) - .setSaveConsumer(v -> { - /*ConfigBooleanEntry cb = (ConfigBooleanEntry)source.get(e.name); - cb.value = v; - Respackopts.LOGGER.info(cb == e); - Respackopts.LOGGER.info(cb == entry);*/ - e.value = v; - }) + config.addEntry(entryBuilder.startBooleanToggle(getText(n, b), e.getValue()) + .setDefaultValue(e.getDefault()) + .setSaveConsumer(e::setValue) .setTooltipSupplier(() -> getTooltip(n, screenId)) .build()); } else if (entry instanceof ConfigEnumEntry e) { - String selected = ""; - String def = ""; - for (Map.Entry en : e.values.entrySet()) { - if (en.getValue().equals(e.value)) - selected = en.getKey(); - if (en.getValue().equals(e.defaultValue)) - def = en.getKey(); - } config.addEntry(entryBuilder.startDropdownMenu(getText(n, b), - DropdownMenuBuilder.TopCellElementBuilder.of(selected, LiteralText::new), + DropdownMenuBuilder.TopCellElementBuilder.of(e.getValueName(), LiteralText::new), new DropdownBoxEntry.DefaultSelectionCellCreator()) .setSuggestionMode(false) - .setDefaultValue(def) + .setDefaultValue(e.getDefaultName()) .setSelections(() -> e.values.keySet().iterator()) - .setSaveConsumer(v -> e.value = e.values.get(v)) + .setSaveConsumer(v -> e.setValue(e.values.get(v))) .setTooltipSupplier(() -> getTooltip(n, screenId)) .build()); } else if (entry instanceof ConfigNumericEntry e) { if (e.min != null && e.max != null) { config.addEntry(entryBuilder.startIntSlider(getText(n, b), - e.value.intValue(), e.min.intValue(), e.max.intValue()) - .setDefaultValue(e.defaultValue.intValue()) - .setSaveConsumer(v -> e.value = v.doubleValue()) + e.getValue().intValue(), e.min.intValue(), e.max.intValue()) + .setDefaultValue(e.getDefault().intValue()) + .setSaveConsumer(v -> e.setValue(v.doubleValue())) .setTooltipSupplier(() -> getTooltip(n, screenId)) .build()); } else { - config.addEntry(entryBuilder.startDoubleField(getText(n, b), e.value) - .setDefaultValue(e.defaultValue) - .setSaveConsumer(v -> e.value = v) + config.addEntry(entryBuilder.startDoubleField(getText(n, b), e.getValue()) + .setDefaultValue(e.getDefault()) + .setSaveConsumer(e::setValue) .setTooltipSupplier(() -> getTooltip(n, screenId)) .build()); } diff --git a/src/main/java/io/gitlab/jfronny/respackopts/Respackopts.java b/src/main/java/io/gitlab/jfronny/respackopts/Respackopts.java index 9d99353..5b9c06d 100644 --- a/src/main/java/io/gitlab/jfronny/respackopts/Respackopts.java +++ b/src/main/java/io/gitlab/jfronny/respackopts/Respackopts.java @@ -3,10 +3,7 @@ package io.gitlab.jfronny.respackopts; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.reflect.TypeToken; -import io.gitlab.jfronny.respackopts.data.ConfigBooleanEntry; -import io.gitlab.jfronny.respackopts.data.ConfigBranch; -import io.gitlab.jfronny.respackopts.data.ConfigEnumEntry; -import io.gitlab.jfronny.respackopts.data.ConfigNumericEntry; +import io.gitlab.jfronny.respackopts.data.*; import io.gitlab.jfronny.respackopts.data.in.Respackmeta; import io.gitlab.jfronny.respackopts.filters.conditions.SyntaxError; import io.gitlab.jfronny.respackopts.gson.BooleanEntrySerializer; @@ -67,6 +64,7 @@ public class Respackopts implements ClientModInitializer { public static void save() { for (String s : resPackMetas.keySet()) { s = resPackMetas.get(s).id; + LOGGER.info(s + ": " + CONFIG_BRANCH.get(s)); try (Writer writer = Files.newBufferedWriter(CONF_DIR.resolve(s + ".json"))) { GSON.toJson(CONFIG_BRANCH.get(s), writer); writer.flush(); @@ -85,10 +83,10 @@ public class Respackopts implements ClientModInitializer { try (Reader reader = Files.newBufferedReader(q)) { ConfigBranch b = GSON.fromJson(reader, ConfigBranch.class); if (CONFIG_BRANCH.containsKey(id)) - CONFIG_BRANCH.get(id).loadValues(b, false); + CONFIG_BRANCH.get(id).sync(b, SyncMode.CONF_LOAD); else CONFIG_BRANCH.put(id, b); - } catch (IOException | SyntaxError e) { + } catch (IOException e) { LOGGER.error("Failed to load " + id, e); } } diff --git a/src/main/java/io/gitlab/jfronny/respackopts/data/ConfigBooleanEntry.java b/src/main/java/io/gitlab/jfronny/respackopts/data/ConfigBooleanEntry.java index eb1b456..c8c8f36 100644 --- a/src/main/java/io/gitlab/jfronny/respackopts/data/ConfigBooleanEntry.java +++ b/src/main/java/io/gitlab/jfronny/respackopts/data/ConfigBooleanEntry.java @@ -2,6 +2,11 @@ package io.gitlab.jfronny.respackopts.data; public class ConfigBooleanEntry extends Entry { public ConfigBooleanEntry(boolean v) { - value = v; + setValue(v); + } + + @Override + public boolean typeMatches(Entry val) { + return val instanceof ConfigBooleanEntry; } } diff --git a/src/main/java/io/gitlab/jfronny/respackopts/data/ConfigBranch.java b/src/main/java/io/gitlab/jfronny/respackopts/data/ConfigBranch.java index b3882dc..45db607 100644 --- a/src/main/java/io/gitlab/jfronny/respackopts/data/ConfigBranch.java +++ b/src/main/java/io/gitlab/jfronny/respackopts/data/ConfigBranch.java @@ -1,30 +1,31 @@ package io.gitlab.jfronny.respackopts.data; +import com.google.common.collect.ImmutableMap; +import io.gitlab.jfronny.respackopts.Respackopts; import io.gitlab.jfronny.respackopts.filters.conditions.SyntaxError; -import java.io.InvalidClassException; -import java.util.ArrayList; import java.util.HashMap; import java.util.Map; -import java.util.Set; -public class ConfigBranch extends Entry { - private final Map> entries = new HashMap<>(); +public class ConfigBranch extends Entry>> { + public ConfigBranch() { + setValue(new HashMap<>()); + } public boolean getBoolean(String name) throws SyntaxError { String[] sp = name.split("\\."); - if (!entries.containsKey(sp[0])) + if (!super.getValue().containsKey(sp[0])) throw new SyntaxError("Invalid path to key"); - Entry e = entries.get(sp[0]); + Entry e = super.getValue().get(sp[0]); if (sp.length == 1) { if (e instanceof ConfigBooleanEntry b) - return b.value; + return b.getValue(); throw new SyntaxError("Not a boolean"); } if (sp.length == 2 && e instanceof ConfigEnumEntry en) { for (Map.Entry entry : en.values.entrySet()) { if (entry.getKey().equals(sp[1])) - return entry.getValue().equals(en.value); + return entry.getValue().equals(en.getValue()); } throw new SyntaxError("Could not find enum entry"); } @@ -33,73 +34,62 @@ public class ConfigBranch extends Entry { throw new SyntaxError("Invalid path to key"); } - public void loadValues(ConfigBranch newBranch, boolean additionOnly) throws SyntaxError { - for (Map.Entry> e : newBranch.entries.entrySet()) { - if (!entries.containsKey(e.getKey())) - add(e.getKey(), e.getValue()); - else if (!additionOnly) { - if (e.getValue() instanceof ConfigEnumEntry ne) { - ConfigEnumEntry ol = (ConfigEnumEntry)entries.get(e.getKey()); - if (ne.value != null) - ol.value = ne.value; - if (ne.values != null && !ne.values.isEmpty()) - ol.values = ne.values; - } - else if (e.getValue() instanceof ConfigBooleanEntry ne) { - ConfigBooleanEntry ol = (ConfigBooleanEntry)entries.get(e.getKey()); - if (ne.value != null) - ol.value = ne.value; - } - else if (e.getValue() instanceof ConfigNumericEntry ne) { - ConfigNumericEntry ol = (ConfigNumericEntry)entries.get(e.getKey()); - if (ne.value != null) - ol.value = ne.value; - if (ne.min != null) - ol.min = ne.min; - if (ne.max != null) - ol.max = ne.max; - } - else if (e.getValue() instanceof ConfigBranch ne) { - ConfigBranch ol = (ConfigBranch)entries.get(e.getKey()); - ol.loadValues(ne, false); + @Override + public void sync(Entry>> source, SyncMode mode) { + for (Map.Entry> e : source.getValue().entrySet()) { + if (!has(e.getKey())) { + if (mode.isAdd) + add(e.getKey(), e.getValue()); + } else { + Entry current = get(e.getKey()); + if (e.getValue().typeMatches(current)) { + syncSub(current, (Entry)e.getValue(), mode); } else { - throw new SyntaxError("Invalid type"); + Respackopts.LOGGER.warn("Type mismatch in config, ignoring"); } } } } - public , T2> T add(String name, T val) { - val.name = name; - val.defaultValue = val.value; - entries.put(name, val); - return val; + @Override + public boolean typeMatches(Entry val) { + return val instanceof ConfigBranch; + } + + private void syncSub(Entry current, Entry next, SyncMode mode) { + current.sync(next, mode); + } + + public void add(String name, Entry val) { + val.setDefault(val.getValue()); + super.getValue().put(name, val); } public Entry get(String key) { - return entries.get(key); + return super.getValue().get(key); } public boolean has(String key) { - return entries.containsKey(key); + return super.getValue().containsKey(key); } - public Set>> getEntries() { - return entries.entrySet(); + @Override + public Map> getValue() { + return ImmutableMap.copyOf(super.getValue()); } - + public void buildShader(StringBuilder sb, String valuePrefix) throws SyntaxError { - for (Map.Entry> e : entries.entrySet()) { + for (Map.Entry> e : super.getValue().entrySet()) { if (e.getValue() instanceof ConfigNumericEntry n) { sb.append("\n#define "); sb.append(valuePrefix); sb.append(e.getKey()); sb.append(' '); - sb.append(n.value.toString()); + sb.append(n.getValue().toString()); } else if (e.getValue() instanceof ConfigBooleanEntry n) { - if (n.value) { + if (n.getValue()) { sb.append("\n#define "); sb.append(valuePrefix); sb.append(e.getKey()); @@ -110,7 +100,7 @@ public class ConfigBranch extends Entry { sb.append(valuePrefix); sb.append(e.getKey()); sb.append(' '); - sb.append(n.value.toString()); + sb.append(n.getValue().toString()); for (Map.Entry e2 : n.values.entrySet()) { sb.append("\n#define "); sb.append(valuePrefix); @@ -129,4 +119,14 @@ public class ConfigBranch extends Entry { } } } + + @Override + public void appendString(StringBuilder sb) { + for (Map.Entry> e : getValue().entrySet()) { + sb.append("\n"); + sb.append(e.getKey()); + sb.append(": "); + sb.append(e.getValue()); + } + } } diff --git a/src/main/java/io/gitlab/jfronny/respackopts/data/ConfigEnumEntry.java b/src/main/java/io/gitlab/jfronny/respackopts/data/ConfigEnumEntry.java index 4d43136..6773bf4 100644 --- a/src/main/java/io/gitlab/jfronny/respackopts/data/ConfigEnumEntry.java +++ b/src/main/java/io/gitlab/jfronny/respackopts/data/ConfigEnumEntry.java @@ -5,8 +5,57 @@ import java.util.Map; public class ConfigEnumEntry extends Entry { public Map values = new HashMap<>(); + private String fieldName; public ConfigEnumEntry() { - value = 0; + setValue(0); + } + + @Override + public Integer getValue() { + Integer v = super.getValue(); + if (v == null) + throw new NullPointerException(); + return v; + } + + @Override + public void sync(Entry source, SyncMode mode) { + super.sync(source, mode); + ConfigEnumEntry n = (ConfigEnumEntry) source; + if (mode.modifyDefault) { + if (n.values != null && !n.values.isEmpty()) + values = n.values; + } + if (mode.modifyValue) { + if (n.fieldName != null) + setValue(values.get(n.fieldName)); + } + } + + @Override + public boolean typeMatches(Entry val) { + return val instanceof ConfigEnumEntry; + } + + public void setFieldName(String s) { + if (s != null) + fieldName = s; + } + + public String getValueName() { + for (Map.Entry en : values.entrySet()) { + if (en.getValue().equals(getValue())) + return en.getKey(); + } + return getDefaultName(); + } + + public String getDefaultName() { + for (Map.Entry en : values.entrySet()) { + if (en.getValue().equals(getDefault())) + return en.getKey(); + } + throw new NullPointerException(); } } diff --git a/src/main/java/io/gitlab/jfronny/respackopts/data/ConfigNumericEntry.java b/src/main/java/io/gitlab/jfronny/respackopts/data/ConfigNumericEntry.java index d3869ef..2f4e3e1 100644 --- a/src/main/java/io/gitlab/jfronny/respackopts/data/ConfigNumericEntry.java +++ b/src/main/java/io/gitlab/jfronny/respackopts/data/ConfigNumericEntry.java @@ -5,6 +5,35 @@ public class ConfigNumericEntry extends Entry { public Double max; public ConfigNumericEntry() { - value = 0d; + setValue(0d); + } + + @Override + public void sync(Entry source, SyncMode mode) { + super.sync(source, mode); + ConfigNumericEntry n = (ConfigNumericEntry) source; + if (mode.modifyDefault) { + if (n.min != null) + min = n.min; + if (n.max != null) + max = n.max; + } + } + + @Override + public boolean typeMatches(Entry val) { + return val instanceof ConfigNumericEntry; + } + + @Override + public void appendString(StringBuilder sb) { + sb.append(getValue()) + .append(" (") + .append(getDefault()) + .append(", ") + .append(min) + .append("-") + .append(max) + .append(")"); } } diff --git a/src/main/java/io/gitlab/jfronny/respackopts/data/Entry.java b/src/main/java/io/gitlab/jfronny/respackopts/data/Entry.java index d9f9120..95a6f41 100644 --- a/src/main/java/io/gitlab/jfronny/respackopts/data/Entry.java +++ b/src/main/java/io/gitlab/jfronny/respackopts/data/Entry.java @@ -1,7 +1,44 @@ package io.gitlab.jfronny.respackopts.data; public abstract class Entry { - public String name; - public T defaultValue; - public T value; + private T defaultValue; + private T value; + + public T getValue() { + return value; + } + + public void setValue(T value) { + if (value != null) + this.value = value; + } + + public T getDefault() { + return defaultValue; + } + + public void setDefault(T value) { + if (value != null) + defaultValue = value; + } + + public void sync(Entry source, SyncMode mode) { + if (mode.modifyDefault) + setDefault(source.getDefault()); + if (mode.modifyValue) + setValue(source.getValue()); + } + + public abstract boolean typeMatches(Entry val); + + public void appendString(StringBuilder sb) { + sb.append(value + " (" + defaultValue + ")"); + } + + @Override + public String toString() { + StringBuilder log = new StringBuilder(); + appendString(log); + return log.toString(); + } } diff --git a/src/main/java/io/gitlab/jfronny/respackopts/data/SyncMode.java b/src/main/java/io/gitlab/jfronny/respackopts/data/SyncMode.java new file mode 100644 index 0000000..08861b4 --- /dev/null +++ b/src/main/java/io/gitlab/jfronny/respackopts/data/SyncMode.java @@ -0,0 +1,16 @@ +package io.gitlab.jfronny.respackopts.data; + +public class SyncMode { + public static final SyncMode RESPACK_LOAD = new SyncMode(false, true, true); + public static final SyncMode CONF_LOAD = new SyncMode(true, false, false); + + public final boolean modifyValue; + public final boolean modifyDefault; + public final boolean isAdd; + + private SyncMode(boolean modifyValue, boolean modifyDefault, boolean isAdd) { + this.modifyValue = modifyValue; + this.modifyDefault = modifyDefault; + this.isAdd = isAdd; + } +} diff --git a/src/main/java/io/gitlab/jfronny/respackopts/gson/BooleanEntrySerializer.java b/src/main/java/io/gitlab/jfronny/respackopts/gson/BooleanEntrySerializer.java index 190e295..c65c028 100644 --- a/src/main/java/io/gitlab/jfronny/respackopts/gson/BooleanEntrySerializer.java +++ b/src/main/java/io/gitlab/jfronny/respackopts/gson/BooleanEntrySerializer.java @@ -13,6 +13,6 @@ public class BooleanEntrySerializer implements JsonSerializer, Jso @Override public JsonElement serialize(ConfigBranch src, Type typeOfSrc, JsonSerializationContext context) { JsonObject o = new JsonObject(); - for (Map.Entry> entry : src.getEntries()) { + for (Map.Entry> entry : src.getValue().entrySet()) { o.add(entry.getKey(), context.serialize(entry.getValue())); } return o; @@ -34,11 +34,10 @@ public class ConfigBranchSerializer implements JsonSerializer, Jso JsonPrimitive p = j.getAsJsonPrimitive(); if (p.isBoolean()) cbNew.add(s, new ConfigBooleanEntry(p.getAsBoolean())); - else if (p.isNumber()) { - //TODO identify saved enum values - use string? + else if (p.isNumber()) cbNew.add(s, context.deserialize(j, ConfigNumericEntry.class)); - } else if (p.isString()) - throw new JsonSyntaxException("String primitives are not currently supported"); + else if (p.isString()) + cbNew.add(s, context.deserialize(j, ConfigEnumEntry.class)); } else if (j.isJsonArray()) cbNew.add(s, context.deserialize(j, ConfigEnumEntry.class)); diff --git a/src/main/java/io/gitlab/jfronny/respackopts/gson/EnumEntrySerializer.java b/src/main/java/io/gitlab/jfronny/respackopts/gson/EnumEntrySerializer.java index f333cb6..aeefae7 100644 --- a/src/main/java/io/gitlab/jfronny/respackopts/gson/EnumEntrySerializer.java +++ b/src/main/java/io/gitlab/jfronny/respackopts/gson/EnumEntrySerializer.java @@ -9,7 +9,7 @@ import java.util.HashMap; public class EnumEntrySerializer implements JsonSerializer, JsonDeserializer { @Override public JsonElement serialize(ConfigEnumEntry src, Type typeOfSrc, JsonSerializationContext context) { - return new JsonPrimitive(src.value == null ? 0 : src.value); + return new JsonPrimitive(src.getValueName()); } @Override @@ -18,7 +18,12 @@ public class EnumEntrySerializer implements JsonSerializer, Jso if (json.isJsonPrimitive()) { JsonPrimitive jp = json.getAsJsonPrimitive(); if (jp.isNumber()) { - result.value = jp.getAsInt(); + result.setValue(jp.getAsInt()); + result.setDefault(jp.getAsInt()); + return result; + } + else if (jp.isString()) { + result.setFieldName(jp.getAsString()); return result; } else diff --git a/src/main/java/io/gitlab/jfronny/respackopts/gson/LegacyConfigDeserializer.java b/src/main/java/io/gitlab/jfronny/respackopts/gson/LegacyConfigDeserializer.java index f831d9c..6af8275 100644 --- a/src/main/java/io/gitlab/jfronny/respackopts/gson/LegacyConfigDeserializer.java +++ b/src/main/java/io/gitlab/jfronny/respackopts/gson/LegacyConfigDeserializer.java @@ -28,7 +28,8 @@ public class LegacyConfigDeserializer { } for (Map.Entry e : lc.doubles.entrySet()) { ConfigNumericEntry ne = new ConfigNumericEntry(); - ne.value = e.getValue(); + ne.setValue(e.getValue()); + ne.setDefault(e.getValue()); int i = e.getKey().lastIndexOf('.'); if (i == -1) cb.add(e.getKey(), ne); diff --git a/src/main/java/io/gitlab/jfronny/respackopts/gson/NumericEntrySerializer.java b/src/main/java/io/gitlab/jfronny/respackopts/gson/NumericEntrySerializer.java index 2e32f51..8903d5b 100644 --- a/src/main/java/io/gitlab/jfronny/respackopts/gson/NumericEntrySerializer.java +++ b/src/main/java/io/gitlab/jfronny/respackopts/gson/NumericEntrySerializer.java @@ -8,13 +8,14 @@ import java.lang.reflect.Type; public class NumericEntrySerializer implements JsonSerializer, JsonDeserializer { @Override public JsonElement serialize(ConfigNumericEntry src, Type typeOfSrc, JsonSerializationContext context) { - return new JsonPrimitive(src.value); + return new JsonPrimitive(src.getValue()); } @Override public ConfigNumericEntry deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { ConfigNumericEntry result = new ConfigNumericEntry(); if (json.isJsonPrimitive() && json.getAsJsonPrimitive().isNumber()) { - result.value = json.getAsDouble(); + result.setValue(json.getAsDouble()); + result.setDefault(json.getAsDouble()); return result; } else if (isSlider(json)) { @@ -32,7 +33,8 @@ public class NumericEntrySerializer implements JsonSerializer