diff --git a/src/main/java/net/minestom/server/instance/batch/ChunkBatch.java b/src/main/java/net/minestom/server/instance/batch/ChunkBatch.java index a8d2240a4..f6d2a7020 100644 --- a/src/main/java/net/minestom/server/instance/batch/ChunkBatch.java +++ b/src/main/java/net/minestom/server/instance/batch/ChunkBatch.java @@ -4,9 +4,6 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import it.unimi.dsi.fastutil.ints.IntArraySet; import it.unimi.dsi.fastutil.ints.IntSet; -import it.unimi.dsi.fastutil.longs.LongArrayList; -import it.unimi.dsi.fastutil.longs.LongList; -import net.minestom.server.data.Data; import net.minestom.server.instance.Chunk; import net.minestom.server.instance.Instance; import net.minestom.server.instance.InstanceContainer; @@ -39,14 +36,7 @@ public class ChunkBatch implements Batch { private static final Logger LOGGER = LoggerFactory.getLogger(ChunkBatch.class); - // Need to be synchronized manually - // Format: blockIndex/blockStateId/customBlockId (32/16/16 bits) - private final LongList blocks; - - // Need to be synchronized manually - // block index - data - private final Int2ObjectMap blockDataMap; - + private final Int2ObjectMap blocks = new Int2ObjectOpenHashMap<>(); // Available for other implementations to handle. protected final CountDownLatch readyLatch; private final BatchOption options; @@ -56,41 +46,20 @@ public class ChunkBatch implements Batch { } public ChunkBatch(BatchOption options) { - this(new LongArrayList(), new Int2ObjectOpenHashMap<>(), options); + this(options, true); } - protected ChunkBatch(LongList blocks, Int2ObjectMap blockDataMap, BatchOption options) { - this(blocks, blockDataMap, options, true); - } - - private ChunkBatch(LongList blocks, Int2ObjectMap blockDataMap, BatchOption options, boolean ready) { - this.blocks = blocks; - this.blockDataMap = blockDataMap; - + private ChunkBatch(BatchOption options, boolean ready) { this.readyLatch = new CountDownLatch(ready ? 0 : 1); this.options = options; } @Override public void setBlock(int x, int y, int z, @NotNull Block block) { - final short blockStateId = block.getStateId(); - // TODO other ids - - // Cache the entry to be placed later during flush final int index = ChunkUtils.getBlockIndex(x, y, z); - long value = index; - value = (value << 16) | blockStateId; - //value = (value << 16) | customBlockId; - synchronized (blocks) { - this.blocks.add(value); + this.blocks.put(index, block); } - - /*if (data != null) { - synchronized (blockDataMap) { - this.blockDataMap.put(index, data); - } - }*/ } @Override @@ -185,7 +154,7 @@ public class ChunkBatch implements Batch { boolean safeCallback) { if (!this.options.isUnsafeApply()) this.awaitReady(); - final ChunkBatch inverse = this.options.shouldCalculateInverse() ? new ChunkBatch(new LongArrayList(), new Int2ObjectOpenHashMap<>(), options, false) : null; + final ChunkBatch inverse = this.options.shouldCalculateInverse() ? new ChunkBatch(options, false) : null; BLOCK_BATCH_POOL.execute(() -> singleThreadFlush(instance, chunk, inverse, callback, safeCallback)); return inverse; } @@ -202,18 +171,23 @@ public class ChunkBatch implements Batch { return; } - if (this.options.isFullChunk()) + if (this.options.isFullChunk()) { + // Clear the chunk chunk.reset(); + } if (blocks.isEmpty()) { + // Nothing to flush OptionalCallback.execute(callback, chunk); return; } final IntSet sections = new IntArraySet(); synchronized (blocks) { - for (long block : blocks) { - final int section = apply(chunk, block, inverse); + for (var entry : blocks.int2ObjectEntrySet()) { + final int position = entry.getIntKey(); + final Block block = entry.getValue(); + final int section = apply(chunk, position, block, inverse); sections.add(section); } } @@ -229,33 +203,18 @@ public class ChunkBatch implements Batch { * Applies a single block change given a chunk and a value in the described format. * * @param chunk The chunk to apply the change - * @param value block index|state id|custom block id (32|16|16 bits) + * @param index the block position computed using {@link ChunkUtils#getBlockIndex(int, int, int)} + * @param block the block to place * @return The chunk section which the block was placed */ - private int apply(@NotNull Chunk chunk, long value, @Nullable ChunkBatch inverse) { - final short customBlockId = (short) (value & 0xFFFF); - final short blockId = (short) ((value >> 16) & 0xFFFF); - final int index = (int) ((value >> 32) & 0xFFFFFFFFL); - - Data data = null; - if (!blockDataMap.isEmpty()) { - synchronized (blockDataMap) { - data = blockDataMap.get(index); - } - } - + private int apply(@NotNull Chunk chunk, int index, Block block, @Nullable ChunkBatch inverse) { final int x = ChunkUtils.blockIndexToChunkPositionX(index); final int y = ChunkUtils.blockIndexToChunkPositionY(index); final int z = ChunkUtils.blockIndexToChunkPositionZ(index); - if (inverse != null) { Block prevBlock = chunk.getBlock(x, y, z); inverse.setBlock(x, y, z, prevBlock); } - - Block block = Block.fromStateId(blockId); - // TODO other data - chunk.UNSAFE_setBlock(x, y, z, block); return ChunkUtils.getSectionAt(y); } diff --git a/src/main/java/net/minestom/server/instance/batch/ChunkGenerationBatch.java b/src/main/java/net/minestom/server/instance/batch/ChunkGenerationBatch.java index 8137ac3b4..d66e3a710 100644 --- a/src/main/java/net/minestom/server/instance/batch/ChunkGenerationBatch.java +++ b/src/main/java/net/minestom/server/instance/batch/ChunkGenerationBatch.java @@ -13,8 +13,7 @@ public class ChunkGenerationBatch extends ChunkBatch { private final Chunk chunk; public ChunkGenerationBatch(InstanceContainer instance, Chunk chunk) { - super(null, null, new BatchOption()); - + super(new BatchOption()); this.instance = instance; this.chunk = chunk; }