Add methods taking world, chunkX, chunkZ to RegionScheduler

This commit is contained in:
Nassim Jahnke 2023-03-25 18:40:20 +01:00
parent dfc157075a
commit 8d15f3e23d
No known key found for this signature in database
GPG Key ID: 6BE3B555EBC5982B
3 changed files with 150 additions and 92 deletions

View File

@ -8,7 +8,7 @@ and a global region scheduler.
diff --git a/src/main/java/io/papermc/paper/threadedregions/scheduler/AsyncScheduler.java b/src/main/java/io/papermc/paper/threadedregions/scheduler/AsyncScheduler.java diff --git a/src/main/java/io/papermc/paper/threadedregions/scheduler/AsyncScheduler.java b/src/main/java/io/papermc/paper/threadedregions/scheduler/AsyncScheduler.java
new file mode 100644 new file mode 100644
index 0000000000000000000000000000000000000000..64d1fe385d30f1f5ab82d35fe66e268da13346b1 index 0000000000000000000000000000000000000000..66232a9f5cea31dc8046817c3c2a91695930e53f
--- /dev/null --- /dev/null
+++ b/src/main/java/io/papermc/paper/threadedregions/scheduler/AsyncScheduler.java +++ b/src/main/java/io/papermc/paper/threadedregions/scheduler/AsyncScheduler.java
@@ -0,0 +1,50 @@ @@ -0,0 +1,50 @@
@ -30,7 +30,7 @@ index 0000000000000000000000000000000000000000..64d1fe385d30f1f5ab82d35fe66e268d
+ * @param task Specified task. + * @param task Specified task.
+ * @return The {@link ScheduledTask} that represents the scheduled task. + * @return The {@link ScheduledTask} that represents the scheduled task.
+ */ + */
+ public @NotNull ScheduledTask runNow(@NotNull Plugin plugin, @NotNull Consumer<ScheduledTask> task); + @NotNull ScheduledTask runNow(@NotNull Plugin plugin, @NotNull Consumer<ScheduledTask> task);
+ +
+ /** + /**
+ * Schedules the specified task to be executed asynchronously after the time delay has passed. + * Schedules the specified task to be executed asynchronously after the time delay has passed.
@ -40,7 +40,7 @@ index 0000000000000000000000000000000000000000..64d1fe385d30f1f5ab82d35fe66e268d
+ * @param unit The time unit for the time delay. + * @param unit The time unit for the time delay.
+ * @return The {@link ScheduledTask} that represents the scheduled task. + * @return The {@link ScheduledTask} that represents the scheduled task.
+ */ + */
+ public @NotNull ScheduledTask runDelayed(@NotNull Plugin plugin, @NotNull Consumer<ScheduledTask> task, long delay, + @NotNull ScheduledTask runDelayed(@NotNull Plugin plugin, @NotNull Consumer<ScheduledTask> task, long delay,
+ @NotNull TimeUnit unit); + @NotNull TimeUnit unit);
+ +
+ /** + /**
@ -53,18 +53,18 @@ index 0000000000000000000000000000000000000000..64d1fe385d30f1f5ab82d35fe66e268d
+ * @param unit The time unit for the initial delay and period. + * @param unit The time unit for the initial delay and period.
+ * @return The {@link ScheduledTask} that represents the scheduled task. + * @return The {@link ScheduledTask} that represents the scheduled task.
+ */ + */
+ public @NotNull ScheduledTask runAtFixedRate(@NotNull Plugin plugin, @NotNull Consumer<ScheduledTask> task, + @NotNull ScheduledTask runAtFixedRate(@NotNull Plugin plugin, @NotNull Consumer<ScheduledTask> task,
+ long initialDelay, long period, @NotNull TimeUnit unit); + long initialDelay, long period, @NotNull TimeUnit unit);
+ +
+ /** + /**
+ * Attempts to cancel all tasks scheduled by the specified plugin. + * Attempts to cancel all tasks scheduled by the specified plugin.
+ * @param plugin Specified plugin. + * @param plugin Specified plugin.
+ */ + */
+ public void cancelTasks(@NotNull Plugin plugin); + void cancelTasks(@NotNull Plugin plugin);
+} +}
diff --git a/src/main/java/io/papermc/paper/threadedregions/scheduler/EntityScheduler.java b/src/main/java/io/papermc/paper/threadedregions/scheduler/EntityScheduler.java diff --git a/src/main/java/io/papermc/paper/threadedregions/scheduler/EntityScheduler.java b/src/main/java/io/papermc/paper/threadedregions/scheduler/EntityScheduler.java
new file mode 100644 new file mode 100644
index 0000000000000000000000000000000000000000..9c4ee07a86104f3601ba6d8a911197dbe1a17102 index 0000000000000000000000000000000000000000..017dbb27f66cbf744a67189e91c476f8d971d1e7
--- /dev/null --- /dev/null
+++ b/src/main/java/io/papermc/paper/threadedregions/scheduler/EntityScheduler.java +++ b/src/main/java/io/papermc/paper/threadedregions/scheduler/EntityScheduler.java
@@ -0,0 +1,103 @@ @@ -0,0 +1,103 @@
@ -112,7 +112,7 @@ index 0000000000000000000000000000000000000000..9c4ee07a86104f3601ba6d8a911197db
+ * will be invoked (but never both), or {@code false} indicating neither the run nor retired function will be invoked + * will be invoked (but never both), or {@code false} indicating neither the run nor retired function will be invoked
+ * since the scheduler has been retired. + * since the scheduler has been retired.
+ */ + */
+ public boolean execute(@NotNull Plugin plugin, @NotNull Runnable run, @Nullable Runnable retired, long delay); + boolean execute(@NotNull Plugin plugin, @NotNull Runnable run, @Nullable Runnable retired, long delay);
+ +
+ /** + /**
+ * Schedules a task to execute on the next tick. If the task failed to schedule because the scheduler is retired (entity + * Schedules a task to execute on the next tick. If the task failed to schedule because the scheduler is retired (entity
@ -129,7 +129,7 @@ index 0000000000000000000000000000000000000000..9c4ee07a86104f3601ba6d8a911197db
+ * @param retired Retire callback to run if the entity is retired before the run callback can be invoked, may be null. + * @param retired Retire callback to run if the entity is retired before the run callback can be invoked, may be null.
+ * @return The {@link ScheduledTask} that represents the scheduled task, or {@code null} if the entity has been removed. + * @return The {@link ScheduledTask} that represents the scheduled task, or {@code null} if the entity has been removed.
+ */ + */
+ public @Nullable ScheduledTask run(@NotNull Plugin plugin, @NotNull Consumer<ScheduledTask> task, + @Nullable ScheduledTask run(@NotNull Plugin plugin, @NotNull Consumer<ScheduledTask> task,
+ @Nullable Runnable retired); + @Nullable Runnable retired);
+ +
+ /** + /**
@ -148,7 +148,7 @@ index 0000000000000000000000000000000000000000..9c4ee07a86104f3601ba6d8a911197db
+ * @param delayTicks The delay, in ticks. + * @param delayTicks The delay, in ticks.
+ * @return The {@link ScheduledTask} that represents the scheduled task, or {@code null} if the entity has been removed. + * @return The {@link ScheduledTask} that represents the scheduled task, or {@code null} if the entity has been removed.
+ */ + */
+ public @Nullable ScheduledTask runDelayed(@NotNull Plugin plugin, @NotNull Consumer<ScheduledTask> task, + @Nullable ScheduledTask runDelayed(@NotNull Plugin plugin, @NotNull Consumer<ScheduledTask> task,
+ @Nullable Runnable retired, int delayTicks); + @Nullable Runnable retired, int delayTicks);
+ +
+ /** + /**
@ -168,12 +168,12 @@ index 0000000000000000000000000000000000000000..9c4ee07a86104f3601ba6d8a911197db
+ * @param periodTicks The period, in ticks. + * @param periodTicks The period, in ticks.
+ * @return The {@link ScheduledTask} that represents the scheduled task, or {@code null} if the entity has been removed. + * @return The {@link ScheduledTask} that represents the scheduled task, or {@code null} if the entity has been removed.
+ */ + */
+ public @Nullable ScheduledTask runAtFixedRate(@NotNull Plugin plugin, @NotNull Consumer<ScheduledTask> task, + @Nullable ScheduledTask runAtFixedRate(@NotNull Plugin plugin, @NotNull Consumer<ScheduledTask> task,
+ @Nullable Runnable retired, int initialDelayTicks, int periodTicks); + @Nullable Runnable retired, int initialDelayTicks, int periodTicks);
+} +}
diff --git a/src/main/java/io/papermc/paper/threadedregions/scheduler/GlobalRegionScheduler.java b/src/main/java/io/papermc/paper/threadedregions/scheduler/GlobalRegionScheduler.java diff --git a/src/main/java/io/papermc/paper/threadedregions/scheduler/GlobalRegionScheduler.java b/src/main/java/io/papermc/paper/threadedregions/scheduler/GlobalRegionScheduler.java
new file mode 100644 new file mode 100644
index 0000000000000000000000000000000000000000..f2d2565d903af90f6909319c811a49162f972e27 index 0000000000000000000000000000000000000000..45713139678cd2bcb9a370c947a124d8f5e2e36b
--- /dev/null --- /dev/null
+++ b/src/main/java/io/papermc/paper/threadedregions/scheduler/GlobalRegionScheduler.java +++ b/src/main/java/io/papermc/paper/threadedregions/scheduler/GlobalRegionScheduler.java
@@ -0,0 +1,57 @@ @@ -0,0 +1,57 @@
@ -197,7 +197,7 @@ index 0000000000000000000000000000000000000000..f2d2565d903af90f6909319c811a4916
+ * @param plugin The plugin that owns the task + * @param plugin The plugin that owns the task
+ * @param run The task to execute + * @param run The task to execute
+ */ + */
+ public void execute(@NotNull Plugin plugin, @NotNull Runnable run); + void execute(@NotNull Plugin plugin, @NotNull Runnable run);
+ +
+ /** + /**
+ * Schedules a task to be executed on the global region on the next tick. + * Schedules a task to be executed on the global region on the next tick.
@ -205,7 +205,7 @@ index 0000000000000000000000000000000000000000..f2d2565d903af90f6909319c811a4916
+ * @param task The task to execute + * @param task The task to execute
+ * @return The {@link ScheduledTask} that represents the scheduled task. + * @return The {@link ScheduledTask} that represents the scheduled task.
+ */ + */
+ public @NotNull ScheduledTask run(@NotNull Plugin plugin, @NotNull Consumer<ScheduledTask> task); + @NotNull ScheduledTask run(@NotNull Plugin plugin, @NotNull Consumer<ScheduledTask> task);
+ +
+ /** + /**
+ * Schedules a task to be executed on the global region after the specified delay in ticks. + * Schedules a task to be executed on the global region after the specified delay in ticks.
@ -214,7 +214,7 @@ index 0000000000000000000000000000000000000000..f2d2565d903af90f6909319c811a4916
+ * @param delayTicks The delay, in ticks. + * @param delayTicks The delay, in ticks.
+ * @return The {@link ScheduledTask} that represents the scheduled task. + * @return The {@link ScheduledTask} that represents the scheduled task.
+ */ + */
+ public @NotNull ScheduledTask runDelayed(@NotNull Plugin plugin, @NotNull Consumer<ScheduledTask> task, int delayTicks); + @NotNull ScheduledTask runDelayed(@NotNull Plugin plugin, @NotNull Consumer<ScheduledTask> task, int delayTicks);
+ +
+ /** + /**
+ * Schedules a repeating task to be executed on the global region after the initial delay with the + * Schedules a repeating task to be executed on the global region after the initial delay with the
@ -225,24 +225,25 @@ index 0000000000000000000000000000000000000000..f2d2565d903af90f6909319c811a4916
+ * @param periodTicks The period, in ticks. + * @param periodTicks The period, in ticks.
+ * @return The {@link ScheduledTask} that represents the scheduled task. + * @return The {@link ScheduledTask} that represents the scheduled task.
+ */ + */
+ public @NotNull ScheduledTask runAtFixedRate(@NotNull Plugin plugin, @NotNull Consumer<ScheduledTask> task, + @NotNull ScheduledTask runAtFixedRate(@NotNull Plugin plugin, @NotNull Consumer<ScheduledTask> task,
+ int initialDelayTicks, int periodTicks); + int initialDelayTicks, int periodTicks);
+ +
+ /** + /**
+ * Attempts to cancel all tasks scheduled by the specified plugin. + * Attempts to cancel all tasks scheduled by the specified plugin.
+ * @param plugin Specified plugin. + * @param plugin Specified plugin.
+ */ + */
+ public void cancelTasks(@NotNull Plugin plugin); + void cancelTasks(@NotNull Plugin plugin);
+} +}
diff --git a/src/main/java/io/papermc/paper/threadedregions/scheduler/RegionScheduler.java b/src/main/java/io/papermc/paper/threadedregions/scheduler/RegionScheduler.java diff --git a/src/main/java/io/papermc/paper/threadedregions/scheduler/RegionScheduler.java b/src/main/java/io/papermc/paper/threadedregions/scheduler/RegionScheduler.java
new file mode 100644 new file mode 100644
index 0000000000000000000000000000000000000000..80baf45735fbf52a69872712cf3ae6c71739db27 index 0000000000000000000000000000000000000000..87a267ca2cd7a751acdd1fbbfbf9c664640a9805
--- /dev/null --- /dev/null
+++ b/src/main/java/io/papermc/paper/threadedregions/scheduler/RegionScheduler.java +++ b/src/main/java/io/papermc/paper/threadedregions/scheduler/RegionScheduler.java
@@ -0,0 +1,60 @@ @@ -0,0 +1,126 @@
+package io.papermc.paper.threadedregions.scheduler; +package io.papermc.paper.threadedregions.scheduler;
+ +
+import org.bukkit.Location; +import org.bukkit.Location;
+import org.bukkit.World;
+import org.bukkit.entity.Entity; +import org.bukkit.entity.Entity;
+import org.bukkit.plugin.Plugin; +import org.bukkit.plugin.Plugin;
+import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.NotNull;
@ -261,48 +262,113 @@ index 0000000000000000000000000000000000000000..80baf45735fbf52a69872712cf3ae6c7
+ +
+ /** + /**
+ * Schedules a task to be executed on the region which owns the location. + * Schedules a task to be executed on the region which owns the location.
+ *
+ * @param plugin The plugin that owns the task + * @param plugin The plugin that owns the task
+ * @param location The location at which the region executing should own + * @param world The world of the region that owns the task
+ * @param run The task to execute + * @param chunkX The chunk X coordinate of the region that owns the task
+ * @param chunkZ The chunk Z coordinate of the region that owns the task
+ * @param run The task to execute
+ */ + */
+ public void execute(@NotNull Plugin plugin, @NotNull Location location, @NotNull Runnable run); + void execute(@NotNull Plugin plugin, @NotNull World world, int chunkX, int chunkZ, @NotNull Runnable run);
+
+ /**
+ * Schedules a task to be executed on the region which owns the location.
+ *
+ * @param plugin The plugin that owns the task
+ * @param location The location at which the region executing should own
+ * @param run The task to execute
+ */
+ default void execute(@NotNull Plugin plugin, @NotNull Location location, @NotNull Runnable run) {
+ this.execute(plugin, location.getWorld(), location.getBlockX() >> 4, location.getBlockZ() >> 4, run);
+ }
+ +
+ /** + /**
+ * Schedules a task to be executed on the region which owns the location on the next tick. + * Schedules a task to be executed on the region which owns the location on the next tick.
+ *
+ * @param plugin The plugin that owns the task + * @param plugin The plugin that owns the task
+ * @param location The location at which the region executing should own + * @param world The world of the region that owns the task
+ * @param task The task to execute + * @param chunkX The chunk X coordinate of the region that owns the task
+ * @param chunkZ The chunk Z coordinate of the region that owns the task
+ * @param task The task to execute
+ * @return The {@link ScheduledTask} that represents the scheduled task. + * @return The {@link ScheduledTask} that represents the scheduled task.
+ */ + */
+ public @NotNull ScheduledTask run(@NotNull Plugin plugin, @NotNull Location location, @NotNull Consumer<ScheduledTask> task); + @NotNull ScheduledTask run(@NotNull Plugin plugin, @NotNull World world, int chunkX, int chunkZ, @NotNull Consumer<ScheduledTask> task);
+
+ /**
+ * Schedules a task to be executed on the region which owns the location on the next tick.
+ *
+ * @param plugin The plugin that owns the task
+ * @param location The location at which the region executing should own
+ * @param task The task to execute
+ * @return The {@link ScheduledTask} that represents the scheduled task.
+ */
+ default @NotNull ScheduledTask run(@NotNull Plugin plugin, @NotNull Location location, @NotNull Consumer<ScheduledTask> task) {
+ return this.run(plugin, location.getWorld(), location.getBlockX() >> 4, location.getBlockZ() >> 4, task);
+ }
+ +
+ /** + /**
+ * Schedules a task to be executed on the region which owns the location after the specified delay in ticks. + * Schedules a task to be executed on the region which owns the location after the specified delay in ticks.
+ * @param plugin The plugin that owns the task + *
+ * @param location The location at which the region executing should own + * @param plugin The plugin that owns the task
+ * @param task The task to execute + * @param world The world of the region that owns the task
+ * @param chunkX The chunk X coordinate of the region that owns the task
+ * @param chunkZ The chunk Z coordinate of the region that owns the task
+ * @param task The task to execute
+ * @param delayTicks The delay, in ticks. + * @param delayTicks The delay, in ticks.
+ * @return The {@link ScheduledTask} that represents the scheduled task. + * @return The {@link ScheduledTask} that represents the scheduled task.
+ */ + */
+ public @NotNull ScheduledTask runDelayed(@NotNull Plugin plugin, @NotNull Location location, @NotNull Consumer<ScheduledTask> task, + @NotNull ScheduledTask runDelayed(@NotNull Plugin plugin, @NotNull World world, int chunkX, int chunkZ, @NotNull Consumer<ScheduledTask> task,
+ int delayTicks); + int delayTicks);
+
+ /**
+ * Schedules a task to be executed on the region which owns the location after the specified delay in ticks.
+ *
+ * @param plugin The plugin that owns the task
+ * @param location The location at which the region executing should own
+ * @param task The task to execute
+ * @param delayTicks The delay, in ticks.
+ * @return The {@link ScheduledTask} that represents the scheduled task.
+ */
+ default @NotNull ScheduledTask runDelayed(@NotNull Plugin plugin, @NotNull Location location, @NotNull Consumer<ScheduledTask> task,
+ int delayTicks) {
+ return this.runDelayed(plugin, location.getWorld(), location.getBlockX() >> 4, location.getBlockZ() >> 4, task, delayTicks);
+ }
+ +
+ /** + /**
+ * Schedules a repeating task to be executed on the region which owns the location after the initial delay with the + * Schedules a repeating task to be executed on the region which owns the location after the initial delay with the
+ * specified period. + * specified period.
+ * @param plugin The plugin that owns the task + *
+ * @param location The location at which the region executing should own + * @param plugin The plugin that owns the task
+ * @param task The task to execute + * @param world The world of the region that owns the task
+ * @param chunkX The chunk X coordinate of the region that owns the task
+ * @param chunkZ The chunk Z coordinate of the region that owns the task
+ * @param task The task to execute
+ * @param initialDelayTicks The initial delay, in ticks. + * @param initialDelayTicks The initial delay, in ticks.
+ * @param periodTicks The period, in ticks. + * @param periodTicks The period, in ticks.
+ * @return The {@link ScheduledTask} that represents the scheduled task. + * @return The {@link ScheduledTask} that represents the scheduled task.
+ */ + */
+ public @NotNull ScheduledTask runAtFixedRate(@NotNull Plugin plugin, @NotNull Location location, @NotNull Consumer<ScheduledTask> task, + @NotNull ScheduledTask runAtFixedRate(@NotNull Plugin plugin, @NotNull World world, int chunkX, int chunkZ, @NotNull Consumer<ScheduledTask> task,
+ int initialDelayTicks, int periodTicks); + int initialDelayTicks, int periodTicks);
+
+ /**
+ * Schedules a repeating task to be executed on the region which owns the location after the initial delay with the
+ * specified period.
+ *
+ * @param plugin The plugin that owns the task
+ * @param location The location at which the region executing should own
+ * @param task The task to execute
+ * @param initialDelayTicks The initial delay, in ticks.
+ * @param periodTicks The period, in ticks.
+ * @return The {@link ScheduledTask} that represents the scheduled task.
+ */
+ default @NotNull ScheduledTask runAtFixedRate(@NotNull Plugin plugin, @NotNull Location location, @NotNull Consumer<ScheduledTask> task,
+ int initialDelayTicks, int periodTicks) {
+ return this.runAtFixedRate(plugin, location.getWorld(), location.getBlockX() >> 4, location.getBlockZ() >> 4, task, initialDelayTicks, periodTicks);
+ }
+} +}
diff --git a/src/main/java/io/papermc/paper/threadedregions/scheduler/ScheduledTask.java b/src/main/java/io/papermc/paper/threadedregions/scheduler/ScheduledTask.java diff --git a/src/main/java/io/papermc/paper/threadedregions/scheduler/ScheduledTask.java b/src/main/java/io/papermc/paper/threadedregions/scheduler/ScheduledTask.java
new file mode 100644 new file mode 100644
index 0000000000000000000000000000000000000000..fa4ac300d3721b2d6d84b95618d3305874cb803d index 0000000000000000000000000000000000000000..a6b50c9d8af589cc4747e14d343d2045216c249c
--- /dev/null --- /dev/null
+++ b/src/main/java/io/papermc/paper/threadedregions/scheduler/ScheduledTask.java +++ b/src/main/java/io/papermc/paper/threadedregions/scheduler/ScheduledTask.java
@@ -0,0 +1,112 @@ @@ -0,0 +1,112 @@
@ -320,32 +386,32 @@ index 0000000000000000000000000000000000000000..fa4ac300d3721b2d6d84b95618d33058
+ * Returns the plugin that scheduled this task. + * Returns the plugin that scheduled this task.
+ * @return the plugin that scheduled this task. + * @return the plugin that scheduled this task.
+ */ + */
+ public @NotNull Plugin getOwningPlugin(); + @NotNull Plugin getOwningPlugin();
+ +
+ /** + /**
+ * Returns whether this task executes on a fixed period, as opposed to executing only once. + * Returns whether this task executes on a fixed period, as opposed to executing only once.
+ * @return whether this task executes on a fixed period, as opposed to executing only once. + * @return whether this task executes on a fixed period, as opposed to executing only once.
+ */ + */
+ public boolean isRepeatingTask(); + boolean isRepeatingTask();
+ +
+ /** + /**
+ * Attempts to cancel this task, returning the result of the attempt. In all cases, if the task is currently + * Attempts to cancel this task, returning the result of the attempt. In all cases, if the task is currently
+ * being executed no attempt is made to halt the task, however any executions in the future are halted. + * being executed no attempt is made to halt the task, however any executions in the future are halted.
+ * @return the result of the cancellation attempt. + * @return the result of the cancellation attempt.
+ */ + */
+ public @NotNull CancelledState cancel(); + @NotNull CancelledState cancel();
+ +
+ /** + /**
+ * Returns the current execution state of this task. + * Returns the current execution state of this task.
+ * @return the current execution state of this task. + * @return the current execution state of this task.
+ */ + */
+ public @NotNull ExecutionState getExecutionState(); + @NotNull ExecutionState getExecutionState();
+ +
+ /** + /**
+ * Returns whether the current execution state is {@link ExecutionState#CANCELLED} or {@link ExecutionState#CANCELLED_RUNNING}. + * Returns whether the current execution state is {@link ExecutionState#CANCELLED} or {@link ExecutionState#CANCELLED_RUNNING}.
+ * @return whether the current execution state is {@link ExecutionState#CANCELLED} or {@link ExecutionState#CANCELLED_RUNNING}. + * @return whether the current execution state is {@link ExecutionState#CANCELLED} or {@link ExecutionState#CANCELLED_RUNNING}.
+ */ + */
+ public default boolean isCancelled() { + default boolean isCancelled() {
+ final ExecutionState state = this.getExecutionState(); + final ExecutionState state = this.getExecutionState();
+ return state == ExecutionState.CANCELLED || state == ExecutionState.CANCELLED_RUNNING; + return state == ExecutionState.CANCELLED || state == ExecutionState.CANCELLED_RUNNING;
+ } + }
@ -353,7 +419,7 @@ index 0000000000000000000000000000000000000000..fa4ac300d3721b2d6d84b95618d33058
+ /** + /**
+ * Represents the result of attempting to cancel a task. + * Represents the result of attempting to cancel a task.
+ */ + */
+ public enum CancelledState { + enum CancelledState {
+ /** + /**
+ * The task (repeating or not) has been successfully cancelled by the caller thread. The task is not executing + * The task (repeating or not) has been successfully cancelled by the caller thread. The task is not executing
+ * currently, and it will not begin execution in the future. + * currently, and it will not begin execution in the future.
@ -390,7 +456,7 @@ index 0000000000000000000000000000000000000000..fa4ac300d3721b2d6d84b95618d33058
+ /** + /**
+ * Represents the current execution state of the task. + * Represents the current execution state of the task.
+ */ + */
+ public enum ExecutionState { + enum ExecutionState {
+ /** + /**
+ * The task is currently not executing, but may begin execution in the future. + * The task is currently not executing, but may begin execution in the future.
+ */ + */
@ -468,7 +534,7 @@ index ac9b690fcccb60b587e5345f12f1383afd0a73a1..7986b9fcaf256e9042f6d9ddc38e8bd7
@NotNull @NotNull
public static Server.Spigot spigot() { public static Server.Spigot spigot() {
diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java
index 2204336d8800311b65e894739ab1b27273e7c6f2..bf02c948a50d934e94c44f4844254a45ae7cb2a5 100644 index 2204336d8800311b65e894739ab1b27273e7c6f2..5caa00a413450dee18739f6430ffaf5095ea3036 100644
--- a/src/main/java/org/bukkit/Server.java --- a/src/main/java/org/bukkit/Server.java
+++ b/src/main/java/org/bukkit/Server.java +++ b/src/main/java/org/bukkit/Server.java
@@ -2139,4 +2139,36 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi @@ -2139,4 +2139,36 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi

View File

@ -116,7 +116,7 @@ index 7986b9fcaf256e9042f6d9ddc38e8bd76645cbb7..16043d6f7894182e8ff75a8faf57dedf
@NotNull @NotNull
diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java
index bf02c948a50d934e94c44f4844254a45ae7cb2a5..fea84620b25ac393be6d3253c100ddeac1983105 100644 index 5caa00a413450dee18739f6430ffaf5095ea3036..c72eee72401e275af57d4fd67a04df1eac13954c 100644
--- a/src/main/java/org/bukkit/Server.java --- a/src/main/java/org/bukkit/Server.java
+++ b/src/main/java/org/bukkit/Server.java +++ b/src/main/java/org/bukkit/Server.java
@@ -2170,5 +2170,83 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi @@ -2170,5 +2170,83 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi

View File

@ -9818,10 +9818,10 @@ index 0000000000000000000000000000000000000000..505329d601d56e42daa0b794092590cb
+} +}
diff --git a/src/main/java/io/papermc/paper/threadedregions/scheduler/FoliaRegionScheduler.java b/src/main/java/io/papermc/paper/threadedregions/scheduler/FoliaRegionScheduler.java diff --git a/src/main/java/io/papermc/paper/threadedregions/scheduler/FoliaRegionScheduler.java b/src/main/java/io/papermc/paper/threadedregions/scheduler/FoliaRegionScheduler.java
new file mode 100644 new file mode 100644
index 0000000000000000000000000000000000000000..b699e20df7a98b0dd8f783b293f4c4b47b868f2c index 0000000000000000000000000000000000000000..7ee75fe44507f79362f15d6445e32954dcc4308c
--- /dev/null --- /dev/null
+++ b/src/main/java/io/papermc/paper/threadedregions/scheduler/FoliaRegionScheduler.java +++ b/src/main/java/io/papermc/paper/threadedregions/scheduler/FoliaRegionScheduler.java
@@ -0,0 +1,430 @@ @@ -0,0 +1,422 @@
+package io.papermc.paper.threadedregions.scheduler; +package io.papermc.paper.threadedregions.scheduler;
+ +
+import ca.spottedleaf.concurrentutil.util.ConcurrentUtil; +import ca.spottedleaf.concurrentutil.util.ConcurrentUtil;
@ -9840,7 +9840,6 @@ index 0000000000000000000000000000000000000000..b699e20df7a98b0dd8f783b293f4c4b4
+import net.minecraft.server.level.TicketType; +import net.minecraft.server.level.TicketType;
+import net.minecraft.util.Unit; +import net.minecraft.util.Unit;
+import org.bukkit.Bukkit; +import org.bukkit.Bukkit;
+import org.bukkit.Location;
+import org.bukkit.World; +import org.bukkit.World;
+import org.bukkit.craftbukkit.CraftWorld; +import org.bukkit.craftbukkit.CraftWorld;
+import org.bukkit.plugin.IllegalPluginAccessException; +import org.bukkit.plugin.IllegalPluginAccessException;
@ -9854,12 +9853,13 @@ index 0000000000000000000000000000000000000000..b699e20df7a98b0dd8f783b293f4c4b4
+ +
+public final class FoliaRegionScheduler implements RegionScheduler { +public final class FoliaRegionScheduler implements RegionScheduler {
+ +
+ private static Runnable wrap(final Plugin plugin, final Location location, final Runnable run) { + private static Runnable wrap(final Plugin plugin, final World world, final int chunkX, final int chunkZ, final Runnable run) {
+ return () -> { + return () -> {
+ try { + try {
+ run.run(); + run.run();
+ } catch (final Throwable throwable) { + } catch (final Throwable throwable) {
+ plugin.getLogger().log(Level.WARNING, "Location task for " + plugin.getDescription().getFullName() + " at location " + location + " generated an exception", throwable); + plugin.getLogger().log(Level.WARNING, "Location task for " + plugin.getDescription().getFullName()
+ + " in world " + world + " at " + chunkX + ", " + chunkZ + " generated an exception", throwable);
+ } + }
+ }; + };
+ } + }
@ -9871,50 +9871,40 @@ index 0000000000000000000000000000000000000000..b699e20df7a98b0dd8f783b293f4c4b4
+ } + }
+ +
+ private static void scheduleInternalOffRegion(final LocationScheduledTask task, final int delay) { + private static void scheduleInternalOffRegion(final LocationScheduledTask task, final int delay) {
+ final Location location = task.location; + final World world = task.world;
+ if (location == null) { + if (world == null) {
+ // cancelled + // cancelled
+ return; + return;
+ } + }
+ +
+ final World world = Validate.notNull(location.getWorld(), "Location world may not be null");
+
+ final int chunkX = location.getBlockX() >> 4;
+ final int chunkZ = location.getBlockZ() >> 4;
+
+ RegionizedServer.getInstance().taskQueue.queueTickTaskQueue( + RegionizedServer.getInstance().taskQueue.queueTickTaskQueue(
+ ((CraftWorld)world).getHandle(), chunkX, chunkZ, () -> { + ((CraftWorld) world).getHandle(), task.chunkX, task.chunkZ, () -> {
+ scheduleInternalOnRegion(task, delay); + scheduleInternalOnRegion(task, delay);
+ } + }
+ ); + );
+ } + }
+ +
+ @Override + @Override
+ public void execute(final Plugin plugin, final Location location, final Runnable run) { + public void execute(final Plugin plugin, final World world, final int chunkX, final int chunkZ, final Runnable run) {
+ Validate.notNull(plugin, "Plugin may not be null"); + Validate.notNull(plugin, "Plugin may not be null");
+ Validate.notNull(location, "Location may not be null"); + Validate.notNull(world, "World may not be null");
+ Validate.notNull(run, "Runnable may not be null"); + Validate.notNull(run, "Runnable may not be null");
+ +
+ final World world = Validate.notNull(location.getWorld(), "Location world may not be null");
+
+ final int chunkX = location.getBlockX() >> 4;
+ final int chunkZ = location.getBlockZ() >> 4;
+
+ RegionizedServer.getInstance().taskQueue.queueTickTaskQueue( + RegionizedServer.getInstance().taskQueue.queueTickTaskQueue(
+ ((CraftWorld)world).getHandle(), chunkX, chunkZ, wrap(plugin, location.clone(), run) + ((CraftWorld) world).getHandle(), chunkX, chunkZ, wrap(plugin, world, chunkX, chunkZ, run)
+ ); + );
+ } + }
+ +
+ @Override + @Override
+ public ScheduledTask run(final Plugin plugin, final Location location, final Consumer<ScheduledTask> task) { + public ScheduledTask run(final Plugin plugin, final World world, final int chunkX, final int chunkZ, final Consumer<ScheduledTask> task) {
+ return this.runDelayed(plugin, location, task, 1); + return this.runDelayed(plugin, world, chunkX, chunkZ, task, 1);
+ } + }
+ +
+ @Override + @Override
+ public ScheduledTask runDelayed(final Plugin plugin, Location location, final Consumer<ScheduledTask> task, + public ScheduledTask runDelayed(final Plugin plugin, final World world, final int chunkX, final int chunkZ,
+ final int delayTicks) { + final Consumer<ScheduledTask> task, final int delayTicks) {
+ Validate.notNull(plugin, "Plugin may not be null"); + Validate.notNull(plugin, "Plugin may not be null");
+ Validate.notNull(location, "Location may not be null"); + Validate.notNull(world, "World may not be null");
+ Validate.notNull(task, "Task may not be null"); + Validate.notNull(task, "Task may not be null");
+ if (delayTicks <= 0) { + if (delayTicks <= 0) {
+ throw new IllegalArgumentException("Delay ticks may not be <= 0"); + throw new IllegalArgumentException("Delay ticks may not be <= 0");
@ -9924,11 +9914,9 @@ index 0000000000000000000000000000000000000000..b699e20df7a98b0dd8f783b293f4c4b4
+ throw new IllegalPluginAccessException("Plugin attempted to register task while disabled"); + throw new IllegalPluginAccessException("Plugin attempted to register task while disabled");
+ } + }
+ +
+ location = location.clone(); + final LocationScheduledTask ret = new LocationScheduledTask(plugin, world, chunkX, chunkZ, -1, task);
+ +
+ final LocationScheduledTask ret = new LocationScheduledTask(plugin, location, -1, task); + if (Bukkit.isOwnedByCurrentRegion(world, chunkX, chunkZ)) {
+
+ if (Bukkit.isOwnedByCurrentRegion(location)) {
+ scheduleInternalOnRegion(ret, delayTicks); + scheduleInternalOnRegion(ret, delayTicks);
+ } else { + } else {
+ scheduleInternalOffRegion(ret, delayTicks); + scheduleInternalOffRegion(ret, delayTicks);
@ -9943,10 +9931,10 @@ index 0000000000000000000000000000000000000000..b699e20df7a98b0dd8f783b293f4c4b4
+ } + }
+ +
+ @Override + @Override
+ public ScheduledTask runAtFixedRate(final Plugin plugin, Location location, final Consumer<ScheduledTask> task, + public ScheduledTask runAtFixedRate(final Plugin plugin, final World world, final int chunkX, final int chunkZ,
+ final int initialDelayTicks, final int periodTicks) { + final Consumer<ScheduledTask> task, final int initialDelayTicks, final int periodTicks) {
+ Validate.notNull(plugin, "Plugin may not be null"); + Validate.notNull(plugin, "Plugin may not be null");
+ Validate.notNull(location, "Location may not be null"); + Validate.notNull(world, "World may not be null");
+ Validate.notNull(task, "Task may not be null"); + Validate.notNull(task, "Task may not be null");
+ if (initialDelayTicks <= 0) { + if (initialDelayTicks <= 0) {
+ throw new IllegalArgumentException("Initial delay ticks may not be <= 0"); + throw new IllegalArgumentException("Initial delay ticks may not be <= 0");
@ -9959,11 +9947,9 @@ index 0000000000000000000000000000000000000000..b699e20df7a98b0dd8f783b293f4c4b4
+ throw new IllegalPluginAccessException("Plugin attempted to register task while disabled"); + throw new IllegalPluginAccessException("Plugin attempted to register task while disabled");
+ } + }
+ +
+ location = location.clone(); + final LocationScheduledTask ret = new LocationScheduledTask(plugin, world, chunkX, chunkZ, periodTicks, task);
+ +
+ final LocationScheduledTask ret = new LocationScheduledTask(plugin, location, periodTicks, task); + if (Bukkit.isOwnedByCurrentRegion(world, chunkX, chunkZ)) {
+
+ if (Bukkit.isOwnedByCurrentRegion(location)) {
+ scheduleInternalOnRegion(ret, initialDelayTicks); + scheduleInternalOnRegion(ret, initialDelayTicks);
+ } else { + } else {
+ scheduleInternalOffRegion(ret, initialDelayTicks); + scheduleInternalOffRegion(ret, initialDelayTicks);
@ -10054,14 +10040,14 @@ index 0000000000000000000000000000000000000000..b699e20df7a98b0dd8f783b293f4c4b4
+ // note: must be on the thread that owns this scheduler + // note: must be on the thread that owns this scheduler
+ // note: delay > 0 + // note: delay > 0
+ +
+ final Location location = task.location; + final World world = task.world;
+ if (location == null) { + if (world == null) {
+ // cancelled + // cancelled
+ return; + return;
+ } + }
+ +
+ final int sectionX = (location.getBlockX() >> 4) >> TickRegions.getRegionChunkShift(); + final int sectionX = task.chunkX >> TickRegions.getRegionChunkShift();
+ final int sectionZ = (location.getBlockZ() >> 4) >> TickRegions.getRegionChunkShift(); + final int sectionZ = task.chunkZ >> TickRegions.getRegionChunkShift();
+ +
+ final Long2ObjectOpenHashMap<List<LocationScheduledTask>> section = + final Long2ObjectOpenHashMap<List<LocationScheduledTask>> section =
+ this.tasksByDeadlineBySection.computeIfAbsent(CoordinateUtils.getChunkKey(sectionX, sectionZ), (final long keyInMap) -> { + this.tasksByDeadlineBySection.computeIfAbsent(CoordinateUtils.getChunkKey(sectionX, sectionZ), (final long keyInMap) -> {
@ -10119,16 +10105,21 @@ index 0000000000000000000000000000000000000000..b699e20df7a98b0dd8f783b293f4c4b4
+ private static final int STATE_CANCELLED = 4; + private static final int STATE_CANCELLED = 4;
+ +
+ private final Plugin plugin; + private final Plugin plugin;
+ private Location location; + private final int chunkX;
+ private final int chunkZ;
+ private final int repeatDelay; // in ticks + private final int repeatDelay; // in ticks
+ private World world;
+ private Consumer<ScheduledTask> run; + private Consumer<ScheduledTask> run;
+ +
+ private volatile int state; + private volatile int state;
+ private static final VarHandle STATE_HANDLE = ConcurrentUtil.getVarHandle(LocationScheduledTask.class, "state", int.class); + private static final VarHandle STATE_HANDLE = ConcurrentUtil.getVarHandle(LocationScheduledTask.class, "state", int.class);
+ +
+ private LocationScheduledTask(final Plugin plugin, final Location location, final int repeatDelay, final Consumer<ScheduledTask> run) { + private LocationScheduledTask(final Plugin plugin, final World world, final int chunkX, final int chunkZ,
+ final int repeatDelay, final Consumer<ScheduledTask> run) {
+ this.plugin = plugin; + this.plugin = plugin;
+ this.location = location; + this.world = world;
+ this.chunkX = chunkX;
+ this.chunkZ = chunkZ;
+ this.repeatDelay = repeatDelay; + this.repeatDelay = repeatDelay;
+ this.run = run; + this.run = run;
+ } + }
@ -10161,7 +10152,8 @@ index 0000000000000000000000000000000000000000..b699e20df7a98b0dd8f783b293f4c4b4
+ try { + try {
+ this.run.accept(this); + this.run.accept(this);
+ } catch (final Throwable throwable) { + } catch (final Throwable throwable) {
+ this.plugin.getLogger().log(Level.WARNING, "Location task for " + this.plugin.getDescription().getFullName() + " at location " + this.location + " generated an exception", throwable); + this.plugin.getLogger().log(Level.WARNING, "Location task for " + this.plugin.getDescription().getFullName()
+ + " in world " + world + " at " + chunkX + ", " + chunkZ + " generated an exception", throwable);
+ } finally { + } finally {
+ boolean reschedule = false; + boolean reschedule = false;
+ if (!repeating) { + if (!repeating) {
@ -10174,7 +10166,7 @@ index 0000000000000000000000000000000000000000..b699e20df7a98b0dd8f783b293f4c4b4
+ +
+ if (!reschedule) { + if (!reschedule) {
+ this.run = null; + this.run = null;
+ this.location = null; + this.world = null;
+ } else { + } else {
+ FoliaRegionScheduler.scheduleInternalOnRegion(this, this.repeatDelay); + FoliaRegionScheduler.scheduleInternalOnRegion(this, this.repeatDelay);
+ } + }
@ -10199,7 +10191,7 @@ index 0000000000000000000000000000000000000000..b699e20df7a98b0dd8f783b293f4c4b4
+ if (STATE_IDLE == (curr = this.compareAndExchangeStateVolatile(STATE_IDLE, STATE_CANCELLED))) { + if (STATE_IDLE == (curr = this.compareAndExchangeStateVolatile(STATE_IDLE, STATE_CANCELLED))) {
+ this.state = STATE_CANCELLED; + this.state = STATE_CANCELLED;
+ this.run = null; + this.run = null;
+ this.location = null; + this.world = null;
+ return CancelledState.CANCELLED_BY_CALLER; + return CancelledState.CANCELLED_BY_CALLER;
+ } + }
+ // try again + // try again