Refactor Config into ConfigInstance and ConfigInstanceImpl
This commit is contained in:
parent
46fcb539de
commit
e0e5aaba99
|
@ -28,9 +28,12 @@ You MAY annotate fields as @GsonHidden to not serialize them (-> [libjf-base](li
|
|||
Numeric values MAY have a min and max value specified in their @Entry.
|
||||
|
||||
To register a config, add a `libjf:config` entrypoint pointing to its class to your fabric.mod.json.
|
||||
To manually register a config or save changes, use `io.gitlab.jfronny.libjf.config.api.ConfigHolder`
|
||||
To manually register a config or save changes, use `io.gitlab.jfronny.libjf.config.api.ConfigInstance`
|
||||
For example, to save a config for a mod titled `yourmod`:
|
||||
```java
|
||||
// Directly using ConfigInstance
|
||||
ConfigInstance.get("yourmod").write();
|
||||
// Using ConfigHolder
|
||||
ConfigHolder.getInstance().get("yourmod").write();
|
||||
```
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package io.gitlab.jfronny.libjf.config.api;
|
||||
|
||||
import io.gitlab.jfronny.libjf.config.impl.Config;
|
||||
import io.gitlab.jfronny.libjf.config.impl.ConfigHolderImpl;
|
||||
|
||||
import java.util.Map;
|
||||
|
@ -10,8 +9,8 @@ public interface ConfigHolder {
|
|||
return ConfigHolderImpl.INSTANCE;
|
||||
}
|
||||
void register(String modId, Class<?> config);
|
||||
Map<String, Config> getRegistered();
|
||||
Config get(Class<?> configClass);
|
||||
Config get(String configClass);
|
||||
Map<String, ConfigInstance> getRegistered();
|
||||
ConfigInstance get(Class<?> configClass);
|
||||
ConfigInstance get(String modId);
|
||||
boolean isRegistered(Class<?> config);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
package io.gitlab.jfronny.libjf.config.api;
|
||||
|
||||
import io.gitlab.jfronny.libjf.config.impl.EntryInfo;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public interface ConfigInstance {
|
||||
static ConfigInstance get(Class<?> configClass) {
|
||||
return ConfigHolder.getInstance().get(configClass);
|
||||
}
|
||||
static ConfigInstance get(String modId) {
|
||||
return ConfigHolder.getInstance().get(modId);
|
||||
}
|
||||
void load();
|
||||
void syncToClass();
|
||||
void syncFromClass();
|
||||
void write();
|
||||
String getModId();
|
||||
boolean matchesConfigClass(Class<?> candidate);
|
||||
List<EntryInfo> getEntries();
|
||||
Map<String, Runnable> getPresets();
|
||||
}
|
|
@ -2,6 +2,7 @@ package io.gitlab.jfronny.libjf.config.impl;
|
|||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import io.gitlab.jfronny.libjf.config.api.ConfigHolder;
|
||||
import io.gitlab.jfronny.libjf.config.api.ConfigInstance;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
@ -11,36 +12,36 @@ public class ConfigHolderImpl implements ConfigHolder {
|
|||
@ApiStatus.Internal
|
||||
public static final ConfigHolderImpl INSTANCE = new ConfigHolderImpl();
|
||||
private ConfigHolderImpl() {}
|
||||
private final Map<String, Config> configs = new HashMap<>();
|
||||
private final Map<String, ConfigInstance> configs = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public void register(String modId, Class<?> config) {
|
||||
if (!isRegistered(config))
|
||||
configs.put(modId, new Config(modId, config));
|
||||
configs.put(modId, new ConfigInstanceImpl(modId, config));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Config> getRegistered() {
|
||||
public Map<String, ConfigInstance> getRegistered() {
|
||||
return ImmutableMap.copyOf(configs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Config get(Class<?> configClass) {
|
||||
for (Config value : configs.values()) {
|
||||
if (value.configClass.equals(configClass))
|
||||
public ConfigInstance get(Class<?> configClass) {
|
||||
for (ConfigInstance value : configs.values()) {
|
||||
if (value.matchesConfigClass(configClass))
|
||||
return value;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Config get(String configClass) {
|
||||
public ConfigInstance get(String configClass) {
|
||||
return configs.get(configClass);
|
||||
}
|
||||
|
||||
public boolean isRegistered(Class<?> config) {
|
||||
for (Config value : configs.values()) {
|
||||
if (value.configClass.equals(config))
|
||||
for (ConfigInstance value : configs.values()) {
|
||||
if (value.matchesConfigClass(config))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package io.gitlab.jfronny.libjf.config.impl;
|
||||
|
||||
import io.gitlab.jfronny.libjf.LibJf;
|
||||
import io.gitlab.jfronny.libjf.config.api.ConfigInstance;
|
||||
import io.gitlab.jfronny.libjf.config.api.Entry;
|
||||
import io.gitlab.jfronny.libjf.config.api.Preset;
|
||||
import io.gitlab.jfronny.libjf.config.api.Verifier;
|
||||
|
@ -16,7 +17,7 @@ import java.util.*;
|
|||
/** Based on https://github.com/TeamMidnightDust/MidnightLib which is based on https://github.com/Minenash/TinyConfig
|
||||
* Credits to TeamMidnightDust and Minenash */
|
||||
|
||||
public class Config {
|
||||
public class ConfigInstanceImpl implements ConfigInstance {
|
||||
public final List<EntryInfo> entries = new ArrayList<>();
|
||||
public final Map<String, Runnable> presets = new LinkedHashMap<>();
|
||||
public final Set<Runnable> verifiers = new LinkedHashSet<>();
|
||||
|
@ -24,7 +25,7 @@ public class Config {
|
|||
public final String modid;
|
||||
public final Class<?> configClass;
|
||||
|
||||
public Config(String modid, Class<?> config) {
|
||||
public ConfigInstanceImpl(String modid, Class<?> config) {
|
||||
this.modid = modid;
|
||||
configClass = config;
|
||||
path = FabricLoader.getInstance().getConfigDir().resolve(modid + ".json");
|
||||
|
@ -101,6 +102,7 @@ public class Config {
|
|||
load();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load() {
|
||||
try {
|
||||
LibJf.GSON.fromJson(Files.newBufferedReader(path), configClass);
|
||||
|
@ -112,6 +114,7 @@ public class Config {
|
|||
write();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void syncToClass() {
|
||||
for (EntryInfo info : entries) {
|
||||
try {
|
||||
|
@ -123,6 +126,7 @@ public class Config {
|
|||
syncFromClass();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void syncFromClass() {
|
||||
for (Runnable verifier : verifiers) {
|
||||
verifier.run();
|
||||
|
@ -138,6 +142,7 @@ public class Config {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write() {
|
||||
try {
|
||||
if (!Files.exists(path)) Files.createFile(path);
|
||||
|
@ -146,4 +151,24 @@ public class Config {
|
|||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getModId() {
|
||||
return modid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matchesConfigClass(Class<?> candidate) {
|
||||
return candidate != null && candidate.isAssignableFrom(configClass);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<EntryInfo> getEntries() {
|
||||
return entries;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Runnable> getPresets() {
|
||||
return presets;
|
||||
}
|
||||
}
|
|
@ -3,6 +3,7 @@ package io.gitlab.jfronny.libjf.config.impl;
|
|||
import com.terraformersmc.modmenu.api.ConfigScreenFactory;
|
||||
import com.terraformersmc.modmenu.api.ModMenuApi;
|
||||
import io.gitlab.jfronny.libjf.config.api.ConfigHolder;
|
||||
import io.gitlab.jfronny.libjf.config.api.ConfigInstance;
|
||||
import io.gitlab.jfronny.libjf.config.impl.gui.TinyConfigScreen;
|
||||
import io.gitlab.jfronny.libjf.LibJf;
|
||||
|
||||
|
@ -13,14 +14,14 @@ public class ModMenu implements ModMenuApi {
|
|||
@Override
|
||||
public Map<String, ConfigScreenFactory<?>> getProvidedConfigScreenFactories() {
|
||||
Map<String, ConfigScreenFactory<?>> factories = new HashMap<>();
|
||||
for (Map.Entry<String, Config> entry : ConfigHolder.getInstance().getRegistered().entrySet()) {
|
||||
for (Map.Entry<String, ConfigInstance> entry : ConfigHolder.getInstance().getRegistered().entrySet()) {
|
||||
if (!LibJf.MOD_ID.equals(entry.getKey()))
|
||||
factories.put(entry.getKey(), buildFactory(entry.getValue()));
|
||||
}
|
||||
return factories;
|
||||
}
|
||||
|
||||
private static ConfigScreenFactory<?> buildFactory(Config config) {
|
||||
private static ConfigScreenFactory<?> buildFactory(ConfigInstance config) {
|
||||
return s -> new TinyConfigScreen(s, config);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,17 +1,16 @@
|
|||
package io.gitlab.jfronny.libjf.config.impl.entry;
|
||||
|
||||
import io.gitlab.jfronny.libjf.config.api.ConfigHolder;
|
||||
import io.gitlab.jfronny.libjf.config.impl.Config;
|
||||
import io.gitlab.jfronny.libjf.config.impl.ConfigHolderImpl;
|
||||
import io.gitlab.jfronny.libjf.config.impl.gui.EntryInfoWidgetBuilder;
|
||||
import io.gitlab.jfronny.libjf.LibJf;
|
||||
import io.gitlab.jfronny.libjf.config.api.ConfigHolder;
|
||||
import io.gitlab.jfronny.libjf.config.api.ConfigInstance;
|
||||
import io.gitlab.jfronny.libjf.config.impl.gui.EntryInfoWidgetBuilder;
|
||||
import net.fabricmc.api.ClientModInitializer;
|
||||
|
||||
public class JfConfigClient implements ClientModInitializer {
|
||||
@Override
|
||||
public void onInitializeClient() {
|
||||
for (Config config : ConfigHolder.getInstance().getRegistered().values()) {
|
||||
LibJf.LOGGER.info("Registring config UI for " + config.modid);
|
||||
for (ConfigInstance config : ConfigHolder.getInstance().getRegistered().values()) {
|
||||
LibJf.LOGGER.info("Registring config UI for " + config.getModId());
|
||||
EntryInfoWidgetBuilder.initConfig(config);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package io.gitlab.jfronny.libjf.config.impl.gui;
|
||||
|
||||
import io.gitlab.jfronny.libjf.config.api.ConfigInstance;
|
||||
import io.gitlab.jfronny.libjf.config.api.Entry;
|
||||
import io.gitlab.jfronny.libjf.config.impl.Config;
|
||||
import io.gitlab.jfronny.libjf.config.impl.EntryInfo;
|
||||
import io.gitlab.jfronny.libjf.gson.GsonHidden;
|
||||
import net.fabricmc.api.EnvType;
|
||||
|
@ -26,8 +26,8 @@ public class EntryInfoWidgetBuilder {
|
|||
private static final Pattern INTEGER_ONLY = Pattern.compile("(-?[0-9]*)");
|
||||
private static final Pattern DECIMAL_ONLY = Pattern.compile("-?([\\d]+\\.?[\\d]*|[\\d]*\\.?[\\d]+|\\.)");
|
||||
|
||||
public static void initConfig(Config config) {
|
||||
for (EntryInfo info : config.entries) {
|
||||
public static void initConfig(ConfigInstance config) {
|
||||
for (EntryInfo info : config.getEntries()) {
|
||||
if (info.field.isAnnotationPresent(Entry.class) || info.field.isAnnotationPresent(GsonHidden.class))
|
||||
try {
|
||||
initEntry(config, info);
|
||||
|
@ -36,7 +36,7 @@ public class EntryInfoWidgetBuilder {
|
|||
}
|
||||
}
|
||||
|
||||
private static void initEntry(Config config, EntryInfo info) {
|
||||
private static void initEntry(ConfigInstance config, EntryInfo info) {
|
||||
if (!(info.field.isAnnotationPresent(io.gitlab.jfronny.libjf.config.api.Entry.class) || info.field.isAnnotationPresent(GsonHidden.class))) return;
|
||||
Class<?> type = info.field.getType();
|
||||
info.width = info.entry != null ? info.entry.width() : 0;
|
||||
|
@ -55,7 +55,7 @@ public class EntryInfoWidgetBuilder {
|
|||
}, func);
|
||||
} else if (type.isEnum()) {
|
||||
List<?> values = Arrays.asList(info.field.getType().getEnumConstants());
|
||||
Function<Object,Text> func = value -> new TranslatableText(config.modid + ".jfconfig." + "enum." + type.getSimpleName() + "." + info.value.toString());
|
||||
Function<Object,Text> func = value -> new TranslatableText(config.getModId() + ".jfconfig." + "enum." + type.getSimpleName() + "." + info.value.toString());
|
||||
info.widget = new AbstractMap.SimpleEntry<ButtonWidget.PressAction, Function<Object, Text>>(button -> {
|
||||
int index = values.indexOf(info.value) + 1;
|
||||
info.value = values.get(index >= values.size()? 0 : index);
|
||||
|
@ -70,7 +70,7 @@ public class EntryInfoWidgetBuilder {
|
|||
}
|
||||
}
|
||||
|
||||
private static void textField(Config config, EntryInfo info, Function<String,Number> f, Pattern pattern, double min, double max, boolean cast) {
|
||||
private static void textField(ConfigInstance config, EntryInfo info, Function<String,Number> f, Pattern pattern, double min, double max, boolean cast) {
|
||||
boolean isNumber = pattern != null;
|
||||
info.widget = (BiFunction<TextFieldWidget, ButtonWidget, Predicate<String>>) (t, b) -> s -> {
|
||||
s = s.trim();
|
||||
|
@ -90,7 +90,7 @@ public class EntryInfoWidgetBuilder {
|
|||
info.tempValue = s;
|
||||
t.setEditableColor(inLimits? 0xFFFFFFFF : 0xFFFF7777);
|
||||
info.inLimits = inLimits;
|
||||
b.active = config.entries.stream().allMatch(e -> e.inLimits);
|
||||
b.active = config.getEntries().stream().allMatch(e -> e.inLimits);
|
||||
|
||||
if (inLimits)
|
||||
info.value = isNumber? value : s;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package io.gitlab.jfronny.libjf.config.impl.gui;
|
||||
|
||||
import io.gitlab.jfronny.libjf.LibJf;
|
||||
import io.gitlab.jfronny.libjf.config.impl.Config;
|
||||
import io.gitlab.jfronny.libjf.config.api.ConfigInstance;
|
||||
import io.gitlab.jfronny.libjf.config.api.Entry;
|
||||
import io.gitlab.jfronny.libjf.config.impl.EntryInfo;
|
||||
import io.gitlab.jfronny.libjf.config.impl.gui.presets.PresetsScreen;
|
||||
|
@ -28,15 +28,15 @@ import java.util.function.Predicate;
|
|||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public class TinyConfigScreen extends Screen {
|
||||
public TinyConfigScreen(Screen parent, Config config) {
|
||||
super(new TranslatableText(config.modid + ".jfconfig." + "title"));
|
||||
public TinyConfigScreen(Screen parent, ConfigInstance config) {
|
||||
super(new TranslatableText(config.getModId() + ".jfconfig." + "title"));
|
||||
this.parent = parent;
|
||||
this.config = config;
|
||||
this.translationPrefix = config.modid + ".jfconfig.";
|
||||
this.translationPrefix = config.getModId() + ".jfconfig.";
|
||||
}
|
||||
private final String translationPrefix;
|
||||
private final Screen parent;
|
||||
private final Config config;
|
||||
private final ConfigInstance config;
|
||||
private MidnightConfigListWidget list;
|
||||
|
||||
// Real Time config update //
|
||||
|
@ -56,19 +56,7 @@ public class TinyConfigScreen extends Screen {
|
|||
}));
|
||||
|
||||
this.addDrawableChild(new ButtonWidget(this.width / 2 - 154, this.height - 28, 150, 20, ScreenTexts.CANCEL, button -> {
|
||||
try {
|
||||
LibJf.GSON.fromJson(Files.newBufferedReader(config.path), config.configClass); }
|
||||
catch (Exception e) { config.write(); }
|
||||
|
||||
for (EntryInfo info : config.entries) {
|
||||
if (info.field.isAnnotationPresent(Entry.class)) {
|
||||
try {
|
||||
info.value = info.field.get(null);
|
||||
info.tempValue = info.value.toString();
|
||||
} catch (IllegalAccessException ignored) {
|
||||
}
|
||||
}
|
||||
}
|
||||
config.load();
|
||||
Objects.requireNonNull(client).setScreen(parent);
|
||||
}));
|
||||
|
||||
|
@ -80,7 +68,7 @@ public class TinyConfigScreen extends Screen {
|
|||
|
||||
this.list = new MidnightConfigListWidget(this.client, this.width, this.height, 32, this.height - 32, 25);
|
||||
this.addSelectableChild(this.list);
|
||||
for (EntryInfo info : config.entries) {
|
||||
for (EntryInfo info : config.getEntries()) {
|
||||
TranslatableText name = new TranslatableText(translationPrefix + info.field.getName());
|
||||
ButtonWidget resetButton = new ButtonWidget(width - 155, 0, 40, 20, new LiteralText("Reset").formatted(Formatting.RED), (button -> {
|
||||
info.value = info.defaultValue;
|
||||
|
@ -117,7 +105,7 @@ public class TinyConfigScreen extends Screen {
|
|||
|
||||
Optional<ClickableWidget> widget = list.getHoveredButton(mouseY);
|
||||
if (widget.isPresent()) {
|
||||
for (EntryInfo info : config.entries) {
|
||||
for (EntryInfo info : config.getEntries()) {
|
||||
ClickableWidget buttonWidget = widget.get();
|
||||
Text text = ConfigScreenEntry.buttonsWithText.get(buttonWidget);
|
||||
TranslatableText name = new TranslatableText(this.translationPrefix + info.field.getName());
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package io.gitlab.jfronny.libjf.config.impl.gui.presets;
|
||||
|
||||
import io.gitlab.jfronny.libjf.LibJf;
|
||||
import io.gitlab.jfronny.libjf.config.impl.Config;
|
||||
import io.gitlab.jfronny.libjf.config.api.ConfigInstance;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
|
@ -15,10 +15,10 @@ import java.util.Map;
|
|||
@Environment(EnvType.CLIENT)
|
||||
public class PresetsScreen extends Screen {
|
||||
private final Screen parent;
|
||||
private final Config config;
|
||||
private final ConfigInstance config;
|
||||
private PresetListWidget list;
|
||||
|
||||
public PresetsScreen(Screen parent, Config config) {
|
||||
public PresetsScreen(Screen parent, ConfigInstance config) {
|
||||
super(new TranslatableText("libjf-config-v0.presets"));
|
||||
this.parent = parent;
|
||||
this.config = config;
|
||||
|
@ -28,7 +28,7 @@ public class PresetsScreen extends Screen {
|
|||
protected void init() {
|
||||
super.init();
|
||||
this.list = new PresetListWidget(this.client, this.width, this.height, 32, this.height - 32, 25);
|
||||
for (Map.Entry<String, Runnable> entry : config.presets.entrySet()) {
|
||||
for (Map.Entry<String, Runnable> entry : config.getPresets().entrySet()) {
|
||||
this.list.addButton(new ButtonWidget(width / 2 - 100, 0, 200, 20,
|
||||
new TranslatableText(entry.getKey()),
|
||||
button -> {
|
||||
|
|
Loading…
Reference in New Issue