From c49df23fbdfd9f5f628ed169aba5fdb765616b19 Mon Sep 17 00:00:00 2001 From: odaki Date: Tue, 21 Jun 2022 21:52:19 +0900 Subject: [PATCH] Command script regex fix. Command queue fix. pull the Experimental (#534) --- src/candle/frmmain.cpp | 70 +++++++++++++++++++++++++----------------- src/candle/frmmain.h | 28 +++++++++++++++-- 2 files changed, 67 insertions(+), 31 deletions(-) diff --git a/src/candle/frmmain.cpp b/src/candle/frmmain.cpp index 540ec46f..caacf580 100644 --- a/src/candle/frmmain.cpp +++ b/src/candle/frmmain.cpp @@ -899,26 +899,31 @@ void frmMain::openPort() } } -void frmMain::sendCommand(QString command, int tableIndex, bool showInConsole, bool queue) +frmMain::SendCommandResult frmMain::sendCommand(QString command, int tableIndex, bool showInConsole, bool wait) { - if (!m_serialPort.isOpen() || !m_resetCompleted) return; + if (!m_serialPort.isOpen() || !m_resetCompleted) return SendDone; - // Commands queue - if (queue || (bufferLength() + command.length() + 1) > BUFFERLENGTH) { - CommandQueue cq; + // Check command + if (command.isEmpty()) return SendEmpty; - cq.command = command; - cq.tableIndex = tableIndex; - cq.showInConsole = showInConsole; - cq.queue = queue; - - m_queue.append(cq); - return; + // Place to queue on 'wait' flag + if (wait) { + m_queue.append(CommandQueue(command, tableIndex, showInConsole)); + return SendQueue; } - + // Evaluate scripts in command if (tableIndex < 0) command = evaluateCommand(command); + // Check evaluated command + if (command.isEmpty()) return SendEmpty; + + // Place to queue if command buffer is full + if ((bufferLength() + command.length() + 1) > BUFFERLENGTH) { + m_queue.append(CommandQueue(command, tableIndex, showInConsole)); + return SendQueue; + } + command = command.toUpper(); CommandAttributes ca; @@ -956,6 +961,8 @@ void frmMain::sendCommand(QString command, int tableIndex, bool showInConsole, b } m_serialPort.write((command + "\r").toLatin1()); + + return SendDone; } void frmMain::grblReset() @@ -1436,18 +1443,20 @@ void frmMain::onSerialPortReadyRead() emit responseReceived(ca.command, ca.tableIndex, response); // Check queue - if (m_queue.length() > 0) { - CommandQueue cq = m_queue.takeFirst(); - while (true) { - if ((bufferLength() + cq.command.length() + 1) <= BUFFERLENGTH) { - if (!cq.command.isEmpty()) sendCommand(cq.command, cq.tableIndex, cq.showInConsole); - if (!cq.command.isEmpty() && (m_queue.isEmpty() || cq.queue)) break; - else cq = m_queue.takeFirst(); - } else { - m_queue.insert(0, cq); - break; - } - } + static bool processingQueue = false; + if (m_queue.length() > 0 && !processingQueue) { + processingQueue = true; + while (m_queue.length() > 0) { + CommandQueue cq = m_queue.takeFirst(); + SendCommandResult r = sendCommand(cq.command, cq.tableIndex, cq.showInConsole); + if (r == SendDone) { + break; + } else if (r == SendQueue) { + m_queue.prepend(m_queue.takeLast()); + break; + } + } + processingQueue = false; } // Add response to table, send next program commands @@ -3990,14 +3999,17 @@ void frmMain::jogStep() QString frmMain::evaluateCommand(QString command) { // Evaluate script - QRegExp sx("\\{([^\\}]+)\\}"); + static QRegularExpression rx("\\{(?:(?>[^\\{\\}])|(?0))*\\}"); + QRegularExpressionMatch m; QScriptValue v; QString vs; - while (sx.indexIn(command) != -1) { - v = m_scriptEngine.evaluate(sx.cap(1)); + + while ((m = rx.match(command)).hasMatch()) { + v = m_scriptEngine.evaluate(m.captured(0)); vs = v.isUndefined() ? "" : v.isNumber() ? QString::number(v.toNumber(), 'f', 4) : v.toString(); - command.replace(sx.cap(0), vs); + command.replace(m.captured(0), vs); } + return command; } diff --git a/src/candle/frmmain.h b/src/candle/frmmain.h index 6473e7e2..d2eb8cbc 100644 --- a/src/candle/frmmain.h +++ b/src/candle/frmmain.h @@ -62,13 +62,31 @@ struct CommandAttributes { int consoleIndex; int tableIndex; QString command; + + CommandAttributes() { + } + + CommandAttributes(int len, int consoleIdx, int tableIdx, QString cmd) { + length = len; + consoleIndex = consoleIdx; + tableIndex = tableIdx; + command = cmd; + } }; struct CommandQueue { QString command; int tableIndex; bool showInConsole; - bool queue; + + CommandQueue() { + } + + CommandQueue(QString cmd, int idx, bool show) { + command = cmd; + tableIndex = idx; + showInConsole = show; + } }; class CancelException : public std::exception { @@ -92,7 +110,6 @@ class frmMain : public QMainWindow explicit frmMain(QWidget *parent = 0); ~frmMain(); - Q_INVOKABLE void sendCommand(QString command, int tableIndex = -1, bool showInConsole = true, bool queue = false); Q_INVOKABLE void applySettings(); double toolZPosition(); @@ -234,6 +251,12 @@ private slots: private: static const int BUFFERLENGTH = 127; + enum SendCommandResult { + SendDone = 0, + SendEmpty = 1, + SendQueue = 2 + }; + Ui::frmMain *ui; GcodeViewParse m_viewParser; @@ -368,6 +391,7 @@ private slots: bool saveChanges(bool heightMapMode); void updateControlsState(); void openPort(); + SendCommandResult sendCommand(QString command, int tableIndex = -1, bool showInConsole = true, bool wait = false); QString evaluateCommand(QString command); void grblReset(); int bufferLength();