Fix async handler scheduler support for folia (#2531)

This commit is contained in:
Maurice Eisenblätter 2023-10-25 03:10:35 +02:00 committed by GitHub
parent a7aa31adc0
commit d4b4f50674
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 34 additions and 88 deletions

View File

@ -24,6 +24,8 @@ import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import org.bukkit.plugin.Plugin;
import com.comphenix.protocol.ProtocolLibrary;
import com.comphenix.protocol.error.Report;
import com.comphenix.protocol.error.ReportType;
@ -38,8 +40,6 @@ import com.comphenix.protocol.timing.TimedTracker;
import com.google.common.base.Function;
import com.google.common.base.Joiner;
import org.bukkit.plugin.Plugin;
/**
* Represents a handler for an asynchronous event.
* <p>
@ -328,7 +328,7 @@ public class AsyncListenerHandler {
}
private void scheduleAsync(Runnable runnable) {
listener.getPlugin().getServer().getScheduler().runTaskAsynchronously(listener.getPlugin(), runnable);
filterManager.getScheduler().runTaskAsync(runnable);
}
/**

View File

@ -29,4 +29,10 @@ public class DefaultScheduler implements ProtocolScheduler {
int taskId = scheduler.scheduleSyncDelayedTask(plugin, task, delay);
return taskId >= 0 ? new DefaultTask(scheduler, taskId) : null;
}
@Override
public Task runTaskAsync(Runnable task) {
int taskId = scheduler.runTaskAsynchronously(plugin, task).getTaskId();
return taskId >= 0 ? new DefaultTask(scheduler, taskId) : null;
}
}

View File

@ -1,7 +1,6 @@
package com.comphenix.protocol.scheduler;
import org.bukkit.scheduler.BukkitScheduler;
import org.bukkit.scheduler.BukkitTask;
public class DefaultTask implements Task {
private final int taskId;

View File

@ -9,23 +9,32 @@ import org.bukkit.plugin.Plugin;
import java.util.function.Consumer;
public class FoliaScheduler implements ProtocolScheduler {
private final Object foliaScheduler;
private final Object foliaRegionScheduler;
private final MethodAccessor runAtFixedRate;
private final MethodAccessor runDelayed;
private final MethodAccessor execute;
private final MethodAccessor cancel;
private final Object foliaAsyncScheduler;
private final MethodAccessor executeAsync;
private final Plugin plugin;
public FoliaScheduler(Plugin plugin) {
this.plugin = plugin;
MethodAccessor getScheduler = Accessors.getMethodAccessor(Bukkit.getServer().getClass(), "getGlobalRegionScheduler");
this.foliaScheduler = getScheduler.invoke(Bukkit.getServer());
this.foliaRegionScheduler = getScheduler.invoke(Bukkit.getServer());
this.runAtFixedRate = Accessors.getMethodAccessor(foliaScheduler.getClass(), "runAtFixedRate", Plugin.class,
this.runAtFixedRate = Accessors.getMethodAccessor(foliaRegionScheduler.getClass(), "runAtFixedRate", Plugin.class,
Consumer.class, long.class, long.class);
this.execute = Accessors.getMethodAccessor(foliaScheduler.getClass(), "run", Plugin.class, Consumer.class);
this.runDelayed = Accessors.getMethodAccessor(foliaScheduler.getClass(), "runDelayed", Plugin.class, Consumer.class, long.class);
this.execute = Accessors.getMethodAccessor(foliaRegionScheduler.getClass(), "run", Plugin.class, Consumer.class);
this.runDelayed = Accessors.getMethodAccessor(foliaRegionScheduler.getClass(), "runDelayed", Plugin.class, Consumer.class, long.class);
MethodAccessor getAsyncScheduler = Accessors.getMethodAccessor(Bukkit.getServer().getClass(), "getAsyncScheduler");
foliaAsyncScheduler = getAsyncScheduler.invoke(Bukkit.getServer());
this.executeAsync = Accessors.getMethodAccessor(foliaAsyncScheduler.getClass(), "runNow", Plugin.class, Consumer.class);
Class<?> taskClass = MinecraftReflection.getLibraryClass("io.papermc.paper.threadedregions.scheduler.ScheduledTask");
this.cancel = Accessors.getMethodAccessor(taskClass, "cancel");
@ -33,19 +42,25 @@ public class FoliaScheduler implements ProtocolScheduler {
@Override
public Task scheduleSyncRepeatingTask(Runnable task, long delay, long period) {
Object taskHandle = runAtFixedRate.invoke(foliaScheduler, plugin, (Consumer<Object>)(t -> task.run()), delay, period);
Object taskHandle = runAtFixedRate.invoke(foliaRegionScheduler, plugin, (Consumer<Object>)(t -> task.run()), delay, period);
return new FoliaTask(cancel, taskHandle);
}
@Override
public Task runTask(Runnable task) {
Object taskHandle = execute.invoke(foliaScheduler, plugin, (Consumer<Object>)(t -> task.run()));
Object taskHandle = execute.invoke(foliaRegionScheduler, plugin, (Consumer<Object>)(t -> task.run()));
return new FoliaTask(cancel, taskHandle);
}
@Override
public Task scheduleSyncDelayedTask(Runnable task, long delay) {
Object taskHandle = runDelayed.invoke(foliaScheduler, plugin, (Consumer<Object>)(t -> task.run()), delay);
Object taskHandle = runDelayed.invoke(foliaRegionScheduler, plugin, (Consumer<Object>)(t -> task.run()), delay);
return new FoliaTask(cancel, taskHandle);
}
@Override
public Task runTaskAsync(Runnable task) {
Object taskHandle = executeAsync.invoke(foliaAsyncScheduler, plugin, (Consumer<Object>)(t -> task.run()));
return new FoliaTask(cancel, taskHandle);
}
}

View File

@ -1,12 +1,11 @@
package com.comphenix.protocol.scheduler;
import com.comphenix.protocol.ProtocolLib;
import org.bukkit.plugin.Plugin;
public interface ProtocolScheduler {
Task scheduleSyncRepeatingTask(Runnable task, long delay, long period);
Task runTask(Runnable task);
Task scheduleSyncDelayedTask(Runnable task, long delay);
Task runTaskAsync(Runnable task);
}

View File

@ -19,7 +19,6 @@ package com.comphenix.protocol.updater;
import com.comphenix.protocol.ProtocolLibrary;
import com.comphenix.protocol.error.Report;
import com.comphenix.protocol.utility.Closer;
import com.comphenix.protocol.utility.SchedulerUtil;
import org.bukkit.plugin.Plugin;
import java.io.BufferedReader;

View File

@ -1,72 +0,0 @@
package com.comphenix.protocol.utility;
import com.comphenix.protocol.reflect.accessors.Accessors;
import com.comphenix.protocol.reflect.accessors.MethodAccessor;
import org.bukkit.Bukkit;
import org.bukkit.plugin.Plugin;
import java.util.function.Consumer;
public class SchedulerUtil {
private Object foliaScheduler;
private MethodAccessor runAtFixedRate;
private MethodAccessor cancelTasks;
private MethodAccessor execute;
private static SchedulerUtil getInstance() {
return Holder.INSTANCE;
}
private static class Holder {
private static final SchedulerUtil INSTANCE = new SchedulerUtil();
}
private SchedulerUtil() {
if (Util.isUsingFolia()) {
MethodAccessor getScheduler = Accessors.getMethodAccessor(Bukkit.getServer().getClass(), "getGlobalRegionScheduler");
foliaScheduler = getScheduler.invoke(Bukkit.getServer());
runAtFixedRate = Accessors.getMethodAccessor(foliaScheduler.getClass(), "runAtFixedRate", Plugin.class,
Consumer.class, long.class, long.class);
cancelTasks = Accessors.getMethodAccessor(foliaScheduler.getClass(), "cancelTasks", Plugin.class);
execute = Accessors.getMethodAccessor(foliaScheduler.getClass(), "execute", Plugin.class, Runnable.class);
}
}
public static int scheduleSyncRepeatingTask(Plugin plugin, Runnable runnable, long delay, long period) {
return getInstance().doScheduleSyncRepeatingTask(plugin, runnable, delay, period);
}
private int doScheduleSyncRepeatingTask(Plugin plugin, Runnable runnable, long delay, long period) {
if (Util.isUsingFolia()) {
runAtFixedRate.invoke(foliaScheduler, plugin, (Consumer<Object>)(task -> runnable.run()), delay, period);
return 1;
} else {
return plugin.getServer().getScheduler().scheduleSyncRepeatingTask(plugin, runnable, delay, period);
}
}
private void doCancelTask(Plugin plugin, int id) {
if (Util.isUsingFolia()) {
cancelTasks.invoke(foliaScheduler, plugin);
} else {
plugin.getServer().getScheduler().cancelTask(id);
}
}
public static void cancelTask(Plugin plugin, int id) {
getInstance().doCancelTask(plugin, id);
}
private void doExecute(Plugin plugin, Runnable runnable) {
if (Util.isUsingFolia()) {
execute.invoke(foliaScheduler, plugin, runnable);
} else {
plugin.getServer().getScheduler().scheduleSyncDelayedTask(plugin, runnable);
}
}
public static void execute(Plugin plugin, Runnable runnable) {
getInstance().doExecute(plugin, runnable);
}
}