Skip to content

Commit 7f1b6c4

Browse files
committed
Major config system upgrade
1 parent 644d6ff commit 7f1b6c4

25 files changed

+569
-204
lines changed

src/main/java/com/falsepattern/lib/config/Config.java

Lines changed: 228 additions & 104 deletions
Large diffs are not rendered by default.

src/main/java/com/falsepattern/lib/config/ConfigException.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,11 @@ public ConfigException(String message) {
3535
super(message);
3636
}
3737

38+
@StableAPI.Internal
39+
public ConfigException(String message, Throwable cause) {
40+
super(message, cause);
41+
}
42+
3843
@StableAPI.Internal
3944
public ConfigException(Throwable cause) {
4045
super(cause);

src/main/java/com/falsepattern/lib/config/ConfigurationManager.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import lombok.SneakyThrows;
3131
import lombok.val;
3232

33+
import cpw.mods.fml.client.config.DummyConfigElement;
3334
import cpw.mods.fml.client.config.IConfigElement;
3435

3536
import java.lang.reflect.Field;
@@ -138,4 +139,20 @@ public static List<IConfigElement> getConfigElementsMulti(Class<?>... configClas
138139
return result;
139140
}
140141
}
142+
/**
143+
* @return The configuration elements, structured with DummyCategoryElement groups per config class
144+
* @see #getConfigElementsMulti(Class[])
145+
*/
146+
@SuppressWarnings("rawtypes")
147+
@StableAPI.Expose(since = "1.5.0")
148+
public static List<IConfigElement> getConfigElementsMultiStructured(Class<?>... configClasses) throws ConfigException {
149+
if (configClasses.length == 0) {
150+
return Collections.emptyList();
151+
}
152+
val result = new ArrayList<IConfigElement>();
153+
for (val configClass: configClasses) {
154+
result.add(ConfigurationManagerImpl.getConfigCategoryElement(configClass));
155+
}
156+
return result;
157+
}
141158
}

src/main/java/com/falsepattern/lib/config/SimpleGuiConfig.java

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,14 +40,20 @@ public SimpleGuiConfig(GuiScreen parent, Class<?> configClass, String modID, Str
4040
}
4141

4242
@StableAPI.Expose(since = "0.10.0")
43-
public SimpleGuiConfig(GuiScreen parent, String modID, String modName, Class<?>... configClasses)
43+
public SimpleGuiConfig(GuiScreen parent, String modID, String title, Class<?>... configClasses)
44+
throws ConfigException {
45+
this(parent, modID, title, null, configClasses);
46+
}
47+
48+
@StableAPI.Expose(since = "1.5.0")
49+
public SimpleGuiConfig(GuiScreen parent, String modID, String title, String titleLine2, Class<?>... configClasses)
4450
throws ConfigException {
4551
super(parent,
46-
ConfigurationManager.getConfigElementsMulti(configClasses),
52+
ConfigurationManager.getConfigElementsMultiStructured(configClasses),
4753
modID,
4854
false,
4955
false,
50-
modName + " Configuration",
51-
I18n.format("falsepatternlib.gui.config.description"));
56+
title,
57+
titleLine2);
5258
}
5359
}

src/main/java/com/falsepattern/lib/internal/config/LibraryConfig.java

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,11 @@
2727
import com.falsepattern.lib.config.ConfigurationManager;
2828
import com.falsepattern.lib.internal.Tags;
2929

