From 04fe933f4c24817100f3101f088accf55a621f8a Mon Sep 17 00:00:00 2001 From: isxander Date: Thu, 11 Apr 2024 18:43:06 +0100 Subject: Extremely fragile and broken multiversion build with stonecutter --- .../yacl3/config/v2/api/ConfigClassHandler.java | 107 -------- .../isxander/yacl3/config/v2/api/ConfigField.java | 40 --- .../yacl3/config/v2/api/ConfigSerializer.java | 64 ----- .../isxander/yacl3/config/v2/api/FieldAccess.java | 14 -- .../yacl3/config/v2/api/ReadOnlyFieldAccess.java | 36 --- .../isxander/yacl3/config/v2/api/SerialEntry.java | 39 --- .../isxander/yacl3/config/v2/api/SerialField.java | 16 -- .../yacl3/config/v2/api/autogen/AutoGen.java | 32 --- .../yacl3/config/v2/api/autogen/AutoGenField.java | 12 - .../yacl3/config/v2/api/autogen/Boolean.java | 41 --- .../yacl3/config/v2/api/autogen/ColorField.java | 21 -- .../config/v2/api/autogen/CustomDescription.java | 12 - .../yacl3/config/v2/api/autogen/CustomFormat.java | 17 -- .../yacl3/config/v2/api/autogen/CustomImage.java | 69 ------ .../yacl3/config/v2/api/autogen/CustomName.java | 18 -- .../yacl3/config/v2/api/autogen/DoubleField.java | 46 ---- .../yacl3/config/v2/api/autogen/DoubleSlider.java | 48 ---- .../yacl3/config/v2/api/autogen/Dropdown.java | 43 ---- .../yacl3/config/v2/api/autogen/EnumCycler.java | 35 --- .../yacl3/config/v2/api/autogen/FloatField.java | 46 ---- .../yacl3/config/v2/api/autogen/FloatSlider.java | 48 ---- .../config/v2/api/autogen/FormatTranslation.java | 25 -- .../yacl3/config/v2/api/autogen/IntField.java | 41 --- .../yacl3/config/v2/api/autogen/IntSlider.java | 35 --- .../yacl3/config/v2/api/autogen/ItemField.java | 17 -- .../yacl3/config/v2/api/autogen/Label.java | 18 -- .../yacl3/config/v2/api/autogen/ListGroup.java | 60 ----- .../yacl3/config/v2/api/autogen/LongField.java | 41 --- .../yacl3/config/v2/api/autogen/LongSlider.java | 35 --- .../yacl3/config/v2/api/autogen/MasterTickBox.java | 26 -- .../yacl3/config/v2/api/autogen/OptionAccess.java | 35 --- .../yacl3/config/v2/api/autogen/OptionFactory.java | 40 --- .../config/v2/api/autogen/SimpleOptionFactory.java | 138 ----------- .../yacl3/config/v2/api/autogen/StringField.java | 17 -- .../yacl3/config/v2/api/autogen/TickBox.java | 17 -- .../serializer/GsonConfigSerializerBuilder.java | 98 -------- .../config/v2/impl/ConfigClassHandlerImpl.java | 274 --------------------- .../yacl3/config/v2/impl/ConfigFieldImpl.java | 75 ------ .../yacl3/config/v2/impl/FieldBackedBinding.java | 22 -- .../config/v2/impl/ReflectionFieldAccess.java | 49 ---- .../yacl3/config/v2/impl/autogen/AutoGenUtils.java | 54 ---- .../yacl3/config/v2/impl/autogen/BooleanImpl.java | 25 -- .../config/v2/impl/autogen/ColorFieldImpl.java | 19 -- .../config/v2/impl/autogen/DoubleFieldImpl.java | 32 --- .../config/v2/impl/autogen/DoubleSliderImpl.java | 33 --- .../yacl3/config/v2/impl/autogen/DropdownImpl.java | 19 -- .../v2/impl/autogen/EmptyCustomImageFactory.java | 17 -- .../config/v2/impl/autogen/EnumCyclerImpl.java | 42 ---- .../config/v2/impl/autogen/FloatFieldImpl.java | 32 --- .../config/v2/impl/autogen/FloatSliderImpl.java | 33 --- .../yacl3/config/v2/impl/autogen/IntFieldImpl.java | 28 --- .../config/v2/impl/autogen/IntSliderImpl.java | 29 --- .../config/v2/impl/autogen/ItemFieldImpl.java | 17 -- .../yacl3/config/v2/impl/autogen/LabelImpl.java | 16 -- .../config/v2/impl/autogen/ListGroupImpl.java | 102 -------- .../config/v2/impl/autogen/LongFieldImpl.java | 28 --- .../config/v2/impl/autogen/LongSliderImpl.java | 29 --- .../config/v2/impl/autogen/MasterTickBoxImpl.java | 25 -- .../config/v2/impl/autogen/OptionAccessImpl.java | 44 ---- .../v2/impl/autogen/OptionFactoryRegistry.java | 64 ----- .../config/v2/impl/autogen/StringFieldImpl.java | 16 -- .../yacl3/config/v2/impl/autogen/TickBoxImpl.java | 16 -- .../v2/impl/autogen/YACLAutoGenException.java | 11 - .../v2/impl/serializer/GsonConfigSerializer.java | 269 -------------------- 64 files changed, 2867 deletions(-) delete mode 100644 common/src/main/java/dev/isxander/yacl3/config/v2/api/ConfigClassHandler.java delete mode 100644 common/src/main/java/dev/isxander/yacl3/config/v2/api/ConfigField.java delete mode 100644 common/src/main/java/dev/isxander/yacl3/config/v2/api/ConfigSerializer.java delete mode 100644 common/src/main/java/dev/isxander/yacl3/config/v2/api/FieldAccess.java delete mode 100644 common/src/main/java/dev/isxander/yacl3/config/v2/api/ReadOnlyFieldAccess.java delete mode 100644 common/src/main/java/dev/isxander/yacl3/config/v2/api/SerialEntry.java delete mode 100644 common/src/main/java/dev/isxander/yacl3/config/v2/api/SerialField.java delete mode 100644 common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/AutoGen.java delete mode 100644 common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/AutoGenField.java delete mode 100644 common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/Boolean.java delete mode 100644 common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/ColorField.java delete mode 100644 common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/CustomDescription.java delete mode 100644 common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/CustomFormat.java delete mode 100644 common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/CustomImage.java delete mode 100644 common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/CustomName.java delete mode 100644 common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/DoubleField.java delete mode 100644 common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/DoubleSlider.java delete mode 100644 common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/Dropdown.java delete mode 100644 common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/EnumCycler.java delete mode 100644 common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/FloatField.java delete mode 100644 common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/FloatSlider.java delete mode 100644 common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/FormatTranslation.java delete mode 100644 common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/IntField.java delete mode 100644 common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/IntSlider.java delete mode 100644 common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/ItemField.java delete mode 100644 common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/Label.java delete mode 100644 common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/ListGroup.java delete mode 100644 common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/LongField.java delete mode 100644 common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/LongSlider.java delete mode 100644 common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/MasterTickBox.java delete mode 100644 common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/OptionAccess.java delete mode 100644 common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/OptionFactory.java delete mode 100644 common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/SimpleOptionFactory.java delete mode 100644 common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/StringField.java delete mode 100644 common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/TickBox.java delete mode 100644 common/src/main/java/dev/isxander/yacl3/config/v2/api/serializer/GsonConfigSerializerBuilder.java delete mode 100644 common/src/main/java/dev/isxander/yacl3/config/v2/impl/ConfigClassHandlerImpl.java delete mode 100644 common/src/main/java/dev/isxander/yacl3/config/v2/impl/ConfigFieldImpl.java delete mode 100644 common/src/main/java/dev/isxander/yacl3/config/v2/impl/FieldBackedBinding.java delete mode 100644 common/src/main/java/dev/isxander/yacl3/config/v2/impl/ReflectionFieldAccess.java delete mode 100644 common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/AutoGenUtils.java delete mode 100644 common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/BooleanImpl.java delete mode 100644 common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/ColorFieldImpl.java delete mode 100644 common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/DoubleFieldImpl.java delete mode 100644 common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/DoubleSliderImpl.java delete mode 100644 common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/DropdownImpl.java delete mode 100644 common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/EmptyCustomImageFactory.java delete mode 100644 common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/EnumCyclerImpl.java delete mode 100644 common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/FloatFieldImpl.java delete mode 100644 common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/FloatSliderImpl.java delete mode 100644 common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/IntFieldImpl.java delete mode 100644 common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/IntSliderImpl.java delete mode 100644 common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/ItemFieldImpl.java delete mode 100644 common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/LabelImpl.java delete mode 100644 common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/ListGroupImpl.java delete mode 100644 common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/LongFieldImpl.java delete mode 100644 common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/LongSliderImpl.java delete mode 100644 common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/MasterTickBoxImpl.java delete mode 100644 common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/OptionAccessImpl.java delete mode 100644 common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/OptionFactoryRegistry.java delete mode 100644 common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/StringFieldImpl.java delete mode 100644 common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/TickBoxImpl.java delete mode 100644 common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/YACLAutoGenException.java delete mode 100644 common/src/main/java/dev/isxander/yacl3/config/v2/impl/serializer/GsonConfigSerializer.java (limited to 'common/src/main/java/dev/isxander/yacl3/config/v2') diff --git a/common/src/main/java/dev/isxander/yacl3/config/v2/api/ConfigClassHandler.java b/common/src/main/java/dev/isxander/yacl3/config/v2/api/ConfigClassHandler.java deleted file mode 100644 index d94280f..0000000 --- a/common/src/main/java/dev/isxander/yacl3/config/v2/api/ConfigClassHandler.java +++ /dev/null @@ -1,107 +0,0 @@ -package dev.isxander.yacl3.config.v2.api; - -import dev.isxander.yacl3.api.YetAnotherConfigLib; -import dev.isxander.yacl3.config.v2.impl.ConfigClassHandlerImpl; -import net.minecraft.resources.ResourceLocation; - -import java.util.function.Function; - -/** - * Represents a handled config class. - * - * @param the backing config class to be managed - */ -public interface ConfigClassHandler { - /** - * Gets the working instance of the config class. - * This should be used to get and set fields like usual. - */ - T instance(); - - /** - * Gets a second instance of the config class that - * should be used to get default values only. No fields - * should be modified in this instance. - */ - T defaults(); - - /** - * Gets the class of the config. - */ - Class configClass(); - - /** - * Get all eligible fields in the config class. - * They could either be annotated with {@link dev.isxander.yacl3.config.v2.api.autogen.AutoGen} - * or {@link SerialEntry}, do not assume that a field has both of these. - */ - ConfigField[] fields(); - - /** - * The unique identifier of this config handler. - */ - ResourceLocation id(); - - /** - * Auto-generates a GUI for this config class. - * This throws an exception if auto-gen is not supported. - */ - YetAnotherConfigLib generateGui(); - - /** - * Whether this config class supports auto-gen. - * If on a dedicated server, this returns false. - */ - boolean supportsAutoGen(); - - /** - * Safely loads the config class using the provided serializer. - * @return if the config was loaded successfully - */ - boolean load(); - - /** - * Safely saves the config class using the provided serializer. - */ - void save(); - - /** - * The serializer for this config class. - * Manages saving and loading of the config with fields - * annotated with {@link SerialEntry}. - * - * @deprecated use {@link #load()} and {@link #save()} instead. - */ - @Deprecated - ConfigSerializer serializer(); - - /** - * Creates a builder for a config class. - * - * @param configClass the config class to build - * @param the type of the config class - * @return the builder - */ - static Builder createBuilder(Class configClass) { - return new ConfigClassHandlerImpl.BuilderImpl<>(configClass); - } - - interface Builder { - /** - * The unique identifier of this config handler. - * The namespace should be your modid. - * - * @return this builder - */ - Builder id(ResourceLocation id); - - /** - * The function to create the serializer for this config class. - * - * @return this builder - */ - Builder serializer(Function, ConfigSerializer> serializerFactory); - - ConfigClassHandler build(); - } -} diff --git a/common/src/main/java/dev/isxander/yacl3/config/v2/api/ConfigField.java b/common/src/main/java/dev/isxander/yacl3/config/v2/api/ConfigField.java deleted file mode 100644 index 181a4d4..0000000 --- a/common/src/main/java/dev/isxander/yacl3/config/v2/api/ConfigField.java +++ /dev/null @@ -1,40 +0,0 @@ -package dev.isxander.yacl3.config.v2.api; - -import dev.isxander.yacl3.config.v2.api.autogen.AutoGenField; - -import java.util.Optional; - -/** - * Represents a field in a config class. - * This is used to get all metadata on a field, - * and access the field and its default value. - * - * @param the field's type - */ -public interface ConfigField { - /** - * Gets the accessor for the field on the main instance. - * (Accessed through {@link ConfigClassHandler#instance()}) - */ - FieldAccess access(); - - /** - * Gets the accessor for the field on the default instance. - */ - ReadOnlyFieldAccess defaultAccess(); - - /** - * @return the parent config class handler that manages this field. - */ - ConfigClassHandler parent(); - - /** - * The serial entry metadata for this field, if it exists. - */ - Optional serial(); - - /** - * The auto-gen metadata for this field, if it exists. - */ - Optional autoGen(); -} diff --git a/common/src/main/java/dev/isxander/yacl3/config/v2/api/ConfigSerializer.java b/common/src/main/java/dev/isxander/yacl3/config/v2/api/ConfigSerializer.java deleted file mode 100644 index 4ac988c..0000000 --- a/common/src/main/java/dev/isxander/yacl3/config/v2/api/ConfigSerializer.java +++ /dev/null @@ -1,64 +0,0 @@ -package dev.isxander.yacl3.config.v2.api; - -import java.util.Map; - -/** - * The base class for config serializers, - * offering a method to save and load. - * @param the config class to be (de)serialized - */ -public abstract class ConfigSerializer { - protected final ConfigClassHandler config; - - public ConfigSerializer(ConfigClassHandler config) { - this.config = config; - } - - /** - * Saves all fields in the config class. - * This can be done any way as it's abstract, but most - * commonly it is saved to a file. - */ - public abstract void save(); - - /** - * Loads all fields into the config class. - * @param bufferAccessMap a map of the field accesses. instead of directly setting the field with - * {@link ConfigField#access()}, use this parameter. This loads into a temporary object, - * and the class handler handles pushing these changes to the instance. - * @return the result of the load - */ - public LoadResult loadSafely(Map, FieldAccess> bufferAccessMap) { - this.load(); - return LoadResult.NO_CHANGE; - } - - /** - * Loads all fields in the config class. - * - * @deprecated use {@link #loadSafely(Map)} instead. - */ - @Deprecated - public void load() { - throw new IllegalArgumentException("load() is deprecated, use loadSafely() instead."); - } - - public enum LoadResult { - /** - * Indicates that the config was loaded successfully and the temporary object should be applied. - */ - SUCCESS, - /** - * Indicates that the config was not loaded successfully and the load should be abandoned. - */ - FAILURE, - /** - * Indicates that the config has not changed after a load and the temporary object should be ignored. - */ - NO_CHANGE, - /** - * Indicates the config was loaded successfully, but the config should be re-saved straight away. - */ - DIRTY - } -} diff --git a/common/src/main/java/dev/isxander/yacl3/config/v2/api/FieldAccess.java b/common/src/main/java/dev/isxander/yacl3/config/v2/api/FieldAccess.java deleted file mode 100644 index ea30cd8..0000000 --- a/common/src/main/java/dev/isxander/yacl3/config/v2/api/FieldAccess.java +++ /dev/null @@ -1,14 +0,0 @@ -package dev.isxander.yacl3.config.v2.api; - -/** - * A writable field instance access. - * - * @param the type of the field - */ -public interface FieldAccess extends ReadOnlyFieldAccess { - /** - * Sets the value of the field. - * @param value the value to set - */ - void set(T value); -} diff --git a/common/src/main/java/dev/isxander/yacl3/config/v2/api/ReadOnlyFieldAccess.java b/common/src/main/java/dev/isxander/yacl3/config/v2/api/ReadOnlyFieldAccess.java deleted file mode 100644 index 566d60d..0000000 --- a/common/src/main/java/dev/isxander/yacl3/config/v2/api/ReadOnlyFieldAccess.java +++ /dev/null @@ -1,36 +0,0 @@ -package dev.isxander.yacl3.config.v2.api; - -import java.lang.annotation.Annotation; -import java.lang.reflect.Type; -import java.util.Optional; - -/** - * An abstract interface for accessing properties of an instance of a field. - * You do not need to worry about exceptions as the implementation - * will handle them. - * - * @param the type of the field - */ -public interface ReadOnlyFieldAccess { - /** - * @return the current value of the field. - */ - T get(); - - /** - * @return the name of the field. - */ - String name(); - - /** - * @return the type of the field. - */ - Type type(); - - /** - * @return the class of the field. - */ - Class typeClass(); - - Optional getAnnotation(Class annotationClass); -} diff --git a/common/src/main/java/dev/isxander/yacl3/config/v2/api/SerialEntry.java b/common/src/main/java/dev/isxander/yacl3/config/v2/api/SerialEntry.java deleted file mode 100644 index 94bf785..0000000 --- a/common/src/main/java/dev/isxander/yacl3/config/v2/api/SerialEntry.java +++ /dev/null @@ -1,39 +0,0 @@ -package dev.isxander.yacl3.config.v2.api; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Marks a field as serializable, so it can be used in a {@link ConfigSerializer}. - * Any field without this annotation will not be saved or loaded, but can still be turned - * into an auto-generated option. - */ -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.FIELD) -public @interface SerialEntry { - /** - * The serial name of the field. - * If empty, the serializer will decide the name. - */ - String value() default ""; - - /** - * The comment to add to the field. - * Some serializers may not support this. - * If empty, the serializer will not add a comment. - */ - String comment() default ""; - - /** - * Whether the field is required in the loaded config to be valid. - * If it's not, the config will be marked as dirty and re-saved with the default value. - */ - boolean required() default true; - - /** - * Whether the field can be null. - */ - boolean nullable() default false; -} diff --git a/common/src/main/java/dev/isxander/yacl3/config/v2/api/SerialField.java b/common/src/main/java/dev/isxander/yacl3/config/v2/api/SerialField.java deleted file mode 100644 index cf6abfc..0000000 --- a/common/src/main/java/dev/isxander/yacl3/config/v2/api/SerialField.java +++ /dev/null @@ -1,16 +0,0 @@ -package dev.isxander.yacl3.config.v2.api; - -import java.util.Optional; - -/** - * The backing interface for the {@link SerialEntry} annotation. - */ -public interface SerialField { - String serialName(); - - Optional comment(); - - boolean required(); - - boolean nullable(); -} diff --git a/common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/AutoGen.java b/common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/AutoGen.java deleted file mode 100644 index 4187caf..0000000 --- a/common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/AutoGen.java +++ /dev/null @@ -1,32 +0,0 @@ -package dev.isxander.yacl3.config.v2.api.autogen; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Any field that is annotated with this will generate a config option - * in the auto-generated config GUI. This should be paired with an - * {@link OptionFactory} annotation to define how to create the option. - * Some examples of this are {@link TickBox}, {@link FloatSlider}, {@link Label} or {@link StringField}. - */ -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.FIELD) -public @interface AutoGen { - /** - * Should be the id of the category. This is used to group options. - * The translation keys also use this. Category IDs can be set as a - * {@code private static final String} and used in the annotation to prevent - * repeating yourself. - */ - String category(); - - /** - * If left blank, the option will go in the root group, where it is - * listed at the top of the category with no group header. If set, - * this also appends to the translation key. Group IDs can be reused - * between multiple categories. - */ - String group() default ""; -} diff --git a/common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/AutoGenField.java b/common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/AutoGenField.java deleted file mode 100644 index 7f751fb..0000000 --- a/common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/AutoGenField.java +++ /dev/null @@ -1,12 +0,0 @@ -package dev.isxander.yacl3.config.v2.api.autogen; - -import java.util.Optional; - -/** - * Backing interface for the {@link AutoGen} annotation. - */ -public interface AutoGenField { - String category(); - - Optional group(); -} diff --git a/common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/Boolean.java b/common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/Boolean.java deleted file mode 100644 index 5598389..0000000 --- a/common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/Boolean.java +++ /dev/null @@ -1,41 +0,0 @@ -package dev.isxander.yacl3.config.v2.api.autogen; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * An option factory. - *

