Skip to content

Commit

Permalink
remove cache in Scheduler
Browse files Browse the repository at this point in the history
premature optimization is bad
  • Loading branch information
HSGamer committed Mar 26, 2024
1 parent ecc4e10 commit d7c5e67
Show file tree
Hide file tree
Showing 11 changed files with 83 additions and 188 deletions.
Original file line number Diff line number Diff line change
@@ -1,35 +1,25 @@
package io.github.projectunified.minelib.scheduler.async;

import com.google.common.cache.LoadingCache;
import io.github.projectunified.minelib.scheduler.common.scheduler.Scheduler;
import io.github.projectunified.minelib.scheduler.common.task.Task;
import io.github.projectunified.minelib.scheduler.common.util.Platform;
import org.bukkit.plugin.Plugin;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.function.BooleanSupplier;

/**
* A {@link Scheduler} that can run tasks asynchronously
*/
public interface AsyncScheduler extends Scheduler {
LoadingCache<Plugin, AsyncScheduler> PROVIDER = Scheduler.createProvider(
Platform.FOLIA.isPlatform() ? FoliaAsyncScheduler::new : BukkitAsyncScheduler::new
);

/**
* Get the {@link AsyncScheduler} for the given plugin
*
* @param plugin the plugin
* @return the scheduler
*/
static AsyncScheduler get(Plugin plugin) {
try {
return PROVIDER.get(plugin);
} catch (ExecutionException e) {
throw new RuntimeException(e);
}
return Platform.FOLIA.isPlatform() ? new FoliaAsyncScheduler(plugin) : new BukkitAsyncScheduler(plugin);
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,32 +1,20 @@
package io.github.projectunified.minelib.scheduler.canceller;

import com.google.common.cache.LoadingCache;
import io.github.projectunified.minelib.scheduler.common.scheduler.Scheduler;
import io.github.projectunified.minelib.scheduler.common.util.Platform;
import org.bukkit.plugin.Plugin;

import java.util.concurrent.ExecutionException;

/**
* An interface for cancelling tasks
*/
public interface TaskCanceller {
LoadingCache<Plugin, TaskCanceller> PROVIDER = Scheduler.createProvider(
Platform.FOLIA.isPlatform() ? FoliaTaskCanceller::new : BukkitTaskCanceller::new
);

/**
* Get the {@link TaskCanceller} for the given plugin
*
* @param plugin the plugin
* @return the {@link TaskCanceller}
*/
static TaskCanceller get(Plugin plugin) {
try {
return PROVIDER.get(plugin);
} catch (ExecutionException e) {
throw new RuntimeException(e);
}
return Platform.FOLIA.isPlatform() ? new FoliaTaskCanceller(plugin) : new BukkitTaskCanceller(plugin);
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,29 +1,13 @@
package io.github.projectunified.minelib.scheduler.common.scheduler;

import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import io.github.projectunified.minelib.scheduler.common.task.Task;

import java.util.function.BooleanSupplier;
import java.util.function.Function;

/**
* A scheduler that provides a way to run tasks
*/
public interface Scheduler {
/**
* Create a provider
*
* @param function the function
* @param <K> the key type
* @param <T> the scheduler type
* @return the provider
*/
static <K, T> LoadingCache<K, T> createProvider(Function<K, T> function) {
return CacheBuilder.newBuilder().weakKeys().build(CacheLoader.from(function::apply));
}

/**
* Run a task
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,26 @@

import io.github.projectunified.minelib.scheduler.common.task.Task;
import io.github.projectunified.minelib.scheduler.common.util.task.BukkitTask;
import org.bukkit.entity.Entity;
import org.bukkit.plugin.Plugin;
import org.bukkit.scheduler.BukkitRunnable;

import java.util.function.BooleanSupplier;

class BukkitEntityScheduler implements EntityScheduler {
private final Key key;
private final Plugin plugin;
private final Entity entity;

BukkitEntityScheduler(Key key) {
this.key = key;
BukkitEntityScheduler(Plugin plugin, Entity entity) {
this.plugin = plugin;
this.entity = entity;
}

private BukkitRunnable wrapRunnable(BooleanSupplier runnable, Runnable retired) {
return new BukkitRunnable() {
@Override
public void run() {
if (key.isEntityValid()) {
if (EntityScheduler.isEntityValid(entity)) {
if (!runnable.getAsBoolean()) {
cancel();
}
Expand All @@ -39,21 +43,21 @@ private BukkitRunnable wrapRunnable(Runnable runnable, Runnable retired) {
@Override
public Task run(Runnable runnable, Runnable retired) {
return new BukkitTask(
wrapRunnable(runnable, retired).runTask(key.plugin)
wrapRunnable(runnable, retired).runTask(plugin)
);
}

@Override
public Task runLater(Runnable runnable, Runnable retired, long delay) {
return new BukkitTask(
wrapRunnable(runnable, retired).runTaskLater(key.plugin, delay)
wrapRunnable(runnable, retired).runTaskLater(plugin, delay)
);
}

@Override
public Task runTimer(BooleanSupplier runnable, Runnable retired, long delay, long period) {
return new BukkitTask(
wrapRunnable(runnable, retired).runTaskTimer(key.plugin, delay, period)
wrapRunnable(runnable, retired).runTaskTimer(plugin, delay, period)
);
}
}
Original file line number Diff line number Diff line change
@@ -1,24 +1,37 @@
package io.github.projectunified.minelib.scheduler.entity;

import com.google.common.cache.LoadingCache;
import io.github.projectunified.minelib.scheduler.common.scheduler.Scheduler;
import io.github.projectunified.minelib.scheduler.common.task.Task;
import io.github.projectunified.minelib.scheduler.common.util.Platform;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;

import java.util.Objects;
import java.util.concurrent.ExecutionException;
import java.util.function.BooleanSupplier;

/**
* A {@link Scheduler} that schedules tasks for an {@link Entity}
*/
public interface EntityScheduler extends Scheduler {
LoadingCache<Key, EntityScheduler> PROVIDER = Scheduler.createProvider(
Platform.FOLIA.isPlatform() ? FoliaEntityScheduler::new : BukkitEntityScheduler::new
);
/**
* Check if the {@link Entity} is valid.
* This checks if the entity is not null and is still valid.
* For {@link Player} entities, this also checks if the player is online.
*
* @param entity the entity
* @return {@code true} if the entity is valid
*/
static boolean isEntityValid(Entity entity) {
if (entity == null) {
return false;
}

if (entity instanceof Player) {
return ((Player) entity).isOnline();
}

return entity.isValid();
}

/**
* Get the {@link EntityScheduler} for the given {@link Plugin} and {@link Entity}
Expand All @@ -28,11 +41,9 @@ public interface EntityScheduler extends Scheduler {
* @return the scheduler
*/
static EntityScheduler get(Plugin plugin, Entity entity) {
try {
return PROVIDER.get(new Key(plugin, entity));
} catch (ExecutionException e) {
throw new RuntimeException(e);
}
return Platform.FOLIA.isPlatform()
? new FoliaEntityScheduler(plugin, entity)
: new BukkitEntityScheduler(plugin, entity);
}

/**
Expand Down Expand Up @@ -98,47 +109,4 @@ default Task runTimer(BooleanSupplier runnable, long delay, long period) {
return runTimer(runnable, () -> {
}, delay, period);
}

/**
* A key for the {@link EntityScheduler}
*/
class Key {
public final Plugin plugin;
public final Entity entity;

public Key(Plugin plugin, Entity entity) {
this.plugin = plugin;
this.entity = entity;
}

/**
* Check if the entity is valid
*
* @return true if the entity is valid
*/
public boolean isEntityValid() {
if (entity == null) {
return false;
}

if (entity instanceof Player) {
return ((Player) entity).isOnline();
}

return entity.isValid();
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Key key = (Key) o;
return Objects.equals(plugin, key.plugin) && Objects.equals(entity, key.entity);
}

@Override
public int hashCode() {
return Objects.hash(plugin, entity);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,48 +4,52 @@
import io.github.projectunified.minelib.scheduler.common.util.task.FoliaTask;
import io.papermc.paper.threadedregions.scheduler.ScheduledTask;
import org.bukkit.Bukkit;
import org.bukkit.entity.Entity;
import org.bukkit.plugin.Plugin;

import java.util.function.BooleanSupplier;

import static io.github.projectunified.minelib.scheduler.common.util.task.FoliaTask.normalizedTicks;
import static io.github.projectunified.minelib.scheduler.common.util.task.FoliaTask.wrapRunnable;

class FoliaEntityScheduler implements EntityScheduler {
private final Key key;
private final Plugin plugin;
private final Entity entity;

FoliaEntityScheduler(Key key) {
this.key = key;
FoliaEntityScheduler(Plugin plugin, Entity entity) {
this.plugin = plugin;
this.entity = entity;
}

@Override
public Task run(Runnable runnable, Runnable retired) {
ScheduledTask scheduledTask;
if (key.isEntityValid()) {
scheduledTask = key.entity.getScheduler().run(key.plugin, wrapRunnable(runnable), retired);
if (EntityScheduler.isEntityValid(entity)) {
scheduledTask = entity.getScheduler().run(plugin, wrapRunnable(runnable), retired);
} else {
scheduledTask = Bukkit.getGlobalRegionScheduler().run(key.plugin, wrapRunnable(retired));
scheduledTask = Bukkit.getGlobalRegionScheduler().run(plugin, wrapRunnable(retired));
}
return new FoliaTask(scheduledTask);
}

@Override
public Task runLater(Runnable runnable, Runnable retired, long delay) {
ScheduledTask scheduledTask;
if (key.isEntityValid()) {
scheduledTask = key.entity.getScheduler().runDelayed(key.plugin, wrapRunnable(runnable), retired, normalizedTicks(delay));
if (EntityScheduler.isEntityValid(entity)) {
scheduledTask = entity.getScheduler().runDelayed(plugin, wrapRunnable(runnable), retired, normalizedTicks(delay));
} else {
scheduledTask = Bukkit.getGlobalRegionScheduler().runDelayed(key.plugin, wrapRunnable(retired), normalizedTicks(delay));
scheduledTask = Bukkit.getGlobalRegionScheduler().runDelayed(plugin, wrapRunnable(retired), normalizedTicks(delay));
}
return new FoliaTask(scheduledTask);
}

@Override
public Task runTimer(BooleanSupplier runnable, Runnable retired, long delay, long period) {
ScheduledTask scheduledTask;
if (key.isEntityValid()) {
scheduledTask = key.entity.getScheduler().runAtFixedRate(key.plugin, wrapRunnable(runnable), retired, normalizedTicks(delay), normalizedTicks(period));
if (EntityScheduler.isEntityValid(entity)) {
scheduledTask = entity.getScheduler().runAtFixedRate(plugin, wrapRunnable(runnable), retired, normalizedTicks(delay), normalizedTicks(period));
} else {
scheduledTask = Bukkit.getGlobalRegionScheduler().runDelayed(key.plugin, wrapRunnable(retired), normalizedTicks(delay));
scheduledTask = Bukkit.getGlobalRegionScheduler().runDelayed(plugin, wrapRunnable(retired), normalizedTicks(delay));
}
return new FoliaTask(scheduledTask);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,31 +1,20 @@
package io.github.projectunified.minelib.scheduler.global;

import com.google.common.cache.LoadingCache;
import io.github.projectunified.minelib.scheduler.common.scheduler.Scheduler;
import io.github.projectunified.minelib.scheduler.common.util.Platform;
import org.bukkit.plugin.Plugin;

import java.util.concurrent.ExecutionException;

/**
* A {@link Scheduler} that can run tasks globally
*/
public interface GlobalScheduler extends Scheduler {
LoadingCache<Plugin, GlobalScheduler> PROVIDER = Scheduler.createProvider(
Platform.FOLIA.isPlatform() ? FoliaGlobalScheduler::new : BukkitGlobalScheduler::new
);

/**
* Get the {@link GlobalScheduler} for the given plugin
*
* @param plugin the plugin
* @return the scheduler
*/
static GlobalScheduler get(Plugin plugin) {
try {
return PROVIDER.get(plugin);
} catch (ExecutionException e) {
throw new RuntimeException(e);
}
return Platform.FOLIA.isPlatform() ? new FoliaGlobalScheduler(plugin) : new BukkitGlobalScheduler(plugin);
}
}
Loading

0 comments on commit d7c5e67

Please sign in to comment.