mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-04-26 18:55:38 +08:00
refs #334 VATSIM threaded reader classes using CContinuousWorker.
This commit is contained in:
committed by
Roland Winklmeier
parent
195c909ca0
commit
54e883c322
@@ -50,17 +50,19 @@ namespace BlackCore
|
|||||||
connect(this->m_network, &INetwork::textMessagesReceived, this, &CContextNetwork::ps_fsdTextMessageReceived);
|
connect(this->m_network, &INetwork::textMessagesReceived, this, &CContextNetwork::ps_fsdTextMessageReceived);
|
||||||
|
|
||||||
// 2. VATSIM bookings
|
// 2. VATSIM bookings
|
||||||
this->m_vatsimBookingReader = new CVatsimBookingReader(this->getRuntime()->getIContextSettings()->getNetworkSettings().getBookingServiceUrl(), this);
|
this->m_vatsimBookingReader = new CVatsimBookingReader(this, this->getRuntime()->getIContextSettings()->getNetworkSettings().getBookingServiceUrl());
|
||||||
connect(this->m_vatsimBookingReader, &CVatsimBookingReader::dataRead, this, &CContextNetwork::ps_receivedBookings);
|
connect(this->m_vatsimBookingReader, &CVatsimBookingReader::dataRead, this, &CContextNetwork::ps_receivedBookings);
|
||||||
this->m_vatsimBookingReader->read(); // first read
|
this->m_vatsimBookingReader->read(); // first read
|
||||||
this->m_vatsimBookingReader->setInterval(180 * 1000);
|
this->m_vatsimBookingReader->setInterval(180 * 1000);
|
||||||
|
this->m_vatsimBookingReader->start();
|
||||||
|
|
||||||
// 3. VATSIM data file
|
// 3. VATSIM data file
|
||||||
const QStringList dataFileUrls = { "http://info.vroute.net/vatsim-data.txt" };
|
const QStringList dataFileUrls = { "http://info.vroute.net/vatsim-data.txt" };
|
||||||
this->m_vatsimDataFileReader = new CVatsimDataFileReader(dataFileUrls, this);
|
this->m_vatsimDataFileReader = new CVatsimDataFileReader(this, dataFileUrls);
|
||||||
connect(this->m_vatsimDataFileReader, &CVatsimDataFileReader::dataRead, this, &CContextNetwork::ps_dataFileRead);
|
connect(this->m_vatsimDataFileReader, &CVatsimDataFileReader::dataRead, this, &CContextNetwork::ps_dataFileRead);
|
||||||
this->m_vatsimDataFileReader->read(); // first read
|
this->m_vatsimDataFileReader->read(); // first read
|
||||||
this->m_vatsimDataFileReader->setInterval(90 * 1000);
|
this->m_vatsimDataFileReader->setInterval(90 * 1000);
|
||||||
|
this->m_vatsimDataFileReader->start();
|
||||||
|
|
||||||
// 4. Update timer for data (network data such as frequency)
|
// 4. Update timer for data (network data such as frequency)
|
||||||
this->m_dataUpdateTimer = new QTimer(this);
|
this->m_dataUpdateTimer = new QTimer(this);
|
||||||
@@ -91,8 +93,8 @@ namespace BlackCore
|
|||||||
*/
|
*/
|
||||||
void CContextNetwork::gracefulShutdown()
|
void CContextNetwork::gracefulShutdown()
|
||||||
{
|
{
|
||||||
if (this->m_vatsimBookingReader) this->m_vatsimBookingReader->stop();
|
if (this->m_vatsimBookingReader) this->m_vatsimBookingReader->quit();
|
||||||
if (this->m_vatsimDataFileReader) this->m_vatsimDataFileReader->stop();
|
if (this->m_vatsimDataFileReader) this->m_vatsimDataFileReader->quit();
|
||||||
if (this->isConnected()) this->disconnectFromNetwork();
|
if (this->isConnected()) this->disconnectFromNetwork();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,8 +22,8 @@ using namespace BlackMisc::Network;
|
|||||||
|
|
||||||
namespace BlackCore
|
namespace BlackCore
|
||||||
{
|
{
|
||||||
CVatsimBookingReader::CVatsimBookingReader(const QString &url, QObject *parent) :
|
CVatsimBookingReader::CVatsimBookingReader(QObject *owner, const QString &url) :
|
||||||
QObject(parent), CThreadedReader(),
|
CThreadedReader(owner),
|
||||||
m_serviceUrl(url), m_networkManager(nullptr)
|
m_serviceUrl(url), m_networkManager(nullptr)
|
||||||
{
|
{
|
||||||
this->m_networkManager = new QNetworkAccessManager(this);
|
this->m_networkManager = new QNetworkAccessManager(this);
|
||||||
@@ -47,7 +47,7 @@ namespace BlackCore
|
|||||||
void CVatsimBookingReader::ps_loadFinished(QNetworkReply *nwReply)
|
void CVatsimBookingReader::ps_loadFinished(QNetworkReply *nwReply)
|
||||||
{
|
{
|
||||||
this->setPendingNetworkReply(nullptr);
|
this->setPendingNetworkReply(nullptr);
|
||||||
if (!this->isStopped())
|
if (!this->isFinished())
|
||||||
{
|
{
|
||||||
QFuture<void> f = QtConcurrent::run(this, &CVatsimBookingReader::parseBookings, nwReply);
|
QFuture<void> f = QtConcurrent::run(this, &CVatsimBookingReader::parseBookings, nwReply);
|
||||||
this->setPendingFuture(f);
|
this->setPendingFuture(f);
|
||||||
@@ -64,7 +64,7 @@ namespace BlackCore
|
|||||||
QScopedPointer<QNetworkReply, QScopedPointerDeleteLater> nwReply(nwReplyPtr);
|
QScopedPointer<QNetworkReply, QScopedPointerDeleteLater> nwReply(nwReplyPtr);
|
||||||
|
|
||||||
// Worker thread, make sure to write no members here!
|
// Worker thread, make sure to write no members here!
|
||||||
if (this->isStopped())
|
if (this->isFinished())
|
||||||
{
|
{
|
||||||
CLogMessage(this).debug() << Q_FUNC_INFO;
|
CLogMessage(this).debug() << Q_FUNC_INFO;
|
||||||
CLogMessage(this).info("terminated booking parsing process"); // for users
|
CLogMessage(this).info("terminated booking parsing process"); // for users
|
||||||
@@ -100,7 +100,7 @@ namespace BlackCore
|
|||||||
CAtcStationList bookedStations;
|
CAtcStationList bookedStations;
|
||||||
for (int i = 0; i < size; i++)
|
for (int i = 0; i < size; i++)
|
||||||
{
|
{
|
||||||
if (this->isStopped())
|
if (this->isFinished())
|
||||||
{
|
{
|
||||||
CLogMessage(this).debug() << Q_FUNC_INFO;
|
CLogMessage(this).debug() << Q_FUNC_INFO;
|
||||||
CLogMessage(this).info("terminated booking parsing process"); // for users
|
CLogMessage(this).info("terminated booking parsing process"); // for users
|
||||||
|
|||||||
@@ -25,13 +25,13 @@ namespace BlackCore
|
|||||||
/*!
|
/*!
|
||||||
* Read bookings from VATSIM
|
* Read bookings from VATSIM
|
||||||
*/
|
*/
|
||||||
class CVatsimBookingReader : public QObject, public BlackMisc::CThreadedReader<void>
|
class CVatsimBookingReader : public BlackMisc::CThreadedReader<void>
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
//! Constructor
|
//! Constructor
|
||||||
explicit CVatsimBookingReader(const QString &url, QObject *parent = nullptr);
|
explicit CVatsimBookingReader(QObject *owner, const QString &url);
|
||||||
|
|
||||||
//! Read / re-read bookings
|
//! Read / re-read bookings
|
||||||
void read();
|
void read();
|
||||||
|
|||||||
@@ -25,8 +25,8 @@ using namespace BlackMisc::PhysicalQuantities;
|
|||||||
|
|
||||||
namespace BlackCore
|
namespace BlackCore
|
||||||
{
|
{
|
||||||
CVatsimDataFileReader::CVatsimDataFileReader(const QStringList &urls, QObject *parent) :
|
CVatsimDataFileReader::CVatsimDataFileReader(QObject *owner, const QStringList &urls) :
|
||||||
QObject(parent), CThreadedReader(),
|
CThreadedReader(owner),
|
||||||
m_serviceUrls(urls), m_currentUrlIndex(0), m_networkManager(nullptr)
|
m_serviceUrls(urls), m_currentUrlIndex(0), m_networkManager(nullptr)
|
||||||
{
|
{
|
||||||
this->m_networkManager = new QNetworkAccessManager(this);
|
this->m_networkManager = new QNetworkAccessManager(this);
|
||||||
@@ -149,7 +149,7 @@ namespace BlackCore
|
|||||||
void CVatsimDataFileReader::ps_loadFinished(QNetworkReply *nwReply)
|
void CVatsimDataFileReader::ps_loadFinished(QNetworkReply *nwReply)
|
||||||
{
|
{
|
||||||
this->setPendingNetworkReply(nullptr);
|
this->setPendingNetworkReply(nullptr);
|
||||||
if (!this->isStopped())
|
if (!this->isFinished())
|
||||||
{
|
{
|
||||||
QFuture<void> f = QtConcurrent::run(this, &CVatsimDataFileReader::parseVatsimFileInBackground, nwReply);
|
QFuture<void> f = QtConcurrent::run(this, &CVatsimDataFileReader::parseVatsimFileInBackground, nwReply);
|
||||||
this->setPendingFuture(f);
|
this->setPendingFuture(f);
|
||||||
@@ -167,7 +167,7 @@ namespace BlackCore
|
|||||||
QScopedPointer<QNetworkReply, QScopedPointerDeleteLater> nwReply(nwReplyPtr);
|
QScopedPointer<QNetworkReply, QScopedPointerDeleteLater> nwReply(nwReplyPtr);
|
||||||
|
|
||||||
// Worker thread, make sure to write only synced here!
|
// Worker thread, make sure to write only synced here!
|
||||||
if (this->isStopped())
|
if (this->isFinished())
|
||||||
{
|
{
|
||||||
CLogMessage(this).debug() << Q_FUNC_INFO;
|
CLogMessage(this).debug() << Q_FUNC_INFO;
|
||||||
CLogMessage(this).info("terminated VATSIM file parsing process"); // for users
|
CLogMessage(this).info("terminated VATSIM file parsing process"); // for users
|
||||||
@@ -196,7 +196,7 @@ namespace BlackCore
|
|||||||
Section section = SectionNone;
|
Section section = SectionNone;
|
||||||
foreach(QString currentLine, lines)
|
foreach(QString currentLine, lines)
|
||||||
{
|
{
|
||||||
if (this->isStopped())
|
if (this->isFinished())
|
||||||
{
|
{
|
||||||
CLogMessage(this).debug() << Q_FUNC_INFO;
|
CLogMessage(this).debug() << Q_FUNC_INFO;
|
||||||
CLogMessage(this).info("terminated booking parsing process"); // for users
|
CLogMessage(this).info("terminated booking parsing process"); // for users
|
||||||
|
|||||||
@@ -30,13 +30,13 @@ namespace BlackCore
|
|||||||
/*!
|
/*!
|
||||||
* Read bookings from VATSIM
|
* Read bookings from VATSIM
|
||||||
*/
|
*/
|
||||||
class CVatsimDataFileReader : public QObject, public BlackMisc::CThreadedReader<void>
|
class CVatsimDataFileReader : public BlackMisc::CThreadedReader<void>
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
//! Constructor
|
//! Constructor
|
||||||
explicit CVatsimDataFileReader(const QStringList &urls, QObject *parent = nullptr);
|
explicit CVatsimDataFileReader(QObject *owner, const QStringList &urls);
|
||||||
|
|
||||||
//! Read / re-read data file
|
//! Read / re-read data file
|
||||||
void read();
|
void read();
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
//! \file
|
//! \file
|
||||||
|
|
||||||
|
#include "worker.h"
|
||||||
#include <QReadWriteLock>
|
#include <QReadWriteLock>
|
||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
@@ -27,17 +28,9 @@ namespace BlackMisc
|
|||||||
*
|
*
|
||||||
* \remarks Header only class to avoid forward instantiations across subprojects
|
* \remarks Header only class to avoid forward instantiations across subprojects
|
||||||
*/
|
*/
|
||||||
template <class FutureRet = void> class CThreadedReader
|
template <class FutureRet = void> class CThreadedReader : public CContinuousWorker
|
||||||
{
|
{
|
||||||
|
|
||||||
public:
|
public:
|
||||||
//! Destructor
|
|
||||||
virtual ~CThreadedReader()
|
|
||||||
{
|
|
||||||
this->stop();
|
|
||||||
delete m_updateTimer;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Thread safe, set update timestamp
|
//! Thread safe, set update timestamp
|
||||||
//! \threadsafe
|
//! \threadsafe
|
||||||
QDateTime getUpdateTimestamp() const
|
QDateTime getUpdateTimestamp() const
|
||||||
@@ -54,16 +47,9 @@ namespace BlackMisc
|
|||||||
this->m_updateTimestamp = updateTimestamp;
|
this->m_updateTimestamp = updateTimestamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Thread safe, mark as stopped
|
//! \copydoc CContinuousWorker::cleanup
|
||||||
//! \threadsafe
|
virtual void cleanup() override
|
||||||
virtual void stop()
|
|
||||||
{
|
{
|
||||||
if (this->isStopped()) return;
|
|
||||||
|
|
||||||
// thread safe stopping timer and mark as stopped
|
|
||||||
this->setStopFlag();
|
|
||||||
this->setInterval(0);
|
|
||||||
|
|
||||||
// shutdown pending
|
// shutdown pending
|
||||||
QWriteLocker(&this->m_lock);
|
QWriteLocker(&this->m_lock);
|
||||||
if (this->m_pendingFuture.isRunning())
|
if (this->m_pendingFuture.isRunning())
|
||||||
@@ -76,21 +62,12 @@ namespace BlackMisc
|
|||||||
if (this->m_pendingNetworkReply && this->m_pendingNetworkReply->isRunning())
|
if (this->m_pendingNetworkReply && this->m_pendingNetworkReply->isRunning())
|
||||||
{
|
{
|
||||||
this->m_pendingNetworkReply->abort();
|
this->m_pendingNetworkReply->abort();
|
||||||
QCoreApplication::processEvents(QEventLoop::AllEvents, 250); // allow the abort to be called
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// cancel or stop flag above should terminate QFuture
|
// cancel or stop flag above should terminate QFuture
|
||||||
this->m_pendingFuture.waitForFinished();
|
this->m_pendingFuture.waitForFinished();
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Thread safe, is in state stopped?
|
|
||||||
//! \threadsafe
|
|
||||||
bool isStopped() const
|
|
||||||
{
|
|
||||||
QReadLocker rl(&this->m_lock);
|
|
||||||
return this->m_stopped;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Set the update time
|
* Set the update time
|
||||||
* \param updatePeriodMs <=0 stops the timer
|
* \param updatePeriodMs <=0 stops the timer
|
||||||
@@ -116,9 +93,9 @@ namespace BlackMisc
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
//! Constructor
|
//! Constructor
|
||||||
CThreadedReader() : m_lock(QReadWriteLock::Recursive)
|
CThreadedReader(QObject *owner) : CContinuousWorker(owner),
|
||||||
|
m_updateTimer(new QTimer(this)), m_lock(QReadWriteLock::Recursive)
|
||||||
{
|
{
|
||||||
this->m_updateTimer = new QTimer();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Has pending network replay
|
//! Has pending network replay
|
||||||
@@ -137,20 +114,12 @@ namespace BlackMisc
|
|||||||
this->m_pendingFuture = future;
|
this->m_pendingFuture = future;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Thread safe, mark as to be stopped
|
|
||||||
//! \threadsafe
|
|
||||||
void setStopFlag()
|
|
||||||
{
|
|
||||||
QWriteLocker wl(&this->m_lock);
|
|
||||||
this->m_stopped = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
QTimer *m_updateTimer = nullptr; //!< update timer
|
QTimer *m_updateTimer = nullptr; //!< update timer
|
||||||
mutable QReadWriteLock m_lock; //!< lock
|
mutable QReadWriteLock m_lock; //!< lock
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QDateTime m_updateTimestamp; //!< when was file / resource read
|
QDateTime m_updateTimestamp; //!< when was file / resource read
|
||||||
bool m_stopped = false; //!< mark as stopped, threads should terminate
|
|
||||||
QFuture<FutureRet> m_pendingFuture; //!< optional future to be stopped
|
QFuture<FutureRet> m_pendingFuture; //!< optional future to be stopped
|
||||||
QNetworkReply *m_pendingNetworkReply = nullptr; //!< optional network reply to be stopped
|
QNetworkReply *m_pendingNetworkReply = nullptr; //!< optional network reply to be stopped
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user