- * This creates a regular option with a - * {@link dev.isxander.yacl3.api.controller.BooleanControllerBuilder} controller. - */ -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.FIELD) -public @interface Boolean { - enum Formatter { - YES_NO, - TRUE_FALSE, - ON_OFF, - /** - * Uses the translation keys: - *

    - *
  • true: {@code yacl3.config.$configId.$fieldName.fmt.true}
  • - *
  • false: {@code yacl3.config.$configId.$fieldName.fmt.false}
  • - *
- */ - CUSTOM, - } - - /** - * The format used to display the boolean. - */ - Formatter formatter() default Formatter.TRUE_FALSE; - - /** - * Whether to color the formatted text green and red - * depending on the value: true or false respectively. - */ - boolean colored() default false; -} diff --git a/common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/ColorField.java b/common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/ColorField.java deleted file mode 100644 index 74937b4..0000000 --- a/common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/ColorField.java +++ /dev/null @@ -1,21 +0,0 @@ -package dev.isxander.yacl3.config.v2.api.autogen; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * An option factory. - *

- * This creates a regular option with a - * {@link dev.isxander.yacl3.api.controller.ColorControllerBuilder} controller. - */ -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.FIELD) -public @interface ColorField { - /** - * Whether to show/allow the alpha channel in the color field. - */ - boolean allowAlpha() default false; -} diff --git a/common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/CustomDescription.java b/common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/CustomDescription.java deleted file mode 100644 index 08624b4..0000000 --- a/common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/CustomDescription.java +++ /dev/null @@ -1,12 +0,0 @@ -package dev.isxander.yacl3.config.v2.api.autogen; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.FIELD) -public @interface CustomDescription { - String[] value() default ""; -} diff --git a/common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/CustomFormat.java b/common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/CustomFormat.java deleted file mode 100644 index 15f6336..0000000 --- a/common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/CustomFormat.java +++ /dev/null @@ -1,17 +0,0 @@ -package dev.isxander.yacl3.config.v2.api.autogen; - -import dev.isxander.yacl3.api.controller.ValueFormatter; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Allows you to specify a custom {@link ValueFormatter} for a field. - */ -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.FIELD) -public @interface CustomFormat { - Class> value(); -} diff --git a/common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/CustomImage.java b/common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/CustomImage.java deleted file mode 100644 index d193f42..0000000 --- a/common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/CustomImage.java +++ /dev/null @@ -1,69 +0,0 @@ -package dev.isxander.yacl3.config.v2.api.autogen; - -import dev.isxander.yacl3.config.v2.api.ConfigField; -import dev.isxander.yacl3.config.v2.impl.autogen.EmptyCustomImageFactory; -import dev.isxander.yacl3.gui.image.ImageRenderer; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; -import java.util.Optional; -import java.util.concurrent.CompletableFuture; - -/** - * Defines a custom image for an option. - * Without this annotation, the option factory will look - * for the resource {@code modid:textures/yacl3/$config_id_path/$fieldName.webp}. - * WEBP was chosen as the default format because file sizes are greatly reduced, - * which is important to keep your JAR size down, if you're so bothered. - */ -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.FIELD) -public @interface CustomImage { - /** - * The resource path to the image, a {@link net.minecraft.resources.ResourceLocation} - * is constructed with the namespace being the modid of the config, and the path being - * this value. - *

- * The following file formats are supported: - *

    - *
  • {@code .png}
  • - *
  • {@code .webp}
  • - *
  • {@code .jpg}, {@code .jpeg}
  • - *
  • {@code .gif} - HIGHLY DISCOURAGED DUE TO LARGE FILE SIZE
  • - *
- *

- * If left blank, then {@link CustomImage#factory()} is used. - */ - String value() default ""; - - /** - * The width of the image, in pixels. - * This is only required when using a PNG with {@link CustomImage#value()} - */ - int width() default 0; - - /** - * The width of the image, in pixels. - * This is only required when using a PNG with {@link CustomImage#value()} - */ - int height() default 0; - - /** - * The factory to create the image with. - * For the average user, this should not be used as it breaks out of the - * API-safe environment where things could change at any time, but required - * when creating anything advanced with the {@link ImageRenderer}. - *

- * The factory should contain a public, no-args constructor that will be - * invoked via reflection. - * - * @return the class of the factory - */ - Class> factory() default EmptyCustomImageFactory.class; - - interface CustomImageFactory { - CompletableFuture createImage(T value, ConfigField field, OptionAccess access); - } -} diff --git a/common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/CustomName.java b/common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/CustomName.java deleted file mode 100644 index aa235bb..0000000 --- a/common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/CustomName.java +++ /dev/null @@ -1,18 +0,0 @@ -package dev.isxander.yacl3.config.v2.api.autogen; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Overrides the name of an auto-generated option. - */ -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.FIELD) -public @interface CustomName { - /** - * The translation key to use for the option's name. - */ - String value() default ""; -} diff --git a/common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/DoubleField.java b/common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/DoubleField.java deleted file mode 100644 index 963cefd..0000000 --- a/common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/DoubleField.java +++ /dev/null @@ -1,46 +0,0 @@ -package dev.isxander.yacl3.config.v2.api.autogen; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * A regular option factory. - *

- * This creates a regular option with a - * {@link dev.isxander.yacl3.api.controller.DoubleFieldControllerBuilder} controller. - */ -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.FIELD) -public @interface DoubleField { - /** - * The minimum value of the field. If a user enters a value less - * than this, it will be clamped to this value. - *

- * If this is set to {@code -Double.MAX_VALUE}, there will be no minimum. - *

- * If the current value is at this minimum, if available, - * the translation key {@code yacl3.config.$configId.$fieldName.fmt.min} - * will be used. - */ - double min() default -Double.MAX_VALUE; - - /** - * The maximum value of the field. If a user enters a value more - * than this, it will be clamped to this value. - *

- * If this is set to {@code Double.MAX_VALUE}, there will be no minimum. - *

- * If the current value is at this maximum, if available, - * the translation key {@code yacl3.config.$configId.$fieldName.fmt.max} - * will be used. - */ - double max() default Double.MAX_VALUE; - - /** - * The format used to display the double. - * This is the syntax used in {@link String#format(String, Object...)}. - */ - String format() default "%.2f"; -} diff --git a/common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/DoubleSlider.java b/common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/DoubleSlider.java deleted file mode 100644 index 268f6a4..0000000 --- a/common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/DoubleSlider.java +++ /dev/null @@ -1,48 +0,0 @@ -package dev.isxander.yacl3.config.v2.api.autogen; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * A regular option factory. - *

- * This creates a regular option with a - * {@link dev.isxander.yacl3.api.controller.DoubleSliderControllerBuilder} controller. - */ -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.FIELD) -public @interface DoubleSlider { - /** - * The minimum value of the slider. - *

- * If the current value is at this minimum, if available, - * the translation key {@code yacl3.config.$configId.$fieldName.fmt.min} - * will be used. - */ - double min(); - - /** - * The maximum value of the slider. - *

- * If the current value is at this maximum, if available, - * the translation key {@code yacl3.config.$configId.$fieldName.fmt.max} - * will be used. - */ - double max(); - - /** - * The step size of this slider. - * For example, if this is set to 0.1, the slider will - * increment/decrement by 0.1 when dragging, no less, no more and - * will always be a multiple of 0.1. - */ - double step(); - - /** - * The format used to display the double. - * This is the syntax used in {@link String#format(String, Object...)}. - */ - String format() default "%.2f"; -} diff --git a/common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/Dropdown.java b/common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/Dropdown.java deleted file mode 100644 index 44239d5..0000000 --- a/common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/Dropdown.java +++ /dev/null @@ -1,43 +0,0 @@ -package dev.isxander.yacl3.config.v2.api.autogen; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * An option factory. - *

