Skip to content

Commit f95b646

Browse files
committed
Now that we build against the Paper API, we can get rid of this reflection hack
1 parent 61292c0 commit f95b646

File tree

1 file changed

+46
-136
lines changed

1 file changed

+46
-136
lines changed

src/main/java/nl/rutgerkok/blocklocker/impl/SchedulerSupport.java

Lines changed: 46 additions & 136 deletions
Original file line numberDiff line numberDiff line change
@@ -1,92 +1,29 @@
11
package nl.rutgerkok.blocklocker.impl;
22

3-
import java.lang.reflect.InvocationTargetException;
4-
import java.lang.reflect.Method;
5-
import java.util.Objects;
6-
import java.util.concurrent.TimeUnit;
7-
import java.util.function.Consumer;
8-
9-
import org.bukkit.Location;
10-
import org.bukkit.Server;
11-
import org.bukkit.World;
123
import org.bukkit.block.Block;
134
import org.bukkit.plugin.Plugin;
145
import org.bukkit.scheduler.BukkitTask;
156

7+
import java.util.Objects;
8+
import java.util.concurrent.TimeUnit;
9+
import java.util.function.Consumer;
10+
1611
/**
17-
* Horrible reflection code to access the Folia scheduler if we're on Folia.
18-
*
19-
* <p>
20-
* I guess the "best" solution would be to create a submodule that can access
21-
* Folia code. However, that complicates the project setup. I guess at some
22-
* point Paper will offer a better solution, so that you don't need two code
23-
* paths.
24-
*
25-
* <p>
26-
* Some Java purists will say that you should separate this class into three: an
27-
* interface, and two implementations (Folia and Bukkit). However, since the
28-
* reflection code is quite unreadable, I think it's better to keep the
29-
* reference Bukkit code close by.
12+
* Code to support both the standard schedulers of Bukkit, and Folia's scheduler.
3013
*/
3114
final class SchedulerSupport {
3215

33-
private static Method getRegionScheduler;
34-
private static Method getGlobalRegionScheduler;
35-
private static Method getAsyncScheduler;
36-
37-
private static Class<?> globalRegionScheduler;
38-
private static Class<?> regionScheduler;
39-
private static Class<?> asyncScheduler;
40-
41-
private static Method runDelayedOnGlobal;
42-
private static Method runDelayedOnRegion;
43-
private static Method runOnRegion;
44-
private static Method runAtFixedRateAsync;
16+
private static boolean folia;
4517

4618
static {
4719
try {
48-
getRegionScheduler = Server.class.getMethod("getRegionScheduler");
49-
getGlobalRegionScheduler = Server.class.getMethod("getGlobalRegionScheduler");
50-
getAsyncScheduler = Server.class.getMethod("getAsyncScheduler");
51-
52-
globalRegionScheduler = getGlobalRegionScheduler.getReturnType();
53-
regionScheduler = getRegionScheduler.getReturnType();
54-
asyncScheduler = getAsyncScheduler.getReturnType();
55-
56-
runDelayedOnGlobal = globalRegionScheduler
57-
.getMethod("runDelayed", Plugin.class, Consumer.class, long.class);
58-
runDelayedOnRegion = regionScheduler
59-
.getMethod("runDelayed", Plugin.class, World.class, int.class, int.class, Consumer.class, long.class);
60-
runOnRegion = regionScheduler
61-
.getMethod("run", Plugin.class, Location.class, Consumer.class);
62-
runAtFixedRateAsync = asyncScheduler
63-
.getMethod("runAtFixedRate", Plugin.class, Consumer.class, long.class, long.class, TimeUnit.class);
20+
Class.forName("io.papermc.paper.threadedregions.RegionizedServer");
6421
folia = true;
65-
} catch (NoSuchMethodException e) {
22+
} catch (ClassNotFoundException e) {
6623
folia = false;
6724
}
6825
}
6926

70-
private static boolean folia;
71-
72-
/**
73-
* Used to invoke a parameterless instance method.
74-
*
75-
* @param on
76-
* The instance.
77-
* @param name
78-
* Name of the method.
79-
* @return Return value of the method (null for void methods).
80-
*/
81-
private static Object invoke(Object on, String name) {
82-
try {
83-
return on.getClass().getMethod(name).invoke(on);
84-
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException
85-
| SecurityException e) {
86-
throw new RuntimeException("Cannot invoke instance." + name + "()", e);
87-
}
88-
}
89-
9027
private final Plugin plugin;
9128

9229
SchedulerSupport(Plugin plugin) {
@@ -95,92 +32,65 @@ private static Object invoke(Object on, String name) {
9532

9633
public void runLater(Block block, Runnable runnable) {
9734
if (folia) {
98-
try {
99-
Object regionScheduler = getRegionScheduler.invoke(plugin.getServer());
100-
Consumer<?> consumer = task -> {
101-
runnable.run();
102-
};
103-
runOnRegion.invoke(regionScheduler, this.plugin, block.getLocation(), consumer);
104-
} catch (IllegalAccessException | InvocationTargetException e) {
105-
throw new RuntimeException(e);
106-
}
35+
plugin.getServer().getRegionScheduler().run(plugin, block.getLocation(), task -> {
36+
runnable.run();
37+
});
10738
} else {
10839
plugin.getServer().getScheduler().runTask(plugin, runnable);
10940
}
11041
}
11142

11243
public void runLater(Block block, Runnable runnable, int ticks) {
11344
if (folia) {
114-
try {
115-
Object regionScheduler = getRegionScheduler.invoke(plugin.getServer());
116-
Consumer<?> consumer = task -> {
117-
runnable.run();
118-
};
119-
runDelayedOnRegion.invoke(regionScheduler, plugin, block
120-
.getWorld(), block.getX() >> 4, block.getZ() >> 4, consumer, ticks);
121-
} catch (IllegalAccessException | InvocationTargetException e) {
122-
throw new RuntimeException(e);
123-
}
45+
plugin.getServer().getRegionScheduler().runDelayed(plugin, block.getLocation(), task -> {
46+
runnable.run();
47+
}, ticks);
12448
} else {
12549
plugin.getServer().getScheduler().runTaskLater(plugin, runnable, ticks);
12650
}
12751
}
12852

12953
void runLaterGlobally(Runnable runnable, int ticks) {
13054
if (folia) {
131-
try {
132-
Object globalRegionScheduler = getGlobalRegionScheduler.invoke(plugin.getServer());
133-
Consumer<?> consumer = task -> {
134-
runnable.run();
135-
};
136-
runDelayedOnGlobal.invoke(globalRegionScheduler, plugin, consumer, ticks);
137-
} catch (IllegalAccessException | InvocationTargetException e) {
138-
throw new RuntimeException(e);
139-
}
55+
plugin.getServer().getGlobalRegionScheduler().runDelayed(plugin, task -> {
56+
runnable.run();
57+
}, ticks);
14058
} else {
14159
plugin.getServer().getScheduler().runTaskLater(plugin, runnable, ticks);
14260
}
14361
}
14462

14563
void runTimerAsync(Consumer<BukkitTask> task, long checkInterval) {
14664
if (folia) {
147-
try {
148-
Object asyncScheduler = getAsyncScheduler.invoke(plugin.getServer());
149-
150-
Consumer<?> consumer = foliaTask -> {
151-
task.accept(new BukkitTask() {
152-
153-
@Override
154-
public void cancel() {
155-
invoke(foliaTask, "cancel");
156-
}
157-
158-
@Override
159-
public Plugin getOwner() {
160-
return (Plugin) invoke(foliaTask, "getOwningPlugin");
161-
}
162-
163-
@Override
164-
public int getTaskId() {
165-
throw new UnsupportedOperationException();
166-
}
167-
168-
@Override
169-
public boolean isCancelled() {
170-
return (Boolean) invoke(foliaTask, "isCancelled");
171-
}
172-
173-
@Override
174-
public boolean isSync() {
175-
return false;
176-
}
177-
});
178-
};
179-
runAtFixedRateAsync
180-
.invoke(asyncScheduler, plugin, consumer, 1, checkInterval * 50, TimeUnit.MILLISECONDS);
181-
} catch (IllegalAccessException | InvocationTargetException e) {
182-
throw new RuntimeException(e);
183-
}
65+
plugin.getServer().getAsyncScheduler().runAtFixedRate(plugin, foliaTask -> {
66+
task.accept(new BukkitTask() {
67+
68+
@Override
69+
public void cancel() {
70+
foliaTask.cancel();
71+
}
72+
73+
@Override
74+
public Plugin getOwner() {
75+
return foliaTask.getOwningPlugin();
76+
}
77+
78+
@Override
79+
public int getTaskId() {
80+
throw new UnsupportedOperationException();
81+
}
82+
83+
@Override
84+
public boolean isCancelled() {
85+
return foliaTask.isCancelled();
86+
}
87+
88+
@Override
89+
public boolean isSync() {
90+
return false;
91+
}
92+
});
93+
}, 1, checkInterval * 50, TimeUnit.MILLISECONDS);
18494
} else {
18595
BukkitTask[] bukkitTask = new BukkitTask[1];
18696
bukkitTask[0] = plugin.getServer().getScheduler().runTaskTimerAsynchronously(plugin, () -> {

0 commit comments

Comments
 (0)