2020import com .google .gson .*;
2121import com .google .gson .annotations .JsonAdapter ;
2222import com .google .gson .annotations .SerializedName ;
23- import javafx .beans .InvalidationListener ;
2423import javafx .beans .Observable ;
2524import javafx .beans .property .*;
2625import javafx .collections .FXCollections ;
3837import org .jackhuang .hmcl .ui .FXUtils ;
3938import org .jackhuang .hmcl .util .gson .*;
4039import org .jackhuang .hmcl .util .i18n .SupportedLocale ;
41- import org .jackhuang .hmcl .util .javafx .DirtyTracker ;
42- import org .jackhuang .hmcl .util .javafx .ObservableHelper ;
4340import org .jetbrains .annotations .Nullable ;
4441
45- import java .lang .invoke .MethodHandles ;
4642import java .lang .reflect .*;
4743import java .net .Proxy ;
4844import java .nio .file .Path ;
4945import java .util .*;
5046
5147@ JsonAdapter (value = Config .Adapter .class )
52- public final class Config implements Observable {
48+ public final class Config extends ObservableSetting {
5349
5450 public static final int CURRENT_VERSION = 2 ;
5551 public static final int CURRENT_UI_VERSION = 0 ;
@@ -67,54 +63,15 @@ public final class Config implements Observable {
6763 .setObjectToNumberStrategy (ToNumberPolicy .LONG_OR_DOUBLE )
6864 .create ();
6965
70- private static final List <ObservableField <Config >> FIELDS ;
71-
72- static {
73- final MethodHandles .Lookup lookup = MethodHandles .lookup ();
74- Field [] fields = Config .class .getDeclaredFields ();
75-
76- var configFields = new ArrayList <ObservableField <Config >>(fields .length );
77- for (Field field : fields ) {
78- int modifiers = field .getModifiers ();
79- if (Modifier .isTransient (modifiers ) || Modifier .isStatic (modifiers ))
80- continue ;
81-
82- configFields .add (ObservableField .of (lookup , field ));
83- }
84- FIELDS = List .copyOf (configFields );
85- }
86-
8766 @ Nullable
8867 public static Config fromJson (String json ) throws JsonParseException {
8968 return CONFIG_GSON .fromJson (json , Config .class );
9069 }
9170
92- private transient final ObservableHelper helper = new ObservableHelper (this );
93- private transient final DirtyTracker tracker = new DirtyTracker ();
94- private transient final Map <String , JsonElement > unknownFields = new HashMap <>();
95-
9671 public Config () {
97- var shouldBeWrite = Collections .<Observable >newSetFromMap (new IdentityHashMap <>());
98- Collections .addAll (shouldBeWrite , configVersion , uiVersion );
99-
100- for (var field : FIELDS ) {
101- Observable observable = field .get (this );
102- if (shouldBeWrite .contains (observable ))
103- tracker .markDirty (observable );
104- else
105- tracker .track (observable );
106- observable .addListener (helper );
107- }
108- }
109-
110- @ Override
111- public void addListener (InvalidationListener listener ) {
112- helper .addListener (listener );
113- }
114-
115- @ Override
116- public void removeListener (InvalidationListener listener ) {
117- helper .removeListener (listener );
72+ tracker .markDirty (configVersion );
73+ tracker .markDirty (uiVersion );
74+ register ();
11875 }
11976
12077 public String toJson () {
@@ -775,53 +732,10 @@ public MapProperty<String, Profile> getConfigurations() {
775732 return configurations ;
776733 }
777734
778- public static final class Adapter implements JsonSerializer <Config >, JsonDeserializer <Config > {
779-
780- @ Override
781- public JsonElement serialize (Config config , Type typeOfSrc , JsonSerializationContext context ) {
782- if (config == null )
783- return JsonNull .INSTANCE ;
784-
785- JsonObject result = new JsonObject ();
786- for (var field : FIELDS ) {
787- Observable observable = field .get (config );
788- if (config .tracker .isDirty (observable )) {
789- field .serialize (result , config , context );
790- }
791- }
792- config .unknownFields .forEach (result ::add );
793- return result ;
794- }
795-
735+ public static final class Adapter extends ObservableSetting .Adapter <Config > {
796736 @ Override
797- public Config deserialize (JsonElement json , Type typeOfT , JsonDeserializationContext context ) throws JsonParseException {
798- if (json == null || json .isJsonNull ())
799- return null ;
800-
801- if (!json .isJsonObject ())
802- throw new JsonParseException ("Config is not an object: " + json );
803-
804- Config config = new Config ();
805-
806- var values = new LinkedHashMap <>(json .getAsJsonObject ().asMap ());
807- for (ObservableField <Config > field : FIELDS ) {
808- JsonElement value = values .remove (field .getSerializedName ());
809- if (value == null ) {
810- for (String alternateName : field .getAlternateNames ()) {
811- value = values .remove (alternateName );
812- if (value != null )
813- break ;
814- }
815- }
816-
817- if (value != null ) {
818- config .tracker .markDirty (field .get (config ));
819- field .deserialize (config , value , context );
820- }
821- }
822-
823- config .unknownFields .putAll (values );
824- return config ;
737+ protected Config createInstance () {
738+ return new Config ();
825739 }
826740 }
827741}
0 commit comments