mirror of
https://github.com/Minestom/Minestom.git
synced 2025-02-22 23:31:37 +01:00
Prepare better nbt conversion
Signed-off-by: TheMode <themode@outlook.fr>
This commit is contained in:
parent
c22c4e914a
commit
23e1c8a0bc
@ -247,16 +247,23 @@ public class Tag<T> {
|
||||
return tag(key, Serializers.STRING);
|
||||
}
|
||||
|
||||
public static <T extends NBT> @NotNull Tag<T> NBT(@NotNull String key) {
|
||||
return tag(key, (Serializers.Entry<T, ? extends NBT>) Serializers.NBT_ENTRY);
|
||||
}
|
||||
|
||||
public static @NotNull Tag<ItemStack> ItemStack(@NotNull String key) {
|
||||
return tag(key, Serializers.ITEM);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a wrapper around a compound.
|
||||
* Creates a flexible tag able to read and write any {@link NBT} objects.
|
||||
* <p>
|
||||
* Specialized tags are recommended if the type is known as conversion will be required both way (read and write).
|
||||
*/
|
||||
public static @NotNull Tag<NBT> NBT(@NotNull String key) {
|
||||
return tag(key, Serializers.NBT_ENTRY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a tag containing multiple fields.
|
||||
* <p>
|
||||
* Those fields cannot be modified from an outside tag. (This is to prevent the backed object from becoming out of sync)
|
||||
*
|
||||
* @param key the tag key
|
||||
* @param serializer the tag serializer
|
||||
@ -267,6 +274,11 @@ public class Tag<T> {
|
||||
return fromSerializer(key, serializer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Specialized Structure tag affecting the src of the handler (i.e. overwrite all its data).
|
||||
* <p>
|
||||
* Must be used with care.
|
||||
*/
|
||||
public static <T> @NotNull Tag<T> View(@NotNull TagSerializer<T> serializer) {
|
||||
return Structure("", serializer);
|
||||
}
|
||||
|
@ -28,8 +28,6 @@ public interface TagHandler extends TagReadable, TagWritable {
|
||||
* @return a new tag handler with the content of the given compound
|
||||
*/
|
||||
static @NotNull TagHandler fromCompound(@NotNull NBTCompoundLike compound) {
|
||||
TagHandler handler = newHandler();
|
||||
handler.updateContent(compound);
|
||||
return handler;
|
||||
return TagHandlerImpl.fromCompound(compound);
|
||||
}
|
||||
}
|
||||
|
@ -23,19 +23,40 @@ final class TagHandlerImpl implements TagHandler {
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized <T> void setTag(@NotNull Tag<T> tag, @Nullable T value) {
|
||||
// Convert value to fit the tag (e.g. list copies)
|
||||
if (value != null) {
|
||||
final UnaryOperator<T> copy = tag.copy;
|
||||
if (copy != null) value = copy.apply(value);
|
||||
}
|
||||
// View tag access
|
||||
public <T> void setTag(@NotNull Tag<T> tag, @Nullable T value) {
|
||||
if (tag.isView()) {
|
||||
MutableNBTCompound tmp = new MutableNBTCompound();
|
||||
tag.writeUnsafe(tmp, value);
|
||||
updateContent(tmp);
|
||||
return;
|
||||
MutableNBTCompound viewCompound = new MutableNBTCompound();
|
||||
tag.writeUnsafe(viewCompound, value);
|
||||
updateContent(viewCompound);
|
||||
} else {
|
||||
if (value != null) {
|
||||
final UnaryOperator<T> copy = tag.copy;
|
||||
if (copy != null) value = copy.apply(value);
|
||||
}
|
||||
write(tag, value);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull TagReadable readableCopy() {
|
||||
return updatedCache();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateContent(@NotNull NBTCompoundLike compound) {
|
||||
final TagHandlerImpl converted = fromCompound(compound);
|
||||
synchronized (this) {
|
||||
this.cache = converted.cache;
|
||||
this.entries = converted.entries;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull NBTCompound asCompound() {
|
||||
return updatedCache().compound;
|
||||
}
|
||||
|
||||
public synchronized <T> void write(@NotNull Tag<T> tag, @Nullable T value) {
|
||||
// Normal write
|
||||
int tagIndex = tag.index;
|
||||
TagHandlerImpl local = this;
|
||||
@ -63,7 +84,9 @@ final class TagHandlerImpl implements TagHandler {
|
||||
} else if (entry.value instanceof TagHandlerImpl handler) {
|
||||
// Existing path, continue navigating
|
||||
local = handler;
|
||||
} else throw new IllegalStateException("Cannot set a path-able tag on a non-path-able entry");
|
||||
} else {
|
||||
throw new IllegalStateException("Cannot set a path-able tag on a non-path-able entry: " + entry.value.getClass());
|
||||
}
|
||||
entries = local.entries;
|
||||
pathHandlers[i] = local;
|
||||
}
|
||||
@ -101,35 +124,6 @@ final class TagHandlerImpl implements TagHandler {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull TagReadable readableCopy() {
|
||||
return updatedCache();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateContent(@NotNull NBTCompoundLike compound) {
|
||||
Entry<?>[] entries = new Entry[0];
|
||||
for (var entry : compound) {
|
||||
final String key = entry.getKey();
|
||||
final NBT nbt = entry.getValue();
|
||||
final Tag<NBT> tag = Tag.NBT(key);
|
||||
final int index = tag.index;
|
||||
if (index >= entries.length) {
|
||||
entries = Arrays.copyOf(entries, index + 1);
|
||||
}
|
||||
entries[index] = new Entry<>(tag, nbt);
|
||||
}
|
||||
synchronized (this) {
|
||||
this.cache = null;
|
||||
this.entries = entries;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull NBTCompound asCompound() {
|
||||
return updatedCache().compound;
|
||||
}
|
||||
|
||||
private synchronized Cache updatedCache() {
|
||||
Cache cache = this.cache;
|
||||
if (cache == null) {
|
||||
@ -198,8 +192,7 @@ final class TagHandlerImpl implements TagHandler {
|
||||
if (entry.value instanceof TagHandlerImpl handler) {
|
||||
entries = handler.entries;
|
||||
} else if (entry.updatedNbt() instanceof NBTCompound compound) {
|
||||
var tmp = new TagHandlerImpl();
|
||||
tmp.updateContent(compound);
|
||||
TagHandlerImpl tmp = fromCompound(compound);
|
||||
entries = tmp.entries;
|
||||
}
|
||||
}
|
||||
@ -224,4 +217,14 @@ final class TagHandlerImpl implements TagHandler {
|
||||
return tag.createDefault();
|
||||
}
|
||||
}
|
||||
|
||||
static TagHandlerImpl fromCompound(NBTCompoundLike compound) {
|
||||
TagHandlerImpl handler = new TagHandlerImpl();
|
||||
for (var entry : compound) {
|
||||
final Tag<NBT> tag = Tag.NBT(entry.getKey());
|
||||
final NBT nbt = entry.getValue();
|
||||
handler.setTag(tag, nbt);
|
||||
}
|
||||
return handler;
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
package net.minestom.server.tag;
|
||||
|
||||
import org.jglrxavpok.hephaistos.nbt.NBT;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTCompound;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.Map;
|
||||
@ -16,7 +15,7 @@ public class TagNbtTest {
|
||||
@Test
|
||||
public void compoundRead() {
|
||||
var handler = TagHandler.newHandler();
|
||||
Tag<NBTCompound> nbtTag = Tag.NBT("path1");
|
||||
var nbtTag = Tag.NBT("path1");
|
||||
|
||||
var nbt = NBT.Compound(Map.of("key", NBT.Int(5)));
|
||||
handler.setTag(nbtTag, nbt);
|
||||
@ -29,7 +28,7 @@ public class TagNbtTest {
|
||||
@Test
|
||||
public void doubleCompoundRead() {
|
||||
var handler = TagHandler.newHandler();
|
||||
Tag<NBTCompound> nbtTag = Tag.NBT("path1");
|
||||
var nbtTag = Tag.NBT("path1");
|
||||
|
||||
var nbt = NBT.Compound(Map.of("path2", NBT.Compound(Map.of("key", NBT.Int(5)))));
|
||||
handler.setTag(nbtTag, nbt);
|
||||
|
Loading…
Reference in New Issue
Block a user