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
|
package dev.isxander.yacl.api;
import com.google.common.collect.ImmutableList;
import dev.isxander.yacl.config.ConfigInstance;
import dev.isxander.yacl.gui.YACLScreen;
import dev.isxander.yacl.impl.YetAnotherConfigLibImpl;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.text.Text;
import org.apache.commons.lang3.Validate;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.function.BiFunction;
import java.util.function.Consumer;
/**
* Main class of the mod.
* Contains all data and used to provide a {@link Screen}
*/
public interface YetAnotherConfigLib {
/**
* Title of the GUI. Only used for Minecraft narration.
*/
Text title();
/**
* Gets all config categories.
*/
ImmutableList<ConfigCategory> categories();
/**
* Ran when changes are saved. Can be used to save config to a file etc.
*/
Runnable saveFunction();
/**
* Ran every time the YACL screen initialises. Can be paired with FAPI to add custom widgets.
*/
Consumer<YACLScreen> initConsumer();
/**
* Generates a Screen to display based on this instance.
*
* @param parent parent screen to open once closed
*/
Screen generateScreen(@Nullable Screen parent);
/**
* Creates a builder to construct YACL
*/
static Builder createBuilder() {
return new Builder();
}
/**
* Creates an instance using a {@link ConfigInstance} which autofills the save() builder method.
* This also takes an easy functional interface that provides defaults and config to help build YACL bindings.
*/
static <T> YetAnotherConfigLib create(ConfigInstance<T> configInstance, ConfigBackedBuilder<T> builder) {
return builder.build(configInstance.getDefaults(), configInstance.getConfig(), createBuilder().save(configInstance::save)).build();
}
class Builder {
private Text title;
private final List<ConfigCategory> categories = new ArrayList<>();
private Runnable saveFunction = () -> {};
private Consumer<YACLScreen> initConsumer = screen -> {};
private Builder() {
}
/**
* Sets title of GUI for Minecraft narration
*
* @see YetAnotherConfigLib#title()
*/
public Builder title(@NotNull Text title) {
Validate.notNull(title, "`title` cannot be null");
this.title = title;
return this;
}
/**
* Adds a new category.
* To create a category you need to use {@link ConfigCategory#createBuilder()}
*
* @see YetAnotherConfigLib#categories()
*/
public Builder category(@NotNull ConfigCategory category) {
Validate.notNull(category, "`category` cannot be null");
this.categories.add(category);
return this;
}
/**
* Adds multiple categories at once.
* To create a category you need to use {@link ConfigCategory#createBuilder()}
*
* @see YetAnotherConfigLib#categories()
*/
public Builder categories(@NotNull Collection<? extends ConfigCategory> categories) {
Validate.notNull(categories, "`categories` cannot be null");
this.categories.addAll(categories);
return this;
}
/**
* Used to define a save function for when user clicks the Save Changes button
*
* @see YetAnotherConfigLib#saveFunction()
*/
public Builder save(@NotNull Runnable saveFunction) {
Validate.notNull(saveFunction, "`saveFunction` cannot be null");
this.saveFunction = saveFunction;
return this;
}
/**
* Defines a consumer that is accepted every time the YACL screen initialises
*
* @see YetAnotherConfigLib#initConsumer()
*/
public Builder screenInit(@NotNull Consumer<YACLScreen> initConsumer) {
Validate.notNull(initConsumer, "`initConsumer` cannot be null");
this.initConsumer = initConsumer;
return this;
}
public YetAnotherConfigLib build() {
Validate.notNull(title, "`title must not be null to build `YetAnotherConfigLib`");
Validate.notEmpty(categories, "`categories` must not be empty to build `YetAnotherConfigLib`");
Validate.isTrue(!categories.stream().allMatch(category -> category instanceof PlaceholderCategory), "At least one regular category is required to build `YetAnotherConfigLib`");
return new YetAnotherConfigLibImpl(title, ImmutableList.copyOf(categories), saveFunction, initConsumer);
}
}
@FunctionalInterface
interface ConfigBackedBuilder<T> {
YetAnotherConfigLib.Builder build(T defaults, T config, YetAnotherConfigLib.Builder builder);
}
}
|