Respackopts/src/main/java/io/gitlab/jfronny/respackopts/model/tree/ConfigBranch.java

158 lines
5.9 KiB
Java

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<Map<String, ConfigEntry<?>>> {
public ConfigBranch() {
super(new TypeToken<Map<String, ConfigEntry<?>>>(){}.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<Map<String, ConfigEntry<?>>> source, ConfigSyncMode mode) {
for (Map.Entry<String, ConfigEntry<?>> 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<String, ConfigEntry<?>> e : getValue().entrySet()) {
if (!source.getValue().containsKey(e.getKey()))
super.getValue().remove(e.getKey());
}
}
private <T> void syncSub(ConfigEntry<T> current, ConfigEntry<T> next, ConfigSyncMode mode) {
current.sync(next, mode);
}
public <T> void add(String name, ConfigEntry<T> 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<String, ConfigEntry<?>> 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<String, ConfigEntry<?>> getValue() {
return ImmutableMap.copyOf(super.getValue());
}
@Override
public void buildShader(StringBuilder sb, String valueName) {
for (Map.Entry<String, ConfigEntry<?>> e : super.getValue().entrySet()) {
e.getValue().buildShader(sb, valueName + "_" + Respackopts.sanitizeString(e.getKey()));
}
}
@Override
public Value buildStarscript() {
ValueMap vm = new ValueMap();
for (Map.Entry<String, ConfigEntry<?>> 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<String, ConfigEntry<?>> 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<String, ConfigEntry<?>> 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);
}
}
}