mirror of
https://github.com/Minestom/Minestom.git
synced 2025-01-19 06:32:03 +01:00
Fix the first #setInstance being called in the main update thread
This commit is contained in:
parent
88ef4eb3c0
commit
9184b3054f
@ -70,7 +70,7 @@ public final class UpdateManager {
|
||||
futures = threadProvider.update(time);
|
||||
}
|
||||
|
||||
// Waiting players update (newly connected waiting to get into the server)
|
||||
// Waiting players update (newly connected clients waiting to get into the server)
|
||||
entityManager.updateWaitingPlayers();
|
||||
|
||||
// Keep Alive Handling
|
||||
|
@ -20,6 +20,7 @@ import net.minestom.server.instance.InstanceManager;
|
||||
import net.minestom.server.instance.WorldBorder;
|
||||
import net.minestom.server.instance.block.CustomBlock;
|
||||
import net.minestom.server.network.packet.server.play.*;
|
||||
import net.minestom.server.thread.ThreadProvider;
|
||||
import net.minestom.server.utils.ArrayUtils;
|
||||
import net.minestom.server.utils.BlockPosition;
|
||||
import net.minestom.server.utils.Position;
|
||||
@ -33,6 +34,7 @@ import net.minestom.server.utils.validate.Check;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.concurrent.CopyOnWriteArraySet;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.function.Consumer;
|
||||
@ -114,7 +116,8 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer {
|
||||
protected boolean noGravity;
|
||||
protected Pose pose = Pose.STANDING;
|
||||
|
||||
protected final List<Consumer<Entity>> nextTick = Collections.synchronizedList(new ArrayList<>());
|
||||
// list of scheduled tasks to be executed during the next entity tick
|
||||
protected final ConcurrentLinkedQueue<Consumer<Entity>> nextTick = new ConcurrentLinkedQueue<>();
|
||||
|
||||
// Tick related
|
||||
private long ticks;
|
||||
@ -134,8 +137,14 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer {
|
||||
setVelocityUpdatePeriod(5);
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule a task to be run during the next entity tick
|
||||
* It ensures that the task will be executed in the same thread as the entity (depending of the {@link ThreadProvider})
|
||||
*
|
||||
* @param callback the task to execute during the next entity tick
|
||||
*/
|
||||
public void scheduleNextTick(Consumer<Entity> callback) {
|
||||
nextTick.add(callback);
|
||||
this.nextTick.add(callback);
|
||||
}
|
||||
|
||||
public Entity(EntityType entityType) {
|
||||
@ -353,12 +362,14 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer {
|
||||
return;
|
||||
}
|
||||
|
||||
synchronized (nextTick) {
|
||||
for (final Consumer<Entity> e : nextTick) {
|
||||
e.accept(this);
|
||||
// scheduled tasks
|
||||
if (!nextTick.isEmpty()) {
|
||||
Consumer<Entity> callback;
|
||||
while ((callback = nextTick.poll()) != null) {
|
||||
callback.accept(this);
|
||||
}
|
||||
nextTick.clear();
|
||||
}
|
||||
|
||||
// Synchronization with updated fields in #getPosition()
|
||||
{
|
||||
// X/Y/Z axis
|
||||
|
@ -36,17 +36,20 @@ public final class EntityManager {
|
||||
|
||||
Check.notNull(spawningInstance, "You need to specify a spawning instance in the PlayerLoginEvent");
|
||||
|
||||
waitingPlayer.setInstance(spawningInstance);
|
||||
{
|
||||
final Player finalWaitingPlayer = waitingPlayer;
|
||||
spawningInstance.scheduleNextTick(instance -> finalWaitingPlayer.setInstance(instance));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Call the player initialization callbacks and the event {@link PlayerPreLoginEvent}
|
||||
* If the player hasn't been kicked, add him to the waiting list
|
||||
* Call the player initialization callbacks and the event {@link PlayerPreLoginEvent}.
|
||||
* If the {@link Player} hasn't been kicked, add him to the waiting list.
|
||||
* <p>
|
||||
* Can be considered as a pre-init thing
|
||||
* Can be considered as a pre-init thing.
|
||||
*
|
||||
* @param player the player to add
|
||||
* @param player the {@link Player} to add
|
||||
*/
|
||||
public void addWaitingPlayer(Player player) {
|
||||
|
||||
|
@ -176,8 +176,10 @@ public class Player extends LivingEntity implements CommandSender {
|
||||
}
|
||||
|
||||
/**
|
||||
* Used when the player is created
|
||||
* Init the player and spawn him
|
||||
* Used when the player is created.
|
||||
* Init the player and spawn him.
|
||||
* <p>
|
||||
* WARNING: executed in the main update thread
|
||||
*/
|
||||
protected void init() {
|
||||
JoinGamePacket joinGamePacket = new JoinGamePacket();
|
||||
|
@ -938,8 +938,8 @@ public abstract class Instance implements BlockModifier, EventHandler, DataConta
|
||||
* @param time the current time
|
||||
*/
|
||||
public void tick(long time) {
|
||||
{
|
||||
// scheduled tasks
|
||||
// scheduled tasks
|
||||
if (!nextTick.isEmpty()) {
|
||||
Consumer<Instance> callback;
|
||||
while ((callback = nextTick.poll()) != null) {
|
||||
callback.accept(this);
|
||||
|
Loading…
Reference in New Issue
Block a user