- * This creates a regular option with a - * {@link dev.isxander.yacl3.api.controller.DropdownStringControllerBuilder} controller. - */ -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.FIELD) -public @interface Dropdown { - /** - * The allowed values for the field. These will be shown in a dropdown - * that the user can filter and select from. - *

- * Only values in this list will be accepted and written to the config - * file, unless {@link #allow()} is set to ${@code ALLOW_ANY}. - *

- * Empty string is a valid value only if it appears in this list, or if - * {@link #allow()} is set to {@code ALLOW_EMPTY} or {@code ALLOW_ANY}. - */ - String[] values(); - - /** - * Whether to accept the empty string as a valid value if it does not - * already appear in {@link #values()}. If it already appears there, - * the value of this does not apply. - */ - boolean allowEmptyValue() default false; - - /** - * Whether to accept any string as a valid value. The list of strings - * supplied in {@link #values()} are only used as dropdown suggestions. - * Empty strings are still prohibited unless the empty string appears in - * {@link #values()} or {@link #allowEmptyValue()}. - */ - boolean allowAnyValue() default false; -} diff --git a/common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/EnumCycler.java b/common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/EnumCycler.java deleted file mode 100644 index 98d94f9..0000000 --- a/common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/EnumCycler.java +++ /dev/null @@ -1,35 +0,0 @@ -package dev.isxander.yacl3.config.v2.api.autogen; - -import dev.isxander.yacl3.api.NameableEnum; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * An option factory. - *

- * This creates a regular option with a {@link dev.isxander.yacl3.api.controller.CyclingListControllerBuilder} - * controller. If the enum implements {@link CyclableEnum}, the allowed values will be used from that, - * rather than every single enum constant in the class. If not, {@link EnumCycler#allowedOrdinals()} is used. - *

- * There are two methods of formatting for enum values. First, if the enum implements - * {@link dev.isxander.yacl3.api.NameableEnum}, {@link NameableEnum#getDisplayName()} is used. - * Otherwise, the translation key {@code yacl3.config.enum.$enumClassName.$enumName} where - * {@code $enumClassName} is the exact name of the class and {@code $enumName} is equal to the lower - * case of {@link Enum#name()}. - */ -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.FIELD) -public @interface EnumCycler { - /** - * The allowed ordinals of the enum class. If empty, all ordinals are allowed. - * This is only used if the enum does not implement {@link CyclableEnum}. - */ - int[] allowedOrdinals() default {}; - - interface CyclableEnum> { - T[] allowedValues(); - } -} diff --git a/common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/FloatField.java b/common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/FloatField.java deleted file mode 100644 index 1e7e71e..0000000 --- a/common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/FloatField.java +++ /dev/null @@ -1,46 +0,0 @@ -package dev.isxander.yacl3.config.v2.api.autogen; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * A regular option factory. - *

- * This creates a regular option with a - * {@link dev.isxander.yacl3.api.controller.FloatFieldControllerBuilder} controller. - */ -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.FIELD) -public @interface FloatField { - /** - * The minimum value of the field. If a user enters a value less - * than this, it will be clamped to this value. - *

- * If this is set to {@code -Float.MAX_VALUE}, there will be no minimum. - *

- * If the current value is at this minimum, if available, - * the translation key {@code yacl3.config.$configId.$fieldName.fmt.min} - * will be used. - */ - float min() default -Float.MAX_VALUE; - - /** - * The maximum value of the field. If a user enters a value more - * than this, it will be clamped to this value. - *

- * If this is set to {@code Float.MAX_VALUE}, there will be no minimum. - *

- * If the current value is at this maximum, if available, - * the translation key {@code yacl3.config.$configId.$fieldName.fmt.max} - * will be used. - */ - float max() default Float.MAX_VALUE; - - /** - * The format used to display the float. - * This is the syntax used in {@link String#format(String, Object...)}. - */ - String format() default "%.1f"; -} diff --git a/common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/FloatSlider.java b/common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/FloatSlider.java deleted file mode 100644 index 19ae9db..0000000 --- a/common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/FloatSlider.java +++ /dev/null @@ -1,48 +0,0 @@ -package dev.isxander.yacl3.config.v2.api.autogen; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * A regular option factory. - *

- * This creates a regular option with a - * {@link dev.isxander.yacl3.api.controller.FloatSliderControllerBuilder} controller. - */ -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.FIELD) -public @interface FloatSlider { - /** - * The minimum value of the slider. - *

- * If the current value is at this minimum, if available, - * the translation key {@code yacl3.config.$configId.$fieldName.fmt.min} - * will be used. - */ - float min(); - - /** - * The maximum value of the slider. - *

- * If the current value is at this maximum, if available, - * the translation key {@code yacl3.config.$configId.$fieldName.fmt.max} - * will be used. - */ - float max(); - - /** - * The step size of this slider. - * For example, if this is set to 0.1, the slider will - * increment/decrement by 0.1 when dragging, no less, no more and - * will always be a multiple of 0.1. - */ - float step(); - - /** - * The format used to display the float. - * This is the syntax used in {@link String#format(String, Object...)}. - */ - String format() default "%.1f"; -} diff --git a/common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/FormatTranslation.java b/common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/FormatTranslation.java deleted file mode 100644 index 7cc4ded..0000000 --- a/common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/FormatTranslation.java +++ /dev/null @@ -1,25 +0,0 @@ -package dev.isxander.yacl3.config.v2.api.autogen; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Allows you to specify a custom value formatter - * in the form of a translation key. - *

- * Without this annotation, the value will be formatted - * according to the option factory, implementation details - * for that should be found in the javadoc for the factory. - */ -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.FIELD) -public @interface FormatTranslation { - /** - * The translation key for the value formatter. - * One parameter is passed to this key: the option's value, - * using {@link Object#toString()}. - */ - String value() default ""; -} diff --git a/common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/IntField.java b/common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/IntField.java deleted file mode 100644 index 9945d01..0000000 --- a/common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/IntField.java +++ /dev/null @@ -1,41 +0,0 @@ -package dev.isxander.yacl3.config.v2.api.autogen; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * A regular option factory. - *

- * This creates a regular option with a - * {@link dev.isxander.yacl3.api.controller.IntegerFieldControllerBuilder} controller. - *

- * If available, the translation key {@code yacl3.config.$configId.$fieldName.fmt.$value} - * is used where {@code $value} is the current value of the option, for example, {@code 5}. - */ -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.FIELD) -public @interface IntField { - /** - * The minimum value of the field. If a user enters a value less - * than this, it will be clamped to this value. - *

- * If this is set to {@code Integer.MIN_VALUE}, there will be no minimum. - */ - int min() default Integer.MIN_VALUE; - - /** - * The minimum value of the field. If a user enters a value more - * than this, it will be clamped to this value. - *

- * If this is set to {@code Integer.MAX_VALUE}, there will be no minimum. - */ - int max() default Integer.MAX_VALUE; - - /** - * The format used to display the integer. - * This is the syntax used in {@link String#format(String, Object...)}. - */ - String format() default "%.0f"; -} diff --git a/common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/IntSlider.java b/common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/IntSlider.java deleted file mode 100644 index 7fd2282..0000000 --- a/common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/IntSlider.java +++ /dev/null @@ -1,35 +0,0 @@ -package dev.isxander.yacl3.config.v2.api.autogen; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * A regular option factory. - *

- * This creates a regular option with a - * {@link dev.isxander.yacl3.api.controller.IntegerSliderControllerBuilder} controller. - *

- * If available, the translation key {@code yacl3.config.$configId.$fieldName.fmt.$value} - * is used where {@code $value} is the current value of the option, for example, {@code 5}. - */ -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.FIELD) -public @interface IntSlider { - /** - * The minimum value of the slider. - */ - int min(); - - /** - * The maximum value of the slider. - */ - int max(); - - /** - * The format used to display the integer. - * This is the syntax used in {@link String#format(String, Object...)}. - */ - int step(); -} diff --git a/common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/ItemField.java b/common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/ItemField.java deleted file mode 100644 index 84d2c7a..0000000 --- a/common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/ItemField.java +++ /dev/null @@ -1,17 +0,0 @@ -package dev.isxander.yacl3.config.v2.api.autogen; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * An option factory. - *

- * This creates a regular option with a - * {@link dev.isxander.yacl3.api.controller.ItemControllerBuilder} controller. - */ -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.FIELD) -public @interface ItemField { -} diff --git a/common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/Label.java b/common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/Label.java deleted file mode 100644 index 41e026f..0000000 --- a/common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/Label.java +++ /dev/null @@ -1,18 +0,0 @@ -package dev.isxander.yacl3.config.v2.api.autogen; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * An option factory that creates an instance - * of a {@link dev.isxander.yacl3.api.LabelOption}. - *

- * The backing field can be private and final and - * must be of type {@link net.minecraft.network.chat.Component}. - */ -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.FIELD) -public @interface Label { -} diff --git a/common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/ListGroup.java b/common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/ListGroup.java deleted file mode 100644 index c664f71..0000000 --- a/common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/ListGroup.java +++ /dev/null @@ -1,60 +0,0 @@ -package dev.isxander.yacl3.config.v2.api.autogen; - -import dev.isxander.yacl3.api.Option; -import dev.isxander.yacl3.api.controller.ControllerBuilder; -import dev.isxander.yacl3.config.v2.api.ConfigField; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; -import java.util.List; - -/** - * An option factory. - *

- * This creates a List option with a custom controller. - */ -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.FIELD) -public @interface ListGroup { - /** - * The {@link Class} representing a class that implements {@link ValueFactory}. - * To create a new instance for the list when the user adds a new entry to the list. - * Remember this class can be shared with {@link ControllerFactory} as well. - */ - Class> valueFactory(); - - /** - * The {@link Class} representing a class that implements {@link ControllerBuilder} - * to add a controller to every entry in the list. - * Remember this class can be shared with {@link ValueFactory} as well. - */ - Class> controllerFactory(); - - /** - * The maximum number of entries that can be added to the list. - * Once at this limit, the add button is disabled. - * If this is equal to {@code 0}, there is no limit. - */ - int maxEntries() default 0; - - /** - * The minimum number of entries that must be in the list. - * When at this limit, the remove button of the entries is disabled. - */ - int minEntries() default 0; - - /** - * Whether to add new entries at the bottom of the list rather than the top. - */ - boolean addEntriesToBottom() default false; - - interface ValueFactory { - T provideNewValue(); - } - - interface ControllerFactory { - ControllerBuilder createController(ListGroup annotation, ConfigField> field, OptionAccess storage, Option option); - } -} diff --git a/common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/LongField.java b/common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/LongField.java deleted file mode 100644 index 01c3a7e..0000000 --- a/common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/LongField.java +++ /dev/null @@ -1,41 +0,0 @@ -package dev.isxander.yacl3.config.v2.api.autogen; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * A regular option factory. - *

- * This creates a regular option with a - * {@link dev.isxander.yacl3.api.controller.LongFieldControllerBuilder} controller. - *

- * If available, the translation key {@code yacl3.config.$configId.$fieldName.fmt.$value} - * is used where {@code $value} is the current value of the option, for example, {@code 5}. - */ -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.FIELD) -public @interface LongField { - /** - * The minimum value of the field. If a user enters a value less - * than this, it will be clamped to this value. - *

- * If this is set to {@code Long.MIN_VALUE}, there will be no minimum. - */ - long min() default Long.MIN_VALUE; - - /** - * The maximum value of the field. If a user enters a value more - * than this, it will be clamped to this value. - *

- * If this is set to {@code Long.MAX_VALUE}, there will be no minimum. - */ - long max() default Long.MAX_VALUE; - - /** - * The format used to display the long. - * This is the syntax used in {@link String#format(String, Object...)}. - */ - String format() default "%.0f"; -} diff --git a/common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/LongSlider.java b/common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/LongSlider.java deleted file mode 100644 index 5563bd0..0000000 --- a/common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/LongSlider.java +++ /dev/null @@ -1,35 +0,0 @@ -package dev.isxander.yacl3.config.v2.api.autogen; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * A regular option factory. - *

- * This creates a regular option with a - * {@link dev.isxander.yacl3.api.controller.LongSliderControllerBuilder} controller. - *

- * If available, the translation key {@code yacl3.config.$configId.$fieldName.fmt.$value} - * is used where {@code $value} is the current value of the option, for example, {@code 5}. - */ -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.FIELD) -public @interface LongSlider { - /** - * The minimum value of the slider. - */ - long min(); - - /** - * The maximum value of the slider. - */ - long max(); - - /** - * The format used to display the integer. - * This is the syntax used in {@link String#format(String, Object...)}. - */ - long step(); -} diff --git a/common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/MasterTickBox.java b/common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/MasterTickBox.java deleted file mode 100644 index 70dee1a..0000000 --- a/common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/MasterTickBox.java +++ /dev/null @@ -1,26 +0,0 @@ -package dev.isxander.yacl3.config.v2.api.autogen; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * An option factory like {@link TickBox} but controls - * other options' availability based on its state. - */ -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.FIELD) -public @interface MasterTickBox { - /** - * The exact names of the fields with {@link AutoGen} annotation - * to control the availability of. - */ - String[] value(); - - /** - * Whether having the tickbox disabled should enable the options - * rather than disable. - */ - boolean invert() default false; -} diff --git a/common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/OptionAccess.java b/common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/OptionAccess.java deleted file mode 100644 index c55afe4..0000000 --- a/common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/OptionAccess.java +++ /dev/null @@ -1,35 +0,0 @@ -package dev.isxander.yacl3.config.v2.api.autogen; - -import dev.isxander.yacl3.api.Option; -import org.jetbrains.annotations.Nullable; - -import java.util.function.Consumer; - -/** - * An accessor to all options that are auto-generated - * by the config system. - */ -public interface OptionAccess { - /** - * Gets an option by its field name. - * This could be null if the option hasn't been created yet. It is created - * in order of the fields in the class, so if you are trying to get an option - * lower-down in the class, this will return null. - * - * @param fieldName the exact, case-sensitive name of the field. - * @return the created option, or {@code null} if it hasn't been created yet. - */ - @Nullable Option getOption(String fieldName); - - /** - * Schedules an operation to be performed on an option. - * If the option has already been created, the consumer will be - * accepted immediately upon calling this method, if not, it will - * be added to the queue of operations to be performed on the option - * once it does get created. - * - * @param fieldName the exact, case-sensitive name of the field. - * @param optionConsumer the operation to perform on the option. - */ - void scheduleOptionOperation(String fieldName, Consumer> optionConsumer); -} diff --git a/common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/OptionFactory.java b/common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/OptionFactory.java deleted file mode 100644 index 515a40b..0000000 --- a/common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/OptionFactory.java +++ /dev/null @@ -1,40 +0,0 @@ -package dev.isxander.yacl3.config.v2.api.autogen; - -import dev.isxander.yacl3.api.Option; -import dev.isxander.yacl3.config.v2.api.ConfigField; -import dev.isxander.yacl3.config.v2.impl.autogen.OptionFactoryRegistry; - -import java.lang.annotation.Annotation; - -/** - * The backing builder for option factories' annotations. - *

