mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-04-01 21:56:43 +08:00
* new read state "skipped" * renamed to "isNetworkConnectedAndAccessible" * checking before reading, which would only fail if network is not accessible
159 lines
4.8 KiB
C++
159 lines
4.8 KiB
C++
/* Copyright (C) 2013
|
|
* swift project Community / Contributors
|
|
*
|
|
* This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level
|
|
* directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project,
|
|
* including this file, may be copied, modified, propagated, or distributed except according to the terms
|
|
* contained in the LICENSE file.
|
|
*/
|
|
|
|
#include "blackcore/threadedreader.h"
|
|
#include "blackcore/application.h"
|
|
#include "blackmisc/network/networkutils.h"
|
|
#include "blackmisc/threadutils.h"
|
|
|
|
#include <QCoreApplication>
|
|
#include <QMetaObject>
|
|
#include <QReadLocker>
|
|
#include <QThread>
|
|
#include <QTimer>
|
|
#include <QWriteLocker>
|
|
|
|
using namespace BlackMisc;
|
|
using namespace BlackMisc::Network;
|
|
using namespace BlackCore::Vatsim;
|
|
|
|
namespace BlackCore
|
|
{
|
|
const CLogCategoryList &CThreadedReader::getLogCategories()
|
|
{
|
|
static const BlackMisc::CLogCategoryList cats { BlackMisc::CLogCategory::worker() };
|
|
return cats;
|
|
}
|
|
|
|
CThreadedReader::CThreadedReader(QObject *owner, const QString &name) :
|
|
CContinuousWorker(owner, name),
|
|
m_updateTimer(new QTimer(this))
|
|
{
|
|
connect(m_updateTimer, &QTimer::timeout, this, &CThreadedReader::doWork);
|
|
m_updateTimer->setSingleShot(true);
|
|
}
|
|
|
|
CThreadedReader::~CThreadedReader()
|
|
{
|
|
gracefulShutdown();
|
|
}
|
|
|
|
qint64 CThreadedReader::lastModifiedMsSinceEpoch(QNetworkReply *nwReply) const
|
|
{
|
|
return CNetworkUtils::lastModifiedMsSinceEpoch(nwReply);
|
|
}
|
|
|
|
QDateTime CThreadedReader::getUpdateTimestamp() const
|
|
{
|
|
QReadLocker lock(&this->m_lock);
|
|
return this->m_updateTimestamp;
|
|
}
|
|
|
|
void CThreadedReader::setUpdateTimestamp(const QDateTime &updateTimestamp)
|
|
{
|
|
QWriteLocker lock(&this->m_lock);
|
|
this->m_updateTimestamp = updateTimestamp;
|
|
}
|
|
|
|
bool CThreadedReader::updatedWithinLastMs(qint64 timeLastMs)
|
|
{
|
|
QDateTime dt(getUpdateTimestamp());
|
|
if (dt.isNull() || !dt.isValid()) { return false; }
|
|
qint64 delta = QDateTime::currentMSecsSinceEpoch() - dt.toMSecsSinceEpoch();
|
|
return delta <= timeLastMs;
|
|
}
|
|
|
|
bool CThreadedReader::isNetworkConnectedAndAccessible() const
|
|
{
|
|
return sApp->isNetworkConnectedAndAccessible();
|
|
}
|
|
|
|
void CThreadedReader::gracefulShutdown()
|
|
{
|
|
// if not in main thread stop, otherwise it makes no sense to abandon
|
|
this->m_shutdown = true;
|
|
if (!CThreadUtils::isCurrentThreadObjectThread(this))
|
|
{
|
|
this->abandonAndWait();
|
|
}
|
|
}
|
|
|
|
void CThreadedReader::startReader()
|
|
{
|
|
Q_ASSERT(m_initialTime > 0);
|
|
QTimer::singleShot(m_initialTime, this, [ = ] { this->doWork(); });
|
|
}
|
|
|
|
void CThreadedReader::pauseReader()
|
|
{
|
|
QTimer::singleShot(0, m_updateTimer, &QTimer::stop);
|
|
}
|
|
|
|
bool CThreadedReader::isShuttingDown() const
|
|
{
|
|
if (!sApp) { return true; } // sApp object is gone, whole system shutdown
|
|
if (this->m_shutdown) { return true; } // marked as shutdown
|
|
if (this->isAbandoned()) { return true; } // worker abandoned
|
|
return false;
|
|
}
|
|
|
|
bool CThreadedReader::didContentChange(const QString &content, int startPosition)
|
|
{
|
|
uint oldHash = 0;
|
|
{
|
|
QReadLocker rl(&this->m_lock);
|
|
oldHash = this->m_contentHash;
|
|
}
|
|
uint newHash = qHash(startPosition < 0 ? content : content.mid(startPosition));
|
|
if (oldHash == newHash) { return false; }
|
|
{
|
|
QWriteLocker wl(&this->m_lock);
|
|
this->m_contentHash = newHash;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool CThreadedReader::isMarkedAsFailed() const
|
|
{
|
|
return this->m_markedAsFailed;
|
|
}
|
|
|
|
void CThreadedReader::setMarkedAsFailed(bool failed)
|
|
{
|
|
this->m_markedAsFailed = failed;
|
|
}
|
|
|
|
void CThreadedReader::threadAssertCheck() const
|
|
{
|
|
Q_ASSERT_X(QCoreApplication::instance()->thread() != QThread::currentThread(), Q_FUNC_INFO, "Needs to run in own thread");
|
|
Q_ASSERT_X(QObject::thread() == QThread::currentThread(), Q_FUNC_INFO, "Wrong object thread");
|
|
}
|
|
|
|
void CThreadedReader::setInitialAndPeriodicTime(int initialTime, int periodicTime)
|
|
{
|
|
m_initialTime = initialTime;
|
|
m_periodicTime = periodicTime;
|
|
if (m_updateTimer->isActive())
|
|
{
|
|
int oldPeriodicTime = m_updateTimer->interval();
|
|
int delta = m_periodicTime - oldPeriodicTime + m_updateTimer->remainingTime();
|
|
m_updateTimer->start(qMax(delta, 0));
|
|
}
|
|
}
|
|
|
|
void CThreadedReader::doWork()
|
|
{
|
|
if (isFinished()) { return; }
|
|
doWorkImpl();
|
|
Q_ASSERT(m_periodicTime > 0);
|
|
m_updateTimer->start(m_periodicTime);
|
|
}
|
|
|
|
} // namespace
|