I have a need for my sketch to exit and provide a return code to the program which invoked it. I envision something like: // program is ready to end if( errorDetected ) exit(1); // for an error exit else exit(0);
Is there a way to make this work or something equivalent?
int _exitCode= 0;
Boolean _mouseClick= false;
void setup(){
size(1000,550);
// put instructions on screen
background(0);
println("simulate an error code exit");
fill(255);
textSize(40);
textAlign(CENTER,CENTER);
text( "Normal exit", width/4, height/2 );
text( "Error exit", width*.75, height/2 );
text( "Click on type of exit desired:", width/2, height/4 );
}
void draw(){
if( _mouseClick ){
if( mouseX > width/2 ){
_exitCode= 1;
println("Error exit");
} else println( "Normal exit");
exit();
}
}
void mouseClicked(){
_mouseClick= true;
}
public void exitActual() {
try {
System.exit(_exitCode);
} catch (SecurityException e) {
// don't care about applet security exceptions
}
}
Then export the code.
Invoke it from the command line:
returnCodeTest
Click on-screen to select normal or error exit
echo $?
to access the error code,
It works great. Note that when run from the Processing IDE the error exit causes an odd error in the display area at the bottom of the IDE:
Could not run the sketch (Target VM failed to initialize).
For more information, read revisions.txt and Help ? Troubleshooting.
This message does not appear with a normal exit code (0). It does not show on the export version so I think it can be safely ignored.
You used to be able to detect whether a sketch had been launched from the command line or not using the Sun “external” property – which could help choose which kind of exit to use – but I believe that is no longer the case due to an open bug:
Here is a code example implementing exit( int rtnCode ) overloading exit(). This gives the ability to use either exit() or exit(1) (or any code 0-255 ) interchangeably.
I included the code to test for startup by the PDE or command line (for exported sketches) noting it is said not to work with 3.5.3
// returnCodeTest
// demonstrates an implementation for: exit( int rtnCode );
// To use, copy these subroutines into your sketch:
// void exit( int errorCode)
// public void exitActual()
// boolean detectCommandLineStartup()
// then use either exit(); for a normal exit
// or exit(n); with an integer 0-255 retern/error code
// The return/error code is useful only from command line/bash invocation
/**
Bash/command line:
yourSketchName
(your sketch runs here. When exit():
echo $? # this prints the error/return code
**/
// user must copy this next line and place before void setup() into your sketch
int _exitCode= 0;
Boolean _mouseClick= false;
//============== setup ================================ setup ======================
void setup(){
size(1000,550);
// put instructions on screen. This code is for demo of use, needs not to be imported to your sketch
background(0);
println("simulate an error code exit");
fill(255);
textSize(40);
textAlign(CENTER,CENTER);
text( "Click on type of exit desired:", width/2, height/4 );text( "Normal exit", width/4, height/2 );
text( "Error exit", width*.75, height/2 );
//exit(); // un-comment to test normal exit();
}
//============= draw ================================= draw =======================
void draw(){
// this draw() shows how to ue the error exit(n);
// looks for a mouse click on left or right half of screen to select
// Normal or Error exit.
if( _mouseClick ){
if( mouseX > width/2 ){
println("Error exit");
// exit(1) provides the error/return code
exit(1); // takes the place of exit(); but sends the error code
} else println( "Normal exit");
exit();
}
}
//============= mouseClicked ================================ mouseClicked ========================
void mouseClicked(){
// mouseClicked is for demo of return code. Need not import this to your sketch
// mouseClicked in invoked when user presses any mouse button "click"
_mouseClick= true; // set a flag so draw() can know of the click
}
//============= exit(code) ================================ exit(code) ===========================
void exit( int errorCode){
// exit() with error code. This overloads the normal exit()
// normal exit() remains fully functional
// sending an error code from the commandLine is irrelevant and may cause an error display
// send error code only if startup was direct from "command line"
if( detectCommandLineStartup() ) _exitCode= errorCode;
exit();
}
//============= exitActual ================================== exitActual ==========================
public void exitActual() {
try {
System.exit(_exitCode);
} catch (SecurityException e) {
// don't care about applet security exceptions
}
}
//========== detectCommandLineStartup =================== detectCommandSLinetartup ================
boolean detectCommandLineStartup(){
// this technique is reported to be non-functional in Processing 3.53. Take heed.
// user may substitute "return true" for the entire contents of this function.
boolean commandLine;
String cmd = System.getProperty("sun.java.command");
//println(cmd);
if (cmd.contains("--external")) {
commandLine= false;
} else {
commandLine= true;
}
//println(commandLine);
return commandLine;
}
I am running it on Raspberry Pi 3B with 3.0.1 It works there.
I have on Windows 10 version 3.5.3. When run from the PDE the exit(1) works however there is a red message in the debug area “Could not run the sketch (Target VM failed to initialize).
For more information, read revisions.txt and Help ? Troubleshooting.”
Although the sketch did run fine. I suspect that Processing uses return codes other than 0 to signal a variety of such messages. They can probably be ignored.