diff --git a/src/blackmisc/simulation/interpolant.h b/src/blackmisc/simulation/interpolant.h index 255896d41..21199d658 100644 --- a/src/blackmisc/simulation/interpolant.h +++ b/src/blackmisc/simulation/interpolant.h @@ -14,6 +14,27 @@ namespace BlackMisc::Simulation class IInterpolant { public: + //! Default ctor + IInterpolant() = default; + + //! Constructor + explicit IInterpolant(int situationsAvailable) : m_situationsAvailable(situationsAvailable) {} + + //! Constructor + IInterpolant(qint64 interpolatedTime, int situationsAvailable) : m_interpolatedTime(interpolatedTime), m_situationsAvailable(situationsAvailable) {} + + virtual ~IInterpolant() = default; + + //! Perform the interpolation + //! \return interpolated position and altitude + virtual std::tuple interpolatePositionAndAltitude() const = 0; + + //! Interpolate the ground information/factor + virtual Aviation::COnGroundInfo interpolateGroundFactor() const = 0; + + //! Get the PBH interpolator + virtual const IInterpolatorPbh &pbh() const = 0; + //! "Real time" representing the interpolated situation qint64 getInterpolatedTime() const { return m_interpolatedTime; } @@ -33,15 +54,6 @@ namespace BlackMisc::Simulation void setRecalculated(bool reCalculated) { m_recalculated = reCalculated; } protected: - //! Default ctor - IInterpolant() = default; - - //! Constructor - explicit IInterpolant(int situationsAvailable) : m_situationsAvailable(situationsAvailable) {} - - //! Constructor - IInterpolant(qint64 interpolatedTime, int situationsAvailable) : m_interpolatedTime(interpolatedTime), m_situationsAvailable(situationsAvailable) {} - qint64 m_interpolatedTime = -1; //!< "Real time "of interpolated situation int m_situationsAvailable = 0; //!< used situations bool m_valid = true; //!< valid? diff --git a/src/blackmisc/simulation/interpolator.cpp b/src/blackmisc/simulation/interpolator.cpp index 293641bc4..e74fc41f6 100644 --- a/src/blackmisc/simulation/interpolator.cpp +++ b/src/blackmisc/simulation/interpolator.cpp @@ -31,12 +31,11 @@ using namespace BlackMisc::PhysicalQuantities; namespace BlackMisc::Simulation { - template - CInterpolator::CInterpolator(const CCallsign &callsign, - ISimulationEnvironmentProvider *simEnvProvider, - IInterpolationSetupProvider *setupProvider, - IRemoteAircraftProvider *remoteProvider, - CInterpolationLogger *logger) : m_callsign(callsign) + CInterpolator::CInterpolator(const CCallsign &callsign, + ISimulationEnvironmentProvider *simEnvProvider, + IInterpolationSetupProvider *setupProvider, + IRemoteAircraftProvider *remoteProvider, + CInterpolationLogger *logger) : m_callsign(callsign) { // normally when created m_cg is still null since there is no CG in the provider yet @@ -52,8 +51,7 @@ namespace BlackMisc::Simulation this->attachLogger(logger); } - template - CLength CInterpolator::getAndFetchModelCG(const CLength &dbCG) + CLength CInterpolator::getAndFetchModelCG(const CLength &dbCG) { CLength cgDb = dbCG; if (cgDb.isNull()) @@ -74,8 +72,7 @@ namespace BlackMisc::Simulation return cg; } - template - CAircraftSituationList CInterpolator::remoteAircraftSituationsAndChange(const CInterpolationAndRenderingSetupPerCallsign &setup) + CAircraftSituationList CInterpolator::remoteAircraftSituationsAndChange(const CInterpolationAndRenderingSetupPerCallsign &setup) { CAircraftSituationList validSituations = this->remoteAircraftSituations(m_callsign); @@ -103,8 +100,7 @@ namespace BlackMisc::Simulation return validSituations; } - template - bool CInterpolator::presetGroundElevation(CAircraftSituation &situationToPreset, const CAircraftSituation &oldSituation, const CAircraftSituation &newSituation, const CAircraftSituationChange &change) + bool CInterpolator::presetGroundElevation(CAircraftSituation &situationToPreset, const CAircraftSituation &oldSituation, const CAircraftSituation &newSituation, const CAircraftSituationChange &change) { // IMPORTANT: we do not know what the situation will be (interpolated to), so we cannot transfer situationToPreset.resetGroundElevation(); @@ -151,15 +147,13 @@ namespace BlackMisc::Simulation return situationToPreset.hasGroundElevation(); } - template - void CInterpolator::deferredInit() + void CInterpolator::deferredInit() { if (m_model.hasModelString()) { return; } // set in-between this->initCorrespondingModel(); } - template - bool CInterpolator::verifyInterpolationSituations(const CAircraftSituation &oldest, const CAircraftSituation &newer, const CAircraftSituation &latest, const CInterpolationAndRenderingSetupPerCallsign &setup) + bool CInterpolator::verifyInterpolationSituations(const CAircraftSituation &oldest, const CAircraftSituation &newer, const CAircraftSituation &latest, const CInterpolationAndRenderingSetupPerCallsign &setup) { if (!CBuildConfig::isLocalDeveloperDebugBuild()) { return true; } CAircraftSituationList situations; @@ -196,15 +190,13 @@ namespace BlackMisc::Simulation return sorted && details; } - template - const QStringList &CInterpolator::getLogCategories() + const QStringList &CInterpolator::getLogCategories() { static const QStringList cats { CLogCategories::interpolator() }; return cats; } - template - CInterpolationResult CInterpolator::getInterpolation(qint64 currentTimeSinceEpoch, const CInterpolationAndRenderingSetupPerCallsign &setup, uint32_t aircraftNumber) + CInterpolationResult CInterpolator::getInterpolation(qint64 currentTimeSinceEpoch, const CInterpolationAndRenderingSetupPerCallsign &setup, uint32_t aircraftNumber) { CInterpolationResult result; @@ -222,8 +214,7 @@ namespace BlackMisc::Simulation return result; } - template - CAircraftSituation CInterpolator::getInterpolatedSituation() + CAircraftSituation CInterpolator::getInterpolatedSituation() { Q_ASSERT_X(!m_currentInterpolationStatus.isInterpolated(), Q_FUNC_INFO, "Expect reset status"); if (m_currentSituations.isEmpty()) @@ -235,7 +226,7 @@ namespace BlackMisc::Simulation // interpolant as function of derived class // CInterpolatorLinear::Interpolant or CInterpolatorSpline::Interpolant SituationLog log; - const auto interpolant = derived()->getInterpolant(log); + const IInterpolant &interpolant = getInterpolant(log); const bool isValidInterpolant = interpolant.isValid(); CAircraftSituation currentSituation = m_lastSituation; @@ -400,8 +391,7 @@ namespace BlackMisc::Simulation return currentSituation; } - template - CAircraftParts CInterpolator::getInterpolatedParts() + CAircraftParts CInterpolator::getInterpolatedParts() { // Parts are supposed to be in correct order, latest first const CAircraftPartsList validParts = this->remoteAircraftParts(m_callsign); @@ -435,8 +425,7 @@ namespace BlackMisc::Simulation return currentParts; } - template - CAircraftParts CInterpolator::getInterpolatedOrGuessedParts(int aircraftNumber) + CAircraftParts CInterpolator::getInterpolatedOrGuessedParts(int aircraftNumber) { Q_ASSERT_X(m_partsToSituationInterpolationRatio >= 1 && m_partsToSituationInterpolationRatio < 11, Q_FUNC_INFO, "Wrong ratio"); const bool needParts = m_unitTest || m_lastParts.isNull(); @@ -482,8 +471,7 @@ namespace BlackMisc::Simulation return parts; } - template - const CAircraftParts &CInterpolator::logAndReturnNullParts(const QString &info, bool log) + const CAircraftParts &CInterpolator::logAndReturnNullParts(const QString &info, bool log) { if (!m_lastParts.isNull()) { @@ -502,14 +490,12 @@ namespace BlackMisc::Simulation return CAircraftParts::null(); } - template - bool CInterpolator::doLogging() const + bool CInterpolator::doLogging() const { return this->hasAttachedLogger() && m_currentSetup.logInterpolation(); } - template - CAircraftParts CInterpolator::guessParts(const CAircraftSituation &situation, const CAircraftSituationChange &change, const CAircraftModel &model) + CAircraftParts CInterpolator::guessParts(const CAircraftSituation &situation, const CAircraftSituationChange &change, const CAircraftModel &model) { CAircraftParts parts; parts.setMSecsSinceEpoch(situation.getMSecsSinceEpoch()); @@ -638,8 +624,7 @@ namespace BlackMisc::Simulation return parts; } - template - void CInterpolator::logParts(const CAircraftParts &parts, int partsNo, bool empty) const + void CInterpolator::logParts(const CAircraftParts &parts, int partsNo, bool empty) const { if (!this->doLogging()) { return; } PartsLog logInfo; @@ -651,8 +636,7 @@ namespace BlackMisc::Simulation m_logger->logParts(logInfo); } - template - QString CInterpolator::getInterpolatorInfo() const + QString CInterpolator::getInterpolatorInfo() const { return QStringLiteral("Callsign: ") % m_callsign.asString() % @@ -664,14 +648,12 @@ namespace BlackMisc::Simulation boolToYesNo(m_lastSituation.isNull()); } - template - void CInterpolator::resetLastInterpolation() + void CInterpolator::resetLastInterpolation() { m_lastSituation.setNull(); } - template - bool CInterpolator::initIniterpolationStepData(qint64 currentTimeSinceEpoch, const CInterpolationAndRenderingSetupPerCallsign &setup, int aircraftNumber) + bool CInterpolator::initIniterpolationStepData(qint64 currentTimeSinceEpoch, const CInterpolationAndRenderingSetupPerCallsign &setup, int aircraftNumber) { Q_ASSERT_X(!m_callsign.isEmpty(), Q_FUNC_INFO, "Missing callsign"); @@ -723,8 +705,7 @@ namespace BlackMisc::Simulation return success; } - template - CAircraftSituation CInterpolator::initInterpolatedSituation(const CAircraftSituation &oldSituation, const CAircraftSituation &newSituation) const + CAircraftSituation CInterpolator::initInterpolatedSituation(const CAircraftSituation &oldSituation, const CAircraftSituation &newSituation) const { if (m_currentSituations.isEmpty()) { return CAircraftSituation::null(); } @@ -750,8 +731,7 @@ namespace BlackMisc::Simulation return currentSituation; } - template - void CInterpolator::initCorrespondingModel(const CAircraftModel &model) + void CInterpolator::initCorrespondingModel(const CAircraftModel &model) { if (model.hasModelString()) { @@ -768,16 +748,8 @@ namespace BlackMisc::Simulation this->getAndFetchModelCG(model.getCG()); } - template - void CInterpolator::markAsUnitTest() + void CInterpolator::markAsUnitTest() { m_unitTest = true; } - - // see here for the reason of thess forward instantiations - // https://isocpp.org/wiki/faq/templates#separate-template-fn-defn-from-decl - //! \cond PRIVATE - template class CInterpolator; - template class CInterpolator; - //! \endcond } // namespace diff --git a/src/blackmisc/simulation/interpolator.h b/src/blackmisc/simulation/interpolator.h index cffa36545..a929ed75e 100644 --- a/src/blackmisc/simulation/interpolator.h +++ b/src/blackmisc/simulation/interpolator.h @@ -13,6 +13,8 @@ #include "blackmisc/simulation/remoteaircraftprovider.h" #include "blackmisc/simulation/interpolationsetupprovider.h" #include "blackmisc/simulation/simulationenvironmentprovider.h" +#include "blackmisc/simulation/interpolationlogger.h" +#include "blackmisc/simulation/interpolant.h" #include "blackmisc/simulation/aircraftmodel.h" #include "blackmisc/aviation/aircraftsituationchange.h" #include "blackmisc/aviation/aircraftsituation.h" @@ -20,6 +22,7 @@ #include "blackmisc/aviation/callsign.h" #include "blackmisc/logcategories.h" #include "blackmisc/statusmessagelist.h" +#include "blackmisc/blackmiscexport.h" #include #include @@ -32,9 +35,11 @@ namespace BlackMisc::Simulation class CInterpolatorLinear; class CInterpolatorSpline; - //! Interpolator, calculation inbetween positions - template - class CInterpolator : + //! Base class for interpolating (calculate positions inbetween updates). + //! One instance is responsible for one aircraft + //! This class provides the high level functions for interpolation (called from the simulator plugin), logging functionality, as well as the logic to interpolate aircraft parts. + //! Information for the position interpolation (basically aircraft updates from FSD) are provided from this class. + class BLACKMISC_EXPORT CInterpolator : protected CSimulationEnvironmentAware, protected CInterpolationSetupAware, protected CRemoteAircraftAware @@ -174,17 +179,9 @@ namespace BlackMisc::Simulation //! Return NULL parts and log const BlackMisc::Aviation::CAircraftParts &logAndReturnNullParts(const QString &info, bool log); - //! @{ - //! Derived class - Derived *derived() { return static_cast(this); } - const Derived *derived() const { return static_cast(this); } - //! @} + //! Get the interpolant for the given time point + virtual const IInterpolant &getInterpolant(SituationLog &log) = 0; }; - - //! \cond PRIVATE - extern template class BLACKMISC_EXPORT_DECLARE_TEMPLATE CInterpolator; - extern template class BLACKMISC_EXPORT_DECLARE_TEMPLATE CInterpolator; - //! \endcond } // namespace // namespace #endif // guard diff --git a/src/blackmisc/simulation/interpolatorlinear.cpp b/src/blackmisc/simulation/interpolatorlinear.cpp index 083c3ed4e..874610629 100644 --- a/src/blackmisc/simulation/interpolatorlinear.cpp +++ b/src/blackmisc/simulation/interpolatorlinear.cpp @@ -100,7 +100,7 @@ namespace BlackMisc::Simulation } } - CInterpolatorLinear::CInterpolant CInterpolatorLinear::getInterpolant(SituationLog &log) + const IInterpolant &CInterpolatorLinear::getInterpolant(SituationLog &log) { // set default situations CAircraftSituation startSituation = m_interpolant.getStartSituation(); diff --git a/src/blackmisc/simulation/interpolatorlinear.h b/src/blackmisc/simulation/interpolatorlinear.h index 46e22f33b..0cb6e9bce 100644 --- a/src/blackmisc/simulation/interpolatorlinear.h +++ b/src/blackmisc/simulation/interpolatorlinear.h @@ -25,7 +25,7 @@ namespace BlackMisc namespace Simulation { //! Linear interpolator, calculation inbetween positions - class BLACKMISC_EXPORT CInterpolatorLinear : public CInterpolator + class BLACKMISC_EXPORT CInterpolatorLinear : public CInterpolator { virtual void anchor() override; @@ -47,12 +47,11 @@ namespace BlackMisc CInterpolant(const Aviation::CAircraftSituation &startSituation, const Aviation::CAircraftSituation &endSituation, double timeFraction, qint64 interpolatedTime); //! @} - //! Perform the interpolation - //! \return interpolated position and altitude - std::tuple interpolatePositionAndAltitude() const; + //! \copydoc BlackMisc::Simulation::IInterpolant::interpolatePositionAndAltitude + std::tuple interpolatePositionAndAltitude() const override; - //! Interpolate the ground information/factor - Aviation::COnGroundInfo interpolateGroundFactor() const; + //! \copydoc BlackMisc::Simulation::IInterpolant::interpolateGroundFactor + Aviation::COnGroundInfo interpolateGroundFactor() const override; //! Start situation const Aviation::CAircraftSituation &getStartSituation() const { return m_startSituation; } @@ -60,7 +59,8 @@ namespace BlackMisc //! End situation const Aviation::CAircraftSituation &getEndSituation() const { return m_endSituation; } - const IInterpolatorPbh &pbh() const { return m_pbh; } + //! \copydoc BlackMisc::Simulation::IInterpolant::pbh + const IInterpolatorPbh &pbh() const override { return m_pbh; } private: Aviation::CAircraftSituation m_startSituation; @@ -69,8 +69,8 @@ namespace BlackMisc CInterpolatorLinearPbh m_pbh; }; - //! Get the interpolant for the given time point - CInterpolant getInterpolant(SituationLog &log); + //! \copydoc BlackMisc::Simulation::CInterpolator::getInterpolant + const IInterpolant &getInterpolant(SituationLog &log) override; private: CInterpolant m_interpolant; //!< current interpolant diff --git a/src/blackmisc/simulation/interpolatorspline.cpp b/src/blackmisc/simulation/interpolatorspline.cpp index 24858a7ce..717974535 100644 --- a/src/blackmisc/simulation/interpolatorspline.cpp +++ b/src/blackmisc/simulation/interpolatorspline.cpp @@ -175,7 +175,7 @@ namespace BlackMisc::Simulation void CInterpolatorSpline::anchor() {} - CInterpolatorSpline::CInterpolant CInterpolatorSpline::getInterpolant(SituationLog &log) + const IInterpolant &CInterpolatorSpline::getInterpolant(SituationLog &log) { // recalculate derivatives only if they changed // m_situationsLastModified updated in initIniterpolationStepData diff --git a/src/blackmisc/simulation/interpolatorspline.h b/src/blackmisc/simulation/interpolatorspline.h index a87842729..325c2a2ee 100644 --- a/src/blackmisc/simulation/interpolatorspline.h +++ b/src/blackmisc/simulation/interpolatorspline.h @@ -15,7 +15,7 @@ namespace BlackMisc::Simulation { //! Cubic spline interpolator - class BLACKMISC_EXPORT CInterpolatorSpline : public CInterpolator + class BLACKMISC_EXPORT CInterpolatorSpline : public CInterpolator { virtual void anchor() override; @@ -63,13 +63,11 @@ namespace BlackMisc::Simulation //! Constructor CInterpolant(const PosArray &pa, const PhysicalQuantities::CLengthUnit &altitudeUnit, const CInterpolatorLinearPbh &pbh); - //! Perform the interpolation - //! \param situation situation used as a base for interpolation. Contains for example the already interpolated PBH. - //! \return \p situation with interpolated position and altitude and updated timestamp - std::tuple interpolatePositionAndAltitude() const; + //! \copydoc BlackMisc::Simulation::IInterpolant::interpolatePositionAndAltitude + std::tuple interpolatePositionAndAltitude() const override; - //! Interpolate the ground information/factor - Aviation::COnGroundInfo interpolateGroundFactor() const; + //! \copydoc BlackMisc::Simulation::IInterpolant::interpolateGroundFactor + Aviation::COnGroundInfo interpolateGroundFactor() const override; //! Set the time values void setTimes(qint64 currentTimeMs, double timeFraction, qint64 interpolatedTimeMs); @@ -77,7 +75,8 @@ namespace BlackMisc::Simulation //! \private UNIT tests/ASSERT only const PosArray &getPa() const { return m_pa; } - const IInterpolatorPbh &pbh() const { return m_pbh; } + //! \copydoc BlackMisc::Simulation::IInterpolant::pbh + const IInterpolatorPbh &pbh() const override { return m_pbh; } private: PosArray m_pa; //!< current positions array, latest values last @@ -86,8 +85,8 @@ namespace BlackMisc::Simulation CInterpolatorLinearPbh m_pbh; //!< the used PBH interpolator }; - //! Strategy used by CInterpolator::getInterpolatedSituation - CInterpolant getInterpolant(SituationLog &log); + //! \copydoc BlackMisc::Simulation::CInterpolator::getInterpolant + const IInterpolant &getInterpolant(SituationLog &log) override; private: //! Update the elevations used in CInterpolatorSpline::m_s