answering (4), why does JSL, after the RunProgram call, run too soon?
RunProgram can launch several ways. Since you provided a ReadFunction, RunProgram will return immediately and hands back a RunProgram object that has methods you can test:
While( run_program << canread | run_program << canwrite | !(run_program << isreadeof),
// show(run_program<<canread,run_program<<canwrite,run_program<<isreadeof);
Wait( .1 )
);
The example above depends on the external program closing the connection when it terminates. It waits briefly after each check, then looks again to see if the program is still around, waiting to read from JMP, write to JMP, or just has not closed the connection that JMP might be able to read from later. The commented show() will help figure it out.
A simpler approach is to leave out the ReadFunction. Then RunProgram just returns the text the external program printed, after the external program finishes. You can then process the returned text and any files the external program created using JSL (to open windows, make graphs, etc.)
The complicated way: If you are expecting JMP to show updates in JMP-owned windows while the external program runs, you'll need to process the ReadFunction text with JSL that reacts to the text. This is complicated because text can arrive a few characters at a time; you'll need a strategy for collecting the bits of text into a JSL string and determining when the text command is complete and not throwing away part of the next text command. The data for JMP to display can either be in the text or in a file, but the received text command is how you know the data is available. (I don't recommend watching for a file to become available because you might start using a file that is only half-written by the external program.)
Writing the ReadFunction to work well: try something like this:
while(this<<canread, // untested, approximately correct code...
buffer = buffer || (this<<read);
wait(0);
buffer = process(buffer)
)
the process function uses your strategy to determine if the buffer holds a complete text command(s), processes the command(s), removes the command(s) and returns whatever is left in the buffer that will become part of the next text command. Note that process(buffer) should return the entire buffer unchanged if the command is not complete and should process all the text commands in the buffer that are complete.
And, in all of the above complicated part, I've completely ignored how the external program has to be written to generate the printed output that JMP can interpret as text commands. And what a strategy might look like: new-lines or commas or etc to delimit complete commands.
Craige