summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2012-09-07 08:32:31 +0200
committerSven Gothel <[email protected]>2012-09-07 08:32:31 +0200
commit1b6593f973970ad00a0a0f08b56cc83501a55ad2 (patch)
tree18b2498161e255d82e80f4f639dc54bfa89a7ace
parentf2cfb6119a3663715ed2d572643949b3bef58662 (diff)
NEWT EDTUtil: Complete AWT and SWT impl. w/ Newt event dequeue thread (NEDT)
AWT and SWT impl. use the toolkit thread to deliver toolkit events and to execute task. However, NEWT dispatches event using its own queue for NEWT events. Adding a simple thread to dequeue those. Remove 'EDTUtil.start()', since this is implicit @ invoke().
-rw-r--r--src/newt/classes/com/jogamp/newt/swt/NewtCanvasSWT.java10
-rw-r--r--src/newt/classes/com/jogamp/newt/swt/SWTEDTUtil.java217
-rw-r--r--src/newt/classes/com/jogamp/newt/util/EDTUtil.java40
-rw-r--r--src/newt/classes/jogamp/newt/DefaultEDTUtil.java62
-rw-r--r--src/newt/classes/jogamp/newt/DisplayImpl.java9
-rw-r--r--src/newt/classes/jogamp/newt/driver/awt/AWTEDTUtil.java221
-rw-r--r--src/newt/classes/jogamp/newt/driver/awt/DisplayDriver.java10
7 files changed, 477 insertions, 92 deletions
diff --git a/src/newt/classes/com/jogamp/newt/swt/NewtCanvasSWT.java b/src/newt/classes/com/jogamp/newt/swt/NewtCanvasSWT.java
index f45b864fa..cada253bc 100644
--- a/src/newt/classes/com/jogamp/newt/swt/NewtCanvasSWT.java
+++ b/src/newt/classes/com/jogamp/newt/swt/NewtCanvasSWT.java
@@ -67,9 +67,6 @@ public class NewtCanvasSWT extends Canvas implements WindowClosingProtocol {
private static final boolean DEBUG = Debug.debug("Window");
private static final boolean isOSX = NativeWindowFactory.TYPE_MACOSX == NativeWindowFactory.getNativeWindowType(false);
- /** SWT EDTUtil associated w/ parent's SWT Display */
- private final EDTUtil swtEDTUtil;
-
private final AbstractGraphicsScreen screen;
private WindowClosingMode newtChildCloseOp = WindowClosingMode.DISPOSE_ON_CLOSE;
@@ -117,8 +114,6 @@ public class NewtCanvasSWT extends Canvas implements WindowClosingProtocol {
public NewtCanvasSWT(final Composite parent, final int style, Window child) {
super(parent, style | SWT.NO_BACKGROUND);
- swtEDTUtil = new SWTEDTUtil(parent.getDisplay());
-
SWTAccessor.setRealized(this, true);
clientArea = getClientArea();
@@ -326,8 +321,9 @@ public class NewtCanvasSWT extends Canvas implements WindowClosingProtocol {
updateSizeCheck();
final int w = clientArea.width;
final int h = clientArea.height;
-
- newtChild.getScreen().getDisplay().setEDTUtil(swtEDTUtil);
+
+ final Display newtDisplay = newtChild.getScreen().getDisplay();
+ newtDisplay.setEDTUtil(new SWTEDTUtil(newtDisplay, getDisplay()));
newtChild.setSize(w, h);
newtChild.reparentWindow(nativeWindow);
diff --git a/src/newt/classes/com/jogamp/newt/swt/SWTEDTUtil.java b/src/newt/classes/com/jogamp/newt/swt/SWTEDTUtil.java
index 3538caad2..d4b83d891 100644
--- a/src/newt/classes/com/jogamp/newt/swt/SWTEDTUtil.java
+++ b/src/newt/classes/com/jogamp/newt/swt/SWTEDTUtil.java
@@ -27,7 +27,9 @@
*/
package com.jogamp.newt.swt;
-import org.eclipse.swt.widgets.Display;
+import java.awt.EventQueue;
+
+import jogamp.newt.Debug;
import com.jogamp.newt.util.EDTUtil;
@@ -36,64 +38,243 @@ import com.jogamp.newt.util.EDTUtil;
* of the given {@link Display}.
*/
public class SWTEDTUtil implements EDTUtil {
- private final Display swtDisplay;
+ public static final boolean DEBUG = Debug.debug("EDT");
+
+ private final Object edtLock = new Object(); // locking the EDT start/stop state
+ private final ThreadGroup threadGroup;
+ private final String name;
+ private final Runnable dispatchMessages;
+ private final org.eclipse.swt.widgets.Display swtDisplay;
+ private NewtEventDispatchThread nedt = null;
+ private int start_iter=0;
+ private static long pollPeriod = EDTUtil.defaultEDTPollPeriod;
- public SWTEDTUtil(Display swtDisplay) {
+ public SWTEDTUtil(final com.jogamp.newt.Display newtDisplay, org.eclipse.swt.widgets.Display swtDisplay) {
+ this.threadGroup = Thread.currentThread().getThreadGroup();
+ this.name=Thread.currentThread().getName()+"-SWTDisplay-"+newtDisplay.getFQName()+"-EDT-";
+ this.dispatchMessages = new Runnable() {
+ public void run() {
+ ((jogamp.newt.DisplayImpl) newtDisplay).dispatchMessages();
+ } };
this.swtDisplay = swtDisplay;
+ this.nedt = new NewtEventDispatchThread(threadGroup, name);
+ this.nedt.setDaemon(true); // don't stop JVM from shutdown ..
}
- public final Display getDisplay() {
+ public final org.eclipse.swt.widgets.Display getDisplay() {
return swtDisplay;
}
@Override
public long getPollPeriod() {
- return 0;
+ return pollPeriod;
}
@Override
public void setPollPeriod(long ms) {
+ pollPeriod = ms;
}
@Override
public void reset() {
+ synchronized(edtLock) {
+ waitUntilStopped();
+ if(DEBUG) {
+ System.err.println(Thread.currentThread()+": EDT reset - edt: "+nedt);
+ }
+ this.nedt = new NewtEventDispatchThread(threadGroup, name);
+ this.nedt.setDaemon(true); // don't stop JVM from shutdown ..
+ }
}
- @Override
- public void start() {
+ private final void startImpl() {
+ if(nedt.isAlive()) {
+ throw new RuntimeException("EDT Thread.isAlive(): true, isRunning: "+nedt.isRunning()+", edt: "+nedt);
+ }
+ start_iter++;
+ nedt.setName(name+start_iter);
+ nedt.shouldStop = false;
+ if(DEBUG) {
+ System.err.println(Thread.currentThread()+": EDT START - edt: "+nedt);
+ // Thread.dumpStack();
+ }
+ nedt.start();
}
-
+
@Override
public boolean isCurrentThreadEDT() {
return swtDisplay.getThread() == Thread.currentThread();
}
@Override
+ public final boolean isCurrentThreadNEDT() {
+ return nedt == Thread.currentThread();
+ }
+
+ @Override
+ public final boolean isCurrentThreadEDTorNEDT() {
+ final Thread ct = Thread.currentThread();
+ return ct == swtDisplay.getThread() || ct == nedt ;
+ }
+
+ @Override
public boolean isRunning() {
- return true;
+ return nedt.isRunning() ; // SWT is always running
}
-
+
@Override
- public void invokeStop(Runnable finalTask) {
- swtDisplay.syncExec(finalTask);
+ public final void invokeStop(Runnable task) {
+ invokeImpl(true, task, true);
}
@Override
- public void invoke(boolean wait, Runnable task) {
+ public final void invoke(boolean wait, Runnable task) {
+ invokeImpl(wait, task, false);
+ }
+
+ private void invokeImpl(boolean wait, Runnable task, boolean stop) {
+ if(task == null) {
+ throw new RuntimeException("Null Runnable");
+ }
+ synchronized(edtLock) { // lock the EDT status
+ if( nedt.shouldStop ) {
+ // drop task ..
+ if(DEBUG) {
+ System.err.println("Warning: EDT about (1) to stop, won't enqueue new task: "+nedt);
+ Thread.dumpStack();
+ }
+ return;
+ }
+ // System.err.println(Thread.currentThread()+" XXX stop: "+stop+", tasks: "+edt.tasks.size()+", task: "+task);
+ // Thread.dumpStack();
+ if(stop) {
+ nedt.shouldStop = true;
+ if(DEBUG) {
+ System.err.println(Thread.currentThread()+": EDT signal STOP (on edt: "+isCurrentThreadEDT()+") - "+nedt);
+ // Thread.dumpStack();
+ }
+ }
+
+ // start if should not stop && not started yet
+ if( !stop && !nedt.isRunning() ) {
+ startImpl();
+ }
+ }
if(wait) {
swtDisplay.syncExec(task);
} else {
swtDisplay.asyncExec(task);
}
- }
+ }
@Override
- public void waitUntilIdle() {
- // all sync ..
+ final public void waitUntilIdle() {
+ final NewtEventDispatchThread _edt;
+ synchronized(edtLock) {
+ _edt = nedt;
+ }
+ if(!_edt.isRunning() || EventQueue.isDispatchThread() || _edt == Thread.currentThread()) {
+ return;
+ }
+ try {
+ swtDisplay.syncExec(new Runnable() {
+ public void run() { }
+ });
+ } catch (Exception e) { }
}
@Override
- public void waitUntilStopped() {
- // all sync ..
+ final public void waitUntilStopped() {
+ synchronized(edtLock) {
+ if(nedt.isRunning() && nedt != Thread.currentThread() ) {
+ while(nedt.isRunning()) {
+ try {
+ edtLock.wait();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
}
+
+ class NewtEventDispatchThread extends Thread {
+ volatile boolean shouldStop = false;
+ volatile boolean isRunning = false;
+ Object sync = new Object();
+
+ public NewtEventDispatchThread(ThreadGroup tg, String name) {
+ super(tg, name);
+ }
+
+ final public boolean isRunning() {
+ return isRunning;
+ }
+
+ @Override
+ final public void start() throws IllegalThreadStateException {
+ isRunning = true;
+ super.start();
+ }
+
+ /**
+ * Utilizing locking only on tasks and its execution,
+ * not for event dispatching.
+ */
+ @Override
+ final public void run() {
+ if(DEBUG) {
+ System.err.println(getName()+": EDT run() START "+ getName());
+ }
+ RuntimeException error = null;
+ try {
+ do {
+ // event dispatch
+ if(!shouldStop) {
+ // FIXME: Determine whether we require to run the
+ // delivery of events (dispatch) on AWT-EDT.
+ // Since the WindowDriver itself delivers all Window related events,
+ // this shall not be required.
+ // AWTEDTExecutor.singleton.invoke(true, dispatchMessages);
+ dispatchMessages.run();
+ }
+ // wait
+ synchronized(sync) {
+ if(!shouldStop) {
+ try {
+ sync.wait(pollPeriod);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ } while(!shouldStop) ;
+ } catch (Throwable t) {
+ // handle errors ..
+ shouldStop = true;
+ if(t instanceof RuntimeException) {
+ error = (RuntimeException) t;
+ } else {
+ error = new RuntimeException("Within EDT", t);
+ }
+ } finally {
+ if(DEBUG) {
+ System.err.println(getName()+": EDT run() END "+ getName()+", "+error);
+ }
+ synchronized(edtLock) {
+ isRunning = !shouldStop;
+ if(!isRunning) {
+ edtLock.notifyAll();
+ }
+ }
+ if(DEBUG) {
+ System.err.println(getName()+": EDT run() EXIT "+ getName()+", exception: "+error);
+ }
+ if(null!=error) {
+ throw error;
+ }
+ } // finally
+ } // run()
+ } // EventDispatchThread
+
}
diff --git a/src/newt/classes/com/jogamp/newt/util/EDTUtil.java b/src/newt/classes/com/jogamp/newt/util/EDTUtil.java
index 4493e2781..7e19d9de5 100644
--- a/src/newt/classes/com/jogamp/newt/util/EDTUtil.java
+++ b/src/newt/classes/com/jogamp/newt/util/EDTUtil.java
@@ -28,6 +28,9 @@
package com.jogamp.newt.util;
+import jogamp.newt.DisplayImpl;
+import com.jogamp.newt.event.NEWTEvent;
+
/**
* EDT stands for Event Dispatch Thread.
* <p>
@@ -63,25 +66,46 @@ public interface EDTUtil {
/**
* Create a new EDT. One should invoke <code>reset()</code><br>
- * after <code>invokeStop(..)</code> in case another <code>start()</code> or <code>invoke(..)</code>
+ * after <code>invokeStop(..)</code> in case another start via <code>invoke(..)</code>
* is expected.
*
- * @see #start()
* @see #invoke(boolean, java.lang.Runnable)
* @see #invokeStop(java.lang.Runnable)
*/
public void reset();
/**
- * Start the EDT
+ * Returns true if the current thread is the event dispatch thread (EDT).
+ * <p>
+ * The EDT is the platform specific thread dispatching toolkit-events
+ * and executing toolkit-tasks enqueued via {@link #invoke(boolean, Runnable)}.
+ * </p>
+ * <p>
+ * Usually it is the same thread as used to dequeue informal {@link NEWTEvent}s (NEDT), see {@link #isCurrentThreadNEDT()},
+ * however, this may differ, e.g. SWT and AWT implementation.
+ * </p>
*/
- public void start();
+ public boolean isCurrentThreadEDT();
/**
- * @return True if the current thread is the EDT thread
+ * Returns true if the current thread is the internal NEWT event dequeue thread (NEDT).
+ * <p>
+ * The NEDT is the NEWT thread used to dequeue informal {@link NEWTEvent}s enqueued internally
+ * via {@link DisplayImpl#enqueueEvent(boolean, NEWTEvent)}.
+ * </p>
+ * <p>
+ * Usually it is the same thread as the EDT, see {@link #isCurrentThreadEDT()},
+ * however, this may differ, e.g. SWT and AWT implementation.
+ * </p>
*/
- public boolean isCurrentThreadEDT();
-
+ public boolean isCurrentThreadNEDT();
+
+ /**
+ * Returns <code>true</code> if either {@link #isCurrentThreadEDT()} or {@link #isCurrentThreadNEDT()} is <code>true</code>,
+ * otherwise <code>false</code>.
+ */
+ public boolean isCurrentThreadEDTorNEDT();
+
/**
* @return True if EDT is running
*/
@@ -101,9 +125,9 @@ public interface EDTUtil {
public void invokeStop(Runnable finalTask);
/**
+ * Shall start the thread if not running.<br>
* Append task to the EDT task queue.<br>
* Wait until execution is finished if <code>wait == true</code>.<br>
- * Shall start the thread if not running.<br>
* Can be issued from within EDT, ie from within an enqueued task.<br>
*
* @throws RuntimeException in case EDT is stopped and not {@link #reset()}
diff --git a/src/newt/classes/jogamp/newt/DefaultEDTUtil.java b/src/newt/classes/jogamp/newt/DefaultEDTUtil.java
index bdbe96070..18418a8dc 100644
--- a/src/newt/classes/jogamp/newt/DefaultEDTUtil.java
+++ b/src/newt/classes/jogamp/newt/DefaultEDTUtil.java
@@ -49,12 +49,12 @@ import com.jogamp.newt.util.EDTUtil;
public class DefaultEDTUtil implements EDTUtil {
public static final boolean DEBUG = Debug.debug("EDT");
- private ThreadGroup threadGroup;
+ private final Object edtLock = new Object(); // locking the EDT start/stop state
+ private final ThreadGroup threadGroup;
+ private final String name;
+ private final Runnable dispatchMessages;
private EventDispatchThread edt = null;
- private Object edtLock = new Object(); // locking the EDT start/stop state
- private String name;
- int start_iter=0;
- private Runnable dispatchMessages;
+ private int start_iter=0;
private static long pollPeriod = EDTUtil.defaultEDTPollPeriod;
public DefaultEDTUtil(ThreadGroup tg, String name, Runnable dispatchMessages) {
@@ -65,14 +65,17 @@ public class DefaultEDTUtil implements EDTUtil {
this.edt.setDaemon(true); // don't stop JVM from shutdown ..
}
+ @Override
final public long getPollPeriod() {
return pollPeriod;
}
+ @Override
final public void setPollPeriod(long ms) {
pollPeriod = ms;
}
+ @Override
public final void reset() {
synchronized(edtLock) {
waitUntilStopped();
@@ -88,36 +91,46 @@ public class DefaultEDTUtil implements EDTUtil {
}
}
- public final void start() {
- synchronized(edtLock) {
- if(!edt.isRunning() && !edt.shouldStop) {
- if(edt.isAlive()) {
- throw new RuntimeException("EDT Thread.isAlive(): true, isRunning: "+edt.isRunning()+", edt: "+edt+", tasks: "+edt.tasks.size());
- }
- start_iter++;
- edt.setName(name+start_iter);
- edt.shouldStop = false;
- if(DEBUG) {
- System.err.println(Thread.currentThread()+": EDT START - edt: "+edt);
- // Thread.dumpStack();
- }
- edt.start();
- }
+ private final void startImpl() {
+ if(edt.isAlive()) {
+ throw new RuntimeException("EDT Thread.isAlive(): true, isRunning: "+edt.isRunning()+", edt: "+edt+", tasks: "+edt.tasks.size());
}
+ start_iter++;
+ edt.setName(name+start_iter);
+ edt.shouldStop = false;
+ if(DEBUG) {
+ System.err.println(Thread.currentThread()+": EDT START - edt: "+edt);
+ // Thread.dumpStack();
+ }
+ edt.start();
}
+ @Override
public final boolean isCurrentThreadEDT() {
- return edt == Thread.currentThread();
+ return edt == Thread.currentThread(); // EDT == NEDT
+ }
+
+ @Override
+ public final boolean isCurrentThreadNEDT() {
+ return edt == Thread.currentThread(); // EDT == NEDT
}
+ @Override
+ public final boolean isCurrentThreadEDTorNEDT() {
+ return edt == Thread.currentThread(); // EDT == NEDT
+ }
+
+ @Override
public final boolean isRunning() {
return edt.isRunning() ;
}
+ @Override
public final void invokeStop(Runnable task) {
invokeImpl(true, task, true);
}
+ @Override
public final void invoke(boolean wait, Runnable task) {
invokeImpl(wait, task, false);
}
@@ -158,8 +171,11 @@ public class DefaultEDTUtil implements EDTUtil {
}
}
} else {
+ // start if should not stop && not started yet
+ if( !stop && !edt.isRunning() ) {
+ startImpl();
+ }
synchronized(edt.tasks) {
- start(); // start if not started yet and !shouldStop
wait = wait && edt.isRunning();
rTask = new RunnableTask(task,
wait ? rTaskLock : null,
@@ -195,6 +211,7 @@ public class DefaultEDTUtil implements EDTUtil {
}
}
+ @Override
final public void waitUntilIdle() {
final EventDispatchThread _edt;
synchronized(edtLock) {
@@ -215,6 +232,7 @@ public class DefaultEDTUtil implements EDTUtil {
}
}
+ @Override
final public void waitUntilStopped() {
synchronized(edtLock) {
if(edt.isRunning() && edt != Thread.currentThread() ) {
diff --git a/src/newt/classes/jogamp/newt/DisplayImpl.java b/src/newt/classes/jogamp/newt/DisplayImpl.java
index bac4031f0..bca7f6e5b 100644
--- a/src/newt/classes/jogamp/newt/DisplayImpl.java
+++ b/src/newt/classes/jogamp/newt/DisplayImpl.java
@@ -169,8 +169,7 @@ public abstract class DisplayImpl extends Display {
public EDTUtil setEDTUtil(EDTUtil newEDTUtil) {
if(null == newEDTUtil) {
newEDTUtil = createEDTUtil();
- }
- if( newEDTUtil == edtUtil ) {
+ } else if( newEDTUtil == edtUtil ) {
if(DEBUG) {
System.err.println("Display.setEDTUtil: "+newEDTUtil+" - keep!");
}
@@ -366,7 +365,7 @@ public abstract class DisplayImpl extends Display {
DisplayImpl.this.dispatchMessages();
}
}
- DispatchMessagesRunnable dispatchMessagesRunnable = new DispatchMessagesRunnable();
+ protected DispatchMessagesRunnable dispatchMessagesRunnable = new DispatchMessagesRunnable();
final void dispatchMessage(final NEWTEventTask eventTask) {
final NEWTEvent event = eventTask.get();
@@ -446,8 +445,8 @@ public abstract class DisplayImpl extends Display {
return;
}
- // can't wait if we are on EDT -> consume right away
- if(wait && edtUtil.isCurrentThreadEDT()) {
+ // can't wait if we are on EDT or NEDT -> consume right away
+ if(wait && edtUtil.isCurrentThreadEDTorNEDT() ) {
dispatchMessage(new NEWTEventTask(e, null));
return;
}
diff --git a/src/newt/classes/jogamp/newt/driver/awt/AWTEDTUtil.java b/src/newt/classes/jogamp/newt/driver/awt/AWTEDTUtil.java
index 942651187..8771f5c74 100644
--- a/src/newt/classes/jogamp/newt/driver/awt/AWTEDTUtil.java
+++ b/src/newt/classes/jogamp/newt/driver/awt/AWTEDTUtil.java
@@ -28,72 +28,239 @@
package jogamp.newt.driver.awt;
-import javax.media.opengl.Threading;
+import java.awt.EventQueue;
import com.jogamp.newt.util.EDTUtil;
+
+import jogamp.common.awt.AWTEDTExecutor;
import jogamp.newt.Debug;
public class AWTEDTUtil implements EDTUtil {
public static final boolean DEBUG = Debug.debug("EDT");
-
- private static AWTEDTUtil singletonMainThread = new AWTEDTUtil(); // one singleton MainThread
- public static AWTEDTUtil getSingleton() {
- return singletonMainThread;
- }
+ private final Object edtLock = new Object(); // locking the EDT start/stop state
+ private final ThreadGroup threadGroup;
+ private final String name;
+ private final Runnable dispatchMessages;
+ private NewtEventDispatchThread nedt = null;
+ private int start_iter=0;
+ private static long pollPeriod = EDTUtil.defaultEDTPollPeriod;
- AWTEDTUtil() {
- // package private access ..
+ public AWTEDTUtil(ThreadGroup tg, String name, Runnable dispatchMessages) {
+ this.threadGroup = tg;
+ this.name=Thread.currentThread().getName()+"-"+name+"-EDT-";
+ this.dispatchMessages=dispatchMessages;
+ this.nedt = new NewtEventDispatchThread(threadGroup, name);
+ this.nedt.setDaemon(true); // don't stop JVM from shutdown ..
}
+ @Override
final public long getPollPeriod() {
- return 0;
+ return pollPeriod;
}
+ @Override
final public void setPollPeriod(long ms) {
- // nop
+ pollPeriod = ms;
}
+ @Override
final public void reset() {
- // nop AWT is always running
+ synchronized(edtLock) {
+ waitUntilStopped();
+ if(DEBUG) {
+ System.err.println(Thread.currentThread()+": EDT reset - edt: "+nedt);
+ }
+ this.nedt = new NewtEventDispatchThread(threadGroup, name);
+ this.nedt.setDaemon(true); // don't stop JVM from shutdown ..
+ }
}
- final public void start() {
- // nop AWT is always running
+ private final void startImpl() {
+ if(nedt.isAlive()) {
+ throw new RuntimeException("EDT Thread.isAlive(): true, isRunning: "+nedt.isRunning()+", edt: "+nedt);
+ }
+ start_iter++;
+ nedt.setName(name+start_iter);
+ nedt.shouldStop = false;
+ if(DEBUG) {
+ System.err.println(Thread.currentThread()+": EDT START - edt: "+nedt);
+ // Thread.dumpStack();
+ }
+ nedt.start();
}
+ @Override
final public boolean isCurrentThreadEDT() {
- return Threading.isToolkitThread();
+ return EventQueue.isDispatchThread();
}
+ @Override
+ public final boolean isCurrentThreadNEDT() {
+ return nedt == Thread.currentThread();
+ }
+
+ @Override
+ public final boolean isCurrentThreadEDTorNEDT() {
+ return EventQueue.isDispatchThread() || nedt == Thread.currentThread();
+ }
+
+ @Override
final public boolean isRunning() {
- return true; // AWT is always running
+ return nedt.isRunning() ; // AWT is always running
}
- final public void invokeStop(Runnable r) {
- invoke(true, r); // AWT is always running
+ @Override
+ public final void invokeStop(Runnable task) {
+ invokeImpl(true, task, true);
}
- final public void invoke(boolean wait, Runnable r) {
- if(r == null) {
- return;
- }
-
- Threading.invoke(wait, r, null);
+ @Override
+ public final void invoke(boolean wait, Runnable task) {
+ invokeImpl(wait, task, false);
}
+
+ private void invokeImpl(boolean wait, Runnable task, boolean stop) {
+ if(task == null) {
+ throw new RuntimeException("Null Runnable");
+ }
+ synchronized(edtLock) { // lock the EDT status
+ if( nedt.shouldStop ) {
+ // drop task ..
+ if(DEBUG) {
+ System.err.println("Warning: EDT about (1) to stop, won't enqueue new task: "+nedt);
+ Thread.dumpStack();
+ }
+ return;
+ }
+ // System.err.println(Thread.currentThread()+" XXX stop: "+stop+", tasks: "+edt.tasks.size()+", task: "+task);
+ // Thread.dumpStack();
+ if(stop) {
+ nedt.shouldStop = true;
+ if(DEBUG) {
+ System.err.println(Thread.currentThread()+": EDT signal STOP (on edt: "+isCurrentThreadEDT()+") - "+nedt);
+ // Thread.dumpStack();
+ }
+ }
+
+ // start if should not stop && not started yet
+ if( !stop && !nedt.isRunning() ) {
+ startImpl();
+ }
+ }
+ AWTEDTExecutor.singleton.invoke(wait, task);
+ }
+ @Override
final public void waitUntilIdle() {
- // wait until previous events are processed, at least ..
+ final NewtEventDispatchThread _edt;
+ synchronized(edtLock) {
+ _edt = nedt;
+ }
+ if(!_edt.isRunning() || EventQueue.isDispatchThread() || _edt == Thread.currentThread()) {
+ return;
+ }
try {
- Threading.invoke(true, new Runnable() {
+ AWTEDTExecutor.singleton.invoke(true, new Runnable() {
public void run() { }
- }, null);
+ });
} catch (Exception e) { }
}
+ @Override
final public void waitUntilStopped() {
- // nop: AWT is always running
+ synchronized(edtLock) {
+ if(nedt.isRunning() && nedt != Thread.currentThread() ) {
+ while(nedt.isRunning()) {
+ try {
+ edtLock.wait();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
}
+
+ class NewtEventDispatchThread extends Thread {
+ volatile boolean shouldStop = false;
+ volatile boolean isRunning = false;
+ Object sync = new Object();
+
+ public NewtEventDispatchThread(ThreadGroup tg, String name) {
+ super(tg, name);
+ }
+
+ final public boolean isRunning() {
+ return isRunning;
+ }
+
+ @Override
+ final public void start() throws IllegalThreadStateException {
+ isRunning = true;
+ super.start();
+ }
+
+ /**
+ * Utilizing locking only on tasks and its execution,
+ * not for event dispatching.
+ */
+ @Override
+ final public void run() {
+ if(DEBUG) {
+ System.err.println(getName()+": EDT run() START "+ getName());
+ }
+ RuntimeException error = null;
+ try {
+ do {
+ // event dispatch
+ if(!shouldStop) {
+ // FIXME: Determine whether we require to run the
+ // delivery of events (dispatch) on AWT-EDT.
+ // Since the WindowDriver itself delivers all Window related events,
+ // this shall not be required.
+ // AWTEDTExecutor.singleton.invoke(true, dispatchMessages);
+ dispatchMessages.run();
+ }
+ // wait
+ synchronized(sync) {
+ if(!shouldStop) {
+ try {
+ sync.wait(pollPeriod);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ } while(!shouldStop) ;
+ } catch (Throwable t) {
+ // handle errors ..
+ shouldStop = true;
+ if(t instanceof RuntimeException) {
+ error = (RuntimeException) t;
+ } else {
+ error = new RuntimeException("Within EDT", t);
+ }
+ } finally {
+ if(DEBUG) {
+ System.err.println(getName()+": EDT run() END "+ getName()+", "+error);
+ }
+ synchronized(edtLock) {
+ isRunning = !shouldStop;
+ if(!isRunning) {
+ edtLock.notifyAll();
+ }
+ }
+ if(DEBUG) {
+ System.err.println(getName()+": EDT run() EXIT "+ getName()+", exception: "+error);
+ }
+ if(null!=error) {
+ throw error;
+ }
+ } // finally
+ } // run()
+ } // EventDispatchThread
+
}
diff --git a/src/newt/classes/jogamp/newt/driver/awt/DisplayDriver.java b/src/newt/classes/jogamp/newt/driver/awt/DisplayDriver.java
index 39d96585b..70e9ba570 100644
--- a/src/newt/classes/jogamp/newt/driver/awt/DisplayDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/awt/DisplayDriver.java
@@ -38,6 +38,7 @@ import com.jogamp.nativewindow.awt.AWTGraphicsDevice;
import com.jogamp.newt.NewtFactory;
import com.jogamp.newt.util.EDTUtil;
+import jogamp.newt.DefaultEDTUtil;
import jogamp.newt.DisplayImpl;
public class DisplayDriver extends DisplayImpl {
@@ -52,15 +53,12 @@ public class DisplayDriver extends DisplayImpl {
aDevice = d;
}
- protected void closeNativeImpl() { }
-
- @Override
protected EDTUtil createEDTUtil() {
final EDTUtil def;
if(NewtFactory.useEDT()) {
- def = AWTEDTUtil.getSingleton();
+ def = new AWTEDTUtil(Thread.currentThread().getThreadGroup(), "AWTDisplay-"+getFQName(), dispatchMessagesRunnable);
if(DEBUG) {
- System.err.println("AWTDisplay.createNative("+getFQName()+") Create EDTUtil: "+def.getClass().getName());
+ System.err.println("Display.createNative("+getFQName()+") Create EDTUtil: "+def.getClass().getName());
}
} else {
def = null;
@@ -68,6 +66,8 @@ public class DisplayDriver extends DisplayImpl {
return def;
}
+ protected void closeNativeImpl() { }
+
protected void dispatchMessagesNative() { /* nop */ }
}