aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/dev/isxander/yacl3/api
diff options
context:
space:
mode:
authorisxander <xander@isxander.dev>2024-04-11 18:43:06 +0100
committerisxander <xander@isxander.dev>2024-04-11 18:43:06 +0100
commit04fe933f4c24817100f3101f088accf55a621f8a (patch)
treefeff94ca3ab4484160e69a24f4ee38522381950e /src/main/java/dev/isxander/yacl3/api
parent831b894fdb7fe3e173d81387c8f6a2402b8ccfa9 (diff)
downloadYetAnotherConfigLib-04fe933f4c24817100f3101f088accf55a621f8a.tar.gz
YetAnotherConfigLib-04fe933f4c24817100f3101f088accf55a621f8a.tar.bz2
YetAnotherConfigLib-04fe933f4c24817100f3101f088accf55a621f8a.zip
Extremely fragile and broken multiversion build with stonecutter
Diffstat (limited to 'src/main/java/dev/isxander/yacl3/api')
-rw-r--r--src/main/java/dev/isxander/yacl3/api/Binding.java64
-rw-r--r--src/main/java/dev/isxander/yacl3/api/ButtonOption.java55
-rw-r--r--src/main/java/dev/isxander/yacl3/api/ConfigCategory.java138
-rw-r--r--src/main/java/dev/isxander/yacl3/api/Controller.java28
-rw-r--r--src/main/java/dev/isxander/yacl3/api/LabelOption.java41
-rw-r--r--src/main/java/dev/isxander/yacl3/api/ListOption.java178
-rw-r--r--src/main/java/dev/isxander/yacl3/api/ListOptionEntry.java18
-rw-r--r--src/main/java/dev/isxander/yacl3/api/NameableEnum.java10
-rw-r--r--src/main/java/dev/isxander/yacl3/api/Option.java223
-rw-r--r--src/main/java/dev/isxander/yacl3/api/OptionAddable.java51
-rw-r--r--src/main/java/dev/isxander/yacl3/api/OptionDescription.java161
-rw-r--r--src/main/java/dev/isxander/yacl3/api/OptionFlag.java23
-rw-r--r--src/main/java/dev/isxander/yacl3/api/OptionGroup.java131
-rw-r--r--src/main/java/dev/isxander/yacl3/api/PlaceholderCategory.java55
-rw-r--r--src/main/java/dev/isxander/yacl3/api/YetAnotherConfigLib.java113
-rw-r--r--src/main/java/dev/isxander/yacl3/api/controller/BooleanControllerBuilder.java16
-rw-r--r--src/main/java/dev/isxander/yacl3/api/controller/ColorControllerBuilder.java14
-rw-r--r--src/main/java/dev/isxander/yacl3/api/controller/ControllerBuilder.java10
-rw-r--r--src/main/java/dev/isxander/yacl3/api/controller/CyclingListControllerBuilder.java15
-rw-r--r--src/main/java/dev/isxander/yacl3/api/controller/DoubleFieldControllerBuilder.java10
-rw-r--r--src/main/java/dev/isxander/yacl3/api/controller/DoubleSliderControllerBuilder.java10
-rw-r--r--src/main/java/dev/isxander/yacl3/api/controller/DropdownStringControllerBuilder.java18
-rw-r--r--src/main/java/dev/isxander/yacl3/api/controller/EnumControllerBuilder.java12
-rw-r--r--src/main/java/dev/isxander/yacl3/api/controller/EnumDropdownControllerBuilder.java10
-rw-r--r--src/main/java/dev/isxander/yacl3/api/controller/FloatFieldControllerBuilder.java10
-rw-r--r--src/main/java/dev/isxander/yacl3/api/controller/FloatSliderControllerBuilder.java10
-rw-r--r--src/main/java/dev/isxander/yacl3/api/controller/IntegerFieldControllerBuilder.java10
-rw-r--r--src/main/java/dev/isxander/yacl3/api/controller/IntegerSliderControllerBuilder.java10
-rw-r--r--src/main/java/dev/isxander/yacl3/api/controller/ItemControllerBuilder.java11
-rw-r--r--src/main/java/dev/isxander/yacl3/api/controller/LongFieldControllerBuilder.java10
-rw-r--r--src/main/java/dev/isxander/yacl3/api/controller/LongSliderControllerBuilder.java10
-rw-r--r--src/main/java/dev/isxander/yacl3/api/controller/NumberFieldControllerBuilder.java7
-rw-r--r--src/main/java/dev/isxander/yacl3/api/controller/SliderControllerBuilder.java6
-rw-r--r--src/main/java/dev/isxander/yacl3/api/controller/StringControllerBuilder.java10
-rw-r--r--src/main/java/dev/isxander/yacl3/api/controller/TickBoxControllerBuilder.java10
-rw-r--r--src/main/java/dev/isxander/yacl3/api/controller/ValueFormattableController.java14
-rw-r--r--src/main/java/dev/isxander/yacl3/api/controller/ValueFormatter.java7
-rw-r--r--src/main/java/dev/isxander/yacl3/api/utils/Dimension.java33
-rw-r--r--src/main/java/dev/isxander/yacl3/api/utils/MutableDimension.java11
-rw-r--r--src/main/java/dev/isxander/yacl3/api/utils/OptionUtils.java39
40 files changed, 1612 insertions, 0 deletions
diff --git a/src/main/java/dev/isxander/yacl3/api/Binding.java b/src/main/java/dev/isxander/yacl3/api/Binding.java
new file mode 100644
index 0000000..f41b78b
--- /dev/null
+++ b/src/main/java/dev/isxander/yacl3/api/Binding.java
@@ -0,0 +1,64 @@
+package dev.isxander.yacl3.api;
+
+import dev.isxander.yacl3.impl.GenericBindingImpl;
+import dev.isxander.yacl3.mixin.OptionInstanceAccessor;
+import net.minecraft.client.OptionInstance;
+import org.apache.commons.lang3.Validate;
+
+import java.util.function.Consumer;
+import java.util.function.Supplier;
+
+/**
+ * Controls modifying the bound option.
+ * Provides the default value, a setter and a getter.
+ */
+public interface Binding<T> {
+ void setValue(T value);
+
+ T getValue();
+
+ T defaultValue();
+
+ /**
+ * Creates a generic binding.
+ *
+ * @param def default value of the option, used to reset
+ * @param getter should return the current value of the option
+ * @param setter should set the option to the supplied value
+ */
+ static <T> Binding<T> generic(T def, Supplier<T> getter, Consumer<T> setter) {
+ Validate.notNull(def, "`def` must not be null");
+ Validate.notNull(getter, "`getter` must not be null");
+ Validate.notNull(setter, "`setter` must not be null");
+
+ return new GenericBindingImpl<>(def, getter, setter);
+ }
+
+ /**
+ * Creates a {@link Binding} for Minecraft's {@link OptionInstance}
+ */
+ static <T> Binding<T> minecraft(OptionInstance<T> minecraftOption) {
+ Validate.notNull(minecraftOption, "`minecraftOption` must not be null");
+
+ return new GenericBindingImpl<>(
+ ((OptionInstanceAccessor<T>) (Object) minecraftOption).getInitialValue(),
+ minecraftOption::get,
+ minecraftOption::set
+ );
+ }
+
+ /**
+ * Creates an immutable binding that has no default and cannot be modified.
+ *
+ * @param value the value for the binding
+ */
+ static <T> Binding<T> immutable(T value) {
+ Validate.notNull(value, "`value` must not be null");
+
+ return new GenericBindingImpl<>(
+ value,
+ () -> value,
+ changed -> {}
+ );
+ }
+}
diff --git a/src/main/java/dev/isxander/yacl3/api/ButtonOption.java b/src/main/java/dev/isxander/yacl3/api/ButtonOption.java
new file mode 100644
index 0000000..4f53dd4
--- /dev/null
+++ b/src/main/java/dev/isxander/yacl3/api/ButtonOption.java
@@ -0,0 +1,55 @@
+package dev.isxander.yacl3.api;
+
+import dev.isxander.yacl3.gui.YACLScreen;
+import dev.isxander.yacl3.impl.ButtonOptionImpl;
+import net.minecraft.network.chat.Component;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.function.BiConsumer;
+import java.util.function.Consumer;
+
+public interface ButtonOption extends Option<BiConsumer<YACLScreen, ButtonOption>> {
+ /**
+ * Action to be executed upon button press
+ */
+ BiConsumer<YACLScreen, ButtonOption> action();
+
+ static Builder createBuilder() {
+ return new ButtonOptionImpl.BuilderImpl();
+ }
+
+ interface Builder {
+ /**
+ * Sets the name to be used by the option.
+ *
+ * @see Option#name()
+ */
+ Builder name(@NotNull Component name);
+
+ /**
+ * Sets the button text to be displayed next to the name.
+ */
+ Builder text(@NotNull Component text);
+
+ Builder description(@NotNull OptionDescription description);
+
+ Builder action(@NotNull BiConsumer<YACLScreen, ButtonOption> action);
+
+ /**
+ * Action to be executed upon button press
+ *
+ * @see ButtonOption#action()
+ */
+ @Deprecated
+ Builder action(@NotNull Consumer<YACLScreen> action);
+
+ /**
+ * Sets if the option can be configured
+ *
+ * @see Option#available()
+ */
+ Builder available(boolean available);
+
+ ButtonOption build();
+ }
+}
diff --git a/src/main/java/dev/isxander/yacl3/api/ConfigCategory.java b/src/main/java/dev/isxander/yacl3/api/ConfigCategory.java
new file mode 100644
index 0000000..b3d68fc
--- /dev/null
+++ b/src/main/java/dev/isxander/yacl3/api/ConfigCategory.java
@@ -0,0 +1,138 @@
+package dev.isxander.yacl3.api;
+
+import com.google.common.collect.ImmutableList;
+import dev.isxander.yacl3.impl.ConfigCategoryImpl;
+import net.minecraft.network.chat.Component;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Collection;
+import java.util.function.Supplier;
+
+/**
+ * Separates {@link Option}s or {@link OptionGroup}s into multiple distinct sections.
+ * Served to a user as a button in the left column,
+ * upon pressing, the options list is filled with options contained within this category.
+ */
+public interface ConfigCategory {
+ /**
+ * Name of category, displayed as a button on the left column.
+ */
+ @NotNull Component name();
+
+ /**
+ * Gets every {@link OptionGroup} in this category.
+ */
+ @NotNull ImmutableList<OptionGroup> groups();
+
+ /**
+ * Tooltip (or description) of the category.
+ * Rendered on hover.
+ */
+ @NotNull Component tooltip();
+
+ /**
+ * Creates a builder to construct a {@link ConfigCategory}
+ */
+ static Builder createBuilder() {
+ return new ConfigCategoryImpl.BuilderImpl();
+ }
+
+ interface Builder extends OptionAddable {
+ /**
+ * Sets name of the category
+ *
+ * @see ConfigCategory#name()
+ */
+ Builder name(@NotNull Component name);
+
+ /**
+ * Adds an option to the root group of the category.
+ * To add to another group, use {@link Builder#group(OptionGroup)}.
+ * To construct an option, use {@link Option#createBuilder()}
+ *
+ * @see ConfigCategory#groups()
+ * @see OptionGroup#isRoot()
+ */
+ @Override
+ Builder option(@NotNull Option<?> option);
+
+ /**
+ * Adds an option to the root group of the category.
+ * To add to another group, use {@link Builder#group(OptionGroup)}.
+ * To construct an option, use {@link Option#createBuilder()}
+ *
+ * @param optionSupplier to be called to initialise the option. called immediately
+ * @return this
+ */
+ @Override
+ default Builder option(@NotNull Supplier<@NotNull Option<?>> optionSupplier) {
+ OptionAddable.super.option(optionSupplier);
+ return this;
+ }
+
+ /**
+ * Adds an option to the root group of the category if a condition is met.
+ * To add to another group, use {@link Builder#group(OptionGroup)}.
+ * To construct an option, use {@link Option#createBuilder()}
+ *
+ * @param condition only if true is the option added
+ * @return this
+ */
+ @Override
+ default Builder optionIf(boolean condition, @NotNull Option<?> option) {
+ OptionAddable.super.optionIf(condition, option);
+ return this;
+ }
+
+ /**
+ * Adds an option to the root group of the category if a condition is met.
+ * To add to another group, use {@link Builder#group(OptionGroup)}.
+ * To construct an option, use {@link Option#createBuilder()}
+ *
+ * @param condition only if true is the option added
+ * @param optionSupplier to be called to initialise the option. called immediately only if condition is true
+ * @return this
+ */
+ @Override
+ default Builder optionIf(boolean condition, @NotNull Supplier<@NotNull Option<?>> optionSupplier) {
+ OptionAddable.super.optionIf(condition, optionSupplier);
+ return this;
+ }
+
+ /**
+ * Adds multiple options to the root group of the category.
+ * To add to another group, use {@link Builder#groups(Collection)}.
+ * To construct an option, use {@link Option#createBuilder()}
+ *
+ * @see ConfigCategory#groups()
+ * @see OptionGroup#isRoot()
+ */
+ @Override
+ Builder options(@NotNull Collection<? extends Option<?>> options);
+
+ /**
+ * Adds an option group.
+ * To add an option to the root group, use {@link Builder#option(Option)}
+ * To construct a group, use {@link OptionGroup#createBuilder()}
+ */
+ Builder group(@NotNull OptionGroup group);
+
+ /**
+ * Adds multiple option groups.
+ * To add multiple options to the root group, use {@link Builder#options(Collection)}
+ * To construct a group, use {@link OptionGroup#createBuilder()}
+ */
+ Builder groups(@NotNull Collection<OptionGroup> groups);
+
+ /**
+ * Sets the tooltip to be used by the category.
+ * Can be invoked twice to append more lines.
+ * No need to wrap the text yourself, the gui does this itself.
+ *
+ * @param tooltips text lines - merged with a new-line on {@link Builder#build()}.
+ */
+ Builder tooltip(@NotNull Component... tooltips);
+
+ ConfigCategory build();
+ }
+}
diff --git a/src/main/java/dev/isxander/yacl3/api/Controller.java b/src/main/java/dev/isxander/yacl3/api/Controller.java
new file mode 100644
index 0000000..25e4465
--- /dev/null
+++ b/src/main/java/dev/isxander/yacl3/api/Controller.java
@@ -0,0 +1,28 @@
+package dev.isxander.yacl3.api;
+
+import dev.isxander.yacl3.api.utils.Dimension;
+import dev.isxander.yacl3.gui.AbstractWidget;
+import dev.isxander.yacl3.gui.YACLScreen;
+import net.minecraft.network.chat.Component;
+
+/**
+ * Provides a widget to control the option.
+ */
+public interface Controller<T> {
+ /**
+ * Gets the dedicated {@link Option} for this controller
+ */
+ Option<T> option();
+
+ /**
+ * Gets the formatted value based on {@link Option#pendingValue()}
+ */
+ Component formatValue();
+
+ /**
+ * Provides a widget to display
+ *
+ * @param screen parent screen
+ */
+ AbstractWidget provideWidget(YACLScreen screen, Dimension<Integer> widgetDimension);
+}
diff --git a/src/main/java/dev/isxander/yacl3/api/LabelOption.java b/src/main/java/dev/isxander/yacl3/api/LabelOption.java
new file mode 100644
index 0000000..a5f015e
--- /dev/null
+++ b/src/main/java/dev/isxander/yacl3/api/LabelOption.java
@@ -0,0 +1,41 @@
+package dev.isxander.yacl3.api;
+
+import dev.isxander.yacl3.impl.LabelOptionImpl;
+import net.minecraft.network.chat.Component;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Collection;
+
+/**
+ * A label option is an easier way of creating a label with a {@link dev.isxander.yacl3.gui.controllers.LabelController}.
+ * This option is immutable and cannot be disabled. Tooltips are supported through
+ * {@link Component} styling.
+ */
+public interface LabelOption extends Option<Component> {
+ @NotNull Component label();
+
+ /**
+ * Creates a new label option with the given label, skipping a builder for ease.
+ */
+ static LabelOption create(@NotNull Component label) {
+ return new LabelOptionImpl(label);
+ }
+
+ static Builder createBuilder() {
+ return new LabelOptionImpl.BuilderImpl();
+ }
+
+ interface Builder {
+ /**
+ * Appends a line to the label
+ */
+ Builder line(@NotNull Component line);
+
+ /**
+ * Appends multiple lines to the label
+ */
+ Builder lines(@NotNull Collection<? extends Component> lines);
+
+ LabelOption build();
+ }
+}
diff --git a/src/main/java/dev/isxander/yacl3/api/ListOption.java b/src/main/java/dev/isxander/yacl3/api/ListOption.java
new file mode 100644
index 0000000..1f4adfa
--- /dev/null
+++ b/src/main/java/dev/isxander/yacl3/api/ListOption.java
@@ -0,0 +1,178 @@
+package dev.isxander.yacl3.api;
+
+import com.google.common.collect.ImmutableList;
+import dev.isxander.yacl3.api.controller.ControllerBuilder;
+import dev.isxander.yacl3.impl.ListOptionImpl;
+import net.minecraft.network.chat.Component;
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.*;
+import java.util.function.BiConsumer;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.Supplier;
+
+/**
+ * A list option that takes form as an option group for UX.
+ * You add this option through {@link ConfigCategory.Builder#group(OptionGroup)}. Do NOT add as an option.
+ * Users can add remove and reshuffle a list type. You can use any controller you wish, there are no dedicated
+ * controllers for list types. List options do not manipulate your list but get and set the list with a
+ * regular binding for simplicity.
+ *
+ * You may apply option flags like a normal option and collapse like a normal group, it is a merge of them both.
+ * Methods in this interface marked with {@link ApiStatus.Internal} should not be used, and could be subject to
+ * change at any time
+ * @param <T>
+ */
+public interface ListOption<T> extends OptionGroup, Option<List<T>> {
+ @Override
+ @NotNull ImmutableList<ListOptionEntry<T>> options();
+
+ @ApiStatus.Internal
+ int numberOfEntries();
+
+ @ApiStatus.Internal
+ int maximumNumberOfEntries();
+
+ @ApiStatus.Internal
+ int minimumNumberOfEntries();
+
+ @ApiStatus.Internal
+ ListOptionEntry<T> insertNewEntry();
+
+ @ApiStatus.Internal
+ void insertEntry(int index, ListOptionEntry<?> entry);
+
+ @ApiStatus.Internal
+ int indexOf(ListOptionEntry<?> entry);
+
+ @ApiStatus.Internal
+ void removeEntry(ListOptionEntry<?> entry);
+
+ @ApiStatus.Internal
+ void addRefreshListener(Runnable changedListener);
+
+ static <T> Builder<T> createBuilder() {
+ return new ListOptionImpl.BuilderImpl<>();
+ }
+
+ @Deprecated
+ static <T> Builder<T> createBuilder(Class<T> typeClass) {
+ return createBuilder();
+ }
+
+ interface Builder<T> {
+ /**
+ * Sets name of the list, for UX purposes, a name should always be given,
+ * but isn't enforced.
+ *
+ * @see ListOption#name()
+ */
+ Builder<T> name(@NotNull Component name);
+
+ Builder<T> description(@NotNull OptionDescription description);
+
+ /**
+ * Sets the value that is used when creating new entries
+ */
+ Builder<T> initial(@NotNull Supplier<T> initialValue);
+
+ /**
+ * Sets the value that is used when creating new entries
+ */
+ Builder<T> initial(@NotNull T initialValue);
+
+ Builder<T> controller(@NotNull Function<Option<T>, ControllerBuilder<T>> controller);
+
+ /**
+ * Sets the controller for the option.
+ * This is how you interact and change the options.
+ *
+ * @see dev.isxander.yacl3.gui.controllers
+ */
+ Builder<T> customController(@NotNull Function<ListOptionEntry<T>, Controller<T>> control);
+
+ /**
+ * Sets the binding for the option.
+ * Used for default, getter and setter.
+ *
+ * @see Binding
+ */
+ Builder<T> binding(@NotNull Binding<List<T>> binding);
+
+ /**
+ * Sets the binding for the option.
+ * Shorthand of {@link Binding#generic(Object, Supplier, Consumer)}
+ *
+ * @param def default value of the option, used to reset
+ * @param getter should return the current value of the option
+ * @param setter should set the option to the supplied value
+ * @see Binding
+ */
+ Builder<T> binding(@NotNull List<T> def, @NotNull Supplier<@NotNull List<T>> getter, @NotNull Consumer<@NotNull List<T>> setter);
+
+ /**
+ * Sets if the option can be configured
+ *
+ * @see Option#available()
+ */
+ Builder<T> available(boolean available);
+
+ /**
+ * Sets a minimum size for the list. Once this size is reached,
+ * no further entries may be removed.
+ */
+ Builder<T> minimumNumberOfEntries(int number);
+
+ /**
+ * Sets a maximum size for the list. Once this size is reached,
+ * no further entries may be added.
+ */
+ Builder<T> maximumNumberOfEntries(int number);
+
+ /**
+ * Dictates if new entries should be added to the end of the list
+ * rather than the top.
+ */
+ Builder<T> insertEntriesAtEnd(boolean insertAtEnd);
+
+ /**
+ * Adds a flag to the option.
+ * Upon applying changes, all flags are executed.
+ * {@link Option#flags()}
+ */
+ Builder<T> flag(@NotNull OptionFlag... flag);
+
+ /**
+ * Adds a flag to the option.
+ * Upon applying changes, all flags are executed.
+ * {@link Option#flags()}
+ */
+ Builder<T> flags(@NotNull Collection<OptionFlag> flags);
+
+ /**
+ * Dictates if the group should be collapsed by default.
+ * If not set, it will not be collapsed by default.
+ *
+ * @see OptionGroup#collapsed()
+ */
+ Builder<T> collapsed(boolean collapsible);
+
+ /**
+ * Adds a listener to the option. Invoked upon changing any of the list's entries.
+ *
+ * @see Option#addListener(BiConsumer)
+ */
+ ListOption.Builder<T> listener(@NotNull BiConsumer<Option<List<T>>, List<T>> listener);
+
+ /**
+ * Adds multiple listeners to the option. Invoked upon changing of any of the list's entries.
+ *
+ * @see Option#addListener(BiConsumer)
+ */
+ ListOption.Builder<T> listeners(@NotNull Collection<BiConsumer<Option<List<T>>, List<T>>> listeners);
+
+ ListOption<T> build();
+ }
+}
diff --git a/src/main/java/dev/isxander/yacl3/api/ListOptionEntry.java b/src/main/java/dev/isxander/yacl3/api/ListOptionEntry.java
new file mode 100644
index 0000000..23ec657
--- /dev/null
+++ b/src/main/java/dev/isxander/yacl3/api/ListOptionEntry.java
@@ -0,0 +1,18 @@
+package dev.isxander.yacl3.api;
+
+import com.google.common.collect.ImmutableSet;
+import org.jetbrains.annotations.NotNull;
+
+public interface ListOptionEntry<T> extends Option<T> {
+ ListOption<T> parentGroup();
+
+ @Override
+ default @NotNull ImmutableSet<OptionFlag> flags() {
+ return parentGroup().flags();
+ }
+
+ @Override
+ default boolean available() {
+ return parentGroup().available();
+ }
+}
diff --git a/src/main/java/dev/isxander/yacl3/api/NameableEnum.java b/src/main/java/dev/isxander/yacl3/api/NameableEnum.java
new file mode 100644
index 0000000..425623f
--- /dev/null
+++ b/src/main/java/dev/isxander/yacl3/api/NameableEnum.java
@@ -0,0 +1,10 @@
+package dev.isxander.yacl3.api;
+
+import net.minecraft.network.chat.Component;
+
+/**
+ * Used for the default value formatter of {@link dev.isxander.yacl3.gui.controllers.cycling.EnumController} and {@link dev.isxander.yacl3.gui.controllers.dropdown.EnumDropdownController}
+ */
+public interface NameableEnum {
+ Component getDisplayName();
+}
diff --git a/src/main/java/dev/isxander/yacl3/api/Option.java b/src/main/java/dev/isxander/yacl3/api/Option.java
new file mode 100644
index 0000000..38bd8ca
--- /dev/null
+++ b/src/main/java/dev/isxander/yacl3/api/Option.java
@@ -0,0 +1,223 @@
+package dev.isxander.yacl3.api;
+
+import com.google.common.collect.ImmutableSet;
+import dev.isxander.yacl3.api.controller.ControllerBuilder;
+import dev.isxander.yacl3.impl.OptionImpl;
+import net.minecraft.network.chat.Component;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.*;
+import java.util.function.BiConsumer;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.Supplier;
+
+public interface Option<T> {
+ /**
+ * Name of the option
+ */
+ @NotNull Component name();
+
+ @NotNull OptionDescription description();
+
+ /**
+ * Tooltip (or description) of the option.
+ * Rendered on hover.
+ */
+ @Deprecated
+ @NotNull Component tooltip();
+
+ /**
+ * Widget provider for a type of option.
+ *
+ * @see dev.isxander.yacl3.gui.controllers
+ */
+ @NotNull Controller<T> controller();
+
+ /**
+ * Binding for the option.
+ * Controls setting, getting and default value.
+ *
+ * @see Binding
+ */
+ @NotNull Binding<T> binding();
+
+ /**
+ * If the option can be configured
+ */
+ boolean available();
+
+ /**
+ * Sets if the option can be configured after being built
+ *
+ * @see Option#available()
+ */
+ void setAvailable(boolean available);
+
+ /**
+ * Tasks that needs to be executed upon applying changes.
+ */
+ @NotNull ImmutableSet<OptionFlag> flags();
+
+ /**
+ * Checks if the pending value is not equal to the current set value
+ */
+ boolean changed();
+
+