From ba6fac5422824062031de930de2362676b56e0f5 Mon Sep 17 00:00:00 2001 From: Julian Krings Date: Fri, 13 Jun 2025 21:05:11 +0200 Subject: [PATCH] more helper methods --- .../paper/split/PaperAsyncScheduler.java | 4 +- .../scheduling/split/IAsyncScheduler.java | 73 ++++++++- .../scheduling/split/IEntityScheduler.java | 114 ++++++++++++++ .../scheduling/split/IGlobalScheduler.java | 65 ++++++++ .../scheduling/split/IRegionScheduler.java | 146 ++++++++++++++++++ 5 files changed, 399 insertions(+), 3 deletions(-) diff --git a/scheduler/src/main/java/com/volmit/iris/util/scheduling/paper/split/PaperAsyncScheduler.java b/scheduler/src/main/java/com/volmit/iris/util/scheduling/paper/split/PaperAsyncScheduler.java index f35b644b6..6eb38f052 100644 --- a/scheduler/src/main/java/com/volmit/iris/util/scheduling/paper/split/PaperAsyncScheduler.java +++ b/scheduler/src/main/java/com/volmit/iris/util/scheduling/paper/split/PaperAsyncScheduler.java @@ -31,7 +31,7 @@ public class PaperAsyncScheduler implements IAsyncScheduler { @Override public @NotNull Completable runDelayed(@NotNull Function, R> task, - @Range(from = 1, to = Long.MAX_VALUE) long delay, + @Range(from = 0, to = Long.MAX_VALUE) long delay, @NotNull TimeUnit unit) { Ref> ref = new Ref<>(); return ref.value = new PaperTask.Completable<>(scheduler.runDelayed(plugin, t -> ref.value.complete(task), delay, unit), true); @@ -39,7 +39,7 @@ public class PaperAsyncScheduler implements IAsyncScheduler { @Override public @NotNull Task runAtFixedRate(@NotNull Consumer task, - @Range(from = 1, to = Long.MAX_VALUE) long initialDelay, + @Range(from = 0, to = Long.MAX_VALUE) long initialDelay, @Range(from = 1, to = Long.MAX_VALUE) long period, @NotNull TimeUnit unit) { Ref ref = new Ref<>(); diff --git a/scheduler/src/main/java/com/volmit/iris/util/scheduling/split/IAsyncScheduler.java b/scheduler/src/main/java/com/volmit/iris/util/scheduling/split/IAsyncScheduler.java index d4b91cf80..5a5968be3 100644 --- a/scheduler/src/main/java/com/volmit/iris/util/scheduling/split/IAsyncScheduler.java +++ b/scheduler/src/main/java/com/volmit/iris/util/scheduling/split/IAsyncScheduler.java @@ -8,6 +8,7 @@ import org.jetbrains.annotations.Range; import java.util.concurrent.TimeUnit; import java.util.function.Consumer; import java.util.function.Function; +import java.util.function.Supplier; /** * Scheduler that may be used by plugins to schedule tasks to execute asynchronously from the server tick process. @@ -25,6 +26,29 @@ public interface IAsyncScheduler { }); } + /** + * Schedules the specified task to be executed asynchronously immediately. + * @param task Specified task. + * @return The {@link Task} that represents the scheduled task. + */ + default @NotNull Task run(@NotNull Runnable task) { + return run(t -> { + task.run(); + return null; + }); + } + + /** + * Schedules the specified task to be executed asynchronously immediately. + * @param task Specified task. + * @return The {@link Completable} that represents the scheduled task. + */ + default @NotNull Completable run(@NotNull Supplier task) { + return run(t -> { + return task.get(); + }); + } + /** * Schedules the specified task to be executed asynchronously immediately. * @param task Specified task. @@ -48,6 +72,37 @@ public interface IAsyncScheduler { }, delay, unit); } + /** + * Schedules the specified task to be executed asynchronously after the time delay has passed. + * @param task Specified task. + * @param delay The time delay to pass before the task should be executed. + * @param unit The time unit for the time delay. + * @return The {@link Task} that represents the scheduled task. + */ + default @NotNull Task runDelayed(@NotNull Runnable task, + @Range(from = 0, to = Long.MAX_VALUE) long delay, + @NotNull TimeUnit unit) { + return runDelayed(t -> { + task.run(); + return null; + }, delay, unit); + } + + /** + * Schedules the specified task to be executed asynchronously after the time delay has passed. + * @param task Specified task. + * @param delay The time delay to pass before the task should be executed. + * @param unit The time unit for the time delay. + * @return The {@link Completable} that represents the scheduled task. + */ + default @NotNull Completable runDelayed(@NotNull Supplier task, + @Range(from = 0, to = Long.MAX_VALUE) long delay, + @NotNull TimeUnit unit) { + return runDelayed(t -> { + return task.get(); + }, delay, unit); + } + /** * Schedules the specified task to be executed asynchronously after the time delay has passed. * @param task Specified task. @@ -59,6 +114,22 @@ public interface IAsyncScheduler { @Range(from = 0, to = Long.MAX_VALUE) long delay, @NotNull TimeUnit unit); + /** + * Schedules the specified task to be executed asynchronously after the initial delay has passed, + * and then periodically executed with the specified period. + * @param task Specified task. + * @param initialDelay The time delay to pass before the first execution of the task. + * @param period The time between task executions after the first execution of the task. + * @param unit The time unit for the initial delay and period. + * @return The {@link Task} that represents the scheduled task. + */ + default @NotNull Task runAtFixedRate(@NotNull Runnable task, + @Range(from = 0, to = Long.MAX_VALUE) long initialDelay, + @Range(from = 1, to = Long.MAX_VALUE) long period, + @NotNull TimeUnit unit) { + return runAtFixedRate(t -> task.run(), initialDelay, period, unit); + } + /** * Schedules the specified task to be executed asynchronously after the initial delay has passed, * and then periodically executed with the specified period. @@ -70,6 +141,6 @@ public interface IAsyncScheduler { */ @NotNull Task runAtFixedRate(@NotNull Consumer task, @Range(from = 0, to = Long.MAX_VALUE) long initialDelay, - @Range(from = 0, to = Long.MAX_VALUE) long period, + @Range(from = 1, to = Long.MAX_VALUE) long period, @NotNull TimeUnit unit); } diff --git a/scheduler/src/main/java/com/volmit/iris/util/scheduling/split/IEntityScheduler.java b/scheduler/src/main/java/com/volmit/iris/util/scheduling/split/IEntityScheduler.java index 0bfc22124..141630a12 100644 --- a/scheduler/src/main/java/com/volmit/iris/util/scheduling/split/IEntityScheduler.java +++ b/scheduler/src/main/java/com/volmit/iris/util/scheduling/split/IEntityScheduler.java @@ -8,6 +8,7 @@ import org.jetbrains.annotations.Range; import java.util.function.Consumer; import java.util.function.Function; +import java.util.function.Supplier; /** * An entity can move between worlds with an arbitrary tick delay, be temporarily removed @@ -51,6 +52,49 @@ public interface IEntityScheduler { }, retired); } + /** + * Schedules a task to execute on the next tick. If the task failed to schedule because the scheduler is retired (entity + * removed), then returns {@code null}. Otherwise, either the task callback will be invoked after the specified delay, + * or the retired callback will be invoked if the scheduler is retired. + * Note that the retired callback is invoked in critical code, so it should not attempt to remove the entity, remove + * other entities, load chunks, load worlds, modify ticket levels, etc. + * + *

+ * It is guaranteed that the task and retired callback are invoked on the region which owns the entity. + *

+ * @param task The task to execute + * @param retired Retire callback to run if the entity is retired before the run callback can be invoked, may be null. + * @return The {@link Task} that represents the scheduled task, or {@code null} if the entity has been removed. + */ + default @Nullable Task run(@NotNull Runnable task, + @Nullable Runnable retired) { + return run(t -> { + task.run(); + return null; + }, retired); + } + + /** + * Schedules a task to execute on the next tick. If the task failed to schedule because the scheduler is retired (entity + * removed), then returns {@code null}. Otherwise, either the task callback will be invoked after the specified delay, + * or the retired callback will be invoked if the scheduler is retired. + * Note that the retired callback is invoked in critical code, so it should not attempt to remove the entity, remove + * other entities, load chunks, load worlds, modify ticket levels, etc. + * + *

+ * It is guaranteed that the task and retired callback are invoked on the region which owns the entity. + *

+ * @param task The task to execute + * @param retired Retire callback to run if the entity is retired before the run callback can be invoked, may be null. + * @return The {@link Completable} that represents the scheduled task, or {@code null} if the entity has been removed. + */ + default @Nullable Completable run(@NotNull Supplier task, + @Nullable Runnable retired) { + return run(t -> { + return task.get(); + }, retired); + } + /** * Schedules a task to execute on the next tick. If the task failed to schedule because the scheduler is retired (entity * removed), then returns {@code null}. Otherwise, either the task callback will be invoked after the specified delay, @@ -94,6 +138,53 @@ public interface IEntityScheduler { }, retired, delayTicks); } + /** + * Schedules a task with the given delay. If the task failed to schedule because the scheduler is retired (entity + * removed), then returns {@code null}. Otherwise, either the task callback will be invoked after the specified delay, + * or the retired callback will be invoked if the scheduler is retired. + * Note that the retired callback is invoked in critical code, so it should not attempt to remove the entity, remove + * other entities, load chunks, load worlds, modify ticket levels, etc. + * + *

+ * It is guaranteed that the task and retired callback are invoked on the region which owns the entity. + *

+ * @param task The task to execute + * @param retired Retire callback to run if the entity is retired before the run callback can be invoked, may be null. + * @param delayTicks The delay, in ticks. + * @return The {@link Task} that represents the scheduled task, or {@code null} if the entity has been removed. + */ + default @Nullable Task runDelayed(@NotNull Runnable task, + @Nullable Runnable retired, + @Range(from = 1, to = Long.MAX_VALUE) long delayTicks) { + return runDelayed(t -> { + task.run(); + return null; + }, retired, delayTicks); + } + + /** + * Schedules a task with the given delay. If the task failed to schedule because the scheduler is retired (entity + * removed), then returns {@code null}. Otherwise, either the task callback will be invoked after the specified delay, + * or the retired callback will be invoked if the scheduler is retired. + * Note that the retired callback is invoked in critical code, so it should not attempt to remove the entity, remove + * other entities, load chunks, load worlds, modify ticket levels, etc. + * + *

+ * It is guaranteed that the task and retired callback are invoked on the region which owns the entity. + *

+ * @param task The task to execute + * @param retired Retire callback to run if the entity is retired before the run callback can be invoked, may be null. + * @param delayTicks The delay, in ticks. + * @return The {@link Completable} that represents the scheduled task, or {@code null} if the entity has been removed. + */ + default @Nullable Completable runDelayed(@NotNull Supplier task, + @Nullable Runnable retired, + @Range(from = 1, to = Long.MAX_VALUE) long delayTicks) { + return runDelayed(t -> { + return task.get(); + }, retired, delayTicks); + } + /** * Schedules a task with the given delay. If the task failed to schedule because the scheduler is retired (entity * removed), then returns {@code null}. Otherwise, either the task callback will be invoked after the specified delay, @@ -113,6 +204,29 @@ public interface IEntityScheduler { @Nullable Runnable retired, @Range(from = 1, to = Long.MAX_VALUE) long delayTicks); + /** + * Schedules a repeating task with the given delay and period. If the task failed to schedule because the scheduler + * is retired (entity removed), then returns {@code null}. Otherwise, either the task callback will be invoked after + * the specified delay, or the retired callback will be invoked if the scheduler is retired. + * Note that the retired callback is invoked in critical code, so it should not attempt to remove the entity, remove + * other entities, load chunks, load worlds, modify ticket levels, etc. + * + *

+ * It is guaranteed that the task and retired callback are invoked on the region which owns the entity. + *

+ * @param task The task to execute + * @param retired Retire callback to run if the entity is retired before the run callback can be invoked, may be null. + * @param initialDelayTicks The initial delay, in ticks. + * @param periodTicks The period, in ticks. + * @return The {@link Task} that represents the scheduled task, or {@code null} if the entity has been removed. + */ + default @Nullable Task runAtFixedRate(@NotNull Runnable task, + @Nullable Runnable retired, + @Range(from = 1, to = Long.MAX_VALUE) long initialDelayTicks, + @Range(from = 1, to = Long.MAX_VALUE) long periodTicks) { + return runAtFixedRate(t -> task.run(), retired, initialDelayTicks, periodTicks); + } + /** * Schedules a repeating task with the given delay and period. If the task failed to schedule because the scheduler * is retired (entity removed), then returns {@code null}. Otherwise, either the task callback will be invoked after diff --git a/scheduler/src/main/java/com/volmit/iris/util/scheduling/split/IGlobalScheduler.java b/scheduler/src/main/java/com/volmit/iris/util/scheduling/split/IGlobalScheduler.java index 9dea29cb8..5644443ee 100644 --- a/scheduler/src/main/java/com/volmit/iris/util/scheduling/split/IGlobalScheduler.java +++ b/scheduler/src/main/java/com/volmit/iris/util/scheduling/split/IGlobalScheduler.java @@ -7,6 +7,7 @@ import org.jetbrains.annotations.Range; import java.util.function.Consumer; import java.util.function.Function; +import java.util.function.Supplier; /** * The global region task scheduler may be used to schedule tasks that will execute on the global region. @@ -28,6 +29,29 @@ public interface IGlobalScheduler { }); } + /** + * Schedules a task to be executed on the global region on the next tick. + * @param task The task to execute + * @return The {@link Task} that represents the scheduled task. + */ + default @NotNull Task run(@NotNull Runnable task) { + return run(t -> { + task.run(); + return null; + }); + } + + /** + * Schedules a task to be executed on the global region on the next tick. + * @param task The task to execute + * @return The {@link Completable} that represents the scheduled task. + */ + default @NotNull Completable run(@NotNull Supplier task) { + return run(t -> { + return task.get(); + }); + } + /** * Schedules a task to be executed on the global region on the next tick. * @param task The task to execute @@ -51,6 +75,33 @@ public interface IGlobalScheduler { }, delayTicks); } + /** + * Schedules a task to be executed on the global region after the specified delay in ticks. + * @param task The task to execute + * @param delayTicks The delay, in ticks. + * @return The {@link Task} that represents the scheduled task. + */ + default @NotNull Task runDelayed(@NotNull Runnable task, + @Range(from = 1, to = Long.MAX_VALUE) long delayTicks) { + return runDelayed(t -> { + task.run(); + return null; + }, delayTicks); + } + + /** + * Schedules a task to be executed on the global region after the specified delay in ticks. + * @param task The task to execute + * @param delayTicks The delay, in ticks. + * @return The {@link Completable} that represents the scheduled task. + */ + default @NotNull Completable runDelayed(@NotNull Supplier task, + @Range(from = 1, to = Long.MAX_VALUE) long delayTicks) { + return runDelayed(t -> { + return task.get(); + }, delayTicks); + } + /** * Schedules a task to be executed on the global region after the specified delay in ticks. * @param task The task to execute @@ -60,6 +111,20 @@ public interface IGlobalScheduler { @NotNull Completable runDelayed(@NotNull Function, R> task, @Range(from = 1, to = Long.MAX_VALUE) long delayTicks); + /** + * Schedules a repeating task to be executed on the global region after the initial delay with the + * specified period. + * @param task The task to execute + * @param initialDelayTicks The initial delay, in ticks. + * @param periodTicks The period, in ticks. + * @return The {@link Task} that represents the scheduled task. + */ + default @NotNull Task runAtFixedRate(@NotNull Runnable task, + @Range(from = 1, to = Long.MAX_VALUE) long initialDelayTicks, + @Range(from = 1, to = Long.MAX_VALUE) long periodTicks) { + return runAtFixedRate(t -> task.run(), initialDelayTicks, periodTicks); + } + /** * Schedules a repeating task to be executed on the global region after the initial delay with the * specified period. diff --git a/scheduler/src/main/java/com/volmit/iris/util/scheduling/split/IRegionScheduler.java b/scheduler/src/main/java/com/volmit/iris/util/scheduling/split/IRegionScheduler.java index 55607f2b9..b57a07038 100644 --- a/scheduler/src/main/java/com/volmit/iris/util/scheduling/split/IRegionScheduler.java +++ b/scheduler/src/main/java/com/volmit/iris/util/scheduling/split/IRegionScheduler.java @@ -10,6 +10,7 @@ import org.jetbrains.annotations.Range; import java.util.function.Consumer; import java.util.function.Function; +import java.util.function.Supplier; /** * The region task scheduler can be used to schedule tasks by location to be executed on the region which owns the location. @@ -40,6 +41,43 @@ public interface IRegionScheduler { }); } + /** + * Schedules a task to be executed on the region which owns the location on the next tick. + * + * @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 + * @return The {@link Task} that represents the scheduled task. + */ + default @NotNull Task run(@NotNull World world, + int chunkX, + int chunkZ, + @NotNull Runnable task) { + return run(world, chunkX, chunkZ, t -> { + task.run(); + return null; + }); + } + + /** + * Schedules a task to be executed on the region which owns the location on the next tick. + * + * @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 + * @return The {@link Completable} that represents the scheduled task. + */ + default @NotNull Completable run(@NotNull World world, + int chunkX, + int chunkZ, + @NotNull Supplier task) { + return run(world, chunkX, chunkZ, t -> { + return task.get(); + }); + } + /** * Schedules a task to be executed on the region which owns the location on the next tick. * @@ -68,6 +106,34 @@ public interface IRegionScheduler { return run(location.getWorld(), location.getBlockX() >> 4, location.getBlockZ() >> 4, task); } + /** + * Schedules a task to be executed on the region which owns the location on the next tick. + * + * @param location The location at which the region executing should own + * @param task The task to execute + * @return The {@link Task} that represents the scheduled task. + */ + default @NotNull Task run(@NotNull Location location, + @NotNull Runnable task) { + return run(location, t -> { + task.run(); + }); + } + + /** + * Schedules a task to be executed on the region which owns the location on the next tick. + * + * @param location The location at which the region executing should own + * @param task The task to execute + * @return The {@link Completable} that represents the scheduled task. + */ + default @NotNull Completable run(@NotNull Location location, + @NotNull Supplier task) { + return run(location, t -> { + return task.get(); + }); + } + /** * Schedules a task to be executed on the region which owns the location on the next tick. * @@ -101,6 +167,47 @@ public interface IRegionScheduler { }, delayTicks); } + /** + * Schedules a task to be executed on the region which owns the location after the specified delay in ticks. + * + * @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. + * @return The {@link Task} that represents the scheduled task. + */ + default @NotNull Task runDelayed(@NotNull World world, + int chunkX, + int chunkZ, + @NotNull Runnable task, + @Range(from = 1, to = Long.MAX_VALUE) long delayTicks) { + return runDelayed(world, chunkX, chunkZ, t -> { + task.run(); + return null; + }, delayTicks); + } + + /** + * Schedules a task to be executed on the region which owns the location after the specified delay in ticks. + * + * @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. + * @return The {@link Completable} that represents the scheduled task. + */ + default @NotNull Completable runDelayed(@NotNull World world, + int chunkX, + int chunkZ, + @NotNull Supplier task, + @Range(from = 1, to = Long.MAX_VALUE) long delayTicks) { + return runDelayed(world, chunkX, chunkZ, t -> { + return task.get(); + }, delayTicks); + } + /** * Schedules a task to be executed on the region which owns the location after the specified delay in ticks. * @@ -130,6 +237,7 @@ public interface IRegionScheduler { @Range(from = 1, to = Long.MAX_VALUE) long delayTicks) { return runDelayed(location.getWorld(), location.getBlockX() >> 4, location.getBlockZ() >> 4, task, delayTicks); } + /** * Schedules a task to be executed on the region which owns the location after the specified delay in ticks. * @@ -144,6 +252,27 @@ public interface IRegionScheduler { return runDelayed(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 + * specified period. + * + * @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 periodTicks The period, in ticks. + * @return The {@link Task} that represents the scheduled task. + */ + default @NotNull Task runAtFixedRate(@NotNull World world, + int chunkX, + int chunkZ, + @NotNull Runnable task, + @Range(from = 1, to = Long.MAX_VALUE) long initialDelayTicks, + @Range(from = 1, to = Long.MAX_VALUE) long periodTicks) { + return runAtFixedRate(world, chunkX, chunkZ, t -> task.run(), initialDelayTicks, periodTicks); + } + /** * Schedules a repeating task to be executed on the region which owns the location after the initial delay with the * specified period. @@ -163,6 +292,23 @@ public interface IRegionScheduler { @Range(from = 1, to = Long.MAX_VALUE) long initialDelayTicks, @Range(from = 1, to = Long.MAX_VALUE) long periodTicks); + /** + * Schedules a repeating task to be executed on the region which owns the location after the initial delay with the + * specified period. + * + * @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 Task} that represents the scheduled task. + */ + default @NotNull Task runAtFixedRate(@NotNull Location location, + @NotNull Runnable task, + @Range(from = 1, to = Long.MAX_VALUE) long initialDelayTicks, + @Range(from = 1, to = Long.MAX_VALUE) long periodTicks) { + return runAtFixedRate(location, t -> task.run(), initialDelayTicks, periodTicks); + } + /** * Schedules a repeating task to be executed on the region which owns the location after the initial delay with the * specified period.