浏览代码

Entrypoint initialization (closes #10)

Lortseam 4 年之前
父节点
当前提交
77c767aaa7

+ 0 - 43
src/main/java/me/lortseam/completeconfig/ClientConfigHandler.java

@@ -1,43 +0,0 @@
-package me.lortseam.completeconfig;
-
-import me.lortseam.completeconfig.gui.GuiBuilder;
-import me.lortseam.completeconfig.gui.cloth.ClothGuiBuilder;
-import net.fabricmc.loader.api.FabricLoader;
-import net.minecraft.client.gui.screen.Screen;
-
-import java.util.Objects;
-
-public final class ClientConfigHandler extends ConfigHandler {
-
-    private GuiBuilder guiBuilder;
-
-    ClientConfigHandler(String modID) {
-        super(modID);
-    }
-
-    /**
-     * Sets a custom GUI builder.
-     * @param guiBuilder The GUI builder for the mod's config
-     */
-    public void setGuiBuilder(GuiBuilder guiBuilder) {
-        Objects.requireNonNull(guiBuilder);
-        this.guiBuilder = guiBuilder;
-    }
-
-    /**
-     * Generates the configuration GUI.
-     * @param parentScreen The parent screen
-     * @return The generated configuration screen
-     */
-    public Screen buildScreen(Screen parentScreen) {
-        if (guiBuilder == null) {
-            if (FabricLoader.getInstance().isModLoaded("cloth-config2")) {
-                guiBuilder = new ClothGuiBuilder();
-            } else {
-                throw new UnsupportedOperationException("No GUI builder provided");
-            }
-        }
-        return guiBuilder.buildScreen(parentScreen, config, this::save);
-    }
-
-}

+ 15 - 44
src/main/java/me/lortseam/completeconfig/CompleteConfig.java

@@ -1,56 +1,27 @@
 package me.lortseam.completeconfig;
 
-import lombok.AccessLevel;
-import lombok.NoArgsConstructor;
+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.HashMap;
 import java.util.Objects;
-import java.util.Optional;
 
-@NoArgsConstructor(access = AccessLevel.PRIVATE)
-public final class CompleteConfig {
+public final class CompleteConfig implements ModInitializer {
 
-    private static final HashMap<String, ConfigHandler> MANAGERS = new HashMap<>();
-
-    static {
-        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
-            for (ConfigHandler manager : MANAGERS.values()) {
-                manager.save();
+    @Override
+    public void onInitialize() {
+        for (EntrypointContainer<ConfigOwner> entrypoint : FabricLoader.getInstance().getEntrypointContainers("completeconfig", ConfigOwner.class)) {
+            ConfigOwner owner = entrypoint.getEntrypoint();
+            ConfigBuilder builder = ConfigBuilder.create(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);
             }
-        }));
-    }
-
-    /**
-     * Registers a mod.
-     *
-     * @param modID      The ID of the mod
-     * @return The {@link ConfigHandler} for the newly registered mod
-     */
-    public static ConfigHandler register(String modID) {
-        Objects.requireNonNull(modID);
-        if (MANAGERS.containsKey(modID)) {
-            throw new IllegalArgumentException("A manager with this mod ID is already registered");
-        }
-        ConfigHandler manager;
-        switch (FabricLoader.getInstance().getEnvironmentType()) {
-            case CLIENT:
-                manager = new ClientConfigHandler(modID);
-                break;
-
-            case SERVER:
-                manager = new ServerConfigHandler(modID);
-                break;
-
-            default:
-                throw new IllegalStateException("Illegal environment");
         }
-        MANAGERS.put(modID, manager);
-        return manager;
-    }
-
-    static Optional<ConfigHandler> getManager(String modID) {
-        return Optional.ofNullable(MANAGERS.get(modID));
     }
 
 }

+ 15 - 17
src/main/java/me/lortseam/completeconfig/Config.java

@@ -9,28 +9,26 @@ import me.lortseam.completeconfig.serialization.CollectionMapDeserializer;
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
 
+import java.util.List;
+
 public class Config extends CollectionMap {
 
     private static final Logger LOGGER = LogManager.getLogger();
 
-    private final JsonElement json;
-
-    Config(String modID, JsonElement json) {
+    Config(String modID, List<ConfigCategory> topLevelCategories, JsonElement json) {
         super("config." + modID);
-        this.json = json;
-    }
-
-    void registerTopLevelCategory(ConfigCategory category) {
-        if (!fill(modTranslationKey, category)) {
-            return;
-        }
-        try {
-            new GsonBuilder()
-                    .registerTypeAdapter(CollectionMapDeserializer.TYPE, new CollectionMapDeserializer(this, category.getConfigCategoryID()))
-                    .create()
-                    .fromJson(json, CollectionMapDeserializer.TYPE);
-        } catch (JsonSyntaxException e) {
-            LOGGER.warn("[CompleteConfig] An error occurred while trying to load the config for category " + category.getClass());
+        for (ConfigCategory category : topLevelCategories) {
+            if (!fill(modTranslationKey, category)) {
+                continue;
+            }
+            try {
+                new GsonBuilder()
+                        .registerTypeAdapter(CollectionMapDeserializer.TYPE, new CollectionMapDeserializer(this, category.getConfigCategoryID()))
+                        .create()
+                        .fromJson(json, CollectionMapDeserializer.TYPE);
+            } catch (JsonSyntaxException e) {
+                LOGGER.warn("[CompleteConfig] An error occurred while trying to load the config for category " + category.getClass());
+            }
         }
     }
 

+ 35 - 0
src/main/java/me/lortseam/completeconfig/ConfigBuilder.java

@@ -0,0 +1,35 @@
+package me.lortseam.completeconfig;
+
+import me.lortseam.completeconfig.api.ConfigCategory;
+import me.lortseam.completeconfig.api.ConfigOwner;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public final class ConfigBuilder {
+
+    static ConfigBuilder create(String modID, String[] branch, Class<? extends ConfigOwner> owner) {
+        return new ConfigBuilder(modID, branch, owner);
+    }
+
+    private final ConfigHandler handler;
+    private final Class<? extends ConfigOwner> owner;
+    private final List<ConfigCategory> topLevelCategories = new ArrayList<>();
+
+    private ConfigBuilder(String modID, String[] branch, Class<? extends ConfigOwner> owner) {
+        handler = new ConfigHandler(modID, branch);
+        this.owner = owner;
+    }
+
+    public ConfigBuilder add(ConfigCategory... categories) {
+        topLevelCategories.addAll(Arrays.asList(categories));
+        return this;
+    }
+
+    public ConfigHandler finish() {
+        handler.register(owner, topLevelCategories);
+        return handler;
+    }
+
+}

+ 0 - 32
src/main/java/me/lortseam/completeconfig/ConfigCreator.java

@@ -1,32 +0,0 @@
-package me.lortseam.completeconfig;
-
-import net.fabricmc.api.EnvType;
-import net.fabricmc.api.Environment;
-import net.fabricmc.loader.api.FabricLoader;
-
-public final class ConfigCreator {
-
-    @Environment(EnvType.CLIENT)
-    public ClientConfigHandler clientConfig() {
-
-    }
-
-    @Environment(EnvType.SERVER)
-    public ServerConfigHandler serverConfig() {
-
-    }
-
-    public ConfigHandler config() {
-        switch (FabricLoader.getInstance().getEnvironmentType()) {
-            case CLIENT:
-                return clientConfig();
-
-            case SERVER:
-                return serverConfig();
-
-            default:
-                //TODO
-        }
-    }
-
-}

+ 58 - 40
src/main/java/me/lortseam/completeconfig/ConfigHandler.java

@@ -2,11 +2,16 @@ package me.lortseam.completeconfig;
 
 import com.google.gson.*;
 import me.lortseam.completeconfig.api.ConfigCategory;
+import me.lortseam.completeconfig.api.ConfigOwner;
+import me.lortseam.completeconfig.gui.GuiBuilder;
+import me.lortseam.completeconfig.gui.cloth.ClothGuiBuilder;
 import me.lortseam.completeconfig.serialization.CollectionSerializer;
 import me.lortseam.completeconfig.serialization.EntrySerializer;
 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;
 
@@ -17,12 +22,9 @@ import java.io.Writer;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
-import java.util.Optional;
+import java.util.*;
 
-/**
- * Main interaction class for using the CompleteConfig API. References a single mod.
- */
-public abstract class ConfigHandler {
+public final class ConfigHandler {
 
     private static final Gson GSON = new GsonBuilder()
             .registerTypeAdapter(CollectionSerializer.TYPE, new CollectionSerializer())
@@ -30,47 +32,45 @@ public abstract class ConfigHandler {
             .setPrettyPrinting()
             .create();
     private static final Logger LOGGER = LogManager.getLogger();
+    private static final Map<Class<? extends ConfigOwner>, ConfigHandler> HANDLERS = new HashMap<>();
+
+    static {
+        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
+            for (ConfigHandler handler : HANDLERS.values()) {
+                handler.save();
+            }
+        }));
+    }
 
     private final String modID;
     private final Path jsonPath;
-    protected final Config config;
+    protected Config config;
+    @Environment(EnvType.CLIENT)
+    private GuiBuilder guiBuilder;
 
     /**
-     * Gets the {@link ConfigHandler} for the specified mod if that mod was registered before.
+     * Gets the {@link ConfigHandler} for the specified owner if that owner created a config before.
      *
-     * @param modID The ID of the mod
+     * @param owner The owner class of the config
      * @return The {@link ConfigHandler} if one was found or else an empty result
      */
-    public static Optional<ConfigHandler> of(String modID) {
-        return CompleteConfig.getManager(modID);
-    }
-
-    /**
-     * Gets the {@link ClientConfigHandler} for the specified mod if that mod was registered before.
-     *
-     * @param modID The ID of the mod
-     * @return The {@link ClientConfigHandler} if one was found or else an empty result
-     */
-    @Environment(EnvType.CLIENT)
-    public static Optional<ClientConfigHandler> ofClient(String modID) {
-        return of(modID).map(manager -> (ClientConfigHandler) manager);
+    public static Optional<ConfigHandler> of(Class<? extends ConfigOwner> owner) {
+        return Optional.ofNullable(HANDLERS.get(owner));
     }
 
-    /**
-     * Gets the {@link ServerConfigHandler} for the specified mod if that mod was registered before.
-     *
-     * @param modID The ID of the mod
-     * @return The {@link ServerConfigHandler} if one was found or else an empty result
-     */
-    @Environment(EnvType.SERVER)
-    public static Optional<ServerConfigHandler> ofServer(String modID) {
-        return of(modID).map(manager -> (ServerConfigHandler) manager);
+    ConfigHandler(String modID, String[] branch) {
+        this.modID = modID;
+        branch = ArrayUtils.add(branch, 0, modID);
+        branch[branch.length - 1] = branch[branch.length - 1] + ".json";
+        jsonPath = Paths.get(FabricLoader.getInstance().getConfigDir().toString(), branch);
     }
 
-    ConfigHandler(String modID) {
-        this.modID = modID;
-        jsonPath = Paths.get(FabricLoader.getInstance().getConfigDir().toString(), modID + ".json");
-        config = new Config(modID, load());
+    void register(Class<? extends ConfigOwner> owner, List<ConfigCategory> topLevelCategories) {
+        if (HANDLERS.containsKey(owner)) {
+            throw new IllegalArgumentException("The specified owner already created a config!");
+        }
+        HANDLERS.put(owner, this);
+        config = new Config(modID, topLevelCategories, load());
     }
 
     private JsonElement load() {
@@ -80,25 +80,43 @@ public abstract class ConfigHandler {
             } catch (FileNotFoundException e) {
                 throw new RuntimeException(e);
             } catch (JsonSyntaxException e) {
-                LOGGER.warn("[CompleteConfig] An error occurred while trying to load the config for mod " + modID);
+                LOGGER.warn("[CompleteConfig] An error occurred while trying to load the config " + jsonPath.toString());
             }
         }
         return JsonNull.INSTANCE;
     }
 
     /**
-     * Registers one or more top level categories.
-     * @param categories The categories to register
+     * Sets a custom GUI builder.
+     * @param guiBuilder The GUI builder for the mod's config
      */
-    public void register(ConfigCategory... categories) {
-        for (ConfigCategory category : categories) {
-            config.registerTopLevelCategory(category);
+    @Environment(EnvType.CLIENT)
+    public void setGuiBuilder(GuiBuilder guiBuilder) {
+        Objects.requireNonNull(guiBuilder);
+        this.guiBuilder = guiBuilder;
+    }
+
+    /**
+     * Generates the configuration GUI.
+     * @param parentScreen The parent screen
+     * @return The generated configuration screen
+     */
+    @Environment(EnvType.CLIENT)
+    public Screen buildScreen(Screen parentScreen) {
+        if (guiBuilder == null) {
+            if (FabricLoader.getInstance().isModLoaded("cloth-config2")) {
+                guiBuilder = new ClothGuiBuilder();
+            } else {
+                throw new UnsupportedOperationException("No GUI builder provided");
+            }
         }
+        return guiBuilder.buildScreen(parentScreen, config, this::save);
     }
 
     /**
      * Saves the config to a save file.
      */
+    //TODO: Needs public access?
     public void save() {
         if (!Files.exists(jsonPath)) {
             try {

+ 0 - 9
src/main/java/me/lortseam/completeconfig/ServerConfigHandler.java

@@ -1,9 +0,0 @@
-package me.lortseam.completeconfig;
-
-public final class ServerConfigHandler extends ConfigHandler {
-
-    ServerConfigHandler(String modID) {
-        super(modID);
-    }
-
-}

+ 0 - 9
src/main/java/me/lortseam/completeconfig/api/ConfigHolder.java

@@ -1,9 +0,0 @@
-package me.lortseam.completeconfig.api;
-
-public interface ConfigHolder {
-
-    default void createClientConfig() {
-
-    }
-
-}

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

@@ -0,0 +1,21 @@
+package me.lortseam.completeconfig.api;
+
+import me.lortseam.completeconfig.ConfigBuilder;
+
+public interface ConfigOwner {
+
+    default void onInitializeConfig(ConfigBuilder creator) {}
+
+    default void onInitializeClientConfig(ConfigBuilder creator) {
+        onInitializeConfig(creator);
+    }
+
+    default void onInitializeServerConfig(ConfigBuilder creator) {
+        onInitializeConfig(creator);
+    }
+
+    default String[] getConfigBranch() {
+        return new String[0];
+    }
+
+}

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

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