Browse Source

Add mod controller with mod-global type serializers

Lortseam 4 năm trước cách đây
mục cha
commit
208e097407

+ 2 - 1
src/main/java/me/lortseam/completeconfig/ConfigBuilder.java

@@ -2,6 +2,7 @@ package me.lortseam.completeconfig;
 
 import me.lortseam.completeconfig.api.ConfigGroup;
 import me.lortseam.completeconfig.gui.GuiBuilder;
+import me.lortseam.completeconfig.io.ConfigSource;
 import me.lortseam.completeconfig.util.TypeUtils;
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
@@ -88,7 +89,7 @@ public final class ConfigBuilder {
             LOGGER.warn("[CompleteConfig] Mod " + modID + " tried to create an empty config!");
             return null;
         }
-        return new ConfigHandler(new ConfigSource(modID, branch, typeSerializers), topLevelGroups, guiBuilder);
+        return new ConfigHandler(new ConfigSource(ModController.of(modID), branch, typeSerializers), topLevelGroups, guiBuilder);
     }
 
 }

+ 4 - 5
src/main/java/me/lortseam/completeconfig/ConfigHandler.java

@@ -3,6 +3,7 @@ package me.lortseam.completeconfig;
 import me.lortseam.completeconfig.api.ConfigGroup;
 import me.lortseam.completeconfig.data.Config;
 import me.lortseam.completeconfig.gui.GuiBuilder;
+import me.lortseam.completeconfig.io.ConfigSource;
 import net.fabricmc.api.EnvType;
 import net.fabricmc.api.Environment;
 import net.minecraft.client.gui.screen.Screen;
@@ -23,16 +24,14 @@ public final class ConfigHandler {
         }));
     }
 
-    private final ConfigSource source;
     private final Config config;
     private GuiBuilder guiBuilder;
 
     ConfigHandler(ConfigSource source, List<ConfigGroup> topLevelGroups, GuiBuilder guiBuilder) {
-        this.source = source;
-        config = new Config(source.getModID(), topLevelGroups);
+        config = new Config(source, topLevelGroups);
         this.guiBuilder = guiBuilder;
         handlers.add(this);
-        source.load(config);
+        config.load();
     }
 
     /**
@@ -57,7 +56,7 @@ public final class ConfigHandler {
      * Saves the config to the dedicated save file.
      */
     public void save() {
-        source.save(config);
+        config.save();
     }
 
 }

+ 59 - 0
src/main/java/me/lortseam/completeconfig/ModController.java

@@ -0,0 +1,59 @@
+package me.lortseam.completeconfig;
+
+import lombok.AccessLevel;
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import me.lortseam.completeconfig.data.ColorEntry;
+import me.lortseam.completeconfig.util.TypeUtils;
+import net.fabricmc.loader.api.FabricLoader;
+import net.fabricmc.loader.api.ModContainer;
+import net.fabricmc.loader.api.metadata.ModMetadata;
+import org.spongepowered.configurate.serialize.TypeSerializerCollection;
+
+import java.util.HashMap;
+import java.util.Map;
+
+@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
+public final class ModController {
+
+    private static final Map<String, ModController> controllers = new HashMap<>();
+    private static final TypeSerializerCollection GLOBAL_TYPE_SERIALIZERS = TypeSerializerCollection.builder()
+            .registerExact(ColorEntry.TEXT_COLOR_SERIALIZER)
+            .build();
+
+    /**
+     * Gets the mod controller of a loaded mod.
+     *
+     * @param id the ID of the mod
+     * @return the corresponding mod controller
+     */
+    public static ModController of(String id) {
+        ModMetadata metadata = FabricLoader.getInstance().getModContainer(id).map(ModContainer::getMetadata).orElseThrow(() -> {
+            return new IllegalArgumentException("Mod " + id + " is not loaded");
+        });
+        if (!controllers.containsKey(metadata.getId())) {
+            ModController controller = new ModController(metadata);
+            controllers.put(metadata.getId(), controller);
+            return controller;
+        }
+        return controllers.get(metadata.getId());
+    }
+
+    private final ModMetadata metadata;
+    @Getter
+    private TypeSerializerCollection typeSerializers = GLOBAL_TYPE_SERIALIZERS.childBuilder().build();
+
+    public String getID() {
+        return metadata.getId();
+    }
+
+    /**
+     * Registers custom type serializers, applied to all following mod configs.
+     *
+     * @param typeSerializers the type serializers
+     */
+    public void registerTypeSerializers(TypeSerializerCollection typeSerializers) {
+        this.typeSerializers = TypeUtils.mergeSerializers(this.typeSerializers, typeSerializers);
+    }
+
+}

