Skip to content

Commit 9fa4772

Browse files
authored
Merge pull request #3395 from Multiverse/feat/node-load-change
Refactor configuration node on set callbacks to split up load and change events
2 parents 8ab9993 + ae3bc6d commit 9fa4772

File tree

13 files changed

+388
-49
lines changed

13 files changed

+388
-49
lines changed

src/main/java/org/mvplugins/multiverse/core/config/CoreConfigNodes.java

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -386,7 +386,7 @@ private <N extends Node> N node(N node) {
386386
.comment("This config option defines the default language Multiverse should use.")
387387
.defaultValue(Locale.ENGLISH)
388388
.name("default-locale")
389-
.onSetValue((oldValue, newValue) ->
389+
.onLoadAndChange((oldValue, newValue) ->
390390
commandManager.get().getLocales().setDefaultLocale(newValue))
391391
.build());
392392

@@ -396,9 +396,8 @@ private <N extends Node> N node(N node) {
396396
.comment("If the player's language does not have a translation, it will use the default language set above instead.")
397397
.defaultValue(true)
398398
.name("per-player-locale")
399-
.onSetValue((oldValue, newValue) -> {
400-
commandManager.get().usePerIssuerLocale(newValue);
401-
})
399+
.onLoadAndChange((oldValue, newValue) ->
400+
commandManager.get().usePerIssuerLocale(newValue))
402401
.build());
403402

404403
private final ConfigHeaderNode commandHeader = node(ConfigHeaderNode.builder("command")
@@ -477,7 +476,7 @@ private <N extends Node> N node(N node) {
477476
.comment("")
478477
.comment("This config option defines the priority for the PlayerPortalEvent.")
479478
.name("event-priority-player-portal")
480-
.onSetValue((oldValue, newValue) ->
479+
.onLoadAndChange((oldValue, newValue) ->
481480
eventPriorityMapper.get().setPriority("mvcore-player-portal", newValue))
482481
.build());
483482

@@ -486,15 +485,16 @@ private <N extends Node> N node(N node) {
486485
.name("event-priority-player-respawn")
487486
.comment("")
488487
.comment("This config option defines the priority for the PlayerRespawnEvent.")
489-
.onSetValue((oldValue, newValue) ->
488+
.onLoadAndChange((oldValue, newValue) ->
490489
eventPriorityMapper.get().setPriority("mvcore-player-respawn", newValue))
491490
.build());
492491

493492
final ConfigNode<EventPriority> eventPriorityPlayerSpawnLocation = node(ConfigNode.builder("event-priority.player-spawn-location", EventPriority.class)
494493
.defaultValue(EventPriority.NORMAL)
495494
.comment("")
496495
.comment("This config option defines the priority for the PlayerSpawnLocationEvent.")
497-
.name("event-priority-player-spawn-location").onSetValue((oldValue, newValue) ->
496+
.name("event-priority-player-spawn-location")
497+
.onLoadAndChange((oldValue, newValue) ->
498498
eventPriorityMapper.get().setPriority("mvcore-player-spawn-location", newValue))
499499
.build());
500500

@@ -503,7 +503,7 @@ private <N extends Node> N node(N node) {
503503
.name("event-priority-player-teleport")
504504
.comment("")
505505
.comment("This config option defines the priority for the PlayerTeleportEvent.")
506-
.onSetValue((oldValue, newValue) ->
506+
.onLoadAndChange((oldValue, newValue) ->
507507
eventPriorityMapper.get().setPriority("mvcore-player-teleport", newValue))
508508
.build());
509509

@@ -551,7 +551,7 @@ private <N extends Node> N node(N node) {
551551
.validator(value -> (value < 0 || value > 3)
552552
? Try.failure(new MultiverseException("Debug level must be between 0 and 3."))
553553
: Try.success(null))
554-
.onSetValue((oldValue, newValue) -> {
554+
.onLoadAndChange((oldValue, newValue) -> {
555555
if (newValue != Logging.getDebugLevel()) {
556556
Logging.setDebugLevel(newValue);
557557
pluginManager.callEvent(new MVDebugModeEvent(newValue));
@@ -565,15 +565,15 @@ private <N extends Node> N node(N node) {
565565
.comment("This will only work if the above 'global-debug' is set to 1 or more.")
566566
.defaultValue(false)
567567
.name("debug-permissions")
568-
.onSetValue((oldValue, newValue) -> PermissionUtils.setDebugPermissions(newValue))
568+
.onLoadAndChange((oldValue, newValue) -> PermissionUtils.setDebugPermissions(newValue))
569569
.build());
570570

571571
final ConfigNode<Boolean> silentStart = node(ConfigNode.builder("misc.silent-start", Boolean.class)
572572
.comment("")
573573
.comment("If true, the startup console messages will no longer show.")
574574
.defaultValue(false)
575575
.name("silent-start")
576-
.onSetValue((oldValue, newValue) -> Logging.setShowingConfig(!newValue))
576+
.onLoadAndChange((oldValue, newValue) -> Logging.setShowingConfig(!newValue))
577577
.build());
578578

579579
final ConfigNode<Boolean> showDonationMessage = node(ConfigNode.builder("misc.show-donation-message", Boolean.class)

src/main/java/org/mvplugins/multiverse/core/config/handle/BaseConfigurationHandle.java

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,22 @@
33
import java.util.HashMap;
44
import java.util.List;
55
import java.util.Map;
6+
import java.util.Objects;
67
import java.util.logging.Logger;
78

89
import com.dumptruckman.minecraft.util.Logging;
910
import io.vavr.control.Option;
1011
import io.vavr.control.Try;
12+
import org.bukkit.Bukkit;
13+
import org.bukkit.command.CommandSender;
1114
import org.bukkit.configuration.ConfigurationSection;
1215
import org.bukkit.plugin.Plugin;
16+
import org.jetbrains.annotations.ApiStatus;
1317
import org.jetbrains.annotations.NotNull;
1418
import org.jetbrains.annotations.Nullable;
1519

1620
import org.mvplugins.multiverse.core.config.migration.ConfigMigrator;
1721
import org.mvplugins.multiverse.core.config.node.ListValueNode;
18-
import org.mvplugins.multiverse.core.config.node.Node;
1922
import org.mvplugins.multiverse.core.config.node.NodeGroup;
2023
import org.mvplugins.multiverse.core.config.node.ValueNode;
2124

@@ -84,7 +87,8 @@ protected void setUpNodes() {
8487
});
8588

8689
nodeValueMap.forEach((valueNode, value) -> {
87-
valueNode.onSetValue(value, value);
90+
valueNode.onLoad(value);
91+
valueNode.onLoadAndChange(Bukkit.getConsoleSender(), null, value);
8892
});
8993
}
9094

@@ -156,10 +160,29 @@ public <T> T get(@NotNull ValueNode<T> node) {
156160
* @return Empty try if the value was set, try containing an error otherwise.
157161
*/
158162
public <T> Try<Void> set(@NotNull ValueNode<T> node, T value) {
163+
return set(Bukkit.getConsoleSender(), node, value);
164+
}
165+
166+
/**
167+
* Sets the value of a node, if the validator is not null, it will be tested first.
168+
*
169+
* @param sender The sender who triggered the change.
170+
* @param node The node to set the value of.
171+
* @param value The value to set.
172+
* @param <T> The type of the node value.
173+
* @return Empty try if the value was set, try containing an error otherwise.
174+
*
175+
* @since 5.4
176+
*/
177+
@ApiStatus.AvailableSince("5.4")
178+
public <T> Try<Void> set(@NotNull CommandSender sender, @NotNull ValueNode<T> node, T value) {
159179
return node.validate(value).map(ignore -> {
160180
T oldValue = get(node);
161181
nodeValueMap.put(node, value);
162-
node.onSetValue(oldValue, get(node));
182+
if (!Objects.equals(oldValue, value)) {
183+
node.onLoadAndChange(sender, oldValue, value);
184+
node.onChange(sender, oldValue, value);
185+
}
163186
return null;
164187
});
165188
}

src/main/java/org/mvplugins/multiverse/core/config/handle/StringPropertyHandle.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,7 @@ public Try<Void> setPropertyString(@Nullable String name, @Nullable String value
226226
public Try<Void> setPropertyString(@NotNull CommandSender sender, @Nullable String name, @Nullable String value) {
227227
return findNode(name, ValueNode.class)
228228
.flatMap(node -> node.parseFromString(sender, value)
229-
.flatMap(parsedValue -> handle.set(node, parsedValue)));
229+
.flatMap(parsedValue -> handle.set(sender, node, parsedValue)));
230230
}
231231

232232
/**

src/main/java/org/mvplugins/multiverse/core/config/node/ConfigNode.java

Lines changed: 110 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@
1414
import org.jetbrains.annotations.NotNull;
1515
import org.jetbrains.annotations.Nullable;
1616

17+
import org.mvplugins.multiverse.core.config.node.functions.NodeChangeCallback;
18+
import org.mvplugins.multiverse.core.config.node.functions.NodeValueCallback;
19+
import org.mvplugins.multiverse.core.config.node.functions.SenderNodeChangeCallback;
1720
import org.mvplugins.multiverse.core.config.node.functions.SenderNodeStringParser;
1821
import org.mvplugins.multiverse.core.config.node.functions.SenderNodeSuggester;
1922
import org.mvplugins.multiverse.core.config.node.serializer.DefaultSerializerProvider;
@@ -53,7 +56,9 @@ public class ConfigNode<T> extends ConfigHeaderNode implements ValueNode<T> {
5356
protected @Nullable NodeStringParser<T> stringParser;
5457
protected @Nullable NodeSerializer<T> serializer;
5558
protected @Nullable Function<T, Try<Void>> validator;
56-
protected @Nullable BiConsumer<T, T> onSetValue;
59+
protected @Nullable NodeValueCallback<T> onLoad;
60+
protected @Nullable NodeChangeCallback<T> onLoadAndChange;
61+
protected @Nullable NodeChangeCallback<T> onChange;
5762

5863
protected ConfigNode(
5964
@NotNull String path,
@@ -66,7 +71,9 @@ protected ConfigNode(
6671
@Nullable NodeStringParser<T> stringParser,
6772
@Nullable NodeSerializer<T> serializer,
6873
@Nullable Function<T, Try<Void>> validator,
69-
@Nullable BiConsumer<T, T> onSetValue) {
74+
@Nullable NodeValueCallback<T> onLoad,
75+
@Nullable NodeChangeCallback<T> onLoadAndChange,
76+
@Nullable NodeChangeCallback<T> onChange) {
7077
super(path, comments);
7178
this.name = name;
7279
this.type = type;
@@ -82,7 +89,9 @@ protected ConfigNode(
8289
? serializer
8390
: DefaultSerializerProvider.getDefaultSerializer(type);
8491
this.validator = validator;
85-
this.onSetValue = onSetValue;
92+
this.onLoad = onLoad;
93+
this.onLoadAndChange = onLoadAndChange;
94+
this.onChange = onChange;
8695
}
8796

8897
/**
@@ -186,9 +195,29 @@ public Try<Void> validate(@Nullable T value) {
186195
* {@inheritDoc}
187196
*/
188197
@Override
189-
public void onSetValue(@Nullable T oldValue, @Nullable T newValue) {
190-
if (onSetValue != null) {
191-
onSetValue.accept(oldValue, newValue);
198+
public void onLoad(@Nullable T value) {
199+
if (onLoad != null) {
200+
onLoad.run(value);
201+
}
202+
}
203+
204+
/**
205+
* {@inheritDoc}
206+
*/
207+
@Override
208+
public void onLoadAndChange(@NotNull CommandSender sender, @Nullable T oldValue, @Nullable T newValue) {
209+
if (onLoadAndChange != null) {
210+
onLoadAndChange.run(sender, oldValue, newValue);
211+
}
212+
}
213+
214+
/**
215+
* {@inheritDoc}
216+
*/
217+
@Override
218+
public void onChange(@NotNull CommandSender sender, @Nullable T oldValue, @Nullable T newValue) {
219+
if (onChange != null) {
220+
onChange.run(sender, oldValue, newValue);
192221
}
193222
}
194223

@@ -208,7 +237,9 @@ public static class Builder<T, B extends ConfigNode.Builder<T, B>> extends Confi
208237
protected @Nullable NodeStringParser<T> stringParser;
209238
protected @Nullable NodeSerializer<T> serializer;
210239
protected @Nullable Function<T, Try<Void>> validator;
211-
protected @Nullable BiConsumer<T, T> onSetValue;
240+
protected @Nullable NodeValueCallback<T> onLoad;
241+
protected @Nullable NodeChangeCallback<T> onLoadAndChange;
242+
protected @Nullable NodeChangeCallback<T> onChange;
212243

213244
/**
214245
* Creates a new builder.
@@ -368,15 +399,83 @@ protected Builder(@NotNull String path, @NotNull Class<T> type) {
368399
return self();
369400
}
370401

402+
/**
403+
* Sets the action to be performed when the value is loaded.
404+
*
405+
* @param onLoad The action to be performed.
406+
* @return This builder.
407+
*/
408+
@ApiStatus.AvailableSince("5.4")
409+
public @NotNull B onLoad(@NotNull NodeValueCallback<T> onLoad) {
410+
this.onLoad = this.onLoad == null ? onLoad : this.onLoad.then(onLoad);
411+
return self();
412+
}
413+
414+
/**
415+
* Sets the action to be performed when the value is loaded and changed.
416+
*
417+
* @param onLoadAndChange The action to be performed.
418+
* @return This builder.
419+
*
420+
* @since 5.4
421+
*/
422+
@ApiStatus.AvailableSince("5.4")
423+
public @NotNull B onLoadAndChange(@NotNull NodeChangeCallback<T> onLoadAndChange) {
424+
this.onLoadAndChange = this.onLoadAndChange == null ? onLoadAndChange : this.onLoadAndChange.then(onLoadAndChange);
425+
return self();
426+
}
427+
428+
/**
429+
* Sets the action to be performed when the value is loaded and changed.
430+
*
431+
* @param onLoadAndChange The action to be performed.
432+
* @return This builder.
433+
*
434+
* @since 5.4
435+
*/
436+
@ApiStatus.AvailableSince("5.4")
437+
public @NotNull B onLoadAndChange(@NotNull SenderNodeChangeCallback<T> onLoadAndChange) {
438+
return onLoadAndChange((NodeChangeCallback<T>) onLoadAndChange);
439+
}
440+
441+
/**
442+
* Sets the action to be performed when the value is changed.
443+
*
444+
* @param onChange The action to be performed.
445+
* @return This builder.
446+
*
447+
* @since 5.4
448+
*/
449+
@ApiStatus.AvailableSince("5.4")
450+
public @NotNull B onChange(@NotNull NodeChangeCallback<T> onChange) {
451+
this.onChange = this.onChange == null ? onChange : this.onChange.then(onChange);
452+
return self();
453+
}
454+
455+
/**
456+
* Sets the action to be performed when the value is changed.
457+
*
458+
* @param onChange The action to be performed.
459+
* @return This builder.
460+
*
461+
* @since 5.4
462+
*/
463+
@ApiStatus.AvailableSince("5.4")
464+
public @NotNull B onChange(@NotNull SenderNodeChangeCallback<T> onChange) {
465+
return onChange((NodeChangeCallback<T>) onChange);
466+
}
467+
371468
/**
372469
* Sets the action to be performed when the value is set.
373470
*
374471
* @param onSetValue The action to be performed.
375472
* @return This builder.
473+
*
474+
* @deprecated Use {@link #onLoadAndChange(NodeChangeCallback)} instead.
376475
*/
476+
@Deprecated(since = "5.4", forRemoval = true)
377477
public @NotNull B onSetValue(@NotNull BiConsumer<T, T> onSetValue) {
378-
this.onSetValue = this.onSetValue == null ? onSetValue : this.onSetValue.andThen(onSetValue);
379-
return self();
478+
return onLoadAndChange(onSetValue::accept);
380479
}
381480

382481
/**
@@ -385,7 +484,8 @@ protected Builder(@NotNull String path, @NotNull Class<T> type) {
385484
@Override
386485
public @NotNull ConfigNode<T> build() {
387486
return new ConfigNode<>(path, comments.toArray(new String[0]),
388-
name, type, aliases, defaultValue, suggester, stringParser, serializer, validator, onSetValue);
487+
name, type, aliases, defaultValue, suggester, stringParser, serializer, validator,
488+
onLoad, onLoadAndChange, onChange);
389489
}
390490
}
391491
}

0 commit comments

Comments
 (0)