diff options
author | Sven Gothel <[email protected]> | 2009-03-26 07:23:27 +0000 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2009-03-26 07:23:27 +0000 |
commit | da4b831e1c176ef3b3d92486118317eb85fa72d7 (patch) | |
tree | 0ddaad3ebbdedfbfad7a0649e998026f018855ad | |
parent | 2834c004a6fcc1f51818032370c327458dbb1a28 (diff) |
NEWT threading model demo, incl external stimuli adaptor, e.g. MacOSX runLoop
git-svn-id: file:///usr/local/projects/SUN/JOGL/git-svn/../svn-server-sync/jogl-demos/branches/JOGL_2_SANDBOX@330 3298f667-5e0e-4b4a-8ed4-a3559d26a5f4
-rw-r--r-- | src/demos/newt/TaskManagerTest1.java | 2 | ||||
-rw-r--r-- | src/demos/newt/TaskManagerTest2.java | 109 | ||||
-rw-r--r-- | src/demos/newt/util/TaskManager.java (renamed from src/demos/util/TaskManager.java) | 61 | ||||
-rw-r--r-- | src/demos/newt/util/TaskToolWM.java | 227 |
4 files changed, 387 insertions, 12 deletions
diff --git a/src/demos/newt/TaskManagerTest1.java b/src/demos/newt/TaskManagerTest1.java index 7aa801d..5d55bdd 100644 --- a/src/demos/newt/TaskManagerTest1.java +++ b/src/demos/newt/TaskManagerTest1.java @@ -2,7 +2,7 @@ package demos.newt; import javax.media.nativewindow.*; import com.sun.javafx.newt.*; -import demos.util.TaskManager; +import demos.newt.util.TaskManager; public class TaskManagerTest1 implements WindowListener, KeyListener { diff --git a/src/demos/newt/TaskManagerTest2.java b/src/demos/newt/TaskManagerTest2.java new file mode 100644 index 0000000..2ba900f --- /dev/null +++ b/src/demos/newt/TaskManagerTest2.java @@ -0,0 +1,109 @@ +package demos.newt; + +import javax.media.nativewindow.*; +import com.sun.javafx.newt.*; +import demos.newt.util.TaskToolWM; + +public class TaskManagerTest2 implements WindowListener, KeyListener +{ + public static void main(String[] args) + { + new TaskManagerTest2().run(); + } + + public void windowResized(WindowEvent e) {} + public void windowMoved(WindowEvent e) {} + public void windowDestroyNotify(WindowEvent e) { + System.err.println("Window Event Listener DestroyNotify send stop request - START"); + TaskToolWM.unregisterWindowEvent(e.getSource()); + System.err.println("Window Event Listener DestroyNotify send stop request - DONE"); + } + + public void keyPressed(KeyEvent e) + { + if(e.getKeyChar()=='q') { + System.err.println("Key Event Listener 'q' - .."); + TaskToolWM.unregisterWindowEvent(e.getSource()); + } else { + System.err.println("keyPressed "+e); + } + } + public void keyReleased(KeyEvent e) + { + System.err.println("keyReleased "+e); + } + public void keyTyped(KeyEvent e) + { + System.err.println("keyTyped "+e); + } + + private class RenderThread implements Runnable { + Window window; + + public RenderThread(Window w) { + window = w; + } + public void run() { + if(null==window) { + return; + } + try { + // prolog - lock whatever you need + window.lockSurface(); + + // render(window.getSurfaceHandle()); + System.out.println("Render: "+window); + Thread.sleep(200); + } catch (Throwable t) { + // handle errors .. + t.printStackTrace(); + } finally { + // epilog - unlock locked stuff + window.unlockSurface(); + } + } + } + + void run() + { + try + { + + Capabilities caps = new Capabilities(); + caps.setRedBits(8); + caps.setGreenBits(8); + caps.setBlueBits(8); + //caps.setBackgroundOpaque(true); + + Display display = NewtFactory.createDisplay(null); + Screen screen = NewtFactory.createScreen(display, 0); + Window window = NewtFactory.createWindow(screen, caps); + window.setTitle("GlassPrism"); + window.setAutoDrawableClient(true); + window.setUndecorated(false); + window.setSize(256, 256); + window.addKeyListener(this); + + // let's get notified if window is closed + window.addWindowListener(this); + + window.setVisible(true); + + TaskToolWM.registerWindowEvent(window); + TaskToolWM.addRenderTask(window, new RenderThread(window)); + + System.out.println("Main - wait until finished"); + TaskToolWM.waitUntilWindowUnregistered(window); + System.out.println("Main - finished"); + + window.destroy(); + System.out.println("Main - window destroyed"); + TaskToolWM.exit(true); + } + catch (Throwable t) + { + t.printStackTrace(); + } + } +} + diff --git a/src/demos/util/TaskManager.java b/src/demos/newt/util/TaskManager.java index 125d218..da73801 100644 --- a/src/demos/util/TaskManager.java +++ b/src/demos/newt/util/TaskManager.java @@ -34,7 +34,7 @@ * facility. */ -package demos.util; +package demos.newt.util; import java.util.*; @@ -56,15 +56,30 @@ public class TaskManager { public ThreadGroup getThreadGroup() { return threadGroup; } public void start() { + start(false); + } + + /** + * @param externalStimuli true indicates that another thread stimulates, + * ie. calls this TaskManager's run() loop method. + * Hence no own thread is started in this case. + * + * @return The started Runnable, which handles the run-loop. + * Usefull in combination with externalStimuli=true, + * so an external stimuli can call it. + */ + public Runnable start(boolean externalStimuli) { synchronized(taskWorkerLock) { if(null==taskWorker) { taskWorker = new TaskWorker(name); } if(!taskWorker.isRunning()) { - taskWorker.start(); + shouldStop = false; + taskWorker.start(externalStimuli); } taskWorkerLock.notifyAll(); } + return taskWorker; } public void stop() { @@ -104,6 +119,18 @@ public class TaskManager { return res; } + public void waitOnWorker() { + synchronized(taskWorkerLock) { + if(null!=taskWorker && taskWorker.isRunning()) { + try { + taskWorkerLock.wait(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + } + public void waitUntilStopped() { synchronized(taskWorkerLock) { while(null!=taskWorker && taskWorker.isRunning()) { @@ -118,6 +145,7 @@ public class TaskManager { class TaskWorker extends Thread { volatile boolean isRunning = false; + volatile boolean externalStimuli = false; public TaskWorker(String name) { super(threadGroup, name); @@ -127,14 +155,23 @@ public class TaskManager { return isRunning; } - public void run() { + public void start(boolean externalStimuli) throws IllegalThreadStateException { synchronized(this) { + this.externalStimuli = externalStimuli; isRunning = true; } + if(!externalStimuli) { + super.start(); + } + } + + public void run() { while(!shouldStop) { try { // prolog - lock stuff you may wanne do .. + ArrayList clonedTasks; + // wait for something todo .. synchronized(taskWorkerLock) { while(!shouldStop && tasks.size()==0) { @@ -144,12 +181,12 @@ public class TaskManager { e.printStackTrace(); } } + // make a safe clone of the list + // since it may change while working on it + clonedTasks = (ArrayList) tasks.clone(); } - // do it for all tasks, - // first make a safe clone of the list - // since it may change while working on it - ArrayList clonedTasks = (ArrayList) tasks.clone(); + // do it for all tasks for(Iterator i = clonedTasks.iterator(); i.hasNext(); ) { Runnable task = (Runnable) i.next(); task.run(); @@ -160,13 +197,15 @@ public class TaskManager { } finally { // epilog - unlock locked stuff } + if(externalStimuli) break; // no loop if called by external stimuli } synchronized(this) { - isRunning = false; + isRunning = !shouldStop; } - shouldStop=false; - synchronized(taskWorkerLock) { - taskWorkerLock.notifyAll(); + if(!isRunning) { + synchronized(taskWorkerLock) { + taskWorkerLock.notifyAll(); + } } } } diff --git a/src/demos/newt/util/TaskToolWM.java b/src/demos/newt/util/TaskToolWM.java new file mode 100644 index 0000000..eade4e6 --- /dev/null +++ b/src/demos/newt/util/TaskToolWM.java @@ -0,0 +1,227 @@ +/* + * Copyright (c) 2009 Sun Microsystems, Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed or intended for use + * in the design, construction, operation or maintenance of any nuclear + * facility. + */ + +package demos.newt.util; + +import java.util.*; + +import javax.media.nativewindow.*; +import com.sun.javafx.newt.*; + +public class TaskToolWM { + final static boolean externalStimuli; + final static TaskManager eventMgr; + final static Runnable eventMgrRunnable; + final static TaskManager renderMgr; + final static Runnable renderMgrRunnable; + final static Map/*Window,Runnable*/ window2Event; + final static Map/*Window,Set*/ window2Set; + + static { + System.setProperty("java.awt.headless", "true"); + + window2Event = new HashMap(); + window2Set = new HashMap(); + + externalStimuli = Boolean.getBoolean("demos.newt.util.TaskToolWM.externalStimuli"); + + eventMgr = new TaskManager("Event Manager"); + eventMgrRunnable = eventMgr.start(externalStimuli); + + renderMgr = new TaskManager("Render Manager"); + renderMgrRunnable = renderMgr.start(externalStimuli); + + /** + String osName = System.getProperty("os.name"); + if (osNameLowerCase.startsWith("mac os x") || + osNameLowerCase.startsWith("darwin")) { + TaskManagerMacOSX.registerEventRunnable(eventMgrRunnable); + TaskManagerMacOSX.registerRenderRunnable(renderMgrRunnable); + } */ + } + + private static class EventThread implements Runnable { + Window window; + + EventThread(Window w) { + window = w; + } + public void run() { + try { + // prolog - lock whatever you need + + // do it .. + if(null!=window) { + window.pumpMessages(); + } + } catch (Throwable t) { + // handle errors .. + t.printStackTrace(); + } finally { + // epilog - unlock locked stuff + } + } + } + + public static boolean registerWindowEvent(Window w) { + boolean res; + synchronized(window2Event) { + Runnable evt = (Runnable) window2Event.get(w); + if(null==evt) { + evt = new EventThread(w); + window2Event.put(w, evt); + eventMgr.addTask(evt); + res = true; + } else { + res = false; + } + } + return res; + } + + public static boolean unregisterWindowEvent(Window w) { + boolean res; + synchronized(window2Event) { + Runnable evt = (Runnable) window2Event.remove(w); + if(null!=evt) { + eventMgr.removeTask(evt); + res = true; + } else { + res = false; + } + } + return res; + } + + public static boolean isWindowEventRegistered(Window w) { + boolean res; + synchronized(window2Event) { + res = null != window2Event.get(w); + } + return res; + } + + public static void waitUntilWindowsUnregistered() { + while(window2Event.size()>0) { + eventMgr.waitOnWorker(); + } + } + + public static void waitUntilWindowUnregistered(Window w) { + while(isWindowEventRegistered(w)) { + eventMgr.waitOnWorker(); + } + } + + public static boolean addRenderTask(Window w, Runnable task) { + boolean res; + synchronized(window2Set) { + Set s = (Set) window2Set.get(w); + if(null==s) { + s = new HashSet(); + window2Set.put(w, s); + } + if(s.add(task)) { + renderMgr.addTask(task); + res = true; + } else { + res = false; + } + } + return res; + } + + public static boolean removeRenderTasks(Window w) { + boolean res; + synchronized(window2Set) { + Set s = (Set) window2Set.get(w); + if(null==s) { + res = false; + } else { + for(Iterator i=s.iterator(); i.hasNext(); ) { + Runnable task = (Runnable) i.next(); + renderMgr.removeTask(task); + i.remove(); + } + window2Set.remove(w); + res = true; + } + } + return res; + } + + public static boolean removeRenderTask(Window w, Runnable task) { + boolean res; + synchronized(window2Set) { + Set s = (Set) window2Set.get(w); + if(null==s) { + res = false; + } else { + if(s.remove(task)) { + renderMgr.removeTask(task); + if(s.size()==0) { + window2Set.remove(w); + } + res = true; + } else { + res = false; + } + } + } + return res; + } + + public static Runnable[] getRenderTasks(Window w) { + Runnable[] res=null; + synchronized(window2Set) { + Set s = (Set) window2Set.get(w); + if(null!=s) { + res = (Runnable[])s.toArray(); + } + } + return res; + } + + public static void exit(boolean systemExit) { + eventMgr.stop(); + renderMgr.stop(); + if(systemExit) { + System.exit(0); + } + } +} + + |