Bladeren bron

[WIP] Added gui registry

Lortseam 5 jaren geleden
bovenliggende
commit
e00ed65714

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

@@ -1,5 +1,11 @@
 package me.lortseam.completeconfig;
 
+import com.google.common.base.CaseFormat;
+import me.lortseam.completeconfig.entry.Entry;
+import me.lortseam.completeconfig.entry.GuiRegistry;
+import me.shedaniel.clothconfig2.api.ConfigEntryBuilder;
+import net.minecraft.client.resource.language.I18n;
+
 import java.util.HashSet;
 import java.util.Optional;
 import java.util.Set;
@@ -13,10 +19,70 @@ public class CompleteConfig {
             throw new RuntimeException("There is already registered a manager for this mod ID!");
         }
         ConfigManager manager = new ConfigManager(modID);
+        registerDefaultGuiProviders(manager.getGuiRegistry());
         managers.add(manager);
         return manager;
     }
 
+    private static void registerDefaultGuiProviders(GuiRegistry registry) {
+        registry.registerTypeProvider(Boolean.TYPE, (translationKey, value, defaultValue, saveConsumer) -> ConfigEntryBuilder
+                .create()
+                .startBooleanToggle(translationKey, value)
+                .setDefaultValue(defaultValue)
+                .setSaveConsumer(saveConsumer)
+                .build()
+        );
+        registry.registerTypeProvider(Integer.TYPE, (translationKey, value, defaultValue, saveConsumer) -> ConfigEntryBuilder
+                .create()
+                .startIntField(translationKey, value)
+                .setDefaultValue(defaultValue)
+                .setSaveConsumer(saveConsumer)
+                .build()
+        );
+        registry.registerBoundedTypeProvider(Integer.TYPE, (translationKey, value, min, max, defaultValue, saveConsumer) -> ConfigEntryBuilder
+                .create()
+                .startIntSlider(translationKey, value, min, max)
+                .setDefaultValue(defaultValue)
+                .setSaveConsumer(saveConsumer)
+                .build()
+        );
+        registry.registerTypeProvider(Long.TYPE, (translationKey, value, defaultValue, saveConsumer) -> ConfigEntryBuilder
+                .create()
+                .startLongField(translationKey, value)
+                .setDefaultValue(defaultValue)
+                .setSaveConsumer(saveConsumer)
+                .build()
+        );
+        registry.registerBoundedTypeProvider(Long.TYPE, (translationKey, value, min, max, defaultValue, saveConsumer) -> ConfigEntryBuilder
+                .create()
+                .startLongSlider(translationKey, value, min, max)
+                .setDefaultValue(defaultValue)
+                .setSaveConsumer(saveConsumer)
+                .build()
+        );
+        registry.registerTypeProvider(Float.TYPE, (translationKey, value, defaultValue, saveConsumer) -> ConfigEntryBuilder
+                .create()
+                .startFloatField(translationKey, value)
+                .setDefaultValue(defaultValue)
+                .setSaveConsumer(saveConsumer)
+                .build()
+        );
+        registry.registerTypeProvider(Double.TYPE, (translationKey, value, defaultValue, saveConsumer) -> ConfigEntryBuilder
+                .create()
+                .startDoubleField(translationKey, value)
+                .setDefaultValue(defaultValue)
+                .setSaveConsumer(saveConsumer)
+                .build()
+        );
+        registry.registerProvider(field -> Enum.class.isAssignableFrom(field.getDeclaringClass()), (Entry.GuiProvider<? extends Enum>) (translationKey, value, defaultValue, saveConsumer) -> ConfigEntryBuilder
+                .create()
+                .startEnumSelector(translationKey, Enum.class, value)
+                .setDefaultValue(defaultValue)
+                .setEnumNameProvider(e -> I18n.translate(translationKey + "." + CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, e.name())))
+                .setSaveConsumer(saveConsumer)
+                .build());
+    }
+
     public static Optional<ConfigManager> getManager(String modID) {
         return managers.stream().filter(manager -> manager.getModID().equals(modID)).findAny();
     }

+ 14 - 65
src/main/java/me/lortseam/completeconfig/ConfigManager.java

@@ -1,6 +1,5 @@
 package me.lortseam.completeconfig;
 
-import com.google.common.base.CaseFormat;
 import com.google.gson.Gson;
 import com.google.gson.GsonBuilder;
 import com.google.gson.JsonElement;
@@ -14,7 +13,7 @@ import me.lortseam.completeconfig.api.ConfigEntrySaveConsumer;
 import me.lortseam.completeconfig.collection.Collection;
 import me.lortseam.completeconfig.entry.BoundedEntry;
 import me.lortseam.completeconfig.entry.Entry;
-import me.lortseam.completeconfig.entry.GuiProvider;
+import me.lortseam.completeconfig.entry.GuiRegistry;
 import me.lortseam.completeconfig.saveconsumer.SaveConsumer;
 import me.lortseam.completeconfig.serialization.CollectionsDeserializer;
 import me.lortseam.completeconfig.serialization.EntrySerializer;
@@ -24,7 +23,6 @@ import me.shedaniel.clothconfig2.api.ConfigEntryBuilder;
 import me.shedaniel.clothconfig2.impl.builders.SubCategoryBuilder;
 import net.fabricmc.loader.api.FabricLoader;
 import net.minecraft.client.gui.screen.Screen;
-import net.minecraft.client.resource.language.I18n;
 import org.apache.commons.lang3.StringUtils;
 
 import java.io.*;
@@ -33,6 +31,7 @@ import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.util.*;
+import java.util.function.Supplier;
 import java.util.stream.Collectors;
 
 //TODO: Sortierung der Categories, Subcategories und Entrys (Nach Registrierungsreihenfolge oder Alphabet; allgemein und für jeden Container einzeln?)
@@ -44,13 +43,13 @@ public class ConfigManager {
     private final LinkedHashMap<String, Collection> config = new LinkedHashMap<>();
     private final JsonElement json;
     private final Set<SaveConsumer> pendingSaveConsumers = new HashSet<>();
-    private final Map<Class, GuiProvider> guiProviders = new HashMap<>();
+    @Getter
+    private final GuiRegistry guiRegistry = new GuiRegistry();
 
     ConfigManager(String modID) {
         this.modID = modID;
         jsonPath = Paths.get(FabricLoader.getInstance().getConfigDirectory().toPath().toString(), modID + ".json");
         json = load();
-        setDefaultGuiProviders();
     }
 
     private JsonElement load() {
@@ -62,61 +61,6 @@ public class ConfigManager {
         }
     }
 
-    private void setDefaultGuiProviders() {
-        setEntryGuiProvider(Boolean.TYPE, (translationKey, value, defaultValue, saveConsumer) -> ConfigEntryBuilder
-                .create()
-                .startBooleanToggle(translationKey, value)
-                .setDefaultValue(defaultValue)
-                .setSaveConsumer(saveConsumer)
-                .build()
-        );
-        setEntryGuiProvider(Enum.class, (translationKey, value, defaultValue, saveConsumer) -> ConfigEntryBuilder
-                .create()
-                .startEnumSelector(translationKey, Enum.class, value)
-                .setDefaultValue(defaultValue)
-                .setEnumNameProvider(e -> I18n.translate(joinIDs(translationKey, CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, e.name()))))
-                .setSaveConsumer(saveConsumer)
-                .build()
-        );
-        setEntryGuiProvider(Integer.TYPE, (translationKey, value, defaultValue, saveConsumer) -> ConfigEntryBuilder
-                .create()
-                .startIntField(translationKey, value)
-                .setDefaultValue(defaultValue)
-                .setSaveConsumer(saveConsumer)
-                .build()
-        );
-        setEntryGuiProvider(Long.TYPE, (translationKey, value, defaultValue, saveConsumer) -> ConfigEntryBuilder
-                .create()
-                .startLongField(translationKey, value)
-                .setDefaultValue(defaultValue)
-                .setSaveConsumer(saveConsumer)
-                .build()
-        );
-        //TODO: Bounded
-        /*BoundedEntry<Integer> boundedIntEntry = (BoundedEntry<Integer>) entry;
-        fieldBuilder = builder.startIntSlider(translationKey, (Integer) value, boundedIntEntry.getMin(), boundedIntEntry.getMax())
-                .setDefaultValue(boundedIntEntry.getDefaultValue())
-                .setSaveConsumer(boundedIntEntry::setValue);
-        BoundedEntry<Long> boundedLongEntry = (BoundedEntry<Long>) entry;
-        fieldBuilder = builder.startLongSlider(translationKey, (Long) value, boundedLongEntry.getMin(), boundedLongEntry.getMax())
-                .setDefaultValue(boundedLongEntry.getDefaultValue())
-                .setSaveConsumer(boundedLongEntry::setValue);*/
-        setEntryGuiProvider(Float.TYPE, (translationKey, value, defaultValue, saveConsumer) -> ConfigEntryBuilder
-                .create()
-                .startFloatField(translationKey, value)
-                .setDefaultValue(defaultValue)
-                .setSaveConsumer(saveConsumer)
-                .build()
-        );
-        setEntryGuiProvider(Double.TYPE, (translationKey, value, defaultValue, saveConsumer) -> ConfigEntryBuilder
-                .create()
-                .startDoubleField(translationKey, value)
-                .setDefaultValue(defaultValue)
-                .setSaveConsumer(saveConsumer)
-                .build()
-        );
-    }
-
     private LinkedHashMap<String, Entry> getContainerEntries(ConfigEntryContainer container) {
         LinkedHashMap<String, Entry> entries = new LinkedHashMap<>();
         Class clazz = container.getClass();
@@ -178,6 +122,9 @@ public class ConfigManager {
                 } else {
                     entry = new Entry<>(field, field.getType(), container, translationKey);
                 }
+                if (!guiRegistry.hasProvider(entry)) {
+                    throw new RuntimeException("Could not find gui provider for type " + entry.getType());
+                }
                 String fieldName = field.getName();
                 saveConsumers.removeIf(saveConsumer -> {
                     if (!saveConsumer.getFieldName().equals(fieldName)) {
@@ -208,10 +155,6 @@ public class ConfigManager {
         return entries;
     }
 
-    public <T> void setEntryGuiProvider(Class<T> entryValueType, GuiProvider<T> guiProvider) {
-        guiProviders.put(entryValueType, guiProvider);
-    }
-
     public void register(ConfigCategory... categories) {
         Arrays.stream(categories).forEach(category -> registerCategory(config, category, true));
     }
@@ -284,7 +227,13 @@ public class ConfigManager {
         List<AbstractConfigListEntry> list = new ArrayList<>();
         collection.getEntries().forEach((entryID, entry) -> {
             String translationKey = entry.getTranslationKey() != null ? buildTranslationKey(entry.getTranslationKey()) : buildTranslationKey(parentID, entryID);
-            list.add(guiProviders.get(entry.getType()).build(translationKey, entry.getValue(), entry.getDefaultValue(), entry::setValue));
+            AbstractConfigListEntry guiEntry;
+            if (entry instanceof BoundedEntry) {
+                guiEntry = guiRegistry.getBoundedProvider((BoundedEntry) entry).build(translationKey, entry.getValue(), ((BoundedEntry) entry).getMin(), ((BoundedEntry) entry).getMax(), entry.getDefaultValue(), entry::setValue);
+            } else {
+                guiEntry = guiRegistry.getProvider(entry).build(translationKey, entry.getValue(), entry.getDefaultValue(), entry::setValue);
+            }
+            list.add(guiEntry);
         });
         collection.getCollections().forEach((subcategoryID, c) -> {
             String id = joinIDs(parentID, subcategoryID);

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

@@ -2,8 +2,10 @@ package me.lortseam.completeconfig.entry;
 
 import lombok.Getter;
 import me.lortseam.completeconfig.api.ConfigEntryContainer;
+import me.shedaniel.clothconfig2.api.AbstractConfigListEntry;
 
 import java.lang.reflect.Field;
+import java.util.function.Consumer;
 
 //TODO: Bound auch beim Einlesen aus JSON beachten
 public class BoundedEntry<T extends Number> extends Entry<T> {
@@ -17,4 +19,11 @@ public class BoundedEntry<T extends Number> extends Entry<T> {
         this.max = max;
     }
 
+    @FunctionalInterface
+    public interface GuiProvider<T> {
+
+        AbstractConfigListEntry build(String translationKey, T value, T min, T max, T defaultValue, Consumer<T> saveConsumer);
+
+    }
+
 }

+ 11 - 0
src/main/java/me/lortseam/completeconfig/entry/Entry.java

@@ -1,16 +1,20 @@
 package me.lortseam.completeconfig.entry;
 
+import lombok.AccessLevel;
 import lombok.Getter;
 import me.lortseam.completeconfig.api.ConfigEntryContainer;
+import me.shedaniel.clothconfig2.api.AbstractConfigListEntry;
 
 import java.lang.reflect.Field;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.function.Consumer;
 
 public class Entry<T> {
 
+    @Getter(AccessLevel.PACKAGE)
     private final Field field;
     @Getter
     private final Class<T> type;
@@ -67,4 +71,11 @@ public class Entry<T> {
         saveConsumers.put(method, parentObject);
     }
 
+    @FunctionalInterface
+    public interface GuiProvider<T> {
+
+        AbstractConfigListEntry<T> build(String translationKey, T value, T defaultValue, Consumer<T> saveConsumer);
+
+    }
+
 }

+ 0 - 12
src/main/java/me/lortseam/completeconfig/entry/GuiProvider.java

@@ -1,12 +0,0 @@
-package me.lortseam.completeconfig.entry;
-
-import me.shedaniel.clothconfig2.api.AbstractConfigListEntry;
-
-import java.util.function.Consumer;
-
-@FunctionalInterface
-public interface GuiProvider<T> {
-
-    AbstractConfigListEntry<T> build(String translationKey, T value, T defaultValue, Consumer<T> saveConsumer);
-
-}

+ 55 - 0
src/main/java/me/lortseam/completeconfig/entry/GuiRegistry.java

@@ -0,0 +1,55 @@
+package me.lortseam.completeconfig.entry;
+
+import java.lang.reflect.Field;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.function.Predicate;
+
+public class GuiRegistry {
+
+    private final LinkedHashMap<Predicate<Field>, Entry.GuiProvider> entryGuiProviders = new LinkedHashMap<>();
+    private final LinkedHashMap<Predicate<Field>, BoundedEntry.GuiProvider> boundedEntryGuiProviders = new LinkedHashMap<>();
+
+    public void registerProvider(Predicate<Field> predicate, Entry.GuiProvider provider) {
+        entryGuiProviders.put(predicate, provider);
+    }
+
+    public <T> void registerTypeProvider(Class<T> type, Entry.GuiProvider<T> provider) {
+        registerProvider((field) -> field.getDeclaringClass() == type, provider);
+    }
+
+    public void registerBoundedProvider(Predicate<Field> predicate, BoundedEntry.GuiProvider provider) {
+        boundedEntryGuiProviders.put(predicate, provider);
+    }
+
+    public <T> void registerBoundedTypeProvider(Class<T> type, BoundedEntry.GuiProvider<T> provider) {
+        registerBoundedProvider((field) -> field.getDeclaringClass() == type, provider);
+    }
+
+    private <T> T getHighestPriorityProvider(LinkedHashMap<Predicate<Field>, T> providers, Entry entry) {
+        T guiProvider = null;
+        for (Map.Entry<Predicate<Field>, T> mapEntry : providers.entrySet()) {
+            if (mapEntry.getKey().test(entry.getField())) {
+                guiProvider = mapEntry.getValue();
+            }
+        }
+        return guiProvider;
+    }
+
+    public Entry.GuiProvider getProvider(Entry entry) {
+        return getHighestPriorityProvider(entryGuiProviders, entry);
+    }
+
+    public BoundedEntry.GuiProvider getBoundedProvider(BoundedEntry entry) {
+        return getHighestPriorityProvider(boundedEntryGuiProviders, entry);
+    }
+
+    public boolean hasProvider(Entry entry) {
+        if (entry instanceof BoundedEntry) {
+            return getBoundedProvider((BoundedEntry) entry) != null;
+        } else {
+            return getProvider(entry) != null;
+        }
+    }
+
+}