mirror of
https://github.com/jneug/zeichenmaschine.git
synced 2026-04-14 06:33:34 +02:00
Implementierung verschiedener Task-Typen
Die Tasks erfüllen verschiedene Aufgaben und können vom TaskRunner parallel ausgeführt werden. Ob ein so komplexes Task-Management notwendig ist, bleibt offen.
This commit is contained in:
65
src/schule/ngb/zm/tasks/DelayedTask.java
Normal file
65
src/schule/ngb/zm/tasks/DelayedTask.java
Normal file
@@ -0,0 +1,65 @@
|
||||
package schule.ngb.zm.tasks;
|
||||
|
||||
import schule.ngb.zm.Zeichenmaschine;
|
||||
|
||||
import java.util.concurrent.Delayed;
|
||||
import java.util.concurrent.FutureTask;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public abstract class DelayedTask extends Task implements Delayed {
|
||||
|
||||
protected long startTime = System.currentTimeMillis(); // in ms
|
||||
|
||||
/**
|
||||
* Gibt die absolute Verzögerung der Task zurück. Im Gegensatz zu
|
||||
* {@link #getDelay(TimeUnit)} sollte das Ergebnis von {@code getDelay()}
|
||||
* bei mehrmaligem Aufruf konstant bleiben.
|
||||
*
|
||||
* @return Die ursprüngliche Verzögerung in Millisekunden
|
||||
*/
|
||||
public abstract int getDelay();
|
||||
|
||||
public long getStartTime() {
|
||||
return startTime + getDelay();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gibt die verbleibende Verzögerung bis zur Ausführung der Task zurück. Im
|
||||
* Gegensatz zu {@link #getDelay()} sollte für mehrere Aufrufe von
|
||||
* {@code getDelay(TimeUnit)} gelten, dass der zeitlich spätere Aufruf einen
|
||||
* kleineren Wert zurückgibt, als der Frühere (abhängig von der gewählten
|
||||
* {@link TimeUnit}).
|
||||
*
|
||||
* @param unit Die Zeiteinheit für die Verzögerung.
|
||||
* @return Die verbleibende Verzögerung in der angegebenen Zeiteinheit.
|
||||
*/
|
||||
@Override
|
||||
public long getDelay( TimeUnit unit ) {
|
||||
int diff = (int) (getStartTime() - System.currentTimeMillis());
|
||||
return unit.convert(diff, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo( Delayed o ) {
|
||||
return (int) (getDelay(TimeUnit.MILLISECONDS) - o.getDelay(TimeUnit.MILLISECONDS));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
long delay = getDelay(TimeUnit.MILLISECONDS);
|
||||
while( delay > 0 ) {
|
||||
try {
|
||||
wait(delay);
|
||||
} catch( InterruptedException e ) {
|
||||
// Keep waiting
|
||||
}
|
||||
delay = getDelay(TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
running = true;
|
||||
this.update(0.0);
|
||||
running = false;
|
||||
done = true;
|
||||
}
|
||||
|
||||
}
|
||||
51
src/schule/ngb/zm/tasks/FrameSynchronizedTask.java
Normal file
51
src/schule/ngb/zm/tasks/FrameSynchronizedTask.java
Normal file
@@ -0,0 +1,51 @@
|
||||
package schule.ngb.zm.tasks;
|
||||
|
||||
import schule.ngb.zm.Constants;
|
||||
import schule.ngb.zm.Zeichenmaschine;
|
||||
|
||||
public abstract class FrameSynchronizedTask extends Task {
|
||||
|
||||
private static Thread mainThread;
|
||||
|
||||
private static final Thread getMainThread() {
|
||||
if( mainThread == null ) {
|
||||
mainThread = Thread.currentThread();
|
||||
if( !mainThread.getName().equals("Zeichenthread") ) {
|
||||
// Need to search for main Zeichenthread ...
|
||||
}
|
||||
}
|
||||
return mainThread;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
running = true;
|
||||
int lastTick = 0;
|
||||
Thread lock = getMainThread();
|
||||
|
||||
while( running ) {
|
||||
lastTick = Constants.tick;
|
||||
this.update(lastTick);
|
||||
|
||||
synchronized( lock ) {
|
||||
while( lastTick >= Constants.tick ) {
|
||||
/*try {
|
||||
lock.wait();
|
||||
} catch( InterruptedException e ) {
|
||||
// We got interrupted ...
|
||||
}*/
|
||||
Thread.yield();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
running = false;
|
||||
done = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isActive() {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
11
src/schule/ngb/zm/tasks/FramerateLimitedTask.java
Normal file
11
src/schule/ngb/zm/tasks/FramerateLimitedTask.java
Normal file
@@ -0,0 +1,11 @@
|
||||
package schule.ngb.zm.tasks;
|
||||
|
||||
import schule.ngb.zm.Constants;
|
||||
|
||||
public abstract class FramerateLimitedTask extends RateLimitedTask {
|
||||
|
||||
public int getRate() {
|
||||
return Constants.framesPerSecond;
|
||||
}
|
||||
|
||||
}
|
||||
53
src/schule/ngb/zm/tasks/RateLimitedTask.java
Normal file
53
src/schule/ngb/zm/tasks/RateLimitedTask.java
Normal file
@@ -0,0 +1,53 @@
|
||||
package schule.ngb.zm.tasks;
|
||||
|
||||
public abstract class RateLimitedTask extends Task {
|
||||
|
||||
public abstract int getRate();
|
||||
|
||||
@Override
|
||||
public final void run() {
|
||||
if( running || done ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// current time in ns
|
||||
long beforeTime = System.nanoTime();
|
||||
// store for deltas
|
||||
long overslept = 0L;
|
||||
// delta in ms
|
||||
double delta = 0;
|
||||
|
||||
running = true;
|
||||
while( running ) {
|
||||
// delta in seconds
|
||||
delta = (System.nanoTime() - beforeTime) / 1000000000.0;
|
||||
beforeTime = System.nanoTime();
|
||||
|
||||
this.update(delta);
|
||||
|
||||
// delta time in ns
|
||||
long afterTime = System.nanoTime();
|
||||
long dt = afterTime - beforeTime;
|
||||
long sleep = 0;
|
||||
if( getRate() > 0 ) {
|
||||
sleep = ((1000000000L / getRate()) - dt) - overslept;
|
||||
}
|
||||
|
||||
if( sleep > 0 ) {
|
||||
try {
|
||||
Thread.sleep(sleep / 1000000L, (int) (sleep % 1000000L));
|
||||
} catch( InterruptedException e ) {
|
||||
// Interrupt not relevant
|
||||
}
|
||||
} else {
|
||||
Thread.yield();
|
||||
}
|
||||
// Did we sleep to long?
|
||||
overslept = (System.nanoTime() - afterTime) - sleep;
|
||||
}
|
||||
|
||||
running = false;
|
||||
done = true;
|
||||
}
|
||||
|
||||
}
|
||||
24
src/schule/ngb/zm/tasks/Task.java
Normal file
24
src/schule/ngb/zm/tasks/Task.java
Normal file
@@ -0,0 +1,24 @@
|
||||
package schule.ngb.zm.tasks;
|
||||
|
||||
import schule.ngb.zm.Updatable;
|
||||
|
||||
public abstract class Task implements Runnable, Updatable {
|
||||
|
||||
protected boolean running = false;
|
||||
|
||||
protected boolean done = false;
|
||||
|
||||
@Override
|
||||
public boolean isActive() {
|
||||
return running;
|
||||
}
|
||||
|
||||
public boolean isDone() {
|
||||
return !running & done;
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
running = false;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -25,6 +25,11 @@ public class TaskRunner {
|
||||
return runner;
|
||||
}
|
||||
|
||||
public static Future<?> run( Task task ) {
|
||||
TaskRunner r = getTaskRunner();
|
||||
return r.pool.submit(task);
|
||||
}
|
||||
|
||||
public static Future<?> run( Runnable task ) {
|
||||
TaskRunner r = getTaskRunner();
|
||||
return r.pool.submit(task);
|
||||
@@ -35,18 +40,13 @@ public class TaskRunner {
|
||||
return r.pool.submit(task, result);
|
||||
}
|
||||
|
||||
public static Future<?> schedule( Runnable task, int ms ) {
|
||||
TaskRunner r = getTaskRunner();
|
||||
return r.pool.schedule(task, ms, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
public static void invokeLater( Runnable task ) {
|
||||
SwingUtilities.invokeLater(task);
|
||||
}
|
||||
|
||||
public static void shutdown() {
|
||||
if( runner != null ) {
|
||||
runner.pool.shutdown();
|
||||
/*runner.pool.shutdown();
|
||||
try {
|
||||
runner.pool.awaitTermination(SHUTDOWN_TIME, TimeUnit.MILLISECONDS);
|
||||
} catch( InterruptedException ex ) {
|
||||
@@ -55,15 +55,27 @@ public class TaskRunner {
|
||||
if( !runner.pool.isTerminated() ) {
|
||||
runner.pool.shutdownNow();
|
||||
}
|
||||
}
|
||||
}*/
|
||||
runner.pool.shutdownNow();
|
||||
}
|
||||
}
|
||||
|
||||
ScheduledExecutorService pool;
|
||||
ExecutorService pool;
|
||||
|
||||
private TaskRunner() {
|
||||
//pool = new ScheduledThreadPoolExecutor(4);
|
||||
pool = Executors.newScheduledThreadPool(POOL_SIZE, new ThreadFactory() {
|
||||
/*pool = Executors.newScheduledThreadPool(POOL_SIZE, new ThreadFactory() {
|
||||
private final ThreadFactory threadFactory = Executors.defaultThreadFactory();
|
||||
|
||||
@Override
|
||||
public Thread newThread( Runnable r ) {
|
||||
Thread t = threadFactory.newThread(r);
|
||||
t.setName("TaskRunner-" + t.getName());
|
||||
t.setDaemon(true);
|
||||
return t;
|
||||
}
|
||||
});*/
|
||||
pool = Executors.newCachedThreadPool(new ThreadFactory() {
|
||||
private final ThreadFactory threadFactory = Executors.defaultThreadFactory();
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user