Skip to content

Commit b36b06b

Browse files
committed
Lazily compute NBT
1 parent e1cc6bc commit b36b06b

File tree

25 files changed

+187
-169
lines changed

25 files changed

+187
-169
lines changed

worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitPlayer.java

+7-5
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
import com.sk89q.worldedit.util.formatting.text.adapter.bukkit.TextAdapter;
4040
import com.sk89q.worldedit.util.formatting.text.event.ClickEvent;
4141
import com.sk89q.worldedit.util.formatting.text.format.TextColor;
42+
import com.sk89q.worldedit.util.nbt.CompoundBinaryTag;
4243
import com.sk89q.worldedit.world.World;
4344
import com.sk89q.worldedit.world.block.BaseBlock;
4445
import com.sk89q.worldedit.world.block.BlockStateHolder;
@@ -295,11 +296,12 @@ public <B extends BlockStateHolder<B>> void sendFakeBlock(BlockVector3 pos, B bl
295296
player.sendBlockChange(loc, player.getWorld().getBlockAt(loc).getBlockData());
296297
} else {
297298
player.sendBlockChange(loc, BukkitAdapter.adapt(block));
298-
if (block instanceof BaseBlock && ((BaseBlock) block).hasNbt()) {
299-
BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter();
300-
if (adapter != null) {
301-
if (block.getBlockType() == BlockTypes.STRUCTURE_BLOCK) {
302-
adapter.sendFakeNBT(player, pos, ((BaseBlock) block).getNbt());
299+
BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter();
300+
if (adapter != null) {
301+
if (block.getBlockType() == BlockTypes.STRUCTURE_BLOCK && block instanceof BaseBlock) {
302+
CompoundBinaryTag nbt = ((BaseBlock) block).getNbt();
303+
if (nbt != null) {
304+
adapter.sendFakeNBT(player, pos, nbt);
303305
adapter.sendFakeOP(player);
304306
}
305307
}

worldedit-core/src/main/java/com/sk89q/worldedit/LocalSession.java

+6-3
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
import com.sk89q.worldedit.session.request.Request;
4949
import com.sk89q.worldedit.util.Countable;
5050
import com.sk89q.worldedit.util.SideEffectSet;
51+
import com.sk89q.worldedit.util.concurrency.LazyReference;
5152
import com.sk89q.worldedit.util.formatting.text.TranslatableComponent;
5253
import com.sk89q.worldedit.util.nbt.CompoundBinaryTag;
5354
import com.sk89q.worldedit.world.World;
@@ -802,14 +803,16 @@ public void updateServerCUI(Actor actor) {
802803
}
803804

804805
BaseBlock block = ServerCUIHandler.createStructureBlock(player);
805-
if (block != null && block.hasNbt()) {
806-
// If it's null, we don't need to do anything. The old was already removed.
807-
CompoundBinaryTag tags = block.getNbt();
806+
if (block != null) {
807+
CompoundBinaryTag tags = Objects.requireNonNull(
808+
block.getNbt(), "createStructureBlock should return nbt"
809+
);
808810
BlockVector3 tempCuiTemporaryBlock = BlockVector3.at(
809811
tags.getInt("x"),
810812
tags.getInt("y"),
811813
tags.getInt("z")
812814
);
815+
// If it's null, we don't need to do anything. The old was already removed.
813816
if (cuiTemporaryBlock != null && !tempCuiTemporaryBlock.equals(cuiTemporaryBlock)) {
814817
// Update the existing block if it's the same location
815818
player.sendFakeBlock(cuiTemporaryBlock, null);

worldedit-core/src/main/java/com/sk89q/worldedit/blocks/BaseItem.java

+10-13
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
import com.sk89q.jnbt.CompoundTag;
2323
import com.sk89q.worldedit.WorldEdit;
24+
import com.sk89q.worldedit.util.concurrency.LazyReference;
2425
import com.sk89q.worldedit.util.nbt.CompoundBinaryTag;
2526
import com.sk89q.worldedit.util.nbt.TagStringIO;
2627
import com.sk89q.worldedit.world.NbtValued;
@@ -41,7 +42,7 @@ public class BaseItem implements NbtValued {
4142

4243
private ItemType itemType;
4344
@Nullable
44-
private CompoundBinaryTag nbtData;
45+
private LazyReference<CompoundBinaryTag> nbtData;
4546

4647
/**
4748
* Construct the object.
@@ -61,7 +62,7 @@ public BaseItem(ItemType itemType) {
6162
*/
6263
@Deprecated
6364
public BaseItem(ItemType itemType, @Nullable CompoundTag nbtData) {
64-
this(itemType, nbtData == null ? null : nbtData.asBinaryTag());
65+
this(itemType, nbtData == null ? null : LazyReference.from(nbtData::asBinaryTag));
6566
}
6667

6768
/**
@@ -70,7 +71,7 @@ public BaseItem(ItemType itemType, @Nullable CompoundTag nbtData) {
7071
* @param itemType Type of the item
7172
* @param tag NBT Compound tag
7273
*/
73-
public BaseItem(ItemType itemType, @Nullable CompoundBinaryTag tag) {
74+
public BaseItem(ItemType itemType, @Nullable LazyReference<CompoundBinaryTag> tag) {
7475
checkNotNull(itemType);
7576
this.itemType = itemType;
7677
this.nbtData = tag;
@@ -94,30 +95,26 @@ public void setType(ItemType itemType) {
9495
this.itemType = itemType;
9596
}
9697

97-
@Override
98-
public boolean hasNbt() {
99-
return this.nbtData != null;
100-
}
101-
10298
@Nullable
10399
@Override
104-
public CompoundBinaryTag getNbt() {
100+
public LazyReference<CompoundBinaryTag> getNbtReference() {
105101
return this.nbtData;
106102
}
107103

108104
@Override
109-
public void setNbt(@Nullable CompoundBinaryTag nbtData) {
105+
public void setNbtReference(@Nullable LazyReference<CompoundBinaryTag> nbtData) {
110106
this.nbtData = nbtData;
111107
}
112108

113109
@Override
114110
public String toString() {
115111
String nbtString = "";
116-
if (hasNbt()) {
112+
LazyReference<CompoundBinaryTag> nbtData = this.nbtData;
113+
if (nbtData != null) {
117114
try {
118-
nbtString = TagStringIO.get().asString(nbtData);
115+
nbtString = TagStringIO.get().asString(nbtData.getValue());
119116
} catch (IOException e) {
120-
WorldEdit.logger.error("Failed to parse NBT of Item", e);
117+
WorldEdit.logger.error("Failed to serialize NBT of Item", e);
121118
}
122119
}
123120

worldedit-core/src/main/java/com/sk89q/worldedit/blocks/BaseItemStack.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import com.sk89q.jnbt.CompoundTag;
2323
import com.sk89q.worldedit.WorldEdit;
2424
import com.sk89q.worldedit.extension.platform.Capability;
25+
import com.sk89q.worldedit.util.concurrency.LazyReference;
2526
import com.sk89q.worldedit.util.formatting.text.Component;
2627
import com.sk89q.worldedit.util.nbt.CompoundBinaryTag;
2728
import com.sk89q.worldedit.world.item.ItemType;
@@ -61,7 +62,7 @@ public BaseItemStack(ItemType itemType, int amount) {
6162
* @param id The item type
6263
* @param tag Tag value
6364
* @param amount amount in the stack
64-
* @deprecated Use {@link #BaseItemStack(ItemType, CompoundBinaryTag, int)}
65+
* @deprecated Use {@link #BaseItemStack(ItemType, LazyReference, int)}
6566
*/
6667
@Deprecated
6768
public BaseItemStack(ItemType id, CompoundTag tag, int amount) {
@@ -76,7 +77,7 @@ public BaseItemStack(ItemType id, CompoundTag tag, int amount) {
7677
* @param tag Tag value
7778
* @param amount amount in the stack
7879
*/
79-
public BaseItemStack(ItemType id, CompoundBinaryTag tag, int amount) {
80+
public BaseItemStack(ItemType id, LazyReference<CompoundBinaryTag> tag, int amount) {
8081
super(id, tag);
8182
this.amount = amount;
8283
}

worldedit-core/src/main/java/com/sk89q/worldedit/entity/BaseEntity.java

+8-12
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
package com.sk89q.worldedit.entity;
2121

2222
import com.sk89q.jnbt.CompoundTag;
23+
import com.sk89q.worldedit.util.concurrency.LazyReference;
2324
import com.sk89q.worldedit.util.nbt.CompoundBinaryTag;
2425
import com.sk89q.worldedit.world.NbtValued;
2526
import com.sk89q.worldedit.world.entity.EntityType;
@@ -45,14 +46,14 @@ public class BaseEntity implements NbtValued {
4546

4647
private final EntityType type;
4748
@Nullable
48-
private CompoundBinaryTag nbtData;
49+
private LazyReference<CompoundBinaryTag> nbtData;
4950

5051
/**
5152
* Create a new base entity.
5253
*
5354
* @param type the entity type
5455
* @param nbtData NBT data
55-
* @deprecated Use {@link BaseEntity#BaseEntity(EntityType, CompoundBinaryTag)}
56+
* @deprecated Use {@link BaseEntity#BaseEntity(EntityType, LazyReference)}
5657
*/
5758
@Deprecated
5859
public BaseEntity(EntityType type, CompoundTag nbtData) {
@@ -66,9 +67,9 @@ public BaseEntity(EntityType type, CompoundTag nbtData) {
6667
* @param type the entity type
6768
* @param nbtData NBT data
6869
*/
69-
public BaseEntity(EntityType type, CompoundBinaryTag nbtData) {
70+
public BaseEntity(EntityType type, LazyReference<CompoundBinaryTag> nbtData) {
7071
this(type);
71-
setNbt(nbtData);
72+
setNbtReference(nbtData);
7273
}
7374

7475
/**
@@ -88,22 +89,17 @@ public BaseEntity(EntityType type) {
8889
public BaseEntity(BaseEntity other) {
8990
checkNotNull(other);
9091
this.type = other.getType();
91-
setNbt(other.getNbt());
92-
}
93-
94-
@Override
95-
public boolean hasNbt() {
96-
return true;
92+
setNbtReference(other.getNbtReference());
9793
}
9894

9995
@Nullable
10096
@Override
101-
public CompoundBinaryTag getNbt() {
97+
public LazyReference<CompoundBinaryTag> getNbtReference() {
10298
return nbtData;
10399
}
104100

105101
@Override
106-
public void setNbt(@Nullable CompoundBinaryTag nbtData) {
102+
public void setNbtReference(@Nullable LazyReference<CompoundBinaryTag> nbtData) {
107103
this.nbtData = nbtData;
108104
}
109105

worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/DefaultItemParser.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import com.sk89q.worldedit.extension.platform.Actor;
3131
import com.sk89q.worldedit.internal.registry.InputParser;
3232
import com.sk89q.worldedit.util.HandSide;
33+
import com.sk89q.worldedit.util.concurrency.LazyReference;
3334
import com.sk89q.worldedit.util.formatting.text.TextComponent;
3435
import com.sk89q.worldedit.util.formatting.text.TranslatableComponent;
3536
import com.sk89q.worldedit.util.nbt.CompoundBinaryTag;
@@ -132,7 +133,7 @@ public BaseItem parseFromInput(String input, ParserContext context) throws Input
132133
}
133134
}
134135

135-
item = new BaseItem(itemType, itemNbtData);
136+
item = new BaseItem(itemType, itemNbtData == null ? null : LazyReference.computed(itemNbtData));
136137
}
137138

138139
return item;

worldedit-core/src/main/java/com/sk89q/worldedit/internal/cui/ServerCUIHandler.java

+1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import com.sk89q.worldedit.regions.RegionSelector;
2929
import com.sk89q.worldedit.regions.selector.CuboidRegionSelector;
3030
import com.sk89q.worldedit.util.Location;
31+
import com.sk89q.worldedit.util.concurrency.LazyReference;
3132
import com.sk89q.worldedit.util.nbt.ByteBinaryTag;
3233
import com.sk89q.worldedit.util.nbt.CompoundBinaryTag;
3334
import com.sk89q.worldedit.util.nbt.IntBinaryTag;

worldedit-core/src/main/java/com/sk89q/worldedit/util/collection/Int2BaseBlockMap.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ class Int2BaseBlockMap extends AbstractInt2ObjectMap<BaseBlock> {
5050
* @return the internal ID, or {@link BlockStateIdAccess#invalidId()} if not useful
5151
*/
5252
private static int optimizedInternalId(BaseBlock block) {
53-
if (block.hasNbt()) {
53+
if (block.getNbtReference() != null) {
5454
return BlockStateIdAccess.invalidId();
5555
}
5656
return BlockStateIdAccess.getBlockStateId(block.toImmutableState());

worldedit-core/src/main/java/com/sk89q/worldedit/util/concurrency/LazyReference.java

+15
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,17 @@ public static <T> LazyReference<T> from(Supplier<T> valueComputation) {
3232
return new LazyReference<>(valueComputation);
3333
}
3434

35+
/**
36+
* Pre-computed reference, for setting a lazy reference field with a known value.
37+
*
38+
* @param value the value of the reference
39+
* @param <T> the type of the value
40+
* @return the new reference
41+
*/
42+
public static <T> LazyReference<T> computed(T value) {
43+
return new LazyReference<>(value);
44+
}
45+
3546
// Memory saving technique: hold the computation info in the same reference field that we'll
3647
// put the value into, so the memory possibly retained by those parts is GC'able as soon as
3748
// it's no longer needed.
@@ -51,6 +62,10 @@ private LazyReference(Supplier<T> valueComputation) {
5162
this.value = new RefInfo<>(valueComputation);
5263
}
5364

65+
private LazyReference(T value) {
66+
this.value = value;
67+
}
68+
5469
// casts are safe, value is either RefInfo or T
5570
@SuppressWarnings("unchecked")
5671
public T getValue() {

worldedit-core/src/main/java/com/sk89q/worldedit/util/NbtUtils.java renamed to worldedit-core/src/main/java/com/sk89q/worldedit/util/nbt/NbtUtils.java

+1-4
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,8 @@
1717
* along with this program. If not, see <https://www.gnu.org/licenses/>.
1818
*/
1919

20-
package com.sk89q.worldedit.util;
20+
package com.sk89q.worldedit.util.nbt;
2121

22-
import com.sk89q.worldedit.util.nbt.BinaryTag;
23-
import com.sk89q.worldedit.util.nbt.BinaryTagType;
24-
import com.sk89q.worldedit.util.nbt.CompoundBinaryTag;
2522
import com.sk89q.worldedit.world.storage.InvalidFormatException;
2623

2724
public class NbtUtils {

0 commit comments

Comments
 (0)