Skip to content

Commit 0e87f0a

Browse files
v0.2.0,
Add cancellable tasks, Add entity tasks, Remove scopes and use separate method names instead, Change server version checks to use class names instead of version name
1 parent 3f228ad commit 0e87f0a

12 files changed

Lines changed: 547 additions & 129 deletions

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ plugins {
33
}
44

55
group 'com.tcoded'
6-
version '0.1.1'
6+
version '0.2.0'
77

88
java {
99
sourceCompatibility = JavaVersion.VERSION_17

src/main/java/com/tcoded/folialib/FoliaLib.java

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -14,24 +14,32 @@ public class FoliaLib {
1414
public FoliaLib(JavaPlugin plugin) {
1515
this.plugin = plugin;
1616

17-
String version = plugin.getServer().getVersion();
17+
// Find the implementation type based on the class names
18+
ImplementationType foundType = ImplementationType.UNKNOWN;
19+
typeLoop:
20+
for (ImplementationType type : ImplementationType.values()) {
21+
String[] classNames = type.getClassNames();
1822

19-
// Init implementation based on server version string
20-
if (version.startsWith("git-Folia-")) {
21-
this.implementationType = ImplementationType.FOLIA;
22-
this.implementation = new FoliaImplementation(this);
23-
}
24-
else if (version.startsWith("git-Paper-")) {
25-
this.implementationType = ImplementationType.PAPER;
26-
this.implementation = new PaperImplementation(this);
27-
}
28-
else if (version.contains("-Spigot-")) {
29-
this.implementationType = ImplementationType.SPIGOT;
30-
this.implementation = new SpigotImplementation(this);
23+
// Check if any of the class names are present
24+
for (String className : classNames) {
25+
try {
26+
// Try to load the class
27+
Class.forName(className);
28+
29+
// Found the server type, remember that and break the loop
30+
foundType = type;
31+
break typeLoop;
32+
} catch (ClassNotFoundException ignored) {}
33+
}
3134
}
32-
else {
33-
this.implementationType = ImplementationType.UNKNOWN;
34-
this.implementation = new UnsupportedImplementation(this);
35+
36+
// Apply the implementation based on the type
37+
this.implementationType = foundType;
38+
switch (foundType) {
39+
case FOLIA -> this.implementation = new FoliaImplementation(this);
40+
case PAPER -> this.implementation = new PaperImplementation(this);
41+
case SPIGOT -> this.implementation = new SpigotImplementation(this);
42+
default -> this.implementation = new UnsupportedImplementation(this);
3543
}
3644
}
3745

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package com.tcoded.folialib.enums;
2+
3+
public enum EntityTaskResult {
4+
5+
SUCCESS,
6+
ENTITY_RETIRED,
7+
SCHEDULER_RETIRED
8+
9+
}
Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,23 @@
11
package com.tcoded.folialib.enums;
22

33
public enum ImplementationType {
4-
SPIGOT,
5-
PAPER,
6-
FOLIA,
7-
UNKNOWN
4+
5+
// Ordered by priority
6+
@SuppressWarnings("SpellCheckingInspection")
7+
FOLIA ("io.papermc.paper.threadedregions.RegionizedServer"),
8+
@SuppressWarnings("SpellCheckingInspection")
9+
PAPER ("com.destroystokyo.paper.PaperConfig", "io.papermc.paper.configuration.Configuration"),
10+
@SuppressWarnings("SpellCheckingInspection")
11+
SPIGOT ("org.spigotmc.SpigotConfig"),
12+
UNKNOWN;
13+
14+
private final String[] classNames;
15+
16+
ImplementationType(String... classNames) {
17+
this.classNames = classNames;
18+
}
19+
20+
public String[] getClassNames() {
21+
return classNames;
22+
}
823
}

src/main/java/com/tcoded/folialib/enums/ThreadScope.java

Lines changed: 0 additions & 6 deletions
This file was deleted.
Lines changed: 138 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
11
package com.tcoded.folialib.impl;
22

33
import com.tcoded.folialib.FoliaLib;
4-
import com.tcoded.folialib.enums.ThreadScope;
4+
import com.tcoded.folialib.enums.EntityTaskResult;
55
import com.tcoded.folialib.util.TimeConverter;
6+
import com.tcoded.folialib.wrapper.WrappedTask;
7+
import com.tcoded.folialib.wrapper.task.WrappedFoliaTask;
68
import io.papermc.paper.threadedregions.scheduler.AsyncScheduler;
79
import io.papermc.paper.threadedregions.scheduler.GlobalRegionScheduler;
810
import org.bukkit.Location;
9-
import org.bukkit.entity.Player;
11+
import org.bukkit.entity.Entity;
1012
import org.bukkit.plugin.java.JavaPlugin;
1113

14+
import java.util.concurrent.CompletableFuture;
1215
import java.util.concurrent.TimeUnit;
1316

1417
public class FoliaImplementation implements ServerImplementation {
@@ -24,61 +27,158 @@ public FoliaImplementation(FoliaLib foliaLib) {
2427
}
2528

2629
@Override
27-
public void runLater(Runnable runnable, long delay, TimeUnit unit) {
28-
this.runLater(ThreadScope.ASYNC, runnable, delay, unit);
30+
public CompletableFuture<Void> runNextTick(Runnable runnable) {
31+
CompletableFuture<Void> future = new CompletableFuture<>();
32+
33+
this.globalRegionScheduler.execute(plugin, () -> {
34+
runnable.run();
35+
future.complete(null);
36+
});
37+
38+
return future;
2939
}
3040

3141
@Override
32-
public void runLater(ThreadScope scope, Runnable runnable, long delay, TimeUnit unit) {
33-
switch (scope) {
34-
case ASYNC:
35-
this.asyncScheduler.runDelayed(plugin, task -> runnable.run(), delay, unit);
36-
break;
37-
default:
38-
this.globalRegionScheduler.runDelayed(plugin, task -> runnable.run(), TimeConverter.toTicks(delay, unit));
39-
break;
40-
}
42+
public CompletableFuture<Void> runAsync(Runnable runnable) {
43+
CompletableFuture<Void> future = new CompletableFuture<>();
44+
45+
this.asyncScheduler.runNow(plugin, task -> {
46+
runnable.run();
47+
future.complete(null);
48+
});
49+
50+
return future;
4151
}
4252

4353
@Override
44-
public void runTimer(Runnable runnable, long delay, long period, TimeUnit unit) {
45-
this.runTimer(ThreadScope.ASYNC, runnable, delay, period, unit);
54+
public WrappedTask runLater(Runnable runnable, long delay, TimeUnit unit) {
55+
return new WrappedFoliaTask(
56+
this.globalRegionScheduler.runDelayed(
57+
plugin, task -> runnable.run(), TimeConverter.toTicks(delay, unit)
58+
)
59+
);
4660
}
4761

4862
@Override
49-
public void runTimer(ThreadScope scope, Runnable runnable, long delay, long period, TimeUnit unit) {
50-
switch (scope) {
51-
case ASYNC:
52-
this.asyncScheduler.runAtFixedRate(plugin, task -> runnable.run(), delay, period, unit);
53-
break;
54-
default:
55-
this.globalRegionScheduler.runAtFixedRate(plugin, task -> runnable.run(), TimeConverter.toTicks(delay, unit), TimeConverter.toTicks(period, unit));
56-
break;
57-
}
63+
public WrappedTask runLaterAsync(Runnable runnable, long delay, TimeUnit unit) {
64+
return new WrappedFoliaTask(
65+
this.asyncScheduler.runDelayed(
66+
plugin, task -> runnable.run(), delay, unit
67+
)
68+
);
69+
}
70+
71+
@Override
72+
public WrappedTask runTimer(Runnable runnable, long delay, long period, TimeUnit unit) {
73+
return new WrappedFoliaTask(
74+
this.globalRegionScheduler.runAtFixedRate(
75+
plugin, task -> runnable.run(),
76+
TimeConverter.toTicks(delay, unit),
77+
TimeConverter.toTicks(period, unit)
78+
)
79+
);
80+
}
81+
82+
@Override
83+
public WrappedTask runTimerAsync(Runnable runnable, long delay, long period, TimeUnit unit) {
84+
return new WrappedFoliaTask(
85+
this.asyncScheduler.runAtFixedRate(
86+
plugin, task -> runnable.run(),
87+
delay, period, unit
88+
)
89+
);
90+
}
91+
92+
@Override
93+
public CompletableFuture<Void> runAtLocation(Location location, Runnable runnable) {
94+
CompletableFuture<Void> future = new CompletableFuture<>();
95+
96+
this.plugin.getServer().getRegionScheduler().execute(plugin, location, () -> {
97+
runnable.run();
98+
future.complete(null);
99+
});
100+
101+
return future;
102+
}
103+
104+
@Override
105+
public WrappedTask runAtLocationLater(Location location, Runnable runnable, long delay, TimeUnit unit) {
106+
return new WrappedFoliaTask(
107+
this.plugin.getServer().getRegionScheduler().runDelayed(
108+
plugin, location, task -> runnable.run(),
109+
TimeConverter.toTicks(delay, unit)
110+
)
111+
);
58112
}
59113

60114
@Override
61-
public void runInGlobalScope(ThreadScope scope, Runnable runnable) {
62-
switch (scope) {
63-
case ASYNC:
64-
this.asyncScheduler.runNow(plugin, task -> runnable.run());
65-
break;
66-
default:
67-
this.globalRegionScheduler.execute(plugin, runnable);
68-
break;
115+
public WrappedTask runAtLocationTimer(Location location, Runnable runnable, long delay, long period, TimeUnit unit) {
116+
return new WrappedFoliaTask(
117+
this.plugin.getServer().getRegionScheduler().runAtFixedRate(
118+
plugin, location, task -> runnable.run(),
119+
TimeConverter.toTicks(delay, unit),
120+
TimeConverter.toTicks(period, unit)
121+
)
122+
);
123+
}
124+
125+
@Override
126+
public CompletableFuture<EntityTaskResult> runAtEntity(Entity entity, Runnable runnable) {
127+
CompletableFuture<EntityTaskResult> future = new CompletableFuture<>();
128+
129+
boolean success = entity.getScheduler().execute(this.plugin, () -> {
130+
runnable.run();
131+
future.complete(EntityTaskResult.SUCCESS);
132+
}, null, 0);
133+
134+
if (!success) {
135+
future.complete(EntityTaskResult.SCHEDULER_RETIRED);
69136
}
137+
138+
return future;
70139
}
71140

72141
@Override
73-
public void runInRegion(Location location, Runnable runnable) {
74-
//this.globalRegionScheduler.//
75-
this.plugin.getServer().getRegionScheduler().run(plugin, location, task -> runnable.run());
142+
public CompletableFuture<EntityTaskResult> runAtEntityWithFallback(Entity entity, Runnable runnable, Runnable fallback) {
143+
CompletableFuture<EntityTaskResult> future = new CompletableFuture<>();
144+
145+
boolean success = entity.getScheduler().execute(this.plugin, () -> {
146+
runnable.run();
147+
future.complete(EntityTaskResult.SUCCESS);
148+
}, () -> {
149+
fallback.run();
150+
future.complete(EntityTaskResult.ENTITY_RETIRED);
151+
}, 0);
152+
153+
if (!success) {
154+
future.complete(EntityTaskResult.SCHEDULER_RETIRED);
155+
}
156+
157+
return future;
76158
}
77159

78160
@Override
79-
public void runInPlayerRegion(Player player, Runnable runnable) {
80-
//this.globalRegionScheduler.//
81-
this.plugin.getServer().getRegionScheduler().run(plugin, player.getLocation(), task -> runnable.run());
161+
public WrappedTask runAtEntityLater(Entity entity, Runnable runnable, long delay, TimeUnit unit) {
162+
return new WrappedFoliaTask(
163+
entity.getScheduler().runDelayed(
164+
plugin,
165+
task -> runnable.run(),
166+
null,
167+
TimeConverter.toTicks(delay, unit)
168+
)
169+
);
82170
}
83171

172+
@Override
173+
public WrappedTask runAtEntityTimer(Entity entity, Runnable runnable, long delay, long period, TimeUnit unit) {
174+
return new WrappedFoliaTask(
175+
entity.getScheduler().runAtFixedRate(
176+
plugin,
177+
task -> runnable.run(),
178+
null,
179+
TimeConverter.toTicks(delay, unit),
180+
TimeConverter.toTicks(period, unit)
181+
)
182+
);
183+
}
84184
}

0 commit comments

Comments
 (0)