From c312bf59fcf25b9e6a7be2c77e2e8eb4a45884c0 Mon Sep 17 00:00:00 2001 From: TheMode Date: Sun, 13 Jun 2021 13:38:26 +0200 Subject: [PATCH] Revamp tag api --- .../java/net/minestom/server/tag/Tag.java | 41 ++++++++++++++++--- .../minestom/server/tag/TagSerializer.java | 8 ++-- .../net/minestom/server/tag/TagWritable.java | 4 ++ src/test/java/demo/block/CampfireHandler.java | 9 ++-- 4 files changed, 49 insertions(+), 13 deletions(-) diff --git a/src/main/java/net/minestom/server/tag/Tag.java b/src/main/java/net/minestom/server/tag/Tag.java index b89aaed6f..ad9702dec 100644 --- a/src/main/java/net/minestom/server/tag/Tag.java +++ b/src/main/java/net/minestom/server/tag/Tag.java @@ -21,6 +21,8 @@ import java.util.function.Supplier; @ApiStatus.NonExtendable public class Tag { + private static final String EMPTY_KEY = ""; + private final String key; private final Function readFunction; private final BiConsumer writeConsumer; @@ -85,16 +87,16 @@ public class Tag { } public @Nullable T read(@NotNull NBTCompound nbtCompound) { - if (nbtCompound.containsKey(key)) { - return readFunction.apply(nbtCompound); - } else { + T result = readFunction.apply(nbtCompound); + if (result == null) { final var supplier = defaultValue; - return supplier != null ? supplier.get() : null; + result = supplier != null ? supplier.get() : null; } + return result; } public void write(@NotNull NBTCompound nbtCompound, @Nullable T value) { - if (value != null) { + if (value != null || key.equals(EMPTY_KEY)) { this.writeConsumer.accept(nbtCompound, value); } else { nbtCompound.removeTag(key); @@ -180,8 +182,35 @@ public class Tag { (nbtCompound, value) -> nbtCompound.setLongArray(key, value)); } - public static @NotNull Tag Custom(@NotNull String key, @NotNull TagSerializer serializer) { + /** + * Create a wrapper around a compound. + * + * @param key the tag key + * @param serializer the tag serializer + * @param the tag type + * @return the created tag + */ + public static @NotNull Tag Structure(@NotNull String key, @NotNull TagSerializer serializer) { return new Tag<>(key, + nbtCompound -> { + final var compound = nbtCompound.getCompound(key); + if (compound == null) { + return null; + } + return serializer.read(TagReadable.fromCompound(compound)); + }, + (nbtCompound, value) -> { + var compound = nbtCompound.getCompound(key); + if (compound == null) { + compound = new NBTCompound(); + nbtCompound.set(key, compound); + } + serializer.write(TagWritable.fromCompound(compound), value); + }); + } + + public static @NotNull Tag View(@NotNull TagSerializer serializer) { + return new Tag<>(EMPTY_KEY, nbtCompound -> serializer.read(TagReadable.fromCompound(nbtCompound)), (nbtCompound, value) -> serializer.write(TagWritable.fromCompound(nbtCompound), value)); } diff --git a/src/main/java/net/minestom/server/tag/TagSerializer.java b/src/main/java/net/minestom/server/tag/TagSerializer.java index 03318bfdf..36f0f08c2 100644 --- a/src/main/java/net/minestom/server/tag/TagSerializer.java +++ b/src/main/java/net/minestom/server/tag/TagSerializer.java @@ -4,7 +4,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; /** - * Interface used to create custom types compatible with {@link Tag#Custom(String, TagSerializer)}. + * Interface used to create custom {@link Tag tags}. * * @param the type to serialize */ @@ -14,7 +14,7 @@ public interface TagSerializer { * Reads the custom tag from a {@link TagReadable}. * * @param reader the reader - * @return the deserialized value + * @return the deserialized value, null if invalid */ @Nullable T read(@NotNull TagReadable reader); @@ -22,7 +22,7 @@ public interface TagSerializer { * Writes the custom tag to a {@link TagWritable}. * * @param writer the writer - * @param value the value to serialize + * @param value the value to serialize, null to remove */ - void write(@NotNull TagWritable writer, @NotNull T value); + void write(@NotNull TagWritable writer, @Nullable T value); } diff --git a/src/main/java/net/minestom/server/tag/TagWritable.java b/src/main/java/net/minestom/server/tag/TagWritable.java index fe0c2962b..3630615f5 100644 --- a/src/main/java/net/minestom/server/tag/TagWritable.java +++ b/src/main/java/net/minestom/server/tag/TagWritable.java @@ -18,6 +18,10 @@ public interface TagWritable { */ void setTag(@NotNull Tag tag, @Nullable T value); + default void removeTag(@NotNull Tag tag) { + setTag(tag, null); + } + /** * Converts an nbt compound to a tag writer. * diff --git a/src/test/java/demo/block/CampfireHandler.java b/src/test/java/demo/block/CampfireHandler.java index d0ac02a1b..22e0224a7 100644 --- a/src/test/java/demo/block/CampfireHandler.java +++ b/src/test/java/demo/block/CampfireHandler.java @@ -25,8 +25,7 @@ import java.util.List; public class CampfireHandler implements BlockHandler { - public static final Tag> ITEMS = Tag.Custom("Items", new TagSerializer<>() { - + public static final Tag> ITEMS = Tag.View(new TagSerializer<>() { private final Tag internal = Tag.NBT("Items"); @Override @@ -44,7 +43,11 @@ public class CampfireHandler implements BlockHandler { } @Override - public void write(@NotNull TagWritable writer, @NotNull List value) { + public void write(@NotNull TagWritable writer, @Nullable List value) { + if (value == null) { + writer.removeTag(internal); + return; + } NBTList items = new NBTList<>(NBTTypes.TAG_Compound); for (var item : value) { NBTCompound compound = new NBTCompound()