mirror of
https://github.com/jneug/zeichenmaschine.git
synced 2026-04-14 14:43:33 +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;
|
return runner;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Future<?> run( Task task ) {
|
||||||
|
TaskRunner r = getTaskRunner();
|
||||||
|
return r.pool.submit(task);
|
||||||
|
}
|
||||||
|
|
||||||
public static Future<?> run( Runnable task ) {
|
public static Future<?> run( Runnable task ) {
|
||||||
TaskRunner r = getTaskRunner();
|
TaskRunner r = getTaskRunner();
|
||||||
return r.pool.submit(task);
|
return r.pool.submit(task);
|
||||||
@@ -35,18 +40,13 @@ public class TaskRunner {
|
|||||||
return r.pool.submit(task, result);
|
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 ) {
|
public static void invokeLater( Runnable task ) {
|
||||||
SwingUtilities.invokeLater(task);
|
SwingUtilities.invokeLater(task);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void shutdown() {
|
public static void shutdown() {
|
||||||
if( runner != null ) {
|
if( runner != null ) {
|
||||||
runner.pool.shutdown();
|
/*runner.pool.shutdown();
|
||||||
try {
|
try {
|
||||||
runner.pool.awaitTermination(SHUTDOWN_TIME, TimeUnit.MILLISECONDS);
|
runner.pool.awaitTermination(SHUTDOWN_TIME, TimeUnit.MILLISECONDS);
|
||||||
} catch( InterruptedException ex ) {
|
} catch( InterruptedException ex ) {
|
||||||
@@ -55,15 +55,27 @@ public class TaskRunner {
|
|||||||
if( !runner.pool.isTerminated() ) {
|
if( !runner.pool.isTerminated() ) {
|
||||||
runner.pool.shutdownNow();
|
runner.pool.shutdownNow();
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
|
runner.pool.shutdownNow();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ScheduledExecutorService pool;
|
ExecutorService pool;
|
||||||
|
|
||||||
private TaskRunner() {
|
private TaskRunner() {
|
||||||
//pool = new ScheduledThreadPoolExecutor(4);
|
//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();
|
private final ThreadFactory threadFactory = Executors.defaultThreadFactory();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
Reference in New Issue
Block a user