From 750626cb04cc210fd2e5d32b3fe0a18477362f53 Mon Sep 17 00:00:00 2001 From: FalsePattern <30945458+FalsePattern@users.noreply.github.com> Date: Tue, 23 May 2023 14:06:31 +0200 Subject: [PATCH] sort configs properly --- .../lib/internal/asm/FPTransformer.java | 11 +++- .../transformers/ConfigOrderTransformer.java | 55 +++++++++++++++++++ .../GasStationValidatorTransformer.java | 3 +- .../IMixinPluginTransformer.java | 3 +- .../ITypeDiscovererTransformer.java | 2 +- .../impl/config/DeclOrderInternal.java | 17 ++++++ .../impl/config/ParsedConfiguration.java | 10 +++- .../impl/config/fields/AConfigField.java | 5 +- 8 files changed, 99 insertions(+), 7 deletions(-) create mode 100644 src/main/java/com/falsepattern/lib/internal/asm/transformers/ConfigOrderTransformer.java rename src/main/java/com/falsepattern/lib/internal/asm/{ => transformers}/GasStationValidatorTransformer.java (93%) rename src/main/java/com/falsepattern/lib/internal/asm/{ => transformers}/IMixinPluginTransformer.java (98%) rename src/main/java/com/falsepattern/lib/internal/asm/{ => transformers}/ITypeDiscovererTransformer.java (97%) create mode 100644 src/main/java/com/falsepattern/lib/internal/impl/config/DeclOrderInternal.java diff --git a/src/main/java/com/falsepattern/lib/internal/asm/FPTransformer.java b/src/main/java/com/falsepattern/lib/internal/asm/FPTransformer.java index 7be0d45..a845fa8 100644 --- a/src/main/java/com/falsepattern/lib/internal/asm/FPTransformer.java +++ b/src/main/java/com/falsepattern/lib/internal/asm/FPTransformer.java @@ -25,6 +25,10 @@ import com.falsepattern.lib.StableAPI; import com.falsepattern.lib.asm.IClassNodeTransformer; import com.falsepattern.lib.asm.SmartTransformer; import com.falsepattern.lib.internal.Tags; +import com.falsepattern.lib.internal.asm.transformers.ConfigOrderTransformer; +import com.falsepattern.lib.internal.asm.transformers.GasStationValidatorTransformer; +import com.falsepattern.lib.internal.asm.transformers.IMixinPluginTransformer; +import com.falsepattern.lib.internal.asm.transformers.ITypeDiscovererTransformer; import lombok.Getter; import lombok.experimental.Accessors; import org.apache.logging.log4j.LogManager; @@ -36,7 +40,7 @@ import java.util.List; @Accessors(fluent = true) @StableAPI(since = "__INTERNAL__") public class FPTransformer implements SmartTransformer { - static final Logger LOG = LogManager.getLogger(Tags.MODNAME + " ASM"); + public static final Logger LOG = LogManager.getLogger(Tags.MODNAME + " ASM"); @Getter private final List transformers; @@ -45,6 +49,9 @@ public class FPTransformer implements SmartTransformer { private final Logger logger = LOG; public FPTransformer() { - transformers = Arrays.asList(new IMixinPluginTransformer(), new ITypeDiscovererTransformer(), new GasStationValidatorTransformer()); + transformers = Arrays.asList(new IMixinPluginTransformer(), + new ITypeDiscovererTransformer(), + new GasStationValidatorTransformer(), + new ConfigOrderTransformer()); } } diff --git a/src/main/java/com/falsepattern/lib/internal/asm/transformers/ConfigOrderTransformer.java b/src/main/java/com/falsepattern/lib/internal/asm/transformers/ConfigOrderTransformer.java new file mode 100644 index 0000000..6c5c093 --- /dev/null +++ b/src/main/java/com/falsepattern/lib/internal/asm/transformers/ConfigOrderTransformer.java @@ -0,0 +1,55 @@ +package com.falsepattern.lib.internal.asm.transformers; + +import com.falsepattern.lib.asm.IClassNodeTransformer; +import com.falsepattern.lib.config.Config; +import com.falsepattern.lib.internal.impl.config.DeclOrderInternal; +import lombok.val; +import org.objectweb.asm.Opcodes; +import org.objectweb.asm.Type; +import org.objectweb.asm.tree.AnnotationNode; +import org.objectweb.asm.tree.ClassNode; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Optional; + +public class ConfigOrderTransformer implements IClassNodeTransformer { + private static final String DESC_CONFIG = Type.getDescriptor(Config.class); + private static final String DESC_CONFIG_IGNORE = Type.getDescriptor(Config.Ignore.class); + private static final String DESC_ORDER = Type.getDescriptor(DeclOrderInternal.class); + @Override + public String getName() { + return "ConfigOrderTransformer"; + } + + @Override + public boolean shouldTransform(ClassNode cn, String transformedName, boolean obfuscated) { + if (cn.visibleAnnotations != null) { + for (val ann : cn.visibleAnnotations) { + if (DESC_CONFIG.equals(ann.desc)) { + return true; + } + } + } + return false; + } + + @Override + public void transform(ClassNode cn, String transformedName, boolean obfuscated) { + int order = 0; + for (val field: cn.fields) { + if ((field.access & Opcodes.ACC_PUBLIC) != 0 && (field.access & Opcodes.ACC_STATIC) != 0 && (field.access & Opcodes.ACC_FINAL) == 0) { + if (field.visibleAnnotations != null) { + for (val ann: field.visibleAnnotations) { + if (DESC_CONFIG_IGNORE.equals(ann.desc)) { + continue; + } + } + } + } + val annVisitor = field.visitAnnotation(DESC_ORDER, true); + annVisitor.visit("value", order++); + annVisitor.visitEnd(); + } + } +} diff --git a/src/main/java/com/falsepattern/lib/internal/asm/GasStationValidatorTransformer.java b/src/main/java/com/falsepattern/lib/internal/asm/transformers/GasStationValidatorTransformer.java similarity index 93% rename from src/main/java/com/falsepattern/lib/internal/asm/GasStationValidatorTransformer.java rename to src/main/java/com/falsepattern/lib/internal/asm/transformers/GasStationValidatorTransformer.java index c9f5f85..740b85d 100644 --- a/src/main/java/com/falsepattern/lib/internal/asm/GasStationValidatorTransformer.java +++ b/src/main/java/com/falsepattern/lib/internal/asm/transformers/GasStationValidatorTransformer.java @@ -19,9 +19,10 @@ * along with this program. If not, see . */ -package com.falsepattern.lib.internal.asm; +package com.falsepattern.lib.internal.asm.transformers; import com.falsepattern.lib.asm.IClassNodeTransformer; +import com.falsepattern.lib.internal.asm.CoreLoadingPlugin; import org.objectweb.asm.tree.ClassNode; import static com.falsepattern.lib.mixin.MixinInfo.isClassPresentSafe; diff --git a/src/main/java/com/falsepattern/lib/internal/asm/IMixinPluginTransformer.java b/src/main/java/com/falsepattern/lib/internal/asm/transformers/IMixinPluginTransformer.java similarity index 98% rename from src/main/java/com/falsepattern/lib/internal/asm/IMixinPluginTransformer.java rename to src/main/java/com/falsepattern/lib/internal/asm/transformers/IMixinPluginTransformer.java index 2939d4b..bed079f 100644 --- a/src/main/java/com/falsepattern/lib/internal/asm/IMixinPluginTransformer.java +++ b/src/main/java/com/falsepattern/lib/internal/asm/transformers/IMixinPluginTransformer.java @@ -19,10 +19,11 @@ * along with this program. If not, see . */ -package com.falsepattern.lib.internal.asm; +package com.falsepattern.lib.internal.asm.transformers; import com.falsepattern.lib.asm.IClassNodeTransformer; import com.falsepattern.lib.internal.Tags; +import com.falsepattern.lib.internal.asm.FPTransformer; import lombok.val; import org.objectweb.asm.tree.ClassNode; import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin; diff --git a/src/main/java/com/falsepattern/lib/internal/asm/ITypeDiscovererTransformer.java b/src/main/java/com/falsepattern/lib/internal/asm/transformers/ITypeDiscovererTransformer.java similarity index 97% rename from src/main/java/com/falsepattern/lib/internal/asm/ITypeDiscovererTransformer.java rename to src/main/java/com/falsepattern/lib/internal/asm/transformers/ITypeDiscovererTransformer.java index 5387153..6a2b9ee 100644 --- a/src/main/java/com/falsepattern/lib/internal/asm/ITypeDiscovererTransformer.java +++ b/src/main/java/com/falsepattern/lib/internal/asm/transformers/ITypeDiscovererTransformer.java @@ -19,7 +19,7 @@ * along with this program. If not, see . */ -package com.falsepattern.lib.internal.asm; +package com.falsepattern.lib.internal.asm.transformers; import com.falsepattern.lib.asm.IClassNodeTransformer; import lombok.val; diff --git a/src/main/java/com/falsepattern/lib/internal/impl/config/DeclOrderInternal.java b/src/main/java/com/falsepattern/lib/internal/impl/config/DeclOrderInternal.java new file mode 100644 index 0000000..8c0ac60 --- /dev/null +++ b/src/main/java/com/falsepattern/lib/internal/impl/config/DeclOrderInternal.java @@ -0,0 +1,17 @@ +package com.falsepattern.lib.internal.impl.config; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Preserve ordering of elements in the config file and guis based on the ordering in the class. + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +public @interface DeclOrderInternal { + int value(); +} diff --git a/src/main/java/com/falsepattern/lib/internal/impl/config/ParsedConfiguration.java b/src/main/java/com/falsepattern/lib/internal/impl/config/ParsedConfiguration.java index b3663b4..633e362 100644 --- a/src/main/java/com/falsepattern/lib/internal/impl/config/ParsedConfiguration.java +++ b/src/main/java/com/falsepattern/lib/internal/impl/config/ParsedConfiguration.java @@ -46,11 +46,14 @@ import java.io.IOException; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.util.ArrayList; +import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.function.BiConsumer; +import java.util.stream.Collectors; +import java.util.stream.Stream; @RequiredArgsConstructor(access = AccessLevel.PRIVATE) public class ParsedConfiguration { @@ -197,11 +200,16 @@ public class ParsedConfiguration { save(); })); } + rawConfig.setCategoryPropertyOrder(category, fieldsSorted().map((prop) -> prop.name).collect(Collectors.toList())); + } + + private Stream> fieldsSorted() { + return fields.values().stream().sorted(Comparator.comparingInt((prop) -> prop.order)); } @SuppressWarnings("rawtypes") public List getConfigElements() { - return new ArrayList<>(elements.values()); + return fieldsSorted().map((field) -> elements.get(field.name)).collect(Collectors.toList()); } public boolean validate(BiConsumer, Field> invalidFieldHandler, boolean resetInvalid) { diff --git a/src/main/java/com/falsepattern/lib/internal/impl/config/fields/AConfigField.java b/src/main/java/com/falsepattern/lib/internal/impl/config/fields/AConfigField.java index fd12e06..a0974cb 100644 --- a/src/main/java/com/falsepattern/lib/internal/impl/config/fields/AConfigField.java +++ b/src/main/java/com/falsepattern/lib/internal/impl/config/fields/AConfigField.java @@ -21,6 +21,7 @@ package com.falsepattern.lib.internal.impl.config.fields; import com.falsepattern.lib.config.Config; +import com.falsepattern.lib.internal.impl.config.DeclOrderInternal; import lombok.val; import net.minecraftforge.common.config.Configuration; @@ -34,10 +35,11 @@ import java.util.Optional; public abstract class AConfigField { public final boolean noSync; + public final int order; + public final String name; protected final Field field; protected final Configuration configuration; protected final String category; - protected final String name; protected final String langKey; protected final Property.Type type; protected final Property property; @@ -71,6 +73,7 @@ public abstract class AConfigField { } property.setLanguageKey(langKey); noSync = field.isAnnotationPresent(Config.NoSync.class); + order = Optional.ofNullable(field.getAnnotation(DeclOrderInternal.class)).map(DeclOrderInternal::value).orElse(-1); } protected abstract T getField();