diff --git a/lib-api.cpp b/lib-api.cpp index cf1c8dc..9d1d4f5 100644 --- a/lib-api.cpp +++ b/lib-api.cpp @@ -40,6 +40,7 @@ int loadConfig(char16_t *filename) { try { lib.config_filename = QString::fromUtf16(filename); lib.s.load(lib.config_filename); + lib.xnSetConfig(); lib.fillConnectionsCbs(); } catch (...) { return TRK_FILE_CANNOT_ACCESS; } return 0; diff --git a/lib-main.cpp b/lib-main.cpp index 8b03ba1..18542a5 100644 --- a/lib-main.cpp +++ b/lib-main.cpp @@ -21,6 +21,7 @@ LibMain::LibMain(QObject* parent) : QObject(parent) { this->config_filename = _DEFAULT_CONFIG_FILENAME; s.load(this->config_filename); + this->xnSetConfig(); this->guiInit(); log("Library loaded.", LogLevel::Info); } @@ -185,4 +186,22 @@ void LibMain::xnOnCSStatusError(void *, void *) { xn.disconnect(); } +void LibMain::xnSetConfig() { + try { + XNConfig config; + bool ok; + config.outInterval = s["XN"]["outIntervalMs"].toUInt(&ok); + if (!ok) { + log("Unable to load xnConfig: 'outIntervalMs' is not a number!", LogLevel::Error); + return; + } + + xn.setConfig(config); + } catch (const QStrException& e) { + log("Unable to load xnConfig: "+e.str(), LogLevel::Error); + } catch (...) { + log("Unable to load xnConfig: cannot set config (unknown exception)!", LogLevel::Error); + } +} + } // namespace Xn diff --git a/lib-main.h b/lib-main.h index 515494f..7fc6bb9 100644 --- a/lib-main.h +++ b/lib-main.h @@ -46,6 +46,7 @@ class LibMain : public QObject { void guiOnClose(); void log(const QString &msg, LogLevel loglevel); + void xnSetConfig(); private slots: void b_serial_refresh_handle(); diff --git a/settings.h b/settings.h index e3ff247..f64e7a0 100644 --- a/settings.h +++ b/settings.h @@ -16,6 +16,7 @@ const Config DEFAULTS { {"flowcontrol", 1}, {"loglevel", 1}, {"interface", "LI101"}, + {"outIntervalMs", 50}, }}, }; diff --git a/xn-send.cpp b/xn-send.cpp index f29b80a..2a7d121 100644 --- a/xn-send.cpp +++ b/xn-send.cpp @@ -53,7 +53,7 @@ void XpressNet::to_send(std::unique_ptr &cmd, UPCb ok, UPCb err, size log("ENQUEUE: " + cmd->msg(), LogLevel::Debug); m_out.emplace_back(cmd, timeout(cmd.get()), no_sent, std::move(ok), std::move(err)); } else { - if (m_lastSent.addMSecs(_OUT_TIMER_INTERVAL) > QDateTime::currentDateTime()) { + if (m_lastSent.addMSecs(m_config.outInterval) > QDateTime::currentDateTime()) { // Last command sent too early, still space in hist buffer -> // queue & activate timer for next send log("ENQUEUE: " + cmd->msg(), LogLevel::Debug); @@ -81,7 +81,7 @@ void XpressNet::m_out_timer_tick() { } void XpressNet::send_next_out() { - if (m_lastSent.addMSecs(_OUT_TIMER_INTERVAL) > QDateTime::currentDateTime()) { + if (m_lastSent.addMSecs(m_config.outInterval) > QDateTime::currentDateTime()) { if (!m_out_timer.isActive()) m_out_timer.start(); return; diff --git a/xn.cpp b/xn.cpp index 3c7fe3c..2fe8576 100644 --- a/xn.cpp +++ b/xn.cpp @@ -17,7 +17,7 @@ XpressNet::XpressNet(QObject *parent) : QObject(parent) { SLOT(handleError(QSerialPort::SerialPortError))); QObject::connect(&m_hist_timer, SIGNAL(timeout()), this, SLOT(m_hist_timer_tick())); - m_out_timer.setInterval(_OUT_TIMER_INTERVAL); + m_out_timer.setInterval(m_config.outInterval); QObject::connect(&m_out_timer, SIGNAL(timeout()), this, SLOT(m_out_timer_tick())); QObject::connect(&m_serialPort, SIGNAL(aboutToClose()), this, SLOT(sp_about_to_close())); } @@ -75,10 +75,10 @@ QString XpressNet::xnReadCVStatusToQString(const ReadCVStatus st) { } bool XpressNet::liAcknowledgesSetAccState() const { - return (this->m_liType == LIType::uLI || this->m_liType == LIType::LIUSBEth); + return (m_liType == LIType::uLI || m_liType == LIType::LIUSBEth); } -LIType XpressNet::liType() const { return this->m_liType; } +LIType XpressNet::liType() const { return m_liType; } LIType liInterface(const QString &name) { if (name == "LI101") @@ -126,4 +126,16 @@ std::vector XpressNet::ports(LIType litype) { #endif } +XNConfig XpressNet::config() const { + return m_config; +} + +void XpressNet::setConfig(const XNConfig config) { + if ((config.outInterval < _OUT_TIMER_INTERVAL_MIN) || (config.outInterval > _OUT_TIMER_INTERVAL_MAX)) + throw EInvalidConfig("outInterval="+QString::number(config.outInterval)+" is out of range ["+ + QString::number(_OUT_TIMER_INTERVAL_MIN)+"-"+QString::number(_OUT_TIMER_INTERVAL_MAX)+"]"); + m_config = config; + m_out_timer.setInterval(m_config.outInterval); +} + } // namespace Xn diff --git a/xn.h b/xn.h index 428626f..d5abf4e 100644 --- a/xn.h +++ b/xn.h @@ -38,7 +38,7 @@ How does sending work? #include "xn-loco-addr.h" #define XN_VERSION_MAJOR 2 -#define XN_VERSION_MINOR 6 +#define XN_VERSION_MINOR 7 namespace Xn { @@ -50,7 +50,10 @@ constexpr size_t _HIST_SEND_MAX = 3; constexpr size_t _BUF_IN_TIMEOUT = 300; // ms constexpr size_t _STEPS_CNT = 28; constexpr size_t _MAX_HIST_BUF_COUNT = 3; -constexpr size_t _OUT_TIMER_INTERVAL = 50; // 50 ms + +constexpr size_t _OUT_TIMER_INTERVAL_DEFAULT = 50; // ms +constexpr size_t _OUT_TIMER_INTERVAL_MIN = 50; // ms +constexpr size_t _OUT_TIMER_INTERVAL_MAX = 500; // ms struct EOpenError : public QStrException { EOpenError(const QString str) : QStrException(str) {} @@ -62,7 +65,10 @@ struct EInvalidTrkStatus : public QStrException { EInvalidTrkStatus(const QString str) : QStrException(str) {} }; struct EUnsupportedInterface : public QStrException { - EUnsupportedInterface(const QString str) : QStrException(str) {} + EUnsupportedInterface(const QString str) : QStrException(str) {} +}; +struct EInvalidConfig : public QStrException { + EInvalidConfig(const QString str) : QStrException(str) {} }; enum class LIType { @@ -156,6 +162,10 @@ enum class RecvCmdType { CsAccInfoResp = 0x42, }; +struct XNConfig { + size_t outInterval = _OUT_TIMER_INTERVAL_DEFAULT; +}; + class XpressNet : public QObject { Q_OBJECT @@ -205,7 +215,10 @@ class XpressNet : public QObject { static QString xnReadCVStatusToQString(ReadCVStatus st); static std::vector ports(LIType); - LIType liType() const; + LIType liType() const; + + XNConfig config() const; + void setConfig(const XNConfig config); private slots: void handleReadyRead(); @@ -235,6 +248,7 @@ private slots: QTimer m_out_timer; TrkStatus m_trk_status = TrkStatus::Unknown; LIType m_liType; + XNConfig m_config; using MsgType = std::vector; void parseMessage(MsgType &msg); diff --git a/xn.pro b/xn.pro index aa069d5..c1c4e78 100644 --- a/xn.pro +++ b/xn.pro @@ -51,7 +51,7 @@ QT += core gui serialport greaterThan(QT_MAJOR_VERSION, 4): QT += widgets VERSION_MAJOR = 2 -VERSION_MINOR = 6 +VERSION_MINOR = 7 DEFINES += "VERSION_MAJOR=$$VERSION_MAJOR" \ "VERSION_MINOR=$$VERSION_MINOR"