Replaced chunk consumers by ChunkCallback and fixed chunk callbacks being called in the block pool when in a batch

This commit is contained in:
themode 2020-09-19 18:35:00 +02:00
parent d80c2e0658
commit c43064c3a0
10 changed files with 50 additions and 33 deletions

View File

@ -44,6 +44,7 @@ import net.minestom.server.utils.BlockPosition;
import net.minestom.server.utils.MathUtils;
import net.minestom.server.utils.Position;
import net.minestom.server.utils.binary.BinaryWriter;
import net.minestom.server.utils.chunk.ChunkCallback;
import net.minestom.server.utils.chunk.ChunkUtils;
import net.minestom.server.utils.validate.Check;
import net.minestom.server.world.DimensionType;
@ -571,7 +572,7 @@ public class Player extends LivingEntity implements CommandSender {
final int chunkX = ChunkUtils.getChunkCoordX(visibleChunk);
final int chunkZ = ChunkUtils.getChunkCoordZ(visibleChunk);
Consumer<Chunk> callback = (chunk) -> {
ChunkCallback callback = (chunk) -> {
if (chunk != null) {
chunk.addViewer(this);
if (chunk.getChunkX() == Math.floorDiv((int) getPosition().getX(), 16) && chunk.getChunkZ() == Math.floorDiv((int) getPosition().getZ(), 16))

View File

@ -1,6 +1,6 @@
package net.minestom.server.instance;
import java.util.function.Consumer;
import net.minestom.server.utils.chunk.ChunkCallback;
/**
* Interface implemented to change the way chunks are loaded/saved
@ -17,7 +17,7 @@ public interface IChunkLoader {
* @param callback the callback executed when the chunk is done loading
* @return true if the chunk loaded successfully, false otherwise
*/
boolean loadChunk(Instance instance, int chunkX, int chunkZ, Consumer<Chunk> callback);
boolean loadChunk(Instance instance, int chunkX, int chunkZ, ChunkCallback callback);
/**
* Save a specific chunk with a callback for when it is done

View File

@ -22,6 +22,7 @@ import net.minestom.server.network.packet.server.play.TimeUpdatePacket;
import net.minestom.server.storage.StorageLocation;
import net.minestom.server.utils.BlockPosition;
import net.minestom.server.utils.Position;
import net.minestom.server.utils.chunk.ChunkCallback;
import net.minestom.server.utils.chunk.ChunkUtils;
import net.minestom.server.utils.time.CooldownUtils;
import net.minestom.server.utils.time.TimeUnit;
@ -125,7 +126,7 @@ public abstract class Instance implements BlockModifier, EventHandler, DataConta
* @param callback consumer called after the chunk has been generated,
* the returned chunk will never be null
*/
public abstract void loadChunk(int chunkX, int chunkZ, Consumer<Chunk> callback);
public abstract void loadChunk(int chunkX, int chunkZ, ChunkCallback callback);
/**
* Load the chunk if the chunk is already loaded or if
@ -136,7 +137,7 @@ public abstract class Instance implements BlockModifier, EventHandler, DataConta
* @param callback consumer called after the chunk has tried to be loaded,
* contains a chunk if it is successful, null otherwise
*/
public abstract void loadOptionalChunk(int chunkX, int chunkZ, Consumer<Chunk> callback);
public abstract void loadOptionalChunk(int chunkX, int chunkZ, ChunkCallback callback);
/**
* Schedule the removal of a chunk, this method does not promise when it will be done
@ -226,9 +227,9 @@ public abstract class Instance implements BlockModifier, EventHandler, DataConta
*/
public abstract void setStorageLocation(StorageLocation storageLocation);
protected abstract void retrieveChunk(int chunkX, int chunkZ, Consumer<Chunk> callback);
protected abstract void retrieveChunk(int chunkX, int chunkZ, ChunkCallback callback);
protected abstract void createChunk(int chunkX, int chunkZ, Consumer<Chunk> callback);
protected abstract void createChunk(int chunkX, int chunkZ, ChunkCallback callback);
/**
* When set to true, chunks will load with players moving closer
@ -489,13 +490,13 @@ public abstract class Instance implements BlockModifier, EventHandler, DataConta
* @param position the chunk position
* @param callback the callback to run when the chunk is loaded
*/
public void loadChunk(Position position, Consumer<Chunk> callback) {
public void loadChunk(Position position, ChunkCallback callback) {
final int chunkX = ChunkUtils.getChunkCoordinate((int) position.getX());
final int chunkZ = ChunkUtils.getChunkCoordinate((int) position.getZ());
loadChunk(chunkX, chunkZ, callback);
}
public void loadOptionalChunk(Position position, Consumer<Chunk> callback) {
public void loadOptionalChunk(Position position, ChunkCallback callback) {
final int chunkX = ChunkUtils.getChunkCoordinate((int) position.getX());
final int chunkZ = ChunkUtils.getChunkCoordinate((int) position.getZ());
loadOptionalChunk(chunkX, chunkZ, callback);

View File

@ -23,6 +23,7 @@ import net.minestom.server.storage.StorageLocation;
import net.minestom.server.utils.BlockPosition;
import net.minestom.server.utils.Position;
import net.minestom.server.utils.block.CustomBlockUtils;
import net.minestom.server.utils.chunk.ChunkCallback;
import net.minestom.server.utils.chunk.ChunkUtils;
import net.minestom.server.utils.thread.MinestomThread;
import net.minestom.server.utils.time.TimeUnit;
@ -38,7 +39,6 @@ import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.function.BiFunction;
import java.util.function.Consumer;
/**
* InstanceContainer is an instance that contains chunks in contrary to SharedInstance.
@ -338,7 +338,7 @@ public class InstanceContainer extends Instance {
}
@Override
public void loadChunk(int chunkX, int chunkZ, Consumer<Chunk> callback) {
public void loadChunk(int chunkX, int chunkZ, ChunkCallback callback) {
final Chunk chunk = getChunk(chunkX, chunkZ);
if (chunk != null) {
// Chunk already loaded
@ -351,7 +351,7 @@ public class InstanceContainer extends Instance {
}
@Override
public void loadOptionalChunk(int chunkX, int chunkZ, Consumer<Chunk> callback) {
public void loadOptionalChunk(int chunkX, int chunkZ, ChunkCallback callback) {
final Chunk chunk = getChunk(chunkX, chunkZ);
if (chunk != null) {
// Chunk already loaded
@ -463,7 +463,7 @@ public class InstanceContainer extends Instance {
}
@Override
protected void retrieveChunk(int chunkX, int chunkZ, Consumer<Chunk> callback) {
protected void retrieveChunk(int chunkX, int chunkZ, ChunkCallback callback) {
final boolean loaded = chunkLoader.loadChunk(this, chunkX, chunkZ, chunk -> {
cacheChunk(chunk);
callChunkLoadEvent(chunkX, chunkZ);
@ -479,7 +479,7 @@ public class InstanceContainer extends Instance {
}
@Override
protected void createChunk(int chunkX, int chunkZ, Consumer<Chunk> callback) {
protected void createChunk(int chunkX, int chunkZ, ChunkCallback callback) {
Biome[] biomes = new Biome[Chunk.BIOME_COUNT];
if (chunkGenerator == null) {
Arrays.fill(biomes, MinecraftServer.getBiomeManager().getById(0));
@ -646,7 +646,9 @@ public class InstanceContainer extends Instance {
// Unload all waiting chunks
UNSAFE_unloadChunks();
// Time/world border
super.tick(time);
Lock wrlock = changingBlockLock.writeLock();
wrlock.lock();
currentlyChangingBlocks.clear();

View File

@ -2,11 +2,10 @@ package net.minestom.server.instance;
import net.minestom.server.reader.ChunkReader;
import net.minestom.server.storage.StorageLocation;
import net.minestom.server.utils.chunk.ChunkCallback;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.function.Consumer;
public class MinestomBasicChunkLoader implements IChunkLoader {
private final static Logger LOGGER = LoggerFactory.getLogger(MinestomBasicChunkLoader.class);
@ -42,7 +41,7 @@ public class MinestomBasicChunkLoader implements IChunkLoader {
}
@Override
public boolean loadChunk(Instance instance, int chunkX, int chunkZ, Consumer<Chunk> callback) {
public boolean loadChunk(Instance instance, int chunkX, int chunkZ, ChunkCallback callback) {
final byte[] bytes = storageLocation == null ? null : storageLocation.get(getChunkKey(chunkX, chunkZ));
if (bytes == null) {

View File

@ -7,11 +7,11 @@ import net.minestom.server.instance.batch.ChunkBatch;
import net.minestom.server.storage.StorageLocation;
import net.minestom.server.utils.BlockPosition;
import net.minestom.server.utils.Position;
import net.minestom.server.utils.chunk.ChunkCallback;
import net.minestom.server.utils.time.TimeUnit;
import java.util.Collection;
import java.util.UUID;
import java.util.function.Consumer;
/**
* The {@link SharedInstance} is an instance that shares the same chunks as its linked {@link InstanceContainer},
@ -37,12 +37,12 @@ public class SharedInstance extends Instance {
}
@Override
public void loadChunk(int chunkX, int chunkZ, Consumer<Chunk> callback) {
public void loadChunk(int chunkX, int chunkZ, ChunkCallback callback) {
instanceContainer.loadChunk(chunkX, chunkZ, callback);
}
@Override
public void loadOptionalChunk(int chunkX, int chunkZ, Consumer<Chunk> callback) {
public void loadOptionalChunk(int chunkX, int chunkZ, ChunkCallback callback) {
instanceContainer.loadOptionalChunk(chunkX, chunkZ, callback);
}
@ -102,12 +102,12 @@ public class SharedInstance extends Instance {
}
@Override
public void retrieveChunk(int chunkX, int chunkZ, Consumer<Chunk> callback) {
public void retrieveChunk(int chunkX, int chunkZ, ChunkCallback callback) {
instanceContainer.retrieveChunk(chunkX, chunkZ, callback);
}
@Override
protected void createChunk(int chunkX, int chunkZ, Consumer<Chunk> callback) {
protected void createChunk(int chunkX, int chunkZ, ChunkCallback callback) {
instanceContainer.createChunk(chunkX, chunkZ, callback);
}

View File

@ -79,9 +79,13 @@ public class BlockBatch implements InstanceBatch {
final boolean isLast = counter.incrementAndGet() == data.size();
// Execute the callback if this was the last chunk to process
if (isLast) {
if (callback != null)
callback.run();
if (callback != null) {
instance.scheduleNextTick(inst -> {
callback.run();
});
}
}
}

View File

@ -7,11 +7,11 @@ import net.minestom.server.instance.ChunkPopulator;
import net.minestom.server.instance.InstanceContainer;
import net.minestom.server.instance.block.CustomBlock;
import net.minestom.server.utils.block.CustomBlockUtils;
import net.minestom.server.utils.chunk.ChunkCallback;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.Consumer;
/**
* Use chunk coordinate (0-16) instead of world's
@ -60,7 +60,7 @@ public class ChunkBatch implements InstanceBatch {
this.dataList.add(blockData);
}
public void flushChunkGenerator(ChunkGenerator chunkGenerator, Consumer<Chunk> callback) {
public void flushChunkGenerator(ChunkGenerator chunkGenerator, ChunkCallback callback) {
batchesPool.execute(() -> {
final List<ChunkPopulator> populators = chunkGenerator.getPopulators();
final boolean hasPopulator = populators != null && !populators.isEmpty();
@ -81,7 +81,7 @@ public class ChunkBatch implements InstanceBatch {
});
}
public void flush(Consumer<Chunk> callback) {
public void flush(ChunkCallback callback) {
batchesPool.execute(() -> {
singleThreadFlush(callback);
});
@ -91,7 +91,7 @@ public class ChunkBatch implements InstanceBatch {
dataList.clear();
}
private void singleThreadFlush(Consumer<Chunk> callback) {
private void singleThreadFlush(ChunkCallback callback) {
synchronized (dataList) {
synchronized (chunk) {
if (!chunk.isLoaded())
@ -104,8 +104,11 @@ public class ChunkBatch implements InstanceBatch {
// Refresh chunk for viewers
chunk.sendChunkUpdate();
if (callback != null)
callback.accept(chunk);
if (callback != null) {
instance.scheduleNextTick(inst -> {
callback.accept(chunk);
});
}
}
}
}

View File

@ -8,12 +8,11 @@ import net.minestom.server.instance.DynamicChunk;
import net.minestom.server.instance.Instance;
import net.minestom.server.instance.batch.ChunkBatch;
import net.minestom.server.utils.binary.BinaryReader;
import net.minestom.server.utils.chunk.ChunkCallback;
import net.minestom.server.utils.chunk.ChunkUtils;
import net.minestom.server.world.biomes.Biome;
import net.minestom.server.world.biomes.BiomeManager;
import java.util.function.Consumer;
public class ChunkReader {
private static final BiomeManager BIOME_MANAGER = MinecraftServer.getBiomeManager();
@ -29,7 +28,7 @@ public class ChunkReader {
* @param chunkZ the chunk Z
* @param callback the consumer called once the chunk has been read
*/
public static void readChunk(byte[] b, Instance instance, int chunkX, int chunkZ, Consumer<Chunk> callback) {
public static void readChunk(byte[] b, Instance instance, int chunkX, int chunkZ, ChunkCallback callback) {
BinaryReader binaryReader = new BinaryReader(b);
// Used for blocks data

View File

@ -0,0 +1,8 @@
package net.minestom.server.utils.chunk;
import net.minestom.server.instance.Chunk;
import java.util.function.Consumer;
public interface ChunkCallback extends Consumer<Chunk> {
}