mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-08-08 10:45:36 +08:00
refs #386, performance issues
* keep split per callsign map in IInterpolator (so it is available for all interpolators) * Interpolator using CWorker, so it can run in background * added signals to provider to add split situations / callsigns * adjustments to airspace / context for those signals * thread safe access to those from interpolator * renamed from rendered to remote aircraft as discussed * adjust samples * removed no longer required functions in timestampobjectlist * changed connectioStatusChanged from uint -> int
This commit is contained in:
@@ -208,7 +208,7 @@ namespace BlackMiscTest
|
||||
out << "Reads by times / callsigns: " << timer.elapsed() << "ms" << endl;
|
||||
|
||||
timer.start();
|
||||
QMap<CCallsign, CAircraftSituationList> splitList = situations.splitPerCallsign();
|
||||
QHash<CCallsign, CAircraftSituationList> splitList = situations.splitPerCallsign();
|
||||
Q_ASSERT(splitList.size() == numberOfCallsigns);
|
||||
for (int t = 0; t < numberOfTimes; t++)
|
||||
{
|
||||
@@ -310,21 +310,8 @@ namespace BlackMiscTest
|
||||
}
|
||||
out << "Single, pre-sorted split by time upfront, then callsigns: " << timer.elapsed() << "ms" << endl;
|
||||
|
||||
situations.sortOldestFirst(); // eliminate impact of sort
|
||||
timer.start();
|
||||
split = situations.splitByTimeNoSortAscendingTimestamp(halfTime);
|
||||
for (int cs = 0; cs < numberOfCallsigns; cs++)
|
||||
{
|
||||
CCallsign callsign("CS" + QString::number(cs));
|
||||
CAircraftSituationList csSituationsBefore = split[0].findByCallsign(callsign);
|
||||
CAircraftSituationList csSituationsAfter = split[1].findByCallsign(callsign);
|
||||
Q_UNUSED(csSituationsBefore);
|
||||
Q_UNUSED(csSituationsAfter);
|
||||
}
|
||||
out << "Single, unsorted split by time upfront, then callsigns: " << timer.elapsed() << "ms" << endl;
|
||||
|
||||
timer.start();
|
||||
QMap<CCallsign, CAircraftSituationList> csSituations = situations.splitPerCallsign();
|
||||
QHash<CCallsign, CAircraftSituationList> csSituations = situations.splitPerCallsign();
|
||||
out << "Split by " << csSituations.size() << " callsigns, " << timer.elapsed() << "ms" << endl;
|
||||
|
||||
timer.start();
|
||||
|
||||
@@ -27,7 +27,8 @@ namespace BlackCore
|
||||
{
|
||||
|
||||
CAirspaceMonitor::CAirspaceMonitor(QObject *parent, const BlackMisc::Simulation::IOwnAircraftProviderReadOnly *ownAircraftProvider, INetwork *network, CVatsimBookingReader *bookings, CVatsimDataFileReader *dataFile)
|
||||
: QObject(parent), COwnAircraftProviderSupportReadOnly(ownAircraftProvider),
|
||||
: QObject(parent),
|
||||
COwnAircraftProviderSupportReadOnly(ownAircraftProvider),
|
||||
m_network(network), m_vatsimBookingReader(bookings), m_vatsimDataFileReader(dataFile),
|
||||
m_atcWatchdog(this), m_aircraftWatchdog(this)
|
||||
{
|
||||
@@ -59,28 +60,28 @@ namespace BlackCore
|
||||
this->connect(&this->m_atcWatchdog, &CAirspaceWatchdog::timeout, this, &CAirspaceMonitor::ps_atcControllerDisconnected);
|
||||
}
|
||||
|
||||
const CSimulatedAircraftList &CAirspaceMonitor::renderedAircraft() const
|
||||
const CSimulatedAircraftList &CAirspaceMonitor::remoteAircraft() const
|
||||
{
|
||||
// not thread safe, check
|
||||
Q_ASSERT(this->thread() == QThread::currentThread());
|
||||
return m_aircraftInRange;
|
||||
}
|
||||
|
||||
CSimulatedAircraftList &CAirspaceMonitor::renderedAircraft()
|
||||
CSimulatedAircraftList &CAirspaceMonitor::remoteAircraft()
|
||||
{
|
||||
// not thread safe, check
|
||||
Q_ASSERT(this->thread() == QThread::currentThread());
|
||||
return m_aircraftInRange;
|
||||
}
|
||||
|
||||
const CAircraftSituationList &CAirspaceMonitor::renderedAircraftSituations() const
|
||||
const CAircraftSituationList &CAirspaceMonitor::remoteAircraftSituations() const
|
||||
{
|
||||
// not thread safe, check
|
||||
Q_ASSERT(this->thread() == QThread::currentThread());
|
||||
return m_aircraftSituations;
|
||||
}
|
||||
|
||||
CAircraftSituationList &CAirspaceMonitor::renderedAircraftSituations()
|
||||
CAircraftSituationList &CAirspaceMonitor::remoteAircraftSituations()
|
||||
{
|
||||
// not thread safe, check
|
||||
Q_ASSERT(this->thread() == QThread::currentThread());
|
||||
@@ -89,26 +90,18 @@ namespace BlackCore
|
||||
|
||||
CAircraftSituationList CAirspaceMonitor::getRenderedAircraftSituations() const
|
||||
{
|
||||
if (this->thread() == QThread::currentThread()) { return this->m_aircraftSituations; }
|
||||
CAircraftSituationList situations;
|
||||
bool s = QMetaObject::invokeMethod(const_cast<CAirspaceMonitor *>(this), // strip away const, invoke will not change anything,
|
||||
"getRenderedAircraftSituations",
|
||||
Qt::BlockingQueuedConnection,
|
||||
Q_RETURN_ARG(CAircraftSituationList, situations)
|
||||
);
|
||||
Q_ASSERT(s);
|
||||
Q_UNUSED(s);
|
||||
return situations;
|
||||
Q_ASSERT(this->thread() == QThread::currentThread());
|
||||
return this->m_aircraftSituations;
|
||||
}
|
||||
|
||||
const CAircraftPartsList &CAirspaceMonitor::renderedAircraftParts() const
|
||||
const CAircraftPartsList &CAirspaceMonitor::remoteAircraftParts() const
|
||||
{
|
||||
// not thread safe, check
|
||||
Q_ASSERT(this->thread() == QThread::currentThread());
|
||||
return m_aircraftParts;
|
||||
}
|
||||
|
||||
CAircraftPartsList &CAirspaceMonitor::renderedAircraftParts()
|
||||
CAircraftPartsList &CAirspaceMonitor::remoteAircraftParts()
|
||||
{
|
||||
// not thread safe, check
|
||||
Q_ASSERT(this->thread() == QThread::currentThread());
|
||||
@@ -117,16 +110,20 @@ namespace BlackCore
|
||||
|
||||
CAircraftPartsList CAirspaceMonitor::getRenderedAircraftParts() const
|
||||
{
|
||||
if (this->thread() == QThread::currentThread()) { return this->m_aircraftParts; }
|
||||
CAircraftPartsList parts;
|
||||
bool s = QMetaObject::invokeMethod(const_cast<CAirspaceMonitor *>(this), // strip away const, invoke will not change anything
|
||||
"getRenderedAircraftParts",
|
||||
Qt::BlockingQueuedConnection,
|
||||
Q_RETURN_ARG(CAircraftPartsList, parts)
|
||||
);
|
||||
Q_ASSERT(s);
|
||||
Q_UNUSED(s);
|
||||
return parts;
|
||||
Q_ASSERT(this->thread() == QThread::currentThread());
|
||||
return this->m_aircraftParts;
|
||||
}
|
||||
|
||||
bool CAirspaceMonitor::connectRemoteAircraftProviderSignals(
|
||||
std::function<void(const CAircraftSituation &)> situationSlot,
|
||||
std::function<void(const CAircraftParts &)> partsSlot,
|
||||
std::function<void(const CCallsign &)> removedAircraftSlot
|
||||
)
|
||||
{
|
||||
bool s1 = connect(this, &CAirspaceMonitor::addedRemoteAircraftSituation, situationSlot);
|
||||
bool s2 = connect(this, &CAirspaceMonitor::addedRemoteAircraftParts, partsSlot);
|
||||
bool s3 = connect(this, &CAirspaceMonitor::removedAircraft, removedAircraftSlot);
|
||||
return s1 && s2 && s3;
|
||||
}
|
||||
|
||||
bool CAirspaceMonitor::updateAircraftEnabled(const CCallsign &callsign, bool enabledForRedering, const QString &originator)
|
||||
@@ -738,7 +735,7 @@ namespace BlackCore
|
||||
CAircraftSituation situationWithCallsign(situation);
|
||||
situationWithCallsign.setCallsign(callsign);
|
||||
this->m_aircraftSituations.insert(situationWithCallsign);
|
||||
this->m_aircraftSituations.removeOlderThanNowMinusOffset(30000);
|
||||
this->m_aircraftSituations.removeOlderThanNowMinusOffset(AircraftSituationsRemovedOffsetMs);
|
||||
|
||||
bool exists = this->m_aircraftInRange.containsCallsign(callsign);
|
||||
if (!exists)
|
||||
@@ -811,6 +808,7 @@ namespace BlackCore
|
||||
this->m_aircraftWatchdog.resetCallsign(callsign);
|
||||
}
|
||||
|
||||
emit this->addedRemoteAircraftSituation(situationWithCallsign);
|
||||
emit this->changedAircraftInRange();
|
||||
}
|
||||
|
||||
@@ -852,13 +850,15 @@ namespace BlackCore
|
||||
|
||||
CAircraftParts parts = m_aircraftParts.findBackByCallsign(callsign);
|
||||
parts.setCurrentUtcTime();
|
||||
parts.setCallsign(callsign);
|
||||
parts.setCallsign(callsign); // for default values
|
||||
|
||||
// update
|
||||
QJsonObject config = applyIncrementalObject(parts.toJson(), incremental);
|
||||
parts.convertFromJson(config);
|
||||
|
||||
// store part history
|
||||
this->m_aircraftParts.insert(parts);
|
||||
emit this->addedRemoteAircraftParts(parts);
|
||||
|
||||
CPropertyIndexVariantMap vm;
|
||||
vm.addValue(CAircraft::IndexParts, parts);
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
#include "blackmisc/simulation/simulatedaircraftlist.h"
|
||||
#include "blackmisc/simulation/simdirectaccessownaircraft.h"
|
||||
#include "blackmisc/simulation/simdirectaccessrenderedaircraft.h"
|
||||
#include "blackmisc/simulation/simdirectaccessremoteaircraft.h"
|
||||
#include "blackmisc/avatcstationlist.h"
|
||||
#include "blackmisc/avaircraftsituationlist.h"
|
||||
#include "blackmisc/nwclientlist.h"
|
||||
@@ -34,37 +34,38 @@ namespace BlackCore
|
||||
*/
|
||||
class CAirspaceMonitor :
|
||||
public QObject,
|
||||
public BlackMisc::Simulation::COwnAircraftProviderSupportReadOnly,
|
||||
public BlackMisc::Simulation::IRenderedAircraftProvider
|
||||
public BlackMisc::Simulation::IRemoteAircraftProvider, // those data will be provided from the class CAirspaceMonitor
|
||||
public BlackMisc::Simulation::COwnAircraftProviderSupportReadOnly // used to obtain in memory inofmration about own aircraft
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(BlackMisc::Simulation::IRemoteAircraftProvider)
|
||||
|
||||
public:
|
||||
//! Constructor
|
||||
CAirspaceMonitor(QObject *parent, const BlackMisc::Simulation::IOwnAircraftProviderReadOnly *ownAircraft, INetwork *network, CVatsimBookingReader *bookings, CVatsimDataFileReader *dataFile);
|
||||
|
||||
//! \copydoc IRenderedAircraftProviderReadOnly::renderedAircraft
|
||||
virtual const BlackMisc::Simulation::CSimulatedAircraftList &renderedAircraft() const override;
|
||||
//! \copydoc IRemoteAircraftProviderReadOnly::renderedAircraft
|
||||
virtual const BlackMisc::Simulation::CSimulatedAircraftList &remoteAircraft() const override;
|
||||
|
||||
//! \copydoc IRenderedAircraftProvider::renderedAircraft
|
||||
virtual BlackMisc::Simulation::CSimulatedAircraftList &renderedAircraft() override;
|
||||
//! \copydoc IRemoteAircraftProvider::renderedAircraft
|
||||
virtual BlackMisc::Simulation::CSimulatedAircraftList &remoteAircraft() override;
|
||||
|
||||
//! \copydoc IRenderedAircraftProvider::renderedAircraftSituations
|
||||
virtual const BlackMisc::Aviation::CAircraftSituationList &renderedAircraftSituations() const override;
|
||||
//! \copydoc IRemoteAircraftProvider::remoteAircraftSituations
|
||||
virtual const BlackMisc::Aviation::CAircraftSituationList &remoteAircraftSituations() const override;
|
||||
|
||||
//! \copydoc IRenderedAircraftProvider::renderedAircraftSituations
|
||||
virtual BlackMisc::Aviation::CAircraftSituationList &renderedAircraftSituations() override;
|
||||
//! \copydoc IRemoteAircraftProvider::remoteAircraftSituations
|
||||
virtual BlackMisc::Aviation::CAircraftSituationList &remoteAircraftSituations() override;
|
||||
|
||||
//! \copydoc IRenderedAircraftProvider::renderedAircraftParts
|
||||
virtual const BlackMisc::Aviation::CAircraftPartsList &renderedAircraftParts() const override;
|
||||
//! \copydoc IRemoteAircraftProvider::remoteAircraftParts
|
||||
virtual const BlackMisc::Aviation::CAircraftPartsList &remoteAircraftParts() const override;
|
||||
|
||||
//! \copydoc IRenderedAircraftProvider::renderedAircraftParts
|
||||
virtual BlackMisc::Aviation::CAircraftPartsList &renderedAircraftParts() override;
|
||||
//! \copydoc IRemoteAircraftProvider::remoteAircraftParts
|
||||
virtual BlackMisc::Aviation::CAircraftPartsList &remoteAircraftParts() override;
|
||||
|
||||
//! \copydoc IRenderedAircraftProvider::renderedAircraftParts
|
||||
//! \copydoc IRemoteAircraftProvider::remoteAircraftParts
|
||||
virtual bool updateAircraftEnabled(const BlackMisc::Aviation::CCallsign &callsign, bool enabledForRedering, const QString &originator) override;
|
||||
|
||||
//! \copydoc IRenderedAircraftProvider::updateAircraftModel
|
||||
//! \copydoc IRemoteAircraftProvider::updateAircraftModel
|
||||
virtual bool updateAircraftModel(const BlackMisc::Aviation::CCallsign &callsign, const BlackMisc::Simulation::CAircraftModel &model, const QString &originator) override;
|
||||
|
||||
//! Returns the list of users we know about
|
||||
@@ -107,14 +108,35 @@ namespace BlackCore
|
||||
//! Create dummy entries for performance tests
|
||||
void testCreateDummyOnlineAtcStations(int number);
|
||||
|
||||
public slots:
|
||||
//! \copydoc IRenderedAircraftProviderReadOnly::getRenderedAircraftSituations
|
||||
virtual BlackMisc::Aviation::CAircraftSituationList getRenderedAircraftSituations() const override;
|
||||
//! Aircraft situations
|
||||
virtual BlackMisc::Aviation::CAircraftSituationList getRenderedAircraftSituations() const;
|
||||
|
||||
//! \copydoc IRenderedAircraftProviderReadOnly::getRenderedAircraftParts
|
||||
virtual BlackMisc::Aviation::CAircraftPartsList getRenderedAircraftParts() const override;
|
||||
//! Aircraft parts
|
||||
virtual BlackMisc::Aviation::CAircraftPartsList getRenderedAircraftParts() const;
|
||||
|
||||
//! \copydoc IRemoteAircraftProviderReadOnly::connectSignals
|
||||
//! \copydoc IRemoteAircraftProviderReadOnly::connectSignals
|
||||
virtual bool connectRemoteAircraftProviderSignals(
|
||||
std::function<void(const BlackMisc::Aviation::CAircraftSituation &)> situationSlot,
|
||||
std::function<void(const BlackMisc::Aviation::CAircraftParts &)> partsSlot,
|
||||
std::function<void(const BlackMisc::Aviation::CCallsign &)> removedAircraftSlot
|
||||
) override;
|
||||
|
||||
const qint64 AircraftSituationsRemovedOffsetMs = 30 * 1000; //!< situations will be removed if older than
|
||||
|
||||
signals:
|
||||
|
||||
//--- signals for the provider, work locally only (not in DBus
|
||||
|
||||
//! \copydoc IRemoteAircraftProviderReadOnly::addedRemoteAircraftSituation
|
||||
void addedRemoteAircraftSituation(const BlackMisc::Aviation::CAircraftSituation &situation) override;
|
||||
|
||||
//! \copydoc IRemoteAircraftProviderReadOnly::addedRemoteAircraftPart
|
||||
void addedRemoteAircraftParts(const BlackMisc::Aviation::CAircraftParts &parts) override;
|
||||
|
||||
//! \copydoc IRemoteAircraftProviderReadOnly::removedAircraft
|
||||
void removedAircraft(const BlackMisc::Aviation::CCallsign &callsign) override;
|
||||
|
||||
//! Online ATC stations were changed
|
||||
void changedAtcStationsOnline();
|
||||
|
||||
@@ -128,13 +150,10 @@ namespace BlackCore
|
||||
void changedAircraftInRange();
|
||||
|
||||
//! A new aircraft appeared
|
||||
void addedAircraft(const BlackMisc::Simulation::CSimulatedAircraft &renderedAircraft);
|
||||
|
||||
//! An aircraft disappeared
|
||||
void removedAircraft(const BlackMisc::Aviation::CCallsign &callsign);
|
||||
void addedAircraft(const BlackMisc::Simulation::CSimulatedAircraft &remoteAircraft);
|
||||
|
||||
//! Read for model matching
|
||||
void readyForModelMatching(const BlackMisc::Simulation::CSimulatedAircraft &renderedAircraft);
|
||||
void readyForModelMatching(const BlackMisc::Simulation::CSimulatedAircraft &remoteAircraft);
|
||||
|
||||
private:
|
||||
BlackMisc::Aviation::CAtcStationList m_atcStationsOnline;
|
||||
|
||||
@@ -117,7 +117,7 @@ namespace BlackCore
|
||||
* \remarks If I use the enum, adaptor / interface are not created correctly
|
||||
* \see INetwork::ConnectionStatus
|
||||
*/
|
||||
void connectionStatusChanged(uint from, uint to);
|
||||
void connectionStatusChanged(int from, int to);
|
||||
|
||||
//! Text messages received (also private chat messages, rfaio channel messages)
|
||||
void textMessagesReceived(const BlackMisc::Network::CTextMessageList &textMessages);
|
||||
|
||||
@@ -78,6 +78,8 @@ namespace BlackCore
|
||||
connect(this->m_airspace, &CAirspaceMonitor::changedAircraftInRange, this, &CContextNetwork::changedAircraftInRange);
|
||||
connect(this->m_airspace, &CAirspaceMonitor::removedAircraft, this, &CContextNetwork::removedAircraft);
|
||||
connect(this->m_airspace, &CAirspaceMonitor::readyForModelMatching, this, &CContextNetwork::readyForModelMatching);
|
||||
connect(this->m_airspace, &CAirspaceMonitor::addedRemoteAircraftParts, this, &CContextNetwork::addedRemoteAircraftParts);
|
||||
connect(this->m_airspace, &CAirspaceMonitor::addedRemoteAircraftSituation, this, &CContextNetwork::addedRemoteAircraftSituation);
|
||||
}
|
||||
|
||||
CContextNetwork::~CContextNetwork()
|
||||
@@ -85,52 +87,49 @@ namespace BlackCore
|
||||
this->gracefulShutdown();
|
||||
}
|
||||
|
||||
const CSimulatedAircraftList &CContextNetwork::renderedAircraft() const
|
||||
const CSimulatedAircraftList &CContextNetwork::remoteAircraft() const
|
||||
{
|
||||
Q_ASSERT(this->m_airspace);
|
||||
return m_airspace->renderedAircraft();
|
||||
return m_airspace->remoteAircraft();
|
||||
}
|
||||
|
||||
CSimulatedAircraftList &CContextNetwork::renderedAircraft()
|
||||
CSimulatedAircraftList &CContextNetwork::remoteAircraft()
|
||||
{
|
||||
Q_ASSERT(this->m_airspace);
|
||||
return m_airspace->renderedAircraft();
|
||||
return m_airspace->remoteAircraft();
|
||||
}
|
||||
|
||||
CAircraftSituationList &CContextNetwork::renderedAircraftSituations()
|
||||
CAircraftSituationList &CContextNetwork::remoteAircraftSituations()
|
||||
{
|
||||
Q_ASSERT(this->m_airspace);
|
||||
return m_airspace->renderedAircraftSituations();
|
||||
return m_airspace->remoteAircraftSituations();
|
||||
}
|
||||
|
||||
CAircraftSituationList CContextNetwork::getRenderedAircraftSituations() const
|
||||
const CAircraftSituationList &CContextNetwork::remoteAircraftSituations() const
|
||||
{
|
||||
Q_ASSERT(this->m_airspace);
|
||||
return m_airspace->getRenderedAircraftSituations();
|
||||
return m_airspace->remoteAircraftSituations();
|
||||
}
|
||||
|
||||
const CAircraftSituationList &CContextNetwork::renderedAircraftSituations() const
|
||||
const CAircraftPartsList &CContextNetwork::remoteAircraftParts() const
|
||||
{
|
||||
Q_ASSERT(this->m_airspace);
|
||||
return m_airspace->renderedAircraftSituations();
|
||||
return m_airspace->remoteAircraftParts();
|
||||
}
|
||||
|
||||
const CAircraftPartsList &CContextNetwork::renderedAircraftParts() const
|
||||
CAircraftPartsList &CContextNetwork::remoteAircraftParts()
|
||||
{
|
||||
Q_ASSERT(this->m_airspace);
|
||||
return m_airspace->renderedAircraftParts();
|
||||
return m_airspace->remoteAircraftParts();
|
||||
}
|
||||
|
||||
CAircraftPartsList &CContextNetwork::renderedAircraftParts()
|
||||
bool CContextNetwork::connectRemoteAircraftProviderSignals(
|
||||
std::function<void (const CAircraftSituation &)> situationSlot,
|
||||
std::function<void (const CAircraftParts &)> partsSlot,
|
||||
std::function<void (const CCallsign &)> removedAircraftSlot)
|
||||
{
|
||||
Q_ASSERT(this->m_airspace);
|
||||
return m_airspace->renderedAircraftParts();
|
||||
}
|
||||
|
||||
CAircraftPartsList CContextNetwork::getRenderedAircraftParts() const
|
||||
{
|
||||
Q_ASSERT(this->m_airspace);
|
||||
return m_airspace->getRenderedAircraftParts();
|
||||
return this->m_airspace->connectRemoteAircraftProviderSignals(situationSlot, partsSlot, removedAircraftSlot);
|
||||
}
|
||||
|
||||
void CContextNetwork::gracefulShutdown()
|
||||
@@ -359,13 +358,13 @@ namespace BlackCore
|
||||
CSimulatedAircraftList CContextNetwork::getAircraftInRange() const
|
||||
{
|
||||
BlackMisc::CLogMessage(this, BlackMisc::CLogCategory::contextSlot()).debug() << Q_FUNC_INFO;
|
||||
return this->m_airspace->renderedAircraft();
|
||||
return this->m_airspace->remoteAircraft();
|
||||
}
|
||||
|
||||
CSimulatedAircraft CContextNetwork::getAircraftForCallsign(const CCallsign &callsign) const
|
||||
{
|
||||
BlackMisc::CLogMessage(this, BlackMisc::CLogCategory::contextSlot()).debug() << Q_FUNC_INFO << callsign;
|
||||
return this->m_airspace->renderedAircraft().findFirstByCallsign(callsign);
|
||||
return this->m_airspace->remoteAircraft().findFirstByCallsign(callsign);
|
||||
}
|
||||
|
||||
void CContextNetwork::ps_receivedBookings(const CAtcStationList &)
|
||||
@@ -400,7 +399,7 @@ namespace BlackCore
|
||||
bool c = this->m_airspace->updateAircraftEnabled(callsign, enabledForRedering, originator);
|
||||
if (c)
|
||||
{
|
||||
emit this->changedAircraftEnabled(this->renderedAircraft().findFirstByCallsign(callsign), originator);
|
||||
emit this->changedAircraftEnabled(this->remoteAircraft().findFirstByCallsign(callsign), originator);
|
||||
}
|
||||
return c;
|
||||
}
|
||||
@@ -411,7 +410,7 @@ namespace BlackCore
|
||||
bool c = this->m_airspace->updateAircraftModel(callsign, model, originator);
|
||||
if (c)
|
||||
{
|
||||
emit this->changedRenderedAircraftModel(this->renderedAircraft().findFirstByCallsign(callsign), originator);
|
||||
emit this->changedRenderedAircraftModel(this->remoteAircraft().findFirstByCallsign(callsign), originator);
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
#include "blackcore/context_network.h"
|
||||
#include "blackcore/context_settings.h"
|
||||
#include "blackcore/context_runtime.h"
|
||||
#include "blackmisc/simulation/simdirectaccessrenderedaircraft.h"
|
||||
#include "blackmisc/simulation/simdirectaccessremoteaircraft.h"
|
||||
#include "blackcore/dbus_server.h"
|
||||
#include "blackcore/network.h"
|
||||
#include "blackcore/airspace_monitor.h"
|
||||
@@ -37,10 +37,12 @@ namespace BlackCore
|
||||
//! Network context implementation
|
||||
class CContextNetwork :
|
||||
public IContextNetwork,
|
||||
public BlackMisc::Simulation::IRenderedAircraftProvider
|
||||
public BlackMisc::Simulation::IRemoteAircraftProvider
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(BlackMisc::Simulation::IRemoteAircraftProvider)
|
||||
Q_CLASSINFO("D-Bus Interface", BLACKCORE_CONTEXTNETWORK_INTERFACENAME)
|
||||
|
||||
friend class IContextNetwork;
|
||||
friend class CRuntime;
|
||||
|
||||
@@ -48,26 +50,45 @@ namespace BlackCore
|
||||
//! Destructor
|
||||
virtual ~CContextNetwork();
|
||||
|
||||
//! \copydoc IRenderedAircraftProviderReadOnly::renderedAircraft
|
||||
virtual const BlackMisc::Simulation::CSimulatedAircraftList &renderedAircraft() const override;
|
||||
//! \copydoc IRemoteAircraftProviderReadOnly::renderedAircraft
|
||||
virtual const BlackMisc::Simulation::CSimulatedAircraftList &remoteAircraft() const override;
|
||||
|
||||
//! \copydoc IRenderedAircraftProvider::renderedAircraft
|
||||
virtual BlackMisc::Simulation::CSimulatedAircraftList &renderedAircraft() override;
|
||||
virtual BlackMisc::Simulation::CSimulatedAircraftList &remoteAircraft() override;
|
||||
|
||||
//! \copydoc IRenderedAircraftProviderReadOnly::renderedAircraftSituations
|
||||
virtual const BlackMisc::Aviation::CAircraftSituationList &renderedAircraftSituations() const override;
|
||||
//! \copydoc IRemoteAircraftProviderReadOnly::renderedAircraftSituations
|
||||
virtual const BlackMisc::Aviation::CAircraftSituationList &remoteAircraftSituations() const override;
|
||||
|
||||
//! \copydoc IRenderedAircraftProviderReadOnly::renderedAircraftSituations
|
||||
virtual BlackMisc::Aviation::CAircraftSituationList &renderedAircraftSituations() override;
|
||||
//! \copydoc IRemoteAircraftProviderReadOnly::renderedAircraftSituations
|
||||
virtual BlackMisc::Aviation::CAircraftSituationList &remoteAircraftSituations() override;
|
||||
|
||||
//! \copydoc IRenderedAircraftProviderReadOnly::renderedAircraftParts
|
||||
virtual const BlackMisc::Aviation::CAircraftPartsList &renderedAircraftParts() const override;
|
||||
//! \copydoc IRemoteAircraftProviderReadOnly::renderedAircraftParts
|
||||
virtual const BlackMisc::Aviation::CAircraftPartsList &remoteAircraftParts() const override;
|
||||
|
||||
//! \copydoc IRenderedAircraftProvider::renderedAircraftParts
|
||||
virtual BlackMisc::Aviation::CAircraftPartsList &renderedAircraftParts() override;
|
||||
virtual BlackMisc::Aviation::CAircraftPartsList &remoteAircraftParts() override;
|
||||
|
||||
//! \copydoc IRemoteAircraftProviderReadOnly::connectSignals
|
||||
virtual bool connectRemoteAircraftProviderSignals(
|
||||
std::function<void(const BlackMisc::Aviation::CAircraftSituation &)> situationSlot,
|
||||
std::function<void(const BlackMisc::Aviation::CAircraftParts &)> partsSlot,
|
||||
std::function<void(const BlackMisc::Aviation::CCallsign &)> removedAircraftSlot
|
||||
) override;
|
||||
|
||||
signals:
|
||||
// IRemoteAircraftProviderReadOnly must be implemented by concrete class
|
||||
// must not prefixed virtual (though they are) -> warning
|
||||
|
||||
//! \copydoc IRemoteAircraftProviderReadOnly::addedRemoteAircraftSituation
|
||||
void addedRemoteAircraftSituation(const BlackMisc::Aviation::CAircraftSituation &situation) override;
|
||||
|
||||
//! \copydoc IRemoteAircraftProviderReadOnly::addedRemoteAircraftPart
|
||||
void addedRemoteAircraftParts(const BlackMisc::Aviation::CAircraftParts &parts) override;
|
||||
|
||||
//! \copydoc IRemoteAircraftProviderReadOnly::removedAircraft
|
||||
void removedAircraft(const BlackMisc::Aviation::CCallsign &callsign) override;
|
||||
|
||||
public slots:
|
||||
|
||||
//! \copydoc IContextNetwork::readAtcBookingsFromSource()
|
||||
virtual void readAtcBookingsFromSource() const override;
|
||||
|
||||
@@ -83,12 +104,6 @@ namespace BlackCore
|
||||
//! \copydoc IContextNetwork::getAircraftForCallsign
|
||||
virtual BlackMisc::Simulation::CSimulatedAircraft getAircraftForCallsign(const BlackMisc::Aviation::CCallsign &callsign) const override;
|
||||
|
||||
//! \copydoc IRenderedAircraftProviderReadOnly::getRenderedAircraftSituations
|
||||
virtual BlackMisc::Aviation::CAircraftSituationList getRenderedAircraftSituations() const override;
|
||||
|
||||
//! \copydoc IRenderedAircraftProviderReadOnly::getRenderedAircraftParts
|
||||
virtual BlackMisc::Aviation::CAircraftPartsList getRenderedAircraftParts() const override;
|
||||
|
||||
//! \copydoc IContextNetwork::connectToNetwork()
|
||||
virtual BlackMisc::CStatusMessage connectToNetwork(const BlackMisc::Network::CServer &server, uint mode) override;
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ namespace BlackCore
|
||||
void CContextNetworkProxy::relaySignals(const QString &serviceName, QDBusConnection &connection)
|
||||
{
|
||||
bool s = connection.connect(serviceName, IContextNetwork::ObjectPath(), IContextNetwork::InterfaceName(),
|
||||
"connectionStatusChanged", this, SIGNAL(connectionStatusChanged(uint, uint)));
|
||||
"connectionStatusChanged", this, SIGNAL(connectionStatusChanged(int, int)));
|
||||
Q_ASSERT(s);
|
||||
s = connection.connect(serviceName, IContextNetwork::ObjectPath(), IContextNetwork::InterfaceName(),
|
||||
"changedAtcStationsBooked", this, SIGNAL(changedAtcStationsBooked()));
|
||||
|
||||
@@ -210,7 +210,7 @@ namespace BlackCore
|
||||
Q_ASSERT(this->getIContextOwnAircraft()->isUsingImplementingObject());
|
||||
Q_ASSERT(this->getIContextNetwork()->isUsingImplementingObject());
|
||||
IOwnAircraftProvider *ownAircraftProvider = this->getRuntime()->getCContextOwnAircraft();
|
||||
IRenderedAircraftProvider *renderedAircraftProvider = this->getRuntime()->getCContextNetwork();
|
||||
IRemoteAircraftProvider *renderedAircraftProvider = this->getRuntime()->getCContextNetwork();
|
||||
ISimulator *newSimulator = factory->create(ownAircraftProvider, renderedAircraftProvider, this);
|
||||
Q_ASSERT(newSimulator);
|
||||
|
||||
|
||||
174
src/blackcore/interpolator.cpp
Normal file
174
src/blackcore/interpolator.cpp
Normal file
@@ -0,0 +1,174 @@
|
||||
/* Copyright (C) 2015
|
||||
* 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 "interpolator.h"
|
||||
#include "blackmisc/logmessage.h"
|
||||
#include <functional>
|
||||
|
||||
using namespace BlackMisc;
|
||||
using namespace BlackMisc::Aviation;
|
||||
using namespace BlackMisc::Simulation;
|
||||
|
||||
|
||||
namespace BlackCore
|
||||
{
|
||||
|
||||
IInterpolator::IInterpolator(IRemoteAircraftProviderReadOnly *provider, const QString &workerName, QObject *parent) :
|
||||
CContinuousWorker(parent, workerName),
|
||||
CRemoteAircraftProviderSupportReadOnly(provider)
|
||||
{
|
||||
Q_ASSERT(provider);
|
||||
this->m_situationsByCallsign = this->remoteAircraftSituations().splitPerCallsign();
|
||||
this->m_partsByCallsign = this->remoteAircraftParts().splitPerCallsign();
|
||||
bool c = provider->connectRemoteAircraftProviderSignals(
|
||||
std::bind(&IInterpolator::ps_onAddedAircraftSituation, this, std::placeholders::_1),
|
||||
std::bind(&IInterpolator::ps_onAddedAircraftParts, this, std::placeholders::_1),
|
||||
std::bind(&IInterpolator::ps_onRemoveAircraft, this, std::placeholders::_1)
|
||||
);
|
||||
Q_ASSERT(c);
|
||||
Q_UNUSED(c);
|
||||
}
|
||||
|
||||
QList<CAircraftSituationList> IInterpolator::getSituationsTimeSplit(const CCallsign &callsign, qint64 splitTimeMsSinceEpoch) const
|
||||
{
|
||||
QReadLocker l(&m_situationsLock);
|
||||
static const QList<CAircraftSituationList> empty({ CAircraftSituationList(), CAircraftSituationList() });
|
||||
if (!this->m_situationsByCallsign.contains(callsign)) { return empty; }
|
||||
return this->m_situationsByCallsign[callsign].splitByTime(splitTimeMsSinceEpoch);
|
||||
}
|
||||
|
||||
bool IInterpolator::hasEnoughAircraftSituations(const CCallsign &callsign) const
|
||||
{
|
||||
QReadLocker l(&m_situationsLock);
|
||||
if (!this->m_situationsByCallsign.contains(callsign)) { return false; }
|
||||
return this->m_situationsByCallsign[callsign].findBeforeNowMinusOffset(TimeOffsetMs).size() > 0;
|
||||
}
|
||||
|
||||
CAircraftParts IInterpolator::getLatestPartsBeforeOffset(const CCallsign &callsign, qint64 timeOffset, bool *ok) const
|
||||
{
|
||||
QReadLocker l(&m_partsLock);
|
||||
static const CAircraftParts empty;
|
||||
if (ok) { *ok = false; }
|
||||
if (this->m_partsByCallsign.contains(callsign)) { return empty; }
|
||||
CAircraftPartsList partsList = this->m_partsByCallsign[callsign].findBeforeNowMinusOffset(timeOffset);
|
||||
l.unlock();
|
||||
if (partsList.isEmpty()) { return empty; }
|
||||
if (ok) { *ok = true; }
|
||||
return partsList.latestValue();
|
||||
}
|
||||
|
||||
void IInterpolator::requestSituationsCalculationsForAllCallsigns(int requestId)
|
||||
{
|
||||
QReadLocker l(&m_situationsLock);
|
||||
Q_ASSERT(requestId >= 0);
|
||||
const QHash<BlackMisc::Aviation::CCallsign, BlackMisc::Aviation::CAircraftSituationList> situationsCopy = m_situationsByCallsign;
|
||||
l.unlock();
|
||||
|
||||
CAircraftSituationList latestInterpolations;
|
||||
for (const CCallsign &cs : situationsCopy.keys())
|
||||
{
|
||||
bool ok;
|
||||
CAircraftSituation situation = getCurrentInterpolatedSituation(situationsCopy, cs, &ok);
|
||||
if (ok)
|
||||
{
|
||||
latestInterpolations.push_back(situation);
|
||||
}
|
||||
else
|
||||
{
|
||||
// not OK can mean not enough situations
|
||||
// further logging could go here
|
||||
}
|
||||
}
|
||||
|
||||
QWriteLocker wl(&m_requestedInterpolationsLock);
|
||||
while (m_requestedInterpolations.size() >= MaxKeptInterpolationRequests - 1)
|
||||
{
|
||||
m_requestedInterpolations.erase(--m_requestedInterpolations.end());
|
||||
}
|
||||
m_requestedInterpolations.insert(requestId, latestInterpolations); // new to old
|
||||
|
||||
}
|
||||
|
||||
QHash<CCallsign, CAircraftSituationList> IInterpolator::getSituationsByCallsign() const
|
||||
{
|
||||
QReadLocker l(&m_requestedInterpolationsLock);
|
||||
return m_situationsByCallsign;
|
||||
}
|
||||
|
||||
int IInterpolator::latestFinishedRequestId() const
|
||||
{
|
||||
QReadLocker l(&m_requestedInterpolationsLock);
|
||||
if (m_requestedInterpolations.isEmpty()) { return -1; }
|
||||
return m_requestedInterpolations.keys().first();
|
||||
}
|
||||
|
||||
CAircraftSituationList IInterpolator::latestFinishedRequest() const
|
||||
{
|
||||
QReadLocker l(&m_requestedInterpolationsLock);
|
||||
static const CAircraftSituationList empty;
|
||||
if (m_requestedInterpolations.isEmpty()) { return empty; }
|
||||
return m_requestedInterpolations.values().first();
|
||||
}
|
||||
|
||||
CAircraftSituationList IInterpolator::getRequest(int requestId, bool *ok) const
|
||||
{
|
||||
QReadLocker l(&m_requestedInterpolationsLock);
|
||||
static const CAircraftSituationList empty;
|
||||
if (!m_requestedInterpolations.contains(requestId))
|
||||
{
|
||||
if (ok) { *ok = false; }
|
||||
return empty;
|
||||
}
|
||||
if (ok) { *ok = true; }
|
||||
return m_requestedInterpolations[requestId];
|
||||
}
|
||||
|
||||
void IInterpolator::ps_onAddedAircraftSituation(const CAircraftSituation &situation)
|
||||
{
|
||||
QWriteLocker lock(&m_situationsLock);
|
||||
Q_ASSERT(!situation.getCallsign().isEmpty());
|
||||
if (this->m_withDebugMsg) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO << situation; }
|
||||
|
||||
// list from new to old
|
||||
CAircraftSituationList &l = this->m_situationsByCallsign[situation.getCallsign()];
|
||||
if (l.size() >= MaxSituationsPerCallsign - 1)
|
||||
{
|
||||
l.truncate(MaxSituationsPerCallsign - 1);
|
||||
}
|
||||
l.insert(situation);
|
||||
}
|
||||
|
||||
void IInterpolator::ps_onAddedAircraftParts(const CAircraftParts &parts)
|
||||
{
|
||||
QWriteLocker lock(&m_partsLock);
|
||||
Q_ASSERT(!parts.getCallsign().isEmpty());
|
||||
if (this->m_withDebugMsg) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO << parts; }
|
||||
|
||||
// list from new to old
|
||||
CAircraftPartsList &l = this->m_partsByCallsign[parts.getCallsign()];
|
||||
if (l.size() >= MaxPartsPerCallsign - 1)
|
||||
{
|
||||
l.truncate(MaxPartsPerCallsign - 1);
|
||||
}
|
||||
l.insert(parts);
|
||||
}
|
||||
|
||||
void IInterpolator::ps_onRemoveAircraft(const CCallsign &callsign)
|
||||
{
|
||||
QWriteLocker ls(&m_situationsLock);
|
||||
QWriteLocker lp(&m_partsLock);
|
||||
Q_ASSERT(!callsign.isEmpty());
|
||||
if (this->m_withDebugMsg) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO << callsign; }
|
||||
|
||||
if (callsign.isEmpty()) { return; }
|
||||
this->m_partsByCallsign.remove(callsign);
|
||||
this->m_situationsByCallsign.remove(callsign);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
@@ -13,33 +13,98 @@
|
||||
#define BLACKCORE_INTERPOLATOR_H
|
||||
|
||||
#include "blackmisc/avaircraftsituation.h"
|
||||
#include "blackmisc/simulation/simdirectaccessremoteaircraft.h"
|
||||
#include "blackmisc/worker.h"
|
||||
#include "simulator.h"
|
||||
#include <QHash>
|
||||
#include <QList>
|
||||
|
||||
namespace BlackCore
|
||||
{
|
||||
//! Interpolator, calculation inbetween positions
|
||||
class IInterpolator
|
||||
class IInterpolator :
|
||||
public BlackMisc::CContinuousWorker,
|
||||
public BlackMisc::Simulation::CRemoteAircraftProviderSupportReadOnly
|
||||
{
|
||||
public:
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
//! Virtual destructor
|
||||
virtual ~IInterpolator() {}
|
||||
|
||||
//! Has situations?
|
||||
virtual bool hasEnoughAircraftSituations(const BlackMisc::Aviation::CCallsign &callsign) const
|
||||
{
|
||||
Q_ASSERT(m_provider);
|
||||
//! \todo Interpolator, it would be more efficient to directly getting the values and decide then
|
||||
return m_provider->renderedAircraftSituations().findBeforeNowMinusOffset(6000).findByCallsign(callsign).size() > 1;
|
||||
}
|
||||
//! \deprecated Try no to use, it would be more efficient to directly getting the values and decide then
|
||||
//! \threadsafe
|
||||
virtual bool hasEnoughAircraftSituations(const BlackMisc::Aviation::CCallsign &callsign) const;
|
||||
|
||||
//! Current interpolated situation
|
||||
virtual BlackMisc::Aviation::CAircraftSituation getCurrentInterpolatedSituation(const BlackMisc::Aviation::CCallsign &callsign) const = 0;
|
||||
//! \threadsafe
|
||||
virtual BlackMisc::Aviation::CAircraftSituation getCurrentInterpolatedSituation(const QHash<BlackMisc::Aviation::CCallsign, BlackMisc::Aviation::CAircraftSituationList> &allSituations, const BlackMisc::Aviation::CCallsign &callsign, bool *ok = nullptr) const = 0;
|
||||
|
||||
//! Latest parts before time - offset
|
||||
//! \threadsafe
|
||||
BlackMisc::Aviation::CAircraftParts getLatestPartsBeforeOffset(const BlackMisc::Aviation::CCallsign &callsign, qint64 timeOffset = TimeOffsetMs, bool *ok = nullptr) const;
|
||||
|
||||
//! Do a complete calculation for all know callsigns in background.
|
||||
//! Only use positive numbers.
|
||||
//! \threadsafe
|
||||
void requestSituationsCalculationsForAllCallsigns(int requestId);
|
||||
|
||||
//! The situations per callsign
|
||||
//! \threadsafe
|
||||
QHash<BlackMisc::Aviation::CCallsign, BlackMisc::Aviation::CAircraftSituationList> getSituationsByCallsign() const;
|
||||
|
||||
//! Last finished request id, -1 means none
|
||||
//! \threadsafe
|
||||
int latestFinishedRequestId() const;
|
||||
|
||||
//! Latest calculation
|
||||
//! \threadsafe
|
||||
BlackMisc::Aviation::CAircraftSituationList latestFinishedRequest() const;
|
||||
|
||||
//! Calculation by id
|
||||
//! \threadsafe
|
||||
BlackMisc::Aviation::CAircraftSituationList getRequest(int requestId, bool *ok = nullptr) const;
|
||||
|
||||
static const qint64 TimeOffsetMs = 6000; //!< offset for interpolation
|
||||
static const int MaxSituationsPerCallsign = 6; //!< How many situations per callsign
|
||||
static const int MaxPartsPerCallsign = 3; //!< How many parts per callsign
|
||||
static const int MaxKeptInterpolationRequests = 3; //!< How many requests are stored
|
||||
|
||||
private slots:
|
||||
//! New situation got added
|
||||
//! \threadsafe
|
||||
void ps_onAddedAircraftSituation(const BlackMisc::Aviation::CAircraftSituation &situation);
|
||||
|
||||
//! Added aircraft parts
|
||||
//! \threadsafe
|
||||
void ps_onAddedAircraftParts(const BlackMisc::Aviation::CAircraftParts &parts);
|
||||
|
||||
//! Removed aircraft
|
||||
//! \threadsafe
|
||||
void ps_onRemoveAircraft(const BlackMisc::Aviation::CCallsign &callsign);
|
||||
|
||||
protected:
|
||||
//! Constructor
|
||||
IInterpolator(BlackMisc::Simulation::IRenderedAircraftProviderReadOnly *provider) : m_provider(provider) { Q_ASSERT(provider);}
|
||||
BlackMisc::Simulation::IRenderedAircraftProviderReadOnly *m_provider = nullptr; //!< access to provider
|
||||
IInterpolator(BlackMisc::Simulation::IRemoteAircraftProviderReadOnly *provider, const QString &workerName, QObject *parent = nullptr);
|
||||
|
||||
//! Situations for times before / after
|
||||
//! \sa ITimestampObjectList::splitByTime
|
||||
//! \threadsafe
|
||||
//! \deprecated For first version
|
||||
QList<BlackMisc::Aviation::CAircraftSituationList> getSituationsTimeSplit(const BlackMisc::Aviation::CCallsign &callsign, qint64 splitTimeMsSinceEpoch) const;
|
||||
|
||||
bool m_withDebugMsg = true;
|
||||
|
||||
private:
|
||||
mutable QReadWriteLock m_situationsLock;
|
||||
mutable QReadWriteLock m_partsLock;
|
||||
mutable QReadWriteLock m_requestedInterpolationsLock;
|
||||
|
||||
// hashs, because not sorted by key but keeping order
|
||||
QHash<BlackMisc::Aviation::CCallsign, BlackMisc::Aviation::CAircraftSituationList> m_situationsByCallsign;
|
||||
QHash<BlackMisc::Aviation::CCallsign, BlackMisc::Aviation::CAircraftPartsList> m_partsByCallsign;
|
||||
QHash<int, BlackMisc::Aviation::CAircraftSituationList> m_requestedInterpolations;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -18,13 +18,18 @@ using namespace BlackMisc::Aviation;
|
||||
|
||||
namespace BlackCore
|
||||
{
|
||||
CAircraftSituation CInterpolatorLinear::getCurrentInterpolatedSituation(const CCallsign &callsign) const
|
||||
CAircraftSituation CInterpolatorLinear::getCurrentInterpolatedSituation(const QHash<CCallsign, CAircraftSituationList> &allSituations, const CCallsign &callsign, bool *ok) const
|
||||
{
|
||||
QDateTime currentTime = QDateTime::currentDateTimeUtc().addSecs(-6);
|
||||
CAircraftSituationList situationsBefore = renderedAircraftSituations().findBefore(currentTime).findByCallsign(callsign);
|
||||
CAircraftSituationList situationsAfter = renderedAircraftSituations().findAfter(currentTime).findByCallsign(callsign);
|
||||
|
||||
Q_ASSERT_X(!situationsBefore.isEmpty(), "CInterpolatorLinear::getCurrentSituation()", "List previous situations is empty!");
|
||||
const static CAircraftSituation empty;
|
||||
qint64 splitTimeMsSinceEpoch = QDateTime::currentMSecsSinceEpoch() - TimeOffsetMs;
|
||||
QList<CAircraftSituationList> splitSituations = allSituations[callsign].splitByTime(splitTimeMsSinceEpoch);
|
||||
CAircraftSituationList &situationsBefore = splitSituations[0];
|
||||
CAircraftSituationList &situationsAfter = splitSituations[1];
|
||||
if (situationsBefore.isEmpty())
|
||||
{
|
||||
if (ok) { *ok = false; }
|
||||
return empty;
|
||||
}
|
||||
|
||||
CAircraftSituation beginSituation;
|
||||
CAircraftSituation endSituation;
|
||||
@@ -49,7 +54,7 @@ namespace BlackCore
|
||||
double deltaTime = beginSituation.msecsToAbs(endSituation);
|
||||
|
||||
// Fraction of the deltaTime [0.0 - 1.0]
|
||||
double simulationTimeFraction = beginSituation.getUtcTimestamp().msecsTo(currentTime) / deltaTime;
|
||||
double simulationTimeFraction = (beginSituation.getMSecsSinceEpoch() - splitTimeMsSinceEpoch) / deltaTime;
|
||||
|
||||
// Interpolate latitude: Lat = (LatB - LatA) * t + LatA
|
||||
currentPosition.setLatitude((endSituation.getPosition().latitude() - beginSituation.getPosition().latitude())
|
||||
@@ -73,10 +78,14 @@ namespace BlackCore
|
||||
CHeading headingEnd = endSituation.getHeading();
|
||||
|
||||
if ((headingEnd - headingBegin).value(CAngleUnit::deg()) < -180)
|
||||
{
|
||||
headingEnd += CHeading(360, CHeading::Magnetic, CAngleUnit::deg());
|
||||
}
|
||||
|
||||
if ((headingEnd - headingBegin).value(CAngleUnit::deg()) > 180)
|
||||
{
|
||||
headingEnd -= CHeading(360, CHeading::Magnetic, CAngleUnit::deg());
|
||||
}
|
||||
|
||||
currentSituation.setHeading(CHeading((headingEnd - headingBegin)
|
||||
* simulationTimeFraction
|
||||
@@ -86,7 +95,6 @@ namespace BlackCore
|
||||
// Interpolate Pitch: Pitch = (PitchB - PitchA) * t + PitchA
|
||||
CAngle pitchBegin = beginSituation.getPitch();
|
||||
CAngle pitchEnd = endSituation.getPitch();
|
||||
|
||||
CAngle pitch = (pitchEnd - pitchBegin) * simulationTimeFraction + pitchBegin;
|
||||
|
||||
// TODO: According to the specification, pitch above horizon should be negative.
|
||||
@@ -97,7 +105,6 @@ namespace BlackCore
|
||||
// Interpolate bank: Bank = (BankB - BankA) * t + BankA
|
||||
CAngle bankBegin = beginSituation.getBank();
|
||||
CAngle bankEnd = endSituation.getBank();
|
||||
|
||||
CAngle bank = (bankEnd - bankBegin) * simulationTimeFraction + bankBegin;
|
||||
|
||||
// TODO: According to the specification, banks to the right should be negative.
|
||||
@@ -108,7 +115,7 @@ namespace BlackCore
|
||||
currentSituation.setGroundspeed((endSituation.getGroundSpeed() - beginSituation.getGroundSpeed())
|
||||
* simulationTimeFraction
|
||||
+ beginSituation.getGroundSpeed());
|
||||
|
||||
if (ok) { *ok = true; }
|
||||
return currentSituation;
|
||||
}
|
||||
|
||||
|
||||
@@ -20,19 +20,17 @@
|
||||
|
||||
namespace BlackCore
|
||||
{
|
||||
//! \brief Linear interpolator, calculation inbetween positions
|
||||
class CInterpolatorLinear :
|
||||
public IInterpolator,
|
||||
public BlackMisc::Simulation::CRenderedAircraftProviderSupportReadOnly
|
||||
//! Linear interpolator, calculation inbetween positions
|
||||
class CInterpolatorLinear : public IInterpolator
|
||||
{
|
||||
public:
|
||||
//! Constructor
|
||||
CInterpolatorLinear(BlackMisc::Simulation::IRenderedAircraftProviderReadOnly *provider) :
|
||||
IInterpolator(provider),
|
||||
BlackMisc::Simulation::CRenderedAircraftProviderSupportReadOnly(provider) {}
|
||||
CInterpolatorLinear(BlackMisc::Simulation::IRemoteAircraftProviderReadOnly *provider, QObject *parent = nullptr) :
|
||||
IInterpolator(provider, "CInterpolatorLinear", parent)
|
||||
{}
|
||||
|
||||
//! \copydoc IInterpolator::getCurrentInterpolatedSituation
|
||||
virtual BlackMisc::Aviation::CAircraftSituation getCurrentInterpolatedSituation(const BlackMisc::Aviation::CCallsign &callsign) const override;
|
||||
virtual BlackMisc::Aviation::CAircraftSituation getCurrentInterpolatedSituation(const QHash<BlackMisc::Aviation::CCallsign, BlackMisc::Aviation::CAircraftSituationList> &allSituations, const BlackMisc::Aviation::CCallsign &callsign, bool *ok = nullptr) const override;
|
||||
};
|
||||
|
||||
} // namespace BlackCore
|
||||
|
||||
@@ -19,8 +19,8 @@ namespace BlackCore
|
||||
emit simulatorStatusChanged(isConnected(), isSimulating(), isPaused());
|
||||
}
|
||||
|
||||
CSimulatorCommon::CSimulatorCommon(const BlackSim::CSimulatorInfo &simInfo, BlackMisc::Simulation::IOwnAircraftProvider *ownAircraftProvider, BlackMisc::Simulation::IRenderedAircraftProvider *renderedAircraftProvider, QObject *parent)
|
||||
: ISimulator(parent), COwnAircraftProviderSupport(ownAircraftProvider), CRenderedAircraftProviderSupport(renderedAircraftProvider), m_simulatorInfo(simInfo)
|
||||
CSimulatorCommon::CSimulatorCommon(const BlackSim::CSimulatorInfo &simInfo, BlackMisc::Simulation::IOwnAircraftProvider *ownAircraftProvider, BlackMisc::Simulation::IRemoteAircraftProvider *remoteAircraftProvider, QObject *parent)
|
||||
: ISimulator(parent), COwnAircraftProviderSupport(ownAircraftProvider), CRemoteAircraftProviderSupport(remoteAircraftProvider), m_simulatorInfo(simInfo)
|
||||
{ }
|
||||
|
||||
int CSimulatorCommon::getMaxRenderedAircraft() const
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
#include "blackmisc/simulation/simulatedaircraftlist.h"
|
||||
#include "blackmisc/simulation/aircraftmodellist.h"
|
||||
#include "blackmisc/simulation/simdirectaccessownaircraft.h"
|
||||
#include "blackmisc/simulation/simdirectaccessrenderedaircraft.h"
|
||||
#include "blackmisc/simulation/simdirectaccessremoteaircraft.h"
|
||||
#include "blackmisc/statusmessagelist.h"
|
||||
#include "blackmisc/avairportlist.h"
|
||||
#include "blackmisc/nwtextmessage.h"
|
||||
@@ -177,7 +177,7 @@ namespace BlackCore
|
||||
//!
|
||||
virtual ISimulator *create(
|
||||
BlackMisc::Simulation::IOwnAircraftProvider *ownAircraftProvider,
|
||||
BlackMisc::Simulation::IRenderedAircraftProvider *renderedAircraftProvider,
|
||||
BlackMisc::Simulation::IRemoteAircraftProvider *renderedAircraftProvider,
|
||||
QObject *parent = nullptr) = 0;
|
||||
|
||||
//! Simulator info
|
||||
@@ -188,7 +188,7 @@ namespace BlackCore
|
||||
class CSimulatorCommon :
|
||||
public BlackCore::ISimulator,
|
||||
public BlackMisc::Simulation::COwnAircraftProviderSupport, // gain access to in memor own aircraft data
|
||||
public BlackMisc::Simulation::CRenderedAircraftProviderSupport // gain access to in memory rendered aircraft data
|
||||
public BlackMisc::Simulation::CRemoteAircraftProviderSupport // gain access to in memory rendered aircraft data
|
||||
{
|
||||
|
||||
public:
|
||||
@@ -206,7 +206,7 @@ namespace BlackCore
|
||||
CSimulatorCommon(
|
||||
const BlackSim::CSimulatorInfo &simInfo,
|
||||
BlackMisc::Simulation::IOwnAircraftProvider *ownAircraftProvider,
|
||||
BlackMisc::Simulation::IRenderedAircraftProvider *renderedAircraftProvider,
|
||||
BlackMisc::Simulation::IRemoteAircraftProvider *remoteAircraftProvider,
|
||||
QObject *parent = nullptr);
|
||||
|
||||
BlackSim::CSimulatorInfo m_simulatorInfo; //!< about the simulator
|
||||
|
||||
@@ -110,7 +110,7 @@ namespace BlackGui
|
||||
this->tabBar()->setTabText(ap, aps);
|
||||
}
|
||||
|
||||
void CAircraftComponent::ps_connectionStatusChanged(uint from, uint to)
|
||||
void CAircraftComponent::ps_connectionStatusChanged(int from, int to)
|
||||
{
|
||||
INetwork::ConnectionStatus fromStatus = static_cast<INetwork::ConnectionStatus>(from);
|
||||
INetwork::ConnectionStatus toStatus = static_cast<INetwork::ConnectionStatus>(to);
|
||||
|
||||
@@ -74,7 +74,7 @@ namespace BlackGui
|
||||
void ps_onRowCountChanged(int count, bool withFilter);
|
||||
|
||||
//! Connection status has been changed
|
||||
void ps_connectionStatusChanged(uint from, uint to);
|
||||
void ps_connectionStatusChanged(int from, int to);
|
||||
|
||||
private:
|
||||
QScopedPointer<Ui::CAircraftComponent> ui;
|
||||
|
||||
@@ -100,11 +100,11 @@ namespace BlackMisc
|
||||
}
|
||||
|
||||
template <class OBJ, class CONTAINER>
|
||||
QMap<CCallsign, CONTAINER> ICallsignObjectList<OBJ, CONTAINER>::splitPerCallsign() const
|
||||
QHash<CCallsign, CONTAINER> ICallsignObjectList<OBJ, CONTAINER>::splitPerCallsign() const
|
||||
{
|
||||
CONTAINER copyContainer(getContainer());
|
||||
copyContainer.sortByCallsign();
|
||||
QMap<CCallsign, CONTAINER> result;
|
||||
QHash<CCallsign, CONTAINER> result;
|
||||
CCallsign cs;
|
||||
for (const OBJ &csObj : copyContainer)
|
||||
{
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
#include "blackmisc/propertyindexlist.h"
|
||||
#include "blackmisc/propertyindexvariantmap.h"
|
||||
#include <QList>
|
||||
#include <QMap>
|
||||
#include <QHash>
|
||||
|
||||
namespace BlackMisc
|
||||
{
|
||||
@@ -58,7 +58,7 @@ namespace BlackMisc
|
||||
QMap<QString, int> getSuffixes() const;
|
||||
|
||||
//! Split into 0..n containers as per callsign
|
||||
QMap<BlackMisc::Aviation::CCallsign, CONTAINER> splitPerCallsign() const;
|
||||
QHash<BlackMisc::Aviation::CCallsign, CONTAINER> splitPerCallsign() const;
|
||||
|
||||
//! Sort by callsign
|
||||
void sortByCallsign();
|
||||
|
||||
86
src/blackmisc/simulation/simdirectaccessremoteaircraft.cpp
Normal file
86
src/blackmisc/simulation/simdirectaccessremoteaircraft.cpp
Normal file
@@ -0,0 +1,86 @@
|
||||
/* Copyright (C) 2015
|
||||
* 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 "simdirectaccessremoteaircraft.h"
|
||||
|
||||
using namespace BlackMisc::Aviation;
|
||||
|
||||
namespace BlackMisc
|
||||
{
|
||||
namespace Simulation
|
||||
{
|
||||
|
||||
const CSimulatedAircraftList &CRemoteAircraftProviderSupportReadOnly::remoteAircraft() const
|
||||
{
|
||||
Q_ASSERT_X(this->m_remoteAircraftProvider, "renderedAircraft", "No object available");
|
||||
return this->m_remoteAircraftProvider->remoteAircraft();
|
||||
}
|
||||
|
||||
const Aviation::CAircraftSituationList &CRemoteAircraftProviderSupportReadOnly::remoteAircraftSituations() const
|
||||
{
|
||||
Q_ASSERT_X(this->m_remoteAircraftProvider, "renderedAircraftSituations", "No object available");
|
||||
return this->m_remoteAircraftProvider->remoteAircraftSituations();
|
||||
}
|
||||
|
||||
const Aviation::CAircraftPartsList &CRemoteAircraftProviderSupportReadOnly::remoteAircraftParts() const
|
||||
{
|
||||
Q_ASSERT_X(this->m_remoteAircraftProvider, "renderedAircraftParts", "No object available");
|
||||
return this->m_remoteAircraftProvider->remoteAircraftParts();
|
||||
}
|
||||
|
||||
const CSimulatedAircraftList &CRemoteAircraftProviderSupport::remoteAircraft() const
|
||||
{
|
||||
Q_ASSERT_X(this->m_remoteAircraftProvider, "renderedAircraft", "No object available");
|
||||
return this->m_remoteAircraftProvider->remoteAircraft();
|
||||
}
|
||||
|
||||
CSimulatedAircraftList &CRemoteAircraftProviderSupport::remoteAircraft()
|
||||
{
|
||||
Q_ASSERT_X(this->m_remoteAircraftProvider, "renderedAircraft", "No object available");
|
||||
return this->m_remoteAircraftProvider->remoteAircraft();
|
||||
}
|
||||
|
||||
const CAircraftSituationList &CRemoteAircraftProviderSupport::remoteAircraftSituations() const
|
||||
{
|
||||
Q_ASSERT_X(this->m_remoteAircraftProvider, "renderedAircraftSituations", "No object available");
|
||||
return this->m_remoteAircraftProvider->remoteAircraftSituations();
|
||||
}
|
||||
|
||||
CAircraftSituationList &CRemoteAircraftProviderSupport::remoteAircraftSituations()
|
||||
{
|
||||
Q_ASSERT_X(this->m_remoteAircraftProvider, "renderedAircraftSituations", "No object available");
|
||||
return this->m_remoteAircraftProvider->remoteAircraftSituations();
|
||||
}
|
||||
|
||||
const CAircraftPartsList &CRemoteAircraftProviderSupport::remoteAircraftParts() const
|
||||
{
|
||||
Q_ASSERT_X(this->m_remoteAircraftProvider, "renderedAircraftParts", "No object available");
|
||||
return this->m_remoteAircraftProvider->remoteAircraftParts();
|
||||
}
|
||||
|
||||
CAircraftPartsList &CRemoteAircraftProviderSupport::remoteAircraftParts()
|
||||
{
|
||||
Q_ASSERT_X(this->m_remoteAircraftProvider, "renderedAircraftParts", "No object available");
|
||||
return this->m_remoteAircraftProvider->remoteAircraftParts();
|
||||
}
|
||||
|
||||
bool CRemoteAircraftProviderSupport::providerUpdateAircraftModel(const Aviation::CCallsign &callsign, const CAircraftModel &model, const QString &originator)
|
||||
{
|
||||
Q_ASSERT_X(this->m_remoteAircraftProvider, "providerUpdateAircraftModel", "No object available");
|
||||
return this->m_remoteAircraftProvider->updateAircraftModel(callsign, model, originator);
|
||||
}
|
||||
|
||||
bool CRemoteAircraftProviderSupport::providerUpdateAircraftEnabled(const Aviation::CCallsign &callsign, bool enabledForRedering, const QString &originator)
|
||||
{
|
||||
Q_ASSERT_X(this->m_remoteAircraftProvider, "providerUpdateAircraftEnabled", "No object available");
|
||||
return this->m_remoteAircraftProvider->updateAircraftEnabled(callsign, enabledForRedering, originator);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
149
src/blackmisc/simulation/simdirectaccessremoteaircraft.h
Normal file
149
src/blackmisc/simulation/simdirectaccessremoteaircraft.h
Normal file
@@ -0,0 +1,149 @@
|
||||
/* Copyright (C) 2015
|
||||
* 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_SIMDIRECTACCESSREMOTEAIRCRAFT_H
|
||||
#define BLACKMISC_SIMDIRECTACCESSREMOTEAIRCRAFT_H
|
||||
|
||||
#include "blackmisc/simulation/simulatedaircraftlist.h"
|
||||
#include "blackmisc/avaircraftsituationlist.h"
|
||||
#include "blackmisc/aviation/aircraftpartslist.h"
|
||||
#include <functional>
|
||||
|
||||
namespace BlackMisc
|
||||
{
|
||||
namespace Simulation
|
||||
{
|
||||
//! Direct in memory access to remote aircraft
|
||||
//! \note Can not be derived from QObject (as for the signals), as this would create multiple
|
||||
//! inheritance. Hence Q_DECLARE_INTERFACE is used.
|
||||
class IRemoteAircraftProviderReadOnly
|
||||
{
|
||||
public:
|
||||
//! All rendered aircraft
|
||||
virtual const CSimulatedAircraftList &remoteAircraft() const = 0;
|
||||
|
||||
//! All situation (per callsign, time history)
|
||||
virtual const BlackMisc::Aviation::CAircraftSituationList &remoteAircraftSituations() const = 0;
|
||||
|
||||
//! All parts (per callsign, time history)
|
||||
virtual const BlackMisc::Aviation::CAircraftPartsList &remoteAircraftParts() const = 0;
|
||||
|
||||
//! Destructor
|
||||
virtual ~IRemoteAircraftProviderReadOnly() {}
|
||||
|
||||
//! Connect signals to slot receiver. As the interface is no QObject, slots can not be connected directly.
|
||||
virtual bool connectRemoteAircraftProviderSignals(
|
||||
std::function<void(const BlackMisc::Aviation::CAircraftSituation &)> situationSlot,
|
||||
std::function<void(const BlackMisc::Aviation::CAircraftParts &)> partsSlot,
|
||||
std::function<void(const BlackMisc::Aviation::CCallsign &)> removedAircraftSlot
|
||||
) = 0;
|
||||
|
||||
// those signals have to be implemented by classes using the interface.
|
||||
signals:
|
||||
//! A new situation got added
|
||||
virtual void addedRemoteAircraftSituation(const BlackMisc::Aviation::CAircraftSituation &situation) = 0;
|
||||
|
||||
//! New parts got added
|
||||
virtual void addedRemoteAircraftParts(const BlackMisc::Aviation::CAircraftParts &parts) = 0;
|
||||
|
||||
//! Aircraft was removed
|
||||
virtual void removedAircraft(const BlackMisc::Aviation::CCallsign &callsign) = 0;
|
||||
|
||||
};
|
||||
|
||||
//! Direct in memory access to own aircraft
|
||||
class IRemoteAircraftProvider : public IRemoteAircraftProviderReadOnly
|
||||
{
|
||||
public:
|
||||
//! All rendered aircraft
|
||||
//! \note in memory reference, not thread safe
|
||||
virtual CSimulatedAircraftList &remoteAircraft() = 0;
|
||||
|
||||
//! Rendered aircraft situations (history)
|
||||
virtual BlackMisc::Aviation::CAircraftSituationList &remoteAircraftSituations() = 0;
|
||||
|
||||
//! All parts (per callsign, time history)
|
||||
//! \note in memory reference, not thread safe
|
||||
virtual BlackMisc::Aviation::CAircraftPartsList &remoteAircraftParts() = 0;
|
||||
|
||||
//! Enable/disable rendering
|
||||
virtual bool updateAircraftEnabled(const BlackMisc::Aviation::CCallsign &callsign, bool enabledForRedering, const QString &originator) = 0;
|
||||
|
||||
//! Change model string
|
||||
virtual bool updateAircraftModel(const BlackMisc::Aviation::CCallsign &callsign, const BlackMisc::Simulation::CAircraftModel &model, const QString &originator) = 0;
|
||||
};
|
||||
|
||||
//! Class which can be directly used providing access to such an interface
|
||||
class CRemoteAircraftProviderSupportReadOnly
|
||||
{
|
||||
public:
|
||||
//! \copydoc IRemoteAircraftProviderReadOnly::renderedAircraft
|
||||
virtual const CSimulatedAircraftList &remoteAircraft() const;
|
||||
|
||||
//!\copydoc IRemoteAircraftProviderReadOnly::renderedAircraftSituations
|
||||
virtual const BlackMisc::Aviation::CAircraftSituationList &remoteAircraftSituations() const;
|
||||
|
||||
//!\copydoc IRemoteAircraftProviderReadOnly::renderedAircraftParts
|
||||
virtual const BlackMisc::Aviation::CAircraftPartsList &remoteAircraftParts() const;
|
||||
|
||||
//! Destructor
|
||||
virtual ~CRemoteAircraftProviderSupportReadOnly() {}
|
||||
|
||||
protected:
|
||||
//! Constructor
|
||||
CRemoteAircraftProviderSupportReadOnly(const IRemoteAircraftProviderReadOnly *remoteAircraftProvider) : m_remoteAircraftProvider(remoteAircraftProvider) {}
|
||||
const IRemoteAircraftProviderReadOnly *m_remoteAircraftProvider = nullptr; //!< access to object
|
||||
};
|
||||
|
||||
//! Delegating class which can be directly used providing access to such an interface
|
||||
class CRemoteAircraftProviderSupport
|
||||
{
|
||||
public:
|
||||
//! \copydoc IRemoteAircraftProviderReadOnly::renderedAircraft
|
||||
virtual const CSimulatedAircraftList &remoteAircraft() const;
|
||||
|
||||
//! \copydoc IRemoteAircraftProvider::renderedAircraft
|
||||
virtual CSimulatedAircraftList &remoteAircraft();
|
||||
|
||||
//!\copydoc IRemoteAircraftProviderReadOnly::renderedAircraftSituations
|
||||
virtual const BlackMisc::Aviation::CAircraftSituationList &remoteAircraftSituations() const;
|
||||
|
||||
//!\copydoc IRemoteAircraftProvider::remoteAircraftSituations
|
||||
virtual BlackMisc::Aviation::CAircraftSituationList &remoteAircraftSituations();
|
||||
|
||||
//!\copydoc IRemoteAircraftProviderReadOnly::renderedAircraftParts
|
||||
virtual const BlackMisc::Aviation::CAircraftPartsList &remoteAircraftParts() const;
|
||||
|
||||
//!\copydoc IRemoteAircraftProvider::remoteAircraftParts
|
||||
virtual BlackMisc::Aviation::CAircraftPartsList &remoteAircraftParts();
|
||||
|
||||
//! \copydoc IRemoteAircraftProvider::updateAircraftEnabled
|
||||
virtual bool providerUpdateAircraftEnabled(const BlackMisc::Aviation::CCallsign &callsign, bool enabledForRedering, const QString &originator);
|
||||
|
||||
//! \copydoc IRemoteAircraftProvider::updateAircraftModel
|
||||
virtual bool providerUpdateAircraftModel(const BlackMisc::Aviation::CCallsign &callsign, const BlackMisc::Simulation::CAircraftModel &model, const QString &originator);
|
||||
|
||||
//! Destructor
|
||||
virtual ~CRemoteAircraftProviderSupport() {}
|
||||
|
||||
protected:
|
||||
//! Constructor
|
||||
CRemoteAircraftProviderSupport(IRemoteAircraftProvider *remoteAircraftProvider) : m_remoteAircraftProvider(remoteAircraftProvider) { Q_ASSERT(remoteAircraftProvider); }
|
||||
IRemoteAircraftProvider *m_remoteAircraftProvider = nullptr; //!< access to object
|
||||
};
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
|
||||
Q_DECLARE_INTERFACE(BlackMisc::Simulation::IRemoteAircraftProviderReadOnly, "IRemoteAircraftProviderReadOnly")
|
||||
Q_DECLARE_INTERFACE(BlackMisc::Simulation::IRemoteAircraftProvider, "IRemoteAircraftProvider")
|
||||
|
||||
#endif // guard
|
||||
@@ -1,85 +0,0 @@
|
||||
/* Copyright (C) 2015
|
||||
* 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 "simdirectaccessrenderedaircraft.h"
|
||||
|
||||
using namespace BlackMisc::Aviation;
|
||||
|
||||
namespace BlackMisc
|
||||
{
|
||||
namespace Simulation
|
||||
{
|
||||
const CSimulatedAircraftList &CRenderedAircraftProviderSupportReadOnly::renderedAircraft() const
|
||||
{
|
||||
Q_ASSERT_X(this->m_renderedAircraftProvider, "renderedAircraft", "No object available");
|
||||
return this->m_renderedAircraftProvider->renderedAircraft();
|
||||
}
|
||||
|
||||
const Aviation::CAircraftSituationList &CRenderedAircraftProviderSupportReadOnly::renderedAircraftSituations() const
|
||||
{
|
||||
Q_ASSERT_X(this->m_renderedAircraftProvider, "renderedAircraftSituations", "No object available");
|
||||
return this->m_renderedAircraftProvider->renderedAircraftSituations();
|
||||
}
|
||||
|
||||
const Aviation::CAircraftPartsList &CRenderedAircraftProviderSupportReadOnly::renderedAircraftParts() const
|
||||
{
|
||||
Q_ASSERT_X(this->m_renderedAircraftProvider, "renderedAircraftParts", "No object available");
|
||||
return this->m_renderedAircraftProvider->renderedAircraftParts();
|
||||
}
|
||||
|
||||
const CSimulatedAircraftList &CRenderedAircraftProviderSupport::renderedAircraft() const
|
||||
{
|
||||
Q_ASSERT_X(this->m_renderedAircraftProvider, "renderedAircraft", "No object available");
|
||||
return this->m_renderedAircraftProvider->renderedAircraft();
|
||||
}
|
||||
|
||||
CSimulatedAircraftList &CRenderedAircraftProviderSupport::renderedAircraft()
|
||||
{
|
||||
Q_ASSERT_X(this->m_renderedAircraftProvider, "renderedAircraft", "No object available");
|
||||
return this->m_renderedAircraftProvider->renderedAircraft();
|
||||
}
|
||||
|
||||
const CAircraftSituationList &CRenderedAircraftProviderSupport::renderedAircraftSituations() const
|
||||
{
|
||||
Q_ASSERT_X(this->m_renderedAircraftProvider, "renderedAircraftSituations", "No object available");
|
||||
return this->m_renderedAircraftProvider->renderedAircraftSituations();
|
||||
}
|
||||
|
||||
CAircraftSituationList &CRenderedAircraftProviderSupport::renderedAircraftSituations()
|
||||
{
|
||||
Q_ASSERT_X(this->m_renderedAircraftProvider, "renderedAircraftSituations", "No object available");
|
||||
return this->m_renderedAircraftProvider->renderedAircraftSituations();
|
||||
}
|
||||
|
||||
const CAircraftPartsList &CRenderedAircraftProviderSupport::renderedAircraftParts() const
|
||||
{
|
||||
Q_ASSERT_X(this->m_renderedAircraftProvider, "renderedAircraftParts", "No object available");
|
||||
return this->m_renderedAircraftProvider->renderedAircraftParts();
|
||||
}
|
||||
|
||||
CAircraftPartsList &CRenderedAircraftProviderSupport::renderedAircraftParts()
|
||||
{
|
||||
Q_ASSERT_X(this->m_renderedAircraftProvider, "renderedAircraftParts", "No object available");
|
||||
return this->m_renderedAircraftProvider->renderedAircraftParts();
|
||||
}
|
||||
|
||||
bool CRenderedAircraftProviderSupport::providerUpdateAircraftModel(const Aviation::CCallsign &callsign, const CAircraftModel &model, const QString &originator)
|
||||
{
|
||||
Q_ASSERT_X(this->m_renderedAircraftProvider, "providerUpdateAircraftModel", "No object available");
|
||||
return this->m_renderedAircraftProvider->updateAircraftModel(callsign, model, originator);
|
||||
}
|
||||
|
||||
bool CRenderedAircraftProviderSupport::providerUpdateAircraftEnabled(const Aviation::CCallsign &callsign, bool enabledForRedering, const QString &originator)
|
||||
{
|
||||
Q_ASSERT_X(this->m_renderedAircraftProvider, "providerUpdateAircraftEnabled", "No object available");
|
||||
return this->m_renderedAircraftProvider->updateAircraftEnabled(callsign, enabledForRedering, originator);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
@@ -1,126 +0,0 @@
|
||||
/* Copyright (C) 2015
|
||||
* 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_SIMDIRECTACCESSRENDEREDAIRCRAFT_H
|
||||
#define BLACKMISC_SIMDIRECTACCESSRENDEREDAIRCRAFT_H
|
||||
|
||||
#include "blackmisc/simulation/simulatedaircraftlist.h"
|
||||
#include "blackmisc/avaircraftsituationlist.h"
|
||||
#include "blackmisc/aviation/aircraftpartslist.h"
|
||||
|
||||
namespace BlackMisc
|
||||
{
|
||||
namespace Simulation
|
||||
{
|
||||
//! Direct in memory access to rendered aircraft
|
||||
class IRenderedAircraftProviderReadOnly
|
||||
{
|
||||
public:
|
||||
//! All rendered aircraft
|
||||
virtual const CSimulatedAircraftList &renderedAircraft() const = 0;
|
||||
|
||||
//! All situation (per callsign, time history)
|
||||
virtual const BlackMisc::Aviation::CAircraftSituationList &renderedAircraftSituations() const = 0;
|
||||
|
||||
//! Rendered aircraft situations (history) as copy
|
||||
//! \threadsafe
|
||||
virtual BlackMisc::Aviation::CAircraftSituationList getRenderedAircraftSituations() const = 0;
|
||||
|
||||
//! All parts (per callsign, time history)
|
||||
virtual const BlackMisc::Aviation::CAircraftPartsList &renderedAircraftParts() const = 0;
|
||||
|
||||
//! All parts (per callsign, time history) as copy
|
||||
//! \threadsafe
|
||||
virtual BlackMisc::Aviation::CAircraftPartsList getRenderedAircraftParts() const = 0;
|
||||
|
||||
//! Destructor
|
||||
virtual ~IRenderedAircraftProviderReadOnly() {}
|
||||
};
|
||||
|
||||
//! Direct in memory access to own aircraft
|
||||
class IRenderedAircraftProvider : public IRenderedAircraftProviderReadOnly
|
||||
{
|
||||
public:
|
||||
//! All rendered aircraft
|
||||
//! \note in memory reference, not thread safe
|
||||
virtual CSimulatedAircraftList &renderedAircraft() = 0;
|
||||
|
||||
//! Rendered aircraft situations (history)
|
||||
virtual BlackMisc::Aviation::CAircraftSituationList &renderedAircraftSituations() = 0;
|
||||
|
||||
//! All parts (per callsign, time history)
|
||||
//! \note in memory reference, not thread safe
|
||||
virtual BlackMisc::Aviation::CAircraftPartsList &renderedAircraftParts() = 0;
|
||||
|
||||
//! Enable/disable rendering
|
||||
virtual bool updateAircraftEnabled(const BlackMisc::Aviation::CCallsign &callsign, bool enabledForRedering, const QString &originator) = 0;
|
||||
|
||||
//! Change model string
|
||||
virtual bool updateAircraftModel(const BlackMisc::Aviation::CCallsign &callsign, const BlackMisc::Simulation::CAircraftModel &model, const QString &originator) = 0;
|
||||
};
|
||||
|
||||
//! Class which can be directly used providing access to such an interface
|
||||
class CRenderedAircraftProviderSupportReadOnly
|
||||
{
|
||||
public:
|
||||
//! \copydoc IRenderedAircraftProviderReadOnly::renderedAircraft
|
||||
virtual const CSimulatedAircraftList &renderedAircraft() const;
|
||||
|
||||
//!\copydoc IRenderedAircraftProviderReadOnly::renderedAircraftSituations
|
||||
virtual const BlackMisc::Aviation::CAircraftSituationList &renderedAircraftSituations() const;
|
||||
|
||||
//!\copydoc IRenderedAircraftProviderReadOnly::renderedAircraftParts
|
||||
virtual const BlackMisc::Aviation::CAircraftPartsList &renderedAircraftParts() const;
|
||||
|
||||
protected:
|
||||
//! Constructor
|
||||
CRenderedAircraftProviderSupportReadOnly(const IRenderedAircraftProviderReadOnly *renderedAircraftProvider) : m_renderedAircraftProvider(renderedAircraftProvider) {}
|
||||
const IRenderedAircraftProviderReadOnly *m_renderedAircraftProvider = nullptr; //!< access to object
|
||||
};
|
||||
|
||||
//! Delegating class which can be directly used providing access to such an interface
|
||||
class CRenderedAircraftProviderSupport
|
||||
{
|
||||
public:
|
||||
//! \copydoc IRenderedAircraftProviderReadOnly::renderedAircraft
|
||||
virtual const CSimulatedAircraftList &renderedAircraft() const;
|
||||
|
||||
//! \copydoc IRenderedAircraftProvider::renderedAircraft
|
||||
virtual CSimulatedAircraftList &renderedAircraft();
|
||||
|
||||
//!\copydoc IRenderedAircraftProviderReadOnly::renderedAircraftSituations
|
||||
virtual const BlackMisc::Aviation::CAircraftSituationList &renderedAircraftSituations() const;
|
||||
|
||||
//!\copydoc IRenderedAircraftProvider::renderedAircraftSituations
|
||||
virtual BlackMisc::Aviation::CAircraftSituationList &renderedAircraftSituations();
|
||||
|
||||
//!\copydoc IRenderedAircraftProviderReadOnly::renderedAircraftParts
|
||||
virtual const BlackMisc::Aviation::CAircraftPartsList &renderedAircraftParts() const;
|
||||
|
||||
//!\copydoc IRenderedAircraftProvider::renderedAircraftParts
|
||||
virtual BlackMisc::Aviation::CAircraftPartsList &renderedAircraftParts();
|
||||
|
||||
//! \copydoc IRenderedAircraftProvider::updateAircraftEnabled
|
||||
virtual bool providerUpdateAircraftEnabled(const BlackMisc::Aviation::CCallsign &callsign, bool enabledForRedering, const QString &originator);
|
||||
|
||||
//! \copydoc IRenderedAircraftProvider::updateAircraftModel
|
||||
virtual bool providerUpdateAircraftModel(const BlackMisc::Aviation::CCallsign &callsign, const BlackMisc::Simulation::CAircraftModel &model, const QString &originator);
|
||||
|
||||
protected:
|
||||
//! Constructor
|
||||
CRenderedAircraftProviderSupport(IRenderedAircraftProvider *renderedAircraftProvider) : m_renderedAircraftProvider(renderedAircraftProvider) { Q_ASSERT(renderedAircraftProvider); }
|
||||
IRenderedAircraftProvider *m_renderedAircraftProvider = nullptr; //!< access to object
|
||||
};
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
|
||||
#endif // guard
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Copyright (C) 2015
|
||||
* swift Project Community / Contributors
|
||||
* 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,
|
||||
@@ -7,146 +7,79 @@
|
||||
* contained in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "blackmisc/timestampobjectlist.h"
|
||||
#include "blackmisc/predicates.h"
|
||||
#include "blackmisc/avaircraftsituationlist.h"
|
||||
#include "blackmisc/aviation/aircraftpartslist.h"
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
//! \file
|
||||
|
||||
#ifndef BLACKMISC_TIMESTAMPOBJECTLIST_H
|
||||
#define BLACKMISC_TIMESTAMPOBJECTLIST_H
|
||||
|
||||
#include "blackmisc/collection.h"
|
||||
#include "blackmisc/sequence.h"
|
||||
#include <QList>
|
||||
#include <QMap>
|
||||
|
||||
namespace BlackMisc
|
||||
{
|
||||
template <class OBJ, class CONTAINER>
|
||||
ITimestampObjectList<OBJ, CONTAINER>::ITimestampObjectList()
|
||||
{ }
|
||||
|
||||
template <class OBJ, class CONTAINER>
|
||||
CONTAINER ITimestampObjectList<OBJ, CONTAINER>::findBefore(qint64 msSinceEpoch) const
|
||||
//! List of objects with timestamp.
|
||||
//! Such objects should implement \sa ITimestampBased
|
||||
template<class OBJ, class CONTAINER>
|
||||
class ITimestampObjectList
|
||||
{
|
||||
return this->container().findBy([&](const OBJ & obj)
|
||||
{
|
||||
return obj.isOlderThan(msSinceEpoch);
|
||||
});
|
||||
}
|
||||
public:
|
||||
|
||||
template <class OBJ, class CONTAINER>
|
||||
CONTAINER ITimestampObjectList<OBJ, CONTAINER>::findBeforeNowMinusOffset(qint64 msOffset) const
|
||||
{
|
||||
return this->findBefore(QDateTime::currentMSecsSinceEpoch() - msOffset);
|
||||
}
|
||||
//! List of objects before dateTime
|
||||
CONTAINER findBefore(const QDateTime &dateTime) const;
|
||||
|
||||
template <class OBJ, class CONTAINER>
|
||||
CONTAINER ITimestampObjectList<OBJ, CONTAINER>::findBefore(const QDateTime &dateTime) const
|
||||
{
|
||||
return this->findBefore(dateTime.toMSecsSinceEpoch());
|
||||
}
|
||||
//! List of objects before msSinceEpoch
|
||||
CONTAINER findBefore(qint64 msSinceEpoch) const;
|
||||
|
||||
template <class OBJ, class CONTAINER>
|
||||
CONTAINER ITimestampObjectList<OBJ, CONTAINER>::findAfter(qint64 msSinceEpoc) const
|
||||
{
|
||||
return this->container().findBy([&](const OBJ & obj)
|
||||
{
|
||||
return obj.isNewerThan(msSinceEpoc);
|
||||
});
|
||||
}
|
||||
//! List of objects before now - offset
|
||||
CONTAINER findBeforeNowMinusOffset(qint64 msOffset) const;
|
||||
|
||||
template <class OBJ, class CONTAINER>
|
||||
QList<CONTAINER> ITimestampObjectList<OBJ, CONTAINER>::splitByTime(qint64 msSinceEpoch) const
|
||||
{
|
||||
CONTAINER newer(this->container());
|
||||
newer.sortLatestFirst();
|
||||
CONTAINER older;
|
||||
for (auto it = newer.begin(); it != newer.end(); ++it)
|
||||
{
|
||||
if (it->isOlderThan(msSinceEpoch))
|
||||
{
|
||||
// better "move", ?? std::make_move_iterator
|
||||
older.insert(CRange<CONTAINER::iterator>(it, newer.end()));
|
||||
newer.erase(it, newer.end());
|
||||
break;
|
||||
}
|
||||
}
|
||||
//! List of objects after dateTime
|
||||
CONTAINER findAfter(const QDateTime &dateTime) const;
|
||||
|
||||
// before / after
|
||||
return QList<CONTAINER>({newer, older});
|
||||
}
|
||||
//! List of objects after msSinceEpoch
|
||||
CONTAINER findAfter(qint64 msSinceEpoch) const;
|
||||
|
||||
template <class OBJ, class CONTAINER>
|
||||
OBJ ITimestampObjectList<OBJ, CONTAINER>::latestValue() const
|
||||
{
|
||||
if (this->container().isEmpty()) { return OBJ(); }
|
||||
CONTAINER container(container()); // copy
|
||||
container.sortLatestFirst();
|
||||
return container.front();
|
||||
}
|
||||
//! Split into 2 containers, [0] >= msSinceEpoch ("newer") [b] < msSinceEpoch ("older")
|
||||
//! \note Sort order: latest elements first
|
||||
QList<CONTAINER> splitByTime(qint64 msSinceEpoch) const;
|
||||
|
||||
template <class OBJ, class CONTAINER>
|
||||
OBJ ITimestampObjectList<OBJ, CONTAINER>::oldestValue() const
|
||||
{
|
||||
if (this->container().isEmpty()) { return OBJ(); }
|
||||
CONTAINER container(container()); // copy
|
||||
container.sortLatestFirst();
|
||||
return container.back();
|
||||
}
|
||||
//! Latest value
|
||||
OBJ latestValue() const;
|
||||
|
||||
template <class OBJ, class CONTAINER>
|
||||
CONTAINER ITimestampObjectList<OBJ, CONTAINER>::findAfter(const QDateTime &dateTime) const
|
||||
{
|
||||
return this->findAfter(dateTime.toMSecsSinceEpoch());
|
||||
}
|
||||
//! Latest value
|
||||
OBJ oldestValue() const;
|
||||
|
||||
template <class OBJ, class CONTAINER>
|
||||
void ITimestampObjectList<OBJ, CONTAINER>::removeBefore(const QDateTime &dateTime)
|
||||
{
|
||||
this->removeBefore(dateTime.toMSecsSinceEpoch());
|
||||
}
|
||||
//! Remove objects with timestamp before dateTime
|
||||
void removeBefore(const QDateTime &dateTime);
|
||||
|
||||
template <class OBJ, class CONTAINER>
|
||||
void ITimestampObjectList<OBJ, CONTAINER>::removeBefore(qint64 msSinceEpoc)
|
||||
{
|
||||
this->container().removeIf([&](const OBJ & obj)
|
||||
{
|
||||
return obj.isOlderThan(msSinceEpoc);
|
||||
});
|
||||
}
|
||||
//! Remove objects with timestamp before dateTime
|
||||
void removeBefore(qint64 msSinceEpoch);
|
||||
|
||||
template <class OBJ, class CONTAINER>
|
||||
void ITimestampObjectList<OBJ, CONTAINER>::removeOlderThanNowMinusOffset(int offsetMs)
|
||||
{
|
||||
const qint64 epoch = QDateTime::currentMSecsSinceEpoch() - offsetMs;
|
||||
this->container().removeIf([&](const OBJ & obj)
|
||||
{
|
||||
return obj.isOlderThan(epoch);
|
||||
});
|
||||
}
|
||||
//! Remove objects older than seconds
|
||||
void removeOlderThanNowMinusOffset(int offsetMs);
|
||||
|
||||
template <class OBJ, class CONTAINER>
|
||||
void ITimestampObjectList<OBJ, CONTAINER>::sortLatestFirst()
|
||||
{
|
||||
this->container().sortOldestFirst();
|
||||
std::reverse(this->container().begin(), this->container().end());
|
||||
}
|
||||
//! Sort by timestamp
|
||||
void sortLatestFirst();
|
||||
|
||||
template <class OBJ, class CONTAINER>
|
||||
void ITimestampObjectList<OBJ, CONTAINER>::sortOldestFirst()
|
||||
{
|
||||
this->container().sort(BlackMisc::Predicates::MemberLess(&OBJ::getMSecsSinceEpoch));
|
||||
}
|
||||
//! Sort by timestamp
|
||||
void sortOldestFirst();
|
||||
|
||||
template <class OBJ, class CONTAINER>
|
||||
void ITimestampObjectList<OBJ, CONTAINER>::insertTimestampObject(const OBJ &object, int maxElements)
|
||||
{
|
||||
Q_ASSERT(maxElements > 1);
|
||||
if (this->container().size() >= (maxElements - 1))
|
||||
{
|
||||
this->container().truncate(maxElements - 1);
|
||||
}
|
||||
this->container().insert_front(object);
|
||||
}
|
||||
//! Inserts as first object by keeping max. elements
|
||||
void insertTimestampObject(const OBJ &object, int maxElements);
|
||||
|
||||
// see here for the reason of thess forward instantiations
|
||||
// http://www.parashift.com/c++-faq/separate-template-class-defn-from-decl.html
|
||||
template class ITimestampObjectList<BlackMisc::Aviation::CAircraftSituation, BlackMisc::Aviation::CAircraftSituationList>;
|
||||
template class ITimestampObjectList<BlackMisc::Aviation::CAircraftParts, BlackMisc::Aviation::CAircraftPartsList>;
|
||||
protected:
|
||||
//! Constructor
|
||||
ITimestampObjectList();
|
||||
|
||||
} // namespace
|
||||
//! Container
|
||||
virtual const CONTAINER &container() const = 0;
|
||||
|
||||
//! Container
|
||||
virtual CONTAINER &container() = 0;
|
||||
};
|
||||
|
||||
} //namespace
|
||||
|
||||
#endif //guard
|
||||
|
||||
@@ -29,10 +29,11 @@ namespace BlackSimPlugin
|
||||
namespace Fs9
|
||||
{
|
||||
CFs9Client::CFs9Client(
|
||||
IRenderedAircraftProviderReadOnly *renderedAircraftProvider, QObject *owner, const QString &callsign, const CTime &updateInterval) :
|
||||
BlackCore::IInterpolator *interpolator, QObject *owner, const QString &callsign, const CTime &updateInterval) :
|
||||
CDirectPlayPeer(owner, callsign),
|
||||
m_renderedAircraftProvider(renderedAircraftProvider), m_updateInterval(updateInterval)
|
||||
{ }
|
||||
m_interpolator(interpolator), m_updateInterval(updateInterval)
|
||||
{
|
||||
}
|
||||
|
||||
CFs9Client::~CFs9Client()
|
||||
{
|
||||
@@ -75,14 +76,14 @@ namespace BlackSimPlugin
|
||||
void CFs9Client::timerEvent(QTimerEvent *event)
|
||||
{
|
||||
Q_UNUSED(event);
|
||||
Q_ASSERT(m_interpolator);
|
||||
|
||||
if (m_clientStatus == Disconnected) { return; }
|
||||
|
||||
|
||||
QMutexLocker locker(&m_mutexInterpolator);
|
||||
CInterpolatorLinear interpolator(m_renderedAircraftProvider);
|
||||
if (!interpolator.hasEnoughAircraftSituations(this->m_callsign)) { return; }
|
||||
|
||||
CAircraftSituation situation = interpolator.getCurrentInterpolatedSituation(m_callsign);
|
||||
bool ok;
|
||||
CAircraftSituation situation = this->m_interpolator->getCurrentInterpolatedSituation(this->m_interpolator->getSituationsByCallsign(), m_callsign, &ok);
|
||||
if (!ok) { return; }
|
||||
MPPositionSlewMode positionSlewMode = aircraftSituationToFS9(situation);
|
||||
|
||||
QByteArray positionMessage;
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
#define DIRECTPLAY_CLIENT_H
|
||||
|
||||
#include "directplay_peer.h"
|
||||
#include "blackcore/interpolator_linear.h"
|
||||
#include "blackcore/interpolator.h"
|
||||
#include "blackmisc/avaircraftsituation.h"
|
||||
#include "blackmisc/pqtime.h"
|
||||
#include <QMutex>
|
||||
@@ -38,7 +38,7 @@ namespace BlackSimPlugin
|
||||
};
|
||||
|
||||
//! Constructor
|
||||
CFs9Client(BlackMisc::Simulation::IRenderedAircraftProviderReadOnly *renderedAircraftProvider, QObject *owner, const QString &callsign, const BlackMisc::PhysicalQuantities::CTime &updateInterval);
|
||||
CFs9Client(BlackCore::IInterpolator *interpolator, QObject *owner, const QString &callsign, const BlackMisc::PhysicalQuantities::CTime &updateInterval);
|
||||
|
||||
//! Destructor
|
||||
virtual ~CFs9Client();
|
||||
@@ -85,10 +85,9 @@ namespace BlackSimPlugin
|
||||
|
||||
BlackMisc::Aviation::CAircraftSituation m_lastAircraftSituation;
|
||||
BlackMisc::PhysicalQuantities::CTime m_updateInterval;
|
||||
BlackCore::IInterpolator *m_interpolator = nullptr;
|
||||
int m_timerId = 0;
|
||||
|
||||
QMutex m_mutexInterpolator;
|
||||
BlackMisc::Simulation::IRenderedAircraftProviderReadOnly *m_renderedAircraftProvider = nullptr;
|
||||
IDirectPlay8Address *m_hostAddress = nullptr;
|
||||
ClientStatus m_clientStatus = Disconnected;
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "fs9_client.h"
|
||||
#include "multiplayer_packets.h"
|
||||
#include "multiplayer_packet_parser.h"
|
||||
#include "blackcore/interpolator_linear.h"
|
||||
#include "blacksim/simulatorinfo.h"
|
||||
#include "blackmisc/project.h"
|
||||
#include "blackmisc/logmessage.h"
|
||||
@@ -38,11 +39,11 @@ namespace BlackSimPlugin
|
||||
{
|
||||
BlackCore::ISimulator *CSimulatorFs9Factory::create(
|
||||
IOwnAircraftProvider *ownAircraftProvider,
|
||||
IRenderedAircraftProvider *renderedAircraftProvider,
|
||||
IRemoteAircraftProvider *remoteAircraftProvider,
|
||||
QObject *parent)
|
||||
{
|
||||
registerMetadata();
|
||||
return new Fs9::CSimulatorFs9(ownAircraftProvider, renderedAircraftProvider, parent);
|
||||
return new Fs9::CSimulatorFs9(ownAircraftProvider, remoteAircraftProvider, parent);
|
||||
}
|
||||
|
||||
BlackSim::CSimulatorInfo CSimulatorFs9Factory::getSimulatorInfo() const
|
||||
@@ -50,13 +51,15 @@ namespace BlackSimPlugin
|
||||
return CSimulatorInfo::FS9();
|
||||
}
|
||||
|
||||
CSimulatorFs9::CSimulatorFs9(IOwnAircraftProvider *ownAircraftProvider, IRenderedAircraftProvider *renderedAircraftProvider, QObject *parent) :
|
||||
CSimulatorFsCommon(CSimulatorInfo::FS9(), ownAircraftProvider, renderedAircraftProvider, parent),
|
||||
CSimulatorFs9::CSimulatorFs9(IOwnAircraftProvider *ownAircraftProvider, IRemoteAircraftProvider *remoteAircraftProvider, QObject *parent) :
|
||||
CSimulatorFsCommon(CSimulatorInfo::FS9(), ownAircraftProvider, remoteAircraftProvider, parent),
|
||||
m_fs9Host(new CFs9Host(this)), m_lobbyClient(new CLobbyClient(this))
|
||||
{
|
||||
connect(m_fs9Host.data(), &CFs9Host::customPacketReceived, this, &CSimulatorFs9::ps_processFs9Message);
|
||||
connect(m_fs9Host.data(), &CFs9Host::statusChanged, this, &CSimulatorFs9::ps_changeHostStatus);
|
||||
m_fs9Host->start();
|
||||
this->m_interpolator = new BlackCore::CInterpolatorLinear(remoteAircraftProvider, this);
|
||||
this->m_interpolator->start();
|
||||
}
|
||||
|
||||
CSimulatorFs9::~CSimulatorFs9()
|
||||
@@ -104,22 +107,22 @@ namespace BlackSimPlugin
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CSimulatorFs9::addRemoteAircraft(const CSimulatedAircraft &remoteAircraft)
|
||||
bool CSimulatorFs9::addRemoteAircraft(const CSimulatedAircraft &newRemoteAircraft)
|
||||
{
|
||||
CCallsign callsign = remoteAircraft.getCallsign();
|
||||
CCallsign callsign = newRemoteAircraft.getCallsign();
|
||||
if (m_hashFs9Clients.contains(callsign))
|
||||
{
|
||||
// already exists, remove first
|
||||
this->removeRenderedAircraft(callsign);
|
||||
}
|
||||
|
||||
CFs9Client *client = new CFs9Client(this->m_renderedAircraftProvider, this, callsign.toQString(), CTime(25, CTimeUnit::ms()));
|
||||
CFs9Client *client = new CFs9Client(m_interpolator, this, callsign.toQString(), CTime(25, CTimeUnit::ms()));
|
||||
client->setHostAddress(m_fs9Host->getHostAddress());
|
||||
client->setPlayerUserId(m_fs9Host->getPlayerUserId());
|
||||
|
||||
client->start();
|
||||
m_hashFs9Clients.insert(callsign, client);
|
||||
renderedAircraft().applyIfCallsign(callsign, CPropertyIndexVariantMap(CSimulatedAircraft::IndexRendered, CVariant::fromValue(true)));
|
||||
remoteAircraft().applyIfCallsign(callsign, CPropertyIndexVariantMap(CSimulatedAircraft::IndexRendered, CVariant::fromValue(true)));
|
||||
CLogMessage(this).info("FS9: Added aircraft %1") << callsign.toQString();
|
||||
return true;
|
||||
}
|
||||
@@ -131,7 +134,7 @@ namespace BlackSimPlugin
|
||||
auto fs9Client = m_hashFs9Clients.value(callsign);
|
||||
fs9Client->quit();
|
||||
m_hashFs9Clients.remove(callsign);
|
||||
renderedAircraft().applyIfCallsign(callsign, CPropertyIndexVariantMap(CSimulatedAircraft::IndexRendered, CVariant::fromValue(false)));
|
||||
remoteAircraft().applyIfCallsign(callsign, CPropertyIndexVariantMap(CSimulatedAircraft::IndexRendered, CVariant::fromValue(false)));
|
||||
CLogMessage(this).info("FS9: Removed aircraft %1") << callsign.toQString();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
#include "lobby_client.h"
|
||||
#include "../fscommon/simulator_fscommon.h"
|
||||
#include "blackcore/simulator.h"
|
||||
#include "blackcore/interpolator_linear.h"
|
||||
#include "blackcore/interpolator.h"
|
||||
#include "blackmisc/simulation/aircraftmodel.h"
|
||||
#include "blackmisc/avaircraft.h"
|
||||
#include "blacksim/simulatorinfo.h"
|
||||
@@ -43,7 +43,7 @@ namespace BlackSimPlugin
|
||||
//! \copydoc BlackCore::ISimulatorFactory::create()
|
||||
virtual BlackCore::ISimulator *create(
|
||||
BlackMisc::Simulation::IOwnAircraftProvider *ownAircraftProvider,
|
||||
BlackMisc::Simulation::IRenderedAircraftProvider *renderedAircraftProvider,
|
||||
BlackMisc::Simulation::IRemoteAircraftProvider *remoteAircraftProvider,
|
||||
QObject *parent) override;
|
||||
|
||||
//! Simulator info
|
||||
@@ -59,7 +59,7 @@ namespace BlackSimPlugin
|
||||
//! Constructor, parameters as in \sa BlackCore::ISimulatorFactory::create
|
||||
CSimulatorFs9(
|
||||
BlackMisc::Simulation::IOwnAircraftProvider *ownAircraftProvider,
|
||||
BlackMisc::Simulation::IRenderedAircraftProvider *renderedAircraft,
|
||||
BlackMisc::Simulation::IRemoteAircraftProvider *remoteAircraftProvider,
|
||||
QObject *parent = nullptr);
|
||||
|
||||
//! Destructor
|
||||
@@ -86,7 +86,7 @@ namespace BlackSimPlugin
|
||||
virtual bool disconnectFrom() override;
|
||||
|
||||
//! \copydoc ISimulator::addRemoteAircraft()
|
||||
virtual bool addRemoteAircraft(const BlackMisc::Simulation::CSimulatedAircraft &remoteAircraft) override;
|
||||
virtual bool addRemoteAircraft(const BlackMisc::Simulation::CSimulatedAircraft &newRemoteAircraft) override;
|
||||
|
||||
//! \copydoc ISimulator::removeRemoteAircraft()
|
||||
virtual bool removeRenderedAircraft(const BlackMisc::Aviation::CCallsign &callsign) override;
|
||||
@@ -128,6 +128,8 @@ namespace BlackSimPlugin
|
||||
bool m_startedLobbyConnection = false;
|
||||
QHash<BlackMisc::Aviation::CCallsign, QPointer<CFs9Client>> m_hashFs9Clients;
|
||||
CLobbyClient *m_lobbyClient;
|
||||
|
||||
BlackCore::IInterpolator *m_interpolator = nullptr; //!< interpolator instance
|
||||
};
|
||||
} // namespace
|
||||
} // namespace
|
||||
|
||||
@@ -26,7 +26,7 @@ namespace BlackSimPlugin
|
||||
{
|
||||
namespace FsCommon
|
||||
{
|
||||
CSimulatorFsCommon::CSimulatorFsCommon(const BlackSim::CSimulatorInfo &simInfo, BlackMisc::Simulation::IOwnAircraftProvider *ownAircraftProvider, IRenderedAircraftProvider *renderedAircraftProvider, QObject *parent) :
|
||||
CSimulatorFsCommon::CSimulatorFsCommon(const BlackSim::CSimulatorInfo &simInfo, BlackMisc::Simulation::IOwnAircraftProvider *ownAircraftProvider, IRemoteAircraftProvider *renderedAircraftProvider, QObject *parent) :
|
||||
CSimulatorCommon(simInfo, ownAircraftProvider, renderedAircraftProvider, parent),
|
||||
m_fsuipc(new FsCommon::CFsuipc())
|
||||
{
|
||||
|
||||
@@ -84,7 +84,7 @@ namespace BlackSimPlugin
|
||||
CSimulatorFsCommon(
|
||||
const BlackSim::CSimulatorInfo &simInfo,
|
||||
BlackMisc::Simulation::IOwnAircraftProvider *ownAircraftProvider,
|
||||
BlackMisc::Simulation::IRenderedAircraftProvider *renderedAircraftProvider,
|
||||
BlackMisc::Simulation::IRemoteAircraftProvider *renderedAircraftProvider,
|
||||
QObject *parent = nullptr);
|
||||
|
||||
QString simulatorDetails; //!< describes version etc.
|
||||
|
||||
@@ -34,19 +34,22 @@ using namespace BlackMisc::Simulation;
|
||||
using namespace BlackSim;
|
||||
using namespace BlackSim::FsCommon;
|
||||
using namespace BlackSim::Fsx;
|
||||
using namespace BlackCore;
|
||||
|
||||
namespace BlackSimPlugin
|
||||
{
|
||||
namespace Fsx
|
||||
{
|
||||
CSimulatorFsx::CSimulatorFsx(IOwnAircraftProvider *ownAircraftProvider, IRenderedAircraftProvider *renderedAircraftProvider, QObject *parent) :
|
||||
CSimulatorFsCommon(CSimulatorInfo::FSX(), ownAircraftProvider, renderedAircraftProvider, parent)
|
||||
CSimulatorFsx::CSimulatorFsx(IOwnAircraftProvider *ownAircraftProvider, IRemoteAircraftProvider *remoteAircraftProvider, QObject *parent) :
|
||||
CSimulatorFsCommon(CSimulatorInfo::FSX(), ownAircraftProvider, remoteAircraftProvider, parent)
|
||||
{
|
||||
Q_ASSERT(ownAircraftProvider);
|
||||
Q_ASSERT(renderedAircraftProvider);
|
||||
Q_ASSERT(remoteAircraftProvider);
|
||||
CFsxSimulatorSetup setup;
|
||||
setup.init(); // this fetches important settings on local side
|
||||
m_useFsuipc = false; // do not use FSUIPC at the moment with FSX
|
||||
this->m_interpolator = new CInterpolatorLinear(remoteAircraftProvider, this);
|
||||
this->m_interpolator->start();
|
||||
this->m_simulatorInfo.setSimulatorSetup(setup.getSettings());
|
||||
}
|
||||
|
||||
@@ -136,9 +139,9 @@ namespace BlackSimPlugin
|
||||
return connect;
|
||||
}
|
||||
|
||||
bool CSimulatorFsx::addRemoteAircraft(const Simulation::CSimulatedAircraft &remoteAircraft)
|
||||
bool CSimulatorFsx::addRemoteAircraft(const Simulation::CSimulatedAircraft &newRemoteAircraft)
|
||||
{
|
||||
CCallsign callsign = remoteAircraft.getCallsign();
|
||||
CCallsign callsign = newRemoteAircraft.getCallsign();
|
||||
Q_ASSERT(!callsign.isEmpty());
|
||||
if (callsign.isEmpty()) { return false; }
|
||||
|
||||
@@ -150,7 +153,7 @@ namespace BlackSimPlugin
|
||||
Q_ASSERT(false);
|
||||
}
|
||||
|
||||
SIMCONNECT_DATA_INITPOSITION initialPosition = aircraftSituationToFsxInitPosition(remoteAircraft.getSituation());
|
||||
SIMCONNECT_DATA_INITPOSITION initialPosition = aircraftSituationToFsxInitPosition(newRemoteAircraft.getSituation());
|
||||
initialPosition.Airspeed = 0;
|
||||
initialPosition.OnGround = 0;
|
||||
|
||||
@@ -161,10 +164,10 @@ namespace BlackSimPlugin
|
||||
++m_nextObjID;
|
||||
|
||||
// matched models
|
||||
CAircraftModel aircraftModel = modelMatching(remoteAircraft);
|
||||
Q_ASSERT(remoteAircraft.getCallsign() == aircraftModel.getCallsign());
|
||||
providerUpdateAircraftModel(remoteAircraft.getCallsign(), aircraftModel, simulatorOriginator());
|
||||
CSimulatedAircraft aircraftAfterModelApplied = renderedAircraft().findFirstByCallsign(remoteAircraft.getCallsign());
|
||||
CAircraftModel aircraftModel = modelMatching(newRemoteAircraft);
|
||||
Q_ASSERT(newRemoteAircraft.getCallsign() == aircraftModel.getCallsign());
|
||||
providerUpdateAircraftModel(newRemoteAircraft.getCallsign(), aircraftModel, simulatorOriginator());
|
||||
CSimulatedAircraft aircraftAfterModelApplied = remoteAircraft().findFirstByCallsign(newRemoteAircraft.getCallsign());
|
||||
emit modelMatchingCompleted(aircraftAfterModelApplied);
|
||||
|
||||
// create AI
|
||||
@@ -175,13 +178,13 @@ namespace BlackSimPlugin
|
||||
HRESULT hr = SimConnect_AICreateNonATCAircraft(m_hSimConnect, m.constData(), qPrintable(callsign.toQString().left(12)), initialPosition, simObj.getRequestId());
|
||||
if (hr != S_OK) { CLogMessage(this).error("SimConnect, can not create AI traffic"); }
|
||||
m_simConnectObjects.insert(callsign, simObj);
|
||||
renderedAircraft().applyIfCallsign(callsign, CPropertyIndexVariantMap(CSimulatedAircraft::IndexRendered, CVariant::fromValue(true)));
|
||||
remoteAircraft().applyIfCallsign(callsign, CPropertyIndexVariantMap(CSimulatedAircraft::IndexRendered, CVariant::fromValue(true)));
|
||||
CLogMessage(this).info("FSX: Added aircraft %1") << callsign.toQString();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
renderedAircraft().applyIfCallsign(callsign, CPropertyIndexVariantMap(CSimulatedAircraft::IndexRendered, CVariant::fromValue(false)));
|
||||
remoteAircraft().applyIfCallsign(callsign, CPropertyIndexVariantMap(CSimulatedAircraft::IndexRendered, CVariant::fromValue(false)));
|
||||
CLogMessage(this).warning("FSX: Not connected, not added aircraft %1") << callsign.toQString();
|
||||
return false;
|
||||
}
|
||||
@@ -512,7 +515,7 @@ namespace BlackSimPlugin
|
||||
{
|
||||
SimConnect_AIRemoveObject(m_hSimConnect, simObject.getObjectId(), simObject.getRequestId());
|
||||
m_simConnectObjects.remove(simObject.getCallsign());
|
||||
renderedAircraft().applyIfCallsign(simObject.getCallsign(), CPropertyIndexVariantMap(CSimulatedAircraft::IndexRendered, CVariant::fromValue(false)));
|
||||
remoteAircraft().applyIfCallsign(simObject.getCallsign(), CPropertyIndexVariantMap(CSimulatedAircraft::IndexRendered, CVariant::fromValue(false)));
|
||||
CLogMessage(this).info("FSX: Removed aircraft %1") << simObject.getCallsign().toQString();
|
||||
return true;
|
||||
}
|
||||
@@ -594,50 +597,69 @@ namespace BlackSimPlugin
|
||||
void CSimulatorFsx::updateOtherAircraft()
|
||||
{
|
||||
static_assert(sizeof(DataDefinitionRemoteAircraft) == 176, "DataDefinitionRemoteAircraft has an incorrect size.");
|
||||
BlackCore::CInterpolatorLinear interpolator(this->m_renderedAircraftProvider);
|
||||
for (const CSimConnectObject &simObj : m_simConnectObjects)
|
||||
Q_ASSERT(this->m_interpolator);
|
||||
Q_ASSERT_X(this->m_interpolator->thread() != this->thread(), "updateOtherAircraft", "interpolator should run in its own thread");
|
||||
|
||||
bool lastRequestAvailable;
|
||||
CAircraftSituationList interpolations = m_interpolator->getRequest(m_interpolationRequest, &lastRequestAvailable);
|
||||
if (!lastRequestAvailable)
|
||||
{
|
||||
if (!interpolator.hasEnoughAircraftSituations(simObj.getCallsign())) { continue; }
|
||||
m_interpolationsSkipped++;
|
||||
return;
|
||||
}
|
||||
|
||||
SIMCONNECT_DATA_INITPOSITION position = aircraftSituationToFsxInitPosition(interpolator.getCurrentInterpolatedSituation(simObj.getCallsign()));
|
||||
// non blocking calculations in background
|
||||
m_interpolator->requestSituationsCalculationsForAllCallsigns(m_interpolationsSkipped);
|
||||
|
||||
CAircraftParts parts;
|
||||
if (renderedAircraftParts().findBeforeNowMinusOffset(6000).containsCallsign(simObj.getCallsign()))
|
||||
parts = renderedAircraftParts().findBeforeNowMinusOffset(6000).latestValue();
|
||||
|
||||
position.OnGround = parts.isOnGround() ? 1 : 0;
|
||||
// now send to sim
|
||||
for (const CAircraftSituation ¤tSituation : interpolations)
|
||||
{
|
||||
bool hasParts;
|
||||
const CCallsign callsign(currentSituation.getCallsign());
|
||||
const CSimConnectObject &simObj = m_simConnectObjects[callsign];
|
||||
SIMCONNECT_DATA_INITPOSITION position = aircraftSituationToFsxInitPosition(currentSituation);
|
||||
CAircraftParts parts = m_interpolator->getLatestPartsBeforeOffset(callsign, IInterpolator::TimeOffsetMs, &hasParts);
|
||||
|
||||
DataDefinitionRemoteAircraft ddRemoteAircraft;
|
||||
ddRemoteAircraft.position = position;
|
||||
ddRemoteAircraft.lightStrobe = parts.getLights().isStrobeOn() ? 1.0 : 0.0;
|
||||
ddRemoteAircraft.lightLanding = parts.getLights().isLandingOn() ? 1.0 : 0.0;
|
||||
// ddRemoteAircraft.lightTaxi = parts.getLights().isTaxiOn() ? 1.0 : 0.0;
|
||||
ddRemoteAircraft.lightBeacon = parts.getLights().isBeaconOn() ? 1.0 : 0.0;
|
||||
ddRemoteAircraft.lightNav = parts.getLights().isNavOn() ? 1.0 : 0.0;
|
||||
ddRemoteAircraft.lightLogo = parts.getLights().isLogoOn() ? 1.0 : 0.0;
|
||||
ddRemoteAircraft.flapsLeadingEdgeLeftPercent = parts.getFlapsPercent() / 100.0;
|
||||
ddRemoteAircraft.flapsLeadingEdgeRightPercent = parts.getFlapsPercent() / 100.0;
|
||||
ddRemoteAircraft.flapsTrailingEdgeLeftPercent = parts.getFlapsPercent() / 100.0;
|
||||
ddRemoteAircraft.flapsTrailingEdgeRightPercent = parts.getFlapsPercent() / 100.0;
|
||||
ddRemoteAircraft.spoilersHandlePosition = parts.isSpoilersOut() ? 1.0 : 0.0;
|
||||
ddRemoteAircraft.gearHandlePosition = parts.isGearDown() ? 1 : 0;
|
||||
ddRemoteAircraft.engine1Combustion = parts.getEngines().findBy(&CAircraftEngine::getNumber, 1).frontOrDefault().isOn() ? 1 : 0;
|
||||
ddRemoteAircraft.engine2Combustion = parts.getEngines().findBy(&CAircraftEngine::getNumber, 2).frontOrDefault().isOn() ? 1 : 0;
|
||||
ddRemoteAircraft.engine3Combustion = parts.getEngines().findBy(&CAircraftEngine::getNumber, 3).frontOrDefault().isOn() ? 1 : 0;
|
||||
ddRemoteAircraft.engine4Combustion = parts.getEngines().findBy(&CAircraftEngine::getNumber, 4).frontOrDefault().isOn() ? 1 : 0;
|
||||
if (hasParts)
|
||||
{
|
||||
// we have parts
|
||||
position.OnGround = parts.isOnGround() ? 1 : 0;
|
||||
|
||||
ddRemoteAircraft.position = position;
|
||||
ddRemoteAircraft.lightStrobe = parts.getLights().isStrobeOn() ? 1.0 : 0.0;
|
||||
ddRemoteAircraft.lightLanding = parts.getLights().isLandingOn() ? 1.0 : 0.0;
|
||||
// ddRemoteAircraft.lightTaxi = parts.getLights().isTaxiOn() ? 1.0 : 0.0;
|
||||
ddRemoteAircraft.lightBeacon = parts.getLights().isBeaconOn() ? 1.0 : 0.0;
|
||||
ddRemoteAircraft.lightNav = parts.getLights().isNavOn() ? 1.0 : 0.0;
|
||||
ddRemoteAircraft.lightLogo = parts.getLights().isLogoOn() ? 1.0 : 0.0;
|
||||
ddRemoteAircraft.flapsLeadingEdgeLeftPercent = parts.getFlapsPercent() / 100.0;
|
||||
ddRemoteAircraft.flapsLeadingEdgeRightPercent = parts.getFlapsPercent() / 100.0;
|
||||
ddRemoteAircraft.flapsTrailingEdgeLeftPercent = parts.getFlapsPercent() / 100.0;
|
||||
ddRemoteAircraft.flapsTrailingEdgeRightPercent = parts.getFlapsPercent() / 100.0;
|
||||
ddRemoteAircraft.spoilersHandlePosition = parts.isSpoilersOut() ? 1.0 : 0.0;
|
||||
ddRemoteAircraft.gearHandlePosition = parts.isGearDown() ? 1 : 0;
|
||||
ddRemoteAircraft.engine1Combustion = parts.getEngines().findBy(&CAircraftEngine::getNumber, 1).frontOrDefault().isOn() ? 1 : 0;
|
||||
ddRemoteAircraft.engine2Combustion = parts.getEngines().findBy(&CAircraftEngine::getNumber, 2).frontOrDefault().isOn() ? 1 : 0;
|
||||
ddRemoteAircraft.engine3Combustion = parts.getEngines().findBy(&CAircraftEngine::getNumber, 3).frontOrDefault().isOn() ? 1 : 0;
|
||||
ddRemoteAircraft.engine4Combustion = parts.getEngines().findBy(&CAircraftEngine::getNumber, 4).frontOrDefault().isOn() ? 1 : 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
//! \todo interpolator, set data without parts by educated guessing whatsoever
|
||||
position.OnGround = parts.isOnGround() ? 1 : 0;
|
||||
}
|
||||
|
||||
if (simObj.getObjectId() != 0)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
hr += SimConnect_SetDataOnSimObject(m_hSimConnect, CSimConnectDefinitions::DataRemoteAircraft,
|
||||
simObj.getObjectId(), 0, 0,
|
||||
sizeof(DataDefinitionRemoteAircraft), &ddRemoteAircraft);
|
||||
|
||||
if (hr != S_OK) CLogMessage(this).warning("Failed so set data on SimObject");
|
||||
|
||||
if (hr != S_OK) { CLogMessage(this).warning("Failed so set data on SimObject"); }
|
||||
}
|
||||
}
|
||||
} // ok, no parts
|
||||
}
|
||||
|
||||
SIMCONNECT_DATA_INITPOSITION CSimulatorFsx::aircraftSituationToFsxInitPosition(const CAircraftSituation &situation)
|
||||
|
||||
@@ -74,7 +74,7 @@ namespace BlackSimPlugin
|
||||
//! Constructor, parameters as in \sa BlackCore::ISimulatorFactory::create
|
||||
CSimulatorFsx(
|
||||
BlackMisc::Simulation::IOwnAircraftProvider *ownAircraftProvider,
|
||||
BlackMisc::Simulation::IRenderedAircraftProvider *renderedAircraftProvider,
|
||||
BlackMisc::Simulation::IRemoteAircraftProvider *remoteAircraftProvider,
|
||||
QObject *parent = nullptr);
|
||||
|
||||
//! Destructor
|
||||
@@ -104,7 +104,7 @@ namespace BlackSimPlugin
|
||||
virtual bool disconnectFrom() override;
|
||||
|
||||
//! \copydoc ISimulator::addRemoteAircraft()
|
||||
virtual bool addRemoteAircraft(const BlackMisc::Simulation::CSimulatedAircraft &remoteAircraft) override;
|
||||
virtual bool addRemoteAircraft(const BlackMisc::Simulation::CSimulatedAircraft &newRemoteAircraft) override;
|
||||
|
||||
//! \copydoc ISimulator::removeRenderedAircraft()
|
||||
virtual bool removeRenderedAircraft(const BlackMisc::Aviation::CCallsign &callsign) override;
|
||||
@@ -181,9 +181,12 @@ namespace BlackSimPlugin
|
||||
int m_syncDeferredCounter = 0; //!< Set when synchronized, used to wait some time
|
||||
int m_simconnectTimerId = -1; //!< Timer identifier
|
||||
int m_skipCockpitUpdateCycles = 0; //!< Skip some update cycles to allow changes in simulator cockpit to be set
|
||||
int m_interpolationRequest = 0; //!< current interpolation request
|
||||
int m_interpolationsSkipped = 0; //!< number of skipped interpolation request
|
||||
HANDLE m_hSimConnect = nullptr; //!< Handle to SimConnect object
|
||||
uint m_nextObjID = 1; //!< object ID TODO: also used as request id, where to we place other request ids as for facilities
|
||||
BlackMisc::PhysicalQuantities::CTime m_syncTimeOffset; //!< Time offset (if synchronized)
|
||||
BlackCore::IInterpolator *m_interpolator = nullptr; //!< interpolator instance
|
||||
QHash<BlackMisc::Aviation::CCallsign, CSimConnectObject> m_simConnectObjects;
|
||||
QFutureWatcher<bool> m_watcherConnect;
|
||||
};
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace BlackSimPlugin
|
||||
{
|
||||
namespace Fsx
|
||||
{
|
||||
BlackCore::ISimulator *CSimulatorFsxFactory::create(BlackMisc::Simulation::IOwnAircraftProvider *ownAircraftProvider, BlackMisc::Simulation::IRenderedAircraftProvider *renderedAircraftProvider, QObject *parent)
|
||||
BlackCore::ISimulator *CSimulatorFsxFactory::create(BlackMisc::Simulation::IOwnAircraftProvider *ownAircraftProvider, BlackMisc::Simulation::IRemoteAircraftProvider *renderedAircraftProvider, QObject *parent)
|
||||
{
|
||||
Q_ASSERT(ownAircraftProvider);
|
||||
return new CSimulatorFsx(ownAircraftProvider, renderedAircraftProvider, parent);
|
||||
|
||||
@@ -35,7 +35,7 @@ namespace BlackSimPlugin
|
||||
//! \copydoc BlackCore::ISimulatorFactory::create
|
||||
virtual BlackCore::ISimulator *create(
|
||||
BlackMisc::Simulation::IOwnAircraftProvider *ownAircraftProvider,
|
||||
BlackMisc::Simulation::IRenderedAircraftProvider *renderedAircraftProvider,
|
||||
BlackMisc::Simulation::IRemoteAircraftProvider *renderedAircraftProvider,
|
||||
QObject *parent) override;
|
||||
|
||||
//! \copydoc BlackCore::ISimulatorFactory::getSimulatorInfo
|
||||
|
||||
@@ -28,8 +28,8 @@ namespace BlackSimPlugin
|
||||
namespace XPlane
|
||||
{
|
||||
|
||||
CSimulatorXPlane::CSimulatorXPlane(IOwnAircraftProvider *ownAircraftProvider, IRenderedAircraftProvider *renderedAircraftProvider, QObject *parent) :
|
||||
CSimulatorCommon(CSimulatorInfo::XP(), ownAircraftProvider, renderedAircraftProvider, parent)
|
||||
CSimulatorXPlane::CSimulatorXPlane(IOwnAircraftProvider *ownAircraftProvider, IRemoteAircraftProvider *remoteAircraftProvider, QObject *parent) :
|
||||
CSimulatorCommon(CSimulatorInfo::XP(), ownAircraftProvider, remoteAircraftProvider, parent)
|
||||
{
|
||||
m_watcher = new QDBusServiceWatcher(this);
|
||||
m_watcher->setWatchMode(QDBusServiceWatcher::WatchForRegistration | QDBusServiceWatcher::WatchForUnregistration);
|
||||
@@ -330,17 +330,17 @@ namespace BlackSimPlugin
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CSimulatorXPlane::addRemoteAircraft(const CSimulatedAircraft &remoteAircraft)
|
||||
bool CSimulatorXPlane::addRemoteAircraft(const CSimulatedAircraft &newRemoteAircraft)
|
||||
{
|
||||
if (!isConnected()) { return false; }
|
||||
//! \todo XPlane driver check if already exists, how?
|
||||
//! \todo XPlane driver set correct return value
|
||||
// KB: from what I can see here all data are available
|
||||
// Is there any model matching required ????
|
||||
CAircraftIcao icao = remoteAircraft.getIcaoInfo();
|
||||
m_traffic->addPlane(remoteAircraft.getCallsign().asString(), icao.getAircraftDesignator(), icao.getAirlineDesignator(), icao.getLivery());
|
||||
renderedAircraft().applyIfCallsign(remoteAircraft.getCallsign(), CPropertyIndexVariantMap(CSimulatedAircraft::IndexRendered, CVariant::fromValue(true)));
|
||||
CLogMessage(this).info("XP: Added aircraft %1") << remoteAircraft.getCallsign().toQString();
|
||||
CAircraftIcao icao = newRemoteAircraft.getIcaoInfo();
|
||||
m_traffic->addPlane(newRemoteAircraft.getCallsign().asString(), icao.getAircraftDesignator(), icao.getAirlineDesignator(), icao.getLivery());
|
||||
remoteAircraft().applyIfCallsign(newRemoteAircraft.getCallsign(), CPropertyIndexVariantMap(CSimulatedAircraft::IndexRendered, CVariant::fromValue(true)));
|
||||
CLogMessage(this).info("XP: Added aircraft %1") << newRemoteAircraft.getCallsign().toQString();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -365,7 +365,7 @@ namespace BlackSimPlugin
|
||||
{
|
||||
if (! isConnected()) { return false; }
|
||||
m_traffic->removePlane(callsign.asString());
|
||||
renderedAircraft().applyIfCallsign(callsign, CPropertyIndexVariantMap(CSimulatedAircraft::IndexRendered, CVariant::fromValue(false)));
|
||||
remoteAircraft().applyIfCallsign(callsign, CPropertyIndexVariantMap(CSimulatedAircraft::IndexRendered, CVariant::fromValue(false)));
|
||||
CLogMessage(this).info("XP: Removed aircraft %1") << callsign.toQString();
|
||||
return true;
|
||||
}
|
||||
@@ -395,7 +395,7 @@ namespace BlackSimPlugin
|
||||
return true;
|
||||
}
|
||||
|
||||
BlackCore::ISimulator *CSimulatorXPlaneFactory::create(IOwnAircraftProvider *ownAircraftProvider, IRenderedAircraftProvider *renderedAircraftProvider, QObject *parent)
|
||||
BlackCore::ISimulator *CSimulatorXPlaneFactory::create(IOwnAircraftProvider *ownAircraftProvider, IRemoteAircraftProvider *renderedAircraftProvider, QObject *parent)
|
||||
{
|
||||
return new CSimulatorXPlane(ownAircraftProvider, renderedAircraftProvider, parent);
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ namespace BlackSimPlugin
|
||||
//! Constructor, parameters as in \sa BlackCore::ISimulatorFactory::create
|
||||
CSimulatorXPlane(
|
||||
BlackMisc::Simulation::IOwnAircraftProvider *ownAircraftProvider,
|
||||
BlackMisc::Simulation::IRenderedAircraftProvider *renderedAircraft,
|
||||
BlackMisc::Simulation::IRemoteAircraftProvider *remoteAircraft,
|
||||
QObject *parent = nullptr);
|
||||
|
||||
//! \copydoc BlackCore::ISimulator::isConnected
|
||||
@@ -69,7 +69,7 @@ namespace BlackSimPlugin
|
||||
virtual bool disconnectFrom() override;
|
||||
|
||||
//! \copydoc ISimulator::addRemoteAircraft()
|
||||
virtual bool addRemoteAircraft(const BlackMisc::Simulation::CSimulatedAircraft &remoteAircraft) override;
|
||||
virtual bool addRemoteAircraft(const BlackMisc::Simulation::CSimulatedAircraft &newRemoteAircraft) override;
|
||||
|
||||
//! \copydoc BlackCore::ISimulator::removeRemoteAircraft
|
||||
virtual bool removeRenderedAircraft(const BlackMisc::Aviation::CCallsign &callsign) override;
|
||||
@@ -172,7 +172,7 @@ namespace BlackSimPlugin
|
||||
//! \copydoc BlackCore::ISimulatorFactory::create()
|
||||
virtual BlackCore::ISimulator *create(
|
||||
BlackMisc::Simulation::IOwnAircraftProvider *ownAircraftProvider,
|
||||
BlackMisc::Simulation::IRenderedAircraftProvider *renderedAircraftProvider,
|
||||
BlackMisc::Simulation::IRemoteAircraftProvider *renderedAircraftProvider,
|
||||
QObject *parent) override;
|
||||
|
||||
//! \copydoc BlackCore::ISimulatorFactory::getSimulatorInfo
|
||||
|
||||
@@ -216,8 +216,9 @@ void SwiftGuiStd::ps_onConnectionTerminated()
|
||||
/*
|
||||
* Connection status changed
|
||||
*/
|
||||
void SwiftGuiStd::ps_onConnectionStatusChanged(uint /** from **/, uint to)
|
||||
void SwiftGuiStd::ps_onConnectionStatusChanged(int from, int to)
|
||||
{
|
||||
Q_UNUSED(from);
|
||||
this->updateGuiStatusInformation();
|
||||
INetwork::ConnectionStatus newStatus = static_cast<INetwork::ConnectionStatus>(to);
|
||||
|
||||
|
||||
@@ -197,10 +197,10 @@ private slots:
|
||||
|
||||
/*!
|
||||
* \brief Connection status changed
|
||||
* \param from old status, as uint so it is compliant with DBus
|
||||
* \param to new status, as uint so it is compliant with DBus
|
||||
* \param from old status, as int so it is compliant with DBus
|
||||
* \param to new status, as int so it is compliant with DBus
|
||||
*/
|
||||
void ps_onConnectionStatusChanged(uint from, uint to);
|
||||
void ps_onConnectionStatusChanged(int from, int to);
|
||||
|
||||
//
|
||||
// GUI related slots
|
||||
|
||||
Reference in New Issue
Block a user