diff options
Diffstat (limited to 'src/java/com/sun/gluegen/opengl/BuildComposablePipeline.java')
-rw-r--r-- | src/java/com/sun/gluegen/opengl/BuildComposablePipeline.java | 586 |
1 files changed, 489 insertions, 97 deletions
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(); |