fabric-synctask #1

Merged
quentinlegot merged 10 commits from fabric-synctask into master 2023-02-13 15:26:38 +01:00
13 changed files with 113 additions and 72 deletions
Showing only changes of commit e7178d44a9 - Show all commits

View File

@ -5,7 +5,7 @@ public abstract class AltarikRunnable implements Runnable {
private boolean isCancelled = false; private boolean isCancelled = false;
/** /**
* Warning: Some task cannot be cancelled (mostly async tasks like {@link fr.altarik.toolbox.task.asyncTasks.AsyncTasks} * Warning: Some task cannot be cancelled (mostly async tasks like {@link fr.altarik.toolbox.task.async.AsyncTasks}
* The result of this call is ignored in this case, you can still add a way to not execute its content (like if(isCancelled) return;) * The result of this call is ignored in this case, you can still add a way to not execute its content (like if(isCancelled) return;)
*/ */
public void cancel() { public void cancel() {

View File

@ -1,4 +0,0 @@
package fr.altarik.toolbox.task;
public interface AsyncTaskI extends TaskI, AutoCloseable {
}

View File

@ -8,7 +8,7 @@ public interface PeriodicTaskI extends TaskI {
* @param delay delay before starting the task * @param delay delay before starting the task
* @param period time to wait between runs * @param period time to wait between runs
* @throws InterruptedException When executed asynchronously, task may be interrupted * @throws InterruptedException When executed asynchronously, task may be interrupted
* @see fr.altarik.toolbox.task.syncTasks.PeriodicSyncTask * @see fr.altarik.toolbox.task.sync.PeriodicSyncTask
*/ */
public void addTask(AltarikRunnable function, long delay, long period) throws InterruptedException; public void addTask(AltarikRunnable function, long delay, long period) throws InterruptedException;
} }

View File

@ -1,15 +1,29 @@
package fr.altarik.toolbox.task.syncTasks; package fr.altarik.toolbox.task;
import fr.altarik.toolbox.task.AltarikRunnable;
public class SchedulerTaskData { public class SchedulerTaskData {
/**
* Delay before executing the function for the first time
* Correspond to tick in synchronous context and milliseconds in asynchronous context
*/
private final long delay; private final long delay;
/**
* Period of time before re-executing the function
* Correspond to tick in synchronous context and milliseconds in asynchronous context
*/
private final long period; private final long period;
private final AltarikRunnable function; private final AltarikRunnable function;
private long currentDelay; private long currentDelay;
/**
*
* Delay and Period times corresponds to tick in synchronous context and milliseconds in asynchronous context
*
* @param function instructions to execute
* @param delay Delay before executing the function for the first time
* @param period Period of time before re-executing the function
*/
public SchedulerTaskData(AltarikRunnable function, long delay, long period) { public SchedulerTaskData(AltarikRunnable function, long delay, long period) {
this.function = function; this.function = function;
this.delay = delay; this.delay = delay;
@ -36,4 +50,6 @@ public class SchedulerTaskData {
public long getPeriod() { public long getPeriod() {
return period; return period;
} }
} }

View File

@ -1,6 +1,6 @@
package fr.altarik.toolbox.task; package fr.altarik.toolbox.task;
import fr.altarik.toolbox.task.asyncTasks.AsyncTasks; import fr.altarik.toolbox.task.async.AsyncTasks;
import net.fabricmc.api.ModInitializer; import net.fabricmc.api.ModInitializer;
public class Task implements ModInitializer { public class Task implements ModInitializer {

View File

@ -1,6 +1,8 @@
package fr.altarik.toolbox.task.asyncTasks; package fr.altarik.toolbox.task.async;
import fr.altarik.toolbox.task.*; import fr.altarik.toolbox.task.AltarikRunnable;
import fr.altarik.toolbox.task.PeriodicTaskI;
import fr.altarik.toolbox.task.TaskI;
import it.unimi.dsi.fastutil.ints.IntComparators; import it.unimi.dsi.fastutil.ints.IntComparators;
import java.util.ArrayList; import java.util.ArrayList;
@ -56,7 +58,7 @@ public class AsyncPeriodicTasks implements PeriodicTaskI, AsyncTaskI {
@Override @Override
public void addTask(AltarikRunnable function) throws InterruptedException { public void addTask(AltarikRunnable function) throws InterruptedException {
this.addTask(function, 0, 1); this.addTask(function, 0, 1000);
} }
@Override @Override

View File

@ -0,0 +1,6 @@
package fr.altarik.toolbox.task.async;
import fr.altarik.toolbox.task.TaskI;
public interface AsyncTaskI extends TaskI, AutoCloseable {
}

View File

@ -1,4 +1,4 @@
package fr.altarik.toolbox.task.asyncTasks; package fr.altarik.toolbox.task.async;
import fr.altarik.toolbox.task.AltarikRunnable; import fr.altarik.toolbox.task.AltarikRunnable;
import fr.altarik.toolbox.task.TaskI; import fr.altarik.toolbox.task.TaskI;

View File

@ -1,16 +1,27 @@
package fr.altarik.toolbox.task; package fr.altarik.toolbox.task.async;
import fr.altarik.toolbox.task.syncTasks.SchedulerTaskData; import fr.altarik.toolbox.task.AltarikRunnable;
import fr.altarik.toolbox.task.SchedulerTaskData;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.HashMap;
import java.util.Vector; import java.util.Vector;
public class TaskScheduler { public class TaskScheduler {
private Vector<SchedulerTaskData> asyncTasks; private Vector<SchedulerTaskData> asyncTasks;
/**
* Return last time the method was executed, Value initialized to now when using sending the task to scheduler
*/
private HashMap<SchedulerTaskData, Instant> lastTimeExecution;
private boolean stop = false; private boolean stop = false;
public synchronized void sendAsyncTask(AltarikRunnable function, long delay, long period) throws InterruptedException { public synchronized void sendAsyncTask(AltarikRunnable function, long delay, long period) throws InterruptedException {
asyncTasks.addElement(new SchedulerTaskData(function, delay, period)); SchedulerTaskData data = new SchedulerTaskData(function, delay, period);
asyncTasks.addElement(data);
lastTimeExecution.put(new SchedulerTaskData(function, delay, period), Instant.now());
notify(); notify();
} }
@ -30,12 +41,13 @@ public class TaskScheduler {
asyncTasks.remove(data); asyncTasks.remove(data);
if(!data.getFunction().isCancelled()) { if(!data.getFunction().isCancelled()) {
long currentDelay = data.getCurrentDelay(); long currentDelay = data.getCurrentDelay();
if(currentDelay != 0) { Instant currentTime = Instant.now();
data.setCurrentDelay(currentDelay - 1); Instant lastExecution = lastTimeExecution.get(data);
asyncTasks.addElement(data); // (lastExec + delay) - currentTime
} else { if(lastExecution.plus(currentDelay, ChronoUnit.MILLIS).isBefore(currentTime)) {
data.getFunction().run(); data.getFunction().run();
data.setCurrentDelay(data.getPeriod()); data.setCurrentDelay(data.getPeriod());
lastTimeExecution.put(data, Instant.now());
asyncTasks.addElement(data); asyncTasks.addElement(data);
} }
} }

View File

@ -0,0 +1,57 @@
package fr.altarik.toolbox.task.sync;
import fr.altarik.toolbox.task.AltarikRunnable;
import fr.altarik.toolbox.task.PeriodicTaskI;
import fr.altarik.toolbox.task.SchedulerTaskData;
import fr.altarik.toolbox.task.TaskI;
import java.util.ArrayList;
import java.util.List;
public class PeriodicSyncTask implements PeriodicTaskI, Runnable {
private ServerTickListener listener;
private List<SchedulerTaskData> tasks;
private PeriodicSyncTask() {
this.listener = new ServerTickListener(this);
this.tasks = new ArrayList<>(2);
}
public static TaskI initialize() {
return new PeriodicSyncTask();
}
@Override
public void addTask(AltarikRunnable function) throws InterruptedException {
addTask(function, 0, 1);
}
@Override
public void run() {
List<SchedulerTaskData> removeList = new ArrayList<>(tasks.size());
for(SchedulerTaskData data : tasks) {
if(!data.getFunction().isCancelled()) {
long currentDelay = data.getCurrentDelay();
if(currentDelay != 0) {
data.setCurrentDelay(currentDelay - 1);
} else {
data.getFunction().run();
data.setCurrentDelay(data.getPeriod());
}
} else {
removeList.add(data);
}
}
for(SchedulerTaskData toRemove : removeList) {
tasks.remove(toRemove);
}
}
@Override
public void addTask(AltarikRunnable function, long delay, long period) throws InterruptedException {
tasks.add(new SchedulerTaskData(function, delay, period));
}
}

View File

@ -1,4 +1,4 @@
package fr.altarik.toolbox.task.syncTasks; package fr.altarik.toolbox.task.sync;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents; import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents;
import net.minecraft.server.MinecraftServer; import net.minecraft.server.MinecraftServer;
@ -13,7 +13,7 @@ public class ServerTickListener {
} }
private void onServerTick(MinecraftServer minecraftServer) { private void onServerTick(MinecraftServer minecraftServer) {
task.run();
} }
} }

View File

@ -1,48 +0,0 @@
package fr.altarik.toolbox.task.syncTasks;
import fr.altarik.toolbox.task.AltarikRunnable;
import fr.altarik.toolbox.task.PeriodicTaskI;
import fr.altarik.toolbox.task.TaskI;
import java.util.ArrayList;
import java.util.List;
public class PeriodicSyncTask implements PeriodicTaskI, Runnable {
private ServerTickListener listener;
private List<AltarikRunnable> tasks;
private PeriodicSyncTask() {
this.listener = new ServerTickListener(this);
this.tasks = new ArrayList<>(2);
}
public static TaskI initialize() {
return new PeriodicSyncTask();
}
@Override
public void addTask(AltarikRunnable function) throws InterruptedException {
tasks.add(function);
}
@Override
public void run() {
List<AltarikRunnable> removeList = new ArrayList<>(tasks.size());
for(AltarikRunnable task : tasks) {
if(task.isCancelled()) {
removeList.add(task);
} else {
task.run();
}
}
tasks.removeAll(removeList);
}
@Override
public void addTask(AltarikRunnable function, long delay, long period) throws InterruptedException {
}
}

View File

@ -2,7 +2,7 @@ package fr.altarik.toolbox;
import fr.altarik.toolbox.task.AltarikRunnable; import fr.altarik.toolbox.task.AltarikRunnable;
import fr.altarik.toolbox.task.TaskI; import fr.altarik.toolbox.task.TaskI;
import fr.altarik.toolbox.task.asyncTasks.AsyncTasks; import fr.altarik.toolbox.task.async.AsyncTasks;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import java.util.Date; import java.util.Date;