Prepare potential CAS tag impl

Signed-off-by: TheMode <themode@outlook.fr>
This commit is contained in:
TheMode 2022-04-16 19:15:48 +02:00
parent 49488c4893
commit c5bef0958d
5 changed files with 45 additions and 24 deletions

View File

@ -49,19 +49,25 @@ final class TagHandlerImpl implements TagHandler {
tag.writeUnsafe(viewCompound, value);
updateContent(viewCompound);
} else {
if (value instanceof NBT nbt) {
synchronized (this) {
write(tag, null);
TagNbtSeparator.separate(tag.getKey(), nbt,
entry -> write(entry.tag(), entry.value()));
}
final Entry<?> entry = valueToEntry(tag, value);
updateEntry(tag, entry);
}
}
private <T> Entry<?> valueToEntry(Tag<T> tag, @Nullable T value) {
if (value == null) return null;
if (value instanceof NBT nbt) {
if (nbt instanceof NBTCompound compound) {
final TagHandlerImpl handler = fromCompound(compound);
return new PathEntry(tag.getKey(), handler);
} else {
if (value != null) {
final UnaryOperator<T> copy = tag.copy;
if (copy != null) value = copy.apply(value);
}
write(tag, value);
final var nbtEntry = TagNbtSeparator.separateSingle(tag.getKey(), nbt);
return new TagEntry<>(nbtEntry.tag(), nbtEntry.value());
}
} else {
final UnaryOperator<T> copy = tag.copy;
if (copy != null) value = copy.apply(value);
return new TagEntry<>(tag, value);
}
}
@ -89,7 +95,7 @@ final class TagHandlerImpl implements TagHandler {
return updatedCache().compound;
}
private synchronized <T> void write(@NotNull Tag<T> tag, @Nullable T value) {
private synchronized <T> void updateEntry(@NotNull Tag<T> tag, @Nullable Entry<?> value) {
int tagIndex = tag.index;
TagHandlerImpl local = this;
@ -137,7 +143,7 @@ final class TagHandlerImpl implements TagHandler {
}
}
// Normal tag
if (value != null) local.entries.put(tagIndex, new TagEntry<>(tag, value));
if (value != null) local.entries.put(tagIndex, value);
else local.entries.remove(tagIndex);
this.cache = null;
if (pathHandlers != null) {
@ -262,7 +268,7 @@ final class TagHandlerImpl implements TagHandler {
}
@Override
public NBT updatedNbt() {
public NBTCompound updatedNbt() {
return value.asCompound();
}
}

View File

@ -5,6 +5,7 @@ import org.jglrxavpok.hephaistos.nbt.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Consumer;
import java.util.function.Function;
@ -33,6 +34,18 @@ final class TagNbtSeparator {
convert(new ArrayList<>(), key, nbt, consumer);
}
static Entry separateSingle(String key, NBT nbt) {
assert !(nbt instanceof NBTCompound);
AtomicReference<Entry<?>> entryRef = new AtomicReference<>();
convert(new ArrayList<>(), key, nbt, entry -> {
assert entryRef.getPlain() == null : "Multiple entries found for nbt tag: " + key + " -> " + nbt;
entryRef.setPlain(entry);
});
var entry = entryRef.getPlain();
assert entry != null;
return entry;
}
private static void convert(List<String> path, String key, NBT nbt, Consumer<Entry> consumer) {
if (nbt instanceof NBTByte nbtByte) {
consumer.accept(makeEntry(path, Tag.Byte(key), nbtByte.getValue()));

View File

@ -3,7 +3,8 @@ package net.minestom.server.tag;
import net.kyori.adventure.text.Component;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
public class TagComponentTest {
@ -13,7 +14,7 @@ public class TagComponentTest {
var tag = Tag.Component("component");
var handler = TagHandler.newHandler();
handler.setTag(tag, component);
assertSame(component, handler.getTag(tag));
assertEquals(component, handler.getTag(tag));
}
@Test

View File

@ -8,7 +8,8 @@ import java.lang.ref.WeakReference;
import static net.minestom.server.api.TestUtils.assertEqualsSNBT;
import static net.minestom.server.api.TestUtils.waitUntilCleared;
import static org.junit.jupiter.api.Assertions.*;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
public class TagItemTest {
@ -19,7 +20,7 @@ public class TagItemTest {
var handler = TagHandler.newHandler();
handler.setTag(tag, item);
assertSame(item, handler.getTag(tag));
assertEquals(item, handler.getTag(tag));
}
@Test
@ -37,7 +38,7 @@ public class TagItemTest {
var tag = Tag.ItemStack("item");
var handler = TagHandler.newHandler();
handler.setTag(tag, item);
assertSame(item, handler.getTag(tag));
assertEquals(item, handler.getTag(tag));
handler.setTag(tag, null);
assertNull(handler.getTag(tag));
@ -49,7 +50,7 @@ public class TagItemTest {
var tag = Tag.ItemStack("item");
var handler = TagHandler.newHandler();
handler.setTag(tag, item);
assertSame(item, handler.getTag(tag));
assertEquals(item, handler.getTag(tag));
handler.setTag(tag, null);
var ref = new WeakReference<>(item);
@ -66,9 +67,9 @@ public class TagItemTest {
var tag = Tag.ItemStack("item");
handler.setTag(tag, item);
assertSame(item, handler.getTag(tag));
assertEquals(item, handler.getTag(tag));
handler.setTag(tag, item2);
assertSame(item2, handler.getTag(tag));
assertEquals(item2, handler.getTag(tag));
}
@Test
@ -82,7 +83,7 @@ public class TagItemTest {
// Write the item using the ItemStack tag
{
handler.setTag(itemTag, item);
assertSame(item, handler.getTag(itemTag));
assertEquals(item, handler.getTag(itemTag));
assertEquals(item.toItemNBT(), handler.getTag(nbtTag));
}
// Override it with an NBT tag

View File

@ -16,7 +16,7 @@ public class TagUuidTest {
var tag = Tag.UUID("uuid");
var handler = TagHandler.newHandler();
handler.setTag(tag, uuid);
assertSame(uuid, handler.getTag(tag));
assertEquals(uuid, handler.getTag(tag));
}
@Test