Files
pilotclient/src/blackmisc/simulation/backgroundvalidation.cpp
Klaus Basan f3ec7a8a68 Ref T660, utility functions
* check if model is in path
* addAsValidOrInvalidModel
* set corresponding simulator for validation
* display validation of empty model set
2019-09-16 20:29:57 +01:00

181 lines
6.6 KiB
C++

/* Copyright (C) 2019
* 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. 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 "backgroundvalidation.h"
#include "blackmisc/simulation/aircraftmodelutils.h"
#include "blackmisc/simulation/aircraftmodellist.h"
#include "blackmisc/threadutils.h"
#include "blackmisc/eventloop.h"
#include "blackmisc/logmessage.h"
#include <QDateTime>
using namespace BlackMisc::Network;
using namespace BlackMisc::Simulation::Data;
namespace BlackMisc
{
namespace Simulation
{
const CLogCategoryList &CBackgroundValidation::getLogCategories()
{
static const CLogCategoryList cats({ CLogCategory::worker(), CLogCategory::modelSetCache() });
return cats;
}
CBackgroundValidation::CBackgroundValidation(QObject *owner) :
CContinuousWorker(owner, "Background validation")
{
connect(&m_updateTimer, &QTimer::timeout, this, &CBackgroundValidation::doWork);
m_updateTimer.setInterval(60 * 1000);
}
void CBackgroundValidation::setCurrentSimulator(const CSimulatorInfo &simulator, const QString &simDirectory)
{
QWriteLocker l(&m_lock);
m_simulator = simulator;
m_simDirectory = simDirectory;
}
bool CBackgroundValidation::wasAlreadyChecked(const CSimulatorInfo &simulator) const
{
QReadLocker l(&m_lock);
return m_checkedSimulatorMsgs.contains(simulator);
}
void CBackgroundValidation::resetAlreadyChecked(const CSimulatorInfo &simulator)
{
QWriteLocker l(&m_lock);
m_checkedSimulatorMsgs.remove(simulator);
}
CSimulatorInfo CBackgroundValidation::getCurrentSimulator() const
{
QReadLocker l(&m_lock);
return m_simulator;
}
bool CBackgroundValidation::triggerValidation(const CSimulatorInfo &simulator, const QString &simDirectory)
{
const QPointer<CBackgroundValidation> myself(this);
if (simulator.isNoSimulator())
{
return this->requestLastValidationResults();
}
{
QWriteLocker l(&m_lock);
if (m_inWork) { return false; }
m_simulator = simulator;
m_simDirectory = simDirectory;
m_checkedSimulatorMsgs.remove(simulator);
}
QTimer::singleShot(0, this, [ = ]
{
if (!myself) { return; }
myself->doWork();
});
return true;
}
bool CBackgroundValidation::requestLastValidationResults()
{
CAircraftModelList valid;
CAircraftModelList invalid;
CAircraftModelList models;
CStatusMessageList msgs;
CSimulatorInfo simulator;
bool wasStopped = false;
{
QReadLocker l(&m_lock);
simulator = m_lastResultSimulator;
valid = m_lastResultValid;
invalid = m_lastResultInvalid;
msgs = m_lastResultMsgs;
wasStopped = m_lastResultWasStopped;
}
if (m_lastResultSimulator.isUnspecified()) { return false; }
emit this->validated(simulator, valid, invalid, wasStopped, msgs);
return true;
}
void CBackgroundValidation::doWork()
{
if (m_inWork) { return; }
m_inWork = true;
emit this->validating(true);
const bool isTimerBased = (QObject::sender() == &m_updateTimer);
CAircraftModelList valid;
CAircraftModelList invalid;
CStatusMessageList msgs;
bool wasStopped = false;
bool validated = false;
bool onlyErrorsAndWarnings = false;
const CSimulatorInfo simulator = this->getCurrentSimulator();
const qint64 started = QDateTime::currentMSecsSinceEpoch();
do
{
if (!simulator.isSingleSimulator()) { break; }
if (this->wasAlreadyChecked(simulator)) { break; }
const CAircraftMatcherSetup setup = m_matchingSettings.get();
if (!setup.doVerificationAtStartup()) { break; }
onlyErrorsAndWarnings = setup.onlyShowVerificationWarningsAndErrors();
const CAircraftModelList models = m_modelSets.getCachedModels(simulator);
const qint64 now = QDateTime::currentMSecsSinceEpoch();
validated = true;
if (models.isEmpty())
{
msgs.push_back(CStatusMessage(this, CStatusMessage::SeverityWarning, QStringLiteral("No models in set for '%1'").arg(simulator.toQString(true))));
}
else
{
msgs = CAircraftModelUtilities::validateModelFiles(simulator, models, valid, invalid, false, 25, wasStopped, m_simDirectory);
}
const qint64 deltaTimeMs = now - started;
msgs.push_back(CStatusMessage(this, CStatusMessage::SeverityInfo, QStringLiteral("Validated in %1ms").arg(deltaTimeMs)));
msgs.sortBySeverityHighestFirst();
msgs.freezeOrder();
QWriteLocker l(&m_lock);
m_lastResultValid = valid;
m_lastResultInvalid = invalid;
m_lastResultWasStopped = wasStopped;
m_lastResultSimulator = simulator;
m_lastResultMsgs = msgs;
m_checkedSimulatorMsgs.insert(simulator, msgs);
}
while (false);
m_inWork = false;
if (isTimerBased)
{
m_timerBasedRuns++;
// stop timer after some runs
if (m_timerBasedRuns > 3)
{
m_updateTimer.stop();
}
}
emit this->validating(false);
if (validated)
{
const bool e = !onlyErrorsAndWarnings || (!invalid.isEmpty() || msgs.hasWarningOrErrorMessages());
if (e || !isTimerBased) { emit this->validated(simulator, valid, invalid, wasStopped, msgs); }
}
}
} // ns
} // ns