package io.gitlab.jfronny.respackopts.model.tree; import com.google.common.collect.ImmutableMap; import com.google.gson.reflect.TypeToken; import io.gitlab.jfronny.respackopts.Respackopts; import io.gitlab.jfronny.respackopts.model.enums.ConfigSyncMode; import io.gitlab.jfronny.respackopts.util.RpoFormatException; import me.shedaniel.clothconfig2.api.AbstractConfigListEntry; import me.shedaniel.clothconfig2.impl.builders.SubCategoryBuilder; import meteordevelopment.starscript.value.Value; import meteordevelopment.starscript.value.ValueMap; import java.util.LinkedHashMap; import java.util.Map; public class ConfigBranch extends ConfigEntry>> { public ConfigBranch() { super(new TypeToken>>(){}.getRawType()); setValue(new LinkedHashMap<>()); } public boolean getBoolean(String name) throws RpoFormatException { String[] sp = name.split("\\."); if (!super.getValue().containsKey(sp[0])) throw new RpoFormatException("Invalid path to key in " + getName() + ": " + name); ConfigEntry e = super.getValue().get(sp[0]); if (sp.length == 1) { if (e instanceof ConfigBooleanEntry b) return b.getValue(); throw new RpoFormatException("Not a boolean in " + getName()); } if (sp.length == 2 && e instanceof ConfigEnumEntry en) { for (String entry : en.values) { if (entry.equals(sp[1])) return entry.equals(en.getValue()); } throw new RpoFormatException("Could not find enum entry in " + getName()); } if (e instanceof ConfigBranch b) return b.getBoolean(name.substring(name.indexOf('.') + 1)); throw new RpoFormatException("Invalid path to key in " + getName()); } @Override public void sync(ConfigEntry>> source, ConfigSyncMode mode) { for (Map.Entry> e : source.getValue().entrySet()) { if (!has(e.getKey())) { if (mode == ConfigSyncMode.RESPACK_LOAD) add(e.getKey(), e.getValue().clone()); } else { ConfigEntry current = get(e.getKey()); if (e.getValue().getEntryClass().equals(current.getEntryClass())) { syncSub(current, (ConfigEntry)e.getValue(), mode); } else { if (mode == ConfigSyncMode.RESPACK_LOAD) { Respackopts.LOGGER.warn("Type mismatch in config (" + getName() + "), overwriting"); add(e.getKey(), e.getValue().clone()); } else Respackopts.LOGGER.warn("Type mismatch in config (" + getName() + "), ignoring"); } } } if (mode == ConfigSyncMode.RESPACK_LOAD) for (Map.Entry> e : getValue().entrySet()) { if (!source.getValue().containsKey(e.getKey())) super.getValue().remove(e.getKey()); } } private void syncSub(ConfigEntry current, ConfigEntry next, ConfigSyncMode mode) { current.sync(next, mode); } public void add(String name, ConfigEntry val) { val.setVersion(version); val.parent = this; super.getValue().put(name, val); } public ConfigEntry get(String key) { return super.getValue().get(key); } public String getEntryName(ConfigEntry entry) { for (Map.Entry> e : getValue().entrySet()) { if (e.getValue() == entry) return e.getKey(); } throw new IndexOutOfBoundsException(); } public boolean has(String key) { return super.getValue().containsKey(key); } @Override public Map> getValue() { return ImmutableMap.copyOf(super.getValue()); } @Override public void buildShader(StringBuilder sb, String valueName) { for (Map.Entry> e : super.getValue().entrySet()) { e.getValue().buildShader(sb, valueName + "_" + Respackopts.sanitizeString(e.getKey())); } } @Override public Value buildStarscript() { ValueMap vm = new ValueMap(); for (Map.Entry> e : super.getValue().entrySet()) { vm.set(Respackopts.sanitizeString(e.getKey()), () -> e.getValue().buildStarscript()); } return Value.map(vm); } @Override public AbstractConfigListEntry buildEntry(GuiEntryBuilderParam guiEntryBuilderParam) { SubCategoryBuilder sc = guiEntryBuilderParam.entryBuilder().startSubCategory(guiEntryBuilderParam.name()); Respackopts.GUI_FACTORY.buildCategory(this, guiEntryBuilderParam.screenId(), sc::add, guiEntryBuilderParam.agg(), guiEntryBuilderParam.entryBuilder(), guiEntryBuilderParam.entryName()); sc.setTooltipSupplier(guiEntryBuilderParam.tooltipSupplier()); return sc.build(); } @Override public String getEntryType() { return "title"; } @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()); } } @Override public ConfigBranch clone() { ConfigBranch branch = new ConfigBranch(); for (Map.Entry> e : getValue().entrySet()) { branch.add(e.getKey(), e.getValue().clone()); } return branch; } @Override public void setVersion(int version) { super.setVersion(version); for (ConfigEntry value : getValue().values()) { value.setVersion(version); } } }