소스 검색

Transformations

Lortseam 4 년 전
부모
커밋
d53dbf5059

+ 7 - 9
src/main/java/me/lortseam/completeconfig/data/BoundedEntry.java

@@ -1,12 +1,10 @@
 package me.lortseam.completeconfig.data;
 
 import lombok.Getter;
-import me.lortseam.completeconfig.api.ConfigEntryContainer;
-import me.lortseam.completeconfig.data.text.TranslationIdentifier;
+import me.lortseam.completeconfig.data.entry.EntryOrigin;
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
 
-import java.lang.reflect.Field;
 import java.math.BigDecimal;
 
 public class BoundedEntry<T extends Number> extends Entry<T> {
@@ -18,13 +16,13 @@ public class BoundedEntry<T extends Number> extends Entry<T> {
     @Getter
     private final boolean slider;
 
-    BoundedEntry(Field field, ConfigEntryContainer parentObject, TranslationIdentifier parentTranslation, T min, T max, boolean slider) {
-        super(field, parentObject, parentTranslation, value -> {
+    public BoundedEntry(EntryOrigin origin, T min, T max, boolean slider) {
+        super(origin, value -> {
             if (new BigDecimal(value.toString()).compareTo(new BigDecimal(min.toString())) < 0) {
-                LOGGER.warn("[CompleteConfig] Tried to set value of field " + field + " to a value less than minimum bound, setting to minimum now!");
+                LOGGER.warn("[CompleteConfig] Tried to set value of field " + origin.getField() + " to a value less than minimum bound, setting to minimum now!");
                 return min;
             } else if (new BigDecimal(value.toString()).compareTo(new BigDecimal(max.toString())) > 0) {
-                LOGGER.warn("[CompleteConfig] Tried to set value of field " + field + " to a value greater than maximum bound, setting to maximum now!");
+                LOGGER.warn("[CompleteConfig] Tried to set value of field " + origin.getField() + " to a value greater than maximum bound, setting to maximum now!");
                 return max;
             }
             return value;
@@ -34,8 +32,8 @@ public class BoundedEntry<T extends Number> extends Entry<T> {
         this.slider = slider;
     }
 
-    BoundedEntry(Field field, ConfigEntryContainer parentObject, TranslationIdentifier parentTranslation, T min, T max) {
-        this(field, parentObject, parentTranslation, min, max, false);
+    public BoundedEntry(EntryOrigin origin, T min, T max) {
+        this(origin, min, max, false);
     }
 
 }

+ 3 - 6
src/main/java/me/lortseam/completeconfig/data/ColorEntry.java

@@ -3,22 +3,19 @@ package me.lortseam.completeconfig.data;
 import lombok.AccessLevel;
 import lombok.Getter;
 import lombok.NoArgsConstructor;
-import me.lortseam.completeconfig.api.ConfigEntryContainer;
-import me.lortseam.completeconfig.data.text.TranslationIdentifier;
+import me.lortseam.completeconfig.data.entry.EntryOrigin;
 import net.minecraft.text.TextColor;
 import org.spongepowered.configurate.serialize.CoercionFailedException;
 import org.spongepowered.configurate.serialize.ScalarSerializer;
 import org.spongepowered.configurate.serialize.TypeSerializer;
 
-import java.lang.reflect.Field;
-
 public class ColorEntry<T> extends Entry<T> {
 
     @Getter
     private final boolean alphaMode;
 
-    protected ColorEntry(Field field, ConfigEntryContainer parentObject, TranslationIdentifier parentTranslation, boolean alphaMode) {
-        super(field, parentObject, parentTranslation);
+    public ColorEntry(EntryOrigin origin, boolean alphaMode) {
+        super(origin);
         this.alphaMode = alphaMode;
     }
 

+ 34 - 55
src/main/java/me/lortseam/completeconfig/data/Entry.java

@@ -1,12 +1,14 @@
 package me.lortseam.completeconfig.data;
 
+import com.google.common.collect.Lists;
 import lombok.Getter;
 import me.lortseam.completeconfig.api.ConfigEntry;
 import me.lortseam.completeconfig.api.ConfigEntryContainer;
+import me.lortseam.completeconfig.data.entry.EntryOrigin;
+import me.lortseam.completeconfig.data.entry.Transformation;
 import me.lortseam.completeconfig.data.part.DataPart;
 import me.lortseam.completeconfig.data.text.TranslationIdentifier;
 import me.lortseam.completeconfig.exception.IllegalAnnotationParameterException;
-import me.lortseam.completeconfig.exception.IllegalAnnotationTargetException;
 import net.minecraft.text.Text;
 import net.minecraft.text.TextColor;
 import org.apache.commons.lang3.StringUtils;
@@ -24,6 +26,28 @@ import java.util.function.UnaryOperator;
 public class Entry<T> extends EntryBase<T> implements DataPart {
 
     private static final Logger LOGGER = LogManager.getLogger();
+    private static final List<Transformation> transformations = Lists.newArrayList(
+            Transformation.ofAnnotation(ConfigEntry.Bounded.Integer.class, origin -> {
+                ConfigEntry.Bounded.Integer bounds = origin.getAnnotation();
+                return new BoundedEntry<>(origin, bounds.min(), bounds.max(), bounds.slider());
+            }, int.class, Integer.class),
+            Transformation.ofAnnotation(ConfigEntry.Bounded.Long.class, origin -> {
+                ConfigEntry.Bounded.Long bounds = origin.getAnnotation();
+                return new BoundedEntry<>(origin, bounds.min(), bounds.max(), bounds.slider());
+            }, long.class, Long.class),
+            Transformation.ofAnnotation(ConfigEntry.Bounded.Float.class, origin -> {
+                ConfigEntry.Bounded.Float bounds = origin.getAnnotation();
+                return new BoundedEntry<>(origin, bounds.min(), bounds.max());
+            }, float.class, Float.class),
+            Transformation.ofAnnotation(ConfigEntry.Bounded.Double.class, origin -> {
+                ConfigEntry.Bounded.Double bounds = origin.getAnnotation();
+                return new BoundedEntry<>(origin, bounds.min(), bounds.max());
+            }, double.class, Double.class),
+            Transformation.of(base -> Enum.class.isAssignableFrom(base.typeClass), EnumEntry::new),
+            Transformation.ofAnnotation(ConfigEntry.Enum.class, origin -> new EnumEntry<>(origin, origin.getAnnotation().displayType()), base -> Enum.class.isAssignableFrom(base.typeClass)),
+            Transformation.ofAnnotation(ConfigEntry.Color.class, origin -> new ColorEntry<>(origin, origin.getAnnotation().alphaMode())),
+            Transformation.ofType(TextColor.class, origin -> new ColorEntry<>(origin, false))
+    );
     private static final Map<Field, EntryBase> entries = new HashMap<>();
 
     static EntryBase<?> of(String fieldName, Class<? extends ConfigEntryContainer> parentClass) {
@@ -38,53 +62,8 @@ public class Entry<T> extends EntryBase<T> implements DataPart {
         return entries.computeIfAbsent(field, absentField -> new Draft<>(field));
     }
 
-    private static Entry<?> create(EntryBase<?> base, ConfigEntryContainer parentObject, TranslationIdentifier parentTranslation) {
-        Field field = base.field;
-        Class<?> typeClass = base.typeClass;
-        if (field.isAnnotationPresent(ConfigEntry.Bounded.Integer.class)) {
-            if (typeClass != int.class && typeClass != Integer.class) {
-                throw new IllegalAnnotationTargetException("Cannot apply Integer bound to non Integer field " + field);
-            }
-            ConfigEntry.Bounded.Integer bounds = field.getDeclaredAnnotation(ConfigEntry.Bounded.Integer.class);
-            return new BoundedEntry<>(field, parentObject, parentTranslation, bounds.min(), bounds.max(), bounds.slider());
-        }
-        if (field.isAnnotationPresent(ConfigEntry.Bounded.Long.class)) {
-            if (typeClass != long.class && typeClass != Long.class) {
-                throw new IllegalAnnotationTargetException("Cannot apply Long bound to non Long field " + field);
-            }
-            ConfigEntry.Bounded.Long bounds = field.getDeclaredAnnotation(ConfigEntry.Bounded.Long.class);
-            return new BoundedEntry<>(field, parentObject, parentTranslation, bounds.min(), bounds.max(), bounds.slider());
-        }
-        if (field.isAnnotationPresent(ConfigEntry.Bounded.Float.class)) {
-            if (typeClass != float.class && typeClass != Float.class) {
-                throw new IllegalAnnotationTargetException("Cannot apply Float bound to non Float field " + field);
-            }
-            ConfigEntry.Bounded.Float bounds = field.getDeclaredAnnotation(ConfigEntry.Bounded.Float.class);
-            return new BoundedEntry<>(field, parentObject, parentTranslation, bounds.min(), bounds.max());
-        }
-        if (field.isAnnotationPresent(ConfigEntry.Bounded.Double.class)) {
-            if (typeClass != double.class && typeClass != Double.class) {
-                throw new IllegalAnnotationTargetException("Cannot apply Double bound to non Double field " + field);
-            }
-            ConfigEntry.Bounded.Double bounds = field.getDeclaredAnnotation(ConfigEntry.Bounded.Double.class);
-            return new BoundedEntry<>(field, parentObject, parentTranslation, bounds.min(), bounds.max());
-        }
-        if (Enum.class.isAssignableFrom(base.getTypeClass())) {
-            if (field.isAnnotationPresent(ConfigEntry.Enum.class)) {
-                return new EnumEntry<>(field, parentObject, parentTranslation, field.getDeclaredAnnotation(ConfigEntry.Enum.class).displayType());
-            } else {
-                return new EnumEntry<>(field, parentObject, parentTranslation);
-            }
-        } else if (field.isAnnotationPresent(ConfigEntry.Enum.class)) {
-            throw new IllegalAnnotationTargetException("Cannot apply enum options to non enum field " + field);
-        }
-        if (field.isAnnotationPresent(ConfigEntry.Color.class)) {
-            return new ColorEntry<>(field, parentObject, parentTranslation, field.getDeclaredAnnotation(ConfigEntry.Color.class).alphaMode());
-        }
-        if (typeClass == TextColor.class) {
-            return new ColorEntry<>(field, parentObject, parentTranslation, false);
-        }
-        return new Entry<>(field, parentObject, parentTranslation);
+    public static void registerTransformation(Transformation<?> transformation) {
+        transformations.add(0, transformation);
     }
 
     private final ConfigEntryContainer parentObject;
@@ -100,16 +79,16 @@ public class Entry<T> extends EntryBase<T> implements DataPart {
     private final UnaryOperator<T> modifier;
     private final List<Listener<T>> listeners = new ArrayList<>();
 
-    protected Entry(Field field, ConfigEntryContainer parentObject, TranslationIdentifier parentTranslation, UnaryOperator<T> modifier) {
-        super(field);
-        this.parentObject = parentObject;
-        this.parentTranslation = parentTranslation;
+    protected Entry(EntryOrigin origin, UnaryOperator<T> modifier) {
+        super(origin.getField());
+        parentObject = origin.getParentObject();
+        parentTranslation = origin.getParentTranslation();
         this.modifier = modifier;
         defaultValue = getValue();
     }
 
-    protected Entry(Field field, ConfigEntryContainer parentObject, TranslationIdentifier parentTranslation) {
-        this(field, parentObject, parentTranslation, null);
+    protected Entry(EntryOrigin origin) {
+        this(origin, null);
     }
 
     public T getValue() {
@@ -283,7 +262,7 @@ public class Entry<T> extends EntryBase<T> implements DataPart {
         }
 
         Entry<T> build(ConfigEntryContainer parentObject, TranslationIdentifier parentTranslation) {
-            Entry<T> entry = (Entry<T>) create(this, parentObject, parentTranslation);
+            Entry<T> entry = transformations.stream().filter(transformation -> transformation.test(this)).findFirst().orElse(Transformation.of(base -> true, Entry::new)).transform(this, parentObject, parentTranslation);
             for (Consumer<Entry<T>> interaction : interactions) {
                 interaction.accept(entry);
             }

+ 1 - 1
src/main/java/me/lortseam/completeconfig/data/EntryBase.java

@@ -7,7 +7,7 @@ import java.lang.reflect.Field;
 import java.lang.reflect.Type;
 import java.util.function.Consumer;
 
-abstract class EntryBase<T> {
+public abstract class EntryBase<T> {
 
     @Getter
     protected final Field field;

+ 5 - 7
src/main/java/me/lortseam/completeconfig/data/EnumEntry.java

@@ -3,11 +3,9 @@ package me.lortseam.completeconfig.data;
 import com.google.common.base.CaseFormat;
 import lombok.Getter;
 import me.lortseam.completeconfig.api.ConfigEntry;
-import me.lortseam.completeconfig.api.ConfigEntryContainer;
-import me.lortseam.completeconfig.data.text.TranslationIdentifier;
+import me.lortseam.completeconfig.data.entry.EntryOrigin;
 import net.minecraft.text.Text;
 
-import java.lang.reflect.Field;
 import java.util.function.Function;
 
 public class EnumEntry<T extends Enum> extends Entry<T> {
@@ -15,13 +13,13 @@ public class EnumEntry<T extends Enum> extends Entry<T> {
     @Getter
     private final DisplayType displayType;
 
-    EnumEntry(Field field, ConfigEntryContainer parentObject, TranslationIdentifier parentTranslation, DisplayType displayType) {
-        super(field, parentObject, parentTranslation);
+    public EnumEntry(EntryOrigin origin, DisplayType displayType) {
+        super(origin);
         this.displayType = displayType;
     }
 
-    EnumEntry(Field field, ConfigEntryContainer parentObject, TranslationIdentifier parentTranslation) {
-        this(field, parentObject, parentTranslation, DisplayType.DEFAULT);
+    public EnumEntry(EntryOrigin origin) {
+        this(origin, DisplayType.DEFAULT);
     }
 
     public Function<Enum, Text> getEnumNameProvider() {

+ 20 - 0
src/main/java/me/lortseam/completeconfig/data/entry/AnnotatedEntryOrigin.java

@@ -0,0 +1,20 @@
+package me.lortseam.completeconfig.data.entry;
+
+import lombok.Getter;
+import me.lortseam.completeconfig.api.ConfigEntryContainer;
+import me.lortseam.completeconfig.data.text.TranslationIdentifier;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Field;
+
+public class AnnotatedEntryOrigin<A extends Annotation> extends EntryOrigin {
+
+    @Getter
+    private final A annotation;
+
+    AnnotatedEntryOrigin(Field field, ConfigEntryContainer parentObject, TranslationIdentifier parentTranslation, A annotation) {
+        super(field, parentObject, parentTranslation);
+        this.annotation = annotation;
+    }
+
+}

+ 21 - 0
src/main/java/me/lortseam/completeconfig/data/entry/EntryOrigin.java

@@ -0,0 +1,21 @@
+package me.lortseam.completeconfig.data.entry;
+
+import lombok.AccessLevel;
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import me.lortseam.completeconfig.api.ConfigEntryContainer;
+import me.lortseam.completeconfig.data.text.TranslationIdentifier;
+
+import java.lang.reflect.Field;
+
+@RequiredArgsConstructor(access = AccessLevel.PACKAGE)
+public class EntryOrigin {
+
+    @Getter
+    private final Field field;
+    @Getter
+    private final ConfigEntryContainer parentObject;
+    @Getter
+    private final TranslationIdentifier parentTranslation;
+
+}

+ 60 - 0
src/main/java/me/lortseam/completeconfig/data/entry/Transformation.java

@@ -0,0 +1,60 @@
+package me.lortseam.completeconfig.data.entry;
+
+import lombok.AccessLevel;
+import lombok.RequiredArgsConstructor;
+import me.lortseam.completeconfig.api.ConfigEntryContainer;
+import me.lortseam.completeconfig.data.Entry;
+import me.lortseam.completeconfig.data.EntryBase;
+import me.lortseam.completeconfig.data.text.TranslationIdentifier;
+import me.lortseam.completeconfig.exception.IllegalAnnotationTargetException;
+import org.apache.commons.lang3.ArrayUtils;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Field;
+import java.lang.reflect.Type;
+import java.util.function.Predicate;
+
+@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
+public class Transformation<O extends EntryOrigin> {
+
+    public static Transformation<EntryOrigin> of(Predicate<EntryBase<?>> predicate, Transformer<EntryOrigin> transformer) {
+        return new Transformation<>(predicate, EntryOrigin::new, transformer);
+    }
+
+    public static Transformation<EntryOrigin> ofType(Type type, Transformer<EntryOrigin> transformer) {
+        return of(base -> base.getType().equals(type), transformer);
+    }
+
+    public static <A extends Annotation> Transformation<AnnotatedEntryOrigin<A>> ofAnnotation(Class<A> annotationClass, Transformer<AnnotatedEntryOrigin<A>> transformer, Predicate<EntryBase<?>> predicate) {
+        return new Transformation<>(base -> base.getField().isAnnotationPresent(annotationClass) && predicate.test(base), (field, parentObject, parentTranslation) -> new AnnotatedEntryOrigin<>(field, parentObject, parentTranslation, field.getDeclaredAnnotation(annotationClass)), transformer);
+    }
+
+    public static <A extends Annotation> Transformation<AnnotatedEntryOrigin<A>> ofAnnotation(Class<A> annotationClass, Transformer<AnnotatedEntryOrigin<A>> transformer, Type... types) {
+        return ofAnnotation(annotationClass, transformer, base -> {
+            if (types.length > 0 && !ArrayUtils.contains(types, base.getType())) {
+                throw new IllegalAnnotationTargetException("Cannot apply annotation " + annotationClass + " to field " + base.getField());
+            }
+            return true;
+        });
+    }
+
+    private final Predicate<EntryBase<?>> predicate;
+    private final OriginCreator<O> originCreator;
+    private final Transformer<O> transformer;
+
+    public boolean test(EntryBase<?> base) {
+        return predicate.test(base);
+    }
+
+    public Entry<?> transform(EntryBase<?> base, ConfigEntryContainer parentObject, TranslationIdentifier parentTranslation) {
+        return transformer.transform(originCreator.create(base.getField(), parentObject, parentTranslation));
+    }
+
+    @FunctionalInterface
+    private interface OriginCreator<O extends EntryOrigin> {
+
+        O create(Field field, ConfigEntryContainer parentObject, TranslationIdentifier parentTranslation);
+
+    }
+
+}

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

@@ -0,0 +1,10 @@
+package me.lortseam.completeconfig.data.entry;
+
+import me.lortseam.completeconfig.data.Entry;
+
+@FunctionalInterface
+public interface Transformer<O extends EntryOrigin> {
+
+    Entry<?> transform(O origin);
+
+}