225 lines
8.2 KiB
Java
225 lines
8.2 KiB
Java
package io.gitlab.jfronny.respackopts.model.tree;
|
|
|
|
import com.google.common.collect.ImmutableMap;
|
|
import io.gitlab.jfronny.commons.serialize.databind.api.SerializeWithAdapter;
|
|
import io.gitlab.jfronny.commons.serialize.databind.api.TypeToken;
|
|
import io.gitlab.jfronny.libjf.config.api.v2.dsl.CategoryBuilder;
|
|
import io.gitlab.jfronny.libjf.config.api.v2.dsl.ConfigBuilder;
|
|
import io.gitlab.jfronny.muscript.data.additional.DFinal;
|
|
import io.gitlab.jfronny.muscript.data.additional.DelegateDynamic;
|
|
import io.gitlab.jfronny.muscript.data.additional.context.Scope;
|
|
import io.gitlab.jfronny.muscript.data.dynamic.Dynamic;
|
|
import io.gitlab.jfronny.respackopts.Respackopts;
|
|
import io.gitlab.jfronny.respackopts.RespackoptsConfig;
|
|
import io.gitlab.jfronny.respackopts.gson.entry.ConfigBranchSerializer;
|
|
import io.gitlab.jfronny.respackopts.integration.SaveHook;
|
|
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.*;
|
|
|
|
@SerializeWithAdapter(adapter = ConfigBranchSerializer.class)
|
|
public class ConfigBranch extends ConfigEntry<Map<String, ConfigEntry<?>>> implements DelegateDynamic {
|
|
public ConfigBranch() {
|
|
super(new TypeToken<Map<String, ConfigEntry<?>>>(){}.getRawType());
|
|
setValue(new LinkedHashMap<>());
|
|
}
|
|
|
|
private void checkValue() {
|
|
if (version < 10) return;
|
|
for (Iterator<String> iterator = getValue().keySet().iterator(); iterator.hasNext(); ) {
|
|
String s = iterator.next();
|
|
if (!Respackopts.isLegal(s)) {
|
|
Respackopts.LOGGER.error("Illegal entry for " + getName() + ", skipping: " + s);
|
|
iterator.remove();
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public Map<String, ConfigEntry<?>> setValue(Map<String, ConfigEntry<?>> value) {
|
|
var res = super.setValue(value);
|
|
checkValue();
|
|
return res;
|
|
}
|
|
|
|
@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) {
|
|
getValue().forEach((key, value) -> {
|
|
if (!source.getValue().containsKey(key)) {
|
|
super.getValue().remove(key);
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
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) {
|
|
if (version >= 10 && !Respackopts.isLegal(name)) {
|
|
Respackopts.LOGGER.error("Illegal entry for " + getName() + ", skipping: " + name);
|
|
return;
|
|
}
|
|
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) {
|
|
super.getValue().forEach((key, value) -> {
|
|
value.buildShader(sb, valueName + "_" + Respackopts.sanitizeString(key));
|
|
});
|
|
}
|
|
|
|
@Override
|
|
public Dynamic getDelegate() {
|
|
Map<String, ConfigEntry<?>> map = new HashMap<>();
|
|
super.getValue().forEach((key, value) -> {
|
|
if (Respackopts.isLegal(key)) map.put(key, value);
|
|
else if (version >= 10) {
|
|
Respackopts.LOGGER.error("Illegal key in " + getName() + ", skipping: " + key);
|
|
} else map.put(Respackopts.sanitizeString(key), value);
|
|
});
|
|
return DFinal.of(map);
|
|
}
|
|
|
|
public Scope addTo(Scope scope) {
|
|
super.getValue().forEach((key, value) -> {
|
|
scope.set(version >= 10 ? key : Respackopts.sanitizeString(key), value);
|
|
});
|
|
return scope;
|
|
}
|
|
|
|
@Override
|
|
public CategoryBuilder<?> buildEntry(GuiEntryBuilderParam builder) {
|
|
return builder.builder().category(builder.name(), cb -> {
|
|
getValue().forEach((key, value) -> {
|
|
value.buildEntry(new GuiEntryBuilderParam(cb, key, 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();
|
|
getValue().forEach((key, value) -> {
|
|
value.buildEntry(
|
|
new GuiEntryBuilderParam(
|
|
builder,
|
|
key,
|
|
() -> agg.accept(value.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();
|
|
getValue().forEach((key, value) -> {
|
|
ind.line("- " + value.getName() + ":");
|
|
value.appendString(ind);
|
|
});
|
|
}
|
|
|
|
@Override
|
|
public ConfigBranch clone() {
|
|
ConfigBranch branch = new ConfigBranch();
|
|
getValue().forEach((key, value) -> {
|
|
ConfigEntry<?> entry = value.clone();
|
|
entry.setReloadType(value.getReloadType());
|
|
branch.add(key, entry);
|
|
});
|
|
branch.setVersion(getVersion());
|
|
return branch;
|
|
}
|
|
|
|
@Override
|
|
public void setVersion(int version) {
|
|
super.setVersion(version);
|
|
for (ConfigEntry<?> value : getValue().values()) {
|
|
value.setVersion(version);
|
|
}
|
|
checkValue();
|
|
}
|
|
|
|
@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<>();
|
|
getValue().forEach((key, value) -> {
|
|
source.add(key);
|
|
source.add(value);
|
|
});
|
|
source.add(super.hashCode());
|
|
return Objects.hash(source.toArray());
|
|
}
|
|
}
|