30-
@Config(modid = Tags.MODID)
30+
@Config.Comment("Miscellaneous FalsePatternLib settings")
31+
@Config.LangKey
32+
@Config(modid = Tags.MODID,
33+
category = "misc",
34+
categoryMigrations = "general")
3135
public class LibraryConfig {
3236
static {
3337
ConfigurationManager.selfInit();
@@ -36,14 +40,19 @@ public class LibraryConfig {
3640
@Config.Comment({"Fixes the mod options menu in-game.",
3741
"By default, the mod options when in already in a game will show \"Test1, Test2, DISABLED\" in bright red.",
3842
"This replaces that interface with the one from the main menu."})
39-
@Config.LangKey("config.falsepatternlib.ingamemodoptionsfix")
43+
@Config.LangKey
4044
@Config.DefaultBoolean(true)
45+
@Config.Name(value = "inGameModOptionsFix",
46+
migrations = "")
4147
public static boolean IN_GAME_MOD_OPTIONS_FIX;
4248

43-
@Config.Comment("How \"loud\" the config error logging should be.")
44-
@Config.LangKey("config.falsepatternlib.configlogging")
49+
@Config.Comment({"How the config error logging should be set up.",
50+
"[None] disables all built-in config validation error logging"})
51+
@Config.LangKey
4552
@Config.DefaultEnum("Log")
46-
public static ValidationLogging CONFIG_ERROR_LOUDNESS;
53+
@Config.Name(value = "configErrorLogging",
54+
migrations = "CONFIG_ERROR_LOUDNESS")
55+
public static ValidationLogging CONFIG_ERROR_LOGGING;
4756

4857
public enum ValidationLogging {
4958
@StableAPI.Expose(since = "__INTERNAL__") None,

src/main/java/com/falsepattern/lib/internal/config/ToastConfig.java

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -27,34 +27,38 @@
2727
import com.falsepattern.lib.config.ConfigurationManager;
2828
import com.falsepattern.lib.internal.Tags;
2929

30-
import cpw.mods.fml.relauncher.Side;
31-
import cpw.mods.fml.relauncher.SideOnly;
32-
33-
@SideOnly(Side.CLIENT)
30+
@Config.Comment("Toast notification settings")
31+
@Config.LangKey
3432
@Config(modid = Tags.MODID,
3533
category = "toasts")
3634
public class ToastConfig {
3735
static {
3836
ConfigurationManager.selfInit();
3937
}
4038

41-
@Config.Comment("The maximum amount of toasts to show on the screen")
42-
@Config.LangKey("config.falsepatternlib.maxtoasts")
39+
@Config.Comment("The maximum amount of toasts to show on the screen.")
40+
@Config.LangKey
4341
@Config.DefaultInt(5)
4442
@Config.RangeInt(min = 1,
4543
max = 10)
44+
@Config.Name(value = "maxVisible",
45+
migrations = "")
4646
public static int MAX_VISIBLE;
4747

48-
@Config.Comment("The amount of empty space from the top of the screen in pixels")
49-
@Config.LangKey("config.falsepatternlib.toastoffset")
48+
@Config.Comment("The amount of empty space from the top of the screen in pixels.")
49+
@Config.LangKey
5050
@Config.DefaultInt(0)
5151
@Config.RangeInt(min = 0,
5252
max = 10000)
53+
@Config.Name(value = "yOffset",
54+
migrations = "")
5355
public static int Y_OFFSET;
5456

55-
@Config.Comment("Which side of the screen should toasts show up on")
56-
@Config.LangKey("config.falsepatternlib.toastalign")
57+
@Config.Comment("Which side of the screen should toasts show up on.")
58+
@Config.LangKey
5759
@Config.DefaultEnum("Right")
60+
@Config.Name(value = "align",
61+
migrations = "")
5862
public static Side ALIGN;
5963

6064
public static boolean leftAlign() {

src/main/java/com/falsepattern/lib/internal/impl/config/ConfigElementProxy.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,12 @@
3535

3636
public class ConfigElementProxy<T> implements IConfigElement<T> {
3737
private final ConfigElement<T> element;
38+
private final String comment;
3839
private final Runnable syncCallback;
3940

40-
public ConfigElementProxy(Property prop, Runnable syncCallback) {
41+
public ConfigElementProxy(Property prop, String comment, Runnable syncCallback) {
4142
this.element = new ConfigElement<>(prop);
43+
this.comment = comment;
4244
this.syncCallback = syncCallback;
4345
}
4446

@@ -74,14 +76,15 @@ public String getLanguageKey() {
7476

7577
@Override
7678
public String getComment() {
77-
return element.getComment();
79+
return comment;
7880
}
7981

8082
@Override
8183
public List<IConfigElement> getChildElements() {
8284
return element.getChildElements();
8385
}
8486

87+
// Caller sensitive
8588
@Override
8689
public ConfigGuiType getType() {
8790
return element.getType();
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
* This file is part of FalsePatternLib.
3+
*
4+
* Copyright (C) 2022-2024 FalsePattern
5+
* All Rights Reserved
6+
*
7+
* The above copyright notice and this permission notice shall be included
8+
* in all copies or substantial portions of the Software.
9+
*
10+
* FalsePatternLib is free software: you can redistribute it and/or modify
11+
* it under the terms of the GNU Lesser General Public License as published by
12+
* the Free Software Foundation, either version 3 of the License, or
13+
* (at your option) any later version.
14+
*
15+
* FalsePatternLib is distributed in the hope that it will be useful,
16+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
17+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18+
* GNU Lesser General Public License for more details.
19+
*
20+
* You should have received a copy of the GNU Lesser General Public License
21+
* along with FalsePatternLib. If not, see <https://www.gnu.org/licenses/>.
22+
*/
23+
24+
package com.falsepattern.lib.internal.impl.config;
25+
26+
import com.github.bsideup.jabel.Desugar;
27+
28+
import net.minecraftforge.common.config.Configuration;
29+
30+
import java.lang.reflect.Field;
31+
32+
@Desugar
33+
public record ConfigFieldParameters(
34+
Field field,
35+
Configuration configuration,
36+
String modid,
37+
String category
38+
) {}

src/main/java/com/falsepattern/lib/internal/impl/config/ConfigurationManagerImpl.java

Lines changed: 49 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,11 @@
3434
import lombok.AccessLevel;
3535
import lombok.NoArgsConstructor;
3636
import lombok.val;
37+
import org.jetbrains.annotations.NotNull;
38+
import org.jetbrains.annotations.Nullable;
3739

3840
import net.minecraftforge.common.config.Configuration;
41+
import cpw.mods.fml.client.config.DummyConfigElement;
3942
import cpw.mods.fml.client.config.IConfigElement;
4043
import cpw.mods.fml.client.event.ConfigChangedEvent;
4144

@@ -47,6 +50,7 @@
4750
import java.io.DataOutputStream;
4851
import java.io.IOException;
4952
import java.lang.reflect.Field;
53+
import java.nio.file.Files;
5054
import java.nio.file.Path;
5155
import java.util.ArrayList;
5256
import java.util.HashMap;
@@ -64,7 +68,7 @@
6468
*/
6569
@NoArgsConstructor(access = AccessLevel.PRIVATE)
6670
public final class ConfigurationManagerImpl {
67-
private static final Map<String, Configuration> configs = new HashMap<>();
71+
private static final Map<Path, Configuration> configs = new HashMap<>();
6872
private static final Map<Configuration, Set<Class<?>>> configToClassMap = new HashMap<>();
6973
private static final Map<Class<?>, ParsedConfiguration> parsedConfigMap = new HashMap<>();
7074
private static final BiMap<String, Class<?>> serializedNames = HashBiMap.create();
@@ -81,9 +85,33 @@ public static void register(Class<?> configClass) throws ConfigException {
8185
}
8286
}
8387

84-
static Configuration getForgeConfig(String modid) {
85-
return configs.computeIfAbsent(modid, (ignored) -> {
86-
val c = new Configuration(configDir.resolve(modid + ".cfg").toFile());
88+
private static @Nullable Path resolveConfigFile(String pathSuffix, boolean create) throws ConfigException {
89+
var thePath = configDir.resolve(pathSuffix);
90+
val parent = thePath.getParent();
91+
if (!Files.exists(parent)) {
92+
if (!create) {
93+
return null;
94+
}
95+
try {
96+
Files.createDirectories(parent);
97+
} catch (IOException e) {
98+
throw new ConfigException(String.format("Failed to create config parent directory at %s", parent), e);
99+
}
100+
}
101+
val fileName = thePath.getFileName().toString();
102+
if (!fileName.contains(".")) {
103+
thePath = parent.resolve(fileName + ".cfg");
104+
}
105+
return thePath;
106+
}
107+
108+
static @NotNull Configuration getForgeConfig(String pathSuffix, boolean create) throws ConfigException {
109+
val thePath = resolveConfigFile(pathSuffix, create);
110+
if (thePath == null || !(create || Files.exists(thePath))) {
111+
throw new ConfigException(String.format("Could not find config file at %s", pathSuffix));
112+
}
113+
return configs.computeIfAbsent(thePath, (ignored) -> {
114+
val c = new Configuration(thePath.toFile());
87115
c.load();
88116
return c;
89117
});
@@ -93,14 +121,14 @@ public static void load(Class<?> configClass) throws ConfigException {
93121
if (!parsedConfigMap.containsKey(configClass)) {
94122
throw new ConfigException("Class " + configClass.getName() + " is not a registered configuration!");
95123
}
96-
parsedConfigMap.get(configClass).load();
124+
parsedConfigMap.get(configClass).loadFile();
97125
}
98126

99127
public static void save(Class<?> configClass) throws ConfigException {
100128
if (!parsedConfigMap.containsKey(configClass)) {
101129
throw new ConfigException("Class " + configClass.getName() + " is not a registered configuration!");
102130
}
103-
parsedConfigMap.get(configClass).save();
131+
parsedConfigMap.get(configClass).saveFile();
104132
}
105133

106134
public static boolean validateFields(BiConsumer<Class<?>, Field> invalidFieldHandler, Class<?> configClass, boolean resetInvalid)
@@ -235,6 +263,21 @@ private static void init() {
235263
initialized = true;
236264
}
237265

266+
public static DummyConfigElement.DummyCategoryElement<?> getConfigCategoryElement(Class<?> configClass) throws ConfigException {
267+
if (!parsedConfigMap.containsKey(configClass)) {
268+
throw new ConfigException("Class " + configClass.getName() + " is not a registered configuration!");
269+
}
270+
val config = parsedConfigMap.get(configClass);
271+
val entry = new DummyConfigElement.DummyCategoryElement<>(
272+
config.category,
273+
config.langKey,
274+
config.getConfigElements()
275+
);
276+
entry.setRequiresWorldRestart(config.requiresWorldRestart());
277+
entry.setRequiresMcRestart(config.requiresMcRestart());
278+
return entry;
279+
}
280+
238281
public static void sendSyncRequest() throws IOException {
239282
val event = new SyncRequest();
240283
event.transmit();

0 commit comments

Comments
 (0)