From 2181702c5cd092af79e0fa2f15480d1d0e230742 Mon Sep 17 00:00:00 2001 From: Mathew Sutcliffe Date: Sun, 5 Feb 2017 16:51:55 +0000 Subject: [PATCH] refs #863 Change interpolation setup member to be a method parameter instead. --- src/blackcore/simulator.h | 2 ++ src/blackcore/simulatorcommon.cpp | 13 ++++--- src/blackcore/simulatorcommon.h | 2 ++ src/blackmisc/simulation/interpolator.cpp | 34 +++++-------------- src/blackmisc/simulation/interpolator.h | 23 +++---------- .../simulation/interpolatorlinear.cpp | 4 +-- src/blackmisc/simulation/interpolatorlinear.h | 2 +- src/plugins/simulator/fs9/fs9client.cpp | 14 +++++++- src/plugins/simulator/fs9/fs9client.h | 8 +++++ src/plugins/simulator/fsx/simulatorfsx.cpp | 6 ++-- src/xbus/traffic.cpp | 6 ++-- tests/blackmisc/testinterpolator.cpp | 7 ++-- 12 files changed, 58 insertions(+), 63 deletions(-) diff --git a/src/blackcore/simulator.h b/src/blackcore/simulator.h index 047de1e53..926c3d14a 100644 --- a/src/blackcore/simulator.h +++ b/src/blackcore/simulator.h @@ -125,9 +125,11 @@ namespace BlackCore virtual BlackMisc::PhysicalQuantities::CTime getTimeSynchronizationOffset() const = 0; //! Debugging messages etc. + //! \threadsafe virtual BlackMisc::Simulation::CInterpolationAndRenderingSetup getInterpolationAndRenderingSetup() const = 0; //! Enable debugging messages etc. + //! \threadsafe virtual void setInterpolationAndRenderingSetup(const BlackMisc::Simulation::CInterpolationAndRenderingSetup &setup) = 0; //! Is the aircraft rendered (displayed in simulator)? diff --git a/src/blackcore/simulatorcommon.cpp b/src/blackcore/simulatorcommon.cpp index f1133a3f0..a4e013b69 100644 --- a/src/blackcore/simulatorcommon.cpp +++ b/src/blackcore/simulatorcommon.cpp @@ -310,9 +310,11 @@ namespace BlackCore void CSimulatorCommon::setInterpolationAndRenderingSetup(const CInterpolationAndRenderingSetup &setup) { - this->m_interpolator->setInterpolatorSetup(setup); - if (this->m_interpolationRenderingSetup == setup) { return; } - this->m_interpolationRenderingSetup = setup; + { + QWriteLocker lock(&this->m_interpolationRenderingSetupMutex); + if (this->m_interpolationRenderingSetup == setup) { return; } + this->m_interpolationRenderingSetup = setup; + } const bool r = setup.isRenderingRestricted(); const bool e = setup.isRenderingEnabled(); @@ -322,6 +324,7 @@ namespace BlackCore CInterpolationAndRenderingSetup CSimulatorCommon::getInterpolationAndRenderingSetup() const { + QReadLocker lock(&this->m_interpolationRenderingSetupMutex); return m_interpolationRenderingSetup; } @@ -369,12 +372,10 @@ namespace BlackCore // .plugin loginterpolator etc. if (parser.part(1).startsWith("logint") && parser.hasPart(2)) { - if (!this->m_interpolator) { return false; } const QString p = parser.part(2).toLower(); if (p == "off" || p == "false") { this->m_interpolationRenderingSetup.clearInterpolatorLogCallsigns(); - this->m_interpolator->setInterpolatorSetup(this->m_interpolationRenderingSetup); CStatusMessage(this).info("Disabled interpolation logging"); return true; } @@ -388,7 +389,6 @@ namespace BlackCore { // stop logging this->m_interpolationRenderingSetup.clearInterpolatorLogCallsigns(); - this->m_interpolator->setInterpolatorSetup(this->m_interpolationRenderingSetup); // write this->m_interpolator->writeLogInBackground(); @@ -401,7 +401,6 @@ namespace BlackCore if (this->getAircraftInRangeCallsigns().contains(cs)) { this->m_interpolationRenderingSetup.addCallsignToLog(CCallsign(cs)); - this->m_interpolator->setInterpolatorSetup(this->m_interpolationRenderingSetup); CLogMessage(this).info("Will log interpolation for '%1'") << cs; return true; } diff --git a/src/blackcore/simulatorcommon.h b/src/blackcore/simulatorcommon.h index aa3cc7e17..46b6dae72 100644 --- a/src/blackcore/simulatorcommon.h +++ b/src/blackcore/simulatorcommon.h @@ -14,6 +14,7 @@ #include #include +#include #include #include "blackcore/aircraftmatcher.h" @@ -187,6 +188,7 @@ namespace BlackCore int m_statsUpdateAircraftCountMs = 0; //!< statistics update time BlackMisc::Simulation::CSimulatorInternals m_simulatorInternals; //!< setup object BlackMisc::Simulation::CInterpolationAndRenderingSetup m_interpolationRenderingSetup; //!< logging, rendering etc. + mutable QReadWriteLock m_interpolationRenderingSetupMutex; //!< mutex protecting setup object // some optional functionality which can be used by the sims as needed BlackMisc::Simulation::CSimulatedAircraftList m_aircraftToAddAgainWhenRemoved; //!< add this model again when removed, normally used to change model diff --git a/src/blackmisc/simulation/interpolator.cpp b/src/blackmisc/simulation/interpolator.cpp index 79c94c6c6..632836767 100644 --- a/src/blackmisc/simulation/interpolator.cpp +++ b/src/blackmisc/simulation/interpolator.cpp @@ -35,11 +35,8 @@ namespace BlackMisc this->setObjectName(objectName); } - IInterpolator::~IInterpolator() - { } - BlackMisc::Aviation::CAircraftSituation IInterpolator::getInterpolatedSituation( - const CCallsign &callsign, qint64 currentTimeSinceEpoc, + const CCallsign &callsign, qint64 currentTimeSinceEpoc, const CInterpolationAndRenderingSetup &setup, const CInterpolationHints &hints, InterpolationStatus &status) const { // has to be thread safe @@ -47,13 +44,15 @@ namespace BlackMisc status.reset(); Q_ASSERT_X(!callsign.isEmpty(), Q_FUNC_INFO, "empty callsign"); - auto currentSituation = this->getInterpolatedSituation(callsign, this->remoteAircraftSituations(callsign), currentTimeSinceEpoc, hints, status); + auto currentSituation = this->getInterpolatedSituation(callsign, this->remoteAircraftSituations(callsign), currentTimeSinceEpoc, setup, hints, status); currentSituation.setCallsign(callsign); // make sure callsign is correct return currentSituation; } - CAircraftParts IInterpolator::getInterpolatedParts(const CCallsign &callsign, const CAircraftPartsList &parts, qint64 currentTimeMsSinceEpoch, IInterpolator::PartsStatus &partsStatus, bool log) const + CAircraftParts IInterpolator::getInterpolatedParts(const CCallsign &callsign, const CAircraftPartsList &parts, qint64 currentTimeMsSinceEpoch, + const CInterpolationAndRenderingSetup &setup, IInterpolator::PartsStatus &partsStatus, bool log) const { + Q_UNUSED(setup); partsStatus.reset(); if (currentTimeMsSinceEpoch < 0) { currentTimeMsSinceEpoch = QDateTime::currentMSecsSinceEpoch(); } @@ -114,27 +113,16 @@ namespace BlackMisc return currentParts; } - CAircraftParts IInterpolator::getInterpolatedParts(const CCallsign &callsign, qint64 currentTimeMsSinceEpoch, IInterpolator::PartsStatus &partsStatus, bool log) const + CAircraftParts IInterpolator::getInterpolatedParts(const CCallsign &callsign, qint64 currentTimeMsSinceEpoch, + const CInterpolationAndRenderingSetup &setup, IInterpolator::PartsStatus &partsStatus, bool log) const { Q_ASSERT_X(!callsign.isEmpty(), Q_FUNC_INFO, "empty callsign"); partsStatus.reset(); - return this->getInterpolatedParts(callsign, this->remoteAircraftParts(callsign, -1), currentTimeMsSinceEpoch, partsStatus, log); - } - - void IInterpolator::setInterpolatorSetup(const CInterpolationAndRenderingSetup &setup) - { - QWriteLocker l(&m_lockSetup); - m_setup = setup; + return this->getInterpolatedParts(callsign, this->remoteAircraftParts(callsign, -1), currentTimeMsSinceEpoch, setup, partsStatus, log); } CWorker *IInterpolator::writeLogInBackground() { - // make sure logging is stopped - { - QWriteLocker l(&m_lockSetup); - m_setup.clearInterpolatorLogCallsigns(); - } - QList interpolation; QList parts; { @@ -209,12 +197,6 @@ namespace BlackMisc } } - CInterpolationAndRenderingSetup IInterpolator::getInterpolatorSetup() const - { - QReadLocker l(&m_lockSetup); - return m_setup; - } - void IInterpolator::logInterpolation(const IInterpolator::InterpolationLog &log) const { QWriteLocker l(&m_lockLogs); diff --git a/src/blackmisc/simulation/interpolator.h b/src/blackmisc/simulation/interpolator.h index f9cfdc35f..e8b470706 100644 --- a/src/blackmisc/simulation/interpolator.h +++ b/src/blackmisc/simulation/interpolator.h @@ -39,9 +39,6 @@ namespace BlackMisc Q_OBJECT public: - //! Virtual destructor - virtual ~IInterpolator(); - //! Log category static QString getLogCategory() { return "swift.interpolator"; } @@ -96,7 +93,7 @@ namespace BlackMisc //! \threadsafe virtual BlackMisc::Aviation::CAircraftSituation getInterpolatedSituation( const BlackMisc::Aviation::CCallsign &callsign, qint64 currentTimeSinceEpoc, - const CInterpolationHints &hints, InterpolationStatus &status) const; + const CInterpolationAndRenderingSetup &setup, const CInterpolationHints &hints, InterpolationStatus &status) const; //! Current interpolated situation, to be implemented by subclass //! \threadsafe @@ -104,24 +101,20 @@ namespace BlackMisc virtual BlackMisc::Aviation::CAircraftSituation getInterpolatedSituation( const BlackMisc::Aviation::CCallsign &callsign, const BlackMisc::Aviation::CAircraftSituationList &situations, qint64 currentTimeSinceEpoc, - const CInterpolationHints &hints, InterpolationStatus &status) const = 0; + const CInterpolationAndRenderingSetup &setup, const CInterpolationHints &hints, InterpolationStatus &status) const = 0; //! Parts before given offset time (aka pending parts) //! \threadsafe virtual BlackMisc::Aviation::CAircraftParts getInterpolatedParts( const Aviation::CCallsign &callsign, const BlackMisc::Aviation::CAircraftPartsList &parts, qint64 cutoffTime, - PartsStatus &partsStatus, bool log = false) const; + const CInterpolationAndRenderingSetup &setup, PartsStatus &partsStatus, bool log = false) const; //! Parts before given offset time (aka pending parts) //! \threadsafe virtual BlackMisc::Aviation::CAircraftParts getInterpolatedParts( const BlackMisc::Aviation::CCallsign &callsign, qint64 cutoffTime, - PartsStatus &partsStatus, bool log = false) const; - - //! Enable debug messages etc. - //! \threadsafe - void setInterpolatorSetup(const CInterpolationAndRenderingSetup &setup); + const CInterpolationAndRenderingSetup &setup, PartsStatus &partsStatus, bool log = false) const; //! Write a log in background //! \threadsafe @@ -130,11 +123,6 @@ namespace BlackMisc //! Clear log file void clearLog(); - //! Enable log messages etc. - //! \threadsafe - //! \remark public for FS9 to get setup in Fs9Client - CInterpolationAndRenderingSetup getInterpolatorSetup() const; - //! Takes input between 0 and 1 and returns output between 0 and 1 smoothed with an S-shaped curve. //! //! Useful for making interpolation seem smoother, efficiently as it just uses simple arithmetic. @@ -201,8 +189,6 @@ namespace BlackMisc //! Set on ground flag static void setGroundFlagFromInterpolator(const CInterpolationHints &hints, double groundFactor, BlackMisc::Aviation::CAircraftSituation &situation); - CInterpolationAndRenderingSetup m_setup; //!< allows to enable/disable debug/log messages - private: //! Write log to file static CStatusMessageList writeLogFile(const QList &interpolation, const QList &parts); @@ -216,7 +202,6 @@ namespace BlackMisc //! Create readable time static QString msSinceEpochToTime(qint64 t1, qint64 t2, qint64 t3 = -1); - mutable QReadWriteLock m_lockSetup; //!< lock setup mutable QReadWriteLock m_lockLogs; //!< lock logging mutable QList m_partsLogs; //!< logs of parts mutable QList m_interpolationLogs; //!< logs of interpolation diff --git a/src/blackmisc/simulation/interpolatorlinear.cpp b/src/blackmisc/simulation/interpolatorlinear.cpp index 5a779e610..c6e3f1190 100644 --- a/src/blackmisc/simulation/interpolatorlinear.cpp +++ b/src/blackmisc/simulation/interpolatorlinear.cpp @@ -40,12 +40,12 @@ namespace BlackMisc { namespace Simulation { - CAircraftSituation CInterpolatorLinear::getInterpolatedSituation(const CCallsign &callsign, const CAircraftSituationList &situations, qint64 currentTimeMsSinceEpoc, const CInterpolationHints &hints, InterpolationStatus &status) const + CAircraftSituation CInterpolatorLinear::getInterpolatedSituation(const CCallsign &callsign, const CAircraftSituationList &situations, qint64 currentTimeMsSinceEpoc, + const CInterpolationAndRenderingSetup &setup, const CInterpolationHints &hints, InterpolationStatus &status) const { // // function has to be thread safe // - const CInterpolationAndRenderingSetup setup = this->getInterpolatorSetup(); status.reset(); // any data at all? diff --git a/src/blackmisc/simulation/interpolatorlinear.h b/src/blackmisc/simulation/interpolatorlinear.h index 60130d057..e0a1f59f3 100644 --- a/src/blackmisc/simulation/interpolatorlinear.h +++ b/src/blackmisc/simulation/interpolatorlinear.h @@ -42,7 +42,7 @@ namespace BlackMisc //! \copydoc IInterpolator::getInterpolatedSituation virtual BlackMisc::Aviation::CAircraftSituation getInterpolatedSituation( const BlackMisc::Aviation::CCallsign &callsign, - const BlackMisc::Aviation::CAircraftSituationList &situations, qint64 currentTimeSinceEpoc, + const BlackMisc::Aviation::CAircraftSituationList &situations, qint64 currentTimeSinceEpoc, const CInterpolationAndRenderingSetup &setup, const BlackMisc::Simulation::CInterpolationHints &hints, InterpolationStatus &status) const override; //! Log category diff --git a/src/plugins/simulator/fs9/fs9client.cpp b/src/plugins/simulator/fs9/fs9client.cpp index 7fd4b17bc..186076d97 100644 --- a/src/plugins/simulator/fs9/fs9client.cpp +++ b/src/plugins/simulator/fs9/fs9client.cpp @@ -162,6 +162,18 @@ namespace BlackSimPlugin } } + void CFs9Client::setInterpolationSetup(const CInterpolationAndRenderingSetup &setup) + { + QWriteLocker lock(&m_interpolationSetupMutex); + m_interpolationSetup = setup; + } + + CInterpolationAndRenderingSetup CFs9Client::getInterpolationSetup() const + { + QReadLocker lock(&m_interpolationSetupMutex); + return m_interpolationSetup; + } + void CFs9Client::timerEvent(QTimerEvent *event) { Q_UNUSED(event); @@ -172,7 +184,7 @@ namespace BlackSimPlugin IInterpolator::InterpolationStatus status; CInterpolationHints hints; // \fixme 201701 #865 KB if there is an elevation provider for FS9 add it here or set elevation hints.setLoggingInterpolation(this->m_interpolator->getInterpolatorSetup().getLogCallsigns().contains(m_callsign)); - const CAircraftSituation situation = this->m_interpolator->getInterpolatedSituation(m_callsign, -1, hints, status); + const CAircraftSituation situation = this->m_interpolator->getInterpolatedSituation(m_callsign, -1, this->m_interpolationSetup, hints, status); // Test only for successful interpolation. FS9 requires constant positions if (!status.didInterpolationSucceed()) { return; } diff --git a/src/plugins/simulator/fs9/fs9client.h b/src/plugins/simulator/fs9/fs9client.h index dec55a739..3c6f9c8d2 100644 --- a/src/plugins/simulator/fs9/fs9client.h +++ b/src/plugins/simulator/fs9/fs9client.h @@ -17,6 +17,7 @@ #include "blackmisc/aviation/callsign.h" #include #include +#include //! \file @@ -49,6 +50,9 @@ namespace BlackSimPlugin //! Set DirectPlay host address void setHostAddress(const QString &hostAddress); + //! Set interpolation setup + //! \threadsafe + void setInterpolationSetup(const BlackMisc::Simulation::CInterpolationAndRenderingSetup &setup); public slots: //! Send new text message @@ -88,8 +92,12 @@ namespace BlackSimPlugin void sendMultiplayerParamaters(); void sendMultiplayerChangePlayerPlane(); + BlackMisc::Simulation::CInterpolationAndRenderingSetup getInterpolationSetup() const; + BlackMisc::PhysicalQuantities::CTime m_updateInterval; BlackMisc::Simulation::IInterpolator *m_interpolator = nullptr; + BlackMisc::Simulation::CInterpolationAndRenderingSetup m_interpolationSetup; + mutable QReadWriteLock m_interpolationSetupMutex; QString m_modelName; int m_timerId = 0; diff --git a/src/plugins/simulator/fsx/simulatorfsx.cpp b/src/plugins/simulator/fsx/simulatorfsx.cpp index e9135172b..3e4c57ddd 100644 --- a/src/plugins/simulator/fsx/simulatorfsx.cpp +++ b/src/plugins/simulator/fsx/simulatorfsx.cpp @@ -906,14 +906,16 @@ namespace BlackSimPlugin const bool logInterpolationAndParts = callsignsToLog.contains(callsign); IInterpolator::PartsStatus partsStatus; partsStatus.setSupportsParts(useAircraftParts); - const CAircraftParts parts = useAircraftParts ? this->m_interpolator->getInterpolatedParts(callsign, -1, partsStatus, logInterpolationAndParts) : CAircraftParts(); + + const CInterpolationAndRenderingSetup setup(getInterpolationAndRenderingSetup()); + const CAircraftParts parts = useAircraftParts ? this->m_interpolator->getInterpolatedParts(callsign, -1, setup, partsStatus, logInterpolationAndParts) : CAircraftParts(); // get interpolated situation IInterpolator::InterpolationStatus interpolatorStatus; CInterpolationHints hints(m_hints[simObj.getCallsign()]); hints.setAircraftParts(useAircraftParts ? parts : CAircraftParts(), useAircraftParts); hints.setLoggingInterpolation(logInterpolationAndParts); - const CAircraftSituation interpolatedSituation = this->m_interpolator->getInterpolatedSituation(callsign, currentTimestamp, hints, interpolatorStatus); + const CAircraftSituation interpolatedSituation = this->m_interpolator->getInterpolatedSituation(callsign, currentTimestamp, setup, hints, interpolatorStatus); if (interpolatorStatus.allTrue()) { diff --git a/src/xbus/traffic.cpp b/src/xbus/traffic.cpp index c6f8d1d23..cd267f280 100644 --- a/src/xbus/traffic.cpp +++ b/src/xbus/traffic.cpp @@ -48,9 +48,10 @@ namespace XBus // also to disable aircraft parts / or logging parts (log file). I wonder if you want to consider it here // e.g. interpolator->getInterpolatorSetup().getLogCallsigns().contains(callsign) // if the setup is needed more than once, store it here to avoid multiple locks + BlackMisc::Simulation::CInterpolationAndRenderingSetup setup; BlackMisc::Simulation::CInterpolationHints hints; BlackMisc::Simulation::IInterpolator::PartsStatus status; - hints.setAircraftParts(interpolator->getInterpolatedParts(callsign, parts, -1, status)); + hints.setAircraftParts(interpolator->getInterpolatedParts(callsign, parts, -1, setup, status)); hints.setElevationProvider([this](const auto & situation) { using namespace BlackMisc::PhysicalQuantities; @@ -338,8 +339,9 @@ namespace XBus { if (plane->situations.size() < 3) { return xpmpData_Unavailable; } // avoid sudden movements when a pilot connects + BlackMisc::Simulation::CInterpolationAndRenderingSetup setup; BlackMisc::Simulation::IInterpolator::InterpolationStatus status; - const auto situation = m_interpolator->getInterpolatedSituation(plane->callsign, plane->situations, -1, plane->hints(m_interpolator), status); + const auto situation = m_interpolator->getInterpolatedSituation(plane->callsign, plane->situations, -1, setup, plane->hints(m_interpolator), status); if (! status.didInterpolationSucceed()) { return xpmpData_Unavailable; } if (! status.hasChangedPosition()) { return xpmpData_Unchanged; } diff --git a/tests/blackmisc/testinterpolator.cpp b/tests/blackmisc/testinterpolator.cpp index 33f471d8f..a0d9939a8 100644 --- a/tests/blackmisc/testinterpolator.cpp +++ b/tests/blackmisc/testinterpolator.cpp @@ -92,6 +92,7 @@ namespace BlackMiscTest // interpolation functional check IInterpolator::InterpolationStatus status; const CInterpolationHints hints; + const CInterpolationAndRenderingSetup setup; double latOld = 360.0; double lngOld = 360.0; for (qint64 currentTime = ts - 2 * deltaT + offset; currentTime < ts + offset; currentTime += (deltaT / 20)) @@ -100,7 +101,7 @@ namespace BlackMiscTest // from: ts - 2 * deltaT + offset // to: ts + offset CAircraftSituation currentSituation(interpolator.getInterpolatedSituation - (cs, currentTime, hints, status) + (cs, currentTime, setup, hints, status) ); QVERIFY2(status.didInterpolationSucceed(), "Interpolation was not succesful"); QVERIFY2(status.hasChangedPosition(), "Interpolation did not changed"); @@ -130,7 +131,7 @@ namespace BlackMiscTest // from: ts - 2* deltaT + offset // to: ts + offset CAircraftSituation currentSituation(interpolator.getInterpolatedSituation - (cs, currentTime, hints, status) + (cs, currentTime, setup, hints, status) ); QVERIFY2(status.allTrue(), "Failed interpolation"); QVERIFY2(currentSituation.getCallsign() == cs, "Wrong callsign"); @@ -150,7 +151,7 @@ namespace BlackMiscTest for (qint64 currentTime = ts - 2 * deltaT; currentTime < ts; currentTime += 250) { IInterpolator::PartsStatus partsStatus; - CAircraftParts pl(interpolator.getInterpolatedParts(cs, ts, partsStatus)); + CAircraftParts pl(interpolator.getInterpolatedParts(cs, ts, setup, partsStatus)); fetchedParts++; QVERIFY2(partsStatus.isSupportingParts(), "Parts not supported"); }