13
13
import com .google .gson .JsonSerializationContext ;
14
14
import com .google .gson .JsonSerializer ;
15
15
import dynamic_fps .impl .Constants ;
16
- import dynamic_fps .impl .PowerState ;
17
16
import dynamic_fps .impl .service .Platform ;
18
17
import dynamic_fps .impl .util .Logging ;
19
18
import org .jetbrains .annotations .Nullable ;
20
19
21
20
import java .io .IOException ;
21
+ import java .io .InputStream ;
22
22
import java .lang .reflect .Type ;
23
23
import java .nio .charset .StandardCharsets ;
24
24
import java .nio .file .Files ;
@@ -41,16 +41,19 @@ public class Serialization {
41
41
private static final String CONFIG_FILE = Constants .MOD_ID + ".json" ;
42
42
43
43
public static void save (DynamicFPSConfig instance ) {
44
- String data = GSON .toJson (instance ) + "\n " ;
44
+ JsonObject config = (JsonObject ) GSON .toJsonTree (instance );
45
+ JsonObject parent = (JsonObject ) GSON .toJsonTree (DynamicFPSConfig .DEFAULT );
46
+
47
+ String data = GSON .toJson (removeUnchangedFields (config , parent )) + "\n " ;
45
48
46
49
Path cache = Platform .getInstance ().getCacheDir ();
47
- Path config = Platform .getInstance ().getConfigDir ().resolve (CONFIG_FILE );
50
+ Path configs = Platform .getInstance ().getConfigDir ().resolve (CONFIG_FILE );
48
51
49
52
try {
50
53
Path temp = Files .createTempFile (cache , "config" , ".json" );
51
54
52
55
Files .write (temp , data .getBytes (StandardCharsets .UTF_8 ));
53
- Serialization .move (temp , config ); // Attempt atomic move, fall back otherwise.
56
+ Serialization .move (temp , configs ); // Attempt atomic move, fall back otherwise
54
57
} catch (IOException e ) {
55
58
// Cloth Config's built-in saving does not support catching exceptions :(
56
59
throw new RuntimeException ("Failed to save or modify Dynamic FPS config!" , e );
@@ -65,6 +68,25 @@ private static void move(Path from, Path to) throws IOException {
65
68
}
66
69
}
67
70
71
+ private static JsonObject removeUnchangedFields (JsonObject config , JsonObject parent ) {
72
+ // Recursively delete all fields that are equal to the defaults ...
73
+
74
+ parent .entrySet ().forEach (entry -> {
75
+ String name = entry .getKey ();
76
+
77
+ JsonElement other = entry .getValue ();
78
+ JsonElement value = config .get (name );
79
+
80
+ if (value .equals (other )) {
81
+ config .remove (name );
82
+ } else if (value .isJsonObject () && other .isJsonObject ()) {
83
+ removeUnchangedFields ((JsonObject ) value , (JsonObject ) other );
84
+ }
85
+ });
86
+
87
+ return config ;
88
+ }
89
+
68
90
@ SuppressWarnings ("deprecation" )
69
91
public static DynamicFPSConfig load () {
70
92
byte [] data ;
@@ -91,20 +113,45 @@ public static DynamicFPSConfig load() {
91
113
return GSON .fromJson (root , DynamicFPSConfig .class ); // Ignores regular constructor!
92
114
}
93
115
94
- private static void upgradeConfig (JsonObject root ) {
95
- addIdleTime (root );
96
- upgradeVolumeMultiplier (root );
97
- addAbandonedConfig (root );
98
- addUncapMenuFrameRate (root );
99
- addEnabled (root );
100
- addVolumeTransitionSpeed (root );
101
- }
116
+ public static DynamicFPSConfig loadDefault () {
117
+ byte [] data ;
118
+
119
+ try (InputStream stream = Serialization .class .getResourceAsStream ("/assets/dynamic_fps/data/default_config.json" )) {
120
+ if (stream == null ) {
121
+ throw new IOException ("Stream is null." );
122
+ }
102
123
103
- private static void addIdleTime (JsonObject root ) {
104
- // Add idle_time field if it's missing
105
- if (!root .has ("idle_time" )) {
106
- root .addProperty ("idle_time" , 0 );
124
+ data = stream .readAllBytes ();
125
+ } catch (IOException e ) {
126
+ throw new RuntimeException ("Failed to load Dynamic FPS config." , e );
107
127
}
128
+
129
+ return GSON .fromJson (new String (data , StandardCharsets .UTF_8 ), DynamicFPSConfig .class );
130
+ }
131
+
132
+ private static void upgradeConfig (JsonObject config ) {
133
+ // v3.3.0
134
+ upgradeVolumeMultiplier (config );
135
+
136
+ // version agnostic
137
+ addMissingFields (config , (JsonObject ) GSON .toJsonTree (DynamicFPSConfig .DEFAULT ));
138
+ }
139
+
140
+ private static void addMissingFields (JsonObject config , JsonObject parent ) {
141
+ // Recursively add all fields that are missing from the user config
142
+
143
+ parent .entrySet ().forEach (entry -> {
144
+ String name = entry .getKey ();
145
+
146
+ JsonElement other = entry .getValue ();
147
+ JsonElement value = config .get (name );
148
+
149
+ if (value == null ) {
150
+ config .add (name , other );
151
+ } else if (value .isJsonObject () && other .isJsonObject ()) {
152
+ addMissingFields ((JsonObject ) value , (JsonObject ) other );
153
+ }
154
+ });
108
155
}
109
156
110
157
private static void upgradeVolumeMultiplier (JsonObject root ) {
@@ -143,47 +190,6 @@ private static void upgradeVolumeMultiplier(JsonObject root) {
143
190
}
144
191
}
145
192
146
- private static void addAbandonedConfig (JsonObject root ) {
147
- // Add default config for abandoned power state
148
- JsonObject states = getStatesAsObject (root );
149
-
150
- if (states == null ) {
151
- return ;
152
- }
153
-
154
- if (states .has ("abandoned" )) {
155
- return ;
156
- }
157
-
158
- states .add ("abandoned" , GSON .toJsonTree (Config .getDefault (PowerState .ABANDONED )));
159
- }
160
-
161
- private static void addUncapMenuFrameRate (JsonObject root ) {
162
- // Add uncap_menu_frame_rate field if it's missing
163
- if (!root .has ("uncap_menu_frame_rate" )) {
164
- root .addProperty ("uncap_menu_frame_rate" , false );
165
- }
166
- }
167
-
168
- private static void addEnabled (JsonObject root ) {
169
- // Add enabled field if it's missing
170
- if (!root .has ("enabled" )) {
171
- root .addProperty ("enabled" , true );
172
- }
173
- }
174
-
175
- private static void addVolumeTransitionSpeed (JsonObject root ) {
176
- // Add volume_transition_speed object if it's missing
177
- if (!root .has ("volume_transition_speed" )) {
178
- JsonObject object = new JsonObject ();
179
-
180
- object .addProperty ("up" , 1.0f );
181
- object .addProperty ("down" , 0.5f );
182
-
183
- root .add ("volume_transition_speed" , object );
184
- }
185
- }
186
-
187
193
private static @ Nullable JsonObject getStatesAsObject (JsonObject root ) {
188
194
if (!root .has ("states" )) {
189
195
return null ;
0 commit comments