mirror of
https://github.com/Minestom/Minestom.git
synced 2025-01-19 14:41:34 +01:00
Optimize thread providers
This commit is contained in:
parent
1d047b5de3
commit
0d4689a367
@ -52,7 +52,10 @@ public final class UpdateManager {
|
|||||||
final long time = System.currentTimeMillis();
|
final long time = System.currentTimeMillis();
|
||||||
|
|
||||||
// Server tick (instance/chunk/entity)
|
// Server tick (instance/chunk/entity)
|
||||||
|
// Synchronize with the update manager instance, like the signal for chunk load/unload
|
||||||
|
synchronized (this) {
|
||||||
threadProvider.update(time);
|
threadProvider.update(time);
|
||||||
|
}
|
||||||
|
|
||||||
// Waiting players update (newly connected waiting to get into the server)
|
// Waiting players update (newly connected waiting to get into the server)
|
||||||
entityManager.updateWaitingPlayers();
|
entityManager.updateWaitingPlayers();
|
||||||
|
@ -16,7 +16,7 @@ public abstract class DataType<T> {
|
|||||||
/**
|
/**
|
||||||
* Decode the data type
|
* Decode the data type
|
||||||
*
|
*
|
||||||
* @param packetReader the data readerr
|
* @param packetReader the data reader
|
||||||
* @return the decoded value
|
* @return the decoded value
|
||||||
*/
|
*/
|
||||||
public abstract T decode(PacketReader packetReader);
|
public abstract T decode(PacketReader packetReader);
|
||||||
|
@ -5,18 +5,19 @@ import net.minestom.server.inventory.Inventory;
|
|||||||
import net.minestom.server.inventory.InventoryType;
|
import net.minestom.server.inventory.InventoryType;
|
||||||
import net.minestom.server.network.packet.PacketReader;
|
import net.minestom.server.network.packet.PacketReader;
|
||||||
import net.minestom.server.network.packet.PacketWriter;
|
import net.minestom.server.network.packet.PacketWriter;
|
||||||
import org.jglrxavpok.hephaistos.nbt.NBTException;
|
|
||||||
|
|
||||||
public class InventoryData extends DataType<Inventory> {
|
public class InventoryData extends DataType<Inventory> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void encode(PacketWriter packetWriter, Inventory value) {
|
public void encode(PacketWriter packetWriter, Inventory value) {
|
||||||
InventoryType inventoryType = value.getInventoryType();
|
final InventoryType inventoryType = value.getInventoryType();
|
||||||
int size = inventoryType.getAdditionalSlot();
|
final int size = inventoryType.getAdditionalSlot();
|
||||||
|
|
||||||
|
// Inventory title & type
|
||||||
packetWriter.writeSizedString(value.getTitle());
|
packetWriter.writeSizedString(value.getTitle());
|
||||||
packetWriter.writeSizedString(inventoryType.name());
|
packetWriter.writeSizedString(inventoryType.name());
|
||||||
|
|
||||||
|
// Write all item stacks
|
||||||
for (int i = 0; i < size; i++) {
|
for (int i = 0; i < size; i++) {
|
||||||
packetWriter.writeItemStack(value.getItemStack(i));
|
packetWriter.writeItemStack(value.getItemStack(i));
|
||||||
}
|
}
|
||||||
@ -24,12 +25,13 @@ public class InventoryData extends DataType<Inventory> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Inventory decode(PacketReader packetReader) {
|
public Inventory decode(PacketReader packetReader) {
|
||||||
String title = packetReader.readSizedString();
|
final String title = packetReader.readSizedString();
|
||||||
InventoryType inventoryType = InventoryType.valueOf(packetReader.readSizedString());
|
final InventoryType inventoryType = InventoryType.valueOf(packetReader.readSizedString());
|
||||||
int size = inventoryType.getAdditionalSlot();
|
final int size = inventoryType.getAdditionalSlot();
|
||||||
|
|
||||||
Inventory inventory = new Inventory(inventoryType, title);
|
Inventory inventory = new Inventory(inventoryType, title);
|
||||||
|
|
||||||
|
// Read all item stacks
|
||||||
for (int i = 0; i < size; i++) {
|
for (int i = 0; i < size; i++) {
|
||||||
inventory.setItemStack(i, packetReader.readSlot());
|
inventory.setItemStack(i, packetReader.readSlot());
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,6 @@ import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
|
|||||||
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
|
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
|
||||||
import it.unimi.dsi.fastutil.longs.LongArraySet;
|
import it.unimi.dsi.fastutil.longs.LongArraySet;
|
||||||
import it.unimi.dsi.fastutil.longs.LongSet;
|
import it.unimi.dsi.fastutil.longs.LongSet;
|
||||||
import net.minestom.server.instance.Chunk;
|
|
||||||
import net.minestom.server.instance.Instance;
|
import net.minestom.server.instance.Instance;
|
||||||
import net.minestom.server.utils.chunk.ChunkUtils;
|
import net.minestom.server.utils.chunk.ChunkUtils;
|
||||||
|
|
||||||
@ -22,12 +21,12 @@ public class PerGroupChunkProvider extends ThreadProvider {
|
|||||||
/**
|
/**
|
||||||
* Chunk -> its chunk group
|
* Chunk -> its chunk group
|
||||||
*/
|
*/
|
||||||
private Map<Instance, Long2ObjectMap<LongSet>> instanceChunksGroupMap = new ConcurrentHashMap<>();
|
private final Map<Instance, Long2ObjectMap<LongSet>> instanceChunksGroupMap = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used to know to which instance is linked a Set of chunks
|
* Used to know to which instance is linked a Set of chunks
|
||||||
*/
|
*/
|
||||||
private Map<Instance, Map<LongSet, Instance>> instanceInstanceMap = new ConcurrentHashMap<>();
|
private final Map<Instance, Map<LongSet, Instance>> instanceInstanceMap = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onChunkLoad(Instance instance, int chunkX, int chunkZ) {
|
public void onChunkLoad(Instance instance, int chunkX, int chunkZ) {
|
||||||
@ -107,18 +106,14 @@ public class PerGroupChunkProvider extends ThreadProvider {
|
|||||||
@Override
|
@Override
|
||||||
public void update(long time) {
|
public void update(long time) {
|
||||||
// Set of already-updated instances this tick
|
// Set of already-updated instances this tick
|
||||||
final Set<Instance> updatedInstance = new HashSet<>();
|
Set<Instance> updatedInstance = new HashSet<>();
|
||||||
|
|
||||||
instanceInstanceMap.entrySet().forEach(entry -> {
|
|
||||||
final Instance instance = entry.getKey();
|
|
||||||
final Map<LongSet, Instance> instanceMap = entry.getValue();
|
|
||||||
|
|
||||||
|
instanceInstanceMap.forEach((instance, instanceMap) -> {
|
||||||
// True if the instance ended its tick call
|
// True if the instance ended its tick call
|
||||||
AtomicBoolean instanceUpdated = new AtomicBoolean(false);
|
AtomicBoolean instanceUpdated = new AtomicBoolean(false);
|
||||||
|
|
||||||
// Update all the chunks + instances
|
// Update all the chunks + instances
|
||||||
for (Map.Entry<LongSet, Instance> ent : instanceMap.entrySet()) {
|
instanceMap.keySet().forEach(chunksIndexes -> {
|
||||||
final LongSet chunksIndexes = ent.getKey();
|
|
||||||
|
|
||||||
final boolean shouldUpdateInstance = updatedInstance.add(instance);
|
final boolean shouldUpdateInstance = updatedInstance.add(instance);
|
||||||
pool.execute(() -> {
|
pool.execute(() -> {
|
||||||
@ -133,21 +128,11 @@ public class PerGroupChunkProvider extends ThreadProvider {
|
|||||||
while (!instanceUpdated.get()) {
|
while (!instanceUpdated.get()) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (long chunkIndex : chunksIndexes) {
|
// Tick all this chunk group
|
||||||
final int[] chunkCoordinates = ChunkUtils.getChunkCoord(chunkIndex);
|
chunksIndexes.forEach((long chunkIndex) -> processChunkTick(instance, chunkIndex, time));
|
||||||
final Chunk chunk = instance.getChunk(chunkCoordinates[0], chunkCoordinates[1]);
|
|
||||||
if (!ChunkUtils.isLoaded(chunk)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
updateChunk(instance, chunk, time);
|
|
||||||
|
|
||||||
updateEntities(instance, chunk, time);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,7 +2,6 @@ package net.minestom.server.thread;
|
|||||||
|
|
||||||
import it.unimi.dsi.fastutil.longs.LongArraySet;
|
import it.unimi.dsi.fastutil.longs.LongArraySet;
|
||||||
import it.unimi.dsi.fastutil.longs.LongSet;
|
import it.unimi.dsi.fastutil.longs.LongSet;
|
||||||
import net.minestom.server.instance.Chunk;
|
|
||||||
import net.minestom.server.instance.Instance;
|
import net.minestom.server.instance.Instance;
|
||||||
import net.minestom.server.utils.chunk.ChunkUtils;
|
import net.minestom.server.utils.chunk.ChunkUtils;
|
||||||
|
|
||||||
@ -35,26 +34,14 @@ public class PerInstanceThreadProvider extends ThreadProvider {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update(long time) {
|
public void update(long time) {
|
||||||
for (Map.Entry<Instance, LongSet> entry : instanceChunkMap.entrySet()) {
|
instanceChunkMap.forEach((instance, chunkIndexes) -> {
|
||||||
final Instance instance = entry.getKey();
|
|
||||||
final LongSet chunkIndexes = entry.getValue();
|
|
||||||
|
|
||||||
pool.execute(() -> {
|
pool.execute(() -> {
|
||||||
|
// Tick instance
|
||||||
updateInstance(instance, time);
|
updateInstance(instance, time);
|
||||||
|
// Tick chunks
|
||||||
for (long chunkIndex : chunkIndexes) {
|
chunkIndexes.forEach((long chunkIndex) -> processChunkTick(instance, chunkIndex, time));
|
||||||
final int[] chunkCoordinates = ChunkUtils.getChunkCoord(chunkIndex);
|
});
|
||||||
final Chunk chunk = instance.getChunk(chunkCoordinates[0], chunkCoordinates[1]);
|
|
||||||
if (!ChunkUtils.isLoaded(chunk))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
updateChunk(instance, chunk, time);
|
|
||||||
|
|
||||||
updateEntities(instance, chunk, time);
|
|
||||||
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private LongSet getChunkCoordinates(Instance instance) {
|
private LongSet getChunkCoordinates(Instance instance) {
|
||||||
|
@ -4,6 +4,7 @@ import net.minestom.server.MinecraftServer;
|
|||||||
import net.minestom.server.entity.*;
|
import net.minestom.server.entity.*;
|
||||||
import net.minestom.server.instance.Chunk;
|
import net.minestom.server.instance.Chunk;
|
||||||
import net.minestom.server.instance.Instance;
|
import net.minestom.server.instance.Instance;
|
||||||
|
import net.minestom.server.utils.chunk.ChunkUtils;
|
||||||
import net.minestom.server.utils.thread.MinestomThread;
|
import net.minestom.server.utils.thread.MinestomThread;
|
||||||
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@ -82,6 +83,24 @@ public abstract class ThreadProvider {
|
|||||||
* INSTANCE UPDATE
|
* INSTANCE UPDATE
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process a whole tick for a chunk
|
||||||
|
*
|
||||||
|
* @param instance the instance of the chunk
|
||||||
|
* @param chunkIndex the index of the chunk {@link ChunkUtils#getChunkIndex(int, int)}
|
||||||
|
* @param time the time of the update in milliseconds
|
||||||
|
*/
|
||||||
|
protected void processChunkTick(Instance instance, long chunkIndex, long time) {
|
||||||
|
final int[] chunkCoordinates = ChunkUtils.getChunkCoord(chunkIndex);
|
||||||
|
final Chunk chunk = instance.getChunk(chunkCoordinates[0], chunkCoordinates[1]);
|
||||||
|
if (!ChunkUtils.isLoaded(chunk))
|
||||||
|
return;
|
||||||
|
|
||||||
|
updateChunk(instance, chunk, time);
|
||||||
|
|
||||||
|
updateEntities(instance, chunk, time);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute an instance tick
|
* Execute an instance tick
|
||||||
*
|
*
|
||||||
|
Loading…
Reference in New Issue
Block a user