aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/dev/isxander/yacl3/api/StateManager.java
blob: 07d263e93cc1e9fc1d21e561cef361c18dad98e4 (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
package dev.isxander.yacl3.api;

import dev.isxander.yacl3.impl.ImmutableStateManager;
import dev.isxander.yacl3.impl.InstantStateManager;
import dev.isxander.yacl3.impl.SimpleStateManager;
import org.jetbrains.annotations.NotNull;

import java.util.function.Consumer;
import java.util.function.Supplier;

public interface StateManager<T> {
    static <T> StateManager<T> createSimple(Binding<T> binding) {
        return new SimpleStateManager<>(binding);
    }

    static <T> StateManager<T> createSimple(@NotNull T def, @NotNull Supplier<@NotNull T> getter, @NotNull Consumer<@NotNull T> setter) {
        return new SimpleStateManager<>(Binding.generic(def, getter, setter));
    }

    static <T> StateManager<T> createInstant(Binding<T> binding) {
        return new InstantStateManager<>(binding);
    }

    static <T> StateManager<T> createInstant(@NotNull T def, @NotNull Supplier<@NotNull T> getter, @NotNull Consumer<@NotNull T> setter) {
        return new InstantStateManager<>(Binding.generic(def, getter, setter));
    }

    static <T> StateManager<T> createImmutable(@NotNull T value) {
        return new ImmutableStateManager<>(value);
    }

    /**
     * Sets the pending value.
     */
    void set(T value);

    /**
     * @return the pending value.
     */
    T get();

    /**
     * Applies the pending value to the backed binding.
     */
    void apply();

    void resetToDefault(ResetAction action);

    /**
     * Essentially "forgets" the pending value and reassigns state as backed by the binding.
     */
    void sync();

    /**
     * @return true if the pending value is the same as the backed binding value.
     */
    boolean isSynced();

    /**
     * @return true if this state manage will always be synced with the backing binding.
     */
    default boolean isAlwaysSynced() {
        return false;
    }

    boolean isDefault();

    void addListener(StateListener<T> stateListener);

    enum ResetAction {
        BY_OPTION,
        BY_GLOBAL,
    }

    interface StateListener<T> {
        static <T> StateListener<T> noop() {
            return (oldValue, newValue) -> {};
        }

        void onStateChange(T oldValue, T newValue);

        default StateListener<T> andThen(StateListener<T> after) {
            return (oldValue, newValue) -> {
                this.onStateChange(oldValue, newValue);
                after.onStateChange(oldValue, newValue);
            };
        }
    }
}