3
3
import com .falsepattern .lib .StableAPI ;
4
4
import com .falsepattern .lib .internal .CoreLoadingPlugin ;
5
5
import com .falsepattern .lib .internal .FalsePatternLib ;
6
+ import cpw .mods .fml .client .config .IConfigElement ;
6
7
import cpw .mods .fml .client .event .ConfigChangedEvent ;
8
+ import cpw .mods .fml .common .FMLCommonHandler ;
7
9
import cpw .mods .fml .common .eventhandler .SubscribeEvent ;
8
10
import lombok .*;
9
11
import net .minecraftforge .common .MinecraftForge ;
12
+ import net .minecraftforge .common .config .ConfigElement ;
10
13
import net .minecraftforge .common .config .Configuration ;
11
14
12
15
import java .lang .reflect .Field ;
22
25
@ NoArgsConstructor (access = AccessLevel .PRIVATE )
23
26
@ StableAPI (since = "0.6.0" )
24
27
public class ConfigurationManager {
25
- private static final Map <String , Set <Class <?>>> configs = new HashMap <>();
28
+ private static final Map <String , Configuration > configs = new HashMap <>();
29
+
30
+ private static final Map <Configuration , Set <Class <?>>> configToClassMap = new HashMap <>();
26
31
27
32
private static final ConfigurationManager instance = new ConfigurationManager ();
28
33
@@ -31,27 +36,66 @@ public class ConfigurationManager {
31
36
private static Path configDir ;
32
37
33
38
/**
34
- * Registers a configuration class to be loaded.
35
- * @param config The class to register.
39
+ * Registers a configuration class to be loaded. This should be done in preInit.
40
+ * @param configClass The class to register.
36
41
*/
37
- public static void registerConfig (Class <?> config ) throws ConfigException {
38
- val cfg = Optional .ofNullable (config .getAnnotation (Config .class )).orElseThrow (() -> new ConfigException ("Class " + config .getName () + " does not have a @Config annotation!" ));
39
- val cfgSet = configs .computeIfAbsent (cfg .modid (), (ignored ) -> new HashSet <>());
40
- cfgSet .add (config );
42
+ public static void registerConfig (Class <?> configClass ) throws ConfigException {
43
+ val cfg = Optional
44
+ .ofNullable (configClass .getAnnotation (Config .class ))
45
+ .orElseThrow (() -> new ConfigException ("Class " + configClass .getName () + " does not have a @Config annotation!" ));
46
+ val category = Optional
47
+ .of (cfg .category ().trim ())
48
+ .map ((cat ) -> cat .length () == 0 ? null : cat )
49
+ .orElseThrow (() -> new ConfigException ("Config class " + configClass .getName () + " has an empty category!" ));
50
+ val rawConfig = configs .computeIfAbsent (cfg .modid (), (ignored ) -> {
51
+ val c = new Configuration (configDir .resolve (cfg .modid () + ".cfg" ).toFile ());
52
+ c .load ();
53
+ return c ;
54
+ });
55
+ configToClassMap .computeIfAbsent (rawConfig , (ignored ) -> new HashSet <>()).add (configClass );
41
56
try {
42
- processConfig (config );
57
+ processConfigInternal (configClass , category , rawConfig );
58
+ rawConfig .save ();
43
59
} catch (IllegalAccessException | NoSuchMethodException | InvocationTargetException | NoSuchFieldException e ) {
44
60
throw new ConfigException (e );
45
61
}
46
62
}
47
63
64
+ /**
65
+ * Process the configuration into a list of config elements usable in config GUI code.
66
+ * @param configClass The class to process.
67
+ * @return The configuration elements.
68
+ */
69
+ public static List <? extends IConfigElement <?>> getConfigElements (Class <?> configClass ) throws ConfigException {
70
+ val cfg = Optional
71
+ .ofNullable (configClass .getAnnotation (Config .class ))
72
+ .orElseThrow (() -> new ConfigException ("Class " + configClass .getName () + " does not have a @Config annotation!" ));
73
+ val rawConfig = Optional
74
+ .ofNullable (configs .get (cfg .modid ()))
75
+ .map ((conf ) -> Optional .ofNullable (configToClassMap .get (conf ))
76
+ .map ((l ) -> l .contains (configClass ))
77
+ .orElse (false ) ? conf : null )
78
+ .orElseThrow (() -> new ConfigException ("Tried to get config elements for non-registed config class!" ));
79
+ val category = cfg .category ();
80
+ val elements = new ConfigElement <>(rawConfig .getCategory (category )).getChildElements ();
81
+ return elements .stream ().map ((element ) -> new IConfigElementProxy <>((IConfigElement <?>) element , () -> {
82
+ try {
83
+ processConfigInternal (configClass , category , rawConfig );
84
+ rawConfig .save ();
85
+ } catch (IllegalAccessException | NoSuchMethodException | InvocationTargetException |
86
+ NoSuchFieldException | ConfigException e ) {
87
+ e .printStackTrace ();
88
+ }
89
+ })).collect (Collectors .toList ());
90
+ }
91
+
48
92
/**
49
93
* Internal, do not use.
50
94
*/
51
95
public static void init () {
52
96
if (initialized ) return ;
53
97
configDir = CoreLoadingPlugin .mcDir .toPath ().resolve ("config" );
54
- MinecraftForge . EVENT_BUS .register (instance );
98
+ FMLCommonHandler . instance (). bus () .register (instance );
55
99
initialized = true ;
56
100
}
57
101
@@ -61,27 +105,20 @@ public static void init() {
61
105
*/
62
106
@ SubscribeEvent
63
107
public void onConfigChanged (ConfigChangedEvent .OnConfigChangedEvent event ) {
64
- val configClasses = configs .get (event .modID );
65
- if (configClasses == null )
108
+ val config = configs .get (event .modID );
109
+ if (config == null )
66
110
return ;
67
- configClasses .forEach ((config ) -> {
111
+ val configClasses = configToClassMap .get (config );
112
+ configClasses .forEach ((configClass ) -> {
68
113
try {
69
- processConfig (config );
114
+ val category = Optional .ofNullable (configClass .getAnnotation (Config .class )).map (Config ::category ).orElseThrow (() -> new ConfigException ("Failed to get config category for class " + configClass .getName ()));
115
+ processConfigInternal (configClass , category , config );
70
116
} catch (Exception e ) {
71
- throw new RuntimeException ( e );
117
+ e . printStackTrace ( );
72
118
}
73
119
});
74
120
}
75
-
76
- private static void processConfig (Class <?> configClass ) throws IllegalAccessException , NoSuchMethodException , InvocationTargetException , NoSuchFieldException , ConfigException {
77
- val cfg = configClass .getAnnotation (Config .class );
78
- val category = cfg .category ();
79
- var configName = cfg .name ().trim ();
80
- if (configName .length () == 0 ) {
81
- configName = cfg .modid ();
82
- }
83
- val rawConfig = new Configuration (configDir .resolve (configName + ".cfg" ).toFile ());
84
- rawConfig .load ();
121
+ private static void processConfigInternal (Class <?> configClass , String category , Configuration rawConfig ) throws IllegalAccessException , NoSuchMethodException , InvocationTargetException , NoSuchFieldException , ConfigException {
85
122
val cat = rawConfig .getCategory (category );
86
123
for (val field : configClass .getDeclaredFields ()) {
87
124
if (field .getAnnotation (Config .Ignore .class ) != null ) continue ;
@@ -144,7 +181,6 @@ private static void processConfig(Class<?> configClass) throws IllegalAccessExce
144
181
cat .setRequiresWorldRestart (true );
145
182
}
146
183
}
147
- rawConfig .save ();
148
184
}
149
185
150
186
@ SneakyThrows
0 commit comments