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 { /** * 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 controller(); /** * Binding for the option. * Controls setting, getting and default value. * * @see Binding */ @NotNull Binding 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 flags(); /** * Checks if the pending value is not equal to the current set value */ boolean changed(); /** * Value in the GUI, ready to set the actual bound value or be undone. */ @NotNull T pendingValue(); /** * Sets the pending value */ void requestSet(@NotNull T value); /** * Applies the pending value to the bound value. * Cannot be undone. * * @return if there were changes to apply {@link Option#changed()} */ boolean applyValue(); /** * Sets the pending value to the bound value. */ void forgetPendingValue(); /** * Sets the pending value to the default bound value. */ void requestSetDefault(); /** * Checks if the current pending value is equal to its default value */ boolean isPendingValueDefault(); default boolean canResetToDefault() { return true; } /** * Adds a listener for when the pending value changes */ void addListener(BiConsumer, T> changedListener); static Builder createBuilder() { return new OptionImpl.BuilderImpl<>(); } /** * Creates a builder to construct an {@link Option} * * @param type of the option's value * @param typeClass used to capture the type */ @Deprecated static Builder createBuilder(Class typeClass) { return createBuilder(); } interface Builder { /** * Sets the name to be used by the option. * * @see Option#name() */ Builder name(@NotNull Component name); /** * Sets the description to be used by the option. * @see OptionDescription * @param description the static description. * @return this builder */ Builder description(@NotNull OptionDescription description); /** * Sets the function to get the description by the option's current value. * * @see OptionDescription * @param descriptionFunction the function to get the description by the option's current value. * @return this builder */ Builder description(@NotNull Function descriptionFunction); Builder controller(@NotNull Function, ControllerBuilder> controllerBuilder); /** * Sets the controller for the option. * This is how you interact and change the options. * * @see dev.isxander.yacl3.gui.controllers */ Builder customController(@NotNull Function, Controller> control); /** * Sets the binding for the option. * Used for default, getter and setter. * * @see Binding */ Builder binding(@NotNull Binding 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 binding(@NotNull T def, @NotNull Supplier<@NotNull T> getter, @NotNull Consumer<@NotNull T> setter); /** * Sets if the option can be configured * * @see Option#available() */ Builder available(boolean available); /** * Adds a flag to the option. * Upon applying changes, all flags are executed. * {@link Option#flags()} */ Builder flag(@NotNull OptionFlag... flag); /** * Adds a flag to the option. * Upon applying changes, all flags are executed. * {@link Option#flags()} */ Builder flags(@NotNull Collection flags); /** * Instantly invokes the binder's setter when modified in the GUI. * Prevents the user from undoing the change *

* Does not support {@link Option#flags()}! */ Builder instant(boolean instant); /** * Adds a listener to the option. Invoked upon changing the pending value. * * @see Option#addListener(BiConsumer) */ Builder listener(@NotNull BiConsumer, T> listener); /** * Adds multiple listeners to the option. Invoked upon changing the pending value. * * @see Option#addListener(BiConsumer) */ Builder listeners(@NotNull Collection, T>> listeners); Option build(); } }