From 265b6d33f017420c18e347c15c1b67c3437509a8 Mon Sep 17 00:00:00 2001 From: Klaus Basan Date: Fri, 13 Jan 2017 22:05:11 +0100 Subject: [PATCH] refs #859, allow to trigger digest signal manually * Useful if the input signal was just a bogus signal used to trigger * Login component shows a use case --- src/blackgui/components/logincomponent.cpp | 10 ++++---- src/blackgui/components/logincomponent.h | 6 +---- src/blackmisc/digestsignal.cpp | 20 +++++++++++++--- src/blackmisc/digestsignal.h | 28 +++++++++++++++------- src/blackmisc/threadutils.cpp | 6 ++--- 5 files changed, 44 insertions(+), 26 deletions(-) diff --git a/src/blackgui/components/logincomponent.cpp b/src/blackgui/components/logincomponent.cpp index c7d7ba0e9..617b37063 100644 --- a/src/blackgui/components/logincomponent.cpp +++ b/src/blackgui/components/logincomponent.cpp @@ -205,7 +205,7 @@ namespace BlackGui { this->m_logoffCountdownTimer->stop(); ui->pb_LogoffTimeout->setValue(LogoffIntervalSeconds); - emit loginOrLogoffCancelled(); + emit this->loginOrLogoffCancelled(); } void CLoginComponent::ps_toggleNetworkConnection() @@ -301,11 +301,11 @@ namespace BlackGui if (!ownAircraft.getAircraftIcaoCombinedType().isEmpty()) { ac += " "; ac += ownAircraft.getAircraftIcaoCode().getCombinedType(); } ui->le_LoginSince->setText(QDateTime::currentDateTimeUtc().toString()); ui->le_LoginAsAircaft->setText(ac); - emit loginOrLogoffSuccessful(); + emit this->loginOrLogoffSuccessful(); } else { - emit loginOrLogoffCancelled(); + emit this->loginOrLogoffCancelled(); } } @@ -462,7 +462,7 @@ namespace BlackGui const bool changedOwnAircraftIcaoValues = this->updateOwnAircaftIcaoValuesFromGuiValues(); if (changedOwnAircraftIcaoValues || changedOwnAircraftCallsignPilot) { - emit this->loginDataChanged(); + this->m_changedLoginDataDigestSignal.inputSignal(); } } @@ -595,7 +595,7 @@ namespace BlackGui this->updateOwnAircraftCallsignAndPilotFromGuiValues(); // let others know data changed - emit this->loginDataChanged(); + this->m_changedLoginDataDigestSignal.inputSignal(); } void CLoginComponent::ps_mappingWizard() diff --git a/src/blackgui/components/logincomponent.h b/src/blackgui/components/logincomponent.h index 2ab2f22f3..6f42cb305 100644 --- a/src/blackgui/components/logincomponent.h +++ b/src/blackgui/components/logincomponent.h @@ -78,10 +78,6 @@ namespace BlackGui //! Request network settings void requestNetworkSettings(); - //! Relevant login data changed - //! \private normally loginDataChangedDigest will be used - void loginDataChanged(); - //! Relevant login data changed (digest version) void loginDataChangedDigest(); @@ -208,7 +204,7 @@ namespace BlackGui QScopedPointer ui; QScopedPointer m_mappingWizard; - BlackMisc::CDigestSignal m_changedLoginDataDigestSignal { this, &CLoginComponent::loginDataChanged, &CLoginComponent::loginDataChangedDigest, 1500, 10 }; + BlackMisc::CDigestSignal m_changedLoginDataDigestSignal { this, &CLoginComponent::loginDataChangedDigest, 1500, 10 }; bool m_autoPopupWizard = false; //!< automatically popup wizard if mapping is needed bool m_visible = false; //!< is this component selected? const int LogoffIntervalSeconds = 20; //!< time before logoff diff --git a/src/blackmisc/digestsignal.cpp b/src/blackmisc/digestsignal.cpp index 74ed28a9e..f6f11f9ef 100644 --- a/src/blackmisc/digestsignal.cpp +++ b/src/blackmisc/digestsignal.cpp @@ -7,13 +7,20 @@ * contained in the LICENSE file. */ -#include "blackmisc/digestsignal.h" +#include "digestsignal.h" +#include "threadutils.h" namespace BlackMisc { - - void CDigestSignal::ps_inputSignal() + void CDigestSignal::inputSignal() { + if (!CThreadUtils::isCurrentThreadObjectThread(this)) + { + // call in correct thread + QTimer::singleShot(0, this, &CDigestSignal::inputSignal); + return; + } + m_timer.start(); // start or restart m_inputsCount++; if (m_inputsCount >= m_maxInputsPerDigest) @@ -29,4 +36,11 @@ namespace BlackMisc emit digestSignal(); } + void CDigestSignal::init(int maxDelayMs) + { + QObject::connect(&m_timer, &QTimer::timeout, this, &CDigestSignal::ps_timeout); + m_timer.setSingleShot(true); + m_timer.setInterval(maxDelayMs); + } + } // namespace diff --git a/src/blackmisc/digestsignal.h b/src/blackmisc/digestsignal.h index 8f9fa3c8a..46cce0ff3 100644 --- a/src/blackmisc/digestsignal.h +++ b/src/blackmisc/digestsignal.h @@ -30,29 +30,39 @@ namespace BlackMisc CDigestSignal(T *sender, F1 inputSignal, F2 digestSignal, int maxDelayMs = 500, int maxInputsPerDigest = 3) : m_maxInputsPerDigest(maxInputsPerDigest) { - QObject::connect(sender, inputSignal, this, &CDigestSignal::ps_inputSignal); + QObject::connect(sender, inputSignal, this, &CDigestSignal::inputSignal); QObject::connect(this, &CDigestSignal::digestSignal, sender, digestSignal); - - QObject::connect(&m_timer, &QTimer::timeout, this, &CDigestSignal::ps_timeout); - m_timer.setSingleShot(true); - m_timer.setInterval(maxDelayMs); + init(maxDelayMs); } - // Destructor + //! Constructor without input signal, can be manually triggered + template + CDigestSignal(T *sender, F2 digestSignal, int maxDelayMs = 500, int maxInputsPerDigest = 3) + : m_maxInputsPerDigest(maxInputsPerDigest) + { + QObject::connect(this, &CDigestSignal::digestSignal, sender, digestSignal); + init(maxDelayMs); + } + + //! Destructor virtual ~CDigestSignal() {} signals: //! Send digest signal void digestSignal(); - private slots: - //! Received input signal - void ps_inputSignal(); + public slots: + //! Received input signal, or manually trigger + void inputSignal(); + private slots: //! Timer timed out void ps_timeout(); private: + //! Init in ctor + void init(int maxDelayMs); + QTimer m_timer; const int m_maxInputsPerDigest = 3; int m_inputsCount = 0; diff --git a/src/blackmisc/threadutils.cpp b/src/blackmisc/threadutils.cpp index 1dc9304d7..789d34d5b 100644 --- a/src/blackmisc/threadutils.cpp +++ b/src/blackmisc/threadutils.cpp @@ -19,15 +19,14 @@ namespace BlackMisc bool CThreadUtils::isCurrentThreadObjectThread(QObject *toBeTested) { Q_ASSERT_X(toBeTested, Q_FUNC_INFO, "missing QObject"); - if (!toBeTested) { return false; } - if (!toBeTested->thread()) { return false; } + Q_ASSERT_X(toBeTested->thread(), Q_FUNC_INFO, "missing thread"); return (QThread::currentThread() == toBeTested->thread()); } bool CThreadUtils::isApplicationThreadObjectThread(QObject *toBeTested) { Q_ASSERT_X(toBeTested, Q_FUNC_INFO, "missing QObject"); - if (!toBeTested || !toBeTested->thread()) { return false; } + Q_ASSERT_X(toBeTested->thread(), Q_FUNC_INFO, "missing thread"); if (!QCoreApplication::instance() || !QCoreApplication::instance()->thread()) { return false; } return (QCoreApplication::instance()->thread() == toBeTested->thread()); } @@ -38,5 +37,4 @@ namespace BlackMisc if (!QCoreApplication::instance()->thread()) { return false; } return (QCoreApplication::instance()->thread() == QThread::currentThread()); } - } // ns