|
@@ -1,8 +1,7 @@
|
|
|
package me.km.scheduler;
|
|
|
|
|
|
-import java.util.ConcurrentModificationException;
|
|
|
-import java.util.HashMap;
|
|
|
-import java.util.LinkedList;
|
|
|
+import java.util.Iterator;
|
|
|
+import java.util.concurrent.ConcurrentLinkedQueue;
|
|
|
import me.hammerle.snuviscript.code.ISnuviLogger;
|
|
|
import me.hammerle.snuviscript.code.ISnuviScheduler;
|
|
|
import net.minecraftforge.api.distmarker.Dist;
|
|
@@ -11,17 +10,12 @@ import net.minecraftforge.api.distmarker.OnlyIn;
|
|
|
@OnlyIn(Dist.DEDICATED_SERVER)
|
|
|
public class SnuviScheduler implements ISnuviScheduler {
|
|
|
private final ISnuviLogger logger;
|
|
|
- private boolean checker;
|
|
|
- private int counter;
|
|
|
- private final LinkedList<SnuviTask> addQueue = new LinkedList<>();
|
|
|
- private final LinkedList<Integer> removeQueue = new LinkedList<>();
|
|
|
- private final HashMap<Integer, SnuviTask> tasks = new HashMap<>();
|
|
|
+ private final ConcurrentLinkedQueue<SnuviTask> tasks = new ConcurrentLinkedQueue<>();
|
|
|
private final AsyncWorker worker = new AsyncWorker();
|
|
|
private boolean noAdding = false;
|
|
|
|
|
|
public SnuviScheduler(ISnuviLogger logger) {
|
|
|
this.logger = logger;
|
|
|
- counter = 0;
|
|
|
worker.start();
|
|
|
}
|
|
|
|
|
@@ -30,7 +24,7 @@ public class SnuviScheduler implements ISnuviScheduler {
|
|
|
long endTime = System.nanoTime() + 60_000_000_000l;
|
|
|
logger.print("Waiting until end of synchronized tasks ...");
|
|
|
while(!tasks.isEmpty() && System.nanoTime() < endTime) {
|
|
|
- tick();
|
|
|
+ tick(1000);
|
|
|
}
|
|
|
logger.print("Waiting until end of asynchronous tasks ...");
|
|
|
while(worker.hasWork() && System.nanoTime() < endTime) {
|
|
@@ -39,73 +33,54 @@ public class SnuviScheduler implements ISnuviScheduler {
|
|
|
} catch(InterruptedException ex) {
|
|
|
}
|
|
|
}
|
|
|
+ worker.stop();
|
|
|
logger.print("the scheduler is now stopped");
|
|
|
}
|
|
|
|
|
|
- public void cancelTask(int id) {
|
|
|
- removeQueue.add(id);
|
|
|
- }
|
|
|
-
|
|
|
- public int scheduleRepeatingTask(Runnable r, long ticks, long rtimer) {
|
|
|
+ public void scheduleRepeatingTask(Runnable r, long ticks, long rtimer) {
|
|
|
if(noAdding) {
|
|
|
- logger.print("scheduling tasks is not allowed on server stop");
|
|
|
- return -1;
|
|
|
+ return;
|
|
|
}
|
|
|
- synchronized(addQueue) {
|
|
|
- counter++;
|
|
|
- addQueue.add(new SnuviTask(counter, r, ticks, rtimer));
|
|
|
- }
|
|
|
- return counter;
|
|
|
+ tasks.add(new SnuviTask(r, ticks, rtimer));
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
- public int scheduleTask(Runnable r, long delay) {
|
|
|
- return scheduleRepeatingTask(r, delay, 0);
|
|
|
+ public void scheduleTask(Runnable r, long delay) {
|
|
|
+ scheduleRepeatingTask(r, delay, 0);
|
|
|
}
|
|
|
|
|
|
- @Override
|
|
|
- public int scheduleTask(Runnable r) {
|
|
|
- return scheduleTask(r, 0);
|
|
|
+ public void tick() {
|
|
|
+ tick(1);
|
|
|
}
|
|
|
|
|
|
- public void tick() {
|
|
|
- worker.doWork();
|
|
|
- try {
|
|
|
- if(!removeQueue.isEmpty()) {
|
|
|
- removeQueue.forEach(i -> tasks.remove(i));
|
|
|
- removeQueue.clear();
|
|
|
+ private void tick(int ticks) {
|
|
|
+ Iterator<SnuviTask> iter = tasks.iterator();
|
|
|
+ long endTime = System.currentTimeMillis() + 25;
|
|
|
+ while(iter.hasNext()) {
|
|
|
+ if(System.currentTimeMillis() > endTime) {
|
|
|
+ logger.print("scheduler has run longer than 25 ms");
|
|
|
+ break;
|
|
|
}
|
|
|
- synchronized(addQueue) {
|
|
|
- if(!addQueue.isEmpty()) {
|
|
|
- addQueue.forEach(task -> tasks.put(task.getId(), task));
|
|
|
- addQueue.clear();
|
|
|
+ SnuviTask task = iter.next();
|
|
|
+ try {
|
|
|
+ if(task.tick(ticks, noAdding)) {
|
|
|
+ iter.remove();
|
|
|
}
|
|
|
+ } catch(Exception ex) {
|
|
|
+ logger.print("scheduler exception - task will be removed", ex, null, null, null, null);
|
|
|
+ iter.remove();
|
|
|
}
|
|
|
- checker = false;
|
|
|
- long l = System.currentTimeMillis();
|
|
|
- tasks.values().removeIf(task -> {
|
|
|
- if(checker) {
|
|
|
- return false;
|
|
|
- }
|
|
|
- if(System.currentTimeMillis() - l > 25) {
|
|
|
- checker = true;
|
|
|
- logger.print("scheduler has run longer than 25 ms");
|
|
|
- return false;
|
|
|
- }
|
|
|
- try {
|
|
|
- return task.tick(noAdding);
|
|
|
- } catch(Exception ex) {
|
|
|
- logger.print("scheduler exception - task will be removed");
|
|
|
- ex.printStackTrace();
|
|
|
- return true;
|
|
|
- }
|
|
|
- });
|
|
|
- } catch(ConcurrentModificationException ex) {
|
|
|
- logger.print(ex);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- public AsyncWorker getWorker() {
|
|
|
- return worker;
|
|
|
+ public void scheduleAsyncTask(Runnable r) {
|
|
|
+ if(noAdding) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ worker.add(r);
|
|
|
+ }
|
|
|
+
|
|
|
+ public boolean hasAsyncWork() {
|
|
|
+ return worker.hasWork();
|
|
|
}
|
|
|
}
|