فهرست منبع

Save consumer -> Listener

Lortseam 5 سال پیش
والد
کامیت
43fe842404

+ 26 - 24
src/main/java/me/lortseam/completeconfig/ConfigManager.java

@@ -9,7 +9,7 @@ import lombok.Getter;
 import me.lortseam.completeconfig.api.ConfigCategory;
 import me.lortseam.completeconfig.api.ConfigEntry;
 import me.lortseam.completeconfig.api.ConfigEntryContainer;
-import me.lortseam.completeconfig.api.ConfigEntrySaveConsumer;
+import me.lortseam.completeconfig.api.ConfigEntryListener;
 import me.lortseam.completeconfig.collection.Collection;
 import me.lortseam.completeconfig.entry.Entry;
 import me.lortseam.completeconfig.exception.IllegalModifierException;
@@ -17,7 +17,7 @@ import me.lortseam.completeconfig.gui.GuiRegistry;
 import me.lortseam.completeconfig.exception.IllegalAnnotationParameterException;
 import me.lortseam.completeconfig.exception.IllegalAnnotationTargetException;
 import me.lortseam.completeconfig.exception.IllegalReturnValueException;
-import me.lortseam.completeconfig.saveconsumer.SaveConsumer;
+import me.lortseam.completeconfig.listener.Listener;
 import me.lortseam.completeconfig.serialization.CollectionsDeserializer;
 import me.lortseam.completeconfig.serialization.EntrySerializer;
 import me.shedaniel.clothconfig2.api.AbstractConfigListEntry;
