mirror of
https://github.com/PlaceholderAPI/PlaceholderAPI
synced 2025-09-05 17:07:06 +02:00
Merge UniversalScheduler
This commit is contained in:
@@ -20,13 +20,15 @@ repositories {
|
||||
|
||||
maven("https://repo.codemc.org/repository/maven-public/")
|
||||
maven("https://hub.spigotmc.org/nexus/content/repositories/snapshots/")
|
||||
maven("https://repo.papermc.io/repository/maven-public/")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation("org.bstats:bstats-bukkit:3.0.1")
|
||||
implementation("net.kyori:adventure-platform-bukkit:4.3.3")
|
||||
|
||||
compileOnly("org.spigotmc:spigot-api:1.21-R0.1-SNAPSHOT")
|
||||
//compileOnly("org.spigotmc:spigot-api:1.21-R0.1-SNAPSHOT")
|
||||
compileOnly("dev.folia:folia-api:1.20.1-R0.1-SNAPSHOT")
|
||||
compileOnlyApi("org.jetbrains:annotations:23.0.0")
|
||||
|
||||
testImplementation("org.openjdk.jmh:jmh-core:1.32")
|
||||
|
@@ -31,6 +31,8 @@ import me.clip.placeholderapi.expansion.Version;
|
||||
import me.clip.placeholderapi.expansion.manager.CloudExpansionManager;
|
||||
import me.clip.placeholderapi.expansion.manager.LocalExpansionManager;
|
||||
import me.clip.placeholderapi.listeners.ServerLoadEventListener;
|
||||
import me.clip.placeholderapi.scheduler.UniversalScheduler;
|
||||
import me.clip.placeholderapi.scheduler.scheduling.schedulers.TaskScheduler;
|
||||
import me.clip.placeholderapi.updatechecker.UpdateChecker;
|
||||
import me.clip.placeholderapi.util.Msg;
|
||||
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
|
||||
@@ -86,9 +88,12 @@ public final class PlaceholderAPIPlugin extends JavaPlugin {
|
||||
private final LocalExpansionManager localExpansionManager = new LocalExpansionManager(this);
|
||||
@NotNull
|
||||
private final CloudExpansionManager cloudExpansionManager = new CloudExpansionManager(this);
|
||||
@NotNull
|
||||
private final TaskScheduler scheduler = UniversalScheduler.getScheduler(this);
|
||||
|
||||
private BukkitAudiences adventure;
|
||||
|
||||
|
||||
/**
|
||||
* Gets the static instance of the main class for PlaceholderAPI. This class is not the actual API
|
||||
* class, this is the main class that extends JavaPlugin. For most API methods, use static methods
|
||||
@@ -174,7 +179,7 @@ public final class PlaceholderAPIPlugin extends JavaPlugin {
|
||||
|
||||
HandlerList.unregisterAll(this);
|
||||
|
||||
Bukkit.getScheduler().cancelTasks(this);
|
||||
scheduler.cancelTasks(this);
|
||||
|
||||
adventure.close();
|
||||
adventure = null;
|
||||
@@ -215,6 +220,11 @@ public final class PlaceholderAPIPlugin extends JavaPlugin {
|
||||
return adventure;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public TaskScheduler getScheduler() {
|
||||
return scheduler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtain the configuration class for PlaceholderAPI.
|
||||
*
|
||||
@@ -262,8 +272,8 @@ public final class PlaceholderAPIPlugin extends JavaPlugin {
|
||||
Class.forName("org.bukkit.event.server.ServerLoadEvent");
|
||||
new ServerLoadEventListener(this);
|
||||
} catch (final ClassNotFoundException ignored) {
|
||||
Bukkit.getScheduler()
|
||||
.runTaskLater(this, () -> getLocalExpansionManager().load(Bukkit.getConsoleSender()), 1);
|
||||
scheduler
|
||||
.runTaskLater(() -> getLocalExpansionManager().load(Bukkit.getConsoleSender()), 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -202,10 +202,8 @@ public final class CloudExpansionManager {
|
||||
|
||||
// loop through what's left on the main thread
|
||||
plugin
|
||||
.getServer()
|
||||
.getScheduler()
|
||||
.runTask(
|
||||
plugin,
|
||||
() -> {
|
||||
try {
|
||||
for (Map.Entry<String, CloudExpansion> entry : values.entrySet()) {
|
||||
|
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2023 Sevastjan
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.clip.placeholderapi.scheduler;
|
||||
|
||||
import me.clip.placeholderapi.scheduler.scheduling.schedulers.TaskScheduler;
|
||||
import me.clip.placeholderapi.scheduler.scheduling.tasks.MyScheduledTask;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
/** Just modified BukkitRunnable */
|
||||
public abstract class UniversalRunnable implements Runnable {
|
||||
MyScheduledTask task;
|
||||
|
||||
public synchronized void cancel() throws IllegalStateException {
|
||||
checkScheduled();
|
||||
task.cancel();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this task has been cancelled.
|
||||
*
|
||||
* @return true if the task has been cancelled
|
||||
* @throws IllegalStateException if task was not scheduled yet
|
||||
*/
|
||||
public synchronized boolean isCancelled() throws IllegalStateException {
|
||||
checkScheduled();
|
||||
return task.isCancelled();
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedules this in the Bukkit scheduler to run on next tick.
|
||||
*
|
||||
* @param plugin the reference to the plugin scheduling task
|
||||
* @return {@link MyScheduledTask}
|
||||
* @throws IllegalArgumentException if plugin is null
|
||||
* @throws IllegalStateException if this was already scheduled
|
||||
* @see TaskScheduler#runTask(Runnable)
|
||||
*/
|
||||
|
||||
public synchronized MyScheduledTask runTask(Plugin plugin) throws IllegalArgumentException, IllegalStateException {
|
||||
checkNotYetScheduled();
|
||||
return setupTask(UniversalScheduler.getScheduler(plugin).runTask(this));
|
||||
}
|
||||
|
||||
/**
|
||||
* <b>Asynchronous tasks should never access any API in Bukkit. Great care
|
||||
* should be taken to assure the thread-safety of asynchronous tasks.</b>
|
||||
* <p>
|
||||
* Schedules this in the Bukkit scheduler to run asynchronously.
|
||||
*
|
||||
* @param plugin the reference to the plugin scheduling task
|
||||
* @return {@link MyScheduledTask}
|
||||
* @throws IllegalArgumentException if plugin is null
|
||||
* @throws IllegalStateException if this was already scheduled
|
||||
* @see TaskScheduler#runTaskAsynchronously(Runnable)
|
||||
*/
|
||||
|
||||
public synchronized MyScheduledTask runTaskAsynchronously(Plugin plugin) throws IllegalArgumentException, IllegalStateException {
|
||||
checkNotYetScheduled();
|
||||
return setupTask(UniversalScheduler.getScheduler(plugin).runTaskAsynchronously(this));
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedules this to run after the specified number of server ticks.
|
||||
*
|
||||
* @param plugin the reference to the plugin scheduling task
|
||||
* @param delay the ticks to wait before running the task
|
||||
* @return {@link MyScheduledTask}
|
||||
* @throws IllegalArgumentException if plugin is null
|
||||
* @throws IllegalStateException if this was already scheduled
|
||||
* @see TaskScheduler#runTaskLater(Runnable, long)
|
||||
*/
|
||||
|
||||
public synchronized MyScheduledTask runTaskLater(Plugin plugin, long delay) throws IllegalArgumentException, IllegalStateException {
|
||||
checkNotYetScheduled();
|
||||
return setupTask(UniversalScheduler.getScheduler(plugin).runTaskLater(this, delay));
|
||||
}
|
||||
|
||||
/**
|
||||
* <b>Asynchronous tasks should never access any API in Bukkit. Great care
|
||||
* should be taken to assure the thread-safety of asynchronous tasks.</b>
|
||||
* <p>
|
||||
* Schedules this to run asynchronously after the specified number of
|
||||
* server ticks.
|
||||
*
|
||||
* @param plugin the reference to the plugin scheduling task
|
||||
* @param delay the ticks to wait before running the task
|
||||
* @return {@link MyScheduledTask}
|
||||
* @throws IllegalArgumentException if plugin is null
|
||||
* @throws IllegalStateException if this was already scheduled
|
||||
* @see TaskScheduler#runTaskLaterAsynchronously(Runnable, long)
|
||||
*/
|
||||
|
||||
public synchronized MyScheduledTask runTaskLaterAsynchronously(Plugin plugin, long delay) throws IllegalArgumentException, IllegalStateException {
|
||||
checkNotYetScheduled();
|
||||
return setupTask(UniversalScheduler.getScheduler(plugin).runTaskLaterAsynchronously(this, delay));
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedules this to repeatedly run until cancelled, starting after the
|
||||
* specified number of server ticks.
|
||||
*
|
||||
* @param plugin the reference to the plugin scheduling task
|
||||
* @param delay the ticks to wait before running the task
|
||||
* @param period the ticks to wait between runs
|
||||
* @return {@link MyScheduledTask}
|
||||
* @throws IllegalArgumentException if plugin is null
|
||||
* @throws IllegalStateException if this was already scheduled
|
||||
* @see TaskScheduler#runTaskTimer(Runnable, long, long)
|
||||
*/
|
||||
|
||||
public synchronized MyScheduledTask runTaskTimer(Plugin plugin, long delay, long period) throws IllegalArgumentException, IllegalStateException {
|
||||
checkNotYetScheduled();
|
||||
return setupTask(UniversalScheduler.getScheduler(plugin).runTaskTimer(this, delay, period));
|
||||
}
|
||||
|
||||
/**
|
||||
* <b>Asynchronous tasks should never access any API in Bukkit. Great care
|
||||
* should be taken to assure the thread-safety of asynchronous tasks.</b>
|
||||
* <p>
|
||||
* Schedules this to repeatedly run asynchronously until cancelled,
|
||||
* starting after the specified number of server ticks.
|
||||
*
|
||||
* @param plugin the reference to the plugin scheduling task
|
||||
* @param delay the ticks to wait before running the task for the first
|
||||
* time
|
||||
* @param period the ticks to wait between runs
|
||||
* @return {@link MyScheduledTask}
|
||||
* @throws IllegalArgumentException if plugin is null
|
||||
* @throws IllegalStateException if this was already scheduled
|
||||
* @see TaskScheduler#runTaskTimerAsynchronously(Runnable, long, long)
|
||||
*/
|
||||
|
||||
public synchronized MyScheduledTask runTaskTimerAsynchronously(Plugin plugin, long delay, long period) throws IllegalArgumentException, IllegalStateException {
|
||||
checkNotYetScheduled();
|
||||
return setupTask(UniversalScheduler.getScheduler(plugin).runTaskTimerAsynchronously(this, delay, period));
|
||||
}
|
||||
|
||||
private void checkScheduled() {
|
||||
if (task == null) {
|
||||
throw new IllegalStateException("Not scheduled yet");
|
||||
}
|
||||
}
|
||||
|
||||
private void checkNotYetScheduled() {
|
||||
if (task != null) {
|
||||
throw new IllegalStateException("Already scheduled");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private MyScheduledTask setupTask(final MyScheduledTask task) {
|
||||
this.task = task;
|
||||
return task;
|
||||
}
|
||||
|
||||
|
||||
}
|
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2023 Sevastjan
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.clip.placeholderapi.scheduler;
|
||||
|
||||
import me.clip.placeholderapi.scheduler.bukkit.BukkitScheduler;
|
||||
import me.clip.placeholderapi.scheduler.folia.FoliaScheduler;
|
||||
import me.clip.placeholderapi.scheduler.paper.PaperScheduler;
|
||||
import me.clip.placeholderapi.scheduler.scheduling.schedulers.TaskScheduler;
|
||||
import me.clip.placeholderapi.scheduler.utils.JavaUtil;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
public class UniversalScheduler {
|
||||
private static final boolean IS_FOLIA = JavaUtil.classExists("io.papermc.paper.threadedregions.RegionizedServer");
|
||||
private static final boolean IS_CANVAS = JavaUtil.classExists("io.canvasmc.canvas.server.ThreadedServer");
|
||||
private static final boolean IS_EXPANDED_SCHEDULING_AVAILABLE = JavaUtil.classExists("io.papermc.paper.threadedregions.scheduler.ScheduledTask");
|
||||
|
||||
public static TaskScheduler getScheduler(Plugin plugin) {
|
||||
return IS_FOLIA || IS_CANVAS ? new FoliaScheduler(plugin) : (IS_EXPANDED_SCHEDULING_AVAILABLE ? new PaperScheduler(plugin) : new BukkitScheduler(plugin));
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2023 Sevastjan
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.clip.placeholderapi.scheduler.bukkit;
|
||||
|
||||
import me.clip.placeholderapi.scheduler.scheduling.tasks.MyScheduledTask;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
|
||||
public class BukkitScheduledTask implements MyScheduledTask {
|
||||
|
||||
BukkitTask task;
|
||||
|
||||
boolean isRepeating;
|
||||
|
||||
public BukkitScheduledTask(final BukkitTask task) {
|
||||
this.task = task;
|
||||
this.isRepeating = false;
|
||||
}
|
||||
|
||||
public BukkitScheduledTask(final BukkitTask task, boolean isRepeating) {
|
||||
this.task = task;
|
||||
this.isRepeating = isRepeating;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancel() {
|
||||
task.cancel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return task.isCancelled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Plugin getOwningPlugin() {
|
||||
return task.getOwner();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCurrentlyRunning() {
|
||||
return Bukkit.getServer().getScheduler().isCurrentlyRunning(this.task.getTaskId()); //There's no other way. Fuck bukkit
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRepeatingTask() {
|
||||
return isRepeating;
|
||||
}
|
||||
}
|
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2023 Sevastjan
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.clip.placeholderapi.scheduler.bukkit;
|
||||
|
||||
import me.clip.placeholderapi.scheduler.scheduling.schedulers.TaskScheduler;
|
||||
import me.clip.placeholderapi.scheduler.scheduling.tasks.MyScheduledTask;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
public class BukkitScheduler implements TaskScheduler {
|
||||
final Plugin plugin;
|
||||
|
||||
public BukkitScheduler(Plugin plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isGlobalThread() {
|
||||
return Bukkit.getServer().isPrimaryThread();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEntityThread(Entity entity) {
|
||||
return Bukkit.getServer().isPrimaryThread();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRegionThread(Location location) {
|
||||
return Bukkit.getServer().isPrimaryThread();
|
||||
}
|
||||
|
||||
@Override
|
||||
public MyScheduledTask runTask(Runnable runnable) {
|
||||
return new BukkitScheduledTask(Bukkit.getScheduler().runTask(plugin, runnable));
|
||||
}
|
||||
|
||||
@Override
|
||||
public MyScheduledTask runTaskLater(Runnable runnable, long delay) {
|
||||
return new BukkitScheduledTask(Bukkit.getScheduler().runTaskLater(plugin, runnable, delay));
|
||||
}
|
||||
|
||||
@Override
|
||||
public MyScheduledTask runTaskTimer(Runnable runnable, long delay, long period) {
|
||||
return new BukkitScheduledTask(Bukkit.getScheduler().runTaskTimer(plugin, runnable, delay, period));
|
||||
}
|
||||
|
||||
@Override
|
||||
public MyScheduledTask runTaskAsynchronously(Runnable runnable) {
|
||||
return new BukkitScheduledTask(Bukkit.getScheduler().runTaskAsynchronously(plugin, runnable));
|
||||
}
|
||||
|
||||
@Override
|
||||
public MyScheduledTask runTaskLaterAsynchronously(Runnable runnable, long delay) {
|
||||
return new BukkitScheduledTask(Bukkit.getScheduler().runTaskLaterAsynchronously(plugin, runnable, delay));
|
||||
}
|
||||
|
||||
@Override
|
||||
public MyScheduledTask runTaskTimerAsynchronously(Runnable runnable, long delay, long period) {
|
||||
return new BukkitScheduledTask(Bukkit.getScheduler().runTaskTimerAsynchronously(plugin, runnable, delay, period));
|
||||
}
|
||||
|
||||
//Useless? Or...
|
||||
public MyScheduledTask runTask(Plugin plugin, Runnable runnable) {
|
||||
return new BukkitScheduledTask(Bukkit.getScheduler().runTask(plugin, runnable));
|
||||
}
|
||||
|
||||
@Override
|
||||
public MyScheduledTask runTaskLater(Plugin plugin, Runnable runnable, long delay) {
|
||||
return new BukkitScheduledTask(Bukkit.getScheduler().runTaskLater(plugin, runnable, delay));
|
||||
}
|
||||
|
||||
@Override
|
||||
public MyScheduledTask runTaskTimer(Plugin plugin, Runnable runnable, long delay, long period) {
|
||||
return new BukkitScheduledTask(Bukkit.getScheduler().runTaskTimer(plugin, runnable, delay, period));
|
||||
}
|
||||
|
||||
@Override
|
||||
public MyScheduledTask runTaskAsynchronously(Plugin plugin, Runnable runnable) {
|
||||
return new BukkitScheduledTask(Bukkit.getScheduler().runTaskAsynchronously(plugin, runnable));
|
||||
}
|
||||
|
||||
@Override
|
||||
public MyScheduledTask runTaskLaterAsynchronously(Plugin plugin, Runnable runnable, long delay) {
|
||||
return new BukkitScheduledTask(Bukkit.getScheduler().runTaskLaterAsynchronously(plugin, runnable, delay));
|
||||
}
|
||||
|
||||
@Override
|
||||
public MyScheduledTask runTaskTimerAsynchronously(Plugin plugin, Runnable runnable, long delay, long period) {
|
||||
return new BukkitScheduledTask(Bukkit.getScheduler().runTaskTimerAsynchronously(plugin, runnable, delay, period));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Runnable runnable) {
|
||||
Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, runnable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancelTasks() {
|
||||
Bukkit.getScheduler().cancelTasks(plugin);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancelTasks(Plugin plugin) {
|
||||
Bukkit.getScheduler().cancelTasks(plugin);
|
||||
}
|
||||
}
|
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2023 Sevastjan
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.clip.placeholderapi.scheduler.folia;
|
||||
|
||||
import me.clip.placeholderapi.scheduler.scheduling.tasks.MyScheduledTask;
|
||||
import io.papermc.paper.threadedregions.scheduler.ScheduledTask;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
public class FoliaScheduledTask implements MyScheduledTask {
|
||||
private final ScheduledTask task;
|
||||
|
||||
public FoliaScheduledTask(final ScheduledTask task) {
|
||||
this.task = task;
|
||||
}
|
||||
|
||||
public void cancel() {
|
||||
this.task.cancel();
|
||||
}
|
||||
|
||||
public boolean isCancelled() {
|
||||
return this.task.isCancelled();
|
||||
}
|
||||
|
||||
public Plugin getOwningPlugin() {
|
||||
return this.task.getOwningPlugin();
|
||||
}
|
||||
|
||||
public boolean isCurrentlyRunning() {
|
||||
final ScheduledTask.ExecutionState state = this.task.getExecutionState();
|
||||
return state == ScheduledTask.ExecutionState.RUNNING || state == ScheduledTask.ExecutionState.CANCELLED_RUNNING;
|
||||
}
|
||||
|
||||
public boolean isRepeatingTask() {
|
||||
return this.task.isRepeatingTask();
|
||||
}
|
||||
}
|
@@ -0,0 +1,220 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2023 Sevastjan
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.clip.placeholderapi.scheduler.folia;
|
||||
|
||||
import me.clip.placeholderapi.scheduler.scheduling.schedulers.TaskScheduler;
|
||||
import me.clip.placeholderapi.scheduler.scheduling.tasks.MyScheduledTask;
|
||||
import io.papermc.paper.threadedregions.scheduler.AsyncScheduler;
|
||||
import io.papermc.paper.threadedregions.scheduler.GlobalRegionScheduler;
|
||||
import io.papermc.paper.threadedregions.scheduler.RegionScheduler;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class FoliaScheduler implements TaskScheduler {
|
||||
|
||||
final Plugin plugin;
|
||||
|
||||
public FoliaScheduler(Plugin plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
private final RegionScheduler regionScheduler = Bukkit.getServer().getRegionScheduler();
|
||||
private final GlobalRegionScheduler globalRegionScheduler = Bukkit.getServer().getGlobalRegionScheduler();
|
||||
private final AsyncScheduler asyncScheduler = Bukkit.getServer().getAsyncScheduler();
|
||||
|
||||
@Override
|
||||
public boolean isGlobalThread() {
|
||||
return Bukkit.getServer().isGlobalTickThread();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTickThread() {
|
||||
return Bukkit.getServer().isPrimaryThread(); // The Paper implementation checks whether this is a tick thread, this method exists to avoid confusion.
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEntityThread(Entity entity) {
|
||||
return Bukkit.getServer().isOwnedByCurrentRegion(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRegionThread(Location location) {
|
||||
return Bukkit.getServer().isOwnedByCurrentRegion(location);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MyScheduledTask runTask(Runnable runnable) {
|
||||
return new FoliaScheduledTask(globalRegionScheduler.run(plugin, task -> runnable.run()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public MyScheduledTask runTaskLater(Runnable runnable, long delay) {
|
||||
//Folia exception: Delay ticks may not be <= 0
|
||||
if (delay <= 0) {
|
||||
return runTask(runnable);
|
||||
}
|
||||
return new FoliaScheduledTask(globalRegionScheduler.runDelayed(plugin, task -> runnable.run(), delay));
|
||||
}
|
||||
|
||||
@Override
|
||||
public MyScheduledTask runTaskTimer(Runnable runnable, long delay, long period) {
|
||||
//Folia exception: Delay ticks may not be <= 0
|
||||
delay = getOneIfNotPositive(delay);
|
||||
return new FoliaScheduledTask(globalRegionScheduler.runAtFixedRate(plugin, task -> runnable.run(), delay, period));
|
||||
}
|
||||
|
||||
@Override
|
||||
public MyScheduledTask runTask(Plugin plugin, Runnable runnable) {
|
||||
return new FoliaScheduledTask(globalRegionScheduler.run(plugin, task -> runnable.run()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public MyScheduledTask runTaskLater(Plugin plugin, Runnable runnable, long delay) {
|
||||
//Folia exception: Delay ticks may not be <= 0
|
||||
if (delay <= 0) {
|
||||
return runTask(plugin, runnable);
|
||||
}
|
||||
return new FoliaScheduledTask(globalRegionScheduler.runDelayed(plugin, task -> runnable.run(), delay));
|
||||
}
|
||||
|
||||
@Override
|
||||
public MyScheduledTask runTaskTimer(Plugin plugin, Runnable runnable, long delay, long period) {
|
||||
//Folia exception: Delay ticks may not be <= 0
|
||||
delay = getOneIfNotPositive(delay);
|
||||
return new FoliaScheduledTask(globalRegionScheduler.runAtFixedRate(plugin, task -> runnable.run(), delay, period));
|
||||
}
|
||||
|
||||
@Override
|
||||
public MyScheduledTask runTask(Location location, Runnable runnable) {
|
||||
return new FoliaScheduledTask(regionScheduler.run(plugin, location, task -> runnable.run()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public MyScheduledTask runTaskLater(Location location, Runnable runnable, long delay) {
|
||||
//Folia exception: Delay ticks may not be <= 0
|
||||
if (delay <= 0) {
|
||||
return runTask(runnable);
|
||||
}
|
||||
return new FoliaScheduledTask(regionScheduler.runDelayed(plugin, location, task -> runnable.run(), delay));
|
||||
}
|
||||
|
||||
@Override
|
||||
public MyScheduledTask runTaskTimer(Location location, Runnable runnable, long delay, long period) {
|
||||
//Folia exception: Delay ticks may not be <= 0
|
||||
delay = getOneIfNotPositive(delay);
|
||||
return new FoliaScheduledTask(regionScheduler.runAtFixedRate(plugin, location, task -> runnable.run(), delay, period));
|
||||
}
|
||||
|
||||
@Override
|
||||
public MyScheduledTask runTask(Entity entity, Runnable runnable) {
|
||||
return new FoliaScheduledTask(entity.getScheduler().run(plugin, task -> runnable.run(), null));
|
||||
}
|
||||
|
||||
@Override
|
||||
public MyScheduledTask runTaskLater(Entity entity, Runnable runnable, long delay) {
|
||||
//Folia exception: Delay ticks may not be <= 0
|
||||
if (delay <= 0) {
|
||||
return runTask(entity, runnable);
|
||||
}
|
||||
return new FoliaScheduledTask(entity.getScheduler().runDelayed(plugin, task -> runnable.run(), null, delay));
|
||||
}
|
||||
|
||||
@Override
|
||||
public MyScheduledTask runTaskTimer(Entity entity, Runnable runnable, long delay, long period) {
|
||||
//Folia exception: Delay ticks may not be <= 0
|
||||
delay = getOneIfNotPositive(delay);
|
||||
return new FoliaScheduledTask(entity.getScheduler().runAtFixedRate(plugin, task -> runnable.run(), null, delay, period));
|
||||
}
|
||||
|
||||
@Override
|
||||
public MyScheduledTask runTaskAsynchronously(Runnable runnable) {
|
||||
return new FoliaScheduledTask(asyncScheduler.runNow(plugin, task -> runnable.run()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public MyScheduledTask runTaskLaterAsynchronously(Runnable runnable, long delay) {
|
||||
//Folia exception: Delay ticks may not be <= 0
|
||||
delay = getOneIfNotPositive(delay);
|
||||
return new FoliaScheduledTask(asyncScheduler.runDelayed(plugin, task -> runnable.run(), delay * 50L, TimeUnit.MILLISECONDS));
|
||||
}
|
||||
|
||||
@Override
|
||||
public MyScheduledTask runTaskTimerAsynchronously(Runnable runnable, long delay, long period) {
|
||||
return new FoliaScheduledTask(asyncScheduler.runAtFixedRate(plugin, task -> runnable.run(), delay * 50, period * 50, TimeUnit.MILLISECONDS));
|
||||
}
|
||||
|
||||
@Override
|
||||
public MyScheduledTask runTaskAsynchronously(Plugin plugin, Runnable runnable) {
|
||||
return new FoliaScheduledTask(asyncScheduler.runNow(plugin, task -> runnable.run()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public MyScheduledTask runTaskLaterAsynchronously(Plugin plugin, Runnable runnable, long delay) {
|
||||
//Folia exception: Delay ticks may not be <= 0
|
||||
delay = getOneIfNotPositive(delay);
|
||||
return new FoliaScheduledTask(asyncScheduler.runDelayed(plugin, task -> runnable.run(), delay * 50L, TimeUnit.MILLISECONDS));
|
||||
}
|
||||
|
||||
@Override
|
||||
public MyScheduledTask runTaskTimerAsynchronously(Plugin plugin, Runnable runnable, long delay, long period) {
|
||||
//Folia exception: Delay ticks may not be <= 0
|
||||
delay = getOneIfNotPositive(delay);
|
||||
return new FoliaScheduledTask(asyncScheduler.runAtFixedRate(plugin, task -> runnable.run(), delay * 50, period * 50, TimeUnit.MILLISECONDS));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Runnable runnable) {
|
||||
globalRegionScheduler.execute(plugin, runnable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Location location, Runnable runnable) {
|
||||
regionScheduler.execute(plugin, location, runnable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Entity entity, Runnable runnable) {
|
||||
entity.getScheduler().execute(plugin, runnable, null, 1L);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancelTasks() {
|
||||
globalRegionScheduler.cancelTasks(plugin);
|
||||
asyncScheduler.cancelTasks(plugin);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancelTasks(Plugin plugin) {
|
||||
globalRegionScheduler.cancelTasks(plugin);
|
||||
asyncScheduler.cancelTasks(plugin);
|
||||
}
|
||||
|
||||
private long getOneIfNotPositive(long x) {
|
||||
return x <= 0 ? 1L : x;
|
||||
}
|
||||
}
|
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2023 Sevastjan
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.clip.placeholderapi.scheduler.paper;
|
||||
|
||||
import me.clip.placeholderapi.scheduler.folia.FoliaScheduler;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
//Thanks to Towny
|
||||
public class PaperScheduler extends FoliaScheduler {
|
||||
public PaperScheduler(Plugin plugin) {
|
||||
super(plugin);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isGlobalThread() {
|
||||
// isGlobalThread does not exist on paper, match the bukkit task scheduler's behaviour.
|
||||
return Bukkit.getServer().isPrimaryThread();
|
||||
}
|
||||
}
|
@@ -0,0 +1,346 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2023 Sevastjan
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.clip.placeholderapi.scheduler.scheduling.schedulers;
|
||||
|
||||
import me.clip.placeholderapi.scheduler.scheduling.tasks.MyScheduledTask;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
public interface TaskScheduler {
|
||||
|
||||
/**
|
||||
* <b>Folia</b>: Returns whether the current thread is ticking the global region <br>
|
||||
* <b>Paper & Bukkit</b>: Returns {@link org.bukkit.Server#isPrimaryThread}
|
||||
*/
|
||||
boolean isGlobalThread();
|
||||
|
||||
/**
|
||||
* @return {@link org.bukkit.Server#isPrimaryThread}
|
||||
*/
|
||||
default boolean isTickThread() {
|
||||
return Bukkit.getServer().isPrimaryThread();
|
||||
}
|
||||
|
||||
/**
|
||||
* <b>Folia & Paper</b>: Returns whether the current thread is ticking a region and that the region
|
||||
* being ticked owns the specified entity. Note that this function is the only appropriate method of
|
||||
* checking for ownership of an entity, as retrieving the entity's location is undefined unless the
|
||||
* entity is owned by the current region
|
||||
* <p>
|
||||
* <b>Bukkit</b>: returns {@link org.bukkit.Server#isPrimaryThread}
|
||||
*
|
||||
* @param entity Specified entity
|
||||
*/
|
||||
boolean isEntityThread(Entity entity);
|
||||
|
||||
/**
|
||||
* <b>Folia & Paper</b>: Returns whether the current thread is ticking a region and that the region
|
||||
* being ticked owns the chunk at the specified world and block position as included in the specified location
|
||||
* <p>
|
||||
* <b>Bukkit</b>: returns {@link org.bukkit.Server#isPrimaryThread}
|
||||
*
|
||||
* @param location Specified location, must have a non-null world.
|
||||
*/
|
||||
boolean isRegionThread(Location location);
|
||||
|
||||
/**
|
||||
* Schedules a task to be executed on the next tick <br>
|
||||
* <b>Folia & Paper</b>: ...on the global region <br>
|
||||
* <b>Bukkit</b>: ...on the main thread
|
||||
*
|
||||
* @param runnable The task to execute
|
||||
*/
|
||||
MyScheduledTask runTask(Runnable runnable);
|
||||
|
||||
/**
|
||||
* Schedules a task to be executed after the specified delay in ticks <br>
|
||||
* <b>Folia & Paper</b>: ...on the global region <br>
|
||||
* <b>Bukkit</b>: ...on the main thread
|
||||
*
|
||||
* @param runnable The task to execute
|
||||
* @param delay The delay, in ticks
|
||||
*/
|
||||
MyScheduledTask runTaskLater(Runnable runnable, long delay);
|
||||
|
||||
/**
|
||||
* Schedules a repeating task to be executed after the initial delay with the specified period <br>
|
||||
* <b>Folia & Paper</b>: ...on the global region <br>
|
||||
* <b>Bukkit</b>: ...on the main thread
|
||||
*
|
||||
* @param runnable The task to execute
|
||||
* @param delay The initial delay, in ticks.
|
||||
* @param period The period, in ticks.
|
||||
*/
|
||||
MyScheduledTask runTaskTimer(Runnable runnable, long delay, long period);
|
||||
|
||||
/**
|
||||
* Deprecated: use {@link #runTask(Runnable)}
|
||||
*/
|
||||
@Deprecated
|
||||
default MyScheduledTask runTask(Plugin plugin, Runnable runnable) {
|
||||
return runTask(runnable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated: use {@link #runTaskLater(Runnable, long)}
|
||||
*/
|
||||
@Deprecated
|
||||
default MyScheduledTask runTaskLater(Plugin plugin, Runnable runnable, long delay) {
|
||||
return runTaskLater(runnable, delay);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated: use {@link #runTaskTimer(Runnable, long, long)}
|
||||
*/
|
||||
@Deprecated
|
||||
default MyScheduledTask runTaskTimer(Plugin plugin, Runnable runnable, long delay, long period) {
|
||||
return runTaskTimer(runnable, delay, period);
|
||||
}
|
||||
|
||||
/**
|
||||
* <b>Folia & Paper</b>: Schedules a task to be executed on the region which owns the location on the next tick
|
||||
* <p>
|
||||
* <b>Bukkit</b>: same as {@link #runTask(Runnable)}
|
||||
*
|
||||
* @param location The location which the region executing should own
|
||||
* @param runnable The task to execute
|
||||
*/
|
||||
default MyScheduledTask runTask(Location location, Runnable runnable) {
|
||||
return runTask(runnable);
|
||||
}
|
||||
|
||||
/**
|
||||
* <b>Folia & Paper</b>: Schedules a task to be executed on the region which owns the location after the
|
||||
* specified delay in ticks
|
||||
* <p>
|
||||
* <b>Bukkit</b>: same as {@link #runTaskLater(Runnable, long)}
|
||||
*
|
||||
* @param location The location which the region executing should own
|
||||
* @param runnable The task to execute
|
||||
* @param delay The delay, in ticks.
|
||||
*/
|
||||
default MyScheduledTask runTaskLater(Location location, Runnable runnable, long delay) {
|
||||
return runTaskLater(runnable, delay);
|
||||
}
|
||||
|
||||
/**
|
||||
* <b>Folia & Paper</b>: Schedules a repeating task to be executed on the region which owns the location
|
||||
* after the initial delay with the specified period
|
||||
* <p>
|
||||
* <b>Bukkit</b>: same as {@link #runTaskTimer(Runnable, long, long)}
|
||||
*
|
||||
* @param location The location which the region executing should own
|
||||
* @param runnable The task to execute
|
||||
* @param delay The initial delay, in ticks.
|
||||
* @param period The period, in ticks.
|
||||
*/
|
||||
default MyScheduledTask runTaskTimer(Location location, Runnable runnable, long delay, long period) {
|
||||
return runTaskTimer(runnable, delay, period);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated: use {@link #runTaskLater(Runnable, long)}
|
||||
*/
|
||||
@Deprecated
|
||||
default MyScheduledTask scheduleSyncDelayedTask(Runnable runnable, long delay) {
|
||||
return runTaskLater(runnable, delay);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated: use {@link #execute(Runnable)} or {@link #runTask(Runnable)}
|
||||
*/
|
||||
@Deprecated
|
||||
default MyScheduledTask scheduleSyncDelayedTask(Runnable runnable) {
|
||||
return runTask(runnable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated: use {@link #runTaskTimer(Runnable, long, long)}
|
||||
*/
|
||||
@Deprecated
|
||||
default MyScheduledTask scheduleSyncRepeatingTask(Runnable runnable, long delay, long period) {
|
||||
return runTaskTimer(runnable, delay, period);
|
||||
}
|
||||
|
||||
/**
|
||||
* <b>Folia & Paper</b>: Schedules a task to be executed on the region which owns the location
|
||||
* of given entity on the next tick
|
||||
* <p>
|
||||
* <b>Bukkit</b>: same as {@link #runTask(Runnable)}
|
||||
*
|
||||
* @param entity The entity whose location the region executing should own
|
||||
* @param runnable The task to execute
|
||||
*/
|
||||
default MyScheduledTask runTask(Entity entity, Runnable runnable) {
|
||||
return runTask(runnable);
|
||||
}
|
||||
|
||||
/**
|
||||
* <b>Folia & Paper</b>: Schedules a task to be executed on the region which owns the location
|
||||
* of given entity after the specified delay in ticks
|
||||
* <p>
|
||||
* <b>Bukkit</b>: same as {@link #runTaskLater(Runnable, long)}
|
||||
*
|
||||
* @param entity The entity whose location the region executing should own
|
||||
* @param runnable The task to execute
|
||||
* @param delay The delay, in ticks.
|
||||
*/
|
||||
default MyScheduledTask runTaskLater(Entity entity, Runnable runnable, long delay) {
|
||||
return runTaskLater(runnable, delay);
|
||||
}
|
||||
|
||||
/**
|
||||
* <b>Folia & Paper</b>: Schedules a repeating task to be executed on the region which owns the
|
||||
* location of given entity after the initial delay with the specified period
|
||||
* <p>
|
||||
* <b>Bukkit</b>: same as {@link #runTaskTimer(Runnable, long, long)}
|
||||
*
|
||||
* @param entity The entity whose location the region executing should own
|
||||
* @param runnable The task to execute
|
||||
* @param delay The initial delay, in ticks.
|
||||
* @param period The period, in ticks.
|
||||
*/
|
||||
default MyScheduledTask runTaskTimer(Entity entity, Runnable runnable, long delay, long period) {
|
||||
return runTaskTimer(runnable, delay, period);
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedules the specified task to be executed asynchronously immediately
|
||||
*
|
||||
* @param runnable The task to execute
|
||||
* @return The {@link MyScheduledTask} that represents the scheduled task
|
||||
*/
|
||||
MyScheduledTask runTaskAsynchronously(Runnable runnable);
|
||||
|
||||
/**
|
||||
* Schedules the specified task to be executed asynchronously after the time delay has passed
|
||||
*
|
||||
* @param runnable The task to execute
|
||||
* @param delay The time delay to pass before the task should be executed
|
||||
* @return The {@link MyScheduledTask} that represents the scheduled task
|
||||
*/
|
||||
MyScheduledTask runTaskLaterAsynchronously(Runnable runnable, long delay);
|
||||
|
||||
/**
|
||||
* Schedules the specified task to be executed asynchronously after the initial delay has passed,
|
||||
* and then periodically executed with the specified period
|
||||
*
|
||||
* @param runnable The task to execute
|
||||
* @param delay The time delay to pass before the first execution of the task, in ticks
|
||||
* @param period The time between task executions after the first execution of the task, in ticks
|
||||
* @return The {@link MyScheduledTask} that represents the scheduled task
|
||||
*/
|
||||
MyScheduledTask runTaskTimerAsynchronously(Runnable runnable, long delay, long period);
|
||||
|
||||
/**
|
||||
* Deprecated: use {@link #runTaskAsynchronously(Runnable)}
|
||||
*/
|
||||
@Deprecated
|
||||
default MyScheduledTask runTaskAsynchronously(Plugin plugin, Runnable runnable) {
|
||||
return runTaskAsynchronously(runnable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated: use {@link #runTaskLaterAsynchronously(Runnable, long)}
|
||||
*/
|
||||
@Deprecated
|
||||
default MyScheduledTask runTaskLaterAsynchronously(Plugin plugin, Runnable runnable, long delay) {
|
||||
return runTaskLaterAsynchronously(runnable, delay);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated: use {@link #runTaskTimerAsynchronously(Runnable, long, long)}
|
||||
*/
|
||||
@Deprecated
|
||||
default MyScheduledTask runTaskTimerAsynchronously(Plugin plugin, Runnable runnable, long delay, long period) {
|
||||
return runTaskTimerAsynchronously(runnable, delay, period);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls a method on the main thread and returns a Future object. This task will be executed
|
||||
* by the main(Bukkit)/global(Folia&Paper) server thread.
|
||||
* <p>
|
||||
* Note: The Future.get() methods must NOT be called from the main thread.
|
||||
* <p>
|
||||
* Note2: There is at least an average of 10ms latency until the isDone() method returns true.
|
||||
*
|
||||
* @param task Task to be executed
|
||||
*/
|
||||
default <T> Future<T> callSyncMethod(final Callable<T> task) {
|
||||
CompletableFuture<T> completableFuture = new CompletableFuture<>();
|
||||
execute(() -> {
|
||||
try {
|
||||
completableFuture.complete(task.call());
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
});
|
||||
return completableFuture;
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedules a task to be executed on the global region
|
||||
*
|
||||
* @param runnable The task to execute
|
||||
*/
|
||||
void execute(Runnable runnable);
|
||||
|
||||
/**
|
||||
* Schedules a task to be executed on the region which owns the location
|
||||
*
|
||||
* @param location The location which the region executing should own
|
||||
* @param runnable The task to execute
|
||||
*/
|
||||
default void execute(Location location, Runnable runnable) {
|
||||
execute(runnable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedules a task to be executed on the region which owns the location of given entity
|
||||
*
|
||||
* @param entity The entity which location the region executing should own
|
||||
* @param runnable The task to execute
|
||||
*/
|
||||
default void execute(Entity entity, Runnable runnable) {
|
||||
execute(runnable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to cancel all tasks scheduled by this plugin
|
||||
*/
|
||||
void cancelTasks();
|
||||
|
||||
/**
|
||||
* Attempts to cancel all tasks scheduled by the specified plugin
|
||||
*
|
||||
* @param plugin specified plugin
|
||||
*/
|
||||
void cancelTasks(Plugin plugin);
|
||||
}
|
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2023 Sevastjan
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.clip.placeholderapi.scheduler.scheduling.tasks;
|
||||
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
public interface MyScheduledTask {
|
||||
/**
|
||||
* Cancels executing task
|
||||
*/
|
||||
void cancel();
|
||||
|
||||
/**
|
||||
* @return true if task is cancelled, false otherwise
|
||||
*/
|
||||
boolean isCancelled();
|
||||
|
||||
/**
|
||||
* @return The plugin under which the task was scheduled.
|
||||
*/
|
||||
Plugin getOwningPlugin();
|
||||
|
||||
/**
|
||||
* @return true if task is currently executing, false otherwise
|
||||
*/
|
||||
boolean isCurrentlyRunning();
|
||||
|
||||
/**
|
||||
* @return true if task is repeating, false otherwise
|
||||
*/
|
||||
boolean isRepeatingTask();
|
||||
}
|
@@ -0,0 +1,12 @@
|
||||
package me.clip.placeholderapi.scheduler.utils;
|
||||
|
||||
public class JavaUtil {
|
||||
public static boolean classExists(String className) {
|
||||
try {
|
||||
Class.forName(className);
|
||||
return true;
|
||||
} catch (ClassNotFoundException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
@@ -26,6 +26,7 @@ import java.net.URL;
|
||||
import java.util.Arrays;
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
||||
import me.clip.placeholderapi.scheduler.scheduling.schedulers.TaskScheduler;
|
||||
import me.clip.placeholderapi.util.Msg;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.event.EventHandler;
|
||||
@@ -35,15 +36,17 @@ import org.bukkit.event.player.PlayerJoinEvent;
|
||||
|
||||
public class UpdateChecker implements Listener {
|
||||
|
||||
private final int RESOURCE_ID = 6245;
|
||||
private static final int RESOURCE_ID = 6245;
|
||||
private final PlaceholderAPIPlugin plugin;
|
||||
private final TaskScheduler scheduler;
|
||||
private final String pluginVersion;
|
||||
private String spigotVersion;
|
||||
private boolean updateAvailable;
|
||||
|
||||
public UpdateChecker(PlaceholderAPIPlugin i) {
|
||||
plugin = i;
|
||||
pluginVersion = i.getDescription().getVersion();
|
||||
public UpdateChecker(PlaceholderAPIPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
scheduler = plugin.getScheduler();
|
||||
pluginVersion = plugin.getDescription().getVersion();
|
||||
}
|
||||
|
||||
public boolean hasUpdateAvailable() {
|
||||
@@ -55,7 +58,7 @@ public class UpdateChecker implements Listener {
|
||||
}
|
||||
|
||||
public void fetch() {
|
||||
Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> {
|
||||
scheduler.runTaskAsynchronously(() -> {
|
||||
try {
|
||||
HttpsURLConnection con = (HttpsURLConnection) new URL(
|
||||
"https://api.spigotmc.org/legacy/update.php?resource=" + RESOURCE_ID).openConnection();
|
||||
@@ -76,7 +79,7 @@ public class UpdateChecker implements Listener {
|
||||
return;
|
||||
}
|
||||
|
||||
Bukkit.getScheduler().runTask(plugin, () -> {
|
||||
scheduler.runTask(() -> {
|
||||
plugin.getLogger()
|
||||
.info("An update for PlaceholderAPI (v" + getSpigotVersion() + ") is available at:");
|
||||
plugin.getLogger()
|
||||
|
@@ -27,6 +27,8 @@ import java.util.function.BiConsumer;
|
||||
import java.util.stream.Collector;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -36,14 +38,14 @@ public final class Futures {
|
||||
private Futures() {}
|
||||
|
||||
|
||||
public static <T> void onMainThread(@NotNull final Plugin plugin,
|
||||
public static <T> void onMainThread(@NotNull final PlaceholderAPIPlugin plugin,
|
||||
@NotNull final CompletableFuture<T> future,
|
||||
@NotNull final BiConsumer<T, Throwable> consumer) {
|
||||
future.whenComplete((value, exception) -> {
|
||||
if (Bukkit.isPrimaryThread()) {
|
||||
consumer.accept(value, exception);
|
||||
} else {
|
||||
Bukkit.getScheduler().runTask(plugin, () -> consumer.accept(value, exception));
|
||||
plugin.getScheduler().runTask(() -> consumer.accept(value, exception));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@@ -1,5 +1,6 @@
|
||||
name: PlaceholderAPI
|
||||
main: "me.clip.placeholderapi.PlaceholderAPIPlugin"
|
||||
folia-supported: true
|
||||
|
||||
version: ${version}
|
||||
author: HelpChat
|
||||
|
Reference in New Issue
Block a user