mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-03-30 11:55:35 +08:00
refs #863 Interpolator inheritance based on CRTP rather than virtual methods.
This commit is contained in:
@@ -49,7 +49,6 @@ namespace BlackMisc
|
||||
}
|
||||
namespace Simulation
|
||||
{
|
||||
class IInterpolator;
|
||||
class CAirspaceAircraftSnapshot;
|
||||
class CSimulatedAircraft;
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "interpolator.h"
|
||||
#include "blackconfig/buildconfig.h"
|
||||
#include "blackmisc/simulation/interpolationhints.h"
|
||||
#include "blackmisc/simulation/interpolatorlinear.h"
|
||||
#include "blackmisc/aviation/callsign.h"
|
||||
#include "blackmisc/pq/length.h"
|
||||
#include "blackmisc/logmessage.h"
|
||||
@@ -27,24 +28,27 @@ namespace BlackMisc
|
||||
{
|
||||
namespace Simulation
|
||||
{
|
||||
IInterpolator::IInterpolator(const QString &objectName, QObject *parent) :
|
||||
template <typename Derived>
|
||||
CInterpolator<Derived>::CInterpolator(const QString &objectName, QObject *parent) :
|
||||
QObject(parent)
|
||||
{
|
||||
this->setObjectName(objectName);
|
||||
}
|
||||
|
||||
BlackMisc::Aviation::CAircraftSituation IInterpolator::getInterpolatedSituation(
|
||||
template <typename Derived>
|
||||
BlackMisc::Aviation::CAircraftSituation CInterpolator<Derived>::getInterpolatedSituation(
|
||||
qint64 currentTimeSinceEpoc, const CInterpolationAndRenderingSetup &setup,
|
||||
const CInterpolationHints &hints, CInterpolationStatus &status) const
|
||||
{
|
||||
status.reset();
|
||||
|
||||
auto currentSituation = this->getInterpolatedSituation(callsign, this->m_aircraftSituations, currentTimeSinceEpoc, setup, hints, status);
|
||||
auto currentSituation = derived()->getInterpolatedSituation(callsign, this->m_aircraftSituations, 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,
|
||||
template <typename Derived>
|
||||
CAircraftParts CInterpolator<Derived>::getInterpolatedParts(const CCallsign &callsign, const CAircraftPartsList &parts, qint64 currentTimeMsSinceEpoch,
|
||||
const CInterpolationAndRenderingSetup &setup, CPartsStatus &partsStatus, bool log) const
|
||||
{
|
||||
Q_UNUSED(setup);
|
||||
@@ -102,31 +106,35 @@ namespace BlackMisc
|
||||
log.callsign = callsign;
|
||||
log.timestamp = currentTimeMsSinceEpoch;
|
||||
log.parts = currentParts;
|
||||
IInterpolator::logParts(log);
|
||||
CInterpolator::logParts(log);
|
||||
}
|
||||
|
||||
return currentParts;
|
||||
}
|
||||
|
||||
CAircraftParts IInterpolator::getInterpolatedParts(const CCallsign &callsign, qint64 currentTimeMsSinceEpoch,
|
||||
template <typename Derived>
|
||||
CAircraftParts CInterpolator<Derived>::getInterpolatedParts(const CCallsign &callsign, qint64 currentTimeMsSinceEpoch,
|
||||
const CInterpolationAndRenderingSetup &setup, CPartsStatus &partsStatus, bool log) const
|
||||
{
|
||||
partsStatus.reset();
|
||||
return this->getInterpolatedParts(callsign, this->m_aircraftParts, currentTimeMsSinceEpoch, setup, partsStatus, log);
|
||||
}
|
||||
|
||||
void IInterpolator::addAircraftSituation(const CAircraftSituation &situation)
|
||||
template <typename Derived>
|
||||
void CInterpolator<Derived>::addAircraftSituation(const CAircraftSituation &situation)
|
||||
{
|
||||
m_aircraftSituations.push_frontMaxElements(situation, IRemoteAircraftProvider::MaxSituationsPerCallsign);
|
||||
}
|
||||
|
||||
void IInterpolator::addAircraftParts(const CAircraftParts &parts)
|
||||
template <typename Derived>
|
||||
void CInterpolator<Derived>::addAircraftParts(const CAircraftParts &parts)
|
||||
{
|
||||
m_aircraftParts.push_front(parts);
|
||||
IRemoteAircraftProvider::removeOutdatedParts(m_aircraftParts);
|
||||
}
|
||||
|
||||
CWorker *IInterpolator::writeLogInBackground()
|
||||
template <typename Derived>
|
||||
CWorker *CInterpolator<Derived>::writeLogInBackground()
|
||||
{
|
||||
QList<InterpolationLog> interpolation;
|
||||
QList<PartsLog> parts;
|
||||
@@ -138,7 +146,7 @@ namespace BlackMisc
|
||||
|
||||
CWorker *worker = CWorker::fromTask(this, "WriteInterpolationLog", [interpolation, parts]()
|
||||
{
|
||||
const CStatusMessageList msg = IInterpolator::writeLogFile(interpolation, parts);
|
||||
const CStatusMessageList msg = CInterpolator::writeLogFile(interpolation, parts);
|
||||
CLogMessage::preformatted(msg);
|
||||
});
|
||||
return worker;
|
||||
@@ -164,57 +172,62 @@ namespace BlackMisc
|
||||
return files;
|
||||
}
|
||||
|
||||
CStatusMessageList IInterpolator::writeLogFile(const QList<InterpolationLog> &interpolation, const QList<PartsLog> &parts)
|
||||
template <typename Derived>
|
||||
CStatusMessageList CInterpolator<Derived>::writeLogFile(const QList<InterpolationLog> &interpolation, const QList<PartsLog> &parts)
|
||||
{
|
||||
if (parts.isEmpty() && interpolation.isEmpty()) { return CStatusMessage(static_cast<IInterpolator *>(nullptr)).warning("No data for log"); }
|
||||
if (parts.isEmpty() && interpolation.isEmpty()) { return CStatusMessage(static_cast<CInterpolator *>(nullptr)).warning("No data for log"); }
|
||||
static const QString html = QLatin1String("Entries: %1\n\n%2");
|
||||
const QString htmlTemplate = CFileUtils::readFileToString(CBuildConfig::getHtmlTemplateFileName());
|
||||
|
||||
CStatusMessageList msgs;
|
||||
const QString ts = QDateTime::currentDateTimeUtc().toString("yyyyMMddhhmmss");
|
||||
const QString htmlInterpolation = IInterpolator::getHtmlInterpolationLog(interpolation);
|
||||
const QString htmlInterpolation = CInterpolator::getHtmlInterpolationLog(interpolation);
|
||||
if (!htmlInterpolation.isEmpty())
|
||||
{
|
||||
const QString fn = CFileUtils::appendFilePaths(CDirectoryUtils::getLogDirectory(), QString("%1 interpolation.html").arg(ts));
|
||||
const bool s = CFileUtils::writeStringToFile(htmlTemplate.arg(html.arg(interpolation.size()).arg(htmlInterpolation)), fn);
|
||||
msgs.push_back(IInterpolator::logStatusFileWriting(s, fn));
|
||||
msgs.push_back(CInterpolator::logStatusFileWriting(s, fn));
|
||||
}
|
||||
|
||||
const QString htmlParts = IInterpolator::getHtmlPartsLog(parts);
|
||||
const QString htmlParts = CInterpolator::getHtmlPartsLog(parts);
|
||||
if (!htmlParts.isEmpty())
|
||||
{
|
||||
const QString fn = CFileUtils::appendFilePaths(CDirectoryUtils::getLogDirectory(), QString("%1 parts.html").arg(ts));
|
||||
const bool s = CFileUtils::writeStringToFile(htmlTemplate.arg(html.arg(parts.size()).arg(htmlParts)), fn);
|
||||
msgs.push_back(IInterpolator::logStatusFileWriting(s, fn));
|
||||
msgs.push_back(CInterpolator::logStatusFileWriting(s, fn));
|
||||
}
|
||||
return msgs;
|
||||
}
|
||||
|
||||
CStatusMessage IInterpolator::logStatusFileWriting(bool success, const QString &fileName)
|
||||
template <typename Derived>
|
||||
CStatusMessage CInterpolator<Derived>::logStatusFileWriting(bool success, const QString &fileName)
|
||||
{
|
||||
if (success)
|
||||
{
|
||||
return CStatusMessage(static_cast<IInterpolator *>(nullptr)).info("Written log file '%1'") << fileName;
|
||||
return CStatusMessage(static_cast<CInterpolator *>(nullptr)).info("Written log file '%1'") << fileName;
|
||||
}
|
||||
else
|
||||
{
|
||||
return CStatusMessage(static_cast<IInterpolator *>(nullptr)).error("Failed to write log file '%1'") << fileName;
|
||||
return CStatusMessage(static_cast<CInterpolator *>(nullptr)).error("Failed to write log file '%1'") << fileName;
|
||||
}
|
||||
}
|
||||
|
||||
void IInterpolator::logInterpolation(const IInterpolator::InterpolationLog &log) const
|
||||
template <typename Derived>
|
||||
void CInterpolator<Derived>::logInterpolation(const typename CInterpolator<Derived>::InterpolationLog &log) const
|
||||
{
|
||||
QWriteLocker l(&m_lockLogs);
|
||||
m_interpolationLogs.append(log);
|
||||
}
|
||||
|
||||
void IInterpolator::logParts(const IInterpolator::PartsLog &parts) const
|
||||
template <typename Derived>
|
||||
void CInterpolator<Derived>::logParts(const typename CInterpolator<Derived>::PartsLog &parts) const
|
||||
{
|
||||
QWriteLocker l(&m_lockLogs);
|
||||
m_partsLogs.append(parts);
|
||||
}
|
||||
|
||||
QString IInterpolator::getHtmlInterpolationLog(const QList<InterpolationLog> &logs)
|
||||
template <typename Derived>
|
||||
QString CInterpolator<Derived>::getHtmlInterpolationLog(const QList<InterpolationLog> &logs)
|
||||
{
|
||||
if (logs.isEmpty()) { return {}; }
|
||||
const QString tableHeader =
|
||||
@@ -294,7 +307,8 @@ namespace BlackMisc
|
||||
return QLatin1String("<table class=\"small\">\n") % tableHeader % tableRows % QLatin1String("</table>\n");
|
||||
}
|
||||
|
||||
QString IInterpolator::getHtmlPartsLog(const QList<PartsLog> &logs)
|
||||
template <typename Derived>
|
||||
QString CInterpolator<Derived>::getHtmlPartsLog(const QList<PartsLog> &logs)
|
||||
{
|
||||
if (logs.isEmpty()) { return {}; }
|
||||
const QString tableHeader =
|
||||
@@ -321,14 +335,16 @@ namespace BlackMisc
|
||||
return QLatin1String("<table class=\"small\">\n") % tableHeader % tableRows % QLatin1String("</table>\n");
|
||||
}
|
||||
|
||||
void IInterpolator::clearLog()
|
||||
template <typename Derived>
|
||||
void CInterpolator<Derived>::clearLog()
|
||||
{
|
||||
QWriteLocker l(&m_lockLogs);
|
||||
this->m_partsLogs.clear();
|
||||
this->m_interpolationLogs.clear();
|
||||
}
|
||||
|
||||
void IInterpolator::setGroundElevationFromHint(const CInterpolationHints &hints, CAircraftSituation &situation, bool override)
|
||||
template <typename Derived>
|
||||
void CInterpolator<Derived>::setGroundElevationFromHint(const CInterpolationHints &hints, CAircraftSituation &situation, bool override)
|
||||
{
|
||||
if (!override && situation.hasGroundElevation()) { return; }
|
||||
const CAltitude elevation = hints.getGroundElevation(situation);
|
||||
@@ -336,7 +352,8 @@ namespace BlackMisc
|
||||
situation.setGroundElevation(elevation);
|
||||
}
|
||||
|
||||
void IInterpolator::setGroundFlagFromInterpolator(const CInterpolationHints &hints, double groundFactor, CAircraftSituation &situation)
|
||||
template <typename Derived>
|
||||
void CInterpolator<Derived>::setGroundFlagFromInterpolator(const CInterpolationHints &hints, double groundFactor, CAircraftSituation &situation)
|
||||
{
|
||||
// by interpolation
|
||||
if (groundFactor >= 1.0)
|
||||
@@ -386,13 +403,15 @@ namespace BlackMisc
|
||||
situation.setOnGround(CAircraftSituation::OnGround, CAircraftSituation::OnGroundByGuessing);
|
||||
}
|
||||
|
||||
QString IInterpolator::msSinceEpochToTime(qint64 ms)
|
||||
template <typename Derived>
|
||||
QString CInterpolator<Derived>::msSinceEpochToTime(qint64 ms)
|
||||
{
|
||||
static const QString dateFormat("hh:mm:ss.zzz");
|
||||
return QDateTime::fromMSecsSinceEpoch(ms).toString(dateFormat);
|
||||
}
|
||||
|
||||
QString IInterpolator::msSinceEpochToTime(qint64 t1, qint64 t2, qint64 t3)
|
||||
template <typename Derived>
|
||||
QString CInterpolator<Derived>::msSinceEpochToTime(qint64 t1, qint64 t2, qint64 t3)
|
||||
{
|
||||
if (t3 < 0) return QString("%1 %2").arg(msSinceEpochToTime(t1), msSinceEpochToTime(t2));
|
||||
return QString("%1 %2 %3").arg(msSinceEpochToTime(t1), msSinceEpochToTime(t2), msSinceEpochToTime(t3));
|
||||
@@ -418,5 +437,11 @@ namespace BlackMisc
|
||||
{
|
||||
m_supportsParts = false;
|
||||
}
|
||||
|
||||
// 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 BLACKMISC_EXPORT_DEFINE_TEMPLATE CInterpolator<CInterpolatorLinear>;
|
||||
//! \endcond
|
||||
} // namespace
|
||||
} // namespace
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
#define BLACKMISC_SIMULATION_INTERPOLATOR_H
|
||||
|
||||
#include "interpolationrenderingsetup.h"
|
||||
#include "blackmisc/blackmiscexport.h"
|
||||
#include "blackmisc/aviation/aircraftpartslist.h"
|
||||
#include "blackmisc/aviation/aircraftsituation.h"
|
||||
#include "blackmisc/aviation/aircraftpartslist.h"
|
||||
@@ -30,37 +29,41 @@ namespace BlackMisc
|
||||
namespace Simulation
|
||||
{
|
||||
class CInterpolationHints;
|
||||
class CInterpolatorLinear;
|
||||
struct CInterpolationStatus;
|
||||
struct CPartsStatus;
|
||||
|
||||
//! Interpolator, calculation inbetween positions
|
||||
class BLACKMISC_EXPORT IInterpolator : public QObject
|
||||
template <typename Derived>
|
||||
class CInterpolator : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
//! Log category
|
||||
static QString getLogCategory() { return "swift.interpolator"; }
|
||||
|
||||
//! Current interpolated situation
|
||||
virtual BlackMisc::Aviation::CAircraftSituation getInterpolatedSituation(
|
||||
BlackMisc::Aviation::CAircraftSituation getInterpolatedSituation(
|
||||
const BlackMisc::Aviation::CCallsign &callsign, qint64 currentTimeSinceEpoc,
|
||||
const CInterpolationAndRenderingSetup &setup, const CInterpolationHints &hints, CInterpolationStatus &status) const;
|
||||
|
||||
//! Current interpolated situation, to be implemented by subclass
|
||||
virtual BlackMisc::Aviation::CAircraftSituation getInterpolatedSituation(
|
||||
BlackMisc::Aviation::CAircraftSituation getInterpolatedSituation(
|
||||
const BlackMisc::Aviation::CCallsign &callsign,
|
||||
const BlackMisc::Aviation::CAircraftSituationList &situations, qint64 currentTimeSinceEpoc,
|
||||
const CInterpolationAndRenderingSetup &setup, const CInterpolationHints &hints, CInterpolationStatus &status) const = 0;
|
||||
const CInterpolationAndRenderingSetup &setup, const CInterpolationHints &hints, CInterpolationStatus &status) const
|
||||
{
|
||||
qFatal("Not implemented");
|
||||
return {};
|
||||
}
|
||||
|
||||
//! Parts before given offset time (aka pending parts)
|
||||
virtual BlackMisc::Aviation::CAircraftParts getInterpolatedParts(
|
||||
BlackMisc::Aviation::CAircraftParts getInterpolatedParts(
|
||||
const Aviation::CCallsign &callsign,
|
||||
const BlackMisc::Aviation::CAircraftPartsList &parts, qint64 cutoffTime,
|
||||
const CInterpolationAndRenderingSetup &setup, CPartsStatus &partsStatus, bool log = false) const;
|
||||
|
||||
//! Parts before given offset time (aka pending parts)
|
||||
virtual BlackMisc::Aviation::CAircraftParts getInterpolatedParts(
|
||||
BlackMisc::Aviation::CAircraftParts getInterpolatedParts(
|
||||
const BlackMisc::Aviation::CCallsign &callsign, qint64 cutoffTime,
|
||||
const CInterpolationAndRenderingSetup &setup, CPartsStatus &partsStatus, bool log = false) const;
|
||||
|
||||
@@ -120,7 +123,7 @@ namespace BlackMisc
|
||||
};
|
||||
|
||||
//! Constructor
|
||||
IInterpolator(const QString &objectName, QObject *parent);
|
||||
CInterpolator(const QString &objectName, QObject *parent);
|
||||
|
||||
//! Log current interpolation cycle, only stores in memory, for performance reasons
|
||||
//! \remark const to allow const interpolator functions
|
||||
@@ -159,6 +162,9 @@ namespace BlackMisc
|
||||
//! Create readable time
|
||||
static QString msSinceEpochToTime(qint64 t1, qint64 t2, qint64 t3 = -1);
|
||||
|
||||
Derived *derived() { return static_cast<Derived *>(this); }
|
||||
const Derived *derived() const { return static_cast<const Derived *>(this); }
|
||||
|
||||
mutable QReadWriteLock m_lockLogs; //!< lock logging
|
||||
mutable QList<PartsLog> m_partsLogs; //!< logs of parts
|
||||
mutable QList<InterpolationLog> m_interpolationLogs; //!< logs of interpolation
|
||||
@@ -210,6 +216,10 @@ namespace BlackMisc
|
||||
private:
|
||||
bool m_supportsParts = false; //!< supports parts for given callsign
|
||||
};
|
||||
|
||||
//! \cond PRIVATE
|
||||
extern template class BLACKMISC_EXPORT_DECLARE_TEMPLATE CInterpolator<CInterpolatorLinear>;
|
||||
//! \endcond
|
||||
} // namespace
|
||||
} // namespace
|
||||
#endif // guard
|
||||
|
||||
@@ -100,8 +100,8 @@ namespace BlackMisc
|
||||
// do not call for XP (lazy init)
|
||||
if (!hints.hasElevationProvider())
|
||||
{
|
||||
IInterpolator::setGroundElevationFromHint(hints, oldSituation, false);
|
||||
IInterpolator::setGroundElevationFromHint(hints, newSituation, false);
|
||||
CInterpolator::setGroundElevationFromHint(hints, oldSituation, false);
|
||||
CInterpolator::setGroundElevationFromHint(hints, newSituation, false);
|
||||
}
|
||||
|
||||
CAircraftSituation currentSituation(oldSituation); // also sets ground elevation if available
|
||||
|
||||
@@ -26,22 +26,24 @@ namespace BlackMisc
|
||||
namespace Simulation
|
||||
{
|
||||
//! Linear interpolator, calculation inbetween positions
|
||||
class BLACKMISC_EXPORT CInterpolatorLinear : public IInterpolator
|
||||
class BLACKMISC_EXPORT CInterpolatorLinear : public CInterpolator<CInterpolatorLinear>
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
//! Constructor
|
||||
CInterpolatorLinear(QObject *parent = nullptr) :
|
||||
IInterpolator("CInterpolatorLinear", parent)
|
||||
CInterpolator("CInterpolatorLinear", parent)
|
||||
{}
|
||||
|
||||
// public base class signature
|
||||
using IInterpolator::getInterpolatedSituation;
|
||||
using CInterpolator::getInterpolatedSituation;
|
||||
|
||||
//! \copydoc IInterpolator::getInterpolatedSituation
|
||||
virtual BlackMisc::Aviation::CAircraftSituation getInterpolatedSituation(
|
||||
BlackMisc::Aviation::CAircraftSituation getInterpolatedSituation(
|
||||
const BlackMisc::Aviation::CCallsign &callsign,
|
||||
const BlackMisc::Aviation::CAircraftSituationList &situations, qint64 currentTimeSinceEpoc, const CInterpolationAndRenderingSetup &setup,
|
||||
const BlackMisc::Simulation::CInterpolationHints &hints, CInterpolationStatus &status) const override;
|
||||
const BlackMisc::Simulation::CInterpolationHints &hints, CInterpolationStatus &status) const;
|
||||
|
||||
//! Log category
|
||||
static QString getLogCategory() { return "swift.interpolatorlinear"; }
|
||||
|
||||
@@ -50,7 +50,7 @@ namespace BlackSimPlugin
|
||||
void setHostAddress(const QString &hostAddress);
|
||||
|
||||
//! Get interpolator
|
||||
BlackMisc::Simulation::IInterpolator *getInterpolator() { return &m_interpolator; }
|
||||
BlackMisc::Simulation::CInterpolatorLinear *getInterpolator() { return &m_interpolator; }
|
||||
|
||||
//! Set interpolation setup
|
||||
//! \threadsafe
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
#include "simconnectdatadefinition.h"
|
||||
#include <QSharedPointer>
|
||||
|
||||
namespace BlackMisc { namespace Simulation { class IInterpolator; } }
|
||||
namespace BlackMisc { namespace Simulation { class CInterpolatorLinear; } }
|
||||
namespace BlackSimPlugin
|
||||
{
|
||||
namespace Fsx
|
||||
@@ -44,7 +44,7 @@ namespace BlackSimPlugin
|
||||
const QString &getAircraftModelString() const { return m_aircraft.getModelString(); }
|
||||
|
||||
//! Interpolator
|
||||
BlackMisc::Simulation::IInterpolator *getInterpolator() const { return m_interpolator.data(); }
|
||||
BlackMisc::Simulation::CInterpolatorLinear *getInterpolator() const { return m_interpolator.data(); }
|
||||
|
||||
//! Get current lights (requested from simulator)
|
||||
const BlackMisc::Aviation::CAircraftLights &getCurrentLightsInSimulator() const { return m_currentLightsInSim; }
|
||||
@@ -122,7 +122,7 @@ namespace BlackSimPlugin
|
||||
BlackMisc::Aviation::CAircraftLights m_currentLightsInSim { nullptr }; //!< current lights to know state for toggling
|
||||
BlackMisc::Aviation::CAircraftLights m_lightsAsSent { nullptr }; //!< lights as sent to simulator
|
||||
SIMCONNECT_PERIOD m_requestSimDataPeriod = SIMCONNECT_PERIOD_NEVER; //!< how often do we query ground elevation
|
||||
QSharedPointer<BlackMisc::Simulation::IInterpolator> m_interpolator; //!< shared pointer because CSimConnectObject can be copied
|
||||
QSharedPointer<BlackMisc::Simulation::CInterpolatorLinear> m_interpolator; //!< shared pointer because CSimConnectObject can be copied
|
||||
};
|
||||
|
||||
//! Simulator objects (aka AI aircraft)
|
||||
|
||||
@@ -28,14 +28,7 @@
|
||||
#define XBUS_TRAFFIC_OBJECTPATH "/xbus/traffic"
|
||||
//! \endcond
|
||||
|
||||
namespace BlackMisc
|
||||
{
|
||||
namespace Simulation
|
||||
{
|
||||
class IInterpolator;
|
||||
class CInterpolationHints;
|
||||
}
|
||||
}
|
||||
namespace BlackMisc { namespace Simulation { class CInterpolationHints; } }
|
||||
namespace XBus
|
||||
{
|
||||
/*!
|
||||
|
||||
Reference in New Issue
Block a user