Skip to content

Commit 2c36e24

Browse files
committed
working on leaving the Jython process running
1 parent 29246d8 commit 2c36e24

File tree

4 files changed

+105
-33
lines changed

4 files changed

+105
-33
lines changed
File renamed without changes.
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
package info.sansgills.mode.python;
2+
3+
import java.awt.Point;
4+
import java.io.BufferedReader;
5+
import java.io.InputStream;
6+
import java.io.InputStreamReader;
7+
import java.io.OutputStream;
8+
9+
import processing.app.exec.StreamRedirectThread;
10+
import processing.core.PApplet;
11+
12+
/**
13+
*
14+
* The glue between the PDE process and the sketch process
15+
* Handles sending messages to and recieving messages from
16+
*
17+
*/
18+
public class Communicator {
19+
private PythonEditor editor;
20+
private Process sketchProcess;
21+
22+
private StreamRedirectThread outThread;
23+
private MessageReceiverThread errThread;
24+
25+
private OutputStream toSketch;
26+
27+
public Communicator (Process sketchProcess, PythonEditor editor){
28+
this.sketchProcess = sketchProcess;
29+
this.editor = editor;
30+
31+
outThread = new StreamRedirectThread("JVM Stdout Reader", sketchProcess.getInputStream(), System.out);
32+
errThread = new MessageReceiverThread(sketchProcess.getErrorStream(), editor);
33+
34+
toSketch = sketchProcess.getOutputStream();
35+
36+
outThread.start();
37+
errThread.start();
38+
}
39+
40+
public void close(){
41+
errThread.running = false;
42+
errThread = null;
43+
outThread = null;
44+
}
45+
46+
47+
//private class to handle doing things when the sketch process sends us a message via system.err
48+
private class MessageReceiverThread extends Thread{
49+
PythonEditor editor;
50+
BufferedReader messageReader;
51+
52+
public boolean running;
53+
54+
public MessageReceiverThread(InputStream messageStream, PythonEditor editor){
55+
this.messageReader = new BufferedReader(new InputStreamReader(messageStream));
56+
this.editor = editor;
57+
this.running = true;
58+
}
59+
60+
public void run() {
61+
try {
62+
String currentLine;
63+
64+
// continually read messages
65+
while ((currentLine = messageReader.readLine()) != null && running) {
66+
if (currentLine.indexOf(PApplet.EXTERNAL_STOP) == 0) {
67+
// sketch telling us it stopped
68+
editor.internalCloseRunner();
69+
return;
70+
}else if (currentLine.indexOf(PApplet.EXTERNAL_MOVE) == 0) {
71+
//sketch telling us it moved
72+
String nums = currentLine.substring(currentLine.indexOf(' ') + 1).trim();
73+
int space = nums.indexOf(' ');
74+
int left = Integer.parseInt(nums.substring(0, space));
75+
int top = Integer.parseInt(nums.substring(space + 1));
76+
editor.setSketchLocation(new Point(left, top));
77+
return;
78+
}else{
79+
System.err.println(currentLine);
80+
}
81+
}
82+
} catch (Exception e) {}
83+
}
84+
}
85+
}

src/info/sansgills/mode/python/PythonRunner.java

Lines changed: 3 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,7 @@ public class PythonRunner {
2727
Process sketchProcess; // the process we create
2828

2929
// Threads to redirect output / error streams from process to us
30-
Thread errThread = null;
31-
Thread outThread = null;
30+
Communicator communicator;
3231

3332
public PythonRunner(PythonBuild build, PythonEditor editor) {
3433
this.build = build;
@@ -164,10 +163,9 @@ private void exec(final String[] args){
164163
new Thread(new Runnable(){
165164
public void run(){
166165
sketchProcess = PApplet.exec(args);
167-
attach(); //TODO dirty hack
166+
communicator = new Communicator(sketchProcess, editor);
168167
try{
169168
int result = sketchProcess.waitFor();
170-
System.out.println("result: "+result);
171169
}catch(InterruptedException e){
172170
System.out.println("error:");
173171
e.printStackTrace();
@@ -176,26 +174,11 @@ public void run(){
176174
}).start();
177175
}
178176

179-
/*
180-
* Create redirect threads for stdout, stderr, etc.
181-
*
182-
* TODO handle special err. messages
183-
*/
184-
private void attach(){
185-
// piggybacking off of Java Mode's redirect for now
186-
outThread = new StreamRedirectThread("JVM stdout Reader",
187-
sketchProcess.getInputStream(), System.out);
188-
errThread = new StreamRedirectThread("JVM stderr Reader",
189-
sketchProcess.getErrorStream(), System.err);
190-
191-
outThread.start();
192-
errThread.start();
193-
}
194-
195177
/*
196178
* Kill the code.
197179
*/
198180
public void close() {
181+
communicator.close();
199182
if(sketchProcess != null){
200183
sketchProcess.destroy();
201184
sketchProcess = null;

src/info/sansgills/mode/python/wrapper/ProcessingJythonWrapper.java

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package info.sansgills.mode.python.wrapper;
22

3-
import java.io.File;
43
import java.util.Arrays;
54
import java.util.Scanner;
65

@@ -31,7 +30,10 @@ public class ProcessingJythonWrapper {
3130
//EVERYTHING IS STATIC
3231

3332
//Read in prepend.py from jar (this is the only one-liner to read in a stream, don't you love java)
34-
static final String prepend = new Scanner(ProcessingJythonWrapper.class.getResourceAsStream("prepend.py")).useDelimiter("\\A").next();
33+
static final String prepend;
34+
static{
35+
prepend = new Scanner(ProcessingJythonWrapper.class.getResourceAsStream("prepend.py")).useDelimiter("\\A").next();
36+
}
3537

3638
static final String[] sketchFunctions = { "setup", "draw", "mousePressed",
3739
"mouseReleased", "mouseClicked", "mouseWheel", "mouseMoved",
@@ -48,26 +50,28 @@ public class ProcessingJythonWrapper {
4850
* First argument is the path to the script; the rest are things to pass to PApplet.
4951
*
5052
*/
51-
public static void main(String[] args) {
53+
public static void main(String[] args) {
5254
String scriptPath = args[0];
5355
String[] params = Arrays.copyOfRange(args, 1, args.length);
56+
prepare();
5457
run(scriptPath, params);
5558
}
5659

60+
public static void prepare() {
61+
interp = new InteractiveConsole(); // create jython environment
62+
sys = Py.getSystemState(); // python 'sys' variable
63+
64+
// give jython the packages we need
65+
// TODO libraries?
66+
PySystemState.add_package("info.sansgills.mode.python.wrapper");
67+
PySystemState.add_package("processing.core");
68+
PySystemState.add_package("processing.opengl");
69+
}
70+
5771
/*
5872
* Run.
5973
*/
6074
public static void run(String scriptPath, String[] params){
61-
interp = new InteractiveConsole(); // create jython environment
62-
sys = Py.getSystemState(); // python 'sys' variable
63-
64-
65-
// give jython the packages we need
66-
// TODO libraries?
67-
sys.add_package("info.sansgills.mode.python.wrapper");
68-
sys.add_package("processing.core");
69-
sys.add_package("processing.opengl");
70-
7175
try {
7276
//run prepend.py
7377
interp.exec(prepend);

0 commit comments

Comments
 (0)