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

180 lines
6.8 KiB
Java

package io.gitlab.jfronny.respackopts.model.tree;
import com.google.common.collect.ImmutableMap;
import io.gitlab.jfronny.muscript.data.dynamic.*;
import io.gitlab.jfronny.gson.reflect.TypeToken;
import io.gitlab.jfronny.libjf.config.api.v1.dsl.CategoryBuilder;
import io.gitlab.jfronny.libjf.config.api.v1.dsl.ConfigBuilder;
import io.gitlab.jfronny.respackopts.Respackopts;
import io.gitlab.jfronny.respackopts.integration.SaveHook;
import io.gitlab.jfronny.respackopts.RespackoptsConfig;
import io.gitlab.jfronny.respackopts.model.enums.ConfigSyncMode;
import io.gitlab.jfronny.respackopts.model.enums.PackReloadType;
import io.gitlab.jfronny.respackopts.util.IndentingStringBuilder;
import io.gitlab.jfronny.respackopts.util.MetaCache;
import java.nio.file.Path;
import java.util.*;
public class ConfigBranch extends ConfigEntry<Map<String, ConfigEntry<?>>> {
public ConfigBranch() {
super(new TypeToken<Map<String, ConfigEntry<?>>>(){}.getRawType());
setValue(new LinkedHashMap<>());
}
@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 DObject getDynamic() {
Map<String, Dynamic<?>> map = new HashMap<>();
for (Map.Entry<String, ConfigEntry<?>> e : super.getValue().entrySet()) {
map.put(Respackopts.sanitizeString(e.getKey()), e.getValue().getDynamic());
}
return DFinal.of(map);
}
@Override
public CategoryBuilder<?> buildEntry(GuiEntryBuilderParam builder) {
return builder.builder().category(builder.name(), cb -> {
for (Map.Entry<String, ConfigEntry<?>> e : getValue().entrySet()) {
e.getValue().buildEntry(new GuiEntryBuilderParam(cb, e.getKey(), builder.onSave()));
}
return cb;
});
}
public <T extends ConfigBuilder<?>> T buildConfig(T builder, String packId, Path dataLocation) {
builder.setTranslationPrefix("rpo." + packId + ".");
PackReloadType.Aggregator agg = new PackReloadType.Aggregator();
for (Map.Entry<String, ConfigEntry<?>> e : getValue().entrySet()) {
e.getValue().buildEntry(
new GuiEntryBuilderParam(builder,
e.getKey(),
() -> agg.accept(e.getValue().getReloadType()))
);
}
builder.executeAfterWrite(cfg -> {
if (RespackoptsConfig.debugLogs) Respackopts.LOGGER.info("GuiFactory SavingRunnable " + agg.get());
MetaCache.save(new SaveHook.Arguments(agg.get() == PackReloadType.Resource, false, true));
});
builder.setPath(dataLocation);
return builder;
}
@Override
public void appendString(IndentingStringBuilder sb) {
IndentingStringBuilder ind = sb.indent();
for (Map.Entry<String, ConfigEntry<?>> e : getValue().entrySet()) {
ind.line("- " + e.getValue().getName() + ":");
e.getValue().appendString(ind);
}
}
@Override
public ConfigBranch clone() {
ConfigBranch branch = new ConfigBranch();
for (Map.Entry<String, ConfigEntry<?>> e : getValue().entrySet()) {
ConfigEntry<?> entry = e.getValue().clone();
entry.setReloadType(e.getValue().getReloadType());
branch.add(e.getKey(), entry);
}
branch.setVersion(getVersion());
return branch;
}
@Override
public void setVersion(int version) {
super.setVersion(version);
for (ConfigEntry<?> value : getValue().values()) {
value.setVersion(version);
}
}
@Override
public boolean equals(Object o) {
if (!super.equals(o)) return false;
if (!(o instanceof ConfigBranch other)) return false;
Map<String, ConfigEntry<?>> otherMap = other.getValue();
if (otherMap.size() != getValue().size()) return false;
for (Map.Entry<String, ConfigEntry<?>> entry : getValue().entrySet()) {
if (!otherMap.containsKey(entry.getKey())) return false;
if (!otherMap.get(entry.getKey()).equals(entry.getValue())) return false;
}
return true;
}
@Override
public int hashCode() {
List<Object> source = new ArrayList<>();
for (Map.Entry<String, ConfigEntry<?>> entry : getValue().entrySet()) {
source.add(entry.getKey());
source.add(entry.getValue());
}
source.add(super.hashCode());
return Objects.hash(source.toArray());
}
}