package org.betterx.bclib.config; import net.minecraft.resources.ResourceLocation; import org.betterx.bclib.BCLib; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.util.LinkedList; import java.util.List; import java.util.function.Predicate; public class NamedPathConfig extends PathConfig { public static class ConfigTokenDescription { public final ConfigToken token; public final String internalName; public final Boolean hidden; public final int leftPadding; public final int topPadding; @SuppressWarnings("unchecked") ConfigTokenDescription(Field fl) throws IllegalAccessException { token = (ConfigToken) fl.get(null); internalName = fl.getName(); ConfigUI ui = fl.getAnnotation(ConfigUI.class); if (ui != null) { this.hidden = ui.hide(); leftPadding = ui.leftPadding(); topPadding = ui.topPadding(); } else { this.hidden = false; this.leftPadding = 0; topPadding = 0; } } public String getPath() { StringBuilder path = new StringBuilder(); for (String p : token.getPath()) { path.append(".") .append(p); } path.append(".").append(token.getEntry()); return path.toString(); } } public static class DependendConfigToken extends ConfigToken { protected final Predicate dependenciesTrue; protected DependendConfigToken(Class type, T defaultValue, String entry, ResourceLocation path, Predicate dependenciesTrue) { this(type, defaultValue, entry, new String[]{path.getNamespace(), path.getPath()}, dependenciesTrue); } protected DependendConfigToken(Class type, T defaultValue, String entry, String path, Predicate dependenciesTrue) { super(type, defaultValue, entry, path); this.dependenciesTrue = dependenciesTrue; } protected DependendConfigToken(Class type, T defaultValue, String entry, String[] path, Predicate dependenciesTrue) { super(type, defaultValue, entry, path); this.dependenciesTrue = dependenciesTrue; } public boolean dependenciesTrue(NamedPathConfig config) { return dependenciesTrue.test(config); } public static DependendConfigToken Boolean(boolean defaultValue, String entry, String path, Predicate dependenciesTrue) { return new DependendConfigToken(ConfigKeeper.BooleanEntry.class, defaultValue, entry, path, dependenciesTrue); } } public static class ConfigToken extends ConfigKey { public final T defaultValue; public final Class type; protected ConfigToken(Class type, T defaultValue, String entry, ResourceLocation path) { this(type, defaultValue, entry, path.getNamespace(), path.getPath()); } @SuppressWarnings("unchecked") protected ConfigToken(Class type, T defaultValue, String entry, String... path) { super(entry, path); this.defaultValue = defaultValue; this.type = type; } public boolean dependenciesTrue(NamedPathConfig config) { return true; } public static ConfigToken Boolean(boolean defaultValue, String entry, String path) { return new ConfigToken(ConfigKeeper.BooleanEntry.class, defaultValue, entry, path); } public static ConfigToken Int(int defaultValue, String entry, String path) { return new ConfigToken(ConfigKeeper.IntegerEntry.class, defaultValue, entry, path); } public static ConfigToken Float(float defaultValue, String entry, String path) { return new ConfigToken(ConfigKeeper.FloatEntry.class, defaultValue, entry, path); } public static ConfigToken String(String defaultValue, String entry, String path) { return new ConfigToken(ConfigKeeper.StringEntry.class, defaultValue, entry, path); } public static ConfigToken> StringArray(List defaultValue, String entry, String path) { return new ConfigToken>(ConfigKeeper.StringArrayEntry.class, defaultValue, entry, path); } } public NamedPathConfig(String modID, String group, boolean autoSync, boolean diffContent) { super(modID, group, autoSync, diffContent); onInit(); } public NamedPathConfig(String modID, String group, boolean autoSync) { super(modID, group, autoSync); onInit(); } public NamedPathConfig(String modID, String group) { super(modID, group); onInit(); } public List> getAllOptions() { List> res = new LinkedList<>(); for (Field fl : this.getClass().getDeclaredFields()) { int modifiers = fl.getModifiers(); if (Modifier.isPublic(modifiers) && Modifier.isStatic(modifiers) && ConfigToken.class.isAssignableFrom(fl.getType())) { try { res.add(new ConfigTokenDescription<>(fl)); } catch (IllegalAccessException e) { BCLib.LOGGER.error("Could not access " + fl); } } } return res; } protected void onInit() { getAllOptions().forEach(e -> get(e.token)); this.saveChanges(); } /** * The value without any check of {@link DependendConfigToken} *

* In most cases you probably want to use {@link #get(ConfigToken)}, we use this Method if we * present the actual value of the Settings from the Config File without any additional processing. * * @param what The Option you want to get * @param The Type of the Option * @return The Value of the Option (without checking the {@link DependendConfigToken}): */ public T getRaw(ConfigToken what) { return _get(what, true); } /** * The value of an Option * * @param what he Option you want to get * @param The Type of the Option * @return The Value of the Option. If this option is a {@link DependendConfigToken}, the returned value * may not be the value from the config File. For Example, on a {@link Boolean}-Type the result is always false * if {@link DependendConfigToken#dependenciesTrue} returns {@code false}. */ public T get(ConfigToken what) { return _get(what, false); } @SuppressWarnings("unchecked") private T _get(ConfigToken what, boolean raw) { //TODO: Check if we can make config fully Generic to avoid runtime type checks... if (ConfigKeeper.BooleanEntry.class.isAssignableFrom(what.type)) { return (T) _getBoolean((ConfigToken) what, raw); } if (ConfigKeeper.IntegerEntry.class.isAssignableFrom(what.type)) { return (T) _getInt((ConfigToken) what); } if (ConfigKeeper.FloatEntry.class.isAssignableFrom(what.type)) { return (T) _getFloat((ConfigToken) what); } if (ConfigKeeper.StringEntry.class.isAssignableFrom(what.type)) { return (T) _getString((ConfigToken) what); } if (ConfigKeeper.StringArrayEntry.class.isAssignableFrom(what.type)) { return (T) _getStringArray((ConfigToken>) what); } return this._get(what); } private T _get(ConfigToken what) { BCLib.LOGGER.error(what + " has unsupported Type."); return what.defaultValue; } public void set(ConfigToken what, boolean value) { this.setBoolean(what, value); } private Boolean _getBoolean(ConfigToken what, boolean raw) { if (!raw && !what.dependenciesTrue(this)) { return false; } return this.getBoolean(what, what.defaultValue); } public void set(ConfigToken what, int value) { this.setInt(what, value); } private Integer _getInt(ConfigToken what) { return this.getInt(what, what.defaultValue); } public void set(ConfigToken what, float value) { this.setFloat(what, value); } private Float _getFloat(ConfigToken what) { return this.getFloat(what, what.defaultValue); } public void set(ConfigToken what, String value) { this.setString(what, value); } private String _getString(ConfigToken what) { return this.getString(what, what.defaultValue); } public void set(ConfigToken> what, List value) { this.setStringArray(what, value); } private List _getStringArray(ConfigToken> what) { return this.getStringArray(what, what.defaultValue); } }