Implement node serialisation

This commit is contained in:
Ben Woo 2023-08-29 16:39:20 +08:00
parent 5dba9b5904
commit c569bc797f
No known key found for this signature in database
GPG Key ID: FB2A3645536E12C8
7 changed files with 66 additions and 4 deletions

View File

@ -3,7 +3,9 @@ package com.onarandombox.MultiverseCore.configuration.handle;
import com.onarandombox.MultiverseCore.configuration.migration.ConfigMigrator;
import com.onarandombox.MultiverseCore.configuration.node.ConfigNodeNotFoundException;
import com.onarandombox.MultiverseCore.configuration.node.NodeGroup;
import com.onarandombox.MultiverseCore.configuration.node.NodeSerializer;
import com.onarandombox.MultiverseCore.configuration.node.ValueNode;
import io.vavr.control.Option;
import io.vavr.control.Try;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.plugin.Plugin;
@ -58,7 +60,7 @@ public abstract class GenericConfigHandle<C extends ConfigurationSection> {
nodes.forEach(node -> {
if (node instanceof ValueNode valueNode) {
set(valueNode, config.getObject(valueNode.getPath(), valueNode.getType(), valueNode.getDefaultValue()));
set(valueNode, get(valueNode));
}
});
}
@ -81,7 +83,10 @@ public abstract class GenericConfigHandle<C extends ConfigurationSection> {
* @return The value of the node.
*/
public <T> T get(@NotNull ValueNode<T> node) {
return config.getObject(node.getPath(), node.getType(), node.getDefaultValue());
if (node.getSerializer() == null) {
return config.getObject(node.getPath(), node.getType(), node.getDefaultValue());
}
return node.getSerializer().deserialize(config.get(node.getPath(), node.getDefaultValue()), node.getType());
}
/**
@ -108,7 +113,12 @@ public abstract class GenericConfigHandle<C extends ConfigurationSection> {
public <T> Try<Void> set(@NotNull ValueNode<T> node, T value) {
return node.validate(value).map(ignore -> {
T oldValue = get(node);
config.set(node.getPath(), value);
if (node.getSerializer() != null) {
var serialized = node.getSerializer().serialize(value, node.getType());
config.set(node.getPath(), serialized);
} else {
config.set(node.getPath(), value);
}
node.onSetValue(oldValue, get(node));
return null;
});

View File

@ -32,6 +32,7 @@ public class ConfigNode<T> extends ConfigHeaderNode implements ValueNode<T> {
protected final @Nullable String name;
protected final @NotNull Class<T> type;
protected final @Nullable T defaultValue;
protected final @Nullable NodeSerializer<T> serializer;
protected final @Nullable Function<T, Try<Void>> validator;
protected final @Nullable BiConsumer<T, T> onSetValue;
@ -41,6 +42,7 @@ public class ConfigNode<T> extends ConfigHeaderNode implements ValueNode<T> {
@Nullable String name,
@NotNull Class<T> type,
@Nullable T defaultValue,
@Nullable NodeSerializer<T> serializer,
@Nullable Function<T, Try<Void>> validator,
@Nullable BiConsumer<T, T> onSetValue
) {
@ -48,6 +50,7 @@ public class ConfigNode<T> extends ConfigHeaderNode implements ValueNode<T> {
this.name = name;
this.type = type;
this.defaultValue = defaultValue;
this.serializer = serializer;
this.validator = validator;
this.onSetValue = onSetValue;
}
@ -76,6 +79,10 @@ public class ConfigNode<T> extends ConfigHeaderNode implements ValueNode<T> {
return defaultValue;
}
public @Nullable NodeSerializer<T> getSerializer() {
return serializer;
}
/**
* {@inheritDoc}
*/
@ -108,6 +115,7 @@ public class ConfigNode<T> extends ConfigHeaderNode implements ValueNode<T> {
protected @Nullable String name;
protected @NotNull final Class<T> type;
protected @Nullable T defaultValue;
protected @Nullable NodeSerializer<T> serializer;
protected @Nullable Function<T, Try<Void>> validator;
protected @Nullable BiConsumer<T, T> onSetValue;
@ -145,6 +153,11 @@ public class ConfigNode<T> extends ConfigHeaderNode implements ValueNode<T> {
return (B) this;
}
public @NotNull B serializer(@NotNull NodeSerializer<T> serializer) {
this.serializer = serializer;
return (B) this;
}
public @NotNull B validator(@NotNull Function<T, Try<Void>> validator) {
this.validator = validator;
return (B) this;
@ -166,7 +179,7 @@ public class ConfigNode<T> extends ConfigHeaderNode implements ValueNode<T> {
*/
@Override
public @NotNull ConfigNode<T> build() {
return new ConfigNode<>(path, comments.toArray(new String[0]), name, type, defaultValue, validator, onSetValue);
return new ConfigNode<>(path, comments.toArray(new String[0]), name, type, defaultValue, serializer, validator, onSetValue);
}
}
}

View File

@ -0,0 +1,16 @@
package com.onarandombox.MultiverseCore.configuration.node;
import com.dumptruckman.minecraft.util.Logging;
public class EnumNodeSerializer<T extends Enum<T>> implements NodeSerializer<T> {
@Override
public T deserialize(Object object, Class<T> type) {
return Enum.valueOf(type, object.toString().toUpperCase());
}
@Override
public Object serialize(T object, Class<T> type) {
return object.toString();
}
}

View File

@ -0,0 +1,6 @@
package com.onarandombox.MultiverseCore.configuration.node;
public interface NodeSerializer<T> {
T deserialize(Object object, Class<T> type);
Object serialize(T object, Class<T> type);
}

View File

@ -28,6 +28,13 @@ public interface ValueNode<T> extends Node {
*/
@Nullable T getDefaultValue();
/**
* Gets the serializer for this node.
*
* @return The serializer for this node.
*/
@Nullable NodeSerializer<T> getSerializer();
/**
* Validates the value of this node.
*

View File

@ -1,5 +1,6 @@
package com.onarandombox.MultiverseCore.worldnew;
import com.dumptruckman.minecraft.util.Logging;
import com.onarandombox.MultiverseCore.worldnew.config.WorldConfig;
import com.onarandombox.MultiverseCore.worldnew.config.WorldsConfigFile;
import jakarta.inject.Inject;
@ -19,6 +20,7 @@ public class WorldManager {
public void loadAllWorlds() {
for (String worldName : worldsConfigFile.getAllWorldsInConfig()) {
Logging.fine("Loading world: " + worldName);
loadWorld(worldName);
}
saveWorldsConfig();

View File

@ -1,14 +1,18 @@
package com.onarandombox.MultiverseCore.worldnew.config;
import com.onarandombox.MultiverseCore.configuration.node.ConfigNode;
import com.onarandombox.MultiverseCore.configuration.node.EnumNodeSerializer;
import com.onarandombox.MultiverseCore.configuration.node.Node;
import com.onarandombox.MultiverseCore.configuration.node.NodeGroup;
import com.onarandombox.MultiverseCore.configuration.node.NodeSerializer;
import com.onarandombox.MultiverseCore.world.configuration.AllowedPortalType;
import org.bukkit.Difficulty;
import org.bukkit.GameMode;
import org.bukkit.World;
public class WorldConfigNodes {
private static final NodeSerializer<?> ENUM_NODE_SERIALIZER = new EnumNodeSerializer<>();
private final NodeGroup nodes = new NodeGroup();
WorldConfigNodes() {
@ -56,16 +60,19 @@ public class WorldConfigNodes {
public final ConfigNode<Difficulty> DIFFICULTY = node(ConfigNode.builder("difficulty", Difficulty.class)
.defaultValue(Difficulty.NORMAL)
.name("difficulty")
.serializer((NodeSerializer<Difficulty>) ENUM_NODE_SERIALIZER)
.build());
public final ConfigNode<World.Environment> ENVIRONMENT = node(ConfigNode.builder("environment", World.Environment.class)
.defaultValue(World.Environment.NORMAL)
.name("environment")
.serializer((NodeSerializer<World.Environment>) ENUM_NODE_SERIALIZER)
.build());
public final ConfigNode<GameMode> GAMEMODE = node(ConfigNode.builder("gamemode", GameMode.class)
.defaultValue(GameMode.SURVIVAL)
.name("gamemode")
.serializer((NodeSerializer<GameMode>) ENUM_NODE_SERIALIZER)
.build());
public final ConfigNode<String> GENERATOR = node(ConfigNode.builder("generator", String.class)
@ -96,6 +103,7 @@ public class WorldConfigNodes {
public final ConfigNode<AllowedPortalType> PORTAL_FORM = node(ConfigNode.builder("portal-form", AllowedPortalType.class)
.defaultValue(AllowedPortalType.ALL)
.name("portal-form")
.serializer((NodeSerializer<AllowedPortalType>) ENUM_NODE_SERIALIZER)
.build());
public final ConfigNode<Boolean> PVP = node(ConfigNode.builder("pvp", Boolean.class)