@@ -45,7 +45,7 @@ public class ConfigManager {
     private final Path jsonPath;
     private final LinkedHashMap<String, Collection> config = new LinkedHashMap<>();
     private final JsonElement json;
-    private final Set<SaveConsumer> pendingSaveConsumers = new HashSet<>();
+    private final Set<Listener> pendingListeners = new HashSet<>();
     @Getter
     private final GuiRegistry guiRegistry = new GuiRegistry();
     private Supplier<ConfigBuilder> guiBuilder = ConfigBuilder::create;
@@ -71,31 +71,31 @@ public class ConfigManager {
         LinkedHashMap<String, Entry> entries = new LinkedHashMap<>();
         Class clazz = container.getClass();
         while (clazz != null) {
-            Set<SaveConsumer> saveConsumers = new HashSet<>();
-            Iterator<SaveConsumer> iter = pendingSaveConsumers.iterator();
+            List<Listener> listeners = new ArrayList<>();
+            Iterator<Listener> iter = pendingListeners.iterator();
             while (iter.hasNext()) {
-                SaveConsumer saveConsumer = iter.next();
-                if (saveConsumer.getFieldClass() == clazz) {
-                    saveConsumers.add(saveConsumer);
-                    pendingSaveConsumers.remove(saveConsumer);
+                Listener listener = iter.next();
+                if (listener.getFieldClass() == clazz) {
+                    listeners.add(listener);
+                    pendingListeners.remove(listener);
                 }
             }
-            Arrays.stream(clazz.getDeclaredMethods()).filter(method -> !Modifier.isStatic(method.getModifiers()) && method.isAnnotationPresent(ConfigEntrySaveConsumer.class)).forEach(method -> {
-                ConfigEntrySaveConsumer saveConsumerAnnotation = method.getDeclaredAnnotation(ConfigEntrySaveConsumer.class);
-                String fieldName = saveConsumerAnnotation.value();
-                Class<? extends ConfigEntryContainer> fieldClass = saveConsumerAnnotation.container();
+            Arrays.stream(clazz.getDeclaredMethods()).filter(method -> !Modifier.isStatic(method.getModifiers()) && method.isAnnotationPresent(ConfigEntryListener.class)).forEach(method -> {
+                ConfigEntryListener listener = method.getDeclaredAnnotation(ConfigEntryListener.class);
+                String fieldName = listener.value();
+                Class<? extends ConfigEntryContainer> fieldClass = listener.container();
                 if (fieldClass == ConfigEntryContainer.class) {
-                    saveConsumers.add(new SaveConsumer(method, container, fieldName));
+                    listeners.add(new Listener(method, container, fieldName));
                 } else {
                     Map<String, Entry> fieldClassEntries = findEntries(config, fieldClass);
                     if (fieldClassEntries.isEmpty()) {
-                        pendingSaveConsumers.add(new SaveConsumer(method, container, fieldName, fieldClass));
+                        pendingListeners.add(new Listener(method, container, fieldName, fieldClass));
                     } else {
                         Entry entry = fieldClassEntries.get(fieldName);
                         if (entry == null) {
-                            throw new IllegalAnnotationParameterException("Could not find field " + fieldName + " in " + fieldClass + " requested by save consumer method " + method);
+                            throw new IllegalAnnotationParameterException("Could not find field " + fieldName + " in " + fieldClass + " requested by listener method " + method);
                         }
-                        entry.addSaveConsumer(method, container);
+                        entry.addListener(method, container);
                     }
                 }
             });
@@ -117,10 +117,12 @@ public class ConfigManager {
                 }
                 Entry.Builder builder = Entry.Builder.create(field, container);
                 if (field.isAnnotationPresent(ConfigEntry.class)) {
-                    String customTranslationKey = field.getDeclaredAnnotation(ConfigEntry.class).customTranslationKey();
+                    ConfigEntry entryAnnotation = field.getDeclaredAnnotation(ConfigEntry.class);
+                    String customTranslationKey = entryAnnotation.customTranslationKey();
                     if (!StringUtils.isBlank(customTranslationKey)) {
                         builder.setCustomTranslationKey(customTranslationKey);
                     }
+                    builder.setForceUpdate(entryAnnotation.forceUpdate());
                 }
                 if (field.isAnnotationPresent(ConfigEntry.Integer.Bounded.class)) {
                     if (field.getType() != int.class && field.getType() != Integer.class) {
@@ -152,18 +154,18 @@ public class ConfigManager {
                     throw new UnsupportedOperationException("Could not find gui provider for field type " + entry.getType());
                 }
                 String fieldName = field.getName();
-                saveConsumers.removeIf(saveConsumer -> {
-                    if (!saveConsumer.getFieldName().equals(fieldName)) {
+                listeners.removeIf(listener -> {
+                    if (!listener.getFieldName().equals(fieldName)) {
                         return false;
                     }
-                    entry.addSaveConsumer(saveConsumer.getMethod(), saveConsumer.getParentObject());
+                    entry.addListener(listener.getMethod(), listener.getParentObject());
                     return true;
                 });
                 clazzEntries.put(fieldName, entry);
             });
-            if (!saveConsumers.isEmpty()) {
-                SaveConsumer saveConsumer = saveConsumers.iterator().next();
-                throw new IllegalAnnotationParameterException("Could not find field " + saveConsumer.getFieldName() + " in " + clazz + " requested by save consumer method " + saveConsumer.getMethod());
+            if (!listeners.isEmpty()) {
+                Listener listener = listeners.iterator().next();
+                throw new IllegalAnnotationParameterException("Could not find field " + listener.getFieldName() + " in " + clazz + " requested by listener method " + listener.getMethod());
             }
             clazzEntries.putAll(entries);
             entries = clazzEntries;

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

@@ -14,6 +14,8 @@ public @interface ConfigEntry {
 
     String customTranslationKey() default "";
 
+    boolean forceUpdate() default false;
+
     @NoArgsConstructor(access = AccessLevel.PRIVATE)
     class Integer {
 

+ 1 - 4
src/main/java/me/lortseam/completeconfig/api/ConfigEntrySaveConsumer.java → src/main/java/me/lortseam/completeconfig/api/ConfigEntryListener.java

@@ -7,14 +7,11 @@ import java.lang.annotation.Target;
 
 @Target(ElementType.METHOD)
 @Retention(RetentionPolicy.RUNTIME)
-//TODO: Rename to ConfigEntryListener
-public @interface ConfigEntrySaveConsumer {
+public @interface ConfigEntryListener {
 
     //TODO: Automatically detect field name dependening on method name (e.g. setExampleValue -> field name is exampleValue)
     String value();
 
     Class<? extends ConfigEntryContainer> container() default ConfigEntryContainer.class;
 
-    //TODO: Add boolean to update field regardless of this save consumer
-
 }

+ 23 - 13
src/main/java/me/lortseam/completeconfig/entry/Entry.java

@@ -10,9 +10,7 @@ import java.lang.reflect.Field;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.math.BigDecimal;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Objects;
+import java.util.*;
 
 public class Entry<T> {
 
@@ -30,14 +28,16 @@ public class Entry<T> {
     private final String customTranslationKey;
     @Getter
     private final Extras<T> extras;
-    private final Map<Method, ConfigEntryContainer> saveConsumers = new HashMap<>();
+    private final List<Listener> listeners = new ArrayList<>();
+    private final boolean forceUpdate;
 
-    private Entry(Field field, Class<T> type, ConfigEntryContainer parentObject, String customTranslationKey, Extras<T> extras) {
+    private Entry(Field field, Class<T> type, ConfigEntryContainer parentObject, String customTranslationKey, Extras<T> extras, boolean forceUpdate) {
         this.field = field;
         this.type = type;
         this.parentObject = parentObject;
         this.customTranslationKey = customTranslationKey;
         this.extras = extras;
+        this.forceUpdate = forceUpdate;
         defaultValue = getValue();
     }
 
@@ -82,17 +82,17 @@ public class Entry<T> {
     }
 
     private void set(T value) {
-        if (saveConsumers.values().stream().noneMatch(parentObject -> parentObject == this.parentObject)) {
+        if (listeners.stream().noneMatch(listener -> listener.parentObject == parentObject) || forceUpdate) {
             try {
                 field.set(parentObject, value);
             } catch (IllegalAccessException e) {
                 throw new RuntimeException(e);
             }
         }
-        if (!saveConsumers.isEmpty()) {
-            for (Map.Entry<Method, ConfigEntryContainer> mapEntry : saveConsumers.entrySet()) {
+        if (!listeners.isEmpty()) {
+            for (Listener listener : listeners) {
                 try {
-                    mapEntry.getKey().invoke(mapEntry.getValue(), value);
+                    listener.method.invoke(listener.parentObject, value);
                 } catch (IllegalAccessException | InvocationTargetException e) {
                     throw new RuntimeException(e);
                 }
@@ -100,14 +100,14 @@ public class Entry<T> {
         }
     }
 
-    public void addSaveConsumer(Method method, ConfigEntryContainer parentObject) {
+    public void addListener(Method method, ConfigEntryContainer parentObject) {
         if (method.getParameterCount() != 1 || method.getParameterTypes()[0] != type) {
-            throw new IllegalArgumentException("Save consumer method " + method + " has wrong parameter type(s)");
+            throw new IllegalArgumentException("Listener method " + method + " has wrong parameter type(s)");
         }
         if (!method.isAccessible()) {
             method.setAccessible(true);
         }
-        saveConsumers.put(method, parentObject);
+        listeners.add(new Listener(method, parentObject));
     }
 
     @RequiredArgsConstructor(access = AccessLevel.PRIVATE)
@@ -122,6 +122,8 @@ public class Entry<T> {
         private final ConfigEntryContainer parentObject;
         @Setter
         private String customTranslationKey;
+        @Setter
+        private boolean forceUpdate;
         private Bounds bounds;
 
         public <N extends Number> Builder setBounds(N min, N max) {
@@ -130,9 +132,17 @@ public class Entry<T> {
         }
 
         public Entry<?> build() {
-            return new Entry<>(field, field.getType(), parentObject, customTranslationKey, new Extras<>(bounds));
+            return new Entry<>(field, field.getType(), parentObject, customTranslationKey, new Extras<>(bounds), forceUpdate);
         }
 
     }
 
+    @AllArgsConstructor
+    private static class Listener {
+
+        private final Method method;
+        private final ConfigEntryContainer parentObject;
+
+    }
+
 }

+ 3 - 3
src/main/java/me/lortseam/completeconfig/saveconsumer/SaveConsumer.java → src/main/java/me/lortseam/completeconfig/listener/Listener.java

@@ -1,4 +1,4 @@
-package me.lortseam.completeconfig.saveconsumer;
+package me.lortseam.completeconfig.listener;
 
 import lombok.Getter;
 import lombok.RequiredArgsConstructor;
@@ -7,7 +7,7 @@ import me.lortseam.completeconfig.api.ConfigEntryContainer;
 import java.lang.reflect.Method;
 
 @RequiredArgsConstructor
-public class SaveConsumer {
+public class Listener {
 
     @Getter
     private final Method method;
@@ -18,7 +18,7 @@ public class SaveConsumer {
     @Getter
     private final Class<? extends ConfigEntryContainer> fieldClass;
 
-    public SaveConsumer(Method method, ConfigEntryContainer parentObject, String fieldName) {
+    public Listener(Method method, ConfigEntryContainer parentObject, String fieldName) {
         this.method = method;
         this.parentObject = parentObject;
         this.fieldName = fieldName;