diff options
author | Sven Gothel <[email protected]> | 2009-03-05 01:19:45 +0000 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2009-03-05 01:19:45 +0000 |
commit | 056229b0b7a962c36afca73a9925dc978f93e13c (patch) | |
tree | f81ef563afacb2ca199dcde19545c5ef88a89333 | |
parent | d88ec9ca9e797335a926202ebb0d3adbf7ea952e (diff) |
- Fixed rootrel.build usage, this works properly through gluegen, jogl-demos and this build.
You can say -Drootrel.build=build-x86_64 for example.
- Fixed jogl-demos in regard to this changeset
- Gluegen
- Fixed gluegen BuildComposablePipeline's 'getGL*' methods.
Now they return 'this', otherwise the pipeline would be broken/removed.
- Add BuildComposablePipeline CustomPipeline, which allows customized
class composition with an interface (to be wrapped),
prolog class and the downstream class.
- Add GlueGen (incl. ant task) 'outputRootDir' to be able to set a
top output root dir via ant / commandline.
- GL fixed function
- Package 'javax.media.opengl.sub.fixed.*' defines some fixed function interfaces.
This allows partitioning of custom implementation.
- Using gluegen's new CustomPipeline to compose a GLFixedFuncIf implementation,
using a GL downstream and a GLFixedFuncHookIf prolog.
The latter implements the fixed functionality.
Example is the GLFixedFuncImpl.
gl.getContext().setGL( new GLFixedFuncImpl(gl, new FixedFuncHook(gl.getGL2ES2())) ) ;
or
gl.getContext().setGL( new GLFixedFuncImpl(gl, gl.getGL2ES1()) ) ;
- The example GLFixedFuncHookIf impl FixedFuncPipeline/
can be instantiated with custom shader code.
- ES2 and all other interfaces only contain the original functionality,
besides minor convenient data access methods.
- Fix: GL2ES2 createCompileShader() and createLoadShader() is moved to ShaderCode util class.
- Updated PMVMatrix
- Add: GLAutoDrawable.setContext() .. and all it's implementations
Necessary to set a new GLContext.
- Add: GLContext getAttachedObject(int) and putAttachedObject(int, Object),
to allow the user to attach application specific and TLS sensitive objects to the GLContext.
-
git-svn-id: file:///usr/local/projects/SUN/JOGL/git-svn/../svn-server-sync/gluegen/branches/JOGL_2_SANDBOX@122 a78bb65f-1512-4460-ba86-f6dc96a7bf27
-rwxr-xr-x | make/build.xml | 38 | ||||
-rw-r--r-- | make/gluegen.compiler.xml | 3 | ||||
-rwxr-xr-x | make/gluegen.properties | 2 | ||||
-rw-r--r-- | src/java/com/sun/gluegen/GlueGen.java | 13 | ||||
-rw-r--r-- | src/java/com/sun/gluegen/JavaConfiguration.java | 12 | ||||
-rw-r--r-- | src/java/com/sun/gluegen/ant/GlueGenTask.java | 25 | ||||
-rw-r--r-- | src/java/com/sun/gluegen/opengl/BuildComposablePipeline.java | 586 | ||||
-rwxr-xr-x | src/java/com/sun/gluegen/opengl/GLConfiguration.java | 2 |
8 files changed, 564 insertions, 117 deletions
diff --git a/make/build.xml b/make/build.xml index da090e5..904b16c 100755 --- a/make/build.xml +++ b/make/build.xml @@ -29,6 +29,12 @@ <echo message="antlr.jar=${antlr.jar}" /> </target> + <condition property="rootrel.build" value="build"> + <not> + <isset property="rootrel.build"/> + </not> + </condition> + <target name="setup-excludes-1" if="gluegen.nsig"> <property name="gluegen.excludes" value="" /> </target> @@ -42,13 +48,13 @@ </target> <target name="setup.javase" unless="isCDCFP"> - <copy file="../src/java/com/sun/gluegen/runtime/BufferFactory.java.javase" tofile="../build/gensrc/java/com/sun/gluegen/runtime/BufferFactory.java" /> - <copy file="../src/java/com/sun/gluegen/runtime/StructAccessor.java.javase" tofile="../build/gensrc/java/com/sun/gluegen/runtime/StructAccessor.java" /> + <copy file="../src/java/com/sun/gluegen/runtime/BufferFactory.java.javase" tofile="../${rootrel.build}/gensrc/java/com/sun/gluegen/runtime/BufferFactory.java" /> + <copy file="../src/java/com/sun/gluegen/runtime/StructAccessor.java.javase" tofile="../${rootrel.build}/gensrc/java/com/sun/gluegen/runtime/StructAccessor.java" /> </target> <target name="setup.javame.cdc.fp" if="isCDCFP"> - <copy file="../src/java/com/sun/gluegen/runtime/BufferFactory.java.javame_cdc_fp" tofile="../build/gensrc/java/com/sun/gluegen/runtime/BufferFactory.java" /> - <copy file="../src/java/com/sun/gluegen/runtime/StructAccessor.java.javame_cdc_fp" tofile="../build/gensrc/java/com/sun/gluegen/runtime/StructAccessor.java" /> + <copy file="../src/java/com/sun/gluegen/runtime/BufferFactory.java.javame_cdc_fp" tofile="../${rootrel.build}/gensrc/java/com/sun/gluegen/runtime/BufferFactory.java" /> + <copy file="../src/java/com/sun/gluegen/runtime/StructAccessor.java.javame_cdc_fp" tofile="../${rootrel.build}/gensrc/java/com/sun/gluegen/runtime/StructAccessor.java" /> </target> <target name="init" depends="load.user.properties,setup-excludes-1,setup-excludes-2,init.javame.cdc.fp"> @@ -56,11 +62,11 @@ <!-- The source directories. --> <property name="src.java" value="../src/java" /> - <property name="build" value="../build" /> + <property name="build" value="../${rootrel.build}" /> <!-- The generated source directories. --> - <property name="src.generated" value="../build/gensrc" /> - <property name="src.generated.java" value="../build/gensrc/java" /> + <property name="src.generated" value="../${rootrel.build}/gensrc" /> + <property name="src.generated.java" value="../${rootrel.build}/gensrc/java" /> <!-- The compiler output directories. --> <property name="classes" value="${build}/classes" /> @@ -310,13 +316,13 @@ <target name="c.rename.lib.mingw" if="isMingW"> <!-- FIXME: this is a hack; the cpptask should have an option to change the suffix or at least understand the override from .so to .dll --> - <move file="../build/obj/libgluegen-rt.so" tofile="../build/obj/gluegen-rt.dll" /> + <move file="../${rootrel.build}/obj/libgluegen-rt.so" tofile="../${rootrel.build}/obj/gluegen-rt.dll" /> </target> <target name="c.rename.lib.macosx" if="isOSX"> <!-- FIXME: this is a hack; the cpptask should have an option to change the suffix or at least understand the override from dylib to jnilib --> - <move file="../build/obj/libgluegen-rt.dylib" tofile="../build/obj/libgluegen-rt.jnilib" /> + <move file="../${rootrel.build}/obj/libgluegen-rt.dylib" tofile="../${rootrel.build}/obj/libgluegen-rt.jnilib" /> </target> <target name="c.build" depends="c.configure" unless="build.javaonly" > @@ -334,14 +340,14 @@ <condition property="c.compiler.use-debug"><istrue value="${c.compiler.debug}"/></condition> - <mkdir dir="../build/obj" /> + <mkdir dir="../${rootrel.build}/obj" /> <echo message="Compiling ${c.compiler.src.files}" /> <echo message="user.dir=${user.dir}" /> <cc outtype="shared" - objdir="../build/obj" - outfile="../build/obj/${output.lib.name}" + objdir="../${rootrel.build}/obj" + outfile="../${rootrel.build}/obj/${output.lib.name}" optimize="${c.compiler.optimise}" debug="${c.compiler.debug}" multithreaded="true" @@ -373,8 +379,8 @@ <antcall target="c.rename.lib.mingw" inheritRefs="true" /> <antcall target="c.rename.lib.macosx" inheritRefs="true" /> <!-- Create Java Web Start jar file from built file --> - <jar destfile="../build/gluegen-rt-natives-${os.and.arch}.jar"> - <fileset dir="../build/obj"> + <jar destfile="../${rootrel.build}/gluegen-rt-natives-${os.and.arch}.jar"> + <fileset dir="../${rootrel.build}/obj"> <include name="*gluegen-rt.${native.library.suffix}" /> </fileset> </jar> @@ -388,7 +394,7 @@ <target name="gluegen.rebuild.gluegen-rt" if="isCDCFP"> <!-- Re-build just the gluegen-rt.jar classes using the Java ME boot classes, if they're in use. --> - <delete dir="../build/classes/com/sun/gluegen/runtime" /> + <delete dir="../${rootrel.build}/classes/com/sun/gluegen/runtime" /> <javac destdir="${classes}" source="1.4" debug="true" @@ -506,7 +512,7 @@ <target name="clean"> <delete includeEmptyDirs="true" quiet="true"> - <fileset dir="../build" /> + <fileset dir="../${rootrel.build}" /> </delete> </target> </project> diff --git a/make/gluegen.compiler.xml b/make/gluegen.compiler.xml index c911553..ee7ebee 100644 --- a/make/gluegen.compiler.xml +++ b/make/gluegen.compiler.xml @@ -8,6 +8,9 @@ <compilerarg value="-I/devtools/i686-unknown-linux-gnu/include" /> <compilerarg value="-I/devtools/share/include" /> <compilerarg value="-I/devtools/i686-unknown-linux-gnu/xfree86-4.3.0-linux-ix86-glibc23/include" /> + <defineset> + <define name="LINUX" /> + </defineset> </compiler> <linker id="linker.cfg.linux" name="gcc"> diff --git a/make/gluegen.properties b/make/gluegen.properties index 4f70334..29776df 100755 --- a/make/gluegen.properties +++ b/make/gluegen.properties @@ -21,7 +21,7 @@ antlr.jar=C:/Users/kbr/ANTLR/antlr-2.7.2/antlr.jar # you can choose an alternate compiler with which to build the native # code. Valid strings here are "vc6", "vc7", "vc8", "vc8_x64", and # "mingw". -win32.c.compiler=vc6 +# win32.c.compiler=vc6 # If you are building on a Mac OS X system supporting # cross-compilation and want to generate fat binaries containing diff --git a/src/java/com/sun/gluegen/GlueGen.java b/src/java/com/sun/gluegen/GlueGen.java index a7c64a8..1a7c690 100644 --- a/src/java/com/sun/gluegen/GlueGen.java +++ b/src/java/com/sun/gluegen/GlueGen.java @@ -67,6 +67,7 @@ public class GlueGen implements GlueEmitterControls { Reader reader = null; String filename = null; String emitterClass = null; + String outputRootDir = null; java.util.List cfgFiles = new ArrayList(); if (args.length == 0) { @@ -82,6 +83,8 @@ public class GlueGen implements GlueEmitterControls { for (int j = 0; j < paths.length; j++) { includePaths.add(paths[j]); } + } else if (arg.startsWith("-O")) { + outputRootDir = arg.substring(2); } else if (arg.startsWith("-E")) { emitterClass = arg.substring(2); } else if (arg.startsWith("-C")) { @@ -180,6 +183,16 @@ public class GlueGen implements GlueEmitterControls { emit.readConfigurationFile((String) iter.next()); } + if(null!=outputRootDir && outputRootDir.trim().length()>0) { + if(emit instanceof JavaEmitter) { + // FIXME: hack to interfere with the *Configuration setting via commandlines + JavaEmitter jemit = (JavaEmitter)emit; + if(null!=jemit.getConfig()) { + jemit.getConfig().setOutputRootDir(outputRootDir); + } + } + } + // Provide MachineDescriptions to emitter MachineDescription md32 = new MachineDescription32Bit(); MachineDescription md64 = new MachineDescription64Bit(); diff --git a/src/java/com/sun/gluegen/JavaConfiguration.java b/src/java/com/sun/gluegen/JavaConfiguration.java index dafa131..d25473a 100644 --- a/src/java/com/sun/gluegen/JavaConfiguration.java +++ b/src/java/com/sun/gluegen/JavaConfiguration.java @@ -62,6 +62,12 @@ public class JavaConfiguration { * working directory. */ private String javaOutputDir = "."; + + /** + * Top output root directory for all generated files. Default is null, ie not to use it. + */ + private String outputRootDir = null; + /** * Directory into which generated native JNI code will be written. Default * is current working directory. @@ -238,6 +244,8 @@ public class JavaConfiguration { } } + public void setOutputRootDir(String s) { outputRootDir=s; } + /** Returns the package name parsed from the configuration file. */ public String packageName() { return packageName; } /** Returns the implementation package name parsed from the configuration file. */ @@ -247,9 +255,9 @@ public class JavaConfiguration { /** Returns the implementation class name parsed from the configuration file. */ public String implClassName() { return implClassName; } /** Returns the Java code output directory parsed from the configuration file. */ - public String javaOutputDir() { return javaOutputDir; } + public String javaOutputDir() { return (null!=outputRootDir)?(outputRootDir + "/" + javaOutputDir):javaOutputDir; } /** Returns the native code output directory parsed from the configuration file. */ - public String nativeOutputDir() { return nativeOutputDir; } + public String nativeOutputDir() { return (null!=outputRootDir)?(outputRootDir + "/" + nativeOutputDir):nativeOutputDir; } /** Returns whether the native code directory structure mirrors the Java hierarchy. */ public boolean nativeOutputUsesJavaHierarchy() { return nativeOutputUsesJavaHierarchy; } /** Returns whether the comment of a native method binding should include a @native tag. */ diff --git a/src/java/com/sun/gluegen/ant/GlueGenTask.java b/src/java/com/sun/gluegen/ant/GlueGenTask.java index 45ce1b0..af42392 100644 --- a/src/java/com/sun/gluegen/ant/GlueGenTask.java +++ b/src/java/com/sun/gluegen/ant/GlueGenTask.java @@ -65,6 +65,7 @@ import org.apache.tools.ant.util.JavaEnvUtils; * <p>Usage:</p> * <pre> <gluegen src="[source C file]" + outputrootdir="[optional output root dir]" includes="[optional directory pattern of include files to include]" excludes="[optional directory pattern of include files to exclude]" includeRefid="[optional FileSet or DirSet for include files]" @@ -93,6 +94,11 @@ public class GlueGenTask extends Task // ========================================================================= /** + * <p>The optional output root dir.</p> + */ + private String outputRootDir; + + /** * <p>The name of the emitter class.</p> */ private String emitter; @@ -152,6 +158,18 @@ public class GlueGenTask extends Task // ========================================================================= // ANT getters and setters + + /** + * <p>Set the output root dir (optional). This is called by ANT.</p> + * + * @param outputRootDir the optional output root dir + */ + public void setOutputRootDir(String outputRootDir) + { + log( ("Setting output root dir: " + outputRootDir), Project.MSG_VERBOSE); + this.outputRootDir=outputRootDir; + } + /** * <p>Set the emitter class name. This is called by ANT.</p> * @@ -350,6 +368,8 @@ public class GlueGenTask extends Task private void validateAttributes() throws BuildException { + // outputRootDir is optional .. + // validate that the emitter class is set if(!isValid(emitter)) throw new BuildException("Invalid emitter class name: " + emitter); @@ -398,6 +418,11 @@ public class GlueGenTask extends Task // NOTE: GlueGen uses concatenated flag / value rather than two // separate arguments + // add the output root dir + if(null!=outputRootDir && outputRootDir.trim().length()>0) { + gluegenCommandline.createArgument().setValue("-O" + outputRootDir); + } + // add the emitter class name gluegenCommandline.createArgument().setValue("-E" + emitter); diff --git a/src/java/com/sun/gluegen/opengl/BuildComposablePipeline.java b/src/java/com/sun/gluegen/opengl/BuildComposablePipeline.java index e250d85..db2bfd2 100644 --- a/src/java/com/sun/gluegen/opengl/BuildComposablePipeline.java +++ b/src/java/com/sun/gluegen/opengl/BuildComposablePipeline.java @@ -48,8 +48,22 @@ import java.util.regex.*; public class BuildComposablePipeline { - private String outputDirectory; + public static final int GEN_DEBUG = 1 << 0 ; // default + public static final int GEN_TRACE = 1 << 1 ; // default + public static final int GEN_CUSTOM = 1 << 2 ; + public static final int GEN_PROLOG_XOR_DOWNSTREAM = 1 << 3 ; + + int mode; + private String outputDir; + private String outputPackage; + private String outputName; private Class classToComposeAround; + private Class classPrologOpt; + private Class classDownstream; + private String basePackage; + private String baseName; // does not include package! + private String downstreamPackage; + private String downstreamName; // does not include package! // Only desktop OpenGL has immediate mode glBegin / glEnd private boolean hasImmediateMode; @@ -57,21 +71,57 @@ public class BuildComposablePipeline // Desktop OpenGL and GLES1 have GL_STACK_OVERFLOW and GL_STACK_UNDERFLOW errors private boolean hasStackOverflow; - public static void main(String[] args) - { - String nameOfClassToComposeAround = args[0]; - Class classToComposeAround; + public static Class getClass(String name) { + Class clazz=null; try { - classToComposeAround = Class.forName(nameOfClassToComposeAround); + clazz = Class.forName(name); } catch (Exception e) { throw new RuntimeException( - "Could not find class \"" + nameOfClassToComposeAround + "\"", e); - } + "Could not find class \"" + name + "\"", e); + } + return clazz; + } + + public static Method getMethod(Class clazz, Method m) { + Method res = null; + try { + res = clazz.getMethod(m.getName(), m.getParameterTypes()); + } catch (Exception e) { } + return res; + } + + public static void main(String[] args) + { + String classToComposeAroundName = args[0]; + Class classPrologOpt, classDownstream; + Class classToComposeAround = getClass(classToComposeAroundName); String outputDir = args[1]; + String outputPackage, outputName; + int mode; + + if(args.length>2) { + String outputClazzName = args[2]; + outputPackage = getPackageName(outputClazzName); + outputName = getBaseClassName(outputClazzName); + classPrologOpt = getClass(args[3]); + classDownstream = getClass(args[4]); + mode = GEN_CUSTOM; + if(args.length>5) { + if(args[5].equals("prolog_xor_downstream")) { + mode |= GEN_PROLOG_XOR_DOWNSTREAM; + } + } + } else { + outputPackage = getPackageName(classToComposeAroundName); + outputName = null; // TBD .. + classPrologOpt = null; + classDownstream = classToComposeAround; + mode = GEN_DEBUG | GEN_TRACE; + } BuildComposablePipeline composer = - new BuildComposablePipeline(classToComposeAround, outputDir); + new BuildComposablePipeline(mode, outputDir, outputPackage, outputName, classToComposeAround, classPrologOpt, classDownstream); try { @@ -84,10 +134,16 @@ public class BuildComposablePipeline } } - protected BuildComposablePipeline(Class classToComposeAround, String outputDirectory) + protected BuildComposablePipeline(int mode, String outputDir, String outputPackage, String outputName, + Class classToComposeAround, Class classPrologOpt, Class classDownstream) { - this.outputDirectory = outputDirectory; - this.classToComposeAround = classToComposeAround; + this.mode=mode; + this.outputDir=outputDir; + this.outputPackage=outputPackage; + this.outputName=outputName; + this.classToComposeAround=classToComposeAround; + this.classPrologOpt=classPrologOpt; + this.classDownstream=classDownstream; if (! classToComposeAround.isInterface()) { @@ -114,20 +170,49 @@ public class BuildComposablePipeline */ public void emit() throws IOException { - String pDir = outputDirectory; - String pInterface = classToComposeAround.getName(); - List/*<Method>*/ publicMethodsRaw = Arrays.asList(classToComposeAround.getMethods()); + List/*<Method>*/ publicMethodsRaw = new ArrayList(); + publicMethodsRaw.addAll(Arrays.asList(classToComposeAround.getMethods())); Set/*<Method>*/ publicMethodsPlain = new HashSet(); for (Iterator iter=publicMethodsRaw.iterator(); iter.hasNext(); ) { Method method = (Method) iter.next(); // Don't hook methods which aren't real GL methods, // such as the synthetic "getGL2ES2" - boolean runHooks = (method.getName().startsWith("gl")); - publicMethodsPlain.add(new PlainMethod(method, runHooks)); + String name = method.getName(); + boolean runHooks = name.startsWith("gl"); + if (!name.startsWith("getGL") && !name.equals("toString")) { + publicMethodsPlain.add(new PlainMethod(method, runHooks)); + } } - (new DebugPipeline(pDir, pInterface)).emit(publicMethodsPlain.iterator()); - (new TracePipeline(pDir, pInterface)).emit(publicMethodsPlain.iterator()); + if(0!=(mode&GEN_DEBUG)) { + (new DebugPipeline(outputDir, outputPackage, classToComposeAround, classDownstream)).emit(publicMethodsPlain.iterator()); + } + if(0!=(mode&GEN_TRACE)) { + (new TracePipeline(outputDir, outputPackage, classToComposeAround, classDownstream)).emit(publicMethodsPlain.iterator()); + } + if(0!=(mode&GEN_CUSTOM)) { + (new CustomPipeline(mode, outputDir, outputPackage, outputName, classToComposeAround, classPrologOpt, classDownstream)).emit(publicMethodsPlain.iterator()); + } + } + + public static String getPackageName(String clazzName) { + int lastDot = clazzName.lastIndexOf('.'); + if (lastDot == -1) + { + // no package, class is at root level + return null; + } + return clazzName.substring(0, lastDot); + } + + public static String getBaseClassName(String clazzName) { + int lastDot = clazzName.lastIndexOf('.'); + if (lastDot == -1) + { + // no package, class is at root level + return clazzName; + } + return clazzName.substring(lastDot+1); } //------------------------------------------------------- @@ -193,9 +278,18 @@ public class BuildComposablePipeline protected abstract class PipelineEmitter { private File file; - private String basePackage; - private String baseName; // does not include package! - private String outputDir; + protected String basePackage; + protected String baseName; // does not include package! + protected String downstreamPackage; + protected String downstreamName; // does not include package! + protected String prologPackageOpt=null; + protected String prologNameOpt=null; // does not include package! + + protected String outputDir; + protected String outputPackage; + protected Class baseInterfaceClass; + protected Class prologClassOpt=null; + protected Class downstreamClass; /** * @param outputDir the directory into which the pipeline classes will be @@ -205,28 +299,28 @@ public class BuildComposablePipeline * @exception IllegalArgumentException if classToComposeAround is not an * interface. */ - public PipelineEmitter(String outputDir, String baseInterfaceClassName) + public PipelineEmitter(String outputDir, String outputPackage, Class baseInterfaceClass, Class prologClassOpt, Class downstreamClass) { - int lastDot = baseInterfaceClassName.lastIndexOf('.'); - if (lastDot == -1) - { - // no package, class is at root level - this.baseName = baseInterfaceClassName; - this.basePackage = null; - } - else - { - this.baseName = baseInterfaceClassName.substring(lastDot+1); - this.basePackage = baseInterfaceClassName.substring(0, lastDot); - } + this.outputDir=outputDir; + this.outputPackage=outputPackage; + this.baseInterfaceClass=baseInterfaceClass; + this.prologClassOpt=prologClassOpt; + this.downstreamClass=downstreamClass; - this.outputDir = outputDir; + basePackage = getPackageName(baseInterfaceClass.getName()); + baseName = getBaseClassName(baseInterfaceClass.getName()); + downstreamPackage = getPackageName(downstreamClass.getName()); + downstreamName = getBaseClassName(downstreamClass.getName()); + if(null!=prologClassOpt) { + prologPackageOpt = getPackageName(prologClassOpt.getName()); + prologNameOpt = getBaseClassName(prologClassOpt.getName()); + } } public void emit(Iterator/*<Method>*/ methodsToWrap) throws IOException { - String pipelineClassName = getPipelineName(); - this.file = new File(outputDir + File.separatorChar + pipelineClassName + ".java"); + String outputClassName = getOutputName(); + this.file = new File(outputDir + File.separatorChar + outputClassName + ".java"); String parentDir = file.getParent(); if (parentDir != null) { @@ -236,14 +330,41 @@ public class BuildComposablePipeline PrintWriter output = new PrintWriter(new BufferedWriter(new FileWriter(file))); + HashSet clazzList = new HashSet(); + clazzList.add(baseInterfaceClass); + clazzList.addAll(Arrays.asList(baseInterfaceClass.getInterfaces())); + + String[] ifNames = new String[clazzList.size()]; + { + int i=0; + for (Iterator iter=clazzList.iterator(); iter.hasNext(); ) { + ifNames[i++] = new String(((Class)iter.next()).getName()); + } + } + + clazzList.add(downstreamClass); + if(null!=prologClassOpt) { + clazzList.add(prologClassOpt); + } + + String[] importNames = new String[clazzList.size()+2]; + { + int i=0; + importNames[i++] = new String("java.io.*"); + importNames[i++] = new String("javax.media.opengl.*"); + for (Iterator iter=clazzList.iterator(); iter.hasNext(); ) { + importNames[i++] = new String(((Class)iter.next()).getName()); + } + } + CodeGenUtils.emitJavaHeaders(output, - basePackage, - pipelineClassName, + outputPackage, + outputClassName, "com.sun.gluegen.runtime", // FIXME: should make configurable true, - new String[] { "java.io.*", "javax.media.opengl.*" }, + importNames, new String[] { "public" }, - new String[] { baseName }, + ifNames, null, new CodeGenUtils.EmissionCallback() { public void emit(PrintWriter w) { emitClassDocComment(w); } @@ -254,6 +375,8 @@ public class BuildComposablePipeline constructorHook(output); + output.println(strGLGetMethods); + while (methodsToWrap.hasNext()) { PlainMethod pm = (PlainMethod)methodsToWrap.next(); @@ -266,21 +389,32 @@ public class BuildComposablePipeline postMethodEmissionHook(output); output.println(); - output.print(" private " + baseName + " " + getDownstreamObjectName() + ";"); + output.print(" private " + downstreamName + " " + getDownstreamObjectName() + ";"); // end the class output.println(); output.print("} // end class "); - output.println(pipelineClassName); + output.println(outputClassName); output.flush(); output.close(); + + System.out.println("wrote to file: "+file); // JAU } /** Get the name of the object through which API calls should be routed. */ protected String getDownstreamObjectName() { - return "downstream" + baseName; + return "downstream" + downstreamName; + } + + /** Get the name of the object which shall be called as a prolog. */ + protected String getPrologObjectNameOpt() + { + if(null!=prologNameOpt) { + return "prolog" + prologNameOpt; + } + return null; } protected void emitMethodDocComment(PrintWriter output, Method m) @@ -305,35 +439,61 @@ public class BuildComposablePipeline output.print(" "); Class retType = m.getReturnType(); - if (runHooks) { + boolean callPreDownstreamHook = runHooks && hasPreDownstreamCallHook(m); + boolean callPostDownstreamHook = runHooks && hasPostDownstreamCallHook(m); + boolean callDownstream = (null!=getMethod(downstreamClass, m)) && + !( 0!=(GEN_PROLOG_XOR_DOWNSTREAM&getMode()) && callPreDownstreamHook ) ; + boolean hasResult = (retType != Void.TYPE); + + if(!callDownstream && !emptyDownstreamAllowed()) { + throw new RuntimeException("Method "+m+" has no downstream ("+downstreamName+")"); + } + + if(!callPreDownstreamHook && !callPostDownstreamHook && !callDownstream && !emptyMethodAllowed()) { + throw new RuntimeException("Method "+m+" is empty, no downstream ("+downstreamName+") nor prolog ("+prologNameOpt+")."); + } + + if (callPreDownstreamHook) { + if(hasResult && !callDownstream) { + if(callPostDownstreamHook) { + output.print(" "+JavaType.createForClass(retType).getName()); + output.print(" _res = "); + } else { + output.print(" return "); + } + } preDownstreamCallHook(output, m); } - if (retType != Void.TYPE) - { - output.print(JavaType.createForClass(retType).getName()); - output.print(" _res = "); + if(callDownstream) { + if (hasResult) { + if(callPostDownstreamHook) { + output.print(" "+JavaType.createForClass(retType).getName()); + output.print(" _res = "); + } else { + output.print(" return "); + } + } + output.print(getDownstreamObjectName()); + output.print('.'); + output.print(m.getName()); + output.print('('); + output.print(getArgListAsString(m, false, true)); + output.println(");"); } - output.print(getDownstreamObjectName()); - output.print('.'); - output.print(m.getName()); - output.print('('); - output.print(getArgListAsString(m, false, true)); - output.println(");"); - if (runHooks) { + if (callPostDownstreamHook) { postDownstreamCallHook(output, m); } - if (retType != Void.TYPE) - { - output.println(" return _res;"); + if (hasResult && callDownstream && callPostDownstreamHook) { + output.println(" return _res;"); } output.println(" }"); } - private String getArgListAsString(Method m, boolean includeArgTypes, boolean includeArgNames) + protected String getArgListAsString(Method m, boolean includeArgTypes, boolean includeArgNames) { StringBuffer buf = new StringBuffer(256); if (!includeArgNames && !includeArgTypes) @@ -372,8 +532,8 @@ public class BuildComposablePipeline return baseName; } - /** Get the name for this pipeline class. */ - protected abstract String getPipelineName(); + /** Get the output name for this pipeline class. */ + protected abstract String getOutputName(); /** * Called after the class headers have been generated, but before any @@ -384,31 +544,29 @@ public class BuildComposablePipeline /** * Emits the constructor for the pipeline; called after the preMethodEmissionHook. */ - protected void constructorHook(PrintWriter output) { - output.print( " public " + getPipelineName() + "(" + baseName + " "); - output.println(getDownstreamObjectName() + ")"); - output.println(" {"); - output.println(" if (" + getDownstreamObjectName() + " == null) {"); - output.println(" throw new IllegalArgumentException(\"null " + getDownstreamObjectName() + "\");"); - output.println(" }"); - output.print( " this." + getDownstreamObjectName()); - output.println(" = " + getDownstreamObjectName() + ";"); - output.println(" // Fetch GLContext object for better error checking (if possible)"); - output.println(" _context = " + getDownstreamObjectName() + ".getContext();"); - output.println(" }"); - output.println(); - } + protected abstract void constructorHook(PrintWriter output); /** * Called after the method wrappers have been generated, but before the * closing parenthesis of the class is emitted. */ - protected abstract void postMethodEmissionHook(PrintWriter output); + protected void postMethodEmissionHook(PrintWriter output) { + output.println( " public String toString() {"); + output.println( " StringBuffer sb = new StringBuffer();"); + output.println( " sb.append(\""+getOutputName()+" [ implementing "+baseInterfaceClass.getName()+",\\n\\t\");"); + if(null!=prologClassOpt) { + output.println( " sb.append(\" prolog: \"+"+getPrologObjectNameOpt()+".toString()+\",\\n\\t\");"); + } + output.println( " sb.append(\" downstream: \"+"+getDownstreamObjectName()+".toString()+\"\\n\\t]\");"); + output.println( " return sb.toString();"); + output.println( " }"); + } /** * Called before the pipeline routes the call to the downstream object. */ protected abstract void preDownstreamCallHook(PrintWriter output, Method m); + protected abstract boolean hasPreDownstreamCallHook(Method m); /** * Called after the pipeline has routed the call to the downstream object, @@ -416,34 +574,224 @@ public class BuildComposablePipeline */ protected abstract void postDownstreamCallHook(PrintWriter output, Method m); + protected abstract boolean hasPostDownstreamCallHook(Method m); + + protected abstract int getMode(); + protected abstract boolean emptyMethodAllowed(); + protected abstract boolean emptyDownstreamAllowed(); + /** Emit a Javadoc comment for this pipeline class. */ protected abstract void emitClassDocComment(PrintWriter output); + protected final static String strGLGetMethods = + " public javax.media.opengl.GL getGL() {\n"+ + " return (javax.media.opengl.GL) this;\n"+ + " }\n"+ + " public javax.media.opengl.GL2ES1 getGL2ES1() {\n"+ + " if(GLProfile.implementationOfGL2ES1(this)) {\n"+ + " return (javax.media.opengl.GL2ES1) this;\n"+ + " }\n"+ + " throw new GLException(\"Not a GL2ES1 implementation\");\n"+ + " }\n"+ + " public javax.media.opengl.GL2 getGL2() {\n"+ + " if(GLProfile.implementationOfGL2(this)) {\n"+ + " return (javax.media.opengl.GL2) this;\n"+ + " }\n"+ + " throw new GLException(\"Not a GL2 implementation\");\n"+ + " }\n"+ + " public javax.media.opengl.GL2ES2 getGL2ES2() {\n"+ + " if(GLProfile.implementationOfGL2ES2(this)) {\n"+ + " return (javax.media.opengl.GL2ES2) this;\n"+ + " }\n"+ + " throw new GLException(\"Not a GL2ES2 implementation\");\n"+ + " }\n"+ + " public javax.media.opengl.GLES1 getGLES1() {\n"+ + " if(GLProfile.implementationOfGLES1(this)) {\n"+ + " return (javax.media.opengl.GLES1) this;\n"+ + " }\n"+ + " throw new GLException(\"Not a GLES1 implementation\");\n"+ + " }\n"+ + " public javax.media.opengl.GLES2 getGLES2() {\n"+ + " if(GLProfile.implementationOfGLES2(this)) {\n"+ + " return (javax.media.opengl.GLES2) this;\n"+ + " }\n"+ + " throw new GLException(\"Not a GLES2 implementation\");\n"+ + " }"; + } // end class PipelineEmitter //------------------------------------------------------- + protected class CustomPipeline extends PipelineEmitter + { + String className; + int mode; + + public CustomPipeline(int mode, String outputDir, String outputPackage, String outputName, Class baseInterfaceClass, Class prologClassOpt, Class downstreamClass) + { + super(outputDir, outputPackage, baseInterfaceClass, prologClassOpt, downstreamClass); + className = outputName; + this.mode = mode; + } + + protected String getOutputName() + { + return className; + } + + protected int getMode() { return mode; } + + protected boolean emptyMethodAllowed() { + return false; + } + protected boolean emptyDownstreamAllowed() { + return true; + } + + protected void preMethodEmissionHook(PrintWriter output) + { + } + + protected void constructorHook(PrintWriter output) { + output.print( " public " + getOutputName() + "(" ); + output.print( downstreamName + " " + getDownstreamObjectName() ); + if(null!=prologNameOpt) { + output.println( ", " + prologNameOpt + " " + getPrologObjectNameOpt() + ")"); + } else { + output.println(")"); + } + output.println(" {"); + output.println(" if (" + getDownstreamObjectName() + " == null) {"); + output.println(" throw new IllegalArgumentException(\"null " + getDownstreamObjectName() + "\");"); + output.println(" }"); + output.print( " this." + getDownstreamObjectName()); + output.println(" = " + getDownstreamObjectName() + ";"); + if(null!=prologNameOpt) { + output.print( " this." + getPrologObjectNameOpt()); + output.println(" = " + getPrologObjectNameOpt() + ";"); + } + output.println(" }"); + output.println(); + } + + protected void postMethodEmissionHook(PrintWriter output) + { + super.postMethodEmissionHook(output); + if(null!=prologNameOpt) { + output.print(" private " + prologNameOpt + " " + getPrologObjectNameOpt() + ";"); + } + } + + protected void emitClassDocComment(PrintWriter output) + { + output.println("/**"); + output.println(" * Composable pipeline {@link "+outputPackage+"."+outputName+"}, implementing the interface"); + output.println(" * {@link "+baseInterfaceClass.getName()+"}"); + output.println(" * <p>"); + output.println(" * Each method follows the call graph <ul>"); + if(null!=prologClassOpt) { + output.println(" * <li> call <em>prolog</em> {@link "+prologClassOpt.getName()+"} if available"); + } + output.println(" * <li> call <em>downstream</em> {@link "+downstreamClass.getName()+"} if available"); + if(null!=prologClassOpt && 0!=(GEN_PROLOG_XOR_DOWNSTREAM&getMode())) { + output.println(" * <strong>and</strong> if no call to {@link "+prologClassOpt.getName()+"} is made"); + } + output.println(" * </ul><p>"); + output.println(" * "); + output.println(" * <ul>"); + output.println(" * <li> <em>Interface</em> {@link "+baseInterfaceClass.getName()+"}"); + if(null!=prologClassOpt) { + output.println(" * <li> <em>Prolog</em> {@link "+prologClassOpt.getName()+"}"); + } + output.println(" * <li> <em>Downstream</em> {@link "+downstreamClass.getName()+"}"); + output.println(" * </ul><p>"); + output.println(" * Sample code which installs this pipeline: </P>"); + output.println(" * "); + output.println("<PRE>"); + if(null!=prologNameOpt) { + output.println(" drawable.setGL( new "+className+"( drawable.getGL(), new "+prologNameOpt+"(drawable.getGL()) ) );"); + } else { + output.println(" drawable.setGL( new "+className+"( drawable.getGL() ) );"); + } + output.println("</PRE>"); + output.println("*/"); + } + + protected boolean hasPreDownstreamCallHook(Method m) { + return null!=getMethod(prologClassOpt, m); + } + + protected void preDownstreamCallHook(PrintWriter output, Method m) + { + if(null!=prologNameOpt) { + output.print(getPrologObjectNameOpt()); + output.print('.'); + output.print(m.getName()); + output.print('('); + output.print(getArgListAsString(m, false, true)); + output.println(");"); + } + } + + protected boolean hasPostDownstreamCallHook(Method m) { + return false; + } + + protected void postDownstreamCallHook(PrintWriter output, Method m) + { + } + + } // end class CustomPipeline + protected class DebugPipeline extends PipelineEmitter { String className; - String baseInterfaceClassName; - public DebugPipeline(String outputDir, String baseInterfaceClassName) + public DebugPipeline(String outputDir, String outputPackage, Class baseInterfaceClass, Class downstreamClass) { - super(outputDir, baseInterfaceClassName); + super(outputDir, outputPackage, baseInterfaceClass, null, downstreamClass); className = "Debug" + getBaseInterfaceName(); } - protected String getPipelineName() + protected String getOutputName() { return className; } + protected int getMode() { return 0; } + + protected boolean emptyMethodAllowed() { + return false; + } + protected boolean emptyDownstreamAllowed() { + return false; + } + protected void preMethodEmissionHook(PrintWriter output) { } + protected void constructorHook(PrintWriter output) { + output.print( " public " + getOutputName() + "(" ); + output.println( downstreamName + " " + getDownstreamObjectName() + ")"); + output.println(" {"); + output.println(" if (" + getDownstreamObjectName() + " == null) {"); + output.println(" throw new IllegalArgumentException(\"null " + getDownstreamObjectName() + "\");"); + output.println(" }"); + output.print( " this." + getDownstreamObjectName()); + output.println(" = " + getDownstreamObjectName() + ";"); + if(null!=prologNameOpt) { + output.print( " this." + getPrologObjectNameOpt()); + output.println(" = " + getPrologObjectNameOpt() + ";"); + } + output.println(" // Fetch GLContext object for better error checking (if possible)"); + output.println(" _context = " + getDownstreamObjectName() + ".getContext();"); + output.println(" }"); + output.println(); + } + protected void postMethodEmissionHook(PrintWriter output) { + super.postMethodEmissionHook(output); output.println(" private void checkGLGetError(String caller)"); output.println(" {"); if (hasImmediateMode) { @@ -454,16 +802,16 @@ public class BuildComposablePipeline } output.println(" // Debug code to make sure the pipeline is working; leave commented out unless testing this class"); output.println(" //System.err.println(\"Checking for GL errors " + - "after call to \" + caller + \"()\");"); + "after call to \" + caller);"); output.println(); output.println(" int err = " + getDownstreamObjectName() + ".glGetError();"); output.println(" if (err == GL_NO_ERROR) { return; }"); output.println(); - output.println(" StringBuffer buf = new StringBuffer("); - output.println(" \"glGetError() returned the following error codes " + - "after a call to \" + caller + \"(): \");"); + output.println(" StringBuffer buf = new StringBuffer(Thread.currentThread()+"); + output.println(" \" glGetError() returned the following error codes " + + "after a call to \" + caller + \": \");"); output.println(); output.println(" // Loop repeatedly to allow for distributed GL implementations,"); output.println(" // as detailed in the glGetError() specification"); @@ -516,11 +864,19 @@ public class BuildComposablePipeline output.println("*/"); } + protected boolean hasPreDownstreamCallHook(Method m) { + return true; + } + protected void preDownstreamCallHook(PrintWriter output, Method m) { output.println(" checkContext();"); } + protected boolean hasPostDownstreamCallHook(Method m) { + return true; + } + protected void postDownstreamCallHook(PrintWriter output, Method m) { if (m.getName().equals("glBegin")) @@ -535,8 +891,21 @@ public class BuildComposablePipeline output.println(" insideBeginEndPair = false;"); } + output.println(" String txt = new String(\""+ m.getName() + "(\" +"); + Class[] params = m.getParameterTypes() ; + for(int i=0; params!=null && i<params.length; i++) { + if(params[i].equals(int.class)) { + output.println(" \"<"+params[i].getName()+"> 0x\"+Integer.toHexString(arg"+i+").toUpperCase() +"); + } else { + output.println(" \"<"+params[i].getName()+">\" +"); + } + if(i<params.length-1) { + output.println(" \", \" +"); + } + } + output.println(" \")\");"); // calls to glGetError() are only allowed outside of glBegin/glEnd pairs - output.println(" checkGLGetError(\"" + m.getName() + "\");"); + output.println(" checkGLGetError( txt );"); } } @@ -547,25 +916,33 @@ public class BuildComposablePipeline protected class TracePipeline extends PipelineEmitter { String className; - String baseInterfaceClassName; - public TracePipeline(String outputDir, String baseInterfaceClassName) + public TracePipeline(String outputDir, String outputPackage, Class baseInterfaceClass, Class downstreamClass) { - super(outputDir, baseInterfaceClassName); + super(outputDir, outputPackage, baseInterfaceClass, null, downstreamClass); className = "Trace" + getBaseInterfaceName(); } - protected String getPipelineName() + protected String getOutputName() { return className; } + protected int getMode() { return 0; } + + protected boolean emptyMethodAllowed() { + return false; + } + protected boolean emptyDownstreamAllowed() { + return false; + } + protected void preMethodEmissionHook(PrintWriter output) { } protected void constructorHook(PrintWriter output) { - output.print( " public " + getPipelineName() + "(" + getBaseInterfaceName() + " "); - output.println(getDownstreamObjectName() + ", PrintStream " + getOutputStreamName() + ")"); + output.print( " public " + getOutputName() + "(" ); + output.println( downstreamName + " " + getDownstreamObjectName() + ", PrintStream " + getOutputStreamName() + ")"); output.println(" {"); output.println(" if (" + getDownstreamObjectName() + " == null) {"); output.println(" throw new IllegalArgumentException(\"null " + getDownstreamObjectName() + "\");"); @@ -580,6 +957,7 @@ public class BuildComposablePipeline protected void postMethodEmissionHook(PrintWriter output) { + super.postMethodEmissionHook(output); output.println("private PrintStream " + getOutputStreamName() + ";"); output.println("private int indent = 0;"); output.println("protected String dumpArray(Object obj)"); @@ -623,6 +1001,10 @@ public class BuildComposablePipeline output.println("*/"); } + protected boolean hasPreDownstreamCallHook(Method m) { + return true; + } + protected void preDownstreamCallHook(PrintWriter output, Method m) { Class[] params = m.getParameterTypes(); @@ -639,17 +1021,27 @@ public class BuildComposablePipeline output.print(" print(\"" + m.getName() + "(\""); for ( int i =0; i < params.length; i++ ) { - if ( params[i].isArray() ) + if ( params[i].isArray() ) { output.print("+dumpArray(arg"+i+")"); - else - output.print("+arg"+i); - if ( i < params.length-1) + } else { + if(params[i].equals(int.class)) { + output.println("+\"<"+params[i].getName()+"> 0x\"+Integer.toHexString(arg"+i+").toUpperCase()"); + } else { + output.println("+\"<"+params[i].getName()+">\"+arg"+i); + } + } + if ( i < params.length-1) { output.print("+\",\""); + } } output.println("+\")\");"); output.print(" "); } + protected boolean hasPostDownstreamCallHook(Method m) { + return true; + } + protected void postDownstreamCallHook(PrintWriter output, Method m) { Class ret = m.getReturnType(); diff --git a/src/java/com/sun/gluegen/opengl/GLConfiguration.java b/src/java/com/sun/gluegen/opengl/GLConfiguration.java index 7be02f5..3d61b60 100755 --- a/src/java/com/sun/gluegen/opengl/GLConfiguration.java +++ b/src/java/com/sun/gluegen/opengl/GLConfiguration.java @@ -161,7 +161,7 @@ public class GLConfiguration extends ProcAddressConfiguration { prologue = prologue + "Disabled"; } - prologue = prologue + "();"; + prologue = prologue + "(true);"; res.add(0, prologue); |