From 116d428f84437cc999a735ba5169675fd9d46d14 Mon Sep 17 00:00:00 2001 From: Klaus Basan Date: Mon, 19 Mar 2018 20:33:34 +0100 Subject: [PATCH] Ref T259, Ref T243 added setup provider (interpolation setup) --- .../simulation/interpolationsetupprovider.cpp | 145 ++++++++++++++++++ .../simulation/interpolationsetupprovider.h | 109 +++++++++++++ 2 files changed, 254 insertions(+) create mode 100644 src/blackmisc/simulation/interpolationsetupprovider.cpp create mode 100644 src/blackmisc/simulation/interpolationsetupprovider.h diff --git a/src/blackmisc/simulation/interpolationsetupprovider.cpp b/src/blackmisc/simulation/interpolationsetupprovider.cpp new file mode 100644 index 000000000..bb580621f --- /dev/null +++ b/src/blackmisc/simulation/interpolationsetupprovider.cpp @@ -0,0 +1,145 @@ +/* Copyright (C) 2018 + * 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 "interpolationsetupprovider.h" + +using namespace BlackMisc::Aviation; + +namespace BlackMisc +{ + namespace Simulation + { + CInterpolationAndRenderingSetupPerCallsign IInterpolationSetupProvider::getInterpolationSetupPerCallsignOrDefault(const CCallsign &callsign) const + { + QReadLocker l(&m_lockSetup); + return m_setups.contains(callsign) ? m_setups.value(callsign) : CInterpolationAndRenderingSetupPerCallsign(callsign, m_globalSetup); + } + + CInterpolationSetupList IInterpolationSetupProvider::getInterpolationSetupsPerCallsign() const + { + const SetupsPerCallsign setups = this->getSetupsPerCallsign(); + return CInterpolationSetupList(setups.values()); + } + + void IInterpolationSetupProvider::setInterpolationSetupsPerCallsign(const CInterpolationSetupList &setups) + { + SetupsPerCallsign setupsPerCs; + for (const CInterpolationAndRenderingSetupPerCallsign &setup : setups) + { + setupsPerCs.insert(setup.getCallsign(), setup); + } + + QWriteLocker l(&m_lockSetup); + m_setups = setupsPerCs; + } + + CInterpolationAndRenderingSetupGlobal IInterpolationSetupProvider::getInterpolationSetupGlobal() const + { + QReadLocker l(&m_lockSetup); + return m_globalSetup; + } + + CCallsignSet IInterpolationSetupProvider::getLogCallsigns() const + { + const SetupsPerCallsign setups = this->getSetupsPerCallsign(); + CCallsignSet callsigns; + for (const CCallsign &cs : setups.keys()) + { + if (setups.value(cs).logInterpolation()) { callsigns.insert(cs); } + } + return callsigns; + } + + bool IInterpolationSetupProvider::setInterpolationSetupGlobal(const CInterpolationAndRenderingSetupGlobal &setup) + { + { + QReadLocker l(&m_lockSetup); + if (m_globalSetup == setup) { return false; } + } + + QWriteLocker l(&m_lockSetup); + m_globalSetup = setup; + return true; + } + + bool IInterpolationSetupProvider::setInterpolationSetupPerCallsign(const CInterpolationAndRenderingSetupPerCallsign &setup, const CCallsign &callsign, bool removeGlobalSetup) + { + if (removeGlobalSetup) + { + if (setup.isEqualToGlobal(this->getInterpolationSetupGlobal())) + { + QWriteLocker l(&m_lockSetup); + m_setups.remove(callsign); + return false; + } + } + QWriteLocker l(&m_lockSetup); + m_setups[callsign] = setup; + return true; + } + + void IInterpolationSetupProvider::setLogCallsign(bool log, const CCallsign &callsign) + { + CInterpolationAndRenderingSetupPerCallsign setup = this->getInterpolationSetupPerCallsignOrDefault(callsign); + if (setup.logInterpolation() == log) { return; } + setup.setLogInterpolation(log); + this->setInterpolationSetupPerCallsign(setup, callsign); + } + + void IInterpolationSetupProvider::clearInterpolationLogCallsigns() + { + SetupsPerCallsign setupsCopy = this->getSetupsPerCallsign(); + if (setupsCopy.isEmpty()) { return; } + + // potential risk, changes inbetween in another thread are missed now + // on the other side, we keep locks for a minimal time frame + SetupsPerCallsign setupsToKeep; + CInterpolationAndRenderingSetupGlobal global = this->getInterpolationSetupGlobal(); + for (const CCallsign &cs : setupsCopy.keys()) + { + CInterpolationAndRenderingSetupPerCallsign setup = setupsCopy.value(cs); + setup.setLogInterpolation(false); + if (setup.isEqualToGlobal(global)) { continue; } + setupsToKeep.insert(cs, setup); + } + + QWriteLocker l(&m_lockSetup); + m_setups = setupsToKeep; + } + + bool IInterpolationSetupProvider::logAnyCallsign() const + { + const SetupsPerCallsign setupsCopy = this->getSetupsPerCallsign(); + if (setupsCopy.isEmpty()) { return false; } + for (const CCallsign &cs : setupsCopy.keys()) + { + if (setupsCopy.value(cs).logInterpolation()) { return true; } + } + return false; + } + + IInterpolationSetupProvider::SetupsPerCallsign IInterpolationSetupProvider::getSetupsPerCallsign() const + { + QReadLocker l(&m_lockSetup); + return m_setups; + } + + CInterpolationAndRenderingSetupPerCallsign CInterpolationSetupAware::getInterpolationSetupPerCallsignOrDefault(const CCallsign &callsign) const + { + if (!this->hasProvider()) { return CInterpolationAndRenderingSetupPerCallsign(); } + return this->provider()->getInterpolationSetupPerCallsignOrDefault(callsign); + } + + CInterpolationAndRenderingSetupGlobal CInterpolationSetupAware::getInterpolationSetupGlobal() const + { + if (!this->hasProvider()) { return CInterpolationAndRenderingSetupGlobal(); } + return this->provider()->getInterpolationSetupGlobal(); + } + } // namespace +} // namespace diff --git a/src/blackmisc/simulation/interpolationsetupprovider.h b/src/blackmisc/simulation/interpolationsetupprovider.h new file mode 100644 index 000000000..89f721325 --- /dev/null +++ b/src/blackmisc/simulation/interpolationsetupprovider.h @@ -0,0 +1,109 @@ +/* Copyright (C) 2018 + * 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_INTERPOLATIONSETUPPROVIDER_H +#define BLACKMISC_SIMULATION_INTERPOLATIONSETUPPROVIDER_H + +#include "interpolationsetuplist.h" +#include "interpolationrenderingsetup.h" +#include "interpolationsetuplist.h" +#include "blackmisc/aviation/callsignset.h" +#include "blackmisc/provider.h" +#include +#include + +namespace BlackMisc +{ + namespace Simulation + { + //! Direct in memory access to client (network client) data + class BLACKMISC_EXPORT IInterpolationSetupProvider : public IProvider + { + public: + using SetupsPerCallsign = QMap; //!< setups per callsign + + //! Get the setup for callsign, if not existing the global setup + //! \threadsafe + CInterpolationAndRenderingSetupPerCallsign getInterpolationSetupPerCallsignOrDefault(const Aviation::CCallsign &callsign) const; + + //! Get all setups per callsign + //! \threadsafe + virtual CInterpolationSetupList getInterpolationSetupsPerCallsign() const; + + //! Set all setups per callsign + //! \threadsafe + virtual void setInterpolationSetupsPerCallsign(const CInterpolationSetupList &setups); + + //! The global setup + //! \threadsafe + virtual CInterpolationAndRenderingSetupGlobal getInterpolationSetupGlobal() const; + + //! All callsigns marked to be logged + //! \threadsafe + Aviation::CCallsignSet getLogCallsigns() const; + + protected: + //! Set the global setup + //! \threadsafe + bool setInterpolationSetupGlobal(const CInterpolationAndRenderingSetupGlobal &setup); + + //! Insert specialized setup + //! \threadsafe + bool setInterpolationSetupPerCallsign(const CInterpolationAndRenderingSetupPerCallsign &setup, const Aviation::CCallsign &callsign, bool removeGlobalSetup = true); + + //! Log/un-log given callsign + //! \threadsafe + void setLogCallsign(bool log, const Aviation::CCallsign &callsign); + + //! Clear all interpolation log callsigns + //! \threadsafe + void clearInterpolationLogCallsigns(); + + //! Log any callsign? + //! \threadsafe + bool logAnyCallsign() const; + + //! The setups per callsign + //! \threadsafe + SetupsPerCallsign getSetupsPerCallsign() const; + + private: + CInterpolationAndRenderingSetupGlobal m_globalSetup; + SetupsPerCallsign m_setups; + mutable QReadWriteLock m_lockSetup; //!< lock clients + }; + + //! Class which can be directly used to access an \sa IInterpolationSetupProvider object + class BLACKMISC_EXPORT CInterpolationSetupAware : public IProviderAware + { + public: + //! \copydoc IInterpolationSetupProvider::getInterpolationSetupPerCallsignOrDefault + CInterpolationAndRenderingSetupPerCallsign getInterpolationSetupPerCallsignOrDefault(const Aviation::CCallsign &callsign) const; + + //! \copydoc IInterpolationSetupProvider::getInterpolationSetupGlobal + CInterpolationAndRenderingSetupGlobal getInterpolationSetupGlobal() const; + + protected: + //! Default constructor + CInterpolationSetupAware() {} + + //! Constructor + CInterpolationSetupAware(IInterpolationSetupProvider *setupProvider) : IProviderAware(setupProvider) { } + + //! Provider + void setInterpolationSetupProvider(IInterpolationSetupProvider *provider) { this->setProvider(provider); } + }; + } // namespace +} // namespace + +Q_DECLARE_INTERFACE(BlackMisc::Simulation::IInterpolationSetupProvider, "org.swift-project.blackmisc::network::iinterpolationsetupprovider") + +#endif // guard