Minestom/src/main/java/net/minestom/server/tag/Tag.java

148 lines
5.0 KiB
Java
Raw Normal View History

2021-05-17 12:34:45 +02:00
package net.minestom.server.tag;
2021-05-17 17:46:56 +02:00
import org.jetbrains.annotations.ApiStatus;
2021-05-17 12:34:45 +02:00
import org.jetbrains.annotations.NotNull;
2021-05-17 12:44:22 +02:00
import org.jetbrains.annotations.Nullable;
2021-05-17 12:34:45 +02:00
import org.jglrxavpok.hephaistos.nbt.NBT;
import org.jglrxavpok.hephaistos.nbt.NBTCompound;
import java.util.function.BiConsumer;
import java.util.function.Function;
2021-05-17 12:44:22 +02:00
import java.util.function.Supplier;
2021-05-17 12:34:45 +02:00
2021-05-17 15:14:16 +02:00
/**
* Represents a key to retrieve or change a value.
* <p>
* All tags are serializable.
*
* @param <T> the tag type
*/
2021-05-17 17:46:56 +02:00
@ApiStatus.NonExtendable
public class Tag<T> {
2021-05-17 12:34:45 +02:00
private final String key;
private final Function<NBTCompound, T> readFunction;
private final BiConsumer<NBTCompound, T> writeConsumer;
2021-05-17 15:17:53 +02:00
private volatile Supplier<T> defaultValue;
2021-05-17 12:44:22 +02:00
2021-05-17 17:46:56 +02:00
protected Tag(@NotNull String key,
2021-05-17 12:34:45 +02:00
@NotNull Function<NBTCompound, T> readFunction,
@NotNull BiConsumer<NBTCompound, T> writeConsumer) {
this.key = key;
this.readFunction = readFunction;
this.writeConsumer = writeConsumer;
}
public @NotNull String getKey() {
return key;
}
2021-05-17 12:44:22 +02:00
public Tag<T> defaultValue(@NotNull Supplier<T> defaultValue) {
this.defaultValue = defaultValue;
return this;
}
public Tag<T> defaultValue(@NotNull T defaultValue) {
defaultValue(() -> defaultValue);
return this;
}
2021-05-17 13:04:00 +02:00
public @Nullable T read(@NotNull NBTCompound nbtCompound) {
if (nbtCompound.containsKey(key)) {
return readFunction.apply(nbtCompound);
} else {
2021-05-17 15:17:53 +02:00
final var supplier = defaultValue;
return supplier != null ? supplier.get() : null;
2021-05-17 13:04:00 +02:00
}
2021-05-17 12:34:45 +02:00
}
2021-05-17 13:04:00 +02:00
public void write(@NotNull NBTCompound nbtCompound, @Nullable T value) {
if (value != null) {
this.writeConsumer.accept(nbtCompound, value);
} else {
nbtCompound.removeTag(key);
}
2021-05-17 12:34:45 +02:00
}
public static @NotNull Tag<Byte> Byte(@NotNull String key) {
return new Tag<>(key,
nbtCompound -> nbtCompound.getByte(key),
(nbtCompound, value) -> nbtCompound.setByte(key, value));
}
public static @NotNull Tag<Short> Short(@NotNull String key) {
return new Tag<>(key,
nbtCompound -> nbtCompound.getShort(key),
(nbtCompound, value) -> nbtCompound.setShort(key, value));
}
public static @NotNull Tag<Integer> Integer(@NotNull String key) {
return new Tag<>(key,
nbtCompound -> nbtCompound.getInt(key),
(nbtCompound, integer) -> nbtCompound.setInt(key, integer));
}
public static @NotNull Tag<Long> Long(@NotNull String key) {
return new Tag<>(key,
nbtCompound -> nbtCompound.getLong(key),
(nbtCompound, value) -> nbtCompound.setLong(key, value));
}
public static @NotNull Tag<Float> Float(@NotNull String key) {
return new Tag<>(key,
nbtCompound -> nbtCompound.getFloat(key),
(nbtCompound, value) -> nbtCompound.setFloat(key, value));
}
public static @NotNull Tag<Double> Double(@NotNull String key) {
return new Tag<>(key,
nbtCompound -> nbtCompound.getDouble(key),
(nbtCompound, value) -> nbtCompound.setDouble(key, value));
}
public static @NotNull Tag<byte[]> ByteArray(@NotNull String key) {
return new Tag<>(key,
nbtCompound -> nbtCompound.getByteArray(key),
(nbtCompound, value) -> nbtCompound.setByteArray(key, value));
}
public static @NotNull Tag<String> String(@NotNull String key) {
return new Tag<>(key,
nbtCompound -> nbtCompound.getString(key),
(nbtCompound, value) -> nbtCompound.setString(key, value));
}
public static @NotNull Tag<NBT> NBT(@NotNull String key) {
return new Tag<>(key,
nbt -> {
var currentNBT = nbt.get(key);
// Avoid a NPE when cloning a null variable.
if (currentNBT == null) {
return null;
}
return currentNBT.deepClone();
},
((nbt, value) -> nbt.set(key, value.deepClone())));
}
public static @NotNull Tag<int[]> IntArray(@NotNull String key) {
return new Tag<>(key,
nbtCompound -> nbtCompound.getIntArray(key),
(nbtCompound, value) -> nbtCompound.setIntArray(key, value));
}
public static @NotNull Tag<long[]> LongArray(@NotNull String key) {
return new Tag<>(key,
nbtCompound -> nbtCompound.getLongArray(key),
(nbtCompound, value) -> nbtCompound.setLongArray(key, value));
}
2021-05-17 14:02:14 +02:00
public static <T> @NotNull Tag<T> Custom(@NotNull String key, @NotNull TagSerializer<T> serializer) {
return new Tag<>(key,
2021-05-17 18:26:38 +02:00
nbtCompound -> serializer.read(TagReadable.fromCompound(nbtCompound)),
(nbtCompound, value) -> serializer.write(TagWritable.fromCompound(nbtCompound), value));
2021-05-17 14:02:14 +02:00
}
2021-05-17 12:34:45 +02:00
}