diff --git a/src/main/java/net/minestom/server/tag/Tag.java b/src/main/java/net/minestom/server/tag/Tag.java index 71196ead1..aea8d0b61 100644 --- a/src/main/java/net/minestom/server/tag/Tag.java +++ b/src/main/java/net/minestom/server/tag/Tag.java @@ -129,10 +129,15 @@ public class Tag { }, null, path, copy != null ? ts -> { T[] array = (T[]) new Object[ts.size()]; + boolean shallowCopy = true; for (int i = 0; i < ts.size(); i++) { - array[i] = copy.apply(ts.get(i)); + T t = ts.get(i); + array[i] = copy.apply(t); + if (shallowCopy && array[i] != t) { + shallowCopy = false; + } } - return List.of(array); + return shallowCopy ? List.copyOf(ts) : List.of(array); } : List::copyOf); } diff --git a/src/test/java/net/minestom/server/tag/TagListTest.java b/src/test/java/net/minestom/server/tag/TagListTest.java index f81c2ee87..c7ab7c855 100644 --- a/src/test/java/net/minestom/server/tag/TagListTest.java +++ b/src/test/java/net/minestom/server/tag/TagListTest.java @@ -26,6 +26,41 @@ public class TagListTest { assertNull(handler.getTag(tag)); } + @Test + public void cache() { + var handler = TagHandler.newHandler(); + var tag = Tag.Integer("number").list(); + var val = List.of(1, 2, 3); + + handler.setTag(tag, val); + assertSame(val, handler.getTag(tag)); + } + + @Test + public void recursiveCache() { + var handler = TagHandler.newHandler(); + var tag = Tag.Integer("number").list().list(); + var val = List.of(List.of(1, 2, 3), List.of(4, 5, 6)); + + handler.setTag(tag, val); + assertSame(val.get(0), handler.getTag(tag).get(0)); + assertSame(val.get(1), handler.getTag(tag).get(1)); + assertSame(val, handler.getTag(tag)); + } + + @Test + public void recursiveCacheIncorrect() { + var handler = TagHandler.newHandler(); + var tag = Tag.Integer("number").list().list(); + var val = List.of(List.of(1, 2, 3), new ArrayList<>(Arrays.asList(4, 5, 6))); + + handler.setTag(tag, val); + assertSame(val.get(0), handler.getTag(tag).get(0)); + assertNotSame(val.get(1), handler.getTag(tag).get(1)); + assertNotSame(val, handler.getTag(tag)); + assertEquals(val, handler.getTag(tag)); + } + @Test public void snbt() { var handler = TagHandler.newHandler();