- * If you want to make a basic option with a controller, it's recommended - * to use {@link SimpleOptionFactory} instead which is a subclass of this. - * - * @param the annotation type - * @param the option's binding type - */ -public interface OptionFactory { - /** - * Creates an option from the given annotation, backing field, and storage. - * - * @param annotation the annotation that fields are annotated with to use this factory - * @param field the backing field - * @param optionAccess the option access to access other options in the GUI - * @return the built option to be added to the group/category - */ - Option createOption(A annotation, ConfigField field, OptionAccess optionAccess); - - /** - * Registers an option factory to be used by configs. - * - * @param annotationClass the class of the annotation to use a factory - * @param factory an instance of the factory - * @param the type of the annotation - * @param the type of the option's binding - */ - static void register(Class annotationClass, OptionFactory factory) { - OptionFactoryRegistry.registerOptionFactory(annotationClass, factory); - } -} diff --git a/common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/SimpleOptionFactory.java b/common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/SimpleOptionFactory.java deleted file mode 100644 index f7d807f..0000000 --- a/common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/SimpleOptionFactory.java +++ /dev/null @@ -1,138 +0,0 @@ -package dev.isxander.yacl3.config.v2.api.autogen; - -import dev.isxander.yacl3.api.Option; -import dev.isxander.yacl3.api.OptionDescription; -import dev.isxander.yacl3.api.OptionFlag; -import dev.isxander.yacl3.api.controller.ControllerBuilder; -import dev.isxander.yacl3.config.v2.api.ConfigField; -import dev.isxander.yacl3.config.v2.impl.FieldBackedBinding; -import dev.isxander.yacl3.config.v2.impl.autogen.AutoGenUtils; -import dev.isxander.yacl3.config.v2.impl.autogen.EmptyCustomImageFactory; -import dev.isxander.yacl3.config.v2.impl.autogen.YACLAutoGenException; -import net.minecraft.client.Minecraft; -import net.minecraft.locale.Language; -import net.minecraft.network.chat.Component; -import net.minecraft.network.chat.MutableComponent; -import net.minecraft.resources.ResourceLocation; -import org.jetbrains.annotations.Nullable; - -import java.lang.annotation.Annotation; -import java.util.Optional; -import java.util.Set; - -public abstract class SimpleOptionFactory implements OptionFactory { - @Override - public Option createOption(A annotation, ConfigField field, OptionAccess optionAccess) { - Option option = Option.createBuilder() - .name(this.name(annotation, field, optionAccess)) - .description(v -> this.description(v, annotation, field, optionAccess).build()) - .binding(new FieldBackedBinding<>(field.access(), field.defaultAccess())) - .controller(opt -> { - ControllerBuilder builder = this.createController(annotation, field, optionAccess, opt); - - AutoGenUtils.addCustomFormatterToController(builder, field.access()); - - return builder; - }) - .available(this.available(annotation, field, optionAccess)) - .flags(this.flags(annotation, field, optionAccess)) - .listener((opt, v) -> this.listener(annotation, field, optionAccess, opt, v)) - .build(); - - postInit(annotation, field, optionAccess, option); - return option; - } - - protected abstract ControllerBuilder createController(A annotation, ConfigField field, OptionAccess storage, Option option); - - protected MutableComponent name(A annotation, ConfigField field, OptionAccess storage) { - Optional customName = field.access().getAnnotation(CustomName.class); - return Component.translatable(customName.map(CustomName::value).orElse(this.getTranslationKey(field, null))); - } - - protected OptionDescription.Builder description(T value, A annotation, ConfigField field, OptionAccess storage) { - OptionDescription.Builder builder = OptionDescription.createBuilder(); - - String key = this.getTranslationKey(field, "desc"); - if (Language.getInstance().has(key)) { - builder.text(Component.translatable(key)); - } else { - key += "."; - int i = 1; - while (Language.getInstance().has(key + i)) { - builder.text(Component.translatable(key + i)); - i++; - } - } - - field.access().getAnnotation(CustomDescription.class).ifPresent(customDescription -> { - for (String line : customDescription.value()) { - builder.text(Component.translatable(line)); - } - }); - - Optional imageOverrideOpt = field.access().getAnnotation(CustomImage.class); - if (imageOverrideOpt.isPresent()) { - CustomImage imageOverride = imageOverrideOpt.get(); - - if (!imageOverride.factory().equals(EmptyCustomImageFactory.class)) { - CustomImage.CustomImageFactory imageFactory; - try { - imageFactory = (CustomImage.CustomImageFactory) AutoGenUtils.constructNoArgsClass( - imageOverride.factory(), - () -> "'%s': The factory class on @OverrideImage has no no-args constructor.".formatted(field.access().name()), - () -> "'%s': Failed to instantiate factory class %s.".formatted(field.access().name(), imageOverride.factory().getName()) - ); - } catch (ClassCastException e) { - throw new YACLAutoGenException("'%s': The factory class on @OverrideImage is of incorrect type. Expected %s, got %s.".formatted(field.access().name(), field.access().type().getTypeName(), imageOverride.factory().getTypeParameters()[0].getName())); - } - - builder.customImage(imageFactory.createImage(value, field, storage).thenApply(Optional::of)); - } else if (!imageOverride.value().isEmpty()) { - String path = imageOverride.value(); - ResourceLocation imageLocation = new ResourceLocation(field.parent().id().getNamespace(), path); - String extension = path.substring(path.lastIndexOf('.') + 1); - - switch (extension) { - case "png", "jpg", "jpeg" -> builder.image(imageLocation, imageOverride.width(), imageOverride.height()); - case "webp" -> builder.webpImage(imageLocation); - case "gif" -> builder.gifImage(imageLocation); - default -> throw new YACLAutoGenException("'%s': Invalid image extension '%s' on @OverrideImage. Expected: ('png','jpg','webp','gif')".formatted(field.access().name(), extension)); - } - } else { - throw new YACLAutoGenException("'%s': @OverrideImage has no value or factory class.".formatted(field.access().name())); - } - } else { - String imagePath = "textures/yacl3/" + field.parent().id().getPath() + "/" + field.access().name() + ".webp"; - imagePath = imagePath.toLowerCase().replaceAll("[^a-z0-9/._:-]", "_"); - ResourceLocation imageLocation = new ResourceLocation(field.parent().id().getNamespace(), imagePath); - if (Minecraft.getInstance().getResourceManager().getResource(imageLocation).isPresent()) { - builder.webpImage(imageLocation); - } - } - - return builder; - } - - protected boolean available(A annotation, ConfigField field, OptionAccess storage) { - return true; - } - - protected Set flags(A annotation, ConfigField field, OptionAccess storage) { - return Set.of(); - } - - protected void listener(A annotation, ConfigField field, OptionAccess storage, Option option, T value) { - - } - - protected void postInit(A annotation, ConfigField field, OptionAccess storage, Option option) { - - } - - protected String getTranslationKey(ConfigField field, @Nullable String suffix) { - String key = "yacl3.config.%s.%s".formatted(field.parent().id().toString(), field.access().name()); - if (suffix != null) key += "." + suffix; - return key; - } -} diff --git a/common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/StringField.java b/common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/StringField.java deleted file mode 100644 index 50d638e..0000000 --- a/common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/StringField.java +++ /dev/null @@ -1,17 +0,0 @@ -package dev.isxander.yacl3.config.v2.api.autogen; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * A regular option factory. - *

- * This creates a regular option with a - * {@link dev.isxander.yacl3.api.controller.StringControllerBuilder} controller. - */ -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.FIELD) -public @interface StringField { -} diff --git a/common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/TickBox.java b/common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/TickBox.java deleted file mode 100644 index 0a88c14..0000000 --- a/common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/TickBox.java +++ /dev/null @@ -1,17 +0,0 @@ -package dev.isxander.yacl3.config.v2.api.autogen; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * An option factory. - *

