mirror of https://github.com/Minestom/Minestom.git
Improving chunk generation performance
This commit is contained in:
parent
d4637f328b
commit
392e702108
|
@ -2,16 +2,18 @@ package net.minestom.server.extras.mojangAuth;
|
|||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.ShortBufferException;
|
||||
|
||||
public class CipherBase {
|
||||
|
||||
private final Cipher cipher;
|
||||
private byte[] inTempArray = new byte[0];
|
||||
private byte[] outTempArray = new byte[0];
|
||||
|
||||
protected CipherBase(Cipher cipher) {
|
||||
protected CipherBase(@NotNull Cipher cipher) {
|
||||
this.cipher = cipher;
|
||||
}
|
||||
|
||||
|
|
|
@ -503,7 +503,7 @@ public class InstanceContainer extends Instance {
|
|||
@Override
|
||||
public ChunkBatch createChunkBatch(@NotNull Chunk chunk) {
|
||||
Check.notNull(chunk, "The chunk of a ChunkBatch cannot be null");
|
||||
return new ChunkBatch(this, chunk);
|
||||
return new ChunkBatch(this, chunk, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -540,7 +540,7 @@ public class InstanceContainer extends Instance {
|
|||
|
||||
if (chunkGenerator != null && chunk.shouldGenerate()) {
|
||||
// Execute the chunk generator to populate the chunk
|
||||
final ChunkBatch chunkBatch = createChunkBatch(chunk);
|
||||
final ChunkBatch chunkBatch = new ChunkBatch(this, chunk, true);
|
||||
|
||||
chunkBatch.flushChunkGenerator(chunkGenerator, callback);
|
||||
} else {
|
||||
|
|
|
@ -31,6 +31,8 @@ public class ChunkBatch implements InstanceBatch {
|
|||
private final InstanceContainer instance;
|
||||
private final Chunk chunk;
|
||||
|
||||
private final boolean generationBatch;
|
||||
|
||||
// Need to be synchronized manually
|
||||
// Format: blockIndex/blockStateId/customBlockId (32/16/16 bits)
|
||||
private final LongList blocks = new LongArrayList();
|
||||
|
@ -39,9 +41,11 @@ public class ChunkBatch implements InstanceBatch {
|
|||
// block index - data
|
||||
private final Int2ObjectMap<Data> blockDataMap = new Int2ObjectOpenHashMap<>();
|
||||
|
||||
public ChunkBatch(@NotNull InstanceContainer instance, @NotNull Chunk chunk) {
|
||||
public ChunkBatch(@NotNull InstanceContainer instance, @NotNull Chunk chunk,
|
||||
boolean generationBatch) {
|
||||
this.instance = instance;
|
||||
this.chunk = chunk;
|
||||
this.generationBatch = generationBatch;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -62,6 +66,10 @@ public class ChunkBatch implements InstanceBatch {
|
|||
}
|
||||
|
||||
private void addBlockData(byte x, int y, byte z, short blockStateId, short customBlockId, @Nullable Data data) {
|
||||
|
||||
if (isGenerationBatch()) {
|
||||
chunk.UNSAFE_setBlock(x, y, z, blockStateId, customBlockId, data, CustomBlockUtils.hasUpdate(customBlockId));
|
||||
} else {
|
||||
final int index = ChunkUtils.getBlockIndex(x, y, z);
|
||||
|
||||
if (data != null) {
|
||||
|
@ -78,6 +86,20 @@ public class ChunkBatch implements InstanceBatch {
|
|||
this.blocks.add(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets if this chunk batch is part of a chunk generation.
|
||||
* <p>
|
||||
* Being a generation batch mean that blocks set are not being stored
|
||||
* but are immediately placed on the chunks. Using less memory
|
||||
* and CPU cycles.
|
||||
*
|
||||
* @return true if this batch is part of a chunk generation
|
||||
*/
|
||||
public boolean isGenerationBatch() {
|
||||
return generationBatch;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to fill the chunk batch.
|
||||
|
@ -92,24 +114,15 @@ public class ChunkBatch implements InstanceBatch {
|
|||
|
||||
chunkGenerator.generateChunkData(this, chunk.getChunkX(), chunk.getChunkZ());
|
||||
|
||||
// Check if there is anything to process
|
||||
if (blocks.isEmpty() && !hasPopulator) {
|
||||
OptionalCallback.execute(callback, chunk);
|
||||
return;
|
||||
}
|
||||
|
||||
singleThreadFlush(hasPopulator ? null : callback, true);
|
||||
|
||||
clearData(); // So the populators won't place those blocks again
|
||||
|
||||
if (hasPopulator) {
|
||||
for (ChunkPopulator chunkPopulator : populators) {
|
||||
chunkPopulator.populateChunk(this, chunk);
|
||||
}
|
||||
singleThreadFlush(callback, true);
|
||||
|
||||
clearData(); // Clear populators blocks
|
||||
}
|
||||
|
||||
instance.scheduleNextTick(inst -> {
|
||||
OptionalCallback.execute(callback, chunk);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -30,7 +30,6 @@ import net.minestom.server.utils.time.TimeUnit;
|
|||
import net.minestom.server.world.DimensionType;
|
||||
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
public class PlayerInit {
|
||||
|
||||
|
@ -44,7 +43,7 @@ public class PlayerInit {
|
|||
NoiseTestGenerator noiseTestGenerator = new NoiseTestGenerator();
|
||||
instanceContainer = MinecraftServer.getInstanceManager().createInstanceContainer(DimensionType.OVERWORLD);
|
||||
instanceContainer.enableAutoChunkLoad(true);
|
||||
instanceContainer.setChunkGenerator(chunkGeneratorDemo);
|
||||
instanceContainer.setChunkGenerator(noiseTestGenerator);
|
||||
|
||||
// Load some chunks beforehand
|
||||
final int loopStart = -3;
|
||||
|
@ -163,8 +162,8 @@ public class PlayerInit {
|
|||
player.addEventCallback(PlayerLoginEvent.class, event -> {
|
||||
|
||||
event.setSpawningInstance(instanceContainer);
|
||||
int x = ThreadLocalRandom.current().nextInt()%10000;
|
||||
player.setRespawnPoint(new Position(x, 64f, 0));
|
||||
//int x = ThreadLocalRandom.current().nextInt()%10000;
|
||||
player.setRespawnPoint(new Position(0, 64f, 0));
|
||||
|
||||
/*player.getInventory().addInventoryCondition((p, slot, clickType, inventoryConditionResult) -> {
|
||||
if (slot == -999)
|
||||
|
|
Loading…
Reference in New Issue