2020-04-24 03:25:58 +02:00
|
|
|
package net.minestom.server.instance.batch;
|
2019-08-12 13:27:24 +02:00
|
|
|
|
2020-04-24 03:25:58 +02:00
|
|
|
import net.minestom.server.data.Data;
|
|
|
|
import net.minestom.server.instance.Chunk;
|
|
|
|
import net.minestom.server.instance.InstanceContainer;
|
|
|
|
import net.minestom.server.utils.SerializerUtils;
|
2019-09-07 11:42:33 +02:00
|
|
|
|
2019-08-12 13:27:24 +02:00
|
|
|
import java.util.ArrayList;
|
|
|
|
import java.util.HashMap;
|
|
|
|
import java.util.List;
|
|
|
|
import java.util.Map;
|
|
|
|
|
2020-03-29 20:58:30 +02:00
|
|
|
public class BlockBatch implements InstanceBatch {
|
2019-08-12 13:27:24 +02:00
|
|
|
|
2019-08-24 20:34:01 +02:00
|
|
|
private InstanceContainer instance;
|
2019-08-12 13:27:24 +02:00
|
|
|
|
|
|
|
private Map<Chunk, List<BlockData>> data = new HashMap<>();
|
|
|
|
|
2019-08-24 20:34:01 +02:00
|
|
|
public BlockBatch(InstanceContainer instance) {
|
2019-08-12 13:27:24 +02:00
|
|
|
this.instance = instance;
|
|
|
|
}
|
|
|
|
|
2019-08-19 17:04:19 +02:00
|
|
|
@Override
|
2019-09-23 19:56:08 +02:00
|
|
|
public void setBlock(int x, int y, int z, short blockId, Data data) {
|
|
|
|
synchronized (this) {
|
|
|
|
Chunk chunk = this.instance.getChunkAt(x, z);
|
2020-02-09 15:34:09 +01:00
|
|
|
addBlockData(chunk, x, y, z, false, blockId, data);
|
2019-09-23 19:56:08 +02:00
|
|
|
}
|
2019-08-12 13:27:24 +02:00
|
|
|
}
|
|
|
|
|
2019-08-19 17:04:19 +02:00
|
|
|
@Override
|
2019-09-15 13:42:36 +02:00
|
|
|
public void setCustomBlock(int x, int y, int z, short blockId, Data data) {
|
2019-09-23 19:56:08 +02:00
|
|
|
synchronized (this) {
|
|
|
|
Chunk chunk = this.instance.getChunkAt(x, z);
|
2020-02-09 15:34:09 +01:00
|
|
|
addBlockData(chunk, x, y, z, true, blockId, data);
|
|
|
|
}
|
|
|
|
}
|
2019-08-19 17:04:19 +02:00
|
|
|
|
2020-02-09 15:34:09 +01:00
|
|
|
private void addBlockData(Chunk chunk, int x, int y, int z, boolean customBlock, short blockId, Data data) {
|
|
|
|
List<BlockData> blocksData = this.data.get(chunk);
|
|
|
|
if (blocksData == null)
|
|
|
|
blocksData = new ArrayList<>();
|
2019-08-19 17:04:19 +02:00
|
|
|
|
2020-02-09 15:34:09 +01:00
|
|
|
BlockData blockData = new BlockData();
|
|
|
|
blockData.x = x % 16;
|
|
|
|
blockData.y = y;
|
|
|
|
blockData.z = z % 16;
|
|
|
|
blockData.isCustomBlock = customBlock;
|
|
|
|
blockData.blockId = blockId;
|
|
|
|
blockData.data = data;
|
2019-08-19 17:04:19 +02:00
|
|
|
|
2020-02-09 15:34:09 +01:00
|
|
|
blocksData.add(blockData);
|
|
|
|
|
|
|
|
this.data.put(chunk, blocksData);
|
2019-08-19 17:04:19 +02:00
|
|
|
}
|
|
|
|
|
2019-08-27 05:23:25 +02:00
|
|
|
public void flush(Runnable callback) {
|
|
|
|
int counter = 0;
|
2019-08-12 13:27:24 +02:00
|
|
|
for (Map.Entry<Chunk, List<BlockData>> entry : data.entrySet()) {
|
2019-08-27 05:23:25 +02:00
|
|
|
counter++;
|
2019-08-12 13:27:24 +02:00
|
|
|
Chunk chunk = entry.getKey();
|
|
|
|
List<BlockData> dataList = entry.getValue();
|
2019-08-27 05:23:25 +02:00
|
|
|
boolean isLast = counter == data.size();
|
2019-08-24 20:34:01 +02:00
|
|
|
batchesPool.execute(() -> {
|
2019-08-22 14:52:32 +02:00
|
|
|
synchronized (chunk) {
|
2019-08-12 13:27:24 +02:00
|
|
|
for (BlockData data : dataList) {
|
|
|
|
data.apply(chunk);
|
|
|
|
}
|
2019-08-27 05:23:25 +02:00
|
|
|
chunk.refreshDataPacket();
|
|
|
|
instance.sendChunkUpdate(chunk);
|
2019-08-27 20:49:11 +02:00
|
|
|
if (isLast) {
|
|
|
|
// data.clear();
|
|
|
|
if (callback != null)
|
|
|
|
callback.run();
|
|
|
|
}
|
2019-08-22 14:52:32 +02:00
|
|
|
}
|
|
|
|
});
|
2019-08-12 13:27:24 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private class BlockData {
|
|
|
|
|
|
|
|
private int x, y, z;
|
2019-09-14 19:27:25 +02:00
|
|
|
private boolean isCustomBlock;
|
2019-08-18 20:38:09 +02:00
|
|
|
private short blockId;
|
2019-09-15 13:42:36 +02:00
|
|
|
private Data data;
|
2019-08-12 13:27:24 +02:00
|
|
|
|
|
|
|
public void apply(Chunk chunk) {
|
2020-04-05 17:46:29 +02:00
|
|
|
int index = SerializerUtils.chunkCoordToIndex((byte) x, (byte) y, (byte) z);
|
2019-09-14 19:27:25 +02:00
|
|
|
if (!isCustomBlock) {
|
2020-04-05 17:46:29 +02:00
|
|
|
chunk.UNSAFE_setBlock(index, blockId, data);
|
2019-08-19 17:04:19 +02:00
|
|
|
} else {
|
2020-04-05 17:46:29 +02:00
|
|
|
chunk.UNSAFE_setCustomBlock(index, blockId, data);
|
2019-08-19 17:04:19 +02:00
|
|
|
}
|
2019-08-12 13:27:24 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|