+ 14 - 2
src/main/java/me/lortseam/completeconfig/data/Config.java

@@ -1,5 +1,6 @@
 package me.lortseam.completeconfig.data;
 
+import me.lortseam.completeconfig.io.ConfigSource;
 import me.lortseam.completeconfig.api.ConfigGroup;
 import me.lortseam.completeconfig.data.gui.TranslationIdentifier;
 
@@ -7,8 +8,11 @@ import java.util.List;
 
 public class Config extends CollectionMap {
 
-    public Config(String modID, List<ConfigGroup> topLevelGroups) {
-        super(new TranslationIdentifier(modID));
+    private final ConfigSource source;
+
+    public Config(ConfigSource source, List<ConfigGroup> topLevelGroups) {
+        super(new TranslationIdentifier(source.getModID()));
+        this.source = source;
         for (ConfigGroup group : topLevelGroups) {
             resolve(group);
         }
@@ -18,4 +22,12 @@ public class Config extends CollectionMap {
         return translation;
     }
 
+    public void load() {
+        source.load(this);
+    }
+
+    public void save() {
+        source.save(this);
+    }
+
 }

+ 9 - 13
src/main/java/me/lortseam/completeconfig/ConfigSource.java → src/main/java/me/lortseam/completeconfig/io/ConfigSource.java

@@ -1,8 +1,7 @@
-package me.lortseam.completeconfig;
+package me.lortseam.completeconfig.io;
 
-import lombok.AccessLevel;
 import lombok.Getter;
-import me.lortseam.completeconfig.data.ColorEntry;
+import me.lortseam.completeconfig.ModController;
 import me.lortseam.completeconfig.data.Config;
 import net.fabricmc.loader.api.FabricLoader;
 import org.apache.commons.lang3.ArrayUtils;
@@ -20,21 +19,18 @@ import java.util.HashSet;
 import java.util.Objects;
 import java.util.Set;
 
-final class ConfigSource {
+public final class ConfigSource {
 
     private static final Logger LOGGER = LogManager.getLogger();
-    private static final TypeSerializerCollection CUSTOM_SERIALIZERS = TypeSerializerCollection.builder()
-            .registerExact(ColorEntry.TEXT_COLOR_SERIALIZER)
-            .build();
     private static final Set<ConfigSource> sources = new HashSet<>();
 
-    @Getter(AccessLevel.PACKAGE)
+    @Getter
     private final String modID;
     private final String[] branch;
     private final HoconConfigurationLoader loader;
 
-    ConfigSource(String modID, String[] branch, TypeSerializerCollection typeSerializers) {
-        this.modID = modID;
+    public ConfigSource(ModController mod, String[] branch, TypeSerializerCollection typeSerializers) {
+        this.modID = mod.getID();
         this.branch = branch;
         if (!sources.add(this)) {
             throw new IllegalArgumentException("A config of the mod " + modID + " with the specified branch " + Arrays.toString(branch) + " already exists!");
@@ -45,7 +41,7 @@ final class ConfigSource {
         loader = HoconConfigurationLoader.builder()
                 .path(filePath)
                 .defaultOptions(options -> options.serializers(builder -> {
-                    builder.registerAll(CUSTOM_SERIALIZERS);
+                    builder.registerAll(mod.getTypeSerializers());
                     if (typeSerializers != null) {
                         builder.registerAll(typeSerializers);
                     }
@@ -53,7 +49,7 @@ final class ConfigSource {
                 .build();
     }
 
-    void load(Config config) {
+    public void load(Config config) {
         try {
             CommentedConfigurationNode root = loader.load();
             if (!root.virtual()) {
@@ -64,7 +60,7 @@ final class ConfigSource {
         }
     }
 
-    void save(Config config) {
+    public void save(Config config) {
         CommentedConfigurationNode root = loader.createNode();
         config.fetch(root);
         try {