Improved Serial input processing.

Before this patch every byte received from Serial
invokes a String allocation, not really efficient.

Moreover a InputStreamReader is chained on the serial
InputStream to correctly convert bytes into UTF-8
characters.
This commit is contained in:
Cristian Maglie 2014-12-23 12:47:24 +01:00
parent 391d3380ee
commit 63f5d26ae9
2 changed files with 26 additions and 52 deletions

View File

@ -25,9 +25,7 @@
package processing.app;
//import processing.core.*;
import processing.app.debug.MessageConsumer;
import static processing.app.I18n._;
import gnu.io.*;
import java.io.*;
@ -55,15 +53,13 @@ public class Serial implements SerialPortEventListener {
// read buffer and streams
InputStream input;
InputStreamReader input;
OutputStream output;
byte buffer[] = new byte[32768];
int bufferIndex;
int bufferLast;
MessageConsumer consumer;
public Serial(boolean monitor) throws SerialException {
this(Preferences.get("serial.port"),
Preferences.getInteger("serial.debug_rate"),
@ -158,7 +154,7 @@ public class Serial implements SerialPortEventListener {
if (portId.getName().equals(iname)) {
//System.out.println("looking for "+iname);
port = (SerialPort)portId.open("serial madness", 2000);
input = port.getInputStream();
input = new InputStreamReader(port.getInputStream());
output = port.getOutputStream();
port.setSerialPortParams(rate, databits, stopbits, parity);
port.addEventListener(this);
@ -237,62 +233,41 @@ public class Serial implements SerialPortEventListener {
port = null;
}
char serialBuffer[] = new char[4096];
public void addListener(MessageConsumer consumer) {
this.consumer = consumer;
}
synchronized public void serialEvent(SerialPortEvent serialEvent) {
//System.out.println("serial port event"); // " + serialEvent);
//System.out.flush();
//System.out.println("into");
//System.out.flush();
//System.err.println("type " + serialEvent.getEventType());
//System.err.println("ahoooyey");
//System.err.println("ahoooyeysdfsdfsdf");
if (serialEvent.getEventType() == SerialPortEvent.DATA_AVAILABLE) {
//System.out.println("data available");
//System.err.flush();
try {
while (input.available() > 0) {
//if (input.available() > 0) {
//serial = input.read();
//serialEvent();
//buffer[bufferCount++] = (byte) serial;
while (input.ready()) {
synchronized (buffer) {
if (bufferLast == buffer.length) {
byte temp[] = new byte[bufferLast << 1];
System.arraycopy(buffer, 0, temp, 0, bufferLast);
buffer = temp;
}
//buffer[bufferLast++] = (byte) input.read();
if(monitor == true)
System.out.print((char) input.read());
if (this.consumer != null)
this.consumer.message("" + (char) input.read());
/*
System.err.println(input.available() + " " +
((char) buffer[bufferLast-1]));
*/ //}
int n = input.read(serialBuffer);
message(serialBuffer, n);
}
}
//System.out.println("no more");
} catch (IOException e) {
errorMessage("serialEvent", e);
//e.printStackTrace();
//System.out.println("angry");
}
catch (Exception e) {
}
}
//System.out.println("out of");
//System.err.println("out of event " + serialEvent.getEventType());
}
/**
* This method is intended to be redefined by users of Serial class
*
* @param buff
* @param n
*/
protected void message(char buff[], int n) {
// Empty
}
/**
* Returns the number of bytes that have been read from serial
* and are waiting to be dealt with by the user.

View File

@ -18,18 +18,18 @@
package processing.app;
import processing.app.debug.MessageConsumer;
import processing.app.debug.TextAreaFIFO;
import processing.core.*;
import static processing.app.I18n._;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.text.*;
public class SerialMonitor extends JFrame implements MessageConsumer,ActionListener {
public class SerialMonitor extends JFrame implements ActionListener {
private Serial serial;
private String port;
private TextAreaFIFO textArea;
@ -210,8 +210,12 @@ public class SerialMonitor extends JFrame implements MessageConsumer,ActionListe
public void openSerialPort() throws SerialException {
if (serial != null) return;
serial = new Serial(port, serialRate);
serial.addListener(this);
serial = new Serial(port, serialRate) {
@Override
protected void message(char buff[], int n) {
addToUpdateBuffer(buff, n);
}
};
updateTimer.start();
}
@ -226,13 +230,8 @@ public class SerialMonitor extends JFrame implements MessageConsumer,ActionListe
}
}
public void message(String s) {
// TODO: can we pass a byte array, to avoid overhead of String
addToUpdateBuffer(s);
}
private synchronized void addToUpdateBuffer(String s) {
updateBuffer.append(s);
private synchronized void addToUpdateBuffer(char buff[], int n) {
updateBuffer.append(buff, 0, n);
}
private synchronized String consumeUpdateBuffer() {