summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xmake/gluegen-cpptasks-base.xml69
-rwxr-xr-xmake/jogamp-env.xml65
-rwxr-xr-xmake/scripts/make.gluegen.all.macosx-java7.sh2
-rw-r--r--make/stub_includes/jni/macosx/jawt_md.h68
-rw-r--r--make/stub_includes/jni/macosx/jni_md.h47
-rw-r--r--src/java/com/jogamp/common/util/Function.java49
-rw-r--r--src/java/com/jogamp/common/util/FunctionTask.java164
-rw-r--r--src/java/com/jogamp/common/util/RunnableTask.java155
-rw-r--r--src/java/com/jogamp/common/util/TaskBase.java137
9 files changed, 600 insertions, 156 deletions
diff --git a/make/gluegen-cpptasks-base.xml b/make/gluegen-cpptasks-base.xml
index 723c7c2..fcb382a 100755
--- a/make/gluegen-cpptasks-base.xml
+++ b/make/gluegen-cpptasks-base.xml
@@ -6,11 +6,14 @@
- by other projects which use GlueGen to generate native code and
- need to compile that native code.
-
- - Before importing this file, the property "gluegen.root" must be
- - defined; this is the relative path from the current working
+ - Before importing this file, the properties "gluegen.root" must be defined;
+ - this is the relative path from the current working
- directory (e.g., from which the parent project's build.xml is being
- executed) to the top of the checked-out GlueGen workspace.
-
+ - The property "gluegen.root.abs-path" must be defined as well;
+ - this is the absolute path of "gluegen.root", see above.
+ -
- The gluegen.cpptasks.detect.os target sets the following
- properties appropriately. They are only set to "true" if the OS/CPU
- configuration is exactly as specified.
@@ -184,8 +187,16 @@
<!-- NOTE: the values of the macos<arch> attributes will not be overridden if already set externally -->
<property name="macosppc" value="false" />
- <property name="macosx32" value="true" />
<property name="macosx64" value="true" />
+ <!-- No 32bit binaries on OSX since Java7 -->
+ <condition property="macosx32" value="false" else="true">
+ <or>
+ <contains string="${ant.java.version}" substring="1.7" casesensitive="false" />
+ <contains string="${ant.java.version}" substring="1.8" casesensitive="false" />
+ <contains string="${ant.java.version}" substring="1.9" casesensitive="false" />
+ <contains string="${ant.java.version}" substring="2.0" casesensitive="false" />
+ </or>
+ </condition>
<!-- Need a way to be able to disable the macosx64 property specification in a build.xml -->
<condition property="use.macosppc">
@@ -841,16 +852,29 @@
<!--
- Set up java.home.dir appropriately on all platforms.
-->
- <target name="setup.java.home.dir.nonmacosx" unless="isOSX">
+ <target name="setup.java.home.dir.nonmacosx" unless="isOSX">
<!-- java home dir is up one directory as java.home points to '<java-install-dir>/jre' -->
<property name="java.home.dir" value="${java.home}/.." />
- </target>
- <target name="setup.java.home.dir.macosx" if="isOSX">
+ <property name="java.includes.dir" value="${java.home.dir}/include" />
+ </target>
+ <target name="setup.java.home.dir.macosx" if="isOSX">
+ <!-- Java7 std location -->
+ <condition property="java.home.dir"
+ value="${java.home}/..">
+ <available file="${java.home}/../include/jni.h"/>
+ </condition>
+ <condition property="java.includes.dir"
+ value="${java.home}/../include">
+ <available file="${java.home}/../include/jni.h"/>
+ </condition>
+ <!-- Fallback value Java6 -->
<property name="java.home.dir" value="/System/Library/Frameworks/JavaVM.framework/Home" />
- </target>
- <target name="setup.java.home.dir" depends="setup.java.home.dir.nonmacosx,setup.java.home.dir.macosx">
- <property name="java.includes.dir" value="${java.home.dir}/include" />
- </target>
+ <property name="java.includes.dir" value="/System/Library/Frameworks/JavaVM.framework/Headers" />
+ </target>
+ <target name="setup.java.home.dir" depends="setup.java.home.dir.nonmacosx,setup.java.home.dir.macosx">
+ <echo message="java.home.dir ${java.home.dir}" />
+ <echo message="java.includes.dir ${java.includes.dir}" />
+ </target>
<target name="gluegen.cpptasks.configure.compiler" depends="setup.java.home.dir">
@@ -1414,18 +1438,25 @@
<echo message="MacOSX" />
<property name="compiler.cfg.id.base" value="compiler.cfg.macosx" />
<property name="linker.cfg.id.base" value="linker.cfg.macosx" />
- <!-- Need to select either Java 10.6 Update 4's location or the old one -->
+ <!-- Java7 std location -->
+ <!-- Temporary workaround:
+ Provided darwin/jawt_md.h from Oracle for OSX / Java7
+ has X11 dependencies and does not define JAWT_SurfaceLayers.
+ value="${java.includes.dir}/darwin">
+ -->
<condition property="java.includes.dir.platform"
- value="/System/Library/Frameworks/JavaVM.framework/Headers"
- else="/System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Headers">
- <available file="/System/Library/Frameworks/JavaVM.framework/Headers/jni.h"/>
+ value="${gluegen.root.abs-path}/make/stub_includes/jni/macosx">
+ <available file="${java.includes.dir}/darwin/jawt_md.h"/>
</condition>
- <condition property="java.osx.frameworks.dir"
- value="/System/Library/Frameworks/JavaVM.framework/Frameworks"
- else="/OSX/JavaVM.framework/Frameworks/does/not/exist">
- <available file="/System/Library/Frameworks/JavaVM.framework/Frameworks/JavaNativeFoundation.framework/Headers/JavaNativeFoundation.h"/>
+ <condition property="java.lib.dir.platform"
+ value="${java.home.dir}/jre/lib">
+ <available file="${java.home.dir}/jre/lib/libjawt.dylib"/>
</condition>
- <property name="java.lib.dir.platform" value="/System/Library/Frameworks/JavaVM.framework/Libraries" />
+ <!-- Fallback value Java6 -->
+ <property name="java.includes.dir.platform" value="/System/Library/Frameworks/JavaVM.framework/Headers" />
+ <property name="java.lib.dir.platform" value="/System/Library/Frameworks/JavaVM.framework/Libraries" />
+ <echo message="java.includes.dir.platform ${java.includes.dir.platform}" />
+ <echo message="java.lib.dir.platform ${java.lib.dir.platform}" />
</target>
<target name="gluegen.cpptasks.declare.compiler.freebsd.x86" if="isFreeBSDX86">
diff --git a/make/jogamp-env.xml b/make/jogamp-env.xml
index 07083c7..77421f5 100755
--- a/make/jogamp-env.xml
+++ b/make/jogamp-env.xml
@@ -27,6 +27,16 @@
<echo message="java.version ${java.version}"/>
<echo message="java.home ${java.home}"/>
+ <property name="jvmJava.exe" value="${java.home}/bin/java" /> <!-- the java jvm executable for unit tests -->
+ <echo message="jvmJava.exe ${jvmJava.exe}"/>
+
+ <condition property="jvmJava7.exe" value="${env.JAVA7_EXE}">
+ <not>
+ <equals arg1="${env.JAVA7_EXE}" arg2="$${env.JAVA7_EXE}" casesensitive="true" />
+ </not>
+ </condition>
+ <echo message="jvmJava7.exe ${jvmJava7.exe}"/> <!-- optional extra Java7 JVM for unit tests -->
+
<fail message="Please build using Ant 1.8.0 or higher.">
<condition>
<not>
@@ -42,6 +52,8 @@
<contains string="${ant.java.version}" substring="1.6" casesensitive="false" />
<contains string="${ant.java.version}" substring="1.7" casesensitive="false" />
<contains string="${ant.java.version}" substring="1.8" casesensitive="false" />
+ <contains string="${ant.java.version}" substring="1.9" casesensitive="false" />
+ <contains string="${ant.java.version}" substring="2.0" casesensitive="false" />
</or>
</not>
</condition>
@@ -52,10 +64,9 @@
<target name="jogamp.env.init" depends="jogamp.env.validation">
<property environment="env" />
+ <!-- only set 'junit.is.disabled' if set in environment as 'true' to disable JUNIT tests -->
<condition property="junit.is.disabled" value="${env.JUNIT_DISABLED}">
- <not>
- <equals arg1="${env.JUNIT_DISABLED}" arg2="$${env.JUNIT_DISABLED}" casesensitive="true" />
- </not>
+ <istrue value="${env.JUNIT_DISABLED}"/>
</condition>
<echo message="junit.is.disabled ${junit.is.disabled}"/>
@@ -72,7 +83,7 @@
</condition>
<property name="junit.run.arg1" value="-Djunit.run.arg1=dummy" /> <!-- default dummy values -->
- <!-- only set 'build.archiveon' if set in environment to trigger archive creation -->
+ <!-- only set 'build.archiveon' if set in environment as 'true' to trigger archive creation -->
<condition property="build.archiveon" value="${env.BUILD_ARCHIVE}">
<istrue value="${env.BUILD_ARCHIVE}"/>
</condition>
@@ -136,30 +147,51 @@
<property name="target.sourcelevel" value="${ant.java.version}" /> <!-- default fallback values -->
<property name="target.targetlevel" value="${ant.java.version}" /> <!-- default fallback values -->
+ <!-- default value for std Java -->
+ <condition property="target.rt.jar"
+ value="${java.home}/lib/rt.jar">
+ <available file="${java.home}/lib/rt.jar"/>
+ </condition>
<!-- default fallback value on OS X -->
- <available property="target.rt.jar"
- type="file"
- file="/System/Library/Frameworks/JavaVM.framework/Versions/${ant.java.version}/Classes/classes.jar"
- value="/System/Library/Frameworks/JavaVM.framework/Versions/${ant.java.version}/Classes/classes.jar"/>
+ <condition property="target.rt.jar"
+ value="/System/Library/Frameworks/JavaVM.framework/Versions/${ant.java.version}/Classes/classes.jar">
+ <available file="/System/Library/Frameworks/JavaVM.framework/Versions/${ant.java.version}/Classes/classes.jar"/>
+ </condition>
<!-- default fallback value on std Java -->
- <property name="target.rt.jar" value="${java.home}/lib/rt.jar" />
<echo message="target.user.set ${target.user.set}"/>
<echo message="target.sourcelevel ${target.sourcelevel}"/>
<echo message="target.targetlevel ${target.targetlevel}"/>
<echo message="target.rt.jar ${target.rt.jar}"/>
+ <fail message="No target.rt.jar specified not found.">
+ <condition>
+ <not>
+ <isset property="target.rt.jar"/>
+ </not>
+ </condition>
+ </fail>
<property name="host.sourcelevel" value="${ant.java.version}" /> <!-- default values for compile time components -->
<property name="host.targetlevel" value="${ant.java.version}" /> <!-- default values for compile time components -->
- <!-- default fallback value for compile time components on OS X -->
- <available property="host.rt.jar"
- type="file"
- file="/System/Library/Frameworks/JavaVM.framework/Versions/${ant.java.version}/Classes/classes.jar"
- value="/System/Library/Frameworks/JavaVM.framework/Versions/${ant.java.version}/Classes/classes.jar"/>
- <!-- default fallback value for compile time components on std Java -->
- <property name="host.rt.jar" value="${java.home}/lib/rt.jar" />
+ <!-- default value for std Java -->
+ <condition property="host.rt.jar"
+ value="${java.home}/lib/rt.jar">
+ <available file="${java.home}/lib/rt.jar"/>
+ </condition>
+ <!-- default fallback value on OS X -->
+ <condition property="host.rt.jar"
+ value="/System/Library/Frameworks/JavaVM.framework/Versions/${ant.java.version}/Classes/classes.jar">
+ <available file="/System/Library/Frameworks/JavaVM.framework/Versions/${ant.java.version}/Classes/classes.jar"/>
+ </condition>
<echo message="host.sourcelevel ${host.sourcelevel}"/>
<echo message="host.targetlevel ${host.targetlevel}"/>
<echo message="host.rt.jar ${host.rt.jar}"/>
+ <fail message="No host.rt.jar specified not found.">
+ <condition>
+ <not>
+ <isset property="host.rt.jar"/>
+ </not>
+ </condition>
+ </fail>
<fail message="Unsupported Target Java version (sourcelevel): ${target.sourcelevel}. Make sure that the version of the Java compiler is 1.6 (6.0) or greater.">
<condition>
@@ -201,6 +233,7 @@
<echo message="junit.run.arg0 ${junit.run.arg0}"/>
<echo message="junit.run.arg1 ${junit.run.arg1}"/>
+
</target>
</project>
diff --git a/make/scripts/make.gluegen.all.macosx-java7.sh b/make/scripts/make.gluegen.all.macosx-java7.sh
index 6ffefc4..1a69f9e 100755
--- a/make/scripts/make.gluegen.all.macosx-java7.sh
+++ b/make/scripts/make.gluegen.all.macosx-java7.sh
@@ -19,4 +19,4 @@ ant \
-Dtarget.targetlevel=1.6 \
-Dtarget.rt.jar=/opt-share/jre1.6.0_30/lib/rt.jar \
-Drootrel.build=build-macosx-java7 \
- $* 2>&1 | tee make.gluegen.all.macosx.log
+ $* 2>&1 | tee make.gluegen.all.macosx-java7.log
diff --git a/make/stub_includes/jni/macosx/jawt_md.h b/make/stub_includes/jni/macosx/jawt_md.h
new file mode 100644
index 0000000..e65474b
--- /dev/null
+++ b/make/stub_includes/jni/macosx/jawt_md.h
@@ -0,0 +1,68 @@
+/**
+ * Temporary workaround!
+ *
+ * Provided darwin/jawt_md.h from Oracle for OSX / Java7
+ * has X11 dependencies and does not define JAWT_SurfaceLayers.
+ *
+ * This C header file is derived from Apple's Java SDK provided C header file
+ * with the following copyright notice:
+ *
+ * Copyright (c) 2002 Apple computer Inc. All rights reserved.
+ *
+ * This version has complex comments removed and does not contain inlined algorithms etc, if any existed.
+ *
+ * The original C header file was included to JOGL on Mon Jun 15 22:57:38 2009
+ * (commit cbc45e816f4ee81031bffce19a99550681462a24) by Sun Microsystem's staff and were approved.
+ *
+ * This C header file is included due to ensure compatibility with - and invocation of the JAWT protocol.
+ * They are processed by GlueGen to create a Java binding for JAWT invocation only.
+ *
+ * http://ftp.resource.org/courts.gov/c/F3/387/387.F3d.522.03-5400.html (36)
+ * "Atari Games Corp. v. Nintendo of Am., Inc., Nos. 88-4805 & 89-0027, 1993 WL 207548, at *1 (N.D.Cal. May 18, 1993) ("Atari III")
+ * ("Program code that is strictly necessary to achieve current compatibility presents a merger problem, almost by definition,
+ * and is thus excluded from the scope of any copyright.")."
+ *
+ * http://eur-lex.europa.eu/LexUriServ/LexUriServ.do?uri=OJ:L:2009:111:0016:0022:EN:PDF
+ * L 111/17 (10) and (15)
+ */
+
+#ifndef _JAVASOFT_JAWT_MD_H_
+#define _JAVASOFT_JAWT_MD_H_
+
+#include <jawt.h>
+#include <AppKit/NSView.h>
+#include <QuartzCore/CALayer.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * JAWT_DrawingSurfaceInfo.getPlatformInfo()
+ *
+ * Only if not JAWT_SurfaceLayers, see below!
+ */
+typedef struct JAWT_MacOSXDrawingSurfaceInfo
+{
+ /** the view is guaranteed to be valid only for the duration of Component.paint method */
+ NSView *cocoaViewRef;
+}
+JAWT_MacOSXDrawingSurfaceInfo;
+
+#ifndef __GLUEGEN__
+
+ #define JAWT_MACOSX_USE_CALAYER 0x80000000
+
+ /** Java7 and Java6 (OSX >= 10.6.4) CALayer surface if provided (Bit JAWT_MACOSX_USE_CALAYER set in the JAWT version) */
+ @protocol JAWT_SurfaceLayers
+ @property (readwrite, retain) CALayer *layer;
+ @property (readonly) CALayer *windowLayer;
+ @end
+
+#endif __GLUEGEN__
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !_JAVASOFT_JAWT_MD_H_ */
diff --git a/make/stub_includes/jni/macosx/jni_md.h b/make/stub_includes/jni/macosx/jni_md.h
new file mode 100644
index 0000000..7f52704
--- /dev/null
+++ b/make/stub_includes/jni/macosx/jni_md.h
@@ -0,0 +1,47 @@
+/*
+ * Temporary workaround!
+ *
+ * Provided darwin/jawt_md.h from Oracle for OSX / Java7
+ * has X11 dependencies and does not define JAWT_SurfaceLayers.
+ *
+ * @(#)jni_md.h 1.18 03/12/19
+ *
+ * This C header file is derived from Sun Microsystem's Java SDK provided C header file
+ * with the following copyright notice:
+ *
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
+ *
+ * This version has complex comments removed and does not contain inlined algorithms etc, if any existed.
+ *
+ * The original C header file was included to JOGL on Sat Jun 21 02:10:30 2008
+ * (commit cbc45e816f4ee81031bffce19a99550681462a24) by Sun Microsystem's staff and were approved.
+ *
+ * This C header file is included due to ensure compatibility with - and invocation of the JAWT protocol.
+ * They are processed by GlueGen to create a Java binding for JAWT invocation only.
+ *
+ * http://ftp.resource.org/courts.gov/c/F3/387/387.F3d.522.03-5400.html (36)
+ * "Atari Games Corp. v. Nintendo of Am., Inc., Nos. 88-4805 & 89-0027, 1993 WL 207548, at *1 (N.D.Cal. May 18, 1993) ("Atari III")
+ * ("Program code that is strictly necessary to achieve current compatibility presents a merger problem, almost by definition,
+ * and is thus excluded from the scope of any copyright.")."
+ *
+ * http://eur-lex.europa.eu/LexUriServ/LexUriServ.do?uri=OJ:L:2009:111:0016:0022:EN:PDF
+ * L 111/17 (10) and (15)
+ */
+
+#ifndef _JAVASOFT_JNI_MD_H_
+#define _JAVASOFT_JNI_MD_H_
+
+#define JNIEXPORT __attribute__((visibility("default")))
+#define JNIIMPORT
+#define JNICALL
+
+#if __LP64__
+typedef int jint;
+#else
+typedef long jint;
+#endif
+typedef long long jlong;
+typedef signed char jbyte;
+
+#endif /* !_JAVASOFT_JNI_MD_H_ */
diff --git a/src/java/com/jogamp/common/util/Function.java b/src/java/com/jogamp/common/util/Function.java
new file mode 100644
index 0000000..8bec99c
--- /dev/null
+++ b/src/java/com/jogamp/common/util/Function.java
@@ -0,0 +1,49 @@
+/**
+ * Copyright 2013 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``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 JogAmp Community OR
+ * CONTRIBUTORS 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.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+package com.jogamp.common.util;
+
+/**
+ * Generic function interface to perform an action w/ given optional arguments
+ * producing an optional result.
+ * <p>
+ * For <code>void</code> functions, simply use type <code>Object</code>
+ * and ignore the result and/or arguments.
+ * </p>
+ *
+ * @param <T> the result type of {@link #eval(Object...)}
+ */
+public interface Function<R,A> {
+ /**
+ * Implementation may compute variable <code>args</code> list
+ * and returns a result.
+ *
+ * @param args variable argument list, <code>A[]</code>, maybe null
+ * @return the result.
+ */
+ R eval(A... args);
+}
diff --git a/src/java/com/jogamp/common/util/FunctionTask.java b/src/java/com/jogamp/common/util/FunctionTask.java
new file mode 100644
index 0000000..35720a0
--- /dev/null
+++ b/src/java/com/jogamp/common/util/FunctionTask.java
@@ -0,0 +1,164 @@
+/**
+ * Copyright 2013 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``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 JogAmp Community OR
+ * CONTRIBUTORS 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.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+package com.jogamp.common.util;
+
+/**
+ * Helper class to provide a Runnable queue implementation with a Runnable wrapper
+ * which notifies after execution for the <code>invokeAndWait()</code> semantics.
+ */
+public class FunctionTask<R,A> extends TaskBase implements Function<R,A> {
+ protected Function<R,A> runnable;
+ protected R result;
+ protected A[] args;
+
+ /**
+ * Invokes <code>func</code>.
+ * @param waitUntilDone if <code>true</code>, waits until <code>func</code> execution is completed, otherwise returns immediately.
+ * @param func the {@link Function} to execute.
+ * @param args the {@link Function} arguments
+ * @return the {@link Function} return value
+ */
+ public static <U,V> U invoke(boolean waitUntilDone, Function<U,V> func, V... args) {
+ Throwable throwable = null;
+ final Object sync = new Object();
+ final FunctionTask<U,V> rt = new FunctionTask<U,V>( func, waitUntilDone ? sync : null, true );
+ final U res;
+ synchronized(sync) {
+ res = rt.eval(args);
+ if( waitUntilDone ) {
+ try {
+ sync.wait();
+ } catch (InterruptedException ie) {
+ throwable = ie;
+ }
+ if(null==throwable) {
+ throwable = rt.getThrowable();
+ }
+ if(null!=throwable) {
+ throw new RuntimeException(throwable);
+ }
+ }
+ }
+ return res;
+ }
+
+ /**
+ * Create a RunnableTask object w/ synchronization,
+ * ie. suitable for <code>invokeAndWait()</code>.
+ *
+ * @param runnable the user action
+ * @param syncObject the synchronization object the caller shall wait until <code>runnable</code> execution is completed,
+ * or <code>null</code> if waiting is not desired.
+ * @param catchExceptions if true, exception during <code>runnable</code> execution are catched, otherwise not.
+ * Use {@link #getThrowable()} to determine whether an exception has been catched.
+ */
+ public FunctionTask(Function<R,A> runnable, Object syncObject, boolean catchExceptions) {
+ super(syncObject, catchExceptions);
+ this.runnable = runnable ;
+ result = null;
+ args = null;
+ }
+
+ /** Return the user action */
+ public final Function<R,A> getRunnable() {
+ return runnable;
+ }
+
+ /**
+ * Sets the arguments for {@link #run()}.
+ * They will be cleared after calling {@link #run()} or {@link #eval(Object...)}.
+ */
+ public final void setArgs(A... args) {
+ this.args = args;
+ }
+
+ /**
+ * Retrieves the cached result of {@link #run()}
+ * and is cleared within this method.
+ */
+ public final R getResult() {
+ final R res = result;
+ result = null;
+ return res;
+ }
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * Calls {@link #eval(Object...)}.
+ * </p>
+ * <p>
+ * You may set the {@link #eval(Object...)} arguments via {@link #setArgs(Object...)}
+ * and retrieve the result via {@link #getResult()}.
+ * </p>
+ */
+ @Override
+ public final void run() {
+ final A[] args = this.args;
+ this.args = null;
+ this.result = null;
+ tStarted = System.currentTimeMillis();
+ if(null == syncObject) {
+ try {
+ this.result = runnable.eval(args);
+ } catch (Throwable t) {
+ runnableException = t;
+ if(!catchExceptions) {
+ throw new RuntimeException(runnableException);
+ }
+ } finally {
+ tExecuted = System.currentTimeMillis();
+ }
+ } else {
+ synchronized (syncObject) {
+ try {
+ this.result = runnable.eval(args);
+ } catch (Throwable t) {
+ runnableException = t;
+ if(!catchExceptions) {
+ throw new RuntimeException(runnableException);
+ }
+ } finally {
+ tExecuted = System.currentTimeMillis();
+ syncObject.notifyAll();
+ }
+ }
+ }
+ }
+
+ @Override
+ public final R eval(A... args) {
+ this.args = args;
+ run();
+ final R res = result;
+ result = null;
+ return res;
+ }
+}
+
diff --git a/src/java/com/jogamp/common/util/RunnableTask.java b/src/java/com/jogamp/common/util/RunnableTask.java
index b0ce159..5d9441a 100644
--- a/src/java/com/jogamp/common/util/RunnableTask.java
+++ b/src/java/com/jogamp/common/util/RunnableTask.java
@@ -32,87 +32,58 @@ package com.jogamp.common.util;
* Helper class to provide a Runnable queue implementation with a Runnable wrapper
* which notifies after execution for the <code>invokeAndWait()</code> semantics.
*/
-public class RunnableTask implements Runnable {
- Runnable runnable;
- final Object syncObject;
- boolean catchExceptions;
- Object attachment;
-
- Throwable runnableException;
- long tCreated, tStarted;
- volatile long tExecuted;
- volatile boolean isFlushed;
-
- /**
- * Create a RunnableTask object w/o synchronization,
- * ie. not suitable for <code>invokeAndWait()</code>.
- *
- * @param runnable the user action
- */
- public RunnableTask(Runnable runnable) {
- this(runnable, null, false);
- }
+public class RunnableTask extends TaskBase {
+ protected final Runnable runnable;
/**
- * Create a RunnableTask object w/ synchronization,
- * ie. suitable for <code>invokeAndWait()</code>.
- *
- * @param runnable the user action
- * @param syncObject the synchronization object the caller shall wait for in case of <code>invokeAndWait()</code>
+ * Invoks <code>runnable</code>.
+ * @param waitUntilDone if <code>true</code>, waits until <code>runnable</code> execution is completed, otherwise returns immediately.
+ * @param runnable the {@link Runnable} to execute.
*/
- public RunnableTask(Runnable runnable, Object syncObject) {
- this(runnable, syncObject, false);
+ public static void invoke(boolean waitUntilDone, Runnable runnable) {
+ Throwable throwable = null;
+ final Object sync = new Object();
+ final RunnableTask rt = new RunnableTask( runnable, waitUntilDone ? sync : null, true );
+ synchronized(sync) {
+ rt.run();
+ if( waitUntilDone ) {
+ try {
+ sync.wait();
+ } catch (InterruptedException ie) {
+ throwable = ie;
+ }
+ if(null==throwable) {
+ throwable = rt.getThrowable();
+ }
+ if(null!=throwable) {
+ throw new RuntimeException(throwable);
+ }
+ }
+ }
}
-
+
/**
* Create a RunnableTask object w/ synchronization,
- * ie. suitable for <code>invokeAndWait()</code>.
+ * ie. suitable for <code>invokeAndWait()</code>, i.e. {@link #invoke(boolean, Runnable) invoke(true, runnable)}.
*
* @param runnable the user action
- * @param syncObject the synchronization object the caller shall wait for in case of <code>invokeAndWai()t</code>
+ * @param syncObject the synchronization object if caller wait until <code>runnable</code> execution is completed,
+ * or <code>null</code> if waiting is not desired.
* @param catchExceptions if true, exception during <code>runnable</code> execution are catched, otherwise not.
* Use {@link #getThrowable()} to determine whether an exception has been catched.
*/
public RunnableTask(Runnable runnable, Object syncObject, boolean catchExceptions) {
+ super(syncObject, catchExceptions);
this.runnable = runnable ;
- this.syncObject = syncObject ;
- this.catchExceptions = catchExceptions ;
- tCreated = System.currentTimeMillis();
- tStarted = 0;
- tExecuted = 0;
- isFlushed = false;
}
/** Return the user action */
- public Runnable getRunnable() {
+ public final Runnable getRunnable() {
return runnable;
}
- /**
- * Return the synchronization object if any.
- * @see #RunnableTask(Runnable, Object, boolean)
- */
- public Object getSyncObject() {
- return syncObject;
- }
-
- /**
- * Attach a custom object to this task.
- * Useful to piggybag further information, ie tag a task final.
- */
- public void setAttachment(Object o) {
- attachment = o;
- }
-
- /**
- * Return the attachment object if any.
- * @see #setAttachment(Object)
- */
- public Object getAttachment() {
- return attachment;
- }
-
- public void run() {
+ @Override
+ public final void run() {
tStarted = System.currentTimeMillis();
if(null == syncObject) {
try {
@@ -139,63 +110,7 @@ public class RunnableTask implements Runnable {
syncObject.notifyAll();
}
}
- }
- }
-
- /**
- * Simply flush this task and notify a waiting executor.
- * The executor which might have been blocked until notified
- * will be unblocked and the task removed from the queue.
- *
- * @see #isFlushed()
- * @see #isInQueue()
- */
- public void flush() {
- if(!isExecuted() && hasWaiter()) {
- synchronized (syncObject) {
- isFlushed = true;
- syncObject.notifyAll();
- }
- }
- }
-
- /**
- * @return !{@link #isExecuted()} && !{@link #isFlushed()}
- */
- public boolean isInQueue() { return 0 != tExecuted && !isFlushed; }
-
- /**
- * @return True if executed, otherwise false;
- */
- public boolean isExecuted() { return 0 != tExecuted ; }
-
- /**
- * @return True if flushed, otherwise false;
- */
- public boolean isFlushed() { return isFlushed; }
-
- /**
- * @return True if invoking thread waits until done,
- * ie a <code>notifyObject</code> was passed, otherwise false;
- */
- public boolean hasWaiter() { return null != syncObject; }
-
- /**
- * @return A thrown exception while execution of the user action, if any and if catched
- * @see #RunnableTask(Runnable, Object, boolean)
- */
- public Throwable getThrowable() { return runnableException; }
-
- public long getTimestampCreate() { return tCreated; }
- public long getTimestampBeforeExec() { return tStarted; }
- public long getTimestampAfterExec() { return tExecuted; }
- public long getDurationInQueue() { return tStarted - tCreated; }
- public long getDurationInExec() { return tExecuted - tStarted; }
- public long getDurationTotal() { return tExecuted - tCreated; }
-
- @Override
- public String toString() {
- return "RunnableTask[executed "+isExecuted()+", t2-t0 "+getDurationTotal()+", t2-t1 "+getDurationInExec()+", t1-t0 "+getDurationInQueue()+", throwable "+getThrowable()+", Runnable "+runnable+", Attachment "+attachment+"]";
- }
+ }
+ }
}
diff --git a/src/java/com/jogamp/common/util/TaskBase.java b/src/java/com/jogamp/common/util/TaskBase.java
new file mode 100644
index 0000000..d2a924f
--- /dev/null
+++ b/src/java/com/jogamp/common/util/TaskBase.java
@@ -0,0 +1,137 @@
+/**
+ * Copyright 2010 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``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 JogAmp Community OR
+ * CONTRIBUTORS 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.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+package com.jogamp.common.util;
+
+/**
+ * Helper class to provide a Runnable queue implementation with a Runnable wrapper
+ * which notifies after execution for the <code>invokeAndWait()</code> semantics.
+ */
+public abstract class TaskBase implements Runnable {
+ protected final Object syncObject;
+ protected final boolean catchExceptions;
+
+ protected Object attachment;
+ protected Throwable runnableException;
+ protected long tCreated, tStarted;
+ protected volatile long tExecuted;
+ protected volatile boolean isFlushed;
+
+ protected TaskBase(Object syncObject, boolean catchExceptions) {
+ this.syncObject = syncObject ;
+ this.catchExceptions = catchExceptions ;
+ tCreated = System.currentTimeMillis();
+ tStarted = 0;
+ tExecuted = 0;
+ isFlushed = false;
+ }
+
+ /**
+ * Return the synchronization object if any.
+ * @see #RunnableTask(Runnable, Object, boolean)
+ */
+ public final Object getSyncObject() {
+ return syncObject;
+ }
+
+ /**
+ * Attach a custom object to this task.
+ * Useful to piggybag further information, ie tag a task final.
+ */
+ public final void setAttachment(Object o) {
+ attachment = o;
+ }
+
+ /**
+ * Return the attachment object if any.
+ * @see #setAttachment(Object)
+ */
+ public final Object getAttachment() {
+ return attachment;
+ }
+
+ @Override
+ public abstract void run();
+
+ /**
+ * Simply flush this task and notify a waiting executor.
+ * The executor which might have been blocked until notified
+ * will be unblocked and the task removed from the queue.
+ *
+ * @see #isFlushed()
+ * @see #isInQueue()
+ */
+ public final void flush() {
+ if(!isExecuted() && hasWaiter()) {
+ synchronized (syncObject) {
+ isFlushed = true;
+ syncObject.notifyAll();
+ }
+ }
+ }
+
+ /**
+ * @return !{@link #isExecuted()} && !{@link #isFlushed()}
+ */
+ public final boolean isInQueue() { return 0 != tExecuted && !isFlushed; }
+
+ /**
+ * @return True if executed, otherwise false;
+ */
+ public final boolean isExecuted() { return 0 != tExecuted ; }
+
+ /**
+ * @return True if flushed, otherwise false;
+ */
+ public final boolean isFlushed() { return isFlushed; }
+
+ /**
+ * @return True if invoking thread waits until done,
+ * ie a <code>notifyObject</code> was passed, otherwise false;
+ */
+ public final boolean hasWaiter() { return null != syncObject; }
+
+ /**
+ * @return A thrown exception while execution of the user action, if any and if catched
+ * @see #RunnableTask(Runnable, Object, boolean)
+ */
+ public final Throwable getThrowable() { return runnableException; }
+
+ public final long getTimestampCreate() { return tCreated; }
+ public final long getTimestampBeforeExec() { return tStarted; }
+ public final long getTimestampAfterExec() { return tExecuted; }
+ public final long getDurationInQueue() { return tStarted - tCreated; }
+ public final long getDurationInExec() { return tExecuted - tStarted; }
+ public final long getDurationTotal() { return tExecuted - tCreated; }
+
+ @Override
+ public String toString() {
+ return "RunnableTask[executed "+isExecuted()+", t2-t0 "+getDurationTotal()+", t2-t1 "+getDurationInExec()+", t1-t0 "+getDurationInQueue()+", throwable "+getThrowable()+", Attachment "+attachment+"]";
+ }
+}
+