From 0bcd47b277bf2f336ef6888f221e6d1f625bfbdc Mon Sep 17 00:00:00 2001 From: Klaus Basan Date: Sun, 20 Jan 2019 19:28:34 +0100 Subject: [PATCH] Ref T515, background validation for models (in simulator context) --- .../simulation/backgroundvalidation.cpp | 120 ++++++++++++++++++ .../simulation/backgroundvalidation.h | 85 +++++++++++++ 2 files changed, 205 insertions(+) create mode 100644 src/blackmisc/simulation/backgroundvalidation.cpp create mode 100644 src/blackmisc/simulation/backgroundvalidation.h diff --git a/src/blackmisc/simulation/backgroundvalidation.cpp b/src/blackmisc/simulation/backgroundvalidation.cpp new file mode 100644 index 000000000..904233a49 --- /dev/null +++ b/src/blackmisc/simulation/backgroundvalidation.cpp @@ -0,0 +1,120 @@ +/* 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 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 "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 + +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) + { + QWriteLocker l(&m_lock); + m_simulator = simulator; + } + + 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) + { + { + QWriteLocker l(&m_lock); + if (m_inWork) { return false; } + m_simulator = simulator; + m_checkedSimulatorMsgs.remove(simulator); + } + QTimer::singleShot(0, this, &CBackgroundValidation::doWork); + return true; + } + + void CBackgroundValidation::doWork() + { + if (m_inWork) { return; } + m_inWork = true; + emit this->validating(true); + + CAircraftModelList valid; + CAircraftModelList invalid; + CAircraftModelList models; + CStatusMessageList msgs; + bool wasStopped = false; + bool validated = 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; } + + models = m_modelSets.getCachedModels(simulator); + msgs = CAircraftModelUtilities::validateModelFiles(models, valid, invalid, false, 25, wasStopped); + + const qint64 deltaTimeMs = QDateTime::currentMSecsSinceEpoch() - started; + msgs.push_back(CStatusMessage(this, CStatusMessage::SeverityInfo, QStringLiteral("Validated in %1ms").arg(deltaTimeMs))); + + validated = true; + + QWriteLocker l(&m_lock); + m_checkedSimulatorMsgs.insert(simulator, msgs); + } + while (false); + + + m_inWork = false; + emit this->validating(false); + if (validated) + { + emit this->validated(simulator, valid, invalid, wasStopped, msgs); + } + } + } // ns +} // ns diff --git a/src/blackmisc/simulation/backgroundvalidation.h b/src/blackmisc/simulation/backgroundvalidation.h new file mode 100644 index 000000000..9dfa74fde --- /dev/null +++ b/src/blackmisc/simulation/backgroundvalidation.h @@ -0,0 +1,85 @@ +/* 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 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. + */ + +//! \file + +#ifndef BLACKMISC_SIMULATION_BACKGROUNDVALIDATION_H +#define BLACKMISC_SIMULATION_BACKGROUNDVALIDATION_H + +#include "blackmisc/simulation/settings/modelmatchersettings.h" +#include "blackmisc/simulation/data/modelcaches.h" +#include "blackmisc/network/entityflags.h" +#include "blackmisc/settingscache.h" +#include "blackmisc/worker.h" +#include "blackmisc/statusmessagelist.h" +#include "blackmisc/blackmiscexport.h" + +#include +#include +#include + +namespace BlackMisc +{ + namespace Simulation + { + //! Update and consolidation of DB data + class BLACKMISC_EXPORT CBackgroundValidation : public CContinuousWorker + { + Q_OBJECT + + public: + //! Log categories + static const CLogCategoryList &getLogCategories(); + + //! Constructor + CBackgroundValidation(QObject *owner); + + //! Corresponding simulator + //! \threadsafe + void setCurrentSimulator(const CSimulatorInfo &simulator); + + //! Was already checked for simulator? + //! \threadsafe + bool wasAlreadyChecked(const CSimulatorInfo &simulator) const; + + //! Reset checked for simulator + //! \threadsafe + void resetAlreadyChecked(const CSimulatorInfo &simulator); + + //! Corresponding simulator + //! \threadsafe + BlackMisc::Simulation::CSimulatorInfo getCurrentSimulator() const; + + //! Trigger a validation, returns false if "work in progress" + //! \threadsafe + bool triggerValidation(const CSimulatorInfo &simulator); + + signals: + //! Validating + void validating(bool running); + + //! Validated for simulator + void validated(const CSimulatorInfo &simulator, const CAircraftModelList &validModels, const CAircraftModelList &invalidModels, bool stopped, const CStatusMessageList &msgs); + + private: + mutable QReadWriteLock m_lock; //!< lock snapshot + std::atomic_bool m_inWork { false }; //!< indicates a running update + CSimulatorInfo m_simulator; + QMap m_checkedSimulatorMsgs; + CSetting m_matchingSettings { this }; //!< settings + + // Set/caches as member as we are in own thread, central instance will not work + Data::CModelSetCaches m_modelSets { false, this }; + + //! Do the update checks + void doWork(); + }; + } // ns +} // ns +#endif // guard