Skip to content

Commit

Permalink
Fix an issue that newline character (\n) was not taken into considera…
Browse files Browse the repository at this point in the history
…tion (#108)
  • Loading branch information
cheton committed Jan 13, 2017
1 parent 8bce463 commit c9bd1fe
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 31 deletions.
11 changes: 4 additions & 7 deletions src/app/controllers/Grbl/GrblController.js
Original file line number Diff line number Diff line change
Expand Up @@ -119,11 +119,8 @@ class GrblController {

// Sender
this.sender = new Sender(SP_TYPE_CHAR_COUNTING, {
// Grbl has a 127 character serial receive buffer.
// Use a lower value to deduct the length of regular commands:
// - parser state command: $G\n"
// - current status command: "?"
bufferSize: 120
// Consider periodic commands ('$G\n', '?') to make sure the buffer doesn't overflow
bufferSize: (128 - 4) // Grbl's RX buffer size is 128 bytes
});
this.sender.on('data', (gcode = '') => {
if (this.isClose()) {
Expand Down Expand Up @@ -154,8 +151,8 @@ class GrblController {
// Detect the buffer size if Grbl is set to report the rx buffer (#115)
if (res && res.buf && res.buf.rx) {
const rx = Number(res.buf.rx) || 0;
const spare = 8; // deduct the length of regular commands
const bufferSize = (rx - spare);
// Consider periodic commands ('$G\n', '?') to make sure the buffer doesn't overflow
const bufferSize = (rx - 4);
if (bufferSize > this.sender.sp.bufferSize) {
this.sender.sp.bufferSize = bufferSize;
}
Expand Down
53 changes: 29 additions & 24 deletions src/app/lib/sender.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
/* eslint no-continue: 0 */
import events from 'events';

export const SP_TYPE_SEND_RESPONSE = 0;
export const SP_TYPE_CHAR_COUNTING = 1;

const noop = () => {};
const stripLine = (() => {

const stripComments = (() => {
const re1 = new RegExp(/\s*[%#;].*/g); // Strip everything after %, #, or ; to the end of the line, including preceding spaces
const re2 = new RegExp(/\s*\(.*\)/g); // Remove anything inside the parentheses
return line => line.replace(re1, '').replace(re2, '').trim();
return line => line.replace(re1, '').replace(re2, '');
})();

class SPSendResponse {
Expand Down Expand Up @@ -36,7 +38,7 @@ class SPSendResponse {
class SPCharCounting {
callback = null;
state = {
bufferSize: 120, // Defaults to 120
bufferSize: 128, // Defaults to 128
dataLength: 0,
queue: [],
line: ''
Expand All @@ -62,7 +64,7 @@ class SPCharCounting {
this.callback && this.callback(this);
}
reset() {
this.state.bufferSize = 120; // Defaults to 120
this.state.bufferSize = 128; // Defaults to 128
this.state.dataLength = 0;
this.state.queue = [];
this.state.line = '';
Expand Down Expand Up @@ -137,27 +139,29 @@ class Sender extends events.EventEmitter {
}

while (this.state.sent < this.state.total) {
sp.line = sp.line || stripLine(this.state.lines[this.state.sent]);
// Remove leading and trailing whitespace from both ends of a string
sp.line = sp.line || stripComments(this.state.lines[this.state.sent]).trim();

if (sp.line.length + sp.dataLength >= sp.bufferSize) {
// The newline character (\n) consumed the RX buffer space
if ((sp.line.length > 0) && ((sp.dataLength + sp.line.length + 1) >= sp.bufferSize)) {
break;
}

const line = sp.line;
sp.line = '';

this.state.sent++;
this.emit('change');

if (line.length > 0) {
sp.dataLength += line.length;
sp.queue.push(line.length);
this.emit('data', line);
} else {
this.ack(); // Ack for empty lines
if (sp.line.length === 0) {
this.ack(); // ack empty line

// continue to the next line if empty
continue;
}

// Continue to the next line if empty
const line = sp.line + '\n';
sp.line = '';
sp.dataLength += line.length;
sp.queue.push(line.length);
this.emit('data', line);
}
});
}
Expand All @@ -166,20 +170,21 @@ class Sender extends events.EventEmitter {
if (type === SP_TYPE_SEND_RESPONSE) {
this.sp = new SPSendResponse(options, (sp) => {
while (this.state.sent < this.state.total) {
const line = stripLine(this.state.lines[this.state.sent]);
// Remove leading and trailing whitespace from both ends of a string
const line = stripComments(this.state.lines[this.state.sent]).trim();

this.state.sent++;

this.emit('change');

if (line.length > 0) {
this.emit('data', line);
break;
}
if (line.length === 0) {
this.ack(); // ack empty line

this.ack(); // Ack for empty lines
// continue to the next line if empty
continue;
}

// Continue to the next line if empty
this.emit('data', line + '\n');
break;
}
});
}
Expand Down

0 comments on commit c9bd1fe

Please sign in to comment.