aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/dev/isxander/yacl3/api/Option.java
blob: 9190168463e5b42515d25ef6bb0a412553d3aef0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
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();

    @NotNull StateManager<T> stateManager();

    /**
     * Binding for the option.
     * Controls setting, getting and default value.
     *
     * @see Binding
     */
    @Deprecated
    @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();

    /**
     * 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;
    }

    void addEventListener(OptionEventListener<T> listener);

    /**
     * Adds a listener for when the pending value changes
     */
    @Deprecated
    void addListener(BiConsumer<Option<T>, T> changedListener);

    static <T> Builder<T> createBuilder() {
        return new OptionImpl.BuilderImpl<>();
    }

    /**
     * Creates a builder to construct an {@link Option}
     *
     * @param <T> type of the option's value
     * @param typeClass used to capture the type
     */
    @Deprecated
    static <T> Builder<T> createBuilder(Class<T> typeClass) {
        return createBuilder();
    }

    interface Builder<T> {
        /**
         * Sets the name to be used by the option.
         *
         * @see Option#name()
         */
        Builder<T> name(@NotNull Component name);

        /**
         * Sets the description to be used by the option.
         * @see OptionDescription
         * @param description the static description.
         * @return this builder
         */
        Builder<T> 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<T> description(@NotNull Function<T, OptionDescription> descriptionFunction);

        /**
         * Supplies a controller for this option. A controller is the GUI control to interact with the option.
         * @return this builder
         */
        Builder<T> controller(@NotNull Function<Option<T>, ControllerBuilder<T>> controllerBuilder);

        /**
         * 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<Option<T>, Controller<T>> control);

        Builder<T> stateManager(@NotNull StateManager<T> stateManager);

        /**
         * Sets the binding for the option.
         * Used for default, getter and setter.
         * Under-the-hood, this creates a state manager that is individual to the option, sharing state with no options.
         *
         * @see Binding
         */
        Builder<T> binding(@NotNull Binding<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 T def, @NotNull Supplier<@NotNull T> getter, @NotNull Consumer<@NotNull T> setter);

        /**
         * Sets if the option can be configured
         *
         * @see Option#available()
         */
        Builder<T> available(boolean available);

        /**
         * 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<? extends OptionFlag> flags);

        Builder<T> addListener(@NotNull OptionEventListener<T> listener);

        Builder<T> addListeners(@NotNull Collection<OptionEventListener<T>> listeners);

        /**
         * Instantly invokes the binder's setter when modified in the GUI.
         * Prevents the user from undoing the change
         * <p>
         * Does not support {@link Option#flags()}!
         */
        @Deprecated
        Builder<T> instant(boolean instant);

        /**
         * Adds a listener to the option. Invoked upon changing the pending value.
         *
         * @see Option#addListener(BiConsumer)
         */
        @Deprecated
        Builder<T> listener(@NotNull BiConsumer<Option<T>, T> listener);

        /**
         * Adds multiple listeners to the option. Invoked upon changing the pending value.
         *
         * @see Option#addListener(BiConsumer)
         */
        @Deprecated
        Builder<T> listeners(@NotNull Collection<BiConsumer<Option<T>, T>> listeners);

        Option<T> build();
    }
}