- * This creates a regular option with a - * {@link dev.isxander.yacl3.api.controller.TickBoxControllerBuilder} controller. - */ -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.FIELD) -public @interface TickBox { -} diff --git a/common/src/main/java/dev/isxander/yacl3/config/v2/api/serializer/GsonConfigSerializerBuilder.java b/common/src/main/java/dev/isxander/yacl3/config/v2/api/serializer/GsonConfigSerializerBuilder.java deleted file mode 100644 index 33003d7..0000000 --- a/common/src/main/java/dev/isxander/yacl3/config/v2/api/serializer/GsonConfigSerializerBuilder.java +++ /dev/null @@ -1,98 +0,0 @@ -package dev.isxander.yacl3.config.v2.api.serializer; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import dev.isxander.yacl3.config.ConfigEntry; -import dev.isxander.yacl3.config.v2.api.ConfigClassHandler; -import dev.isxander.yacl3.config.v2.api.ConfigSerializer; -import dev.isxander.yacl3.config.v2.api.SerialEntry; -import dev.isxander.yacl3.config.v2.impl.serializer.GsonConfigSerializer; -import net.minecraft.network.chat.Component; -import net.minecraft.network.chat.Style; - -import java.awt.*; -import java.nio.file.Path; -import java.util.function.UnaryOperator; - -/** - * Uses GSON to serialize and deserialize config data from JSON to a file. - *

- * Only fields annotated with {@link dev.isxander.yacl3.config.v2.api.SerialEntry} are included in the JSON. - * {@link Component}, {@link Style} and {@link Color} have default type adapters, so there is no need to provide them in your GSON instance. - * GSON is automatically configured to format fields as {@code lower_camel_case}. - *

- * Optionally, this can also be written under JSON5 spec, allowing comments. - * - * @param config data type - */ -public interface GsonConfigSerializerBuilder { - static GsonConfigSerializerBuilder create(ConfigClassHandler config) { - return new GsonConfigSerializer.Builder<>(config); - } - - /** - * Sets the file path to save and load the config from. - */ - GsonConfigSerializerBuilder setPath(Path path); - - /** - * Sets the GSON instance to use. Overrides all YACL defaults such as: - *

- * Still respects the exclusion strategy to only serialize {@link ConfigEntry} - * but these can be added to with setExclusionStrategies. - * - * @param gsonBuilder gson builder to use - */ - GsonConfigSerializerBuilder overrideGsonBuilder(GsonBuilder gsonBuilder); - - /** - * Sets the GSON instance to use. Overrides all YACL defaults such as: - *
    - *
  • lower_camel_case field naming policy
  • - *
  • null serialization
  • - *
  • {@link Component}, {@link Style} and {@link Color} type adapters
  • - *
- * but these can be added to with setExclusionStrategies. - * - * @param gson gson instance to be converted to a builder - */ - GsonConfigSerializerBuilder overrideGsonBuilder(Gson gson); - - /** - * Appends extra configuration to a GSON builder. - * This is the intended way to add functionality to the GSON instance. - *

- * By default, YACL sets the GSON with the following options: - *

    - *
  • lower_camel_case field naming policy
  • - *
  • null serialization
  • - *
  • {@link Component}, {@link Style} and {@link Color} type adapters
  • - *
- * For example, if you wanted to revert YACL's lower_camel_case naming policy, - * you could do the following: - *
-     * {@code
-     * GsonConfigSerializerBuilder.create(config)
-     *         .appendGsonBuilder(builder -> builder.setFieldNamingPolicy(FieldNamingPolicy.IDENTITY))
-     * }
-     * 
- * - * @param gsonBuilder the function to apply to the builder - */ - GsonConfigSerializerBuilder appendGsonBuilder(UnaryOperator gsonBuilder); - - /** - * Writes the json under JSON5 spec, allowing the use of {@link SerialEntry#comment()}. - * If enabling this option it's recommended to use the file extension {@code .json5}. - * - * @param json5 whether to write under JSON5 spec - * @return this builder - */ - GsonConfigSerializerBuilder setJson5(boolean json5); - - ConfigSerializer build(); -} diff --git a/common/src/main/java/dev/isxander/yacl3/config/v2/impl/ConfigClassHandlerImpl.java b/common/src/main/java/dev/isxander/yacl3/config/v2/impl/ConfigClassHandlerImpl.java deleted file mode 100644 index 813b3ab..0000000 --- a/common/src/main/java/dev/isxander/yacl3/config/v2/impl/ConfigClassHandlerImpl.java +++ /dev/null @@ -1,274 +0,0 @@ -package dev.isxander.yacl3.config.v2.impl; - -import dev.isxander.yacl3.api.*; -import dev.isxander.yacl3.config.ConfigEntry; -import dev.isxander.yacl3.config.v2.api.*; -import dev.isxander.yacl3.config.v2.api.autogen.AutoGen; -import dev.isxander.yacl3.config.v2.api.autogen.OptionAccess; -import dev.isxander.yacl3.config.v2.impl.autogen.OptionFactoryRegistry; -import dev.isxander.yacl3.config.v2.impl.autogen.OptionAccessImpl; -import dev.isxander.yacl3.config.v2.impl.autogen.YACLAutoGenException; -import dev.isxander.yacl3.impl.utils.YACLConstants; -import dev.isxander.yacl3.platform.YACLPlatform; -import net.minecraft.network.chat.Component; -import net.minecraft.resources.ResourceLocation; -import org.apache.commons.lang3.Validate; - -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.util.AbstractMap; -import java.util.Arrays; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.function.Function; -import java.util.stream.Collectors; - -public class ConfigClassHandlerImpl implements ConfigClassHandler { - private final Class configClass; - private final ResourceLocation id; - private final boolean supportsAutoGen; - private final ConfigSerializer serializer; - private final ConfigFieldImpl[] fields; - - private T instance; - private final T defaults; - private final Constructor noArgsConstructor; - - public ConfigClassHandlerImpl(Class configClass, ResourceLocation id, Function, ConfigSerializer> serializerFactory) { - this.configClass = configClass; - this.id = id; - this.supportsAutoGen = id != null && YACLPlatform.getEnvironment().isClient(); - - try { - noArgsConstructor = configClass.getDeclaredConstructor(); - } catch (NoSuchMethodException e) { - throw new YACLAutoGenException("Failed to find no-args constructor for config class %s.".formatted(configClass.getName()), e); - } - this.instance = createNewObject(); - this.defaults = createNewObject(); - - detectOldAnnotation(configClass.getDeclaredFields()); - - this.fields = discoverFields(); - this.serializer = serializerFactory.apply(this); - } - - private ConfigFieldImpl[] discoverFields() { - return Arrays.stream(configClass.getDeclaredFields()) - .peek(field -> field.setAccessible(true)) - .filter(field -> field.isAnnotationPresent(SerialEntry.class) || field.isAnnotationPresent(AutoGen.class)) - .map(field -> new ConfigFieldImpl<>( - new ReflectionFieldAccess<>(field, instance), - new ReflectionFieldAccess<>(field, defaults), - this, - field.getAnnotation(SerialEntry.class), - field.getAnnotation(AutoGen.class) - )) - .toArray(ConfigFieldImpl[]::new); - } - - @Override - public T instance() { - return this.instance; - } - - @Override - public T defaults() { - return this.defaults; - } - - @Override - public Class configClass() { - return this.configClass; - } - - @Override - public ConfigFieldImpl[] fields() { - return this.fields; - } - - @Override - public ResourceLocation id() { - return this.id; - } - - @Override - public boolean supportsAutoGen() { - return this.supportsAutoGen; - } - - @Override - public YetAnotherConfigLib generateGui() { - if (!supportsAutoGen()) { - throw new YACLAutoGenException("Auto GUI generation is not supported for this config class. You either need to enable it in the builder or you are attempting to create a GUI in a dedicated server environment."); - } - - boolean hasAutoGenFields = Arrays.stream(fields()).anyMatch(field -> field.autoGen().isPresent()); - - if (!hasAutoGenFields) { - throw new YACLAutoGenException("No fields in this config class are annotated with @AutoGen. You must annotate at least one field with @AutoGen to generate a GUI."); - } - - OptionAccessImpl storage = new OptionAccessImpl(); - Map categories = new LinkedHashMap<>(); - for (ConfigField configField : fields()) { - configField.autoGen().ifPresent(autoGen -> { - CategoryAndGroups groups = categories.computeIfAbsent( - autoGen.category(), - k -> new CategoryAndGroups( - ConfigCategory.createBuilder() - .name(Component.translatable("yacl3.config.%s.category.%s".formatted(id().toString(), k))), - new LinkedHashMap<>() - ) - ); - OptionAddable group = groups.groups().computeIfAbsent(autoGen.group().orElse(""), k -> { - if (k.isEmpty()) - return groups.category(); - return OptionGroup.createBuilder() - .name(Component.translatable("yacl3.config.%s.category.%s.group.%s".formatted(id().toString(), autoGen.category(), k))); - }); - - Option option; - try { - option = createOption(configField, storage); - } catch (Exception e) { - throw new YACLAutoGenException("Failed to create option for field '%s'".formatted(configField.access().name()), e); - } - - storage.putOption(configField.access().name(), option); - group.option(option); - }); - } - storage.checkBadOperations(); - categories.values().forEach(CategoryAndGroups::finaliseGroups); - - YetAnotherConfigLib.Builder yaclBuilder = YetAnotherConfigLib.createBuilder() - .save(this.serializer()::save) - .title(Component.translatable("yacl3.config.%s.title".formatted(this.id().toString()))); - categories.values().forEach(category -> yaclBuilder.category(category.category().build())); - - return yaclBuilder.build(); - } - - private Option createOption(ConfigField configField, OptionAccess storage) { - return OptionFactoryRegistry.createOption(((ReflectionFieldAccess) configField.access()).field(), configField, storage) - .orElseThrow(() -> new YACLAutoGenException("Failed to create option for field %s".formatted(configField.access().name()))); - } - - @Override - public ConfigSerializer serializer() { - return this.serializer; - } - - @Override - public boolean load() { - // create a new instance to load into - T newInstance = createNewObject(); - - // create field accesses for the new object - Map, ReflectionFieldAccess> accessBufferImpl = Arrays.stream(fields()) - .map(field -> new AbstractMap.SimpleImmutableEntry<>( - field, - new ReflectionFieldAccess<>(field.access().field(), newInstance) - )) - .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); - // convert the map into API safe field accesses - Map, FieldAccess> accessBuffer = accessBufferImpl.entrySet().stream() - .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); - - // attempt to load the config - ConfigSerializer.LoadResult loadResult = ConfigSerializer.LoadResult.FAILURE; - Throwable error = null; - try { - loadResult = this.serializer().loadSafely(accessBuffer); - } catch (Throwable e) { - // handle any errors later in the loadResult switch case - error = e; - } - - switch (loadResult) { - case DIRTY: - case SUCCESS: - // replace the instance with the newly created one - this.instance = newInstance; - for (ConfigFieldImpl field : fields()) { - // update the field accesses to point to the correct object - ((ConfigFieldImpl) field).setFieldAccess((ReflectionFieldAccess) accessBufferImpl.get(field)); - } - - if (loadResult == ConfigSerializer.LoadResult.DIRTY) { - // if the load result is dirty, we need to save the config again - this.save(); - } - case NO_CHANGE: - return true; - case FAILURE: - YACLConstants.LOGGER.error( - "Unsuccessful load of config class '{}'. The load will be abandoned and config remains unchanged.", - configClass.getSimpleName(), error - ); - } - - return false; - } - - @Override - public void save() { - serializer().save(); - } - - private T createNewObject() { - try { - return noArgsConstructor.newInstance(); - } catch (Exception e) { - throw new YACLAutoGenException("Failed to create instance of config class '%s' with no-args constructor.".formatted(configClass.getName()), e); - } - } - - private void detectOldAnnotation(Field[] fields) { - boolean hasOldConfigEntry = Arrays.stream(fields) - .anyMatch(field -> field.isAnnotationPresent(ConfigEntry.class)); - - Validate.isTrue(!hasOldConfigEntry, "At least one field in %s is still annotated with the deprecated @ConfigEntry annotation. This is incorrect. Use @SerialEntry.".formatted(configClass.getName())); - } - - public static class BuilderImpl implements Builder { - private final Class configClass; - private ResourceLocation id; - private Function, ConfigSerializer> serializerFactory; - - public BuilderImpl(Class configClass) { - this.configClass = configClass; - } - - @Override - public Builder id(ResourceLocation id) { - this.id = id; - return this; - } - - @Override - public Builder serializer(Function, ConfigSerializer> serializerFactory) { - this.serializerFactory = serializerFactory; - return this; - } - - @Override - public ConfigClassHandler build() { - Validate.notNull(serializerFactory, "serializerFactory must not be null"); - Validate.notNull(configClass, "configClass must not be null"); - - return new ConfigClassHandlerImpl<>(configClass, id, serializerFactory); - } - } - - private record CategoryAndGroups(ConfigCategory.Builder category, Map groups) { - private void finaliseGroups() { - groups.forEach((name, group) -> { - if (group instanceof OptionGroup.Builder groupBuilder) { - category.group(groupBuilder.build()); - } - }); - } - } -} diff --git a/common/src/main/java/dev/isxander/yacl3/config/v2/impl/ConfigFieldImpl.java b/common/src/main/java/dev/isxander/yacl3/config/v2/impl/ConfigFieldImpl.java deleted file mode 100644 index aeed5ac..0000000 --- a/common/src/main/java/dev/isxander/yacl3/config/v2/impl/ConfigFieldImpl.java +++ /dev/null @@ -1,75 +0,0 @@ -package dev.isxander.yacl3.config.v2.impl; - -import dev.isxander.yacl3.config.v2.api.*; -import dev.isxander.yacl3.config.v2.api.autogen.AutoGen; -import dev.isxander.yacl3.config.v2.api.autogen.AutoGenField; -import org.jetbrains.annotations.Nullable; - -import java.util.Optional; - -public class ConfigFieldImpl implements ConfigField { - private ReflectionFieldAccess field; - private final ReflectionFieldAccess defaultField; - private final ConfigClassHandler parent; - private final Optional serial; - private final Optional autoGen; - - public ConfigFieldImpl(ReflectionFieldAccess field, ReflectionFieldAccess defaultField, ConfigClassHandler parent, @Nullable SerialEntry config, @Nullable AutoGen autoGen) { - this.field = field; - this.defaultField = defaultField; - this.parent = parent; - - this.serial = config != null - ? Optional.of( - new SerialFieldImpl( - "".equals(config.value()) ? field.name() : config.value(), - "".equals(config.comment()) ? Optional.empty() : Optional.of(config.comment()), - config.required(), - config.nullable() - ) - ) - : Optional.empty(); - this.autoGen = autoGen != null - ? Optional.of( - new AutoGenFieldImpl<>( - autoGen.category(), - "".equals(autoGen.group()) ? Optional.empty() : Optional.of(autoGen.group()) - ) - ) - : Optional.empty(); - } - - @Override - public ReflectionFieldAccess access() { - return field; - } - - public void setFieldAccess(ReflectionFieldAccess field) { - this.field = field; - } - - @Override - public ReflectionFieldAccess defaultAccess() { - return defaultField; - } - - @Override - public ConfigClassHandler parent() { - return parent; - } - - @Override - public Optional serial() { - return this.serial; - } - - @Override - public Optional autoGen() { - return this.autoGen; - } - - private record SerialFieldImpl(String serialName, Optional comment, boolean required, boolean nullable) implements SerialField { - } - private record AutoGenFieldImpl(String category, Optional group) implements AutoGenField { - } -} diff --git a/common/src/main/java/dev/isxander/yacl3/config/v2/impl/FieldBackedBinding.java b/common/src/main/java/dev/isxander/yacl3/config/v2/impl/FieldBackedBinding.java deleted file mode 100644 index f2f36e7..0000000 --- a/common/src/main/java/dev/isxander/yacl3/config/v2/impl/FieldBackedBinding.java +++ /dev/null @@ -1,22 +0,0 @@ -package dev.isxander.yacl3.config.v2.impl; - -import dev.isxander.yacl3.api.Binding; -import dev.isxander.yacl3.config.v2.api.FieldAccess; -import dev.isxander.yacl3.config.v2.api.ReadOnlyFieldAccess; - -public record FieldBackedBinding(FieldAccess field, ReadOnlyFieldAccess defaultField) implements Binding { - @Override - public T getValue() { - return field.get(); - } - - @Override - public void setValue(T value) { - field.set(value); - } - - @Override - public T defaultValue() { - return defaultField.get(); - } -} diff --git a/common/src/main/java/dev/isxander/yacl3/config/v2/impl/ReflectionFieldAccess.java b/common/src/main/java/dev/isxander/yacl3/config/v2/impl/ReflectionFieldAccess.java deleted file mode 100644 index e102344..0000000 --- a/common/src/main/java/dev/isxander/yacl3/config/v2/impl/ReflectionFieldAccess.java +++ /dev/null @@ -1,49 +0,0 @@ -package dev.isxander.yacl3.config.v2.impl; - -import dev.isxander.yacl3.config.v2.api.FieldAccess; -import dev.isxander.yacl3.config.v2.impl.autogen.YACLAutoGenException; - -import java.lang.annotation.Annotation; -import java.lang.reflect.Field; -import java.lang.reflect.Type; -import java.util.Optional; - -public record ReflectionFieldAccess(Field field, Object instance) implements FieldAccess { - @Override - public T get() { - try { - return (T) field.get(instance); - } catch (IllegalAccessException e) { - throw new YACLAutoGenException("Failed to access field '%s'".formatted(name()), e); - } - } - - @Override - public void set(T value) { - try { - field.set(instance, value); - } catch (IllegalAccessException e) { - throw new YACLAutoGenException("Failed to set field '%s'".formatted(name()), e); - } - } - - @Override - public String name() { - return field.getName(); - } - - @Override - public Type type() { - return field.getGenericType(); - } - - @Override - public Class typeClass() { - return (Class) field.getType(); - } - - @Override - public Optional getAnnotation(Class annotationClass) { - return Optional.ofNullable(field.getAnnotation(annotationClass)); - } -} diff --git a/common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/AutoGenUtils.java b/common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/AutoGenUtils.java deleted file mode 100644 index 6f614c1..0000000 --- a/common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/AutoGenUtils.java +++ /dev/null @@ -1,54 +0,0 @@ -package dev.isxander.yacl3.config.v2.impl.autogen; - -import dev.isxander.yacl3.api.controller.ControllerBuilder; -import dev.isxander.yacl3.api.controller.ValueFormattableController; -import dev.isxander.yacl3.api.controller.ValueFormatter; -import dev.isxander.yacl3.config.v2.api.ReadOnlyFieldAccess; -import dev.isxander.yacl3.config.v2.api.autogen.CustomFormat; -import dev.isxander.yacl3.config.v2.api.autogen.FormatTranslation; -import net.minecraft.network.chat.Component; -import org.jetbrains.annotations.ApiStatus; - -import java.util.Optional; -import java.util.function.Supplier; - -@ApiStatus.Internal -public final class AutoGenUtils { - public static void addCustomFormatterToController(ControllerBuilder controller, ReadOnlyFieldAccess field) { - Optional formatter = field.getAnnotation(CustomFormat.class); - Optional translation = field.getAnnotation(FormatTranslation.class); - - if (formatter.isPresent() && translation.isPresent()) { - throw new YACLAutoGenException("'%s': Cannot use both @CustomFormatter and @FormatTranslation on the same field.".formatted(field.name())); - } else if (formatter.isEmpty() && translation.isEmpty()) { - return; - } - - if (!(controller instanceof ValueFormattableController)) { - throw new YACLAutoGenException("Attempted to use @CustomFormatter or @FormatTranslation on an option factory for field '%s' that uses a controller that does not support this.".formatted(field.name())); - } - - ValueFormattableController typedBuilder = (ValueFormattableController) controller; - - formatter.ifPresent(formatterClass -> { - try { - typedBuilder.formatValue((ValueFormatter) formatterClass.value().getConstructor().newInstance()); - } catch (Exception e) { - throw new YACLAutoGenException("'%s': Failed to instantiate formatter class %s.".formatted(field.name(), formatterClass.value().getName()), e); - } - }); - - translation.ifPresent(annotation -> - typedBuilder.formatValue(v -> Component.translatable(annotation.value(), v))); - } - - public static T constructNoArgsClass(Class clazz, Supplier constructorNotFoundConsumer, Supplier constructorFailedConsumer) { - try { - return clazz.getConstructor().newInstance(); - } catch (NoSuchMethodException e) { - throw new YACLAutoGenException(constructorNotFoundConsumer.get(), e); - } catch (Exception e) { - throw new YACLAutoGenException(constructorFailedConsumer.get(), e); - } - } -} diff --git a/common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/BooleanImpl.java b/common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/BooleanImpl.java deleted file mode 100644 index b41836a..0000000 --- a/common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/BooleanImpl.java +++ /dev/null @@ -1,25 +0,0 @@ -package dev.isxander.yacl3.config.v2.impl.autogen; - -import dev.isxander.yacl3.api.Option; -import dev.isxander.yacl3.api.controller.BooleanControllerBuilder; -import dev.isxander.yacl3.api.controller.ControllerBuilder; -import dev.isxander.yacl3.config.v2.api.ConfigField; -import dev.isxander.yacl3.config.v2.api.autogen.SimpleOptionFactory; -import dev.isxander.yacl3.config.v2.api.autogen.Boolean; -import dev.isxander.yacl3.config.v2.api.autogen.OptionAccess; -import net.minecraft.network.chat.Component; - -public class BooleanImpl extends SimpleOptionFactory { - @Override - protected ControllerBuilder createController(Boolean annotation, ConfigField field, OptionAccess storage, Option option) { - var builder = BooleanControllerBuilder.create(option) - .coloured(annotation.colored()); - switch (annotation.formatter()) { - case ON_OFF -> builder.onOffFormatter(); - case YES_NO -> builder.yesNoFormatter(); - case TRUE_FALSE -> builder.trueFalseFormatter(); - case CUSTOM -> builder.formatValue(v -> Component.translatable(getTranslationKey(field, "fmt." + v))); - } - return builder; - } -} diff --git a/common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/ColorFieldImpl.java b/common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/ColorFieldImpl.java deleted file mode 100644 index 7910c59..0000000 --- a/common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/ColorFieldImpl.java +++ /dev/null @@ -1,19 +0,0 @@ -package dev.isxander.yacl3.config.v2.impl.autogen; - -import dev.isxander.yacl3.api.Option; -import dev.isxander.yacl3.api.controller.ColorControllerBuilder; -import dev.isxander.yacl3.api.controller.ControllerBuilder; -import dev.isxander.yacl3.config.v2.api.ConfigField; -import dev.isxander.yacl3.config.v2.api.autogen.SimpleOptionFactory; -import dev.isxander.yacl3.config.v2.api.autogen.ColorField; -import dev.isxander.yacl3.config.v2.api.autogen.OptionAccess; - -import java.awt.Color; - -public class ColorFieldImpl extends SimpleOptionFactory { - @Override - protected ControllerBuilder createController(ColorField annotation, ConfigField field, OptionAccess storage, Option option) { - return ColorControllerBuilder.create(option) - .allowAlpha(annotation.allowAlpha()); - } -} diff --git a/common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/DoubleFieldImpl.java b/common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/DoubleFieldImpl.java deleted file mode 100644 index 6445141..0000000 --- a/common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/DoubleFieldImpl.java +++ /dev/null @@ -1,32 +0,0 @@ -package dev.isxander.yacl3.config.v2.impl.autogen; - -import dev.isxander.yacl3.api.Option; -import dev.isxander.yacl3.api.controller.ControllerBuilder; -import dev.isxander.yacl3.api.controller.DoubleFieldControllerBuilder; -import dev.isxander.yacl3.config.v2.api.ConfigField; -import dev.isxander.yacl3.config.v2.api.autogen.DoubleField; -import dev.isxander.yacl3.config.v2.api.autogen.OptionAccess; -import dev.isxander.yacl3.config.v2.api.autogen.SimpleOptionFactory; -import net.minecraft.locale.Language; -import net.minecraft.network.chat.Component; - -public class DoubleFieldImpl extends SimpleOptionFactory { - @Override - protected ControllerBuilder createController(DoubleField annotation, ConfigField field, OptionAccess storage, Option option) { - return DoubleFieldControllerBuilder.create(option) - .formatValue(v -> { - String key = null; - if (v == annotation.min()) - key = getTranslationKey(field, "fmt.min"); - else if (v == annotation.max()) - key = getTranslationKey(field, "fmt.max"); - if (key != null && Language.getInstance().has(key)) - return Component.translatable(key); - key = getTranslationKey(field, "fmt"); - if (Language.getInstance().has(key)) - return Component.translatable(key, v); - return Component.translatable(String.format(annotation.format(), v)); - }) - .range(annotation.min(), annotation.max()); - } -} diff --git a/common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/DoubleSliderImpl.java b/common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/DoubleSliderImpl.java deleted file mode 100644 index e6dd05d..0000000 --- a/common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/DoubleSliderImpl.java +++ /dev/null @@ -1,33 +0,0 @@ -package dev.isxander.yacl3.config.v2.impl.autogen; - -import dev.isxander.yacl3.api.Option; -import dev.isxander.yacl3.api.controller.ControllerBuilder; -import dev.isxander.yacl3.api.controller.DoubleSliderControllerBuilder; -import dev.isxander.yacl3.config.v2.api.ConfigField; -import dev.isxander.yacl3.config.v2.api.autogen.SimpleOptionFactory; -import dev.isxander.yacl3.config.v2.api.autogen.DoubleSlider; -import dev.isxander.yacl3.config.v2.api.autogen.OptionAccess; -import net.minecraft.locale.Language; -import net.minecraft.network.chat.Component; - -public class DoubleSliderImpl extends SimpleOptionFactory { - @Override - protected ControllerBuilder createController(DoubleSlider annotation, ConfigField field, OptionAccess storage, Option option) { - return DoubleSliderControllerBuilder.create(option) - .formatValue(v -> { - String key = null; - if (v == annotation.min()) - key = getTranslationKey(field, "fmt.min"); - else if (v == annotation.max()) - key = getTranslationKey(field, "fmt.max"); - if (key != null && Language.getInstance().has(key)) - return Component.translatable(key); - key = getTranslationKey(field, "fmt"); - if (Language.getInstance().has(key)) - return Component.translatable(key, v); - return Component.translatable(String.format(annotation.format(), v)); - }) - .range(annotation.min(), annotation.max()) - .step(annotation.step()); - } -} diff --git a/common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/DropdownImpl.java b/common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/DropdownImpl.java deleted file mode 100644 index c487aab..0000000 --- a/common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/DropdownImpl.java +++ /dev/null @@ -1,19 +0,0 @@ -package dev.isxander.yacl3.config.v2.impl.autogen; - -import dev.isxander.yacl3.api.Option; -import dev.isxander.yacl3.api.controller.ControllerBuilder; -import dev.isxander.yacl3.api.controller.DropdownStringControllerBuilder; -import dev.isxander.yacl3.config.v2.api.ConfigField; -import dev.isxander.yacl3.config.v2.api.autogen.Dropdown; -import dev.isxander.yacl3.config.v2.api.autogen.OptionAccess; -import dev.isxander.yacl3.config.v2.api.autogen.SimpleOptionFactory; - -public class DropdownImpl extends SimpleOptionFactory { - @Override - protected ControllerBuilder createController(Dropdown annotation, ConfigField field, OptionAccess storage, Option option) { - return DropdownStringControllerBuilder.create(option) - .values(annotation.values()) - .allowEmptyValue(annotation.allowEmptyValue()) - .allowAnyValue(annotation.allowAnyValue()); - } -} diff --git a/common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/EmptyCustomImageFactory.java b/common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/EmptyCustomImageFactory.java deleted file mode 100644 index 1500864..0000000 --- a/common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/EmptyCustomImageFactory.java +++ /dev/null @@ -1,17 +0,0 @@ -package dev.isxander.yacl3.config.v2.impl.autogen; - -import dev.isxander.yacl3.config.v2.api.ConfigField; -import dev.isxander.yacl3.config.v2.api.autogen.OptionAccess; -import dev.isxander.yacl3.config.v2.api.autogen.CustomImage; -import dev.isxander.yacl3.gui.image.ImageRenderer; - -import java.util.Optional; -import java.util.concurrent.CompletableFuture; - -public class EmptyCustomImageFactory implements CustomImage.CustomImageFactory { - - @Override - public CompletableFuture createImage(Object value, ConfigField field, OptionAccess access) { - throw new IllegalStateException(); - } -} diff --git a/common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/EnumCyclerImpl.java b/common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/EnumCyclerImpl.java deleted file mode 100644 index f15d862..0000000 --- a/common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/EnumCyclerImpl.java +++ /dev/null @@ -1,42 +0,0 @@ -package dev.isxander.yacl3.config.v2.impl.autogen; - -import dev.isxander.yacl3.api.NameableEnum; -import dev.isxander.yacl3.api.Option; -import dev.isxander.yacl3.api.controller.ControllerBuilder; -import dev.isxander.yacl3.api.controller.CyclingListControllerBuilder; -import dev.isxander.yacl3.config.v2.api.ConfigField; -import dev.isxander.yacl3.config.v2.api.autogen.SimpleOptionFactory; -import dev.isxander.yacl3.config.v2.api.autogen.EnumCycler; -import dev.isxander.yacl3.config.v2.api.autogen.OptionAccess; -import net.minecraft.network.chat.Component; - -import java.util.Arrays; -import java.util.List; -import java.util.stream.IntStream; - -public class EnumCyclerImpl extends SimpleOptionFactory> { - @Override - protected ControllerBuilder> createController(EnumCycler annotation, ConfigField> field, OptionAccess storage, Option> option) { - List> values; - - if (option.pendingValue() instanceof EnumCycler.CyclableEnum cyclableEnum) { - values = Arrays.asList(cyclableEnum.allowedValues()); - } else { - Enum[] constants = field.access().typeClass().getEnumConstants(); - values = IntStream.range(0, constants.length) - .filter(ordinal -> annotation.allowedOrdinals().length == 0 || Arrays.stream(annotation.allowedOrdinals()).noneMatch(allowed -> allowed == ordinal)) - .mapToObj(ordinal -> constants[ordinal]) - .toList(); - } - - // EnumController doesn't support filtering - var builder = CyclingListControllerBuilder.create(option) - .values(values); - if (NameableEnum.class.isAssignableFrom(field.access().typeClass())) { - builder.formatValue(v -> ((NameableEnum) v).getDisplayName()); - } else { - builder.formatValue(v -> Component.translatable("yacl3.config.enum.%s.%s".formatted(field.access().typeClass().getSimpleName(), v.name().toLowerCase()))); - } - return builder; - } -} diff --git a/common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/FloatFieldImpl.java b/common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/FloatFieldImpl.java deleted file mode 100644 index acdabd6..0000000 --- a/common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/FloatFieldImpl.java +++ /dev/null @@ -1,32 +0,0 @@ -package dev.isxander.yacl3.config.v2.impl.autogen; - -import dev.isxander.yacl3.api.Option; -import dev.isxander.yacl3.api.controller.ControllerBuilder; -import dev.isxander.yacl3.api.controller.FloatFieldControllerBuilder; -import dev.isxander.yacl3.config.v2.api.ConfigField; -import dev.isxander.yacl3.config.v2.api.autogen.FloatField; -import dev.isxander.yacl3.config.v2.api.autogen.OptionAccess; -import dev.isxander.yacl3.config.v2.api.autogen.SimpleOptionFactory; -import net.minecraft.locale.Language; -import net.minecraft.network.chat.Component; - -public class FloatFieldImpl extends SimpleOptionFactory { - @Override - protected ControllerBuilder createController(FloatField annotation, ConfigField field, OptionAccess storage, Option option) { - return FloatFieldControllerBuilder.create(option) - .formatValue(v -> { - String key = null; - if (v == annotation.min()) - key = getTranslationKey(field, "fmt.min"); - else if (v == annotation.max()) - key = getTranslationKey(field, "fmt.max"); - if (key != null && Language.getInstance().has(key)) - return Component.translatable(key); - key = getTranslationKey(field, "fmt"); - if (Language.getInstance().has(key)) - return Component.translatable(key, v); - return Component.translatable(String.format(annotation.format(), v)); - }) - .range(annotation.min(), annotation.max()); - } -} diff --git a/common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/FloatSliderImpl.java b/common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/FloatSliderImpl.java deleted file mode 100644 index f22302f..0000000 --- a/common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/FloatSliderImpl.java +++ /dev/null @@ -1,33 +0,0 @@ -package dev.isxander.yacl3.config.v2.impl.autogen; - -import dev.isxander.yacl3.api.Option; -import dev.isxander.yacl3.api.controller.ControllerBuilder; -import dev.isxander.yacl3.api.controller.FloatSliderControllerBuilder; -import dev.isxander.yacl3.config.v2.api.ConfigField; -import dev.isxander.yacl3.config.v2.api.autogen.SimpleOptionFactory; -import dev.isxander.yacl3.config.v2.api.autogen.FloatSlider; -import dev.isxander.yacl3.config.v2.api.autogen.OptionAccess; -import net.minecraft.locale.Language; -import net.minecraft.network.chat.Component; - -public class FloatSliderImpl extends SimpleOptionFactory { - @Override - protected ControllerBuilder createController(FloatSlider annotation, ConfigField field, OptionAccess storage, Option option) { - return FloatSliderControllerBuilder.create(option) - .formatValue(v -> { - String key = null; - if (v == annotation.min()) - key = getTranslationKey(field, "fmt.min"); - else if (v == annotation.max()) - key = getTranslationKey(field, "fmt.max"); - if (key != null && Language.getInstance().has(key)) - return Component.translatable(key); - key = getTranslationKey(field, "fmt"); - if (Language.getInstance().has(key)) - return Component.translatable(key, v); - return Component.translatable(String.format(annotation.format(), v)); - }) - .range(annotation.min(), annotation.max()) - .step(annotation.step()); - } -} diff --git a/common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/IntFieldImpl.java b/common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/IntFieldImpl.java deleted file mode 100644 index a3b759a..0000000 --- a/common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/IntFieldImpl.java +++ /dev/null @@ -1,28 +0,0 @@ -package dev.isxander.yacl3.config.v2.impl.autogen; - -import dev.isxander.yacl3.api.Option; -import dev.isxander.yacl3.api.controller.ControllerBuilder; -import dev.isxander.yacl3.api.controller.IntegerFieldControllerBuilder; -import dev.isxander.yacl3.config.v2.api.ConfigField; -import dev.isxander.yacl3.config.v2.api.autogen.IntField; -import dev.isxander.yacl3.config.v2.api.autogen.OptionAccess; -import dev.isxander.yacl3.config.v2.api.autogen.SimpleOptionFactory; -import net.minecraft.locale.Language; -import net.minecraft.network.chat.Component; - -public class IntFieldImpl extends SimpleOptionFactory { - @Override - protected ControllerBuilder createController(IntField annotation, ConfigField field, OptionAccess storage, Option option) { - return IntegerFieldControllerBuilder.create(option) - .formatValue(v -> { - String key = getTranslationKey(field, "fmt." + v); - if (Language.getInstance().has(key)) - return Component.translatable(key); - key = getTranslationKey(field, "fmt"); - if (Language.getInstance().has(key)) - return Component.translatable(key, v); - return Component.literal(Integer.toString(v)); - }) - .range(annotation.min(), annotation.max()); - } -} diff --git a/common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/IntSliderImpl.java b/common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/IntSliderImpl.java deleted file mode 100644 index b570b44..0000000 --- a/common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/IntSliderImpl.java +++ /dev/null @@ -1,29 +0,0 @@ -package dev.isxander.yacl3.config.v2.impl.autogen; - -import dev.isxander.yacl3.api.Option; -import dev.isxander.yacl3.api.controller.ControllerBuilder; -import dev.isxander.yacl3.api.controller.IntegerSliderControllerBuilder; -import dev.isxander.yacl3.config.v2.api.ConfigField; -import dev.isxander.yacl3.config.v2.api.autogen.SimpleOptionFactory; -import dev.isxander.yacl3.config.v2.api.autogen.IntSlider; -import dev.isxander.yacl3.config.v2.api.autogen.OptionAccess; -import net.minecraft.locale.Language; -import net.minecraft.network.chat.Component; - -public class IntSliderImpl extends SimpleOptionFactory { - @Override - protected ControllerBuilder createController(IntSlider annotation, ConfigField field, OptionAccess storage, Option option) { - return IntegerSliderControllerBuilder.create(option) - .formatValue(v -> { - String key = getTranslationKey(field, "fmt." + v); - if (Language.getInstance().has(key)) - return Component.translatable(key); - key = getTranslationKey(field, "fmt"); - if (Language.getInstance().has(key)) - return Component.translatable(key, v); - return Component.literal(Integer.toString(v)); - }) - .range(annotation.min(), annotation.max()) - .step(annotation.step()); - } -} diff --git a/common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/ItemFieldImpl.java b/common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/ItemFieldImpl.java deleted file mode 100644 index 2802f5c..0000000 --- a/common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/ItemFieldImpl.java +++ /dev/null @@ -1,17 +0,0 @@ -package dev.isxander.yacl3.config.v2.impl.autogen; - -import dev.isxander.yacl3.api.Option; -import dev.isxander.yacl3.api.controller.ControllerBuilder; -import dev.isxander.yacl3.api.controller.ItemControllerBuilder; -import dev.isxander.yacl3.config.v2.api.ConfigField; -import dev.isxander.yacl3.config.v2.api.autogen.ItemField; -import dev.isxander.yacl3.config.v2.api.autogen.OptionAccess; -import dev.isxander.yacl3.config.v2.api.autogen.SimpleOptionFactory; -import net.minecraft.world.item.Item; - -public class ItemFieldImpl extends SimpleOptionFactory { - @Override - protected ControllerBuilder createController(ItemField annotation, ConfigField field, OptionAccess storage, Option option) { - return ItemControllerBuilder.create(option); - } -} diff --git a/common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/LabelImpl.java b/common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/LabelImpl.java deleted file mode 100644 index 6f9b368..0000000 --- a/common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/LabelImpl.java +++ /dev/null @@ -1,16 +0,0 @@ -package dev.isxander.yacl3.config.v2.impl.autogen; - -import dev.isxander.yacl3.api.LabelOption; -import dev.isxander.yacl3.api.Option; -import dev.isxander.yacl3.config.v2.api.ConfigField; -import dev.isxander.yacl3.config.v2.api.autogen.OptionFactory; -import dev.isxander.yacl3.config.v2.api.autogen.Label; -import dev.isxander.yacl3.config.v2.api.autogen.OptionAccess; -import net.minecraft.network.chat.Component; - -public class LabelImpl implements OptionFactory { - @Override - public Option createOption(Label annotation, ConfigField field, OptionAccess optionAccess) { - return LabelOption.create(field.access().get()); - } -} diff --git a/common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/ListGroupImpl.java b/common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/ListGroupImpl.java deleted file mode 100644 index f78d4ba..0000000 --- a/common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/ListGroupImpl.java +++ /dev/null @@ -1,102 +0,0 @@ -package dev.isxander.yacl3.config.v2.impl.autogen; - -import dev.isxander.yacl3.api.ListOption; -import dev.isxander.yacl3.api.Option; -import dev.isxander.yacl3.api.OptionDescription; -import dev.isxander.yacl3.config.v2.api.ConfigField; -import dev.isxander.yacl3.config.v2.api.autogen.ListGroup; -import dev.isxander.yacl3.config.v2.api.autogen.OptionFactory; -import dev.isxander.yacl3.config.v2.api.autogen.OptionAccess; -import dev.isxander.yacl3.config.v2.impl.FieldBackedBinding; -import net.minecraft.client.Minecraft; -import net.minecraft.locale.Language; -import net.minecraft.network.chat.Component; -import net.minecraft.resources.ResourceLocation; -import org.jetbrains.annotations.Nullable; - -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; -import java.util.List; - -public class ListGroupImpl implements OptionFactory> { - @Override - public Option> createOption(ListGroup annotation, ConfigField> field, OptionAccess optionAccess) { - if (field.autoGen().orElseThrow().group().isPresent()) { - throw new YACLAutoGenException("@ListGroup fields ('%s') cannot be inside a group as lists act as groups.".formatted(field.access().name())); - } - - ListGroup.ValueFactory valueFactory = createValueFactory((Class>) annotation.valueFactory()); - ListGroup.ControllerFactory controllerFactory = createControllerFactory((Class>) annotation.controllerFactory()); - - return ListOption.createBuilder() - .name(Component.translatable(this.getTranslationKey(field, null))) - .description(this.description(field)) - .initial(valueFactory::provideNewValue) - .controller(opt -> controllerFactory.createController(annotation, field, optionAccess, opt)) - .binding(new FieldBackedBinding<>(field.access(), field.defaultAccess())) - .minimumNumberOfEntries(annotation.minEntries()) - .maximumNumberOfEntries(annotation.maxEntries() == 0 ? Integer.MAX_VALUE : annotation.maxEntries()) - .insertEntriesAtEnd(annotation.addEntriesToBottom()) - .build(); - } - - private OptionDescription description(ConfigField> field) { - OptionDescription.Builder builder = OptionDescription.createBuilder(); - - String key = this.getTranslationKey(field, "desc"); - if (Language.getInstance().has(key)) { - builder.text(Component.translatable(key)); - } else { - key += "."; - int i = 0; - while (Language.getInstance().has(key + i++)) { - builder.text(Component.translatable(key + i)); - } - } - - String imagePath = "textures/yacl3/" + field.parent().id().getPath() + "/" + field.access().name() + ".webp"; - imagePath = imagePath.toLowerCase().replaceAll("[^a-z0-9/._:-]", "_"); - ResourceLocation imageLocation = new ResourceLocation(field.parent().id().getNamespace(), imagePath); - if (Minecraft.getInstance().getResourceManager().getResource(imageLocation).isPresent()) { - builder.webpImage(imageLocation); - } - - return builder.build(); - } - - private ListGroup.ValueFactory createValueFactory(Class> clazz) { - Constructor> constructor; - try { - constructor = clazz.getConstructor(); - } catch (NoSuchMethodException e) { - throw new YACLAutoGenException("Could not find no-args constructor for `valueFactory` on '%s' for @ListGroup field.".formatted(clazz.getName()), e); - } - - try { - return constructor.newInstance(); - } catch (InvocationTargetException | InstantiationException | IllegalAccessException e) { - throw new YACLAutoGenException("Couldn't invoke no-args constructor for `valueFactory` on '%s' for @ListGroup field.".formatted(clazz.getName()), e); - } - } - - private ListGroup.ControllerFactory createControllerFactory(Class> clazz) { - Constructor> constructor; - try { - constructor = clazz.getConstructor(); - } catch (NoSuchMethodException e) { - throw new YACLAutoGenException("Could not find no-args constructor on `controllerFactory`, '%s' for @ListGroup field.".formatted(clazz.getName()), e); - } - - try { - return constructor.newInstance(); - } catch (InvocationTargetException | InstantiationException | IllegalAccessException e) { - throw new YACLAutoGenException("Couldn't invoke no-args constructor on `controllerFactory`, '%s' for @ListGroup field.".formatted(clazz.getName()), e); - } - } - - private String getTranslationKey(ConfigField> field, @Nullable String suffix) { - String key = "yacl3.config.%s.%s".formatted(field.parent().id().toString(), field.access().name()); - if (suffix != null) key += "." + suffix; - return key; - } -} diff --git a/common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/LongFieldImpl.java b/common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/LongFieldImpl.java deleted file mode 100644 index 5da7d20..0000000 --- a/common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/LongFieldImpl.java +++ /dev/null @@ -1,28 +0,0 @@ -package dev.isxander.yacl3.config.v2.impl.autogen; - -import dev.isxander.yacl3.api.Option; -import dev.isxander.yacl3.api.controller.ControllerBuilder; -import dev.isxander.yacl3.api.controller.LongFieldControllerBuilder; -import dev.isxander.yacl3.config.v2.api.ConfigField; -import dev.isxander.yacl3.config.v2.api.autogen.LongField; -import dev.isxander.yacl3.config.v2.api.autogen.OptionAccess; -import dev.isxander.yacl3.config.v2.api.autogen.SimpleOptionFactory; -import net.minecraft.locale.Language; -import net.minecraft.network.chat.Component; - -public class LongFieldImpl extends SimpleOptionFactory { - @Override - protected ControllerBuilder createController(LongField annotation, ConfigField field, OptionAccess storage, Option option) { - return LongFieldControllerBuilder.create(option) - .formatValue(v -> { - String key = getTranslationKey(field, "fmt." + v); - if (Language.getInstance().has(key)) - return Component.translatable(key); - key = getTranslationKey(field, "fmt"); - if (Language.getInstance().has(key)) - return Component.translatable(key, v); - return Component.literal(Long.toString(v)); - }) - .range(annotation.min(), annotation.max()); - } -} diff --git a/common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/LongSliderImpl.java b/common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/LongSliderImpl.java deleted file mode 100644 index 95c5254..0000000 --- a/common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/LongSliderImpl.java +++ /dev/null @@ -1,29 +0,0 @@ -package dev.isxander.yacl3.config.v2.impl.autogen; - -import dev.isxander.yacl3.api.Option; -import dev.isxander.yacl3.api.controller.ControllerBuilder; -import dev.isxander.yacl3.api.controller.LongSliderControllerBuilder; -import dev.isxander.yacl3.config.v2.api.ConfigField; -import dev.isxander.yacl3.config.v2.api.autogen.LongSlider; -import dev.isxander.yacl3.config.v2.api.autogen.OptionAccess; -import dev.isxander.yacl3.config.v2.api.autogen.SimpleOptionFactory; -import net.minecraft.locale.Language; -import net.minecraft.network.chat.Component; - -public class LongSliderImpl extends SimpleOptionFactory { - @Override - protected ControllerBuilder createController(LongSlider annotation, ConfigField field, OptionAccess storage, Option option) { - return LongSliderControllerBuilder.create(option) - .formatValue(v -> { - String key = getTranslationKey(field, "fmt." + v); - if (Language.getInstance().has(key)) - return Component.translatable(key); - key = getTranslationKey(field, "fmt"); - if (Language.getInstance().has(key)) - return Component.translatable(key, v); - return Component.literal(Long.toString(v)); - }) - .range(annotation.min(), annotation.max()) - .step(annotation.step()); - } -} diff --git a/common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/MasterTickBoxImpl.java b/common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/MasterTickBoxImpl.java deleted file mode 100644 index 2d37f03..0000000 --- a/common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/MasterTickBoxImpl.java +++ /dev/null @@ -1,25 +0,0 @@ -package dev.isxander.yacl3.config.v2.impl.autogen; - -import dev.isxander.yacl3.api.Option; -import dev.isxander.yacl3.api.controller.ControllerBuilder; -import dev.isxander.yacl3.api.controller.TickBoxControllerBuilder; -import dev.isxander.yacl3.config.v2.api.ConfigField; -import dev.isxander.yacl3.config.v2.api.autogen.SimpleOptionFactory; -import dev.isxander.yacl3.config.v2.api.autogen.MasterTickBox; -import dev.isxander.yacl3.config.v2.api.autogen.OptionAccess; - -public class MasterTickBoxImpl extends SimpleOptionFactory { - @Override - protected ControllerBuilder createController(MasterTickBox annotation, ConfigField field, OptionAccess storage, Option option) { - return TickBoxControllerBuilder.create(option); - } - - @Override - protected void listener(MasterTickBox annotation, ConfigField field, OptionAccess storage, Option option, Boolean value) { - for (String child : annotation.value()) { - storage.scheduleOptionOperation(child, childOpt -> { - childOpt.setAvailable(annotation.invert() != value); - }); - } - } -} diff --git a/common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/OptionAccessImpl.java b/common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/OptionAccessImpl.java deleted file mode 100644 index 579f776..0000000 --- a/common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/OptionAccessImpl.java +++ /dev/null @@ -1,44 +0,0 @@ -package dev.isxander.yacl3.config.v2.impl.autogen; - -import dev.isxander.yacl3.api.Option; -import dev.isxander.yacl3.config.v2.api.autogen.OptionAccess; -import dev.isxander.yacl3.impl.utils.YACLConstants; -import org.jetbrains.annotations.Nullable; - -import java.util.HashMap; -import java.util.Map; -import java.util.function.Consumer; - -public class OptionAccessImpl implements OptionAccess { - private final Map> storage = new HashMap<>(); - private final Map>> scheduledOperations = new HashMap<>(); - - @Override - public @Nullable Option getOption(String fieldName) { - return storage.get(fieldName); - } - - @Override - public void scheduleOptionOperation(String fieldName, Consumer> optionConsumer) { - if (storage.containsKey(fieldName)) { - optionConsumer.accept(storage.get(fieldName)); - } else { - scheduledOperations.merge(fieldName, optionConsumer, Consumer::andThen); - } - } - - public void putOption(String fieldName, Option option) { - storage.put(fieldName, option); - - Consumer> consumer = scheduledOperations.remove(fieldName); - if (consumer != null) { - consumer.accept(option); - } - } - - public void checkBadOperations() { - if (!scheduledOperations.isEmpty()) { - YACLConstants.LOGGER.warn("There are scheduled operations on the `OptionAccess` that tried to reference fields that do not exist. The following have been referenced that do not exist: " + String.join(", ", scheduledOperations.keySet())); - } - } -} diff --git a/common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/OptionFactoryRegistry.java b/common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/OptionFactoryRegistry.java deleted file mode 100644 index 4f6e3c7..0000000 --- a/common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/OptionFactoryRegistry.java +++ /dev/null @@ -1,64 +0,0 @@ -package dev.isxander.yacl3.config.v2.impl.autogen; - -import dev.isxander.yacl3.api.Option; -import dev.isxander.yacl3.config.v2.api.ConfigField; -import dev.isxander.yacl3.config.v2.api.autogen.OptionFactory; -import dev.isxander.yacl3.config.v2.api.autogen.*; -import dev.isxander.yacl3.config.v2.api.autogen.Boolean; -import dev.isxander.yacl3.impl.utils.YACLConstants; - -import java.lang.annotation.Annotation; -import java.lang.reflect.Field; -import java.util.Arrays; -import java.util.HashMap; -import java.util.Map; -import java.util.Optional; - -public class OptionFactoryRegistry { - private static final Map, OptionFactory> factoryMap = new HashMap<>(); - - static { - registerOptionFactory(TickBox.class, new TickBoxImpl()); - registerOptionFactory(Boolean.class, new BooleanImpl()); - registerOptionFactory(IntSlider.class, new IntSliderImpl()); - registerOptionFactory(LongSlider.class, new LongSliderImpl()); - registerOptionFactory(FloatSlider.class, new FloatSliderImpl()); - registerOptionFactory(DoubleSlider.class, new DoubleSliderImpl()); - registerOptionFactory(IntField.class, new IntFieldImpl()); - registerOptionFactory(LongField.class, new LongFieldImpl()); - registerOptionFactory(FloatField.class, new FloatFieldImpl()); - registerOptionFactory(DoubleField.class, new DoubleFieldImpl()); - registerOptionFactory(EnumCycler.class, new EnumCyclerImpl()); - registerOptionFactory(StringField.class, new StringFieldImpl()); - registerOptionFactory(ColorField.class, new ColorFieldImpl()); - registerOptionFactory(Dropdown.class, new DropdownImpl()); - registerOptionFactory(ItemField.class, new ItemFieldImpl()); - registerOptionFactory(Label.class, new LabelImpl()); - registerOptionFactory(ListGroup.class, new ListGroupImpl<>()); - - registerOptionFactory(MasterTickBox.class, new MasterTickBoxImpl()); - } - - public static void registerOptionFactory(Class annotation, OptionFactory factory) { - factoryMap.put(annotation, factory); - } - - public static Optional> createOption(Field field, ConfigField configField, OptionAccess storage) { - Annotation[] annotations = Arrays.stream(field.getAnnotations()) - .filter(annotation -> factoryMap.containsKey(annotation.annotationType())) - .toArray(Annotation[]::new); - - if (annotations.length != 1) { - YACLConstants.LOGGER.warn("Found {} option factory annotations on field {}, expected 1", annotations.length, field); - - if (annotations.length == 0) { - return Optional.empty(); - } - } - - Annotation annotation = annotations[0]; - // noinspection unchecked - OptionFactory factory = (OptionFactory) factoryMap.get(annotation.annotationType()); - return Optional.of(factory.createOption(annotation, configField, storage)); - } -} diff --git a/common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/StringFieldImpl.java b/common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/StringFieldImpl.java deleted file mode 100644 index 96b63a7..0000000 --- a/common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/StringFieldImpl.java +++ /dev/null @@ -1,16 +0,0 @@ -package dev.isxander.yacl3.config.v2.impl.autogen; - -import dev.isxander.yacl3.api.Option; -import dev.isxander.yacl3.api.controller.ControllerBuilder; -import dev.isxander.yacl3.api.controller.StringControllerBuilder; -import dev.isxander.yacl3.config.v2.api.ConfigField; -import dev.isxander.yacl3.config.v2.api.autogen.SimpleOptionFactory; -import dev.isxander.yacl3.config.v2.api.autogen.OptionAccess; -import dev.isxander.yacl3.config.v2.api.autogen.StringField; - -public class StringFieldImpl extends SimpleOptionFactory { - @Override - protected ControllerBuilder createController(StringField annotation, ConfigField field, OptionAccess storage, Option option) { - return StringControllerBuilder.create(option); - } -} diff --git a/common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/TickBoxImpl.java b/common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/TickBoxImpl.java deleted file mode 100644 index 050257c..0000000 --- a/common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/TickBoxImpl.java +++ /dev/null @@ -1,16 +0,0 @@ -package dev.isxander.yacl3.config.v2.impl.autogen; - -import dev.isxander.yacl3.api.Option; -import dev.isxander.yacl3.api.controller.ControllerBuilder; -import dev.isxander.yacl3.api.controller.TickBoxControllerBuilder; -import dev.isxander.yacl3.config.v2.api.ConfigField; -import dev.isxander.yacl3.config.v2.api.autogen.SimpleOptionFactory; -import dev.isxander.yacl3.config.v2.api.autogen.OptionAccess; -import dev.isxander.yacl3.config.v2.api.autogen.TickBox; - -public class TickBoxImpl extends SimpleOptionFactory { - @Override - protected ControllerBuilder createController(TickBox annotation, ConfigField field, OptionAccess storage, Option option) { - return TickBoxControllerBuilder.create(option); - } -} diff --git a/common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/YACLAutoGenException.java b/common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/YACLAutoGenException.java deleted file mode 100644 index 68b375d..0000000 --- a/common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/YACLAutoGenException.java +++ /dev/null @@ -1,11 +0,0 @@ -package dev.isxander.yacl3.config.v2.impl.autogen; - -public class YACLAutoGenException extends RuntimeException { - public YACLAutoGenException(String message) { - super(message); - } - - public YACLAutoGenException(String message, Throwable e) { - super(message, e); - } -} diff --git a/common/src/main/java/dev/isxander/yacl3/config/v2/impl/serializer/GsonConfigSerializer.java b/common/src/main/java/dev/isxander/yacl3/config/v2/impl/serializer/GsonConfigSerializer.java deleted file mode 100644 index 8cd1ed4..0000000 --- a/common/src/main/java/dev/isxander/yacl3/config/v2/impl/serializer/GsonConfigSerializer.java +++ /dev/null @@ -1,269 +0,0 @@ -package dev.isxander.yacl3.config.v2.impl.serializer; - -import com.google.gson.*; -import com.mojang.serialization.JsonOps; -import dev.isxander.yacl3.config.GsonConfigInstance; -import dev.isxander.yacl3.config.v2.api.*; -import dev.isxander.yacl3.config.v2.api.serializer.GsonConfigSerializerBuilder; -import dev.isxander.yacl3.gui.utils.ItemRegistryHelper; -import dev.isxander.yacl3.impl.utils.YACLConstants; -import dev.isxander.yacl3.platform.YACLPlatform; -import net.minecraft.commands.ParserUtils; -import net.minecraft.core.RegistryAccess; -import net.minecraft.core.registries.BuiltInRegistries; -import net.minecraft.network.chat.Component; -import net.minecraft.network.chat.Style; -import net.minecraft.world.item.Item; -import org.jetbrains.annotations.ApiStatus; -import org.quiltmc.parsers.json.JsonReader; -import org.quiltmc.parsers.json.JsonWriter; -import org.quiltmc.parsers.json.gson.GsonReader; -import org.quiltmc.parsers.json.gson.GsonWriter; - -import java.awt.*; -import java.io.IOException; -import java.io.StringWriter; -import java.lang.reflect.Type; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.StandardOpenOption; -import java.util.Arrays; -import java.util.Map; -import java.util.Set; -import java.util.function.Function; -import java.util.function.UnaryOperator; -import java.util.stream.Collectors; - -public class GsonConfigSerializer extends ConfigSerializer { - private final Gson gson; - private final Path path; - private final boolean json5; - - private GsonConfigSerializer(ConfigClassHandler config, Path path, Gson gson, boolean json5) { - super(config); - this.gson = gson; - this.path = path; - this.json5 = json5; - } - - @Override - public void save() { - YACLConstants.LOGGER.info("Serializing {} to '{}'", config.configClass(), path); - - try (StringWriter stringWriter = new StringWriter()) { - JsonWriter jsonWriter = json5 ? JsonWriter.json5(stringWriter) : JsonWriter.json(stringWriter); - GsonWriter gsonWriter = new GsonWriter(jsonWriter); - - jsonWriter.beginObject(); - - for (ConfigField field : config.fields()) { - SerialField serial = field.serial().orElse(null); - if (serial == null) continue; - - if (!json5 && serial.comment().isPresent() && YACLPlatform.isDevelopmentEnv()) { - YACLConstants.LOGGER.warn("Found comment in config field '{}', but json5 is not enabled. Enable it with `.setJson5(true)` on the `GsonConfigSerializerBuilder`. Comments will not be serialized. This warning is only visible in development environments.", serial.serialName()); - } - jsonWriter.comment(serial.comment().orElse(null)); - - jsonWriter.name(serial.serialName()); - - JsonElement element; - try { - element = gson.toJsonTree(field.access().get(), field.access().type()); - } catch (Exception e) { - YACLConstants.LOGGER.error("Failed to serialize config field '{}'. Serializing as null.", serial.serialName(), e); - jsonWriter.nullValue(); - continue; - } - - try { - gson.toJson(element, gsonWriter); - } catch (Exception e) { - YACLConstants.LOGGER.error("Failed to serialize config field '{}'. Due to the error state this JSON writer cannot continue safely and the save will be abandoned.", serial.serialName(), e); - return; - } - } - - jsonWriter.endObject(); - jsonWriter.flush(); - - Files.createDirectories(path.getParent()); - Files.writeString(path, stringWriter.toString(), StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.CREATE); - } catch (IOException e) { - YACLConstants.LOGGER.error("Failed to serialize config class '{}'.", config.configClass().getSimpleName(), e); - } - } - - @Override - public LoadResult loadSafely(Map, FieldAccess> bufferAccessMap) { - if (!Files.exists(path)) { - YACLConstants.LOGGER.info("Config file '{}' does not exist. Creating it with default values.", path); - save(); - return LoadResult.NO_CHANGE; - } - - YACLConstants.LOGGER.info("Deserializing {} from '{}'", config.configClass().getSimpleName(), path); - - Map> fieldMap = Arrays.stream(config.fields()) - .filter(field -> field.serial().isPresent()) - .collect(Collectors.toMap(f -> f.serial().orElseThrow().serialName(), Function.identity())); - Set missingFields = fieldMap.keySet(); - boolean dirty = false; - - try (JsonReader jsonReader = json5 ? JsonReader.json5(path) : JsonReader.json(path)) { - GsonReader gsonReader = new GsonReader(jsonReader); - - jsonReader.beginObject(); - - while (jsonReader.hasNext()) { - String name = jsonReader.nextName(); - ConfigField field = fieldMap.get(name); - missingFields.remove(name); - - if (field == null) { - YACLConstants.LOGGER.warn("Found unknown config field '{}'.", name); - jsonReader.skipValue(); - continue; - } - - FieldAccess bufferAccess = bufferAccessMap.get(field); - SerialField serial = field.serial().orElse(null); - if (serial == null) continue; - - JsonElement element; - try { - element = gson.fromJson(gsonReader, JsonElement.class); - } catch (Exception e) { - YACLConstants.LOGGER.error("Failed to deserialize config field '{}'. Due to the error state this JSON reader cannot be re-used and loading will be aborted.", name, e); - return LoadResult.FAILURE; - } - - if (element.isJsonNull() && !serial.nullable()) { - YACLConstants.LOGGER.warn("Found null value in non-nullable config field '{}'. Leaving field as default and marking as dirty.", name); - dirty = true; - continue; - } - - try { - bufferAccess.set(gson.fromJson(element, bufferAccess.type())); - } catch (Exception e) { - YACLConstants.LOGGER.error("Failed to deserialize config field '{}'. Leaving as default.", name, e); - } - } - - jsonReader.endObject(); - } catch (IOException e) { - YACLConstants.LOGGER.error("Failed to deserialize config class.", e); - return LoadResult.FAILURE; - } - - if (!missingFields.isEmpty()) { - for (String missingField : missingFields) { - if (fieldMap.get(missingField).serial().orElseThrow().required()) { - dirty = true; - YACLConstants.LOGGER.warn("Missing required config field '{}''. Re-saving as default.", missingField); - } - } - } - - return dirty ? LoadResult.DIRTY : LoadResult.SUCCESS; - } - - @Override - @Deprecated - @SuppressWarnings("deprecation") - public void load() { - YACLConstants.LOGGER.warn("Calling ConfigSerializer#load() directly is deprecated. Please use ConfigClassHandler#load() instead."); - config.load(); - } - - public static class StyleTypeAdapter implements JsonSerializer