Idle-Flush gefixt
This commit is contained in:
@@ -47,9 +47,11 @@ private slots:
|
|||||||
void onReadyRead();
|
void onReadyRead();
|
||||||
void onPortError(QSerialPort::SerialPortError err);
|
void onPortError(QSerialPort::SerialPortError err);
|
||||||
void tryReconnect();
|
void tryReconnect();
|
||||||
|
void flushScanTail();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void processRawData(const QByteArray &data);
|
void processRawData(const QByteArray &data);
|
||||||
|
void appendToLineBuffer(const QByteArray &toProcess);
|
||||||
void processLine(const QString &line);
|
void processLine(const QString &line);
|
||||||
void scheduleReconnect();
|
void scheduleReconnect();
|
||||||
|
|
||||||
@@ -59,6 +61,16 @@ private:
|
|||||||
QString m_buffer;
|
QString m_buffer;
|
||||||
QByteArray m_scanTail; // carries partial ANSI sequences across reads
|
QByteArray m_scanTail; // carries partial ANSI sequences across reads
|
||||||
|
|
||||||
|
// If no further bytes arrive shortly after some data was held back in
|
||||||
|
// m_scanTail (to safely detect a possibly-split ANSI sequence), this
|
||||||
|
// timer fires and flushes that tail through the normal line-processing
|
||||||
|
// path anyway. Without this, the last line(s) of a burst can sit stuck
|
||||||
|
// in m_scanTail indefinitely if the sender goes quiet (e.g. a device
|
||||||
|
// that streams a final line and then stops) and only surface once new
|
||||||
|
// bytes eventually arrive (e.g. after a reboot).
|
||||||
|
QTimer *m_idleFlushTimer = nullptr;
|
||||||
|
static constexpr int kIdleFlushMs = 50;
|
||||||
|
|
||||||
QTimer *m_reconnectTimer = nullptr;
|
QTimer *m_reconnectTimer = nullptr;
|
||||||
bool m_autoReconnect = true;
|
bool m_autoReconnect = true;
|
||||||
bool m_userDisconnected = false;
|
bool m_userDisconnected = false;
|
||||||
|
|||||||
@@ -5,8 +5,12 @@
|
|||||||
SerialWorker::SerialWorker(QObject *parent)
|
SerialWorker::SerialWorker(QObject *parent)
|
||||||
: QObject(parent)
|
: QObject(parent)
|
||||||
, m_port(new QSerialPort(this))
|
, m_port(new QSerialPort(this))
|
||||||
|
, m_idleFlushTimer(new QTimer(this))
|
||||||
, m_reconnectTimer(new QTimer(this))
|
, m_reconnectTimer(new QTimer(this))
|
||||||
{
|
{
|
||||||
|
m_idleFlushTimer->setSingleShot(true);
|
||||||
|
connect(m_idleFlushTimer, &QTimer::timeout, this, &SerialWorker::flushScanTail);
|
||||||
|
|
||||||
m_reconnectTimer->setSingleShot(true);
|
m_reconnectTimer->setSingleShot(true);
|
||||||
connect(m_reconnectTimer, &QTimer::timeout, this, &SerialWorker::tryReconnect);
|
connect(m_reconnectTimer, &QTimer::timeout, this, &SerialWorker::tryReconnect);
|
||||||
|
|
||||||
@@ -53,6 +57,7 @@ void SerialWorker::openPort(const QString &portName, qint32 baudRate,
|
|||||||
scheduleReconnect();
|
scheduleReconnect();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
m_idleFlushTimer->stop();
|
||||||
m_buffer.clear();
|
m_buffer.clear();
|
||||||
m_scanTail.clear();
|
m_scanTail.clear();
|
||||||
m_reconnectAttempt = 0;
|
m_reconnectAttempt = 0;
|
||||||
@@ -63,6 +68,7 @@ void SerialWorker::closePort()
|
|||||||
{
|
{
|
||||||
m_userDisconnected = true;
|
m_userDisconnected = true;
|
||||||
m_reconnectTimer->stop();
|
m_reconnectTimer->stop();
|
||||||
|
m_idleFlushTimer->stop();
|
||||||
if (m_port && m_port->isOpen()) {
|
if (m_port && m_port->isOpen()) {
|
||||||
m_port->close();
|
m_port->close();
|
||||||
emit portClosed();
|
emit portClosed();
|
||||||
@@ -149,6 +155,7 @@ void SerialWorker::tryReconnect()
|
|||||||
m_port->setFlowControl(m_flowControl);
|
m_port->setFlowControl(m_flowControl);
|
||||||
|
|
||||||
if (m_port->open(QIODevice::ReadOnly)) {
|
if (m_port->open(QIODevice::ReadOnly)) {
|
||||||
|
m_idleFlushTimer->stop();
|
||||||
m_buffer.clear();
|
m_buffer.clear();
|
||||||
m_scanTail.clear();
|
m_scanTail.clear();
|
||||||
m_reconnectAttempt = 0;
|
m_reconnectAttempt = 0;
|
||||||
@@ -202,9 +209,36 @@ void SerialWorker::processRawData(const QByteArray &data)
|
|||||||
if (sawClear)
|
if (sawClear)
|
||||||
emit clearScreen();
|
emit clearScreen();
|
||||||
|
|
||||||
|
// (Re)arm the idle-flush timer whenever bytes are still being withheld
|
||||||
|
// in m_scanTail, so that a burst which ends right at a chunk boundary
|
||||||
|
// doesn't leave its last line(s) stuck there forever. If nothing is
|
||||||
|
// being withheld, make sure any pending flush is cancelled.
|
||||||
|
if (!m_scanTail.isEmpty())
|
||||||
|
m_idleFlushTimer->start(kIdleFlushMs);
|
||||||
|
else
|
||||||
|
m_idleFlushTimer->stop();
|
||||||
|
|
||||||
if (toProcess.isEmpty())
|
if (toProcess.isEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
appendToLineBuffer(toProcess);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SerialWorker::flushScanTail()
|
||||||
|
{
|
||||||
|
// Nothing new arrived within kIdleFlushMs of the last chunk that left
|
||||||
|
// data in m_scanTail: treat it as final and process it as-is, rather
|
||||||
|
// than waiting indefinitely for more bytes that may never come.
|
||||||
|
if (m_scanTail.isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
QByteArray toProcess = m_scanTail;
|
||||||
|
m_scanTail.clear();
|
||||||
|
appendToLineBuffer(toProcess);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SerialWorker::appendToLineBuffer(const QByteArray &toProcess)
|
||||||
|
{
|
||||||
// Strip remaining (non-clear) ANSI escape sequences for clean display.
|
// Strip remaining (non-clear) ANSI escape sequences for clean display.
|
||||||
static const QRegularExpression ansiRe(
|
static const QRegularExpression ansiRe(
|
||||||
"\x1b(?:[@-Z\\\\-_]|\\[[0-?]*[ -/]*[@-~])");
|
"\x1b(?:[@-Z\\\\-_]|\\[[0-?]*[ -/]*[@-~])");
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Maintainer: diabolus <your@email.com>
|
# Maintainer: diabolus <your@email.com>
|
||||||
pkgname=uartscope
|
pkgname=uartscope
|
||||||
pkgver=1.0.0.r2.g92168ee
|
pkgver=1.0.0.r3.gd3229c7
|
||||||
pkgrel=1
|
pkgrel=1
|
||||||
pkgdesc="Qt6-based UART serial monitor with tag monitoring, table view and auto-reconnect"
|
pkgdesc="Qt6-based UART serial monitor with tag monitoring, table view and auto-reconnect"
|
||||||
arch=('x86_64' 'aarch64')
|
arch=('x86_64' 'aarch64')
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@@ -1,14 +1,14 @@
|
|||||||
# Generated by makepkg 7.1.0
|
# Generated by makepkg 7.1.0
|
||||||
# using fakeroot version 1.38.1
|
# using fakeroot version 1.37.2
|
||||||
pkgname = uartscope
|
pkgname = uartscope
|
||||||
pkgbase = uartscope
|
pkgbase = uartscope
|
||||||
xdata = pkgtype=pkg
|
xdata = pkgtype=pkg
|
||||||
pkgver = 1.0.0.r2.g92168ee-1
|
pkgver = 1.0.0.r3.gd3229c7-1
|
||||||
pkgdesc = Qt6-based UART serial monitor with tag monitoring, table view and auto-reconnect
|
pkgdesc = Qt6-based UART serial monitor with tag monitoring, table view and auto-reconnect
|
||||||
url = https://git.projekt-hirnfrei.de/diabolus/uartscope
|
url = https://git.projekt-hirnfrei.de/diabolus/uartscope
|
||||||
builddate = 1781039770
|
builddate = 1782249637
|
||||||
packager = Unknown Packager
|
packager = Unknown Packager
|
||||||
size = 381553
|
size = 389745
|
||||||
arch = x86_64
|
arch = x86_64
|
||||||
license = MIT
|
license = MIT
|
||||||
conflict = uartscope
|
conflict = uartscope
|
||||||
|
|||||||
Binary file not shown.
Submodule uartscope-git/src/uartscope updated: 92168ee5dc...d3229c7b64
@@ -1,2 +1,2 @@
|
|||||||
92168ee5dc7cfe0e6711207e314b6bd3acb8f291 not-for-merge branch 'main' of https://git.projekt-hirnfrei.de/diabolus/uartscope
|
d3229c7b648e41e6e11e745968686c64ba5ccde8 not-for-merge branch 'main' of https://git.projekt-hirnfrei.de/diabolus/uartscope
|
||||||
cc102c93eb17f7b910d8e74c3505f198bed77f10 not-for-merge tag 'v1.0.0' of https://git.projekt-hirnfrei.de/diabolus/uartscope
|
cc102c93eb17f7b910d8e74c3505f198bed77f10 not-for-merge tag 'v1.0.0' of https://git.projekt-hirnfrei.de/diabolus/uartscope
|
||||||
|
|||||||
Reference in New Issue
Block a user