Skip to content

Commit

Permalink
v0.2.0,
Browse files Browse the repository at this point in the history
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
  • Loading branch information
TechnicallyCoded committed Apr 11, 2023
1 parent 3f228ad commit 0e87f0a
Show file tree
Hide file tree
Showing 12 changed files with 547 additions and 129 deletions.
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ plugins {
}

group 'com.tcoded'
version '0.1.1'
version '0.2.0'

java {
sourceCompatibility = JavaVersion.VERSION_17
Expand Down
40 changes: 24 additions & 16 deletions src/main/java/com/tcoded/folialib/FoliaLib.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,24 +14,32 @@ public class FoliaLib {
public FoliaLib(JavaPlugin plugin) {
this.plugin = plugin;

String version = plugin.getServer().getVersion();
// Find the implementation type based on the class names
ImplementationType foundType = ImplementationType.UNKNOWN;
typeLoop:
for (ImplementationType type : ImplementationType.values()) {
String[] classNames = type.getClassNames();

// Init implementation based on server version string
if (version.startsWith("git-Folia-")) {
this.implementationType = ImplementationType.FOLIA;
this.implementation = new FoliaImplementation(this);
}
else if (version.startsWith("git-Paper-")) {
this.implementationType = ImplementationType.PAPER;
this.implementation = new PaperImplementation(this);
}
else if (version.contains("-Spigot-")) {
this.implementationType = ImplementationType.SPIGOT;
this.implementation = new SpigotImplementation(this);
// Check if any of the class names are present
for (String className : classNames) {
try {
// Try to load the class
Class.forName(className);

// Found the server type, remember that and break the loop
foundType = type;
break typeLoop;
} catch (ClassNotFoundException ignored) {}
}
}
else {
this.implementationType = ImplementationType.UNKNOWN;
this.implementation = new UnsupportedImplementation(this);

// Apply the implementation based on the type
this.implementationType = foundType;
switch (foundType) {
case FOLIA -> this.implementation = new FoliaImplementation(this);
case PAPER -> this.implementation = new PaperImplementation(this);
case SPIGOT -> this.implementation = new SpigotImplementation(this);
default -> this.implementation = new UnsupportedImplementation(this);
}
}

Expand Down
9 changes: 9 additions & 0 deletions src/main/java/com/tcoded/folialib/enums/EntityTaskResult.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.tcoded.folialib.enums;

public enum EntityTaskResult {

SUCCESS,
ENTITY_RETIRED,
SCHEDULER_RETIRED

}
23 changes: 19 additions & 4 deletions src/main/java/com/tcoded/folialib/enums/ImplementationType.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,23 @@
package com.tcoded.folialib.enums;

public enum ImplementationType {
SPIGOT,
PAPER,
FOLIA,
UNKNOWN

// Ordered by priority
@SuppressWarnings("SpellCheckingInspection")
FOLIA ("io.papermc.paper.threadedregions.RegionizedServer"),
@SuppressWarnings("SpellCheckingInspection")
PAPER ("com.destroystokyo.paper.PaperConfig", "io.papermc.paper.configuration.Configuration"),
@SuppressWarnings("SpellCheckingInspection")
SPIGOT ("org.spigotmc.SpigotConfig"),
UNKNOWN;

private final String[] classNames;

ImplementationType(String... classNames) {
this.classNames = classNames;
}

public String[] getClassNames() {
return classNames;
}
}
6 changes: 0 additions & 6 deletions src/main/java/com/tcoded/folialib/enums/ThreadScope.java

This file was deleted.

176 changes: 138 additions & 38 deletions src/main/java/com/tcoded/folialib/impl/FoliaImplementation.java
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
package com.tcoded.folialib.impl;

import com.tcoded.folialib.FoliaLib;
import com.tcoded.folialib.enums.ThreadScope;
import com.tcoded.folialib.enums.EntityTaskResult;
import com.tcoded.folialib.util.TimeConverter;
import com.tcoded.folialib.wrapper.WrappedTask;
import com.tcoded.folialib.wrapper.task.WrappedFoliaTask;
import io.papermc.paper.threadedregions.scheduler.AsyncScheduler;
import io.papermc.paper.threadedregions.scheduler.GlobalRegionScheduler;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.entity.Entity;
import org.bukkit.plugin.java.JavaPlugin;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;

public class FoliaImplementation implements ServerImplementation {
Expand All @@ -24,61 +27,158 @@ public FoliaImplementation(FoliaLib foliaLib) {
}

@Override
public void runLater(Runnable runnable, long delay, TimeUnit unit) {
this.runLater(ThreadScope.ASYNC, runnable, delay, unit);
public CompletableFuture<Void> runNextTick(Runnable runnable) {
CompletableFuture<Void> future = new CompletableFuture<>();

this.globalRegionScheduler.execute(plugin, () -> {
runnable.run();
future.complete(null);
});

return future;
}

@Override
public void runLater(ThreadScope scope, Runnable runnable, long delay, TimeUnit unit) {
switch (scope) {
case ASYNC:
this.asyncScheduler.runDelayed(plugin, task -> runnable.run(), delay, unit);
break;
default:
this.globalRegionScheduler.runDelayed(plugin, task -> runnable.run(), TimeConverter.toTicks(delay, unit));
break;
}
public CompletableFuture<Void> runAsync(Runnable runnable) {
CompletableFuture<Void> future = new CompletableFuture<>();

this.asyncScheduler.runNow(plugin, task -> {
runnable.run();
future.complete(null);
});

return future;
}

@Override
public void runTimer(Runnable runnable, long delay, long period, TimeUnit unit) {
this.runTimer(ThreadScope.ASYNC, runnable, delay, period, unit);
public WrappedTask runLater(Runnable runnable, long delay, TimeUnit unit) {
return new WrappedFoliaTask(
this.globalRegionScheduler.runDelayed(
plugin, task -> runnable.run(), TimeConverter.toTicks(delay, unit)
)
);
}

@Override
public void runTimer(ThreadScope scope, Runnable runnable, long delay, long period, TimeUnit unit) {
switch (scope) {
case ASYNC:
this.asyncScheduler.runAtFixedRate(plugin, task -> runnable.run(), delay, period, unit);
break;
default:
this.globalRegionScheduler.runAtFixedRate(plugin, task -> runnable.run(), TimeConverter.toTicks(delay, unit), TimeConverter.toTicks(period, unit));
break;
}
public WrappedTask runLaterAsync(Runnable runnable, long delay, TimeUnit unit) {
return new WrappedFoliaTask(
this.asyncScheduler.runDelayed(
plugin, task -> runnable.run(), delay, unit
)
);
}

@Override
public WrappedTask runTimer(Runnable runnable, long delay, long period, TimeUnit unit) {
return new WrappedFoliaTask(
this.globalRegionScheduler.runAtFixedRate(
plugin, task -> runnable.run(),
TimeConverter.toTicks(delay, unit),
TimeConverter.toTicks(period, unit)
)
);
}

@Override
public WrappedTask runTimerAsync(Runnable runnable, long delay, long period, TimeUnit unit) {
return new WrappedFoliaTask(
this.asyncScheduler.runAtFixedRate(
plugin, task -> runnable.run(),
delay, period, unit
)
);
}

@Override
public CompletableFuture<Void> runAtLocation(Location location, Runnable runnable) {
CompletableFuture<Void> future = new CompletableFuture<>();

this.plugin.getServer().getRegionScheduler().execute(plugin, location, () -> {
runnable.run();
future.complete(null);
});

return future;
}

@Override
public WrappedTask runAtLocationLater(Location location, Runnable runnable, long delay, TimeUnit unit) {
return new WrappedFoliaTask(
this.plugin.getServer().getRegionScheduler().runDelayed(
plugin, location, task -> runnable.run(),
TimeConverter.toTicks(delay, unit)
)
);
}

@Override
public void runInGlobalScope(ThreadScope scope, Runnable runnable) {
switch (scope) {
case ASYNC:
this.asyncScheduler.runNow(plugin, task -> runnable.run());
break;
default:
this.globalRegionScheduler.execute(plugin, runnable);
break;
public WrappedTask runAtLocationTimer(Location location, Runnable runnable, long delay, long period, TimeUnit unit) {
return new WrappedFoliaTask(
this.plugin.getServer().getRegionScheduler().runAtFixedRate(
plugin, location, task -> runnable.run(),
TimeConverter.toTicks(delay, unit),
TimeConverter.toTicks(period, unit)
)
);
}

@Override
public CompletableFuture<EntityTaskResult> runAtEntity(Entity entity, Runnable runnable) {
CompletableFuture<EntityTaskResult> future = new CompletableFuture<>();

boolean success = entity.getScheduler().execute(this.plugin, () -> {
runnable.run();
future.complete(EntityTaskResult.SUCCESS);
}, null, 0);

if (!success) {
future.complete(EntityTaskResult.SCHEDULER_RETIRED);
}

return future;
}

@Override
public void runInRegion(Location location, Runnable runnable) {
//this.globalRegionScheduler.//
this.plugin.getServer().getRegionScheduler().run(plugin, location, task -> runnable.run());
public CompletableFuture<EntityTaskResult> runAtEntityWithFallback(Entity entity, Runnable runnable, Runnable fallback) {
CompletableFuture<EntityTaskResult> future = new CompletableFuture<>();

boolean success = entity.getScheduler().execute(this.plugin, () -> {
runnable.run();
future.complete(EntityTaskResult.SUCCESS);
}, () -> {
fallback.run();
future.complete(EntityTaskResult.ENTITY_RETIRED);
}, 0);

if (!success) {
future.complete(EntityTaskResult.SCHEDULER_RETIRED);
}

return future;
}

@Override
public void runInPlayerRegion(Player player, Runnable runnable) {
//this.globalRegionScheduler.//
this.plugin.getServer().getRegionScheduler().run(plugin, player.getLocation(), task -> runnable.run());
public WrappedTask runAtEntityLater(Entity entity, Runnable runnable, long delay, TimeUnit unit) {
return new WrappedFoliaTask(
entity.getScheduler().runDelayed(
plugin,
task -> runnable.run(),
null,
TimeConverter.toTicks(delay, unit)
)
);
}

@Override
public WrappedTask runAtEntityTimer(Entity entity, Runnable runnable, long delay, long period, TimeUnit unit) {
return new WrappedFoliaTask(
entity.getScheduler().runAtFixedRate(
plugin,
task -> runnable.run(),
null,
TimeConverter.toTicks(delay, unit),
TimeConverter.toTicks(period, unit)
)
);
}
}
Loading

0 comments on commit 0e87f0a

Please sign in to comment.