Route hybrid schedulers

- Select Bukkit scheduling only when the bound platform identifies as Bukkit.
- Route hybrid Youer hosts through the modded scheduler despite Bukkit classes on the classpath.
- Add regression coverage for Bukkit and NeoForge platform identities.
This commit is contained in:
Brian Neumann-Fopiano
2026-08-28 16:29:58 -04:00
parent ecec18509c
commit 95d8523d1d
2 changed files with 70 additions and 9 deletions
@@ -121,7 +121,7 @@ public class J {
}
public static void aBukkit(Runnable a) {
if (!BUKKIT_PRESENT) {
if (!usesBukkitScheduler()) {
if (IrisPlatforms.isBound()) {
IrisPlatforms.get().scheduler().async(a);
}
@@ -186,7 +186,7 @@ public class J {
}
public static boolean isFolia() {
return BUKKIT_PRESENT && FoliaScheduler.isFolia(Bukkit.getServer());
return usesBukkitScheduler() && FoliaScheduler.isFolia(Bukkit.getServer());
}
public static boolean isPrimaryThread() {
@@ -345,7 +345,7 @@ public class J {
return false;
}
if (!BUKKIT_PRESENT) {
if (!usesBukkitScheduler()) {
if (!IrisPlatforms.isBound()) {
return false;
}
@@ -416,7 +416,7 @@ public class J {
public static void cancelPluginTasks() {
cancelTrackedRepeatingTasks();
if (!BukkitPlatform.hasPlugin()) {
if (!usesBukkitScheduler() || !BukkitPlatform.hasPlugin()) {
return;
}
@@ -442,7 +442,7 @@ public class J {
}
public static void s(Runnable r) {
if (!BUKKIT_PRESENT) {
if (!usesBukkitScheduler()) {
if (IrisPlatforms.isBound()) {
IrisPlatforms.get().scheduler().global(r);
}
@@ -566,7 +566,7 @@ public class J {
}
public static void s(Runnable r, int delay) {
if (!BUKKIT_PRESENT) {
if (!usesBukkitScheduler()) {
if (IrisPlatforms.isBound()) {
IrisPlatforms.get().scheduler().laterGlobal(r, delay);
}
@@ -667,7 +667,7 @@ public class J {
}
public static void a(Runnable r, int delay) {
if (!BUKKIT_PRESENT) {
if (!usesBukkitScheduler()) {
if (IrisPlatforms.isBound()) {
if (delay <= 0) {
IrisPlatforms.get().scheduler().async(r);
@@ -772,11 +772,17 @@ public class J {
}
private static boolean isPluginEnabled() {
return BUKKIT_PRESENT && BukkitPlatform.hasPlugin() && Bukkit.getPluginManager().isPluginEnabled(BukkitPlatform.plugin());
return usesBukkitScheduler() && BukkitPlatform.hasPlugin() && Bukkit.getPluginManager().isPluginEnabled(BukkitPlatform.plugin());
}
private static boolean canSchedule() {
return BUKKIT_PRESENT ? isPluginEnabled() : IrisPlatforms.isBound();
return usesBukkitScheduler() ? isPluginEnabled() : IrisPlatforms.isBound();
}
static boolean usesBukkitScheduler() {
return BUKKIT_PRESENT
&& IrisPlatforms.isBound()
&& "bukkit".equalsIgnoreCase(IrisPlatforms.get().platformName());
}
private static long ticksToMilliseconds(int ticks) {
@@ -0,0 +1,55 @@
package art.arcane.iris.util.common.scheduling;
import art.arcane.iris.spi.IrisPlatform;
import art.arcane.iris.spi.IrisPlatforms;
import art.arcane.iris.spi.PlatformScheduler;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
public class JHybridPlatformTest {
@Before
public void clearPlatform() {
IrisPlatforms.unbind();
}
@After
public void cleanup() {
J.cancelTrackedRepeatingTasks();
IrisPlatforms.unbind();
}
@Test
public void boundBukkitIdentitySelectsBukkitScheduler() {
IrisPlatform platform = mock(IrisPlatform.class);
when(platform.platformName()).thenReturn("bukkit");
IrisPlatforms.bind(platform);
assertTrue(J.usesBukkitScheduler());
}
@Test
public void hybridHostRepeaterUsesBoundModdedScheduler() {
IrisPlatform platform = mock(IrisPlatform.class);
PlatformScheduler scheduler = mock(PlatformScheduler.class);
when(platform.platformName()).thenReturn("neoforge");
when(platform.scheduler()).thenReturn(scheduler);
IrisPlatforms.bind(platform);
assertFalse(J.usesBukkitScheduler());
int taskId = J.ar(() -> {
}, 1);
assertNotEquals(-1, taskId);
verify(scheduler).laterGlobal(any(Runnable.class), eq(1));
}
}