package com.meatballhat.processing; import java.io.File; import java.io.IOException; import java.io.PrintStream; import processing.app.Base; import processing.app.Preferences; import processing.app.SketchException; import processing.app.RunnerListener; import processing.app.Sketch; import processing.core.PApplet; import processing.mode.java.runner.*; public class ProcessingRunner implements processing.app.RunnerListener { static final String helpArg = "--help"; static final String preprocArg = "--preprocess"; static final String buildArg = "--build"; static final String runArg = "--run"; static final String presentArg = "--present"; static final String sketchArg = "--sketch="; static final String outputArg = "--output="; static final String exportAppletArg = "--export-applet"; static final String exportApplicationArg = "--export-application"; static final String platformArg = "--platform="; static final String bitsArg = "--bits="; static final String preferencesArg = "--preferences="; static final int HELP = -1; static final int PREPROCESS = 0; static final int BUILD = 1; static final int RUN = 2; static final int PRESENT = 3; static final int EXPORT_APPLET = 4; static final int EXPORT_APPLICATION = 5; Sketch sketch; static public void main(String[] args) { // Do this early so that error messages go to the console Base.setCommandLine(); // init the platform so that prefs and other native code is ready to go Base.initPlatform(); // make sure a full JDK is installed Base.initRequirements(); // run static initialization that grabs all the prefs //Preferences.init(null); // launch command line handler new ProcessingRunner(args); } public ProcessingRunner(String[] args) { String sketchFolder = null; String pdePath = null; // path to the .pde file String outputPath = null; String preferencesPath = null; int platformIndex = PApplet.platform; // default to this platform int platformBits = 0; int mode = HELP; for (String arg : args) { if (arg.length() == 0) { // ignore it, just the crappy shell script } else if (arg.equals(helpArg)) { // mode already set to HELP } else if (arg.equals(buildArg)) { mode = BUILD; } else if (arg.equals(runArg)) { mode = RUN; } else if (arg.equals(presentArg)) { mode = PRESENT; } else if (arg.equals(preprocArg)) { mode = PREPROCESS; } else if (arg.equals(exportAppletArg)) { mode = EXPORT_APPLET; } else if (arg.equals(exportApplicationArg)) { mode = EXPORT_APPLICATION; } else if (arg.startsWith(platformArg)) { String platformStr = arg.substring(platformArg.length()); platformIndex = Base.getPlatformIndex(platformStr); if (platformIndex == -1) { complainAndQuit(platformStr + " should instead be " + "'windows', 'macosx', or 'linux'."); } } else if (arg.startsWith(sketchArg)) { sketchFolder = arg.substring(sketchArg.length()); File sketchy = new File(sketchFolder); File pdeFile = new File(sketchy, sketchy.getName() + ".pde"); pdePath = pdeFile.getAbsolutePath(); } else if (arg.startsWith(preferencesArg)) { preferencesPath = arg.substring(preferencesArg.length()); } else if (arg.startsWith(outputArg)) { outputPath = arg.substring(outputArg.length()); } else { complainAndQuit("I don't know anything about " + arg + "."); } } if ((outputPath == null) && (mode == PREPROCESS || mode == BUILD || mode == RUN || mode == PRESENT)) { complainAndQuit("An output path must be specified when using " + preprocArg + ", " + buildArg + ", " + runArg + ", or " + presentArg + "."); } if (mode == HELP) { printCommandLine(System.out); System.exit(0); } // --present --platform=windows "--sketch=/Applications/Processing 0148/examples/Basics/Arrays/Array" --output=test-build File outputFolder = new File(outputPath); if (!outputFolder.exists()) { if (!outputFolder.mkdirs()) { complainAndQuit("Could not create the output folder."); } } // run static initialization that grabs all the prefs // (also pass in a prefs path if that was specified) Preferences.init(preferencesPath); if (sketchFolder == null) { complainAndQuit("No sketch path specified."); } else if (outputPath.equals(pdePath)) { complainAndQuit("The sketch path and output path cannot be identical."); } else if (!pdePath.toLowerCase().endsWith(".pde")) { complainAndQuit("Sketch path must point to the main .pde file."); } else { //Sketch sketch = null; boolean success = false; try { sketch = new Sketch(null, pdePath); if (mode == PREPROCESS) { success = true; // FIXME sketch.preprocess(new File(outputPath)) != null; } else if (mode == BUILD) { success = true; // FIXME sketch.build(outputPath) != null; } else if (mode == RUN || mode == PRESENT) { String className = "BUSTED"; // FIXME sketch.build(outputPath); if (className != null) { success = true; Runner runner = new Runner(null, null); // FIXME new Runner(this, sketch); runner.launch(true); // FIXME runner.launch(className, mode == PRESENT); } else { success = false; } } else if (mode == EXPORT_APPLET) { if (outputPath != null) { success = true; // FIXME sketch.exportApplet(outputPath); } else { String target = sketchFolder + File.separatorChar + "applet"; success = true; // FIXME sketch.exportApplet(target); } } else if (mode == EXPORT_APPLICATION) { if (outputPath != null) { success = true; // FIXME sketch.exportApplication(outputPath, platformIndex, platformBits); } else { //String sketchFolder = // pdePath.substring(0, pdePath.lastIndexOf(File.separatorChar)); outputPath = sketchFolder + File.separatorChar + "application." + Base.getPlatformName(platformIndex); success = true; // FIXME sketch.exportApplication(outputPath, platformIndex, platformBits); } } System.exit(success ? 0 : 1); } catch (SketchException re) { statusError(re); } catch (IOException e) { e.printStackTrace(); System.exit(1); } } } public void statusNotice(String message) { System.err.println(message); } public void statusError(String message) { System.err.println(message); } public void statusError(Exception exception) { if (exception instanceof SketchException) { SketchException re = (SketchException) exception; // format the runner exception like emacs //blah.java:2:10:2:13: Syntax Error: This is a big error message String filename = sketch.getCode(re.getCodeIndex()).getFileName(); int line = re.getCodeLine(); int column = re.getCodeColumn(); if (column == -1) column = 0; // TODO if column not specified, should just select the whole line. System.err.println(filename + ":" + line + ":" + column + ":" + line + ":" + column + ":" + " " + re.getMessage()); } else { exception.printStackTrace(); } } static void complainAndQuit(String lastWords) { printCommandLine(System.err); System.err.println(lastWords); System.exit(1); } static void printCommandLine(PrintStream out) { out.println("Processing " + Base.VERSION_NAME + " rocks the console."); out.println(); out.println("--help Show this help text."); out.println(); out.println("--sketch= Specify the sketch folder (required)"); out.println("--output= Specify the output folder (required and"); out.println(" cannot be the same as the sketch folder.)"); out.println(); out.println("--preprocess Preprocess a sketch into .java files."); out.println("--build Preprocess and compile a sketch into .class files."); out.println("--run Preprocess, compile, and run a sketch."); out.println("--present Preprocess, compile, and run a sketch full screen."); out.println(); out.println("--export-applet Export an applet."); out.println("--export-application Export an application."); out.println("--platform Specify the platform (export to application only)."); out.println(" Should be one of 'windows', 'macosx', or 'linux'."); out.println("--bits Must be specified if libraries are used that are"); out.println(" 32- or 64-bit specific such as the OpenGL library."); out.println(" Otherwise specify 0 or leave it out."); out.println(); out.println("--preferences= Specify a preferences file to use. Required if the"); out.println(" sketch uses libraries found in your sketchbook folder."); } public void startIndeterminate() { } public void stopIndeterminate() { } public void statusHalt() { } public boolean isHalted() { return false; } }