Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add TaskId? #5

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -145,11 +145,9 @@ private void checkNotYetScheduled() {
}
}


private MyScheduledTask setupTask(final MyScheduledTask task) {
this.task = task;
return task;
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,9 @@ public boolean isCurrentlyRunning() {
public boolean isRepeatingTask() {
return isRepeating;
}

@Override
public int getTaskId() {
return task.getTaskId();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -103,4 +103,14 @@ public void cancelTasks() {
public void cancelTasks(Plugin plugin) {
Bukkit.getScheduler().cancelTasks(plugin);
}

@Override
public void cancel(int taskId) {
Bukkit.getScheduler().cancelTask(taskId);
}

@Override
public void cancel(MyScheduledTask task) {
task.cancel();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,29 +6,46 @@

public class FoliaScheduledTask implements MyScheduledTask {
private final ScheduledTask task;
private final int taskId;

public FoliaScheduledTask(final ScheduledTask task) {
public FoliaScheduledTask(final ScheduledTask task, int taskId) {
this.task = task;
this.taskId = taskId;
}

@Override
public void cancel() {
this.task.cancel();
}

@Override
public boolean isCancelled() {
return this.task.isCancelled();
}

@Override
public Plugin getOwningPlugin() {
return this.task.getOwningPlugin();
}

@Override
public boolean isCurrentlyRunning() {
final ScheduledTask.ExecutionState state = this.task.getExecutionState();
return state == ScheduledTask.ExecutionState.RUNNING || state == ScheduledTask.ExecutionState.CANCELLED_RUNNING;
}

@Override
public boolean isRepeatingTask() {
return this.task.isRepeatingTask();
}

@Override
public int getTaskId() {
return taskId;
}

public boolean isFinished() {
final ScheduledTask.ExecutionState state = this.task.getExecutionState();
return state == ScheduledTask.ExecutionState.FINISHED;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,17 @@
import org.bukkit.entity.Entity;
import org.bukkit.plugin.Plugin;

import java.util.HashMap;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;

public class FoliaScheduler implements TaskScheduler {

final Plugin plugin;

static final ConcurrentHashMap<Integer, MyScheduledTask> tasks = new ConcurrentHashMap<>();

public FoliaScheduler(Plugin plugin) {
this.plugin = plugin;
}
Expand Down Expand Up @@ -46,7 +51,7 @@ public boolean isRegionThread(Location location) {

@Override
public MyScheduledTask runTask(Runnable runnable) {
return new FoliaScheduledTask(globalRegionScheduler.run(plugin, task -> runnable.run()));
return new FoliaScheduledTask(globalRegionScheduler.run(plugin, task -> runnable.run()), cleanAndGetNextId());
}

@Override
Expand All @@ -55,19 +60,19 @@ public MyScheduledTask runTaskLater(Runnable runnable, long delay) {
if (delay <= 0) {
return runTask(runnable);
}
return new FoliaScheduledTask(globalRegionScheduler.runDelayed(plugin, task -> runnable.run(), delay));
return new FoliaScheduledTask(globalRegionScheduler.runDelayed(plugin, task -> runnable.run(), delay), cleanAndGetNextId());
}

@Override
public MyScheduledTask runTaskTimer(Runnable runnable, long delay, long period) {
//Folia exception: Delay ticks may not be <= 0
delay = getOneIfNotPositive(delay);
return new FoliaScheduledTask(globalRegionScheduler.runAtFixedRate(plugin, task -> runnable.run(), delay, period));
return new FoliaScheduledTask(globalRegionScheduler.runAtFixedRate(plugin, task -> runnable.run(), delay, period), cleanAndGetNextId());
}

@Override
public MyScheduledTask runTask(Plugin plugin, Runnable runnable) {
return new FoliaScheduledTask(globalRegionScheduler.run(plugin, task -> runnable.run()));
return new FoliaScheduledTask(globalRegionScheduler.run(plugin, task -> runnable.run()), cleanAndGetNextId());
}

@Override
Expand All @@ -76,19 +81,19 @@ public MyScheduledTask runTaskLater(Plugin plugin, Runnable runnable, long delay
if (delay <= 0) {
return runTask(plugin, runnable);
}
return new FoliaScheduledTask(globalRegionScheduler.runDelayed(plugin, task -> runnable.run(), delay));
return new FoliaScheduledTask(globalRegionScheduler.runDelayed(plugin, task -> runnable.run(), delay), cleanAndGetNextId());
}

@Override
public MyScheduledTask runTaskTimer(Plugin plugin, Runnable runnable, long delay, long period) {
//Folia exception: Delay ticks may not be <= 0
delay = getOneIfNotPositive(delay);
return new FoliaScheduledTask(globalRegionScheduler.runAtFixedRate(plugin, task -> runnable.run(), delay, period));
return new FoliaScheduledTask(globalRegionScheduler.runAtFixedRate(plugin, task -> runnable.run(), delay, period), cleanAndGetNextId());
}

@Override
public MyScheduledTask runTask(Location location, Runnable runnable) {
return new FoliaScheduledTask(regionScheduler.run(plugin, location, task -> runnable.run()));
return new FoliaScheduledTask(regionScheduler.run(plugin, location, task -> runnable.run()), cleanAndGetNextId());
}

@Override
Expand All @@ -97,19 +102,19 @@ public MyScheduledTask runTaskLater(Location location, Runnable runnable, long d
if (delay <= 0) {
return runTask(runnable);
}
return new FoliaScheduledTask(regionScheduler.runDelayed(plugin, location, task -> runnable.run(), delay));
return new FoliaScheduledTask(regionScheduler.runDelayed(plugin, location, task -> runnable.run(), delay), cleanAndGetNextId());
}

@Override
public MyScheduledTask runTaskTimer(Location location, Runnable runnable, long delay, long period) {
//Folia exception: Delay ticks may not be <= 0
delay = getOneIfNotPositive(delay);
return new FoliaScheduledTask(regionScheduler.runAtFixedRate(plugin, location, task -> runnable.run(), delay, period));
return new FoliaScheduledTask(regionScheduler.runAtFixedRate(plugin, location, task -> runnable.run(), delay, period), cleanAndGetNextId());
}

@Override
public MyScheduledTask runTask(Entity entity, Runnable runnable) {
return new FoliaScheduledTask(entity.getScheduler().run(plugin, task -> runnable.run(), null));
return new FoliaScheduledTask(entity.getScheduler().run(plugin, task -> runnable.run(), null), cleanAndGetNextId());
}

@Override
Expand All @@ -118,50 +123,50 @@ public MyScheduledTask runTaskLater(Entity entity, Runnable runnable, long delay
if (delay <= 0) {
return runTask(entity, runnable);
}
return new FoliaScheduledTask(entity.getScheduler().runDelayed(plugin, task -> runnable.run(), null, delay));
return new FoliaScheduledTask(entity.getScheduler().runDelayed(plugin, task -> runnable.run(), null, delay), cleanAndGetNextId());
}

@Override
public MyScheduledTask runTaskTimer(Entity entity, Runnable runnable, long delay, long period) {
//Folia exception: Delay ticks may not be <= 0
delay = getOneIfNotPositive(delay);
return new FoliaScheduledTask(entity.getScheduler().runAtFixedRate(plugin, task -> runnable.run(), null, delay, period));
return new FoliaScheduledTask(entity.getScheduler().runAtFixedRate(plugin, task -> runnable.run(), null, delay, period), cleanAndGetNextId());
}

@Override
public MyScheduledTask runTaskAsynchronously(Runnable runnable) {
return new FoliaScheduledTask(asyncScheduler.runNow(plugin, task -> runnable.run()));
return new FoliaScheduledTask(asyncScheduler.runNow(plugin, task -> runnable.run()), cleanAndGetNextId());
}

@Override
public MyScheduledTask runTaskLaterAsynchronously(Runnable runnable, long delay) {
//Folia exception: Delay ticks may not be <= 0
delay = getOneIfNotPositive(delay);
return new FoliaScheduledTask(asyncScheduler.runDelayed(plugin, task -> runnable.run(), delay * 50L, TimeUnit.MILLISECONDS));
return new FoliaScheduledTask(asyncScheduler.runDelayed(plugin, task -> runnable.run(), delay * 50L, TimeUnit.MILLISECONDS), cleanAndGetNextId());
}

@Override
public MyScheduledTask runTaskTimerAsynchronously(Runnable runnable, long delay, long period) {
return new FoliaScheduledTask(asyncScheduler.runAtFixedRate(plugin, task -> runnable.run(), delay * 50, period * 50, TimeUnit.MILLISECONDS));
return new FoliaScheduledTask(asyncScheduler.runAtFixedRate(plugin, task -> runnable.run(), delay * 50, period * 50, TimeUnit.MILLISECONDS), cleanAndGetNextId());
}

@Override
public MyScheduledTask runTaskAsynchronously(Plugin plugin, Runnable runnable) {
return new FoliaScheduledTask(asyncScheduler.runNow(plugin, task -> runnable.run()));
return new FoliaScheduledTask(asyncScheduler.runNow(plugin, task -> runnable.run()), cleanAndGetNextId());
}

@Override
public MyScheduledTask runTaskLaterAsynchronously(Plugin plugin, Runnable runnable, long delay) {
//Folia exception: Delay ticks may not be <= 0
delay = getOneIfNotPositive(delay);
return new FoliaScheduledTask(asyncScheduler.runDelayed(plugin, task -> runnable.run(), delay * 50L, TimeUnit.MILLISECONDS));
return new FoliaScheduledTask(asyncScheduler.runDelayed(plugin, task -> runnable.run(), delay * 50L, TimeUnit.MILLISECONDS), cleanAndGetNextId());
}

@Override
public MyScheduledTask runTaskTimerAsynchronously(Plugin plugin, Runnable runnable, long delay, long period) {
//Folia exception: Delay ticks may not be <= 0
delay = getOneIfNotPositive(delay);
return new FoliaScheduledTask(asyncScheduler.runAtFixedRate(plugin, task -> runnable.run(), delay * 50, period * 50, TimeUnit.MILLISECONDS));
return new FoliaScheduledTask(asyncScheduler.runAtFixedRate(plugin, task -> runnable.run(), delay * 50, period * 50, TimeUnit.MILLISECONDS), cleanAndGetNextId());
}

@Override
Expand Down Expand Up @@ -191,7 +196,42 @@ public void cancelTasks(Plugin plugin) {
asyncScheduler.cancelTasks(plugin);
}

@Override
public void cancel(int taskId) {
tasks.get(taskId).cancel();
}

@Override
public void cancel(MyScheduledTask task) {
task.cancel();
}

private long getOneIfNotPositive(long x) {
return x <= 0 ? 1L : x;
}

private synchronized int cleanAndGetNextId() {
int taskId;

handleClean();

do {
taskId = new Random().nextInt();
} while (tasks.containsKey(taskId));
Copy link
Owner Author

@Anon8281 Anon8281 Sep 27, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we don’t use random, we will still be have to use brute force until we find a free task ID.


return taskId;
}

private synchronized void handleClean() {
HashMap<Integer, MyScheduledTask> tasksToRemove = new HashMap<>();

tasks.forEach((id, task) -> {
FoliaScheduledTask foliaScheduledTask = (FoliaScheduledTask) task;
if (task == null || foliaScheduledTask.isFinished()) {
tasksToRemove.put(id, task);
}
});

tasksToRemove.forEach(tasks::remove);
}
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe there is a more appropriate way

}
Original file line number Diff line number Diff line change
Expand Up @@ -320,4 +320,18 @@ default void execute(Entity entity, Runnable runnable) {
* @param plugin specified plugin
*/
void cancelTasks(Plugin plugin);

/**
* Attempts to cancel task with provided id
*
* @param taskId specified id of task
*/
void cancel(int taskId);

/**
* Attempts to cancel task
*
* @param task specified task
*/
void cancel(MyScheduledTask task);
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,9 @@ public interface MyScheduledTask {
* @return true if task is repeating, false otherwise
*/
boolean isRepeatingTask();

/**
* @return Id of task
*/
int getTaskId();
}
Loading