From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com> Date: Sat, 1 Feb 2025 19:10:42 +0300 Subject: [PATCH] Skip EntityScheduler's executeTick checks if there isn't any tasks to be run Original project: https://github.com/SparklyPower/SparklyPaper diff --git a/src/main/java/io/papermc/paper/threadedregions/EntityScheduler.java b/src/main/java/io/papermc/paper/threadedregions/EntityScheduler.java index c03608fec96b51e1867f43d8f42e5aefb1520e46..eda35b81c36ca8ebe4f9487cb41e2b0c4cbfc686 100644 --- a/src/main/java/io/papermc/paper/threadedregions/EntityScheduler.java +++ b/src/main/java/io/papermc/paper/threadedregions/EntityScheduler.java @@ -36,6 +36,7 @@ public final class EntityScheduler { * The Entity. Note that it is the CraftEntity, since only that class properly tracks world transfers. */ public final CraftEntity entity; + public final net.minecraft.server.MinecraftServer server; // DivineMC - Skip EntityScheduler's executeTick checks if there isn't any tasks to be run private static final record ScheduledTask(Consumer run, Consumer retired) {} @@ -46,7 +47,8 @@ public final class EntityScheduler { private final ArrayDeque currentlyExecuting = new ArrayDeque<>(); - public EntityScheduler(final CraftEntity entity) { + public EntityScheduler(final net.minecraft.server.MinecraftServer server, final CraftEntity entity) { // DivineMC - Skip EntityScheduler's executeTick checks if there isn't any tasks to be run + this.server = Validate.notNull(server); this.entity = Validate.notNull(entity); } @@ -61,15 +63,15 @@ public final class EntityScheduler { * @throws IllegalStateException If the scheduler is already retired. */ public void retire() { + final Entity thisEntity = this.entity.getHandleRaw(); // DivineMC - Skip EntityScheduler's executeTick checks if there isn't any tasks to be run synchronized (this.stateLock) { if (this.tickCount == RETIRED_TICK_COUNT) { throw new IllegalStateException("Already retired"); } this.tickCount = RETIRED_TICK_COUNT; + this.server.entitiesWithScheduledTasks.remove(thisEntity); // DivineMC - Skip EntityScheduler's executeTick checks if there isn't any tasks to be run } - final Entity thisEntity = this.entity.getHandleRaw(); - // correctly handle and order retiring while running executeTick for (int i = 0, len = this.currentlyExecuting.size(); i < len; ++i) { final ScheduledTask task = this.currentlyExecuting.pollFirst(); @@ -124,6 +126,7 @@ public final class EntityScheduler { if (this.tickCount == RETIRED_TICK_COUNT) { return false; } + this.server.entitiesWithScheduledTasks.add(this.entity.getHandleRaw()); // DivineMC - Skip EntityScheduler's executeTick checks if there isn't any tasks to be run this.oneTimeDelayed.computeIfAbsent(this.tickCount + Math.max(1L, delay), (final long keyInMap) -> { return new ArrayList<>(); }).add(task); @@ -143,6 +146,12 @@ public final class EntityScheduler { TickThread.ensureTickThread(thisEntity, "May not tick entity scheduler asynchronously"); final List toRun; synchronized (this.stateLock) { + // DivineMC start - Skip EntityScheduler's executeTick checks if there isn't any tasks to be run + if (this.currentlyExecuting.isEmpty() && this.oneTimeDelayed.isEmpty()) { + this.server.entitiesWithScheduledTasks.remove(thisEntity); + return; + } + // DivineMC end - Skip EntityScheduler's executeTick checks if there isn't any tasks to be run if (this.tickCount == RETIRED_TICK_COUNT) { throw new IllegalStateException("Ticking retired scheduler"); } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java index 834389b78d9342e96b3473c9cb6e40ca6cd4e46f..a18069c7de594a8f4ddef46f9dad48dd29cd4b34 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java @@ -93,7 +93,7 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { private final CraftPersistentDataContainer persistentDataContainer = new CraftPersistentDataContainer(CraftEntity.DATA_TYPE_REGISTRY); protected net.kyori.adventure.pointer.Pointers adventure$pointers; // Paper - implement pointers // Paper start - Folia shedulers - public final io.papermc.paper.threadedregions.EntityScheduler taskScheduler = new io.papermc.paper.threadedregions.EntityScheduler(this); + public final io.papermc.paper.threadedregions.EntityScheduler taskScheduler; // DivineMC - Skip EntityScheduler's executeTick checks if there isn't any tasks to be run private final io.papermc.paper.threadedregions.scheduler.FoliaEntityScheduler apiScheduler = new io.papermc.paper.threadedregions.scheduler.FoliaEntityScheduler(this); @Override @@ -106,6 +106,7 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { this.server = server; this.entity = entity; this.entityType = CraftEntityType.minecraftToBukkit(entity.getType()); + this.taskScheduler = new io.papermc.paper.threadedregions.EntityScheduler(this.entity.getServer(), this); // DivineMC - Skip EntityScheduler's executeTick checks if there isn't any tasks to be run } // Purpur start - Fire Immunity API