package org.reprap.comms;
import javax.swing.JFileChooser;
import javax.swing.filechooser.FileFilter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.OutputStream;
import java.io.PrintStream;
import java.math.BigInteger;
import java.util.Date;
import gnu.io.CommPortIdentifier;
import gnu.io.NoSuchPortException;
import gnu.io.PortInUseException;
import gnu.io.SerialPort;
import gnu.io.UnsupportedCommOperationException;
import org.reprap.utilities.Debug;
import org.reprap.utilities.RrGraphics;
import org.reprap.utilities.ExtensionFileFilter;
import org.reprap.Main;
import org.reprap.Preferences;
import org.reprap.geometry.LayerRules;
public class GCodeReaderAndWriter
{
// Codes for responses from the machine
// A positive number returned is a request for that line number
// to be resent.
private static final long shutDown = -3;
//private static final long startOrNullResponse = -2;
private static final long allSentOK = -1;
private double eTemp;
private double bTemp;
private String[] sdFiles = new String[0];
private double x, y, z, e;
private RrGraphics simulationPlot = null;
private String lastResp;
private boolean nonRunningWarn;
/**
* Stop sending a file (if we are).
*/
private boolean paused = false;
private boolean iAmPaused = false;
/**
* Not quite sure why this is needed...
*/
private boolean alreadyReversed = false;
/**
* The name of the port talking to the RepRap machine
*/
String portName;
/**
* this is if we need to talk over serial
*/
private SerialPort port;
/**
* Flag to tell it we've finished
*/
private boolean exhaustBuffer = false;
/**
* this is for doing easy serial writes
*/
private PrintStream serialOutStream = null;
/**
* this is our read handle on the serial port
*/
private InputStream serialInStream = null;
/**
* The root file name for output (without ".gcode" on the end)
*/
private String opFileName;
/**
* List of file names - used to reverse layer order when layers are done top-down
*/
//private String[] opFileArray;
/**
* Index into opFileArray
*/
//private int opFileIndex;
/**
* How does the first file name in a multiple set end?
*/
private static final String gcodeExtension = ".gcode";
/**
* How does the first file name in a multiple set end?
*/
private static final String firstEnding = "_prologue";
/**
* How does the last file name in a multiple set end?
*/
private static final String lastEnding = "_epilogue";
/**
* Flag for temporary files
*/
private static final String tmpString = "_TeMpOrArY_";
/**
* This is used for file input
*/
private BufferedReader fileInStream = null;
/**
* How long is our G-Code input file (if any).
*/
private long fileInStreamLength = -1;
/**
* This is for file output
*/
private PrintStream fileOutStream = null;
/**
* The last command sent
*/
//private String lastCommand;
/**
* The current linenumber
*/
private long lineNumber;
/**
* The ring buffer that stores the commands for
* possible resend requests.
*/
private int head, tail;
private static final int buflen = 10; // No too long, or pause doesn't work well
private String[] ringBuffer;
private long[] ringLines;
/**
* The transmission to the RepRap machine is handled by
* a separate thread. These control that.
*/
//private boolean threadLock = false;
private Thread bufferThread = null;
private int myPriority;
/**
* Some commands (at the moment just M105 - get temperature and M114 - get coords) generate
* a response. Return that as a string.
*/
private int responsesExpected = 0;
// private boolean responseAvailable = false;
// private String response;
//private boolean sendFileToMachine = false;
public GCodeReaderAndWriter()
{
init();
}
/**
* constructor for when we definitely want to send GCodes to a known file
* @param fos
*/
public GCodeReaderAndWriter(PrintStream fos)
{
init();
fileOutStream = fos;
}
private void init()
{
resetReceived();
paused = false;
iAmPaused = false;
alreadyReversed = false;
ringBuffer = new String[buflen];
ringLines = new long[buflen];
head = 0;
tail = 0;
nonRunningWarn = true;
lineNumber = 0;
//threadLock = false;
exhaustBuffer = false;
responsesExpected = 0;
// responseAvailable = false;
// response = "0000";
//opFileIndex = -1;
lastResp = "";
try
{
portName = Preferences.loadGlobalString("Port(name)");
} catch (Exception ex)
{
Debug.e("Cannot load preference Port(name).");
portName = "stdout";
}
openSerialConnection(portName);
myPriority = Thread.currentThread().getPriority();
bufferThread = null;
}
private void nonRunningWarning(String s)
{
if(nonRunningWarn)
Debug.d("GCodeReaderAndWriter(): attempt to " + s + " a non-running output buffer. Further attempts will not be reported.");
nonRunningWarn = false;
}
public boolean buildingFromFile()
{
return fileInStream != null;
}
public boolean savingToFile()
{
return fileOutStream != null;
}
/**
* Stop the printer building.
* This _shouldn't_ also stop it being controlled interactively.
*/
public void pause()
{
paused = true;
// while(!bufferEmpty())
// {
// //Debug.e("Waiting for buffer to empty.");
// sleep (131);
// }
}
/**
* Resume building.
*
*/
public void resume()
{
paused = false;
}
/**
* Are we paused?
* @return
*/
public boolean iAmPaused()
{
return iAmPaused;
}
/**
* Send a GCode file to the machine if that's what we have to do, and
* return true. Otherwise return false.
*
*/
public Thread filePlay()
{
if(fileInStream == null)
{
// Not playing a file...
return null;
}
simulationPlot = null;
if(Preferences.simulate())
simulationPlot = new RrGraphics("RepRap building simulation");
// if(bufferThread == null)
// {
// Debug.e("GCodeWriter: attempt to write to non-existent buffer.");
// return true;
// }
// Launch a thread to run through the file, so we can return control
// to the user
Thread playFile = new Thread()
{
public void run()
{
Thread.currentThread().setName("GCode file printer");
String line;
long bytes = 0;
double fractionDone = 0;
try
{
while ((line = fileInStream.readLine()) != null)
{
bufferQueue(line);
bytes += line.length();
fractionDone = (double)bytes/(double)fileInStreamLength;
setFractionDone(fractionDone, -1, -1);
while(paused)
{
iAmPaused = true;
//Debug.e("Waiting for pause to end.");
sleep(239);
}
iAmPaused = false;
}
fileInStream.close();
} catch (Exception e)
{
Debug.e("Error printing file: " + e.toString());
e.printStackTrace();
}
}
};
playFile.start();
return playFile;
}
public void setFractionDone(double fractionDone, int layer, int outOf)
{
org.reprap.gui.botConsole.BotConsoleFrame.getBotConsoleFrame().setFractionDone(fractionDone, layer, outOf);
}
/**
* Wrapper for Thread.sleep()
* @param millis
*/
public void sleep(int millis)
{
try
{
Thread.sleep(millis);
} catch (Exception ex)
{}
}
/**
* Anything in the buffer? (NB this still works if we aren't
* using the buffer as then head == tail == 0 always).
* @return
*/
// public boolean bufferEmpty()
// {
// return head == tail;
// }
/**
* Between layers nothing will be queued. Use the next two
* functions to slow and speed the buffer's spinning.
*
*/
public void slowBufferThread()
{
if(bufferThread != null)
bufferThread.setPriority(1);
}
public void speedBufferThread()
{
if(bufferThread != null)
bufferThread.setPriority(myPriority);
}
/**
* Force the output stream - use with caution
* @param fos
*/
public void forceOutputFile(PrintStream fos)
{
fileOutStream = fos;
}
/**
* Compute the checksum of a GCode string.
* @param cmd
* @return
*/
private String checkSum(String cmd)
{
int cs = 0;
for(int i = 0; i < cmd.length(); i++)
cs = cs ^ cmd.charAt(i);
cs &= 0xff;
return "*" + cs;
}
private void ringAdd(long ln, String cmd)
{
head++;
if(head >= ringBuffer.length)
head = 0;
ringBuffer[head] = cmd;
ringLines[head] = ln;
}
private String ringGet(long ln)
{
int h = head;
do
{
if(ringLines[h] == ln)
return ringBuffer[h];
h--;
if(h < 0)
h = ringBuffer.length - 1;
} while(h != head);
Debug.e("ringGet: line " + ln + " not stored");
return "";
}
/**
* Send a command to the machine. Return true if a response is expected;
* false if not.
* @param cmd
* @return
*/
private boolean sendLine(String cmd)
{
int com = cmd.indexOf(';');
if(com > 0)
cmd = cmd.substring(0, com);
if(com != 0)
{
cmd = cmd.trim();
if(cmd.length() > 0)
{
ringAdd(lineNumber, cmd);
cmd = "N" + lineNumber + " " + cmd + " ";
cmd += checkSum(cmd);
serialOutStream.print(cmd + "\n");
serialOutStream.flush();
Debug.c("G-code: " + cmd + " dequeued and sent");
return true;
}
return false;
}
Debug.c("G-code: " + cmd + " not sent");
if(cmd.startsWith(";#!LAYER:"))
{
int l = Integer.parseInt(cmd.substring(cmd.indexOf(" ") + 1, cmd.indexOf("/")));
int o = Integer.parseInt(cmd.substring(cmd.indexOf("/") + 1));
setFractionDone(-1, l, o+1);
}
return false;
}
/**
* Queue a command.
*/
private void bufferQueue(String cmd) throws Exception
{
if(simulationPlot != null)
simulationPlot.add(cmd);
if(serialOutStream == null)
{
nonRunningWarning("queue: \"" + cmd + "\" to");
return;
}
if(sendLine(cmd))
{
long resp = waitForResponse();
if(resp == shutDown)
{
throw new Exception("The RepRap machine has flagged a hard error!");
} else if (resp == allSentOK)
{
lineNumber++;
return;
} else // Must be a re-send line number
{
long gotTo = lineNumber;
lineNumber = resp;
String rCmd = " ";
while(lineNumber <= gotTo && !rCmd.contentEquals(""))
{
rCmd = ringGet(lineNumber);
if(sendLine(rCmd))
{
resp = waitForResponse();
if (resp == allSentOK)
return;
if(resp == shutDown)
throw new Exception("The RepRap machine has flagged a hard error!");
}
}
}
}
Debug.d("bufferQueue(): did not send " + cmd);
}
private void resetReceived()
{
eTemp = Double.NEGATIVE_INFINITY;
bTemp = Double.NEGATIVE_INFINITY;
x = Double.NEGATIVE_INFINITY;
y = Double.NEGATIVE_INFINITY;
z = Double.NEGATIVE_INFINITY;
e = Double.NEGATIVE_INFINITY;
}
/**
* Pick out a value from the returned string
* @param s
* @param coord
* @return
*/
private double parseReturnedValue(String s, String cue)
{
int i = s.indexOf(cue);
if(i < 0)
return Double.NEGATIVE_INFINITY;
i += cue.length();
String ss = s.substring(i);
int j = ss.indexOf(" ");
if(j < 0)
return Double.parseDouble(ss);
else
return Double.parseDouble(ss.substring(0, j));
}
/**
* Pick up a list of comma-separated names and transliterate them to lower-case
* This code allows file names to have spaces in, but this is ***highly*** depricated.
* @param s
* @param cue
* @return
*/
private String[] parseReturnedNames(String s, String cue)
{
int i = s.indexOf(cue);
if(i < 0)
return new String[0];
i += cue.length();
String ss = s.substring(i);
int j = ss.indexOf(",}");
if(j < 0)
ss = ss.substring(0,ss.indexOf("}")); // Must end in "name}"
else
ss = ss.substring(0,j); // Must end in "name,}"
String[] result = ss.split(",");
for(i = 0; i < result.length; i++)
result[i] = result[i].toLowerCase();
return result;
}
/**
* If the machine has just returned an extruder temperature, return its value
* @return
*/
public double getETemp()
{
if(serialOutStream == null)
{
nonRunningWarning("getETemp() from ");
return 0;
}
if(eTemp == Double.NEGATIVE_INFINITY)
{
Debug.d("GCodeReaderAndWriter.getETemp() - no value stored!");
return 0;
}
return eTemp;
}
/**
* If the machine has just returned a bed temperature, return its value
* @return
*/
public double getBTemp()
{
if(serialOutStream == null)
{
nonRunningWarning("getBTemp() from ");
return 0;
}
if(bTemp == Double.NEGATIVE_INFINITY)
{
Debug.d("GCodeReaderAndWriter.getBTemp() - no value stored!");
return 0;
}
return bTemp;
}
public String[] getSDFileNames()
{
if(serialOutStream == null)
{
nonRunningWarning("getSDFileNames() from ");
return sdFiles;
}
if(sdFiles.length <= 0)
Debug.e("GCodeReaderAndWriter.getSDFileNames() - no value stored!");
return sdFiles;
}
/**
* If the machine has just returned an x coordinate, return its value
* @return
*/
public double getX()
{
if(serialOutStream == null)
{
nonRunningWarning("getX() from ");
return 0;
}
if(x == Double.NEGATIVE_INFINITY)
{
Debug.e("GCodeReaderAndWriter.getX() - no value stored!");
return 0;
}
return x;
}
/**
* If the machine has just returned a y coordinate, return its value
* @return
*/
public double getY()
{
if(serialOutStream == null)
{
nonRunningWarning("getY() from ");
return 0;
}
if(y == Double.NEGATIVE_INFINITY)
{
Debug.e("GCodeReaderAndWriter.getY() - no value stored!");
return 0;
}
return y;
}
/**
* If the machine has just returned a z coordinate, return its value
* @return
*/
public double getZ()
{
if(serialOutStream == null)
{
nonRunningWarning("getZ() from ");
return 0;
}
if(z == Double.NEGATIVE_INFINITY)
{
Debug.e("GCodeReaderAndWriter.getZ() - no value stored!");
return 0;
}
return z;
}
/**
* If the machine has just returned an e coordinate, return its value
* @return
*/
public double getE()
{
if(serialOutStream == null)
{
nonRunningWarning("getE() from ");
return 0;
}
if(e == Double.NEGATIVE_INFINITY)
{
Debug.e("GCodeReaderAndWriter.getE() - no value stored!");
return 0;
}
return e;
}
public String lastResponse()
{
return lastResp;
}
public String toHex(String arg)
{
return String.format("%x", new BigInteger(1, arg.getBytes(/*YOUR_CHARSET?*/)));
}
/**
* Parse the string sent back from the RepRap machine.
*
*/
private long waitForResponse()
{
int i;
String resp = "";
long result = allSentOK;
String lns;
resetReceived();
boolean goAgain;
Date timer = new Date();
long startWait = timer.getTime();
long timeNow;
long increment = 2000;
long longWait = 10*60*1000; // 10 mins...
for(;;)
{
timeNow = timer.getTime() - startWait;
if(timeNow > increment)
{
Debug.d("GCodeReaderAndWriter().waitForResponse(): waited for " + timeNow/1000 + " seconds.");
increment = 2*increment;
}
if(timeNow > longWait)
{
Debug.e("GCodeReaderAndWriter().waitForResponse(): waited for " + timeNow/1000 + " seconds.");
try {
queue("M0 ;shut RepRap down");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
try
{
i = serialInStream.read();
} catch (Exception e)
{
i = -1;
}
//anything found?
if (i >= 0)
{
char c = (char)i;
//is it at the end of the line?
if (c == '\n' || c == '\r')
{
goAgain = false;
if (resp.startsWith("start") || resp.contentEquals("")) // Startup or null string...
{
resp = "";
goAgain = true;
} else if (resp.startsWith("!!")) // Horrible hard fault?
{
result = shutDown;
Debug.e("GCodeWriter.waitForResponse(): RepRap hard fault! RepRap said: " + resp);
} else if (resp.startsWith("//")) // immediate DEBUG "comment" from the firmware ( like C++ )
{
Debug.d("GCodeWriter.waitForResponse(): " + resp);
resp = "";
goAgain = true;
} else if (resp.endsWith("\\")) // lines ending in a single backslash are considered "continued" to the next line, like "C"
{
// Debug.d("GCodeWriter.waitForResponse(): " + resp);
// resp = ""; don't clear the previuos response...
goAgain = true; // but do "go again"
} else if (resp.startsWith("rs")) // Re-send request?
{
lns = resp.substring(3);
int sp = lns.indexOf(" ");
if(sp > 0)
lns = lns.substring(0, sp);
result = Long.parseLong(lns);
Debug.e("GCodeWriter.waitForResponse() - request to resend from line " + result +
". RepRap said: " + resp);
} else if (!resp.startsWith("ok")) // Must be "ok" if not those - check
{
Debug.e("GCodeWriter.waitForResponse() - dud response from RepRap:" + resp + " (hex: " + toHex(resp) + ")");
result = lineNumber; // Try to send the last line again
}
// Have we got temperatures and/or coordinates and/or filenames?
eTemp = parseReturnedValue(resp, " T:");
bTemp = parseReturnedValue(resp, " B:");
sdFiles = parseReturnedNames(resp, " Files: {");
if(resp.indexOf(" C:") >= 0)
{
x = parseReturnedValue(resp, " X:");
y = parseReturnedValue(resp, " Y:");
z = parseReturnedValue(resp, " Z:");
e = parseReturnedValue(resp, " E:");
}
if(!goAgain)
{
Debug.c("Response: " + resp);
lastResp = resp.substring(2);
return result;
}
} else
resp += c;
}
}
}
/**
* Send a G-code command to the machine or into a file.
* @param cmd
*/
public void queue(String cmd) throws Exception
{
//trim it and cleanup.
cmd = cmd.trim();
cmd = cmd.replaceAll(" ", " ");
if(fileOutStream != null)
{
fileOutStream.println(cmd);
Debug.c("G-code: " + cmd + " written to file");
} else
bufferQueue(cmd);
}
/**
* Copy a file of G Codes straight to output - generally used for canned cycles
*/
public void copyFile(String fileName)
{
File f = new File(fileName);
if (!f.exists())
{
Debug.e("GCodeReaderAndWriter().copyFile: can't find file " + fileName);
return;
}
try
{
FileReader fr = new FileReader(f);
BufferedReader br = new BufferedReader(fr);
String s;
while((s = br.readLine()) != null)
{
queue(s);
}
fr.close();
} catch (Exception e)
{
Debug.e("GCodeReaderAndWriter().copyFile: exception reading file " + fileName);
return;
}
}
private void openSerialConnection(String portName)
{
int baudRate = 19200;
serialInStream = null;
serialOutStream = null;
portName = portName.trim();
//open our port.
Debug.d("GCode opening port " + portName);
Main.setRepRapPresent(false);
try
{
CommPortIdentifier commId = CommPortIdentifier.getPortIdentifier(portName);
port = (SerialPort)commId.open(portName, 30000);
} catch (NoSuchPortException e) {
Debug.d("Can't open port: " + portName + " - no RepRap attached.");
return;
}
catch (PortInUseException e){
Debug.e("Port '" + portName + "' is already in use.");
return;
}
Main.setRepRapPresent(true);
//get our baudrate
try {
baudRate = Preferences.loadGlobalInt("BaudRate");
}
catch (IOException e){}
// Workround for javax.comm bug.
// See http://forum.java.sun.com/thread.jspa?threadID=673793
// FIXME: jvandewiel: is this workaround also needed when using the RXTX library?
try {
port.setSerialPortParams(baudRate,
SerialPort.DATABITS_8,
SerialPort.STOPBITS_1,
SerialPort.PARITY_NONE);
}
catch (UnsupportedCommOperationException e) {
Debug.d("An unsupported comms operation was encountered.\n" + e.toString());
return;
}
// Wait for baud rate change to take effect
try {Thread.sleep(1000);} catch (Exception e) {}
try {
port.setFlowControlMode(SerialPort.FLOWCONTROL_NONE);
} catch (Exception e) {
// Um, Linux USB ports don't do this. What can I do about it?
}
try {
port.enableReceiveTimeout(1);
} catch (UnsupportedCommOperationException e) {
Debug.d("Read timeouts unsupported on this platform");
}
//create our steams
try {
OutputStream writeStream = port.getOutputStream();
serialInStream = port.getInputStream();
serialOutStream = new PrintStream(writeStream);
} catch (IOException e) {
Debug.e("GCodeWriter: Error opening serial port stream.");
serialInStream = null;
serialOutStream = null;
return;
}
//arduino bootloader skip.
//Debug.d("Attempting to initialize Arduino/Sanguino");
try {Thread.sleep(1000);} catch (Exception e) {}
//for(int i = 0; i < 10; i++)
// serialOutStream.write('0');
try {Thread.sleep(1000);} catch (Exception e) {}
//serialOutStream.write('\n');
return;
}
public String loadGCodeFileForMaking()
{
JFileChooser chooser = new JFileChooser();
FileFilter filter;
filter = new ExtensionFileFilter("G Code file to be read", new String[] { "gcode" });
chooser.setFileFilter(filter);
chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
//chooser.setCurrentDirectory();
int result = chooser.showOpenDialog(null);
if (result == JFileChooser.APPROVE_OPTION)
{
String name = chooser.getSelectedFile().getAbsolutePath();
try
{
Debug.d("opening: " + name);
fileInStreamLength = chooser.getSelectedFile().length();
fileInStream = new BufferedReader(new FileReader(chooser.getSelectedFile()));
return chooser.getSelectedFile().getName();
} catch (FileNotFoundException e)
{
Debug.e("Can't read file " + name);
fileInStream = null;
return null;
}
} else
{
Debug.e("Can't read file.");
fileInStream = null;
}
return null;
}
public String setGCodeFileForOutput(boolean topDown, String fileRoot)
{
File defaultFile = new File(fileRoot + ".gcode");
JFileChooser chooser = new JFileChooser();
chooser.setSelectedFile(defaultFile);
FileFilter filter;
filter = new ExtensionFileFilter("G Code file to write to", new String[] { "gcode" });
chooser.setFileFilter(filter);
chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
opFileName = null;
//opFileArray = null;
//opFileIndex = -1;
int result = chooser.showSaveDialog(null);
if (result == JFileChooser.APPROVE_OPTION)
{
opFileName = chooser.getSelectedFile().getAbsolutePath();
if(opFileName.endsWith(gcodeExtension))
opFileName = opFileName.substring(0, opFileName.length() - 6);
try
{
boolean doe = false;
String fn = opFileName;
if(topDown)
{
//opFileIndex = 0;
fn += firstEnding;
fn += tmpString;
doe = true;
}
fn += gcodeExtension;
Debug.d("opening: " + fn);
File fl = new File(fn);
if(doe) fl.deleteOnExit();
FileOutputStream fileStream = new FileOutputStream(fl);
fileOutStream = new PrintStream(fileStream);
String shortName = chooser.getSelectedFile().getName();
if(!shortName.endsWith(gcodeExtension))
shortName += gcodeExtension;
return shortName;
} catch (FileNotFoundException e)
{
//opFileArray = null;
//opFileIndex = -1;
Debug.e("Can't write to file '" + opFileName);
opFileName = null;
fileOutStream = null;
}
}
else
{
fileOutStream = null;
}
return null;
}
/**
* Start the production run
* (as opposed to driving the machine interactively).
*/
public void startRun()
{
if(fileOutStream != null)
{
// Exhause buffer before we start.
if(bufferThread != null)
{
exhaustBuffer = true;
while(exhaustBuffer) sleep(200);
}
bufferThread = null;
head = 0;
tail = 0;
}
}
public void startingLayer(LayerRules lc)
{
// If no filename or the index is not set, forget about the start layer. - Vik, 23-Feb-2009
//if((opFileIndex < 0) || (opFileName == null))
// return;
//if(opFileArray == null)
// if(lc.getPrologueFileName() == null)
// {
// if(lc.getTopDown())
// {
// //opFileIndex = 0;
// //opFileArray = new String[lc.getMachineLayerMax() + 3];
// //opFileArray[opFileIndex] = opFileName + firstEnding + tmpString + gcodeExtension;
// lc.setPrologueFileName(opFileName + firstEnding + tmpString + gcodeExtension);
// finishedLayer(lc);
// }
// }
//opFileArray[opFileIndex] = opFileName + lc.getMachineLayer() + tmpString + gcodeExtension;
lc.setLayerFileName(opFileName + lc.getMachineLayer() + tmpString + gcodeExtension);
//System.out.println("Name out: " + lc.getLayerFileName());
if(!lc.getReversing())
try
{
//File fl = new File(opFileArray[opFileIndex]);
File fl = new File(lc.getLayerFileName());
fl.deleteOnExit();
FileOutputStream fileStream = new FileOutputStream(fl);
fileOutStream = new PrintStream(fileStream);
//System.out.println("Opening: " + lc.getLayerFileName());
} catch (Exception e)
{
//Debug.e("Can't write to file " + opFileArray[opFileIndex]);
Debug.e("Can't write to file " + lc.getLayerFileName());
}
}
public void finishedLayer(LayerRules lc)
{
//if(opFileArray == null)
//if(lc.getPrologueFileName() == null)
//return;
//System.out.println("Name close: " + lc.getLayerFileName());
if(!lc.getReversing())
{
//System.out.println("Closing: " + lc.getLayerFileName());
fileOutStream.close();
}
//opFileIndex++;
}
public void startingEpilogue(LayerRules lc)
{
//if(opFileArray == null)
//if(lc.getPrologueFileName() == null)
// return;
//opFileArray[opFileIndex] = opFileName + lastEnding + tmpString + gcodeExtension;
//lc.setEpilogueFileName(opFileName + lastEnding + tmpString + gcodeExtension);
// try
// {
// //File fl = new File(opFileArray[opFileIndex]);
// File fl = new File(lc.getEpilogueFileName());
// fl.deleteOnExit();
// FileOutputStream fileStream = new FileOutputStream(fl);
// fileOutStream = new PrintStream(fileStream);
// } catch (Exception e)
// {
// //Debug.e("Can't write to file " + opFileArray[opFileIndex]);
// Debug.e("Can't write to file " + lc.getEpilogueFileName());
// }
}
/**
* All done.
*
*/
public void finish(LayerRules lc)
{
Debug.d("disposing of GCodeReaderAndWriter.");
//lc.reverseLayers(opFileName + gcodeExtension);
// // Wait for the ring buffer to be exhausted
// if(fileOutStream == null && bufferThread != null)
// {
// exhaustBuffer = true;
// while(exhaustBuffer) sleep(200);
// }
try
{
if (serialInStream != null)
serialInStream.close();
if (serialOutStream != null)
serialOutStream.close();
if (fileInStream != null)
fileInStream.close();
//if (fileOutStream != null)
// fileOutStream.close();
} catch (Exception e) {}
}
public String getOutputFilename()
{
return opFileName + gcodeExtension;
}
}