Add shouldLoadChunks in BlockBatch#flush

This commit is contained in:
KrystilizeNevaDies 2021-02-12 10:37:53 +10:00
parent 04c792c302
commit ee8815d2f8

View File

@ -6,6 +6,8 @@ import net.minestom.server.instance.Instance;
import net.minestom.server.instance.InstanceContainer; import net.minestom.server.instance.InstanceContainer;
import net.minestom.server.instance.block.CustomBlock; import net.minestom.server.instance.block.CustomBlock;
import net.minestom.server.utils.block.CustomBlockUtils; import net.minestom.server.utils.block.CustomBlockUtils;
import net.minestom.server.utils.chunk.ChunkUtils;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@ -13,6 +15,7 @@ import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
/** /**
@ -76,44 +79,70 @@ public class BlockBatch implements InstanceBatch {
} }
public void flush(@Nullable Runnable callback) { public void flush(@Nullable Runnable callback) {
this.flush(callback, false);
}
public void flush(@Nullable Runnable callback, boolean shouldLoadChunks) {
synchronized (data) { synchronized (data) {
AtomicInteger counter = new AtomicInteger(); // Load chunks if applicable
for (Map.Entry<Chunk, List<BlockData>> entry : data.entrySet()) { if (shouldLoadChunks) {
final Chunk chunk = entry.getKey();
final List<BlockData> dataList = entry.getValue(); // Get chunks
BLOCK_BATCH_POOL.execute(() -> { Chunk[] chunks = data.keySet().toArray(new Chunk[data.size()]);
synchronized (chunk) {
if (!chunk.isLoaded()) // Get chunk indexs
return; Long[] indexs = new Long[chunks.length];
for (int i = 0; i < chunks.length; i++) {
if (batchOption.isFullChunk()) { indexs[i] = ChunkUtils.getChunkIndex(chunks[i].getChunkX(), chunks[i].getChunkZ());
chunk.reset(); }
}
// Load all chunks + flush block data
for (BlockData data : dataList) { ChunkUtils.optionalLoadAll(instance, null, null, (chunk) -> {
data.apply(chunk); flushBlockData(callback);
} });
} else {
// Refresh chunk for viewers flushBlockData(callback);
if (batchOption.isFullChunk()) { }
chunk.sendChunk(); }
} else { }
chunk.sendChunkUpdate();
} private void flushBlockData(@Nullable Runnable callback) {
AtomicInteger counter = new AtomicInteger();
final boolean isLast = counter.incrementAndGet() == data.size(); for (Map.Entry<Chunk, List<BlockData>> entry : data.entrySet()) {
final Chunk chunk = entry.getKey();
// Execute the callback if this was the last chunk to process final List<BlockData> dataList = entry.getValue();
if (isLast) { BLOCK_BATCH_POOL.execute(() -> {
this.instance.refreshLastBlockChangeTime(); synchronized (chunk) {
if (callback != null) { if (!chunk.isLoaded())
this.instance.scheduleNextTick(inst -> callback.run()); return;
}
}
if (batchOption.isFullChunk()) {
chunk.reset();
} }
});
} for (BlockData data : dataList) {
data.apply(chunk);
}
// Refresh chunk for viewers
if (batchOption.isFullChunk()) {
chunk.sendChunk();
} else {
chunk.sendChunkUpdate();
}
final boolean isLast = counter.incrementAndGet() == data.size();
// Execute the callback if this was the last chunk to process
if (isLast) {
this.instance.refreshLastBlockChangeTime();
if (callback != null) {
this.instance.scheduleNextTick(inst -> callback.run());
}
}
}
});
} }
} }