Fix view tag access

Signed-off-by: TheMode <themode@outlook.fr>
This commit is contained in:
TheMode 2022-04-07 11:34:18 +02:00
parent bbd9e58d35
commit 031d9253a3
6 changed files with 75 additions and 11 deletions

View File

@ -12,6 +12,7 @@ import org.jglrxavpok.hephaistos.nbt.NBTList;
import org.jglrxavpok.hephaistos.nbt.NBTType;
import org.jglrxavpok.hephaistos.nbt.mutable.MutableNBTCompound;
import java.util.Arrays;
import java.util.List;
import java.util.function.Function;
import java.util.function.Supplier;
@ -163,7 +164,9 @@ public class Tag<T> {
}
PathEntry[] pathEntries = new PathEntry[path.length];
for (int i = 0; i < path.length; i++) {
var name = path[i];
final String name = path[i];
if (name == null || name.isEmpty())
throw new IllegalArgumentException("Path must not be empty: " + Arrays.toString(path));
pathEntries[i] = new PathEntry(name, INDEX_MAP.get(name));
}
return new Tag<>(index, key, readComparator, entry, defaultValue, pathEntries, copy, listScope);
@ -244,6 +247,10 @@ public class Tag<T> {
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.
*
@ -256,17 +263,19 @@ public class Tag<T> {
return fromSerializer(key, serializer);
}
@ApiStatus.Experimental
public static <T extends Record> @NotNull Tag<T> Structure(@NotNull String key, @NotNull Class<T> type) {
assert type.isRecord();
return fromSerializer(key, TagRecord.serializer(type));
}
public static <T> @NotNull Tag<T> View(@NotNull TagSerializer<T> serializer) {
return Structure("", serializer);
}
public static @NotNull Tag<ItemStack> ItemStack(@NotNull String key) {
return tag(key, Serializers.ITEM);
@ApiStatus.Experimental
public static <T extends Record> @NotNull Tag<T> Structure(@NotNull String key, @NotNull Class<T> type) {
assert type.isRecord();
return Structure(key, TagRecord.serializer(type));
}
@ApiStatus.Experimental
public static <T extends Record> @NotNull Tag<T> View(@NotNull Class<T> type) {
assert type.isRecord();
return View(TagRecord.serializer(type));
}
}

View File

@ -18,6 +18,7 @@ final class TagHandlerImpl implements TagHandler {
@Override
public <T> @UnknownNullability T getTag(@NotNull Tag<T> tag) {
if (tag.getKey().isEmpty()) return tag.read(asCompound());
return read(entries, tag);
}
@ -28,7 +29,14 @@ final class TagHandlerImpl implements TagHandler {
final UnaryOperator<T> copy = tag.copy;
if (copy != null) value = copy.apply(value);
}
// View tag access
if (tag.getKey().isEmpty()) {
MutableNBTCompound tmp = new MutableNBTCompound();
tag.writeUnsafe(tmp, value);
updateContent(tmp);
return;
}
// Normal write
int tagIndex = tag.index;
TagHandlerImpl local = this;
Entry<?>[] entries = this.entries;
@ -171,6 +179,7 @@ final class TagHandlerImpl implements TagHandler {
@Override
public <T> @UnknownNullability T getTag(@NotNull Tag<T> tag) {
if (tag.getKey().isEmpty()) return tag.read(compound);
return read(entries, tag);
}
}

View File

@ -58,7 +58,7 @@ final class TagRecord {
}
};
public static <T extends Record> @NotNull Serializer<T> serializer(@NotNull Class<T> type) {
static <T extends Record> @NotNull Serializer<T> serializer(@NotNull Class<T> type) {
//noinspection unchecked
return (Serializer<T>) serializers.get(type);
}

View File

@ -27,6 +27,12 @@ public class TagPathTest {
assertNull(handler.getTag(tag));
}
@Test
public void invalidPath() {
assertThrows(IllegalArgumentException.class, () -> Tag.Integer("number").path(""));
assertThrows(IllegalArgumentException.class, () -> Tag.Integer("number").path("path", null));
}
@Test
public void emptyRemoval() {
var handler = TagHandler.newHandler();

View File

@ -25,6 +25,27 @@ public class TagRecordTest {
assertEquals(vec, handler.getTag(tag));
}
@Test
public void fromNBT() {
var vecCompound = NBT.Compound(Map.of(
"x", NBT.Double(1),
"y", NBT.Double(2),
"z", NBT.Double(3)));
var handler = TagHandler.fromCompound(NBT.Compound(Map.of("vec", vecCompound)));
var tag = Tag.Structure("vec", Vec.class);
assertEquals(new Vec(1, 2, 3), handler.getTag(tag));
}
@Test
public void fromNBTView() {
var handler = TagHandler.fromCompound(NBT.Compound(Map.of(
"x", NBT.Double(1),
"y", NBT.Double(2),
"z", NBT.Double(3))));
var tag = Tag.View(Vec.class);
assertEquals(new Vec(1, 2, 3), handler.getTag(tag));
}
@Test
public void basicSerializer() {
var handler = TagHandler.newHandler();

View File

@ -58,4 +58,23 @@ public class TagViewTest {
assertEqualsSNBT("{}", handler.asCompound());
}
@Test
public void snbtOverride() {
var handler = TagHandler.newHandler();
var entry = new Entry("hello");
handler.setTag(VIEW_TAG, entry);
assertEqualsSNBT("""
{
"value":"hello"
}
""", handler.asCompound());
handler.setTag(Tag.Integer("value"), 5);
assertEqualsSNBT("""
{
"value":5,
}
""", handler.asCompound());
}
}