40package com.jogamp.gluegen.opengl;
42import com.jogamp.gluegen.CodeGenUtils;
43import com.jogamp.gluegen.JavaType;
45import java.io.BufferedWriter;
47import java.io.FileWriter;
48import java.io.IOException;
49import java.io.PrintWriter;
50import java.lang.reflect.Method;
51import java.nio.Buffer;
52import java.util.ArrayList;
53import java.util.Arrays;
54import java.util.Collections;
55import java.util.Comparator;
56import java.util.HashMap;
57import java.util.HashSet;
58import java.util.Iterator;
89 private static final HashMap<String, String> addedGLHooks =
new HashMap<String, String>();
90 private static final String[] addedGLHookMethodNames =
new String[] {
91 "mapBuffer",
"mapBufferRange",
92 "mapNamedBuffer",
"mapNamedBufferRange" };
94 for(
int i=0; i<addedGLHookMethodNames.length; i++) {
95 addedGLHooks.put(addedGLHookMethodNames[i], addedGLHookMethodNames[i]);
100 private final String outputDir;
101 private final String outputPackage;
102 private final String outputName;
103 private final Class<?> classToComposeAround;
104 private final Class<?> classPrologOpt;
105 private final Class<?> classDownstream;
107 private boolean hasImmediateMode;
109 private boolean hasGL2ES1StackOverflow;
111 public static Class<?>
getClass(
final String name) {
112 Class<?> clazz =
null;
114 clazz = Class.forName(name);
115 }
catch (
final Exception e) {
116 throw new RuntimeException(
117 "Could not find class \"" + name +
"\"", e);
122 public static Method
getMethod(
final Class<?> clazz,
final Method m) {
125 res = clazz.getMethod(m.getName(), m.getParameterTypes());
126 }
catch (
final Exception e) {
131 public static void main(
final String[] args) {
132 final String classToComposeAroundName = args[0];
133 Class<?> classPrologOpt, classDownstream;
134 final Class<?> classToComposeAround =
getClass(classToComposeAroundName);
136 final String outputDir = args[1];
137 String outputPackage, outputName;
140 if (args.length > 2) {
141 final String outputClazzName = args[2];
145 classDownstream =
getClass(args[4]);
147 if (args.length > 5) {
148 for(
int i=5; i<args.length; i++) {
149 if (args[i].equals(
"prolog_xor_downstream")) {
151 }
else if (args[i].equals(
"gl_identity_by_assignable_class")) {
159 classPrologOpt =
null;
160 classDownstream = classToComposeAround;
165 new BuildComposablePipeline(mode, outputDir, outputPackage, outputName, classToComposeAround, classPrologOpt, classDownstream);
169 }
catch (
final IOException e) {
170 throw new RuntimeException(
171 "Error generating composable pipeline source files", e);
175 protected BuildComposablePipeline(
final int mode,
final String outputDir,
final String outputPackage,
final String outputName,
176 final Class<?> classToComposeAround,
final Class<?> classPrologOpt,
final Class<?> classDownstream) {
178 this.outputDir = outputDir;
179 this.outputPackage = outputPackage;
180 this.outputName = outputName;
181 this.classToComposeAround = classToComposeAround;
182 this.classPrologOpt = classPrologOpt;
183 this.classDownstream = classDownstream;
185 if (!classToComposeAround.isInterface()) {
186 throw new IllegalArgumentException(
187 classToComposeAround.getName() +
" is not an interface class");
194 null != classToComposeAround.getMethod(
"glBegin",
new Class<?>[]{Integer.TYPE});
195 }
catch (
final Exception e) {
199 hasGL2ES1StackOverflow = hasImmediateMode &&
200 (classToComposeAround.getField(
"GL_STACK_OVERFLOW") !=
null);
201 }
catch (
final Exception e) {
209 public void emit() throws IOException {
211 final List<Method> publicMethodsRaw = Arrays.asList(classToComposeAround.getMethods());
213 final Set<PlainMethod> publicMethodsPlainSet =
new HashSet<PlainMethod>();
214 for (
final Iterator<Method> iter = publicMethodsRaw.iterator(); iter.hasNext();) {
215 final Method method = iter.next();
218 final String name = method.getName();
219 if ( !name.equals(
"getDownstreamGL") &&
220 !name.equals(
"toString") ) {
221 final boolean syntheticIsGL = name.startsWith(
"isGL");
222 final boolean syntheticGetGL = name.startsWith(
"getGL");
223 final boolean runHooks = name.startsWith(
"gl") || syntheticIsGL || syntheticGetGL || addedGLHooks.containsKey(name);
224 publicMethodsPlainSet.add(
new PlainMethod(method, runHooks, syntheticIsGL, syntheticGetGL));
229 final List<PlainMethod> publicMethodsPlainSorted =
new ArrayList<PlainMethod>();
230 publicMethodsPlainSorted.addAll(publicMethodsPlainSet);
231 Collections.sort(publicMethodsPlainSorted,
new Comparator<PlainMethod>() {
239 (
new DebugPipeline(outputDir, outputPackage, classToComposeAround, classDownstream)).
emit(publicMethodsPlainSorted.iterator());
242 (
new TracePipeline(outputDir, outputPackage, classToComposeAround, classDownstream)).
emit(publicMethodsPlainSorted.iterator());
245 (
new CustomPipeline(mode, outputDir, outputPackage, outputName, classToComposeAround, classPrologOpt, classDownstream)).
emit(publicMethodsPlainSorted.iterator());
250 final int lastDot = clazzName.lastIndexOf(
'.');
255 return clazzName.substring(0, lastDot);
259 final int lastDot = clazzName.lastIndexOf(
'.');
264 return clazzName.substring(lastDot + 1);
271 final boolean runHooks;
272 final boolean isSynthethicIsGL;
273 final boolean isSynthethicGetGL;
275 PlainMethod(
final Method m,
final boolean runHooks,
final boolean isSynthethicIsGL,
final boolean isSynthethicGetGL) {
277 this.runHooks = runHooks;
278 this.isSynthethicIsGL = isSynthethicIsGL;
279 this.isSynthethicGetGL = isSynthethicGetGL;
290 public boolean isSynthetic() {
return isSynthethicIsGL || isSynthethicGetGL; }
295 public boolean equals(
final Object obj) {
299 m.getName().
equals(b.m.getName())
300 && m.getModifiers() == b.m.getModifiers()
301 && m.getReturnType().equals(b.m.getReturnType())
302 && Arrays.equals(m.getParameterTypes(), b.m.getParameterTypes());
310 int hash = m.getName().hashCode() ^ m.getModifiers() ^ m.getReturnType().hashCode();
311 final Class<?>[] args = m.getParameterTypes();
312 for (
int i = 0; i < args.length; i++) {
313 hash ^= args[i].hashCode();
320 final Class<?>[] args = m.getParameterTypes();
321 final StringBuilder argsString =
new StringBuilder();
322 argsString.append(
"(");
323 for (
int i = 0; i < args.length; i++) {
325 argsString.append(
", ");
327 argsString.append(args[i].getName());
329 argsString.append(
")");
331 +
"\n\tname: " + m.getName()
332 +
"\n\tsynt: isGL " + isSynthethicIsGL+
", getGL "+isSynthethicGetGL
333 +
"\n\tmods: " + m.getModifiers()
334 +
"\n\tretu: " + m.getReturnType()
335 +
"\n\targs[" + args.length +
"]: " + argsString.toString();
383 public void emit(
final Iterator<PlainMethod> methodsToWrap)
throws IOException {
385 this.file =
new File(
outputDir + File.separatorChar + outputClassName +
".java");
386 final String parentDir = file.getParent();
387 if (parentDir !=
null) {
388 final File pDirFile =
new File(parentDir);
392 final PrintWriter output =
new PrintWriter(
new BufferedWriter(
new FileWriter(file)));
394 final HashSet<Class<?>> importClazzList =
new HashSet<Class<?>>();
398 final List<Class<?>> baseInterfaces = Arrays.asList(
baseInterfaceClass.getInterfaces());
399 importClazzList.addAll(baseInterfaces);
406 final ArrayList<String> imports =
new ArrayList<String>();
407 imports.add(
"java.io.*");
408 imports.add(
"com.jogamp.opengl.*");
409 imports.add(
"com.jogamp.gluegen.runtime.*");
410 imports.add(Buffer.class.getPackage().getName()+
".*");
411 for (
final Class<?> clasS : importClazzList) {
412 imports.add(clasS.getName());
415 CodeGenUtils.emitJavaHeaders(output,
420 new String[]{
"public"},
423 new CodeGenUtils.EmissionCallback() {
425 public void emit(
final PrintWriter w) {
436 while (methodsToWrap.hasNext()) {
451 output.print(
"} // end class ");
452 output.println(outputClassName);
457 System.out.println(
"wrote to file: " + file);
477 output.format(
" @Override%n public %s %s(%s)%n",
478 JavaType.createForClass(m.getReturnType()).getName(),
484 final boolean runHooks = pm.runHooks();
486 output.println(
" {");
487 final Class<?> retType = m.getReturnType();
493 final boolean hasResult = (retType != Void.TYPE);
495 if (!callDownstream) {
497 throw new RuntimeException(
"Method " + m +
" has no downstream (" +
downstreamName +
")");
501 if (!callPreDownstreamHook && !callPostDownstreamHook && !callDownstream) {
503 throw new RuntimeException(
"Method " + m +
" is empty, no downstream (" +
downstreamName +
") nor prolog (" +
prologNameOpt +
").");
505 output.print(
" if(DEBUG) { System.out.println(\"WARNING: No prolog, no downstream, empty: \"+");
507 output.println(
"); } ");
511 if (callPreDownstreamHook) {
512 if (hasResult && !callDownstream) {
513 if (callPostDownstreamHook) {
514 output.print(
" " + JavaType.createForClass(retType).getName());
515 output.print(
" _res = ");
517 output.print(
" return ");
523 if (callDownstream) {
530 if (callPostDownstreamHook) {
531 output.print(
" " + JavaType.createForClass(retType).getName());
532 output.print(
" _res = ");
534 output.print(
" return ");
542 output.print(m.getName());
545 output.println(
");");
549 if (callPostDownstreamHook) {
553 if (hasResult && callDownstream && callPostDownstreamHook) {
554 output.println(
" return _res;");
557 output.println(
" }");
560 protected String
getArgListAsString(
final Method m,
final boolean includeArgTypes,
final boolean includeArgNames) {
561 final StringBuilder buf =
new StringBuilder(256);
562 if (!includeArgNames && !includeArgTypes) {
563 throw new IllegalArgumentException(
564 "Cannot generate arglist without both arg types and arg names");
567 final Class<?>[] argTypes = m.getParameterTypes();
568 for (
int i = 0; i < argTypes.length; ++i) {
569 if (includeArgTypes) {
570 buf.append(JavaType.createForClass(argTypes[i]).getName());
574 if (includeArgNames) {
578 if (i < argTypes.length - 1) {
583 return buf.toString();
603 output.println(
" public static final boolean DEBUG = jogamp.opengl.Debug.debug(\"" +
getOutputName() +
"\");");
616 output.println(
" @Override");
617 output.println(
" public String toString() {");
618 output.println(
" StringBuilder sb = new StringBuilder();");
619 output.println(
" sb.append(\"" +
getOutputName() +
" [this 0x\"+Integer.toHexString(hashCode())+\" implementing " +
baseInterfaceClass.getName() +
",\\n\\t\");");
624 output.println(
" return sb.toString();");
625 output.println(
" }");
657 final String type = methodName.substring(2);
659 if( type.equals(
"GL") ) {
660 output.println(
" return true;");
662 !type.equals(
"GLES") &&
663 !type.endsWith(
"core") &&
664 !type.endsWith(
"Compatible") )
668 output.println(
" return true;");
670 output.println(
" return false;");
682 final String type = methodName.substring(3);
684 if( type.equals(
"GL") ) {
685 output.println(
" return this;");
686 }
else if( type.equals(
"GLProfile") ) {
691 output.println(
" if( is" + type +
"() ) { return this; }");
692 output.println(
" throw new GLException(\"Not a " + type +
" implementation\");");
694 output.println(
" throw new GLException(\"Not a " + type +
" implementation\");");
703 output.println(
" @Override");
704 output.println(
" public final GL getDownstreamGL() throws GLException {");
706 output.println(
" }");
718 className = outputName;
744 super.preMethodEmissionHook(output);
756 output.println(
" {");
759 output.println(
" }");
766 output.println(
" }");
772 super.postMethodEmissionHook(output);
780 output.println(
"/**");
781 output.println(
" * Composable pipeline {@link " +
outputPackage +
"." + outputName +
"}, implementing the interface");
783 output.println(
" * <p>");
784 output.println(
" * Each method follows the call graph <ul>");
786 output.println(
" * <li> call <em>prolog</em> {@link " +
prologClassOpt.getName() +
"} if available");
788 output.println(
" * <li> call <em>downstream</em> {@link " +
downstreamClass.getName() +
"} if available");
790 output.println(
" * <strong>and</strong> if no call to {@link " +
prologClassOpt.getName() +
"} is made");
792 output.println(
" * </ul><p>");
793 output.println(
" * ");
794 output.println(
" * <ul>");
795 output.println(
" * <li> <em>Interface</em> {@link " +
baseInterfaceClass.getName() +
"}");
797 output.println(
" * <li> <em>Prolog</em> {@link " +
prologClassOpt.getName() +
"}");
799 output.println(
" * <li> <em>Downstream</em> {@link " +
downstreamClass.getName() +
"}");
800 output.println(
" * </ul><p>");
801 output.println(
" * Sample code which installs this pipeline: </P>");
802 output.println(
" * ");
803 output.println(
"<PRE>");
805 output.println(
" GL gl = drawable.setGL( new " + className +
"( drawable.getGL().getGL2ES2(), new " +
prologNameOpt +
"( drawable.getGL().getGL2ES2() ) ) );");
807 output.println(
" GL gl = drawable.setGL( new " + className +
"( drawable.getGL().getGL2ES2() ) );");
809 output.println(
"</PRE>");
810 output.println(
"*/");
824 output.print(m.getName());
827 output.println(
");");
872 super.preMethodEmissionHook(output);
879 output.println(
" {");
882 output.println(
" }");
889 output.println(
" // Fetch GLContext object for better error checking (if possible)");
891 output.println(
" }");
897 super.postMethodEmissionHook(output);
898 output.println(
" private int checkGLError() {");
899 if (hasImmediateMode) {
900 output.println(
" if (insideBeginEndPair) return GL_NO_ERROR;");
904 output.println(
" }");
906 output.println(
" private void writeGLError(int err, String fmt, Object... args)");
907 output.println(
" {");
908 output.println(
" StringBuilder buf = new StringBuilder();");
909 output.println(
" buf.append(Thread.currentThread().toString());");
910 output.println(
" buf.append(\" glGetError() returned the following error codes after a call to \");");
911 output.println(
" buf.append(String.format(fmt, args));");
912 output.println(
" buf.append(\": \");");
914 output.println(
" // Loop repeatedly to allow for distributed GL implementations,");
915 output.println(
" // as detailed in the glGetError() specification");
916 output.println(
" int recursionDepth = 10;");
917 output.println(
" do {");
918 output.println(
" switch (err) {");
919 output.println(
" case GL_INVALID_ENUM: buf.append(\"GL_INVALID_ENUM \"); break;");
920 output.println(
" case GL_INVALID_VALUE: buf.append(\"GL_INVALID_VALUE \"); break;");
921 output.println(
" case GL_INVALID_OPERATION: buf.append(\"GL_INVALID_OPERATION \"); break;");
922 if (hasGL2ES1StackOverflow) {
923 output.println(
" case GL2ES1.GL_STACK_OVERFLOW: buf.append(\"GL_STACK_OVERFLOW \"); break;");
924 output.println(
" case GL2ES1.GL_STACK_UNDERFLOW: buf.append(\"GL_STACK_UNDERFLOW \"); break;");
926 output.println(
" case GL_OUT_OF_MEMORY: buf.append(\"GL_OUT_OF_MEMORY \"); break;");
927 output.println(
" case GL_NO_ERROR: throw new InternalError(\"Should not be treating GL_NO_ERROR as error\");");
928 output.println(
" default: buf.append(\"Unknown glGetError() return value: \");");
929 output.println(
" }");
930 output.println(
" buf.append(\"( \" + err + \" 0x\"+Integer.toHexString(err).toUpperCase() + \"), \");");
931 output.println(
" } while ((--recursionDepth >= 0) && (err = "
933 +
".glGetError()) != GL_NO_ERROR);");
934 output.println(
" throw new GLException(buf.toString());");
935 output.println(
" }");
936 if (hasImmediateMode) {
937 output.println(
" /** True if the pipeline is inside a glBegin/glEnd pair.*/");
938 output.println(
" private boolean insideBeginEndPair = false;");
941 output.println(
" private void checkContext() {");
942 output.println(
" GLContext currentContext = GLContext.getCurrent();");
943 output.println(
" if (currentContext == null) {");
944 output.println(
" throw new GLException(\"No OpenGL context is current on this thread\");");
945 output.println(
" }");
946 output.println(
" if ((_context != null) && (_context != currentContext)) {");
947 output.println(
" throw new GLException(\"This GL object is being incorrectly used with a different GLContext than that which created it\");");
948 output.println(
" }");
949 output.println(
" }");
950 output.println(
" private GLContext _context;");
955 output.println(
"/**");
956 output.println(
" * <p>");
957 output.println(
" * Composable pipeline which wraps an underlying {@link GL} implementation,");
958 output.println(
" * providing error checking after each OpenGL method call. If an error occurs,");
959 output.println(
" * causes a {@link GLException} to be thrown at exactly the point of failure.");
960 output.println(
" * </p>");
961 output.println(
" * <p>");
962 output.println(
" * Sample code which installs this pipeline:");
963 output.println(
" * <pre>");
964 output.println(
" * gl = drawable.setGL(new DebugGL(drawable.getGL()));");
965 output.println(
" * </pre>");
966 output.println(
" * For automatic instantiation see {@link GLPipelineFactory#create(String, Class, GL, Object[])}");
967 output.println(
" * </p>");
968 output.println(
" */");
978 output.println(
" checkContext();");
989 if (m.getName().equals(
"glBegin")) {
990 output.println(
" insideBeginEndPair = true;");
991 output.println(
" // NOTE: can't check glGetError(); it's not allowed inside glBegin/glEnd pair");
993 if (m.getName().equals(
"glEnd")) {
994 output.println(
" insideBeginEndPair = false;");
997 output.println(
" final int err = checkGLError();");
998 output.println(
" if (err != GL_NO_ERROR) {");
1000 final StringBuilder fmtsb =
new StringBuilder();
1001 final StringBuilder argsb =
new StringBuilder();
1003 fmtsb.append(
"\"%s(");
1004 argsb.append(
"\"").append(m.getName()).append(
"\"");
1005 final Class<?>[] params = m.getParameterTypes();
1006 for (
int i = 0; i < params.length; i++) {
1010 fmtsb.append(
"<").append(params[i].getName()).append(
">");
1011 if (params[i].isArray()) {
1013 }
else if (params[i].equals(
int.
class)) {
1014 fmtsb.append(
" 0x%X");
1015 argsb.append(
", arg").append(i);
1017 fmtsb.append(
" %s");
1018 argsb.append(
", arg").append(i);
1021 fmtsb.append(
")\",");
1025 output.print(
" writeGLError(err, ");
1026 output.println(fmtsb.toString());
1028 output.println(argsb.toString());
1029 output.println(
" }");
1066 super.preMethodEmissionHook(output);
1073 output.println(
" {");
1076 output.println(
" }");
1079 output.print(
" this." + getOutputStreamName());
1080 output.println(
" = " + getOutputStreamName() +
";");
1081 output.println(
" }");
1087 super.postMethodEmissionHook(output);
1088 output.println(
"private PrintStream " + getOutputStreamName() +
";");
1089 output.println(
"private int indent = 0;");
1090 output.println(
"protected String dumpArray(Object obj)");
1091 output.println(
"{");
1092 output.println(
" if (obj == null) return \"[null]\";");
1093 output.println(
" StringBuilder sb = new StringBuilder(\"[\");");
1094 output.println(
" int len = java.lang.reflect.Array.getLength(obj);");
1095 output.println(
" int count = Math.min(len,16);");
1096 output.println(
" for ( int i =0; i < count; i++ ) {");
1097 output.println(
" sb.append(java.lang.reflect.Array.get(obj,i));");
1098 output.println(
" if (i < count-1)");
1099 output.println(
" sb.append(',');");
1100 output.println(
" }");
1101 output.println(
" if ( len > 16 )");
1102 output.println(
" sb.append(\"...\").append(len);");
1103 output.println(
" sb.append(']');");
1104 output.println(
" return sb.toString();");
1105 output.println(
"}");
1106 output.println(
"protected void print(String str)");
1107 output.println(
"{");
1108 output.println(
" " + getOutputStreamName() +
".print(str);");
1109 output.println(
"}");
1110 output.println(
"protected void println(String str)");
1111 output.println(
"{");
1112 output.println(
" " + getOutputStreamName() +
".println(str);");
1113 output.println(
"}");
1114 output.println(
"protected void printIndent()");
1115 output.println(
"{");
1116 output.println(
" for( int i =0; i < indent; i++) {" + getOutputStreamName() +
".print(' ');}");
1117 output.println(
"}");
1122 output.println(
"/**");
1123 output.println(
" * <p>");
1124 output.println(
" * Composable pipeline which wraps an underlying {@link GL} implementation,");
1125 output.println(
" * providing tracing information to a user-specified {@link java.io.PrintStream}");
1126 output.println(
" * before and after each OpenGL method call.");
1127 output.println(
" * </p>");
1128 output.println(
" * <p>");
1129 output.println(
" * Sample code which installs this pipeline:");
1130 output.println(
" * <pre>");
1131 output.println(
" * gl = drawable.setGL(new TraceGL(drawable.getGL(), System.err));");
1132 output.println(
" * </pre>");
1133 output.println(
" * For automatic instantiation see {@link GLPipelineFactory#create(String, Class, GL, Object[])}");
1134 output.println(
" * </p>");
1135 output.println(
" */");
1146 if (m.getName().equals(
"glEnd") || m.getName().equals(
"glEndList")) {
1147 output.println(
" indent-=2;");
1148 output.println(
" printIndent();");
1150 output.println(
" printIndent();");
1153 output.print(
" print(");
1155 output.println(
");");
1166 final Class<?> ret = m.getReturnType();
1167 if (ret != Void.TYPE) {
1168 output.println(
" println(\" = \"+_res);");
1170 output.println(
" println(\"\");");
1173 if (m.getName().equals(
"glBegin"))
1174 output.println(
" indent+=2;");
1177 private String getOutputStreamName() {
1183 final Class<?>[] params = m.getParameterTypes();
1184 output.print(
" \"" + m.getName() +
"(\"");
1185 for (
int i = 0; i < params.length; i++) {
1186 output.print(
"+\"<" + params[i].getName() +
">");
1187 if (params[i].isArray()) {
1189 }
else if (params[i].equals(
int.
class)) {
1190 output.print(
" 0x\"+Integer.toHexString(arg" + i +
").toUpperCase()");
1192 output.print(
" \"+arg" + i);
1194 if (i < params.length - 1) {
1195 output.print(
"+\", \"");
1198 output.print(
"+\")\"");
void preMethodEmissionHook(final PrintWriter output)
Called after the class headers have been generated, but before any method wrappers have been generate...
void postDownstreamCallHook(final PrintWriter output, final PlainMethod pm)
Called after the pipeline has routed the call to the downstream object, but before the calling functi...
void emitClassDocComment(final PrintWriter output)
Emit a Javadoc comment for this pipeline class.
void preDownstreamCallHook(final PrintWriter output, final PlainMethod pm)
Called before the pipeline routes the call to the downstream object.
String getOutputName()
Get the output name for this pipeline class.
boolean emptyMethodAllowed()
void constructorHook(final PrintWriter output)
Emits the constructor for the pipeline; called after the preMethodEmissionHook.
boolean hasPostDownstreamCallHook(final PlainMethod pm)
boolean emptyDownstreamAllowed()
void postMethodEmissionHook(final PrintWriter output)
Called after the method wrappers have been generated, but before the closing parenthesis of the class...
boolean hasPreDownstreamCallHook(final PlainMethod pm)
boolean emptyMethodAllowed()
boolean hasPreDownstreamCallHook(final PlainMethod pm)
boolean hasPostDownstreamCallHook(final PlainMethod pm)
boolean emptyDownstreamAllowed()
void preDownstreamCallHook(final PrintWriter output, final PlainMethod pm)
Called before the pipeline routes the call to the downstream object.
void postMethodEmissionHook(final PrintWriter output)
Called after the method wrappers have been generated, but before the closing parenthesis of the class...
void postDownstreamCallHook(final PrintWriter output, final PlainMethod pm)
Called after the pipeline has routed the call to the downstream object, but before the calling functi...
void preMethodEmissionHook(final PrintWriter output)
Called after the class headers have been generated, but before any method wrappers have been generate...
String getOutputName()
Get the output name for this pipeline class.
void constructorHook(final PrintWriter output)
Emits the constructor for the pipeline; called after the preMethodEmissionHook.
void emitClassDocComment(final PrintWriter output)
Emit a Javadoc comment for this pipeline class.
Emits a Java source file that represents one element of the composable pipeline.
void emitMethodDocComment(final PrintWriter output, final Method m)
abstract void emitClassDocComment(PrintWriter output)
Emit a Javadoc comment for this pipeline class.
String getDownstreamObjectName()
Get the name of the object through which API calls should be routed.
abstract void postDownstreamCallHook(PrintWriter output, PlainMethod pm)
Called after the pipeline has routed the call to the downstream object, but before the calling functi...
Class<?> baseInterfaceClass
abstract boolean hasPostDownstreamCallHook(PlainMethod pm)
void emitBody(final PrintWriter output, final PlainMethod pm)
abstract void preDownstreamCallHook(PrintWriter output, PlainMethod pm)
Called before the pipeline routes the call to the downstream object.
void emitGLIsMethodBody(final PrintWriter output, final PlainMethod plainMethod)
Emits one of the isGL* methods.
abstract boolean emptyMethodAllowed()
void postMethodEmissionHook(final PrintWriter output)
Called after the method wrappers have been generated, but before the closing parenthesis of the class...
void emitSignature(final PrintWriter output, final Method m)
String getBaseInterfaceName()
The name of the class around which this pipeline is being composed.
abstract boolean hasPreDownstreamCallHook(PlainMethod pm)
void emitGLGetMethodBody(final PrintWriter output, final PlainMethod plainMethod)
Emits one of the getGL* methods.
void emitSyntheticGLMethods(final PrintWriter output)
Emits all synthetic GL* methods, but not isGL* nor getGL*.
abstract boolean emptyDownstreamAllowed()
abstract void constructorHook(PrintWriter output)
Emits the constructor for the pipeline; called after the preMethodEmissionHook.
void emit(final Iterator< PlainMethod > methodsToWrap)
String getArgListAsString(final Method m, final boolean includeArgTypes, final boolean includeArgNames)
void preMethodEmissionHook(final PrintWriter output)
Called after the class headers have been generated, but before any method wrappers have been generate...
String getPrologObjectNameOpt()
Get the name of the object which shall be called as a prolog.
abstract String getOutputName()
Get the output name for this pipeline class.
boolean isSyntheticGetGL()
boolean equals(final Object obj)
boolean isSyntheticIsGL()
Method getWrappedMethod()
void preDownstreamCallHook(final PrintWriter output, final PlainMethod pm)
Called before the pipeline routes the call to the downstream object.
boolean hasPreDownstreamCallHook(final PlainMethod pm)
void postDownstreamCallHook(final PrintWriter output, final PlainMethod pm)
Called after the pipeline has routed the call to the downstream object, but before the calling functi...
boolean emptyMethodAllowed()
void postMethodEmissionHook(final PrintWriter output)
Called after the method wrappers have been generated, but before the closing parenthesis of the class...
boolean emptyDownstreamAllowed()
void preMethodEmissionHook(final PrintWriter output)
Called after the class headers have been generated, but before any method wrappers have been generate...
String getOutputName()
Get the output name for this pipeline class.
void constructorHook(final PrintWriter output)
Emits the constructor for the pipeline; called after the preMethodEmissionHook.
void emitClassDocComment(final PrintWriter output)
Emit a Javadoc comment for this pipeline class.
boolean hasPostDownstreamCallHook(final PlainMethod pm)
static String getBaseClassName(final String clazzName)
void emit()
Emit the java source code for the classes that comprise the composable pipeline.
static final void printFunctionCallString(final PrintWriter output, final Method m)
static final int GEN_TRACE
static Method getMethod(final Class<?> clazz, final Method m)
static String getPackageName(final String clazzName)
static final int GEN_CUSTOM
static final int GEN_PROLOG_XOR_DOWNSTREAM
By extra command-line argument: prolog_xor_downstream.
static void main(final String[] args)
BuildComposablePipeline(final int mode, final String outputDir, final String outputPackage, final String outputName, final Class<?> classToComposeAround, final Class<?> classPrologOpt, final Class<?> classDownstream)
static final int GEN_DEBUG
static Class<?> getClass(final String name)
static final int GEN_GL_IDENTITY_BY_ASSIGNABLE_CLASS
By extra command-line argument: gl_identity_by_assignable_class.