Răsfoiți Sursa

Overhauled extension system

Lortseam 4 ani în urmă
părinte
comite
8b06a0f7af

+ 45 - 29
lib/src/main/java/me/lortseam/completeconfig/CompleteConfig.java

@@ -1,61 +1,77 @@
 package me.lortseam.completeconfig;
 
+import com.google.common.collect.Sets;
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
 import lombok.NonNull;
 import lombok.extern.log4j.Log4j2;
 import me.lortseam.completeconfig.extensions.CompleteConfigExtension;
-import me.lortseam.completeconfig.extensions.ConfigExtensionPattern;
+import me.lortseam.completeconfig.extensions.Extension;
+import me.lortseam.completeconfig.extensions.GuiExtension;
 import me.lortseam.completeconfig.extensions.clothbasicmath.ClothBasicMathExtension;
+import net.fabricmc.api.EnvType;
 import net.fabricmc.loader.api.FabricLoader;
 import net.fabricmc.loader.api.entrypoint.EntrypointContainer;
+import org.apache.commons.lang3.ClassUtils;
 
 import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationTargetException;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
+import java.util.*;
 
 @Log4j2
-public final class CompleteConfig {
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public final class CompleteConfig implements Extension {
 
-    private static final Map<String, ConfigExtensionPattern> extensions = new HashMap<>();
+    private static final Set<Class<? extends Extension>> validExtensionTypes = Sets.newHashSet(CompleteConfigExtension.class);
+    private static final Set<Extension> extensions = new HashSet<>();
 
     static {
+        registerExtensionType(GuiExtension.class, EnvType.CLIENT, "cloth-config2");
         registerExternalExtension("cloth-basic-math", ClothBasicMathExtension.class);
         for (EntrypointContainer<CompleteConfigExtension> entrypoint : FabricLoader.getInstance().getEntrypointContainers("completeconfig-extension", CompleteConfigExtension.class)) {
-            extensions.put(entrypoint.getProvider().getMetadata().getId(), entrypoint.getEntrypoint());
+            registerExtension(entrypoint.getEntrypoint());
         }
     }
 
-    public static void registerExternalExtension(@NonNull String modID, @NonNull Class<? extends CompleteConfigExtension> extensionClass) {
-        if(!FabricLoader.getInstance().isModLoaded(modID)) return;
+    public static void registerExtensionType(Class<? extends Extension> extensionType, EnvType environment, String... mods) {
+        if(validExtensionTypes.contains(extensionType)) return;
+        if(environment != null && FabricLoader.getInstance().getEnvironmentType() != environment || Arrays.stream(mods).anyMatch(modID -> !FabricLoader.getInstance().isModLoaded(modID))) return;
+        validExtensionTypes.add(extensionType);
+    }
+
+    public static void registerExtensionType(Class<? extends Extension> extensionType, String... mods) {
+        registerExtensionType(extensionType, null, mods);
+    }
+
+    private static void registerExtension(Extension extension) {
+        extensions.add(extension);
+        Set<Class<? extends Extension>> children = extension.children();
+        if(children == null) return;
+        for (Class<? extends Extension> child : children) {
+            registerExtension(child);
+        }
+    }
+
+    private static void registerExtension(Class<? extends Extension> extension) {
+        if(Collections.disjoint(ClassUtils.getAllInterfaces(extension), validExtensionTypes)) return;
         try {
-            Constructor<? extends CompleteConfigExtension> constructor = extensionClass.getDeclaredConstructor();
+            Constructor<? extends Extension> constructor = extension.getDeclaredConstructor();
             if (!constructor.isAccessible()) {
                 constructor.setAccessible(true);
             }
-            CompleteConfigExtension extension = constructor.newInstance();
-            extensions.put(modID, extension);
-            ConfigExtensionPattern envSpecificExtension = null;
-            switch (FabricLoader.getInstance().getEnvironmentType()) {
-                case CLIENT:
-                    envSpecificExtension = extension.client();
-                    break;
-
-                case SERVER:
-                    envSpecificExtension = extension.server();
-                    break;
-            }
-            if (envSpecificExtension != null) {
-                extensions.put(modID, envSpecificExtension);
-            }
+            registerExtension(constructor.newInstance());
         } catch (InstantiationException | IllegalAccessException | NoSuchMethodException | InvocationTargetException e) {
-            logger.error("[CompleteConfig] Failed to instantiate extension " + modID, e);
+            logger.error("[CompleteConfig] Failed to instantiate extension " + extension, e);
         }
     }
 
-    public static Collection<ConfigExtensionPattern> getExtensions() {
-        return Collections.unmodifiableCollection(extensions.values());
+    public static void registerExternalExtension(@NonNull String modID, @NonNull Class<? extends CompleteConfigExtension> extensionType) {
+        if(!FabricLoader.getInstance().isModLoaded(modID)) return;
+        registerExtension(extensionType);
+    }
+
+    public static Collection<Extension> getExtensions() {
+        return Collections.unmodifiableCollection(extensions);
     }
 
 }

+ 6 - 4
lib/src/main/java/me/lortseam/completeconfig/data/Entry.java

@@ -14,7 +14,7 @@ import me.lortseam.completeconfig.data.entry.Transformer;
 import me.lortseam.completeconfig.data.structure.DataPart;
 import me.lortseam.completeconfig.data.text.TranslationIdentifier;
 import me.lortseam.completeconfig.exception.IllegalAnnotationParameterException;
-import me.lortseam.completeconfig.extensions.ConfigExtensionPattern;
+import me.lortseam.completeconfig.extensions.CompleteConfigExtension;
 import me.lortseam.completeconfig.util.TypeUtils;
 import net.minecraft.text.Text;
 import net.minecraft.text.TextColor;
@@ -65,9 +65,11 @@ public class Entry<T> extends EntryBase<T> implements DataPart {
     private static final BiMap<Key, EntryBase> entries = HashBiMap.create();
 
     static {
-        CompleteConfig.getExtensions().stream().map(ConfigExtensionPattern::getTransformations).filter(Objects::nonNull).forEach(extensionTransformations -> {
-            transformations.addAll(0, extensionTransformations);
-        });
+        CompleteConfig.getExtensions().stream().filter(extension -> {
+            return extension instanceof CompleteConfigExtension;
+        }).map(extension -> {
+            return ((CompleteConfigExtension) extension).getTransformations();
+        }).filter(Objects::nonNull).forEach(transformations::addAll);
     }
 
     static EntryBase<?> of(Field field, Class<? extends ConfigContainer> parentClass) {

+ 8 - 3
lib/src/main/java/me/lortseam/completeconfig/extensions/CompleteConfigExtension.java

@@ -1,12 +1,17 @@
 package me.lortseam.completeconfig.extensions;
 
-public interface CompleteConfigExtension extends ConfigExtensionPattern {
+import me.lortseam.completeconfig.data.entry.Transformation;
+import org.spongepowered.configurate.serialize.TypeSerializerCollection;
 
-    default ConfigExtensionPattern client() {
+import java.util.Collection;
+
+public interface CompleteConfigExtension extends Extension {
+
+    default TypeSerializerCollection getTypeSerializers() {
         return null;
     }
 
-    default ConfigExtensionPattern server() {
+    default Collection<Transformation> getTransformations() {
         return null;
     }
 

+ 0 - 24
lib/src/main/java/me/lortseam/completeconfig/extensions/ConfigExtensionPattern.java

@@ -1,24 +0,0 @@
-package me.lortseam.completeconfig.extensions;
-
-import me.lortseam.completeconfig.data.entry.Transformation;
-import net.fabricmc.loader.api.FabricLoader;
-import org.spongepowered.configurate.serialize.TypeSerializerCollection;
-
-import java.util.Collection;
-
-public interface ConfigExtensionPattern {
-
-    default TypeSerializerCollection getTypeSerializers() {
-        return null;
-    }
-
-    default Collection<Transformation> getTransformations() {
-        return null;
-    }
-
-    default void dependOn(String dependentModID, Runnable runnable) {
-        if(!FabricLoader.getInstance().isModLoaded(dependentModID)) return;
-        runnable.run();
-    }
-
-}

+ 11 - 0
lib/src/main/java/me/lortseam/completeconfig/extensions/Extension.java

@@ -0,0 +1,11 @@
+package me.lortseam.completeconfig.extensions;
+
+import java.util.Set;
+
+public interface Extension {
+
+    default Set<Class<? extends Extension>> children() {
+        return null;
+    }
+
+}

+ 13 - 0
lib/src/main/java/me/lortseam/completeconfig/extensions/GuiExtension.java

@@ -0,0 +1,13 @@
+package me.lortseam.completeconfig.extensions;
+
+import me.lortseam.completeconfig.gui.cloth.Provider;
+
+import java.util.Collection;
+
+public interface GuiExtension extends Extension {
+
+    default Collection<Provider> getProviders() {
+        return null;
+    }
+
+}

+ 5 - 3
lib/src/main/java/me/lortseam/completeconfig/extensions/clothbasicmath/ClothBasicMathExtension.java

@@ -1,16 +1,18 @@
 package me.lortseam.completeconfig.extensions.clothbasicmath;
 
 import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
 import lombok.AccessLevel;
 import lombok.NoArgsConstructor;
 import me.lortseam.completeconfig.data.ColorEntry;
 import me.lortseam.completeconfig.data.entry.Transformation;
 import me.lortseam.completeconfig.extensions.CompleteConfigExtension;
-import me.lortseam.completeconfig.extensions.ConfigExtensionPattern;
+import me.lortseam.completeconfig.extensions.Extension;
 import me.shedaniel.math.Color;
 import org.spongepowered.configurate.serialize.TypeSerializerCollection;
 
 import java.util.Collection;
+import java.util.Set;
 
 @NoArgsConstructor(access = AccessLevel.PRIVATE)
 public final class ClothBasicMathExtension implements CompleteConfigExtension {
@@ -30,8 +32,8 @@ public final class ClothBasicMathExtension implements CompleteConfigExtension {
     }
 
     @Override
-    public ConfigExtensionPattern client() {
-        return new ClothBasicMathClientExtension();
+    public Set<Class<? extends Extension>> children() {
+        return ImmutableSet.of(ClothBasicMathGuiExtension.class);
     }
 
 }

+ 9 - 6
lib/src/main/java/me/lortseam/completeconfig/extensions/clothbasicmath/ClothBasicMathClientExtension.java → lib/src/main/java/me/lortseam/completeconfig/extensions/clothbasicmath/ClothBasicMathGuiExtension.java

@@ -1,22 +1,25 @@
 package me.lortseam.completeconfig.extensions.clothbasicmath;
 
 import me.lortseam.completeconfig.data.ColorEntry;
-import me.lortseam.completeconfig.extensions.ConfigExtensionPattern;
+import me.lortseam.completeconfig.extensions.GuiExtension;
 import me.lortseam.completeconfig.gui.cloth.Provider;
-import me.lortseam.completeconfig.gui.cloth.GuiRegistry;
 import me.shedaniel.clothconfig2.api.ConfigEntryBuilder;
 import me.shedaniel.math.Color;
 
-public final class ClothBasicMathClientExtension implements ConfigExtensionPattern {
+import java.util.Collection;
+import java.util.Collections;
 
-    ClothBasicMathClientExtension() {
-        dependOn("cloth-config2", () -> GuiRegistry.addGlobal(Provider.create(ColorEntry.class, (ColorEntry<Color> entry) -> ConfigEntryBuilder.create()
+final class ClothBasicMathGuiExtension implements GuiExtension {
+
+    @Override
+    public Collection<Provider> getProviders() {
+        return Collections.singletonList(Provider.create(ColorEntry.class, (ColorEntry<Color> entry) -> ConfigEntryBuilder.create()
                         .startColorField(entry.getText(), entry.getValue())
                         .setAlphaMode(entry.isAlphaMode())
                         .setDefaultValue(entry.getDefaultValue().getColor())
                         .setTooltip(entry.getTooltip())
                         .setSaveConsumer2(entry::setValue),
-                ColorEntry.class, Color.class)));
+                Color.class));
     }
 
 }

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

@@ -21,7 +21,7 @@ final class ColorSerializer extends ScalarSerializer<Color> {
         if (obj instanceof Integer) {
             return Color.ofTransparent((Integer) obj);
         }
-        throw new CoercionFailedException(type, obj, "TextColor");
+        throw new CoercionFailedException(type, obj, Color.class.getSimpleName());
     }
 
     @Override

+ 10 - 7
lib/src/main/java/me/lortseam/completeconfig/gui/cloth/GuiRegistry.java

@@ -1,22 +1,25 @@
 package me.lortseam.completeconfig.gui.cloth;
 
-import com.google.common.collect.Lists;
 import com.google.common.collect.MoreCollectors;
 import com.google.common.reflect.TypeToken;
+import me.lortseam.completeconfig.CompleteConfig;
 import me.lortseam.completeconfig.data.*;
+import me.lortseam.completeconfig.extensions.GuiExtension;
 import me.shedaniel.clothconfig2.api.ConfigEntryBuilder;
 import me.shedaniel.clothconfig2.impl.builders.DropdownMenuBuilder;
 import net.fabricmc.api.EnvType;
 import net.fabricmc.api.Environment;
 import net.minecraft.text.TextColor;
 
+import java.util.Collection;
 import java.util.*;
+import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
 @Environment(EnvType.CLIENT)
 public final class GuiRegistry {
 
-    private static final List<Provider> globalProviders = Lists.newArrayList(
+    private static final List<Provider> globalProviders = Stream.concat(Stream.of(
             Provider.create(BooleanEntry.class, entry -> ConfigEntryBuilder.create()
                             .startBooleanToggle(entry.getText(), entry.getValue())
                             .setDefaultValue(entry.getDefaultValue())
@@ -162,11 +165,11 @@ public final class GuiRegistry {
                         .setTooltip(entry.getTooltip())
                         .setSaveConsumer3(entry::setValue),
                     entry -> !entry.isAlphaMode(), TextColor.class)
-    );
-
-    public static void addGlobal(Provider... providers) {
-        Collections.addAll(globalProviders, providers);
-    }
+    ), CompleteConfig.getExtensions().stream().filter(extension -> {
+        return extension instanceof GuiExtension;
+    }).map(extension -> {
+        return ((GuiExtension) extension).getProviders();
+    }).filter(Objects::nonNull).flatMap(Collection::stream)).collect(Collectors.toList());
 
     private final List<Provider> providers = new ArrayList<>();
 

+ 6 - 2
lib/src/main/java/me/lortseam/completeconfig/io/ConfigSource.java

@@ -6,7 +6,7 @@ import lombok.ToString;
 import lombok.extern.log4j.Log4j2;
 import me.lortseam.completeconfig.CompleteConfig;
 import me.lortseam.completeconfig.data.Config;
-import me.lortseam.completeconfig.extensions.ConfigExtensionPattern;
+import me.lortseam.completeconfig.extensions.CompleteConfigExtension;
 import net.fabricmc.loader.api.FabricLoader;
 import org.apache.commons.lang3.ArrayUtils;
 import org.spongepowered.configurate.CommentedConfigurationNode;
@@ -63,7 +63,11 @@ public final class ConfigSource {
                 .path(path)
                 .defaultOptions(options -> options.serializers(builder -> {
                     builder.registerAll(GLOBAL_TYPE_SERIALIZERS);
-                    CompleteConfig.getExtensions().stream().map(ConfigExtensionPattern::getTypeSerializers).filter(Objects::nonNull).forEach(builder::registerAll);
+                    CompleteConfig.getExtensions().stream().filter(extension -> {
+                        return extension instanceof CompleteConfigExtension;
+                    }).map(extension -> {
+                        return ((CompleteConfigExtension) extension).getTypeSerializers();
+                    }).filter(Objects::nonNull).forEach(builder::registerAll);
                 }))
                 .build();
     }