Procházet zdrojové kódy

Improved GUI provider registration

Lortseam před 4 roky
rodič
revize
c8e337f2a8

+ 2 - 1
lib/src/main/java/me/lortseam/completeconfig/extensions/clothbasicmath/ClothBasicMathClientExtension.java

@@ -2,13 +2,14 @@ package me.lortseam.completeconfig.extensions.clothbasicmath;
 
 import me.lortseam.completeconfig.data.ColorEntry;
 import me.lortseam.completeconfig.extensions.ConfigExtensionPattern;
+import me.lortseam.completeconfig.gui.cloth.GuiProviderRegistration;
 import me.lortseam.completeconfig.gui.cloth.GuiRegistry;
 import me.shedaniel.math.Color;
 
 public final class ClothBasicMathClientExtension implements ConfigExtensionPattern {
 
     ClothBasicMathClientExtension() {
-        dependOn("cloth-config2", () -> GuiRegistry.addGlobalRegistrar(registry -> registry.registerSpecialProvider((ColorEntry<Color> entry) -> GuiRegistry.build(
+        dependOn("cloth-config2", () -> GuiRegistry.addGlobal(new GuiProviderRegistration<>((ColorEntry<Color> entry) -> GuiRegistry.build(
                 builder -> builder
                         .startColorField(entry.getText(), entry.getValue())
                         .setAlphaMode(entry.isAlphaMode())

+ 25 - 4
lib/src/main/java/me/lortseam/completeconfig/gui/cloth/GuiProviderRegistration.java

@@ -2,20 +2,41 @@ package me.lortseam.completeconfig.gui.cloth;
 
 import lombok.AccessLevel;
 import lombok.Getter;
-import lombok.RequiredArgsConstructor;
 import me.lortseam.completeconfig.data.Entry;
+import me.lortseam.completeconfig.util.Arrays;
 import net.fabricmc.api.EnvType;
 import net.fabricmc.api.Environment;
+import org.apache.commons.lang3.ArrayUtils;
 
+import java.lang.reflect.Type;
 import java.util.function.Predicate;
 
 @Environment(EnvType.CLIENT)
-@RequiredArgsConstructor(access = AccessLevel.PACKAGE)
-final class GuiProviderRegistration {
+public final class GuiProviderRegistration<E extends Entry<?>> {
 
     private final Predicate<Entry<?>> predicate;
     @Getter(AccessLevel.PACKAGE)
-    private final GuiProvider<?> provider;
+    private final GuiProvider<? extends E> provider;
+
+    public GuiProviderRegistration(GuiProvider<? extends E> provider, Predicate<Entry<?>> predicate, Type... types) {
+        this.predicate = entry -> {
+            if (types.length > 0 && !ArrayUtils.contains(types, entry.getType())) return false;
+            return predicate.test(entry);
+        };
+        this.provider = provider;
+    }
+
+    public GuiProviderRegistration(GuiProvider<? extends E> provider, Type... types) {
+        this(provider, entry -> true, Arrays.requireNonEmpty(types, "types"));
+    }
+
+    public GuiProviderRegistration(Class<E> entryType, GuiProvider<? extends E> provider, Predicate<E> predicate, Type... types) {
+        this(provider, entry -> entry.getClass() == entryType && predicate.test((E) entry), types);
+    }
+
+    public GuiProviderRegistration(Class<E> entryType, GuiProvider<? extends E> provider, Type... types) {
+        this(entryType, provider, entry -> true, types);
+    }
 
     boolean test(Entry<?> entry) {
         return predicate.test(entry);

+ 198 - 231
lib/src/main/java/me/lortseam/completeconfig/gui/cloth/GuiRegistry.java

@@ -11,251 +11,218 @@ import me.shedaniel.clothconfig2.impl.builders.FieldBuilder;
 import net.fabricmc.api.EnvType;
 import net.fabricmc.api.Environment;
 import net.minecraft.text.TextColor;
-import org.apache.commons.lang3.ArrayUtils;
 
-import java.lang.reflect.Type;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Optional;
-import java.util.function.Consumer;
+import java.util.*;
 import java.util.function.Function;
-import java.util.function.Predicate;
 
 @Environment(EnvType.CLIENT)
 public final class GuiRegistry {
 
-    private static final List<Consumer<GuiRegistry>> globalRegistrars = Lists.newArrayList(GuiRegistry::registerDefaultProviders);
+    private static final List<GuiProviderRegistration> globalRegistrations = Lists.newArrayList(
+            new GuiProviderRegistration<>(BooleanEntry.class, entry -> build(
+                    builder -> builder
+                            .startBooleanToggle(entry.getText(), entry.getValue())
+                            .setDefaultValue(entry.getDefaultValue())
+                            .setYesNoTextSupplier(entry.getValueTextSupplier())
+                            .setTooltip(entry.getTooltip())
+                            .setSaveConsumer(entry::setValue),
+                    entry.requiresRestart()
+            ), boolean.class, Boolean.class),
+            new GuiProviderRegistration<>((Entry<Integer> entry) -> build(
+                    builder -> builder
+                            .startIntField(entry.getText(), entry.getValue())
+                            .setDefaultValue(entry.getDefaultValue())
+                            .setTooltip(entry.getTooltip())
+                            .setSaveConsumer(entry::setValue),
+                    entry.requiresRestart()
+            ), int.class, Integer.class),
+            new GuiProviderRegistration<>(BoundedEntry.class, (BoundedEntry<Integer> entry) -> build(
+                    builder -> builder
+                            .startIntField(entry.getText(), entry.getValue())
+                            .setDefaultValue(entry.getDefaultValue())
+                            .setMin(entry.getMin())
+                            .setMax(entry.getMax())
+                            .setTooltip(entry.getTooltip())
+                            .setSaveConsumer(entry::setValue),
+                    entry.requiresRestart()
+            ), int.class, Integer.class),
+            new GuiProviderRegistration<>(SliderEntry.class, (SliderEntry<Integer> entry) -> build(
+                    builder -> builder
+                            .startIntSlider(entry.getText(), entry.getValue(), entry.getMin(), entry.getMax())
+                            .setDefaultValue(entry.getDefaultValue())
+                            .setTextGetter(entry.getValueTextSupplier())
+                            .setTooltip(entry.getTooltip())
+                            .setSaveConsumer(entry::setValue),
+                    entry.requiresRestart()
+            ), int.class, Integer.class),
+            new GuiProviderRegistration<>(ColorEntry.class, (ColorEntry<Integer> entry) -> build(
+                    builder -> builder
+                            .startColorField(entry.getText(), entry.getValue())
+                            .setDefaultValue(entry.getDefaultValue())
+                            .setAlphaMode(entry.isAlphaMode())
+                            .setTooltip(entry.getTooltip())
+                            .setSaveConsumer(entry::setValue),
+                    entry.requiresRestart()
+            ), int.class, Integer.class),
+            new GuiProviderRegistration<>((Entry<Long> entry) -> build(
+                    builder -> builder
+                            .startLongField(entry.getText(), entry.getValue())
+                            .setDefaultValue(entry.getDefaultValue())
+                            .setTooltip(entry.getTooltip())
+                            .setSaveConsumer(entry::setValue),
+                    entry.requiresRestart()
+            ), long.class, Long.class),
+            new GuiProviderRegistration<>(BoundedEntry.class, (BoundedEntry<Long> entry) -> build(
+                    builder -> builder
+                            .startLongField(entry.getText(), entry.getValue())
+                            .setDefaultValue(entry.getDefaultValue())
+                            .setMin(entry.getMin())
+                            .setMax(entry.getMax())
+                            .setTooltip(entry.getTooltip())
+                            .setSaveConsumer(entry::setValue),
+                    entry.requiresRestart()
+            ), long.class, Long.class),
+            new GuiProviderRegistration<>(SliderEntry.class, (SliderEntry<Long> entry) -> build(
+                    builder -> builder
+                            .startLongSlider(entry.getText(), entry.getValue(), entry.getMin(), entry.getMax())
+                            .setDefaultValue(entry.getDefaultValue())
+                            .setTextGetter(entry.getValueTextSupplier())
+                            .setTooltip(entry.getTooltip())
+                            .setSaveConsumer(entry::setValue),
+                    entry.requiresRestart()
+            ), long.class, Long.class),
+            new GuiProviderRegistration<>((Entry<Float> entry) -> build(
+                    builder -> builder
+                            .startFloatField(entry.getText(), entry.getValue())
+                            .setDefaultValue(entry.getDefaultValue())
+                            .setTooltip(entry.getTooltip())
+                            .setSaveConsumer(entry::setValue),
+                    entry.requiresRestart()
+            ), float.class, Float.class),
+            new GuiProviderRegistration<>(BoundedEntry.class, (BoundedEntry<Float> entry) -> build(
+                    builder -> builder
+                            .startFloatField(entry.getText(), entry.getValue())
+                            .setDefaultValue(entry.getDefaultValue())
+                            .setMin(entry.getMin())
+                            .setMax(entry.getMax())
+                            .setTooltip(entry.getTooltip())
+                            .setSaveConsumer(entry::setValue),
+                    entry.requiresRestart()
+            ), float.class, Float.class),
+            new GuiProviderRegistration<>((Entry<Double> entry) -> build(
+                    builder -> builder
+                            .startDoubleField(entry.getText(), entry.getValue())
+                            .setDefaultValue(entry.getDefaultValue())
+                            .setTooltip(entry.getTooltip())
+                            .setSaveConsumer(entry::setValue),
+                    entry.requiresRestart()
+            ), double.class, Double.class),
+            new GuiProviderRegistration<>(BoundedEntry.class, (BoundedEntry<Double> entry) -> build(
+                    builder -> builder
+                            .startDoubleField(entry.getText(), entry.getValue())
+                            .setDefaultValue(entry.getDefaultValue())
+                            .setMin(entry.getMin())
+                            .setMax(entry.getMax())
+                            .setTooltip(entry.getTooltip())
+                            .setSaveConsumer(entry::setValue),
+                    entry.requiresRestart()
+            ), double.class, Double.class),
+            new GuiProviderRegistration<>((Entry<String> entry) -> build(
+                    builder -> builder
+                            .startStrField(entry.getText(), entry.getValue())
+                            .setDefaultValue(entry.getDefaultValue())
+                            .setTooltip(entry.getTooltip())
+                            .setSaveConsumer(entry::setValue),
+                    entry.requiresRestart()
+            ), String.class),
+            new GuiProviderRegistration<>(EnumEntry.class, (EnumEntry<Enum<?>> entry) -> build(
+                    builder -> builder
+                            .startEnumSelector(entry.getText(), entry.getTypeClass(), entry.getValue())
+                            .setDefaultValue(entry.getDefaultValue())
+                            .setTooltip(entry.getTooltip())
+                            .setEnumNameProvider(entry.getEnumNameProvider())
+                            .setSaveConsumer(entry::setValue),
+                    entry.requiresRestart()
+            ), entry -> entry.getDisplayType() == EnumEntry.DisplayType.BUTTON),
+            new GuiProviderRegistration<>(EnumEntry.class, (EnumEntry<Enum<?>> entry) -> {
+                List<Enum> enumValues = Arrays.asList(((Class<? extends Enum<?>>) entry.getTypeClass()).getEnumConstants());
+                return build(
+                        builder -> builder
+                                .startDropdownMenu(entry.getText(), DropdownMenuBuilder.TopCellElementBuilder.of(
+                                        entry.getValue(),
+                                        enumTranslation -> enumValues.stream().filter(enumValue -> entry.getEnumNameProvider().apply(enumValue).getString().equals(enumTranslation)).collect(MoreCollectors.toOptional()).orElse(null),
+                                        entry.getEnumNameProvider()
+                                ), DropdownMenuBuilder.CellCreatorBuilder.of(entry.getEnumNameProvider()))
+                                .setSelections(enumValues)
+                                .setDefaultValue(entry.getDefaultValue())
+                                .setSaveConsumer(entry::setValue),
+                        entry.requiresRestart()
+                );
+            }, entry -> entry.getDisplayType() == EnumEntry.DisplayType.DROPDOWN),
+            new GuiProviderRegistration<>((Entry<List<Integer>> entry) -> build(
+                    builder -> builder
+                            .startIntList(entry.getText(), entry.getValue())
+                            .setDefaultValue(entry.getDefaultValue())
+                            .setTooltip(entry.getTooltip())
+                            .setSaveConsumer(entry::setValue),
+                    entry.requiresRestart()
+            ), new TypeToken<List<Integer>>() {}.getType()),
+            new GuiProviderRegistration<>((Entry<List<Long>> entry) -> build(
+                    builder -> builder
+                            .startLongList(entry.getText(), entry.getValue())
+                            .setDefaultValue(entry.getDefaultValue())
+                            .setTooltip(entry.getTooltip())
+                            .setSaveConsumer(entry::setValue),
+                    entry.requiresRestart()
+            ), new TypeToken<List<Long>>() {}.getType()),
+            new GuiProviderRegistration<>((Entry<List<Float>> entry) -> build(
+                    builder -> builder
+                            .startFloatList(entry.getText(), entry.getValue())
+                            .setDefaultValue(entry.getDefaultValue())
+                            .setTooltip(entry.getTooltip())
+                            .setSaveConsumer(entry::setValue),
+                    entry.requiresRestart()
+            ), new TypeToken<List<Float>>() {}.getType()),
+            new GuiProviderRegistration<>((Entry<List<Double>> entry) -> build(
+                    builder -> builder
+                            .startDoubleList(entry.getText(), entry.getValue())
+                            .setDefaultValue(entry.getDefaultValue())
+                            .setTooltip(entry.getTooltip())
+                            .setSaveConsumer(entry::setValue),
+                    entry.requiresRestart()
+            ), new TypeToken<List<Double>>() {}.getType()),
+            new GuiProviderRegistration<>((Entry<List<String>> entry) -> build(
+                    builder -> builder
+                            .startStrList(entry.getText(), entry.getValue())
+                            .setDefaultValue(entry.getDefaultValue())
+                            .setTooltip(entry.getTooltip())
+                            .setSaveConsumer(entry::setValue),
+                    entry.requiresRestart()
+            ), new TypeToken<List<String>>() {}.getType()),
+            new GuiProviderRegistration<>(ColorEntry.class, (ColorEntry<TextColor> entry) -> build(
+                    builder -> builder
+                        .startColorField(entry.getText(), entry.getValue())
+                        .setDefaultValue(entry.getDefaultValue())
+                        .setTooltip(entry.getTooltip())
+                        .setSaveConsumer3(entry::setValue),
+                    entry.requiresRestart()
+            ), entry -> !entry.isAlphaMode(), TextColor.class)
+    );
 
-    public static void addGlobalRegistrar(Consumer<GuiRegistry> registrar) {
-        globalRegistrars.add(registrar);
+    public static void addGlobal(GuiProviderRegistration... registrations) {
+        Collections.addAll(globalRegistrations, registrations);
     }
 
-    public static <T, A extends AbstractConfigListEntry> A build(Function<ConfigEntryBuilder, FieldBuilder<T, A>> builder, boolean requiresRestart) {
-        FieldBuilder<T, A> fieldBuilder = builder.apply(ConfigEntryBuilder.create());
+    public static AbstractConfigListEntry<?> build(Function<ConfigEntryBuilder, FieldBuilder<?, ?>> builder, boolean requiresRestart) {
+        FieldBuilder<?, ?> fieldBuilder = builder.apply(ConfigEntryBuilder.create());
         fieldBuilder.requireRestart(requiresRestart);
         return fieldBuilder.build();
     }
 
-    private final List<GuiProviderRegistration> registrations = new ArrayList<>();
+    private final List<GuiProviderRegistration> registrations = new ArrayList<>(globalRegistrations);
 
-    GuiRegistry() {
-        for (Consumer<GuiRegistry> registrar : globalRegistrars) {
-            registrar.accept(this);
-        }
-    }
-
-    public void registerProvider(GuiProvider<?> provider, Predicate<Entry<?>> predicate, Type... types) {
-        registrations.add(0, new GuiProviderRegistration(entry -> {
-            if (types.length > 0 && !ArrayUtils.contains(types, entry.getType())) return false;
-            return predicate.test(entry);
-        }, provider));
-    }
-
-    public void registerProvider(GuiProvider<?> provider, Type... types) {
-        if (types.length == 0) {
-            throw new IllegalArgumentException("Types must not be empty");
-        }
-        registerProvider(provider, entry -> true, types);
-    }
-
-    public <T extends Entry<?>> void registerSpecialProvider(GuiProvider<?> provider, Class<T> entryType, Predicate<T> predicate, Type... types) {
-        registerProvider(provider, entry -> entry.getClass() == entryType && predicate.test((T) entry), types);
-    }
-
-    public <T extends Entry<?>> void registerSpecialProvider(GuiProvider<?> provider, Class<T> entryType, Type... types) {
-        registerSpecialProvider(provider, entryType, entry -> true, types);
-    }
-
-    private void registerDefaultProviders() {
-       registerProvider((BooleanEntry entry) -> build(
-               builder -> builder
-                       .startBooleanToggle(entry.getText(), entry.getValue())
-                       .setDefaultValue(entry.getDefaultValue())
-                       .setYesNoTextSupplier(entry.getValueTextSupplier())
-                       .setTooltip(entry.getTooltip())
-                       .setSaveConsumer(entry::setValue),
-               entry.requiresRestart()
-       ), boolean.class, Boolean.class);
-       registerProvider((Entry<Integer> entry) -> build(
-               builder -> builder
-                       .startIntField(entry.getText(), entry.getValue())
-                       .setDefaultValue(entry.getDefaultValue())
-                       .setTooltip(entry.getTooltip())
-                       .setSaveConsumer(entry::setValue),
-               entry.requiresRestart()
-       ), int.class, Integer.class);
-       registerSpecialProvider((BoundedEntry<Integer> entry) -> build(
-               builder -> builder
-                       .startIntField(entry.getText(), entry.getValue())
-                       .setDefaultValue(entry.getDefaultValue())
-                       .setMin(entry.getMin())
-                       .setMax(entry.getMax())
-                       .setTooltip(entry.getTooltip())
-                       .setSaveConsumer(entry::setValue),
-               entry.requiresRestart()
-       ), BoundedEntry.class, int.class, Integer.class);
-       registerSpecialProvider((SliderEntry<Integer> entry) -> build(
-               builder -> builder
-                       .startIntSlider(entry.getText(), entry.getValue(), entry.getMin(), entry.getMax())
-                       .setDefaultValue(entry.getDefaultValue())
-                       .setTextGetter(entry.getValueTextSupplier())
-                       .setTooltip(entry.getTooltip())
-                       .setSaveConsumer(entry::setValue),
-               entry.requiresRestart()
-       ), SliderEntry.class, int.class, Integer.class);
-       registerSpecialProvider((ColorEntry<Integer> entry) -> build(
-               builder -> builder
-                       .startColorField(entry.getText(), entry.getValue())
-                       .setDefaultValue(entry.getDefaultValue())
-                       .setAlphaMode(entry.isAlphaMode())
-                       .setTooltip(entry.getTooltip())
-                       .setSaveConsumer(entry::setValue),
-               entry.requiresRestart()
-       ), ColorEntry.class, int.class, Integer.class);
-       registerProvider((Entry<Long> entry) -> build(
-               builder -> builder
-                       .startLongField(entry.getText(), entry.getValue())
-                       .setDefaultValue(entry.getDefaultValue())
-                       .setTooltip(entry.getTooltip())
-                       .setSaveConsumer(entry::setValue),
-               entry.requiresRestart()
-       ), long.class, Long.class);
-       registerSpecialProvider((BoundedEntry<Long> entry) -> build(
-               builder -> builder
-                       .startLongField(entry.getText(), entry.getValue())
-                       .setDefaultValue(entry.getDefaultValue())
-                       .setMin(entry.getMin())
-                       .setMax(entry.getMax())
-                       .setTooltip(entry.getTooltip())
-                       .setSaveConsumer(entry::setValue),
-               entry.requiresRestart()
-       ), BoundedEntry.class, long.class, Long.class);
-       registerSpecialProvider((SliderEntry<Long> entry) -> build(
-               builder -> builder
-                       .startLongSlider(entry.getText(), entry.getValue(), entry.getMin(), entry.getMax())
-                       .setDefaultValue(entry.getDefaultValue())
-                       .setTextGetter(entry.getValueTextSupplier())
-                       .setTooltip(entry.getTooltip())
-                       .setSaveConsumer(entry::setValue),
-               entry.requiresRestart()
-       ), SliderEntry.class, long.class, Long.class);
-       registerProvider((Entry<Float> entry) -> build(
-               builder -> builder
-                       .startFloatField(entry.getText(), entry.getValue())
-                       .setDefaultValue(entry.getDefaultValue())
-                       .setTooltip(entry.getTooltip())
-                       .setSaveConsumer(entry::setValue),
-               entry.requiresRestart()
-       ), float.class, Float.class);
-       registerSpecialProvider((BoundedEntry<Float> entry) -> build(
-               builder -> builder
-                       .startFloatField(entry.getText(), entry.getValue())
-                       .setDefaultValue(entry.getDefaultValue())
-                       .setMin(entry.getMin())
-                       .setMax(entry.getMax())
-                       .setTooltip(entry.getTooltip())
-                       .setSaveConsumer(entry::setValue),
-               entry.requiresRestart()
-       ), BoundedEntry.class, float.class, Float.class);
-       registerProvider((Entry<Double> entry) -> build(
-               builder -> builder
-                       .startDoubleField(entry.getText(), entry.getValue())
-                       .setDefaultValue(entry.getDefaultValue())
-                       .setTooltip(entry.getTooltip())
-                       .setSaveConsumer(entry::setValue),
-               entry.requiresRestart()
-       ), double.class, Double.class);
-       registerSpecialProvider((BoundedEntry<Double> entry) -> build(
-               builder -> builder
-                       .startDoubleField(entry.getText(), entry.getValue())
-                       .setDefaultValue(entry.getDefaultValue())
-                       .setMin(entry.getMin())
-                       .setMax(entry.getMax())
-                       .setTooltip(entry.getTooltip())
-                       .setSaveConsumer(entry::setValue),
-               entry.requiresRestart()
-       ), BoundedEntry.class, double.class, Double.class);
-       registerProvider((Entry<String> entry) -> build(
-               builder -> builder
-                       .startStrField(entry.getText(), entry.getValue())
-                       .setDefaultValue(entry.getDefaultValue())
-                       .setTooltip(entry.getTooltip())
-                       .setSaveConsumer(entry::setValue),
-               entry.requiresRestart()
-       ), String.class);
-       registerSpecialProvider((EnumEntry<Enum<?>> entry) -> build(
-               builder -> builder
-                       .startEnumSelector(entry.getText(), entry.getTypeClass(), entry.getValue())
-                       .setDefaultValue(entry.getDefaultValue())
-                       .setTooltip(entry.getTooltip())
-                       .setEnumNameProvider(entry.getEnumNameProvider())
-                       .setSaveConsumer(entry::setValue),
-               entry.requiresRestart()
-       ), EnumEntry.class, entry -> entry.getDisplayType() == EnumEntry.DisplayType.BUTTON);
-       registerSpecialProvider((EnumEntry<Enum<?>> entry) -> {
-           List<Enum> enumValues = Arrays.asList(((Class<? extends Enum<?>>) entry.getTypeClass()).getEnumConstants());
-           return build(
-                   builder -> builder
-                           .startDropdownMenu(entry.getText(), DropdownMenuBuilder.TopCellElementBuilder.of(
-                                   entry.getValue(),
-                                   enumTranslation -> enumValues.stream().filter(enumValue -> entry.getEnumNameProvider().apply(enumValue).getString().equals(enumTranslation)).collect(MoreCollectors.toOptional()).orElse(null),
-                                   entry.getEnumNameProvider()
-                           ), DropdownMenuBuilder.CellCreatorBuilder.of(entry.getEnumNameProvider()))
-                           .setSelections(enumValues)
-                           .setDefaultValue(entry.getDefaultValue())
-                           .setSaveConsumer(entry::setValue),
-                   entry.requiresRestart()
-           );
-       }, EnumEntry.class, entry -> entry.getDisplayType() == EnumEntry.DisplayType.DROPDOWN);
-       registerProvider((Entry<List<Integer>> entry) -> build(
-               builder -> builder
-                       .startIntList(entry.getText(), entry.getValue())
-                       .setDefaultValue(entry.getDefaultValue())
-                       .setTooltip(entry.getTooltip())
-                       .setSaveConsumer(entry::setValue),
-               entry.requiresRestart()
-       ), new TypeToken<List<Integer>>() {}.getType());
-       registerProvider((Entry<List<Long>> entry) -> build(
-               builder -> builder
-                       .startLongList(entry.getText(), entry.getValue())
-                       .setDefaultValue(entry.getDefaultValue())
-                       .setTooltip(entry.getTooltip())
-                       .setSaveConsumer(entry::setValue),
-               entry.requiresRestart()
-       ), new TypeToken<List<Long>>() {}.getType());
-       registerProvider((Entry<List<Float>> entry) -> build(
-               builder -> builder
-                       .startFloatList(entry.getText(), entry.getValue())
-                       .setDefaultValue(entry.getDefaultValue())
-                       .setTooltip(entry.getTooltip())
-                       .setSaveConsumer(entry::setValue),
-               entry.requiresRestart()
-       ), new TypeToken<List<Float>>() {}.getType());
-       registerProvider((Entry<List<Double>> entry) -> build(
-               builder -> builder
-                       .startDoubleList(entry.getText(), entry.getValue())
-                       .setDefaultValue(entry.getDefaultValue())
-                       .setTooltip(entry.getTooltip())
-                       .setSaveConsumer(entry::setValue),
-               entry.requiresRestart()
-       ), new TypeToken<List<Double>>() {}.getType());
-       registerProvider((Entry<List<String>> entry) -> build(
-               builder -> builder
-                       .startStrList(entry.getText(), entry.getValue())
-                       .setDefaultValue(entry.getDefaultValue())
-                       .setTooltip(entry.getTooltip())
-                       .setSaveConsumer(entry::setValue),
-               entry.requiresRestart()
-       ), new TypeToken<List<String>>() {}.getType());
-       registerSpecialProvider((ColorEntry<TextColor> entry) -> build(
-               builder -> builder
-                       .startColorField(entry.getText(), entry.getValue())
-                       .setDefaultValue(entry.getDefaultValue())
-                       .setTooltip(entry.getTooltip())
-                       .setSaveConsumer3(entry::setValue),
-               entry.requiresRestart()
-       ), ColorEntry.class, entry -> !entry.isAlphaMode(), TextColor.class);
+    public void add(GuiProviderRegistration... registrations) {
+        Collections.addAll(this.registrations, registrations);
     }
 
     Optional<GuiProvider<Entry<?>>> getProvider(Entry<?> entry) {

+ 15 - 0
lib/src/main/java/me/lortseam/completeconfig/util/Arrays.java

@@ -0,0 +1,15 @@
+package me.lortseam.completeconfig.util;
+
+import lombok.experimental.UtilityClass;
+
+@UtilityClass
+public final class Arrays {
+
+    public static <T> T[] requireNonEmpty(T[] array, String name) {
+        if (array.length == 0) {
+            throw new IllegalArgumentException(name + " must not be empty");
+        }
+        return array;
+    }
+
+}