Bladeren bron

GuiProvider

Lortseam 5 jaren geleden
bovenliggende
commit
a1c6c6ea62

+ 1 - 1
gradle.properties

@@ -9,7 +9,7 @@ org.gradle.jvmargs=-Xmx1G
 
 # Mod Properties
 	mod_version = 0.1.0
-	maven_group = me.lortseam
+	maven_group = com.gitlab.Lortseam
 	archives_base_name = completeconfig
 
 # Dependencies

+ 12 - 11
src/main/java/me/lortseam/completeconfig/CompleteConfig.java

@@ -2,6 +2,7 @@ package me.lortseam.completeconfig;
 
 import com.google.common.base.CaseFormat;
 import me.lortseam.completeconfig.entry.Entry;
+import me.lortseam.completeconfig.entry.GuiProvider;
 import me.lortseam.completeconfig.entry.GuiRegistry;
 import me.shedaniel.clothconfig2.api.ConfigEntryBuilder;
 import net.minecraft.client.resource.language.I18n;
@@ -25,58 +26,58 @@ public class CompleteConfig {
     }
 
     private static void registerDefaultGuiProviders(GuiRegistry registry) {
-        registry.registerTypeProvider(Boolean.TYPE, (translationKey, value, defaultValue, saveConsumer) -> ConfigEntryBuilder
+        registry.registerTypeProvider(Boolean.TYPE, (translationKey, type, value, defaultValue, extras, saveConsumer) -> ConfigEntryBuilder
                 .create()
                 .startBooleanToggle(translationKey, value)
                 .setDefaultValue(defaultValue)
                 .setSaveConsumer(saveConsumer)
                 .build()
         );
-        registry.registerTypeProvider(Integer.TYPE, (translationKey, value, defaultValue, saveConsumer) -> ConfigEntryBuilder
+        registry.registerTypeProvider(Integer.TYPE, (translationKey, type, value, defaultValue, extras, saveConsumer) -> ConfigEntryBuilder
                 .create()
                 .startIntField(translationKey, value)
                 .setDefaultValue(defaultValue)
                 .setSaveConsumer(saveConsumer)
                 .build()
         );
-        registry.registerBoundedTypeProvider(Integer.TYPE, (translationKey, value, min, max, defaultValue, saveConsumer) -> ConfigEntryBuilder
+        registry.registerBoundedTypeProvider(Integer.TYPE, (translationKey, type, value, defaultValue, extras, saveConsumer) -> ConfigEntryBuilder
                 .create()
-                .startIntSlider(translationKey, value, min, max)
+                .startIntSlider(translationKey, value, extras.getBounds().getMin(), extras.getBounds().getMax())
                 .setDefaultValue(defaultValue)
                 .setSaveConsumer(saveConsumer)
                 .build()
         );
-        registry.registerTypeProvider(Long.TYPE, (translationKey, value, defaultValue, saveConsumer) -> ConfigEntryBuilder
+        registry.registerTypeProvider(Long.TYPE, (translationKey, type, value, defaultValue, extras, saveConsumer) -> ConfigEntryBuilder
                 .create()
                 .startLongField(translationKey, value)
                 .setDefaultValue(defaultValue)
                 .setSaveConsumer(saveConsumer)
                 .build()
         );
-        registry.registerBoundedTypeProvider(Long.TYPE, (translationKey, value, min, max, defaultValue, saveConsumer) -> ConfigEntryBuilder
+        registry.registerBoundedTypeProvider(Long.TYPE, (translationKey, type, value, defaultValue, extras, saveConsumer) -> ConfigEntryBuilder
                 .create()
-                .startLongSlider(translationKey, value, min, max)
+                .startLongSlider(translationKey, value, extras.getBounds().getMin(), extras.getBounds().getMax())
                 .setDefaultValue(defaultValue)
                 .setSaveConsumer(saveConsumer)
                 .build()
         );
-        registry.registerTypeProvider(Float.TYPE, (translationKey, value, defaultValue, saveConsumer) -> ConfigEntryBuilder
+        registry.registerTypeProvider(Float.TYPE, (translationKey, type, value, defaultValue, extras, saveConsumer) -> ConfigEntryBuilder
                 .create()
                 .startFloatField(translationKey, value)
                 .setDefaultValue(defaultValue)
                 .setSaveConsumer(saveConsumer)
                 .build()
         );
-        registry.registerTypeProvider(Double.TYPE, (translationKey, value, defaultValue, saveConsumer) -> ConfigEntryBuilder
+        registry.registerTypeProvider(Double.TYPE, (translationKey, type, value, defaultValue, extras, 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
+        registry.registerProvider((field, type, extras) -> Enum.class.isAssignableFrom(type), (GuiProvider<? extends Enum>) (translationKey, type, value, defaultValue, extras, saveConsumer) -> ConfigEntryBuilder
                 .create()
-                .startEnumSelector(translationKey, Enum.class, value)
+                .startEnumSelector(translationKey, type, value)
                 .setDefaultValue(defaultValue)
                 .setEnumNameProvider(e -> I18n.translate(translationKey + "." + CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, e.name())))
                 .setSaveConsumer(saveConsumer)

+ 16 - 23
src/main/java/me/lortseam/completeconfig/ConfigManager.java

@@ -11,7 +11,6 @@ import me.lortseam.completeconfig.api.ConfigEntry;
 import me.lortseam.completeconfig.api.ConfigEntryContainer;
 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.GuiRegistry;
 import me.lortseam.completeconfig.saveconsumer.SaveConsumer;
@@ -31,7 +30,6 @@ 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?)
@@ -99,30 +97,31 @@ public class ConfigManager {
                 if (!field.isAccessible()) {
                     field.setAccessible(true);
                 }
-                String translationKey = null;
+                Entry.Builder builder = Entry.Builder.create(field, container);
                 if (field.isAnnotationPresent(ConfigEntry.TranslationKey.class)) {
-                    translationKey = field.getDeclaredAnnotation(ConfigEntry.TranslationKey.class).value();
-                    if (StringUtils.isBlank(translationKey)) {
+                    String customTranslationKey = field.getDeclaredAnnotation(ConfigEntry.TranslationKey.class).value();
+                    if (StringUtils.isBlank(customTranslationKey)) {
                         throw new RuntimeException("Translation key for entry field " + field + " was blank!");
                     }
+                    builder.setCustomTranslationKey(customTranslationKey);
                 }
-                Entry entry;
-                if (field.isAnnotationPresent(ConfigEntry.Integer.Bound.class)) {
+                if (field.isAnnotationPresent(ConfigEntry.Integer.Bounded.class)) {
                     if (field.getType() != Integer.TYPE) {
                         throw new RuntimeException("Cannot apply integer bound to non integer field " + field + "!");
                     }
-                    ConfigEntry.Integer.Bound bound = field.getDeclaredAnnotation(ConfigEntry.Integer.Bound.class);
-                    entry = new BoundedEntry<>(field, Integer.TYPE, container, translationKey, bound.min(), bound.max());
-                } else if (field.isAnnotationPresent(ConfigEntry.Long.Bound.class)) {
+                    ConfigEntry.Integer.Bounded bounds = field.getDeclaredAnnotation(ConfigEntry.Integer.Bounded.class);
+                    builder.setBounds(bounds.min(), bounds.max());
+                } else if (field.isAnnotationPresent(ConfigEntry.Long.Bounded.class)) {
                     if (field.getType() != Long.TYPE) {
                         throw new RuntimeException("Cannot apply long bound to non long field " + field + "!");
                     }
-                    ConfigEntry.Long.Bound bound = field.getDeclaredAnnotation(ConfigEntry.Long.Bound.class);
-                    entry = new BoundedEntry<>(field, Long.TYPE, container, translationKey, bound.min(), bound.max());
-                } else {
-                    entry = new Entry<>(field, field.getType(), container, translationKey);
+                    ConfigEntry.Long.Bounded bounds = field.getDeclaredAnnotation(ConfigEntry.Long.Bounded.class);
+                    builder.setBounds(bounds.min(), bounds.max());
+                }
+                Entry<?> entry = builder.build();
+                if (guiRegistry.getProvider(entry) == null) {
+                    throw new RuntimeException("Could not find gui provider for field type " + entry.getType());
                 }
-                //TODO: Check if there is a gui provider for this entry, else throw error
                 String fieldName = field.getName();
                 saveConsumers.removeIf(saveConsumer -> {
                     if (!saveConsumer.getFieldName().equals(fieldName)) {
@@ -224,14 +223,8 @@ public class ConfigManager {
     private List<AbstractConfigListEntry> buildCollection(String parentID, Collection collection) {
         List<AbstractConfigListEntry> list = new ArrayList<>();
         collection.getEntries().forEach((entryID, entry) -> {
-            String translationKey = entry.getTranslationKey() != null ? buildTranslationKey(entry.getTranslationKey()) : buildTranslationKey(parentID, entryID);
-            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);
+            String translationKey = entry.getCustomTranslationKey() != null ? buildTranslationKey(entry.getCustomTranslationKey()) : buildTranslationKey(parentID, entryID);
+            list.add(guiRegistry.getProvider(entry).build(translationKey, entry.getType(), entry.getValue(), entry.getDefaultValue(), entry.getExtras(), entry::setValue));
         });
         collection.getCollections().forEach((subcategoryID, c) -> {
             String id = joinIDs(parentID, subcategoryID);

+ 2 - 2
src/main/java/me/lortseam/completeconfig/api/ConfigEntry.java

@@ -25,7 +25,7 @@ public @interface ConfigEntry {
 
         @Target(ElementType.FIELD)
         @Retention(RetentionPolicy.RUNTIME)
-        public @interface Bound {
+        public @interface Bounded {
 
             int min();
 
@@ -40,7 +40,7 @@ public @interface ConfigEntry {
 
         @Target(ElementType.FIELD)
         @Retention(RetentionPolicy.RUNTIME)
-        public @interface Bound {
+        public @interface Bounded {
 
             long min();
 

+ 1 - 0
src/main/java/me/lortseam/completeconfig/api/ConfigEntryContainer.java

@@ -15,6 +15,7 @@ public interface ConfigEntryContainer {
         return false;
     }
 
+    //TODO: Implement
     @Target(ElementType.FIELD)
     @Retention(RetentionPolicy.RUNTIME)
     @interface Transitive {

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

@@ -1,29 +0,0 @@
-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> {
-
-    @Getter
-    private final T min, max;
-
-    public BoundedEntry(Field field, Class<T> type, ConfigEntryContainer parentObject, String translationKey, T min, T max) {
-        super(field, type, parentObject, translationKey);
-        this.min = min;
-        this.max = max;
-    }
-
-    @FunctionalInterface
-    public interface GuiProvider<T> {
-
-        AbstractConfigListEntry build(String translationKey, T value, T min, T max, T defaultValue, Consumer<T> saveConsumer);
-
-    }
-
-}

+ 48 - 10
src/main/java/me/lortseam/completeconfig/entry/Entry.java

@@ -1,16 +1,14 @@
 package me.lortseam.completeconfig.entry;
 
-import lombok.AccessLevel;
-import lombok.Getter;
+import lombok.*;
+import lombok.experimental.Accessors;
 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> {
 
@@ -23,15 +21,18 @@ public class Entry<T> {
     @Getter
     private final T defaultValue;
     @Getter
-    private final String translationKey;
+    private final String customTranslationKey;
+    @Getter
+    private final Extras<T> extras;
     private final Map<Method, ConfigEntryContainer> saveConsumers = new HashMap<>();
 
-    public Entry(Field field, Class<T> type, ConfigEntryContainer parentObject, String translationKey) {
+    private Entry(Field field, Class<T> type, ConfigEntryContainer parentObject, String customTranslationKey, Extras<T> extras) {
         this.field = field;
         this.type = type;
         this.parentObject = parentObject;
         defaultValue = getValue();
-        this.translationKey = translationKey;
+        this.customTranslationKey = customTranslationKey;
+        this.extras = extras;
     }
 
     public T getValue() {
@@ -71,10 +72,47 @@ public class Entry<T> {
         saveConsumers.put(method, parentObject);
     }
 
-    @FunctionalInterface
-    public interface GuiProvider<T> {
+    @RequiredArgsConstructor(access = AccessLevel.PACKAGE)
+    public static class Extras<T> {
+
+        @Getter
+        private final Bounds<T> bounds;
+
+    }
+
+    //TODO: Bounds auch beim Einlesen aus JSON beachten
+    @RequiredArgsConstructor(access = AccessLevel.PACKAGE)
+    public static class Bounds<T> {
+
+        @Getter
+        private final T min;
+        @Getter
+        private final T max;
+
+    }
 
-        AbstractConfigListEntry<T> build(String translationKey, T value, T defaultValue, Consumer<T> saveConsumer);
+    @RequiredArgsConstructor(access = AccessLevel.PRIVATE)
+    @Accessors(chain = true)
+    public static class Builder {
+
+        public static Builder create(Field field, ConfigEntryContainer parentObject) {
+            return new Builder(field, parentObject);
+        }
+
+        private final Field field;
+        private final ConfigEntryContainer parentObject;
+        @Setter
+        private String customTranslationKey;
+        private Bounds bounds;
+
+        public <N extends Number> Builder setBounds(N min, N max) {
+            bounds = new Bounds<>(min, max);
+            return this;
+        }
+
+        public Entry<?> build() {
+            return new Entry<>(field, field.getType(), parentObject, customTranslationKey, new Extras<>(bounds));
+        }
 
     }
 

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

@@ -0,0 +1,12 @@
+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, Class<T> type, T value, T defaultValue, Entry.Extras<T> extras, Consumer<T> saveConsumer);
+
+}

+ 10 - 0
src/main/java/me/lortseam/completeconfig/entry/GuiProviderPredicate.java

@@ -0,0 +1,10 @@
+package me.lortseam.completeconfig.entry;
+
+import java.lang.reflect.Field;
+
+@FunctionalInterface
+public interface GuiProviderPredicate<T> {
+
+    boolean test(Field field, Class<T> type, Entry.Extras<T> extras);
+
+}

+ 14 - 33
src/main/java/me/lortseam/completeconfig/entry/GuiRegistry.java

@@ -3,53 +3,34 @@ package me.lortseam.completeconfig.entry;
 import java.lang.reflect.Field;
 import java.util.LinkedHashMap;
 import java.util.Map;
+import java.util.function.BiPredicate;
 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<>();
+    private final LinkedHashMap<GuiProviderPredicate, GuiProvider> guiProviders = new LinkedHashMap<>();
 
-    public void registerProvider(Predicate<Field> predicate, Entry.GuiProvider provider) {
-        entryGuiProviders.put(predicate, provider);
+    public void registerProvider(GuiProviderPredicate predicate, GuiProvider provider) {
+        guiProviders.put(predicate, provider);
     }
 
-    public <T> void registerTypeProvider(Class<T> type, Entry.GuiProvider<T> provider) {
-        registerProvider((field) -> field.getDeclaringClass() == type, provider);
+    public <T> void registerTypeProvider(Class<T> type, GuiProvider<T> provider) {
+        registerProvider((field, fieldType, extras) -> fieldType == type, provider);
     }
 
-    public void registerBoundedProvider(Predicate<Field> predicate, BoundedEntry.GuiProvider provider) {
-        boundedEntryGuiProviders.put(predicate, provider);
+    public <T> void registerBoundedTypeProvider(Class<T> type, GuiProvider<T> provider) {
+        registerProvider((field, fieldType, extras) -> fieldType == type && extras.getBounds() != null, 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())) {
+    public <T> GuiProvider<T> getProvider(Entry<T> entry) {
+        GuiProvider<T> guiProvider = null;
+        for (Map.Entry<GuiProviderPredicate, GuiProvider> mapEntry : guiProviders.entrySet()) {
+            Field field = entry.getField();
+            if (mapEntry.getKey().test(field, field.getType(), entry.getExtras())) {
                 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;
-        }
-    }
-
-}
+}