aboutsummaryrefslogtreecommitdiffstats
path: root/src/newt/classes/com/jogamp/newt/swt/SWTEDTUtil.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/newt/classes/com/jogamp/newt/swt/SWTEDTUtil.java')
-rw-r--r--src/newt/classes/com/jogamp/newt/swt/SWTEDTUtil.java217
1 files changed, 199 insertions, 18 deletions
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
+
}