mirror of
https://github.com/Minestom/Minestom.git
synced 2025-01-01 22:17:37 +01:00
Make dedicated thread class for tick scheduling
Signed-off-by: TheMode <themode@outlook.fr>
This commit is contained in:
parent
82a68cbfad
commit
1edab499f1
@ -26,11 +26,10 @@ import java.util.function.LongConsumer;
|
|||||||
* The {@link ThreadDispatcher} manages the multi-thread aspect of chunk ticks.
|
* The {@link ThreadDispatcher} manages the multi-thread aspect of chunk ticks.
|
||||||
*/
|
*/
|
||||||
public final class UpdateManager {
|
public final class UpdateManager {
|
||||||
|
|
||||||
private volatile boolean stopRequested;
|
private volatile boolean stopRequested;
|
||||||
|
|
||||||
// TODO make configurable
|
// TODO make configurable
|
||||||
private ThreadDispatcher threadDispatcher = ThreadDispatcher.singleThread();
|
private final ThreadDispatcher threadDispatcher = ThreadDispatcher.singleThread();
|
||||||
|
|
||||||
private final Queue<LongConsumer> tickStartCallbacks = new ConcurrentLinkedQueue<>();
|
private final Queue<LongConsumer> tickStartCallbacks = new ConcurrentLinkedQueue<>();
|
||||||
private final Queue<LongConsumer> tickEndCallbacks = new ConcurrentLinkedQueue<>();
|
private final Queue<LongConsumer> tickEndCallbacks = new ConcurrentLinkedQueue<>();
|
||||||
@ -46,96 +45,7 @@ public final class UpdateManager {
|
|||||||
* Starts the server loop in the update thread.
|
* Starts the server loop in the update thread.
|
||||||
*/
|
*/
|
||||||
void start() {
|
void start() {
|
||||||
final ConnectionManager connectionManager = MinecraftServer.getConnectionManager();
|
new TickSchedulerThread().start();
|
||||||
|
|
||||||
new Thread(() -> {
|
|
||||||
while (!stopRequested) {
|
|
||||||
try {
|
|
||||||
long currentTime = System.nanoTime();
|
|
||||||
final long tickStart = System.currentTimeMillis();
|
|
||||||
|
|
||||||
// Tick start callbacks
|
|
||||||
doTickCallback(tickStartCallbacks, tickStart);
|
|
||||||
|
|
||||||
// Waiting players update (newly connected clients waiting to get into the server)
|
|
||||||
connectionManager.updateWaitingPlayers();
|
|
||||||
|
|
||||||
// Keep Alive Handling
|
|
||||||
connectionManager.handleKeepAlive(tickStart);
|
|
||||||
|
|
||||||
// Server tick (chunks/entities)
|
|
||||||
serverTick(tickStart);
|
|
||||||
|
|
||||||
// the time that the tick took in nanoseconds
|
|
||||||
final long tickTime = System.nanoTime() - currentTime;
|
|
||||||
|
|
||||||
// Tick end callbacks
|
|
||||||
doTickCallback(tickEndCallbacks, tickTime);
|
|
||||||
|
|
||||||
// Monitoring
|
|
||||||
if (!tickMonitors.isEmpty()) {
|
|
||||||
final double acquisitionTimeMs = Acquirable.getAcquiringTime() / 1e6D;
|
|
||||||
final double tickTimeMs = tickTime / 1e6D;
|
|
||||||
final TickMonitor tickMonitor = new TickMonitor(tickTimeMs, acquisitionTimeMs);
|
|
||||||
for (Consumer<TickMonitor> consumer : tickMonitors) {
|
|
||||||
consumer.accept(tickMonitor);
|
|
||||||
}
|
|
||||||
Acquirable.resetAcquiringTime();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Flush all waiting packets
|
|
||||||
AsyncUtils.runAsync(() -> {
|
|
||||||
PacketUtils.flush();
|
|
||||||
for (Player player : connectionManager.getOnlinePlayers()) {
|
|
||||||
player.getPlayerConnection().flush();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Disable thread until next tick
|
|
||||||
LockSupport.parkNanos((long) ((MinecraftServer.TICK_MS * 1e6) - tickTime));
|
|
||||||
} catch (Exception e) {
|
|
||||||
MinecraftServer.getExceptionManager().handleException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.threadDispatcher.shutdown();
|
|
||||||
}, MinecraftServer.THREAD_NAME_TICK_SCHEDULER).start();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Executes a server tick and returns only once all the futures are completed.
|
|
||||||
*
|
|
||||||
* @param tickStart the time of the tick in milliseconds
|
|
||||||
*/
|
|
||||||
private void serverTick(long tickStart) {
|
|
||||||
// Tick all instances
|
|
||||||
for (Instance instance : MinecraftServer.getInstanceManager().getInstances()) {
|
|
||||||
try {
|
|
||||||
instance.tick(tickStart);
|
|
||||||
} catch (Exception e) {
|
|
||||||
MinecraftServer.getExceptionManager().handleException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Tick all chunks (and entities inside)
|
|
||||||
this.threadDispatcher.updateAndAwait(tickStart);
|
|
||||||
|
|
||||||
// Clear removed entities & update threads
|
|
||||||
final long tickTime = System.currentTimeMillis() - tickStart;
|
|
||||||
this.threadDispatcher.refreshThreads(tickTime);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Used to execute tick-related callbacks.
|
|
||||||
*
|
|
||||||
* @param callbacks the callbacks to execute
|
|
||||||
* @param value the value to give to the consumers
|
|
||||||
*/
|
|
||||||
private void doTickCallback(Queue<LongConsumer> callbacks, long value) {
|
|
||||||
if (!callbacks.isEmpty()) {
|
|
||||||
LongConsumer callback;
|
|
||||||
while ((callback = callbacks.poll()) != null) {
|
|
||||||
callback.accept(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -245,4 +155,95 @@ public final class UpdateManager {
|
|||||||
public void stop() {
|
public void stop() {
|
||||||
this.stopRequested = true;
|
this.stopRequested = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private final class TickSchedulerThread extends Thread {
|
||||||
|
private final ThreadDispatcher threadDispatcher = UpdateManager.this.threadDispatcher;
|
||||||
|
|
||||||
|
TickSchedulerThread() {
|
||||||
|
super(MinecraftServer.THREAD_NAME_TICK_SCHEDULER);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
final ConnectionManager connectionManager = MinecraftServer.getConnectionManager();
|
||||||
|
while (!stopRequested) {
|
||||||
|
try {
|
||||||
|
long currentTime = System.nanoTime();
|
||||||
|
final long tickStart = System.currentTimeMillis();
|
||||||
|
|
||||||
|
// Tick start callbacks
|
||||||
|
doTickCallback(tickStartCallbacks, tickStart);
|
||||||
|
|
||||||
|
// Waiting players update (newly connected clients waiting to get into the server)
|
||||||
|
connectionManager.updateWaitingPlayers();
|
||||||
|
|
||||||
|
// Keep Alive Handling
|
||||||
|
connectionManager.handleKeepAlive(tickStart);
|
||||||
|
|
||||||
|
// Server tick (chunks/entities)
|
||||||
|
serverTick(tickStart);
|
||||||
|
|
||||||
|
// the time that the tick took in nanoseconds
|
||||||
|
final long tickTime = System.nanoTime() - currentTime;
|
||||||
|
|
||||||
|
// Tick end callbacks
|
||||||
|
doTickCallback(tickEndCallbacks, tickTime);
|
||||||
|
|
||||||
|
// Monitoring
|
||||||
|
if (!tickMonitors.isEmpty()) {
|
||||||
|
final double acquisitionTimeMs = Acquirable.getAcquiringTime() / 1e6D;
|
||||||
|
final double tickTimeMs = tickTime / 1e6D;
|
||||||
|
final TickMonitor tickMonitor = new TickMonitor(tickTimeMs, acquisitionTimeMs);
|
||||||
|
for (Consumer<TickMonitor> consumer : tickMonitors) {
|
||||||
|
consumer.accept(tickMonitor);
|
||||||
|
}
|
||||||
|
Acquirable.resetAcquiringTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Flush all waiting packets
|
||||||
|
AsyncUtils.runAsync(() -> {
|
||||||
|
PacketUtils.flush();
|
||||||
|
for (Player player : MinecraftServer.getConnectionManager().getOnlinePlayers()) {
|
||||||
|
player.getPlayerConnection().flush();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Disable thread until next tick
|
||||||
|
LockSupport.parkNanos((long) ((MinecraftServer.TICK_MS * 1e6) - tickTime));
|
||||||
|
} catch (Exception e) {
|
||||||
|
MinecraftServer.getExceptionManager().handleException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.threadDispatcher.shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Executes a server tick and returns only once all the futures are completed.
|
||||||
|
*
|
||||||
|
* @param tickStart the time of the tick in milliseconds
|
||||||
|
*/
|
||||||
|
private void serverTick(long tickStart) {
|
||||||
|
// Tick all instances
|
||||||
|
for (Instance instance : MinecraftServer.getInstanceManager().getInstances()) {
|
||||||
|
try {
|
||||||
|
instance.tick(tickStart);
|
||||||
|
} catch (Exception e) {
|
||||||
|
MinecraftServer.getExceptionManager().handleException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Tick all chunks (and entities inside)
|
||||||
|
this.threadDispatcher.updateAndAwait(tickStart);
|
||||||
|
|
||||||
|
// Clear removed entities & update threads
|
||||||
|
final long tickTime = System.currentTimeMillis() - tickStart;
|
||||||
|
this.threadDispatcher.refreshThreads(tickTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void doTickCallback(Queue<LongConsumer> callbacks, long value) {
|
||||||
|
LongConsumer callback;
|
||||||
|
while ((callback = callbacks.poll()) != null) {
|
||||||
|
callback.accept(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user