Quellcode durchsuchen

Removed entrypoint initialization in favor of more flexible config builder

Lortseam vor 4 Jahren
Ursprung
Commit
487f0e3cf0

+ 0 - 27
src/main/java/me/lortseam/completeconfig/CompleteConfig.java

@@ -1,27 +0,0 @@
-package me.lortseam.completeconfig;
-
-import me.lortseam.completeconfig.api.ConfigOwner;
-import net.fabricmc.api.EnvType;
-import net.fabricmc.api.ModInitializer;
-import net.fabricmc.loader.api.FabricLoader;
-import net.fabricmc.loader.api.entrypoint.EntrypointContainer;
-
-import java.util.Objects;
-
-public final class CompleteConfig implements ModInitializer {
-
-    @Override
-    public void onInitialize() {
-        for (EntrypointContainer<ConfigOwner> entrypoint : FabricLoader.getInstance().getEntrypointContainers("completeconfig", ConfigOwner.class)) {
-            ConfigOwner owner = entrypoint.getEntrypoint();
-            ConfigBuilder builder = new ConfigBuilder(entrypoint.getProvider().getMetadata().getId(), Objects.requireNonNull(owner.getConfigBranch()), owner.getClass());
-            if (FabricLoader.getInstance().getEnvironmentType() == EnvType.CLIENT) {
-                owner.onInitializeClientConfig(builder);
-            }
-            if (FabricLoader.getInstance().getEnvironmentType() == EnvType.SERVER) {
-                owner.onInitializeServerConfig(builder);
-            }
-        }
-    }
-
-}

+ 26 - 13
src/main/java/me/lortseam/completeconfig/ConfigBuilder.java

@@ -1,8 +1,9 @@
 package me.lortseam.completeconfig;
 
 import me.lortseam.completeconfig.api.ConfigGroup;
-import me.lortseam.completeconfig.api.ConfigOwner;
 import me.lortseam.completeconfig.gui.GuiBuilder;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
 import org.spongepowered.configurate.serialize.TypeSerializerCollection;
 
 import java.util.ArrayList;
@@ -12,17 +13,33 @@ import java.util.Objects;
 
 public final class ConfigBuilder {
 
+    private static final Logger LOGGER = LogManager.getLogger();
+
     private final String modID;
     private final String[] branch;
-    private final Class<? extends ConfigOwner> owner;
     private final List<ConfigGroup> topLevelGroups = new ArrayList<>();
     private TypeSerializerCollection typeSerializers;
     private GuiBuilder guiBuilder;
 
-    ConfigBuilder(String modID, String[] branch, Class<? extends ConfigOwner> owner) {
+    /**
+     * Creates a new config builder for the specified mod with a custom branch.
+     *
+     * <p>The config branch determines the location of the config's save file.
+     *
+     * @param modID the ID of the mod creating the config
+     */
+    public ConfigBuilder(String modID, String[] branch) {
         this.modID = modID;
         this.branch = branch;
-        this.owner = owner;
+    }
+
+    /**
+     * Creates a new config builder for the specified mod.
+     *
+     * @param modID the ID of the mod creating the config
+     */
+    public ConfigBuilder(String modID) {
+        this(modID, new String[0]);
     }
 
     /**
@@ -67,15 +84,11 @@ public final class ConfigBuilder {
      * @return the handler associated with the created config
      */
     public ConfigHandler build() {
-        return ConfigHandler.buildConfig(modID, branch, owner, topLevelGroups, typeSerializers, guiBuilder);
-    }
-
-    /**
-     * @deprecated Use {@link #build()}
-     */
-    @Deprecated
-    public ConfigHandler finish() {
-        return build();
+        if (topLevelGroups.isEmpty()) {
+            LOGGER.warn("[CompleteConfig] Mod " + modID + " tried to create an empty config!");
+            return null;
+        }
+        return new ConfigHandler(new ConfigSource(modID, branch, typeSerializers), topLevelGroups, guiBuilder);
     }
 
 }

+ 13 - 75
src/main/java/me/lortseam/completeconfig/ConfigHandler.java

@@ -1,94 +1,38 @@
 package me.lortseam.completeconfig;
 
-import me.lortseam.completeconfig.api.ConfigGroup;
-import me.lortseam.completeconfig.api.ConfigOwner;
 import me.lortseam.completeconfig.data.Config;
+import me.lortseam.completeconfig.api.ConfigGroup;
 import me.lortseam.completeconfig.gui.GuiBuilder;
 import net.fabricmc.api.EnvType;
 import net.fabricmc.api.Environment;
-import net.fabricmc.loader.api.FabricLoader;
 import net.minecraft.client.gui.screen.Screen;
-import org.apache.commons.lang3.ArrayUtils;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-import org.spongepowered.configurate.CommentedConfigurationNode;
-import org.spongepowered.configurate.ConfigurateException;
-import org.spongepowered.configurate.hocon.HoconConfigurationLoader;
-import org.spongepowered.configurate.serialize.TypeSerializerCollection;
 
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.*;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
 
 public final class ConfigHandler {
 
-    private static final Logger LOGGER = LogManager.getLogger();
-    private static final Map<Class<? extends ConfigOwner>, ConfigHandler> HANDLERS = new HashMap<>();
-    private static final Map<String, List<String[]>> MOD_BRANCHES = new HashMap<>();
+    private static final Set<ConfigHandler> HANDLERS = new HashSet<>();
 
     static {
         Runtime.getRuntime().addShutdownHook(new Thread(() -> {
-            for (ConfigHandler handler : HANDLERS.values()) {
+            for (ConfigHandler handler : HANDLERS) {
                 handler.save();
             }
         }));
     }
 
-    static ConfigHandler buildConfig(String modID, String[] branch, Class<? extends ConfigOwner> owner, List<ConfigGroup> topLevelGroups, TypeSerializerCollection typeSerializers, GuiBuilder guiBuilder) {
-        if (HANDLERS.containsKey(owner)) {
-            throw new IllegalArgumentException("The specified owner " + owner + " already created a config!");
-        }
-        if (topLevelGroups.isEmpty()) {
-            LOGGER.warn("[CompleteConfig] Owner " + owner + " of mod " + modID + " tried to create an empty config!");
-            return null;
-        }
-        List<String[]> branches = MOD_BRANCHES.computeIfAbsent(modID, key -> new ArrayList<>());
-        if (branches.stream().anyMatch(presentBranch -> Arrays.equals(branch, presentBranch))) {
-            throw new IllegalArgumentException("A config of the mod " + modID + " with the specified branch " + Arrays.toString(branch) + " already exists!");
-        }
-        branches.add(branch);
-        String[] subPath = ArrayUtils.add(branch, 0, modID);
-        subPath[subPath.length - 1] = subPath[subPath.length - 1] + ".conf";
-        Path filePath = Paths.get(FabricLoader.getInstance().getConfigDir().toString(), subPath);
-        ConfigHandler handler = new ConfigHandler(modID, filePath, topLevelGroups, typeSerializers, guiBuilder);
-        HANDLERS.put(owner, handler);
-        return handler;
-    }
-
-    /**
-     * Gets the {@link ConfigHandler} for the specified owner if that owner created a config before.
-     *
-     * @param owner The owner class of the config
-     * @return The handler if one was found or else an empty result
-     */
-    public static Optional<ConfigHandler> of(Class<? extends ConfigOwner> owner) {
-        return Optional.ofNullable(HANDLERS.get(owner));
-    }
-
-    private final HoconConfigurationLoader loader;
+    private final ConfigSource source;
     private final Config config;
     private GuiBuilder guiBuilder;
 
-    private ConfigHandler(String modID, Path filePath, List<ConfigGroup> topLevelGroups, TypeSerializerCollection typeSerializers, GuiBuilder guiBuilder) {
-        loader = HoconConfigurationLoader.builder()
-                .path(filePath)
-                .defaultOptions(options -> options.serializers(builder -> builder.registerAll(typeSerializers)))
-                .build();
-        config = new Config(modID, topLevelGroups);
-        CommentedConfigurationNode root = load();
-        if (!root.virtual()) {
-            config.apply(root);
-        }
+    ConfigHandler(ConfigSource source, List<ConfigGroup> topLevelGroups, GuiBuilder guiBuilder) {
+        this.source = source;
+        config = new Config(source.getModID(), topLevelGroups);
         this.guiBuilder = guiBuilder;
-    }
-
-    private CommentedConfigurationNode load() {
-        try {
-            return loader.load();
-        } catch (ConfigurateException e) {
-            LOGGER.error("[CompleteConfig] Failed to load config from file!", e);
-        }
-        return CommentedConfigurationNode.root();
+        HANDLERS.add(this);
+        source.load(config);
     }
 
     /**
@@ -113,13 +57,7 @@ public final class ConfigHandler {
      * Saves the config to a save file.
      */
     public void save() {
-        CommentedConfigurationNode root = loader.createNode();
-        config.fetch(root);
-        try {
-            loader.save(root);
-        } catch (ConfigurateException e) {
-            LOGGER.error("[CompleteConfig] Failed to save config to file!", e);
-        }
+        source.save(config);
     }
 
 }

+ 87 - 0
src/main/java/me/lortseam/completeconfig/ConfigSource.java

@@ -0,0 +1,87 @@
+package me.lortseam.completeconfig;
+
+import lombok.AccessLevel;
+import lombok.Getter;
+import me.lortseam.completeconfig.data.Config;
+import net.fabricmc.loader.api.FabricLoader;
+import org.apache.commons.lang3.ArrayUtils;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.spongepowered.configurate.CommentedConfigurationNode;
+import org.spongepowered.configurate.ConfigurateException;
+import org.spongepowered.configurate.hocon.HoconConfigurationLoader;
+import org.spongepowered.configurate.serialize.TypeSerializerCollection;
+
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Objects;
+
+final class ConfigSource {
+
+    private static final Logger LOGGER = LogManager.getLogger();
+    private static final HashSet<ConfigSource> SOURCES = new HashSet<>();
+
+    @Getter(AccessLevel.PACKAGE)
+    private final String modID;
+    private final String[] branch;
+    private final HoconConfigurationLoader loader;
+
+    ConfigSource(String modID, String[] branch, TypeSerializerCollection typeSerializers) {
+        this.modID = modID;
+        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!");
+        }
+        String[] subPath = ArrayUtils.add(branch, 0, modID);
+        subPath[subPath.length - 1] = subPath[subPath.length - 1] + ".conf";
+        Path filePath = Paths.get(FabricLoader.getInstance().getConfigDir().toString(), subPath);
+        loader = HoconConfigurationLoader.builder()
+                .path(filePath)
+                .defaultOptions(options -> {
+                    if (typeSerializers != null) {
+                        options.serializers(builder -> builder.registerAll(typeSerializers));
+                    }
+                    return options;
+                })
+                .build();
+    }
+
+    void load(Config config) {
+        try {
+            CommentedConfigurationNode root = loader.load();
+            if (!root.virtual()) {
+                config.apply(root);
+            }
+        } catch (ConfigurateException e) {
+            LOGGER.error("[CompleteConfig] Failed to load config from file!", e);
+        }
+    }
+
+    void save(Config config) {
+        CommentedConfigurationNode root = loader.createNode();
+        config.fetch(root);
+        try {
+            loader.save(root);
+        } catch (ConfigurateException e) {
+            LOGGER.error("[CompleteConfig] Failed to save config to file!", e);
+        }
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        ConfigSource that = (ConfigSource) o;
+        return modID.equals(that.modID) && Arrays.equals(branch, that.branch);
+    }
+
+    @Override
+    public int hashCode() {
+        int result = Objects.hash(modID);
+        result = 31 * result + Arrays.hashCode(branch);
+        return result;
+    }
+
+}

+ 0 - 48
src/main/java/me/lortseam/completeconfig/api/ConfigOwner.java

@@ -1,48 +0,0 @@
-package me.lortseam.completeconfig.api;
-
-import me.lortseam.completeconfig.ConfigBuilder;
-
-/**
- * This entrypoint is called to create a config in a specific environment or in both environments.
- *
- * <p>In {@code fabric.mod.json}, the entrypoint is defined with the {@code completeconfig} key.</p>
- */
-public interface ConfigOwner {
-
-    /**
-     * Called on the client side and server side to initialize a config associated with this entrypoint's mod.
-     *
-     * @param builder The config builder
-     */
-    default void onInitializeConfig(ConfigBuilder builder) {}
-
-    /**
-     * Called on the client side to initialize a config associated with this entrypoint's mod.
-     *
-     * @param builder The config builder
-     */
-    default void onInitializeClientConfig(ConfigBuilder builder) {
-        onInitializeConfig(builder);
-    }
-
-    /**
-     * Called on the server side to initialize a config associated with this entrypoint's mod.
-     *
-     * @param builder The config builder
-     */
-    default void onInitializeServerConfig(ConfigBuilder builder) {
-        onInitializeConfig(builder);
-    }
-
-    /**
-     * Used to set a specific branch for the config(s) created using this entrypoint.
-     *
-     * <p>A config branch defines the location of the config's save file.
-     *
-     * @return the config branch
-     */
-    default String[] getConfigBranch() {
-        return new String[0];
-    }
-
-}

+ 1 - 5
src/main/resources/fabric.mod.json

@@ -17,11 +17,7 @@
   "license": "Apache-2.0",
 
   "environment": "*",
-  "entrypoints": {
-    "main": [
-      "me.lortseam.completeconfig.CompleteConfig"
-    ]
-  },
+  "entrypoints": {},
   "depends": {
     "fabricloader": ">=0.9.0"
   },