From 302f183c4a659be9cedb5b6993ff78e7379d9cad Mon Sep 17 00:00:00 2001
From: Sven Gothel
Date: Fri, 11 Jun 2010 00:12:15 +0200
Subject: NEWT Add: addListener(int index, Listener l) ;
getListener(int index) ; NEWTEvent attachments
NEWT Add:
addListener(int index, Listener l) ;
getListener(int index) ;
NEWTEvent attachments for listener to listener communication
via object passing. This methodology is similar to the 'Atom'
attachment of native systems.
It is preferred to a 'consume()/isConsumed()' pattern,
since it is less flexible and would 'endanger' system events.
TODO: Listener[] getListeners() doesn't work and was always buggy.
---
.../test/junit/newt/TestListenerCom01AWT.java | 173 +++++++++++++++++++++
.../jogamp/test/junit/newt/TestParenting01AWT.java | 14 --
.../jogamp/test/junit/newt/WindowEventCom1.java | 46 ++++++
.../jogamp/test/junit/newt/WindowEventCom2.java | 52 +++++++
.../jogamp/test/junit/newt/WindowEventCom3.java | 48 ++++++
5 files changed, 319 insertions(+), 14 deletions(-)
create mode 100755 src/junit/com/jogamp/test/junit/newt/TestListenerCom01AWT.java
create mode 100644 src/junit/com/jogamp/test/junit/newt/WindowEventCom1.java
create mode 100644 src/junit/com/jogamp/test/junit/newt/WindowEventCom2.java
create mode 100644 src/junit/com/jogamp/test/junit/newt/WindowEventCom3.java
(limited to 'src/junit/com')
diff --git a/src/junit/com/jogamp/test/junit/newt/TestListenerCom01AWT.java b/src/junit/com/jogamp/test/junit/newt/TestListenerCom01AWT.java
new file mode 100755
index 000000000..b661d02f3
--- /dev/null
+++ b/src/junit/com/jogamp/test/junit/newt/TestListenerCom01AWT.java
@@ -0,0 +1,173 @@
+/*
+ * Copyright (c) 2010 Sven Gothel. 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 Sven Gothel 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
+ * SVEN GOTHEL HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ */
+
+package com.jogamp.test.junit.newt;
+
+import java.lang.reflect.*;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Test;
+
+import java.awt.Button;
+import java.awt.BorderLayout;
+import java.awt.Canvas;
+import java.awt.Frame;
+
+import javax.media.opengl.*;
+import javax.media.nativewindow.*;
+
+import com.jogamp.opengl.util.Animator;
+import com.jogamp.newt.*;
+import com.jogamp.newt.event.*;
+import com.jogamp.newt.opengl.*;
+import com.jogamp.newt.awt.NewtCanvasAWT;
+
+import java.io.IOException;
+
+import com.jogamp.test.junit.util.*;
+import com.jogamp.test.junit.jogl.demos.es1.RedSquare;
+import com.jogamp.test.junit.jogl.demos.gl2.gears.Gears;
+
+public class TestListenerCom01AWT {
+ static int width, height;
+ static long durationPerTest = 500;
+ static long waitReparent = 300;
+ static boolean verbose = false;
+
+ @BeforeClass
+ public static void initClass() {
+ width = 640;
+ height = 480;
+ }
+
+ @Test
+ public void testListenerStringPassingAndOrder() throws InterruptedException {
+ // setup NEWT GLWindow ..
+ GLWindow glWindow = GLWindow.create(new GLCapabilities(null));
+ Assert.assertNotNull(glWindow);
+ glWindow.setTitle("NEWT - CHILD");
+
+ System.out.println("durationPerTest "+durationPerTest);
+
+ GLEventListener demo = new Gears();
+ setDemoFields(demo, glWindow, false);
+ glWindow.addGLEventListener(demo);
+
+ WindowEventCom1 wl1 = new WindowEventCom1();
+ WindowEventCom2 wl2 = new WindowEventCom2();
+ WindowEventCom3 wl3 = new WindowEventCom3();
+
+ // TraceWindowAdapter wlT = new TraceWindowAdapter();
+ // glWindow.addWindowListener(0, wlT);
+ // Assert.assertEquals(wlT, glWindow.getWindowListener(0));
+
+ glWindow.addWindowListener(0, wl3);
+ glWindow.addWindowListener(0, wl2);
+ glWindow.addWindowListener(0, wl1);
+
+ Assert.assertEquals(wl1, glWindow.getWindowListener(0));
+ Assert.assertEquals(wl2, glWindow.getWindowListener(1));
+ Assert.assertEquals(wl3, glWindow.getWindowListener(2));
+
+ // attach NEWT GLWindow to AWT Canvas
+ NewtCanvasAWT newtCanvasAWT = new NewtCanvasAWT(glWindow);
+ Frame frame = new Frame("AWT Parent Frame");
+ frame.add(newtCanvasAWT);
+ frame.setSize(width, height);
+ frame.setVisible(true);
+
+ Animator animator1 = new Animator(glWindow);
+ animator1.start();
+ while(animator1.isAnimating() && animator1.getDuration()
Date: Wed, 16 Jun 2010 06:57:15 +0200
Subject: JOGL.GLAutoDrawable: - Add: 'public void addGLEventListener(int
index, GLEventListener listener)' Fixes previous GLWindow addition, ie
public in interface and common impl. behavior.
- Add: 'public void invoke(boolean wait, GLRunnable glRunnable)'
- Change: 'public void display()' semantics, in regards to the GLRunnable queue
New: GLRunnable, invoke() at GLAutoDrawable
Allows injection of GL commands from other threads, executed after the
GLEventListener's display() notifyier by the GLAutoDrawable.
NEWT:
- Fix EDTUTil.invokeAndWait() and Display.enqueueAndWait() impl.,
where we only wait for the single action/event to be processed now.
JUnit: NEWT Parenting
- Added test cases for Swing (JFrame, JPanel and COntainer) with NewtCanvasAWT
- Added thread calling 'invoke(true, GLRunnable)'
- start Animator ASAP
---
make/build-newt.xml | 2 +-
.../com/jogamp/opengl/impl/GLDrawableHelper.java | 51 +++
.../com/jogamp/opengl/impl/GLPbufferImpl.java | 8 +
.../com/jogamp/opengl/impl/GLRunnableTask.java | 62 +++
.../classes/javax/media/opengl/GLAutoDrawable.java | 54 ++-
.../classes/javax/media/opengl/GLRunnable.java | 41 ++
.../classes/javax/media/opengl/awt/GLCanvas.java | 8 +
.../classes/javax/media/opengl/awt/GLJPanel.java | 8 +
.../jogamp/test/junit/newt/GLRunnableDummy.java | 63 +++
.../test/junit/newt/TestListenerCom01AWT.java | 2 +-
.../jogamp/test/junit/newt/TestParenting01AWT.java | 429 ---------------------
.../test/junit/newt/TestParenting01NEWT.java | 2 +-
.../test/junit/newt/TestParenting01aAWT.java | 429 +++++++++++++++++++++
.../test/junit/newt/TestParenting01bAWT.java | 188 +++++++++
.../test/junit/newt/TestParenting01cAWT.java | 195 ++++++++++
.../test/junit/newt/TestParenting01cSwingAWT.java | 374 ++++++++++++++++++
.../jogamp/test/junit/newt/TestParenting02AWT.java | 2 +-
.../test/junit/newt/TestParenting02NEWT.java | 2 +-
.../jogamp/test/junit/newt/TestParentingAWT.java | 188 ---------
src/newt/classes/com/jogamp/newt/Display.java | 80 ++--
src/newt/classes/com/jogamp/newt/Window.java | 12 +-
.../com/jogamp/newt/impl/event/NEWTEventTask.java | 54 +++
.../classes/com/jogamp/newt/opengl/GLWindow.java | 4 +
src/newt/classes/com/jogamp/newt/util/EDTUtil.java | 34 +-
24 files changed, 1594 insertions(+), 698 deletions(-)
create mode 100644 src/jogl/classes/com/jogamp/opengl/impl/GLRunnableTask.java
create mode 100644 src/jogl/classes/javax/media/opengl/GLRunnable.java
create mode 100644 src/junit/com/jogamp/test/junit/newt/GLRunnableDummy.java
delete mode 100755 src/junit/com/jogamp/test/junit/newt/TestParenting01AWT.java
create mode 100755 src/junit/com/jogamp/test/junit/newt/TestParenting01aAWT.java
create mode 100755 src/junit/com/jogamp/test/junit/newt/TestParenting01bAWT.java
create mode 100755 src/junit/com/jogamp/test/junit/newt/TestParenting01cAWT.java
create mode 100755 src/junit/com/jogamp/test/junit/newt/TestParenting01cSwingAWT.java
delete mode 100755 src/junit/com/jogamp/test/junit/newt/TestParentingAWT.java
create mode 100644 src/newt/classes/com/jogamp/newt/impl/event/NEWTEventTask.java
(limited to 'src/junit/com')
diff --git a/make/build-newt.xml b/make/build-newt.xml
index 2cb848588..27e770611 100644
--- a/make/build-newt.xml
+++ b/make/build-newt.xml
@@ -87,7 +87,7 @@
+ value="com/jogamp/newt/*, com/jogamp/newt/event/*, com/jogamp/newt/util/*, com/jogamp/newt/impl/*, com/jogamp/newt/impl/event/*"/>
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableHelper.java b/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableHelper.java
index fcd662048..8fefe149e 100644
--- a/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableHelper.java
+++ b/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableHelper.java
@@ -51,6 +51,7 @@ public class GLDrawableHelper {
private static final boolean VERBOSE = Debug.verbose();
private static final boolean NVIDIA_CRASH_WORKAROUND = Debug.isPropertyDefined("jogl.nvidia.crash.workaround", true);
private boolean autoSwapBufferMode = true;
+ private ArrayList glRunnables = new ArrayList(); // one shot GL tasks
public GLDrawableHelper() {
}
@@ -100,6 +101,7 @@ public class GLDrawableHelper {
for (Iterator iter = listeners.iterator(); iter.hasNext(); ) {
((GLEventListener) iter.next()).display(drawable);
}
+ execGLRunnables(drawable);
}
public void reshape(GLAutoDrawable drawable,
@@ -109,6 +111,55 @@ public class GLDrawableHelper {
}
}
+ private void execGLRunnables(GLAutoDrawable drawable) {
+ if(glRunnables.size()>0) {
+ ArrayList _glRunnables = null;
+ synchronized(glRunnables) {
+ if(glRunnables.size()>0) {
+ _glRunnables = glRunnables;
+ glRunnables = new ArrayList();
+ }
+ }
+ if(null!=_glRunnables) {
+ for (Iterator iter = _glRunnables.iterator(); iter.hasNext(); ) {
+ ((GLRunnable) iter.next()).run(drawable);
+ }
+ }
+ }
+ }
+
+ private void invokeLater(GLRunnable glRunnable) {
+ synchronized(glRunnables) {
+ glRunnables.add(glRunnable);
+ glRunnables.notifyAll();
+ }
+ }
+
+ public void invoke(boolean wait, GLRunnable glRunnable) {
+ if(glRunnable == null) {
+ return;
+ }
+ Object lock = new Object();
+ GLRunnableTask rTask = new GLRunnableTask(glRunnable, wait?lock:null/*, true*/);
+ Throwable throwable = null;
+ synchronized(lock) {
+ invokeLater(rTask);
+ if( wait ) {
+ try {
+ lock.wait();
+ } catch (InterruptedException ie) {
+ throwable = ie;
+ }
+ }
+ }
+ if(null==throwable) {
+ throwable = rTask.getThrowable();
+ }
+ if(null!=throwable) {
+ throw new RuntimeException(throwable);
+ }
+ }
+
public void setAutoSwapBufferMode(boolean onOrOff) {
autoSwapBufferMode = onOrOff;
}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/GLPbufferImpl.java b/src/jogl/classes/com/jogamp/opengl/impl/GLPbufferImpl.java
index eb5e09d2f..071ac1378 100644
--- a/src/jogl/classes/com/jogamp/opengl/impl/GLPbufferImpl.java
+++ b/src/jogl/classes/com/jogamp/opengl/impl/GLPbufferImpl.java
@@ -130,10 +130,18 @@ public class GLPbufferImpl implements GLPbuffer {
drawableHelper.addGLEventListener(listener);
}
+ public void addGLEventListener(int index, GLEventListener listener) {
+ drawableHelper.addGLEventListener(index, listener);
+ }
+
public void removeGLEventListener(GLEventListener listener) {
drawableHelper.removeGLEventListener(listener);
}
+ public void invoke(boolean wait, GLRunnable glRunnable) {
+ drawableHelper.invoke(wait, glRunnable);
+ }
+
public void setContext(GLContext ctx) {
context=(GLContextImpl)ctx;
}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/GLRunnableTask.java b/src/jogl/classes/com/jogamp/opengl/impl/GLRunnableTask.java
new file mode 100644
index 000000000..a6a030c6b
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/GLRunnableTask.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2010, Sven Gothel
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions 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 Sven Gothel nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Sven Gothel BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.jogamp.opengl.impl;
+
+import javax.media.opengl.GLRunnable;
+import javax.media.opengl.GLAutoDrawable;
+
+/**
+ * Helper class to provide a Runnable queue implementation with a Runnable wrapper
+ * which notifies after execution for the invokeAndWait()
semantics.
+ */
+public class GLRunnableTask implements GLRunnable {
+ GLRunnable runnable;
+ Object notifyObject;
+
+ Throwable runnableException;
+
+ public GLRunnableTask(GLRunnable runnable, Object notifyObject) {
+ this.runnable = runnable ;
+ this.notifyObject = notifyObject ;
+ }
+
+ public void run(GLAutoDrawable drawable) {
+ try {
+ runnable.run(drawable);
+ } catch (Throwable t) {
+ runnableException = t;
+ }
+ if(null != notifyObject) {
+ synchronized (notifyObject) {
+ notifyObject.notifyAll();
+ }
+ }
+ }
+
+ public Throwable getThrowable() { return runnableException; }
+}
+
diff --git a/src/jogl/classes/javax/media/opengl/GLAutoDrawable.java b/src/jogl/classes/javax/media/opengl/GLAutoDrawable.java
index 7342369d9..7236aa533 100644
--- a/src/jogl/classes/javax/media/opengl/GLAutoDrawable.java
+++ b/src/jogl/classes/javax/media/opengl/GLAutoDrawable.java
@@ -138,11 +138,22 @@ public interface GLAutoDrawable extends GLDrawable {
*/
public void setContext(GLContext context);
- /** Adds a {@link GLEventListener} to this drawable. If multiple
- listeners are added to a given drawable, they are notified of
- events in an arbitrary order. */
+ /** Adds a {@link GLEventListener} to the end of this drawable queue.
+ The listeners are notified of events in the order of the queue. */
public void addGLEventListener(GLEventListener listener);
+ /**
+ * Adds a {@link GLEventListener} at the given index of this drawable queue.
+ * The listeners are notified of events in the order of the queue.
+ * @param index Position where the listener will be inserted.
+ * Should be within (0 <= index && index <= size()).
+ * An index value of -1 is interpreted as the end of the list, size().
+ * @param listener The GLEventListener object to be inserted
+ * @throws IndexOutOfBoundsException If the index is not within (0 <= index && index <= size()), or -1
+ */
+ public void addGLEventListener(int index, GLEventListener listener)
+ throws IndexOutOfBoundsException;
+
/** Removes a {@link GLEventListener} from this drawable. Note that
if this is done from within a particular drawable's {@link
GLEventListener} handler (reshape, display, etc.) that it is not
@@ -150,6 +161,19 @@ public interface GLAutoDrawable extends GLDrawable {
during this update cycle. */
public void removeGLEventListener(GLEventListener listener);
+ /**
+ * Enqueues the one-shot {@link javax.media.opengl.GLRunnable} into the queue,
+ * which will be executed at the next {@link #display()} call.
+ *
+ * Warning: We cannot verify if the caller runs in the same thread
+ * as the display caller, hence we cannot avoid a deadlock
+ * in such case. You have to know what you are doing,
+ * ie call this only in a I/O event listener, or such.
+ * @see #display()
+ * @see javax.media.opengl.GLRunnable
+ */
+ public void invoke(boolean wait, GLRunnable glRunnable);
+
/** FIXME: Returns the current state,
{@link #STATE_INVALID}, {@link #STATE_VALID} or {@link #STATE_DESTROYING}.
Tool to determine, e.g. if a {@link GLEventListener#dispose dispose(..)}
@@ -166,19 +190,28 @@ public interface GLAutoDrawable extends GLDrawable {
routine may be called manually. */
public void destroy();
- /** Causes OpenGL rendering to be performed for this GLAutoDrawable
- by calling {@link GLEventListener#display display(..)} for all
- registered {@link GLEventListener}s. Called automatically by the
- window system toolkit upon receiving a repaint() request. this
- routine may be called manually for better control over the
+ /** Causes OpenGL rendering to be performed for this GLAutoDrawable
+ in the following order:
+
+ - Calling {@link GLEventListener#display display(..)} for all
+ registered {@link GLEventListener}s.
+ - Execute and dismiss all one-shot {@link javax.media.opengl.GLRunnable},
+ enqueued via {@link #invoke(boolean, GLRunnable)}.
+
+
+ Called automatically by the
+ window system toolkit upon receiving a repaint() request.
+
+ This routine may be called manually for better control over the
rendering process. It is legal to call another GLAutoDrawable's
display method from within the {@link GLEventListener#display
- display(..)} callback.
+ display(..)} callback.
+
In case of a new generated OpenGL context,
the implementation shall call {@link GLEventListener#init init(..)} for all
registered {@link GLEventListener}s before making the
actual {@link GLEventListener#display display(..)} calls,
- in case this has not been done yet.*/
+ in case this has not been done yet.
*/
public void display();
/** Enables or disables automatic buffer swapping for this drawable.
@@ -211,4 +244,5 @@ public interface GLAutoDrawable extends GLDrawable {
demos for examples.
@return the set GL pipeline or null if not successful */
public GL setGL(GL gl);
+
}
diff --git a/src/jogl/classes/javax/media/opengl/GLRunnable.java b/src/jogl/classes/javax/media/opengl/GLRunnable.java
new file mode 100644
index 000000000..8d619273f
--- /dev/null
+++ b/src/jogl/classes/javax/media/opengl/GLRunnable.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2010, Sven Gothel
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions 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 Sven Gothel nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Sven Gothel BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package javax.media.opengl;
+
+/** Declares one-shot OpenGL commands, which client code can use to manage OpenGL
+ commands into a {@link GLAutoDrawable}. At the time any of these
+ methods is called, the drawable has made its associated OpenGL
+ context current, so it is valid to make OpenGL calls.
+ A GLRunnable maybe used to inject OpenGL commands via I/O event listener,
+ via {@link GLAutoDrawable#invoke(boolean, GLRunnable)}.
+ */
+public interface GLRunnable {
+ /** Called by the drawable to initiate one-shot OpenGL commands by the
+ client, like {@link GLEventListener#display(GLAutoDrawable)}. */
+ public void run(GLAutoDrawable drawable);
+}
+
diff --git a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java
index 77b8e45d3..2dafd691a 100644
--- a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java
+++ b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java
@@ -484,10 +484,18 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable {
drawableHelper.addGLEventListener(listener);
}
+ public void addGLEventListener(int index, GLEventListener listener) {
+ drawableHelper.addGLEventListener(index, listener);
+ }
+
public void removeGLEventListener(GLEventListener listener) {
drawableHelper.removeGLEventListener(listener);
}
+ public void invoke(boolean wait, GLRunnable glRunnable) {
+ drawableHelper.invoke(wait, glRunnable);
+ }
+
public void setContext(GLContext ctx) {
context=(GLContextImpl)ctx;
}
diff --git a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java
index 955949415..73962e979 100644
--- a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java
+++ b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java
@@ -372,10 +372,18 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable {
drawableHelper.addGLEventListener(listener);
}
+ public void addGLEventListener(int index, GLEventListener listener) {
+ drawableHelper.addGLEventListener(index, listener);
+ }
+
public void removeGLEventListener(GLEventListener listener) {
drawableHelper.removeGLEventListener(listener);
}
+ public void invoke(boolean wait, GLRunnable glRunnable) {
+ drawableHelper.invoke(wait, glRunnable);
+ }
+
public GLContext createContext(GLContext shareWith) {
return backend.createContext(shareWith);
}
diff --git a/src/junit/com/jogamp/test/junit/newt/GLRunnableDummy.java b/src/junit/com/jogamp/test/junit/newt/GLRunnableDummy.java
new file mode 100644
index 000000000..990a0c37d
--- /dev/null
+++ b/src/junit/com/jogamp/test/junit/newt/GLRunnableDummy.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2010 Sven Gothel. 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 Sven Gothel 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
+ * SVEN GOTHEL HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ */
+
+package com.jogamp.test.junit.newt;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.AfterClass;
+import org.junit.Test;
+
+import javax.media.opengl.*;
+
+public class GLRunnableDummy implements GLRunnable {
+ float r=0.0f;
+ float g=0.0f;
+ float b=0.0f;
+ float d=0.001f;
+
+ public void run(GLAutoDrawable drawable) {
+ // nop ..
+ GL2ES1 gl = drawable.getGL().getGL2ES1();
+ gl.glClearColor(r, g, b, 1f);
+ r+=d;
+ if(r>1f) {
+ r=1f;
+ d*=-1f;
+ } else if(r<0f) {
+ r=0f;
+ d*=-1f;
+ }
+ }
+
+}
diff --git a/src/junit/com/jogamp/test/junit/newt/TestListenerCom01AWT.java b/src/junit/com/jogamp/test/junit/newt/TestListenerCom01AWT.java
index b661d02f3..495b8bb3e 100755
--- a/src/junit/com/jogamp/test/junit/newt/TestListenerCom01AWT.java
+++ b/src/junit/com/jogamp/test/junit/newt/TestListenerCom01AWT.java
@@ -142,7 +142,7 @@ public class TestListenerCom01AWT {
static int atoi(String a) {
int i=0;
try {
- durationPerTest = Integer.parseInt(a);
+ i = Integer.parseInt(a);
} catch (Exception ex) { ex.printStackTrace(); }
return i;
}
diff --git a/src/junit/com/jogamp/test/junit/newt/TestParenting01AWT.java b/src/junit/com/jogamp/test/junit/newt/TestParenting01AWT.java
deleted file mode 100755
index 39659d763..000000000
--- a/src/junit/com/jogamp/test/junit/newt/TestParenting01AWT.java
+++ /dev/null
@@ -1,429 +0,0 @@
-/*
- * Copyright (c) 2010 Sven Gothel. 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 Sven Gothel 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
- * SVEN GOTHEL HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
- */
-
-package com.jogamp.test.junit.newt;
-
-import java.lang.reflect.*;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.After;
-import org.junit.AfterClass;
-import org.junit.Test;
-
-import java.awt.Button;
-import java.awt.BorderLayout;
-import java.awt.Canvas;
-import java.awt.Frame;
-import java.awt.Dimension;
-
-import javax.media.opengl.*;
-import javax.media.nativewindow.*;
-
-import com.jogamp.opengl.util.Animator;
-import com.jogamp.newt.*;
-import com.jogamp.newt.event.*;
-import com.jogamp.newt.opengl.*;
-import com.jogamp.newt.awt.NewtCanvasAWT;
-
-import java.io.IOException;
-
-import com.jogamp.test.junit.util.*;
-import com.jogamp.test.junit.jogl.demos.es1.RedSquare;
-import com.jogamp.test.junit.jogl.demos.gl2.gears.Gears;
-
-public class TestParenting01AWT {
- static int width, height;
- static long durationPerTest = 800;
- static long waitReparent = 0;
- static GLCapabilities glCaps;
-
- @BeforeClass
- public static void initClass() {
- width = 640;
- height = 480;
- glCaps = new GLCapabilities(null);
- }
-
- @Test
- public void testWindowParenting01CreateVisibleDestroy1() throws InterruptedException {
- int x = 0;
- int y = 0;
-
- NEWTEventFiFo eventFifo = new NEWTEventFiFo();
-
- GLWindow glWindow1 = GLWindow.create(glCaps);
- Assert.assertNotNull(glWindow1);
- Assert.assertEquals(false, glWindow1.isVisible());
- Assert.assertEquals(false, glWindow1.isNativeWindowValid());
- Assert.assertNull(glWindow1.getParentNativeWindow());
- glWindow1.setTitle("testWindowParenting01CreateVisibleDestroy");
- GLEventListener demo1 = new RedSquare();
- setDemoFields(demo1, glWindow1, false);
- glWindow1.addGLEventListener(demo1);
-
- NewtCanvasAWT newtCanvasAWT = new NewtCanvasAWT(glWindow1);
- Assert.assertNotNull(newtCanvasAWT);
- Assert.assertEquals(false, glWindow1.isVisible());
- Assert.assertEquals(false, glWindow1.isNativeWindowValid());
- Assert.assertNull(glWindow1.getParentNativeWindow());
-
- Frame frame = new Frame("AWT Parent Frame");
- Assert.assertNotNull(frame);
- frame.add(newtCanvasAWT);
- frame.setSize(width, height);
-
- // visible test
- frame.setVisible(true);
- Assert.assertEquals(newtCanvasAWT.getNativeWindow(),glWindow1.getParentNativeWindow());
-
- Animator animator1 = new Animator(glWindow1);
- animator1.start();
- while(animator1.isAnimating() && animator1.getDuration()*/ events = new LinkedList();
- private boolean events2Wait = false;
protected void dispatchMessages() {
if(0==refCount) return; // we should not exist ..
if(!events.isEmpty()) {
- if(events2Wait) {
- synchronized(eventsLock) {
- while (!events.isEmpty()) {
- NEWTEvent e = (NEWTEvent) events.removeFirst();
- Object source = e.getSource();
- if(source instanceof Window) {
- ((Window)source).sendEvent(e);
- } else {
- throw new RuntimeException("Event source not a NEWT Window: "+source.getClass().getName()+", "+source);
- }
- }
- events2Wait = false; // clear
- eventsLock.notifyAll();
- }
- } else {
- // swap events list to free ASAP
- LinkedList/**/ _events = null;
- synchronized(eventsLock) {
- if(!events.isEmpty()) {
- _events = events;
- events = new LinkedList();
- }
- eventsLock.notifyAll();
+ // swap events list to free ASAP
+ LinkedList/**/ _events = null;
+ synchronized(eventsLock) {
+ if(!events.isEmpty()) {
+ _events = events;
+ events = new LinkedList();
}
- if( null != _events ) {
- while (!_events.isEmpty()) {
- NEWTEvent e = (NEWTEvent) _events.removeFirst();
- Object source = e.getSource();
- if(source instanceof Window) {
- ((Window)source).sendEvent(e);
- } else {
- throw new RuntimeException("Event source not a NEWT Window: "+source.getClass().getName()+", "+source);
- }
+ eventsLock.notifyAll();
+ }
+ if( null != _events ) {
+ for (Iterator iter = _events.iterator(); iter.hasNext(); ) {
+ NEWTEventTask eventTask = (NEWTEventTask) iter.next();
+ NEWTEvent event = eventTask.get();
+ Object source = event.getSource();
+ if(source instanceof Window) {
+ ((Window)source).sendEvent(event);
+ } else {
+ throw new RuntimeException("Event source not a NEWT Window: "+source.getClass().getName()+", "+source);
}
+ eventTask.notifyIssuer();
}
}
}
@@ -372,27 +358,21 @@ public abstract class Display {
}
public void enqueueEvent(boolean wait, NEWTEvent e) {
- synchronized(eventsLock) {
- if(DEBUG) {
- System.out.println("Display.enqueueEvent: START - wait "+wait+", "+e);
- }
- events2Wait = wait;
- events.addLast(e);
- }
- if(wait && !events.isEmpty()) {
+ Object lock = new Object();
+ NEWTEventTask eTask = new NEWTEventTask(e, wait?lock:null);
+ synchronized(lock) {
synchronized(eventsLock) {
- while(!events.isEmpty()) {
- try {
- eventsLock.wait();
- } catch (InterruptedException ie) {
- ie.printStackTrace();
- }
+ events.addLast(eTask);
+ eventsLock.notifyAll();
+ }
+ if( wait ) {
+ try {
+ lock.wait();
+ } catch (InterruptedException ie) {
+ throw new RuntimeException(ie);
}
}
}
- if(DEBUG) {
- System.out.println("Display.enqueueEvent: END - wait "+wait+", "+e);
- }
}
public void lock() {
diff --git a/src/newt/classes/com/jogamp/newt/Window.java b/src/newt/classes/com/jogamp/newt/Window.java
index 045a5eb72..e9289f5dc 100755
--- a/src/newt/classes/com/jogamp/newt/Window.java
+++ b/src/newt/classes/com/jogamp/newt/Window.java
@@ -707,9 +707,9 @@ public abstract class Window implements NativeWindow
public void reparentWindow(NativeWindow newParent, Screen newScreen) {
if(!isDestroyed()) {
runOnEDTIfAvail(true, new ReparentAction(newParent, newScreen));
- if( isVisible() ) {
- enqueueWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); // trigger a resize/relayout to listener
- }
+ // if( isVisible() ) {
+ enqueueWindowEvent(true, WindowEvent.EVENT_WINDOW_RESIZED); // trigger a resize/relayout to listener
+ // }
}
}
@@ -1321,8 +1321,12 @@ public abstract class Window implements NativeWindow
// WindowListener/Event Support
//
protected void enqueueWindowEvent(int eventType) {
+ enqueueWindowEvent(false, eventType);
+ }
+
+ protected void enqueueWindowEvent(boolean wait, int eventType) {
WindowEvent event = new WindowEvent(eventType, this, System.currentTimeMillis());
- screen.getDisplay().enqueueEvent( event );
+ screen.getDisplay().enqueueEvent( wait, event );
// sendWindowEvent ( event ); // FIXME: Think about performance/lag .. ?
}
diff --git a/src/newt/classes/com/jogamp/newt/impl/event/NEWTEventTask.java b/src/newt/classes/com/jogamp/newt/impl/event/NEWTEventTask.java
new file mode 100644
index 000000000..479c493b0
--- /dev/null
+++ b/src/newt/classes/com/jogamp/newt/impl/event/NEWTEventTask.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2010, Sven Gothel
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions 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 Sven Gothel nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Sven Gothel BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.jogamp.newt.impl.event;
+
+import com.jogamp.newt.event.NEWTEvent;
+
+/**
+ * Helper class to provide a NEWTEvent queue implementation with a NEWTEvent wrapper
+ * which notifies after sending the event for the invokeAndWait()
semantics.
+ */
+public class NEWTEventTask {
+ NEWTEvent event;
+ Object notifyObject;
+
+ public NEWTEventTask(NEWTEvent event, Object notifyObject) {
+ this.event = event ;
+ this.notifyObject = notifyObject ;
+ }
+
+ public NEWTEvent get() { return event; }
+
+ public void notifyIssuer() {
+ if(null != notifyObject) {
+ synchronized (notifyObject) {
+ notifyObject.notifyAll();
+ }
+ }
+ }
+}
+
diff --git a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java
index 1807201a4..0e93fc0bd 100644
--- a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java
+++ b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java
@@ -487,6 +487,10 @@ public class GLWindow extends Window implements GLAutoDrawable {
helper.removeGLEventListener(listener);
}
+ public void invoke(boolean wait, GLRunnable glRunnable) {
+ helper.invoke(wait, glRunnable);
+ }
+
public void display() {
display(false);
}
diff --git a/src/newt/classes/com/jogamp/newt/util/EDTUtil.java b/src/newt/classes/com/jogamp/newt/util/EDTUtil.java
index 235132460..2e339fd45 100644
--- a/src/newt/classes/com/jogamp/newt/util/EDTUtil.java
+++ b/src/newt/classes/com/jogamp/newt/util/EDTUtil.java
@@ -36,6 +36,7 @@
package com.jogamp.newt.util;
+import com.jogamp.common.util.RunnableTask;
import com.jogamp.newt.Display;
import com.jogamp.newt.impl.Debug;
import java.util.*;
@@ -107,10 +108,7 @@ public class EDTUtil {
return null!=edt && edt.isRunning() ;
}
- public void invokeLater(Runnable task) {
- if(task == null) {
- return;
- }
+ private void invokeLater(Runnable task) {
synchronized(edtLock) {
if(null!=edt && edt.isRunning() && edt != Thread.currentThread() ) {
tasks.add(task);
@@ -122,21 +120,33 @@ public class EDTUtil {
}
}
- public void invokeAndWait(Runnable task) {
- invoke(true, task);
- }
-
public void invoke(boolean wait, Runnable task) {
if(task == null) {
return;
}
- invokeLater(task);
- if(wait) {
- waitOnWorker();
+ boolean doWait = wait && null!=edt && edt.isRunning() && edt != Thread.currentThread();
+ Object lock = new Object();
+ RunnableTask rTask = new RunnableTask(task, doWait?lock:null, true);
+ Throwable throwable = null;
+ synchronized(lock) {
+ invokeLater(rTask);
+ if( doWait ) {
+ try {
+ lock.wait();
+ } catch (InterruptedException ie) {
+ throwable = ie;
+ }
+ }
+ }
+ if(null==throwable) {
+ throwable = rTask.getThrowable();
+ }
+ if(null!=throwable) {
+ throw new RuntimeException(throwable);
}
}
- public void waitOnWorker() {
+ public void waitUntilIdle() {
synchronized(edtLock) {
if(null!=edt && edt.isRunning() && tasks.size()>0 && edt != Thread.currentThread() ) {
try {
--
cgit v1.2.3