refs #393, allow to highlight a certain aircraft by blinking

* signatures in contexts
* some specialized functions in aircraft list
* context menus in aircraft view
* default "blinking" implementation in driver common base class
This commit is contained in:
Klaus Basan
2015-03-23 19:50:15 +01:00
parent 66da4d7353
commit 70670b74c6
38 changed files with 557 additions and 78 deletions

View File

@@ -85,7 +85,7 @@ namespace BlackSimPlugin
CAircraftSituation situation = this->m_interpolator->getInterpolatedSituation(m_callsign, -1, status);
// Test only for successful interpolation. FS9 requires constant positions
if (!status.interpolationSucceeded) return;
if (!status.interpolationSucceeded) { return; }
sendMultiplayerPosition(situation);
sendMultiplayerParamaters();

View File

@@ -134,11 +134,20 @@ namespace BlackSimPlugin
auto fs9Client = m_hashFs9Clients.value(callsign);
fs9Client->quit();
m_hashFs9Clients.remove(callsign);
remoteAircraft().applyIfCallsign(callsign, CPropertyIndexVariantMap(CSimulatedAircraft::IndexRendered, CVariant::fromValue(false)));
remoteAircraft().setRendered(callsign, false);
CLogMessage(this).info("FS9: Removed aircraft %1") << callsign.toQString();
return true;
}
void CSimulatorFs9::removeAllRemoteAircraft()
{
QList<CCallsign> callsigns(this->m_hashFs9Clients.keys());
for (const CCallsign &cs : callsigns)
{
removeRemoteAircraft(cs);
}
}
bool CSimulatorFs9::updateOwnSimulatorCockpit(const CAircraft &ownAircraft, const QString &originator)
{
if (originator == this->simulatorOriginator()) { return false; }
@@ -204,8 +213,14 @@ namespace BlackSimPlugin
this->displayStatusMessage(message.asStatusMessage(true, true));
}
void CSimulatorFs9::timerEvent(QTimerEvent * /* event */)
bool CSimulatorFs9::isRenderedAircraft(const CCallsign &callsign) const
{
return m_hashFs9Clients.contains(callsign);
}
void CSimulatorFs9::timerEvent(QTimerEvent *event)
{
Q_UNUSED(event);
ps_dispatch();
}

View File

@@ -42,9 +42,9 @@ namespace BlackSimPlugin
public:
//! \copydoc BlackCore::ISimulatorFactory::create(ownAircraftProvider, remoteAircraftProvider, parent)
virtual BlackCore::ISimulator *create(
BlackMisc::Simulation::IOwnAircraftProvider *ownAircraftProvider,
BlackMisc::Simulation::IRemoteAircraftProvider *remoteAircraftProvider,
QObject *parent) override;
BlackMisc::Simulation::IOwnAircraftProvider *ownAircraftProvider,
BlackMisc::Simulation::IRemoteAircraftProvider *remoteAircraftProvider,
QObject *parent) override;
//! Simulator info
virtual BlackSim::CSimulatorInfo getSimulatorInfo() const override;
@@ -91,6 +91,9 @@ namespace BlackSimPlugin
//! \copydoc ISimulator::removeRemoteAircraft()
virtual bool removeRemoteAircraft(const BlackMisc::Aviation::CCallsign &callsign) override;
//! \copydoc BlackCore::ISimulator::removeAllRemoteAircraft
virtual void removeAllRemoteAircraft() override;
//! \copydoc ISimulator::updateOwnSimulatorCockpit()
virtual bool updateOwnSimulatorCockpit(const BlackMisc::Aviation::CAircraft &ownAircraft, const QString &originator) override;
@@ -100,6 +103,9 @@ namespace BlackSimPlugin
//! \copydoc ISimulator::displayTextMessage()
virtual void displayTextMessage(const BlackMisc::Network::CTextMessage &message) const override;
//! \copydoc ISimulator::isRenderedAircraft
virtual bool isRenderedAircraft(const BlackMisc::Aviation::CCallsign &callsign) const override;
protected:
//! Timer event
virtual void timerEvent(QTimerEvent *event);
@@ -124,12 +130,10 @@ namespace BlackSimPlugin
// DirectPlay object handling
QPointer<CFs9Host> m_fs9Host;
bool m_isHosting = false; //!< Is sim connected
bool m_isHosting = false; //!< Is sim connected?
bool m_startedLobbyConnection = false;
QHash<BlackMisc::Aviation::CCallsign, QPointer<CFs9Client>> m_hashFs9Clients;
CLobbyClient *m_lobbyClient;
BlackCore::IInterpolator *m_interpolator = nullptr; //!< interpolator instance
};
} // namespace
} // namespace

View File

@@ -257,10 +257,10 @@ namespace BlackSimPlugin
// remove upfront, and then enable / disable again
this->removeRemoteAircraft(aircraft.getCallsign());
return this->changeAircraftEnabled(aircraft, originator);
return this->changeRemoteAircraftEnabled(aircraft, originator);
}
bool CSimulatorFsCommon::changeAircraftEnabled(const CSimulatedAircraft &aircraft, const QString &originator)
bool CSimulatorFsCommon::changeRemoteAircraftEnabled(const CSimulatedAircraft &aircraft, const QString &originator)
{
if (originator == simulatorOriginator()) { return false; }
if (aircraft.isEnabled())

View File

@@ -75,7 +75,7 @@ namespace BlackSimPlugin
virtual bool changeRemoteAircraftModel(const BlackMisc::Simulation::CSimulatedAircraft &aircraft, const QString &originator) override;
//! \copydoc ISimulator::changeAircraftEnabled
virtual bool changeAircraftEnabled(const BlackMisc::Simulation::CSimulatedAircraft &aircraft, const QString &originator) override;
virtual bool changeRemoteAircraftEnabled(const BlackMisc::Simulation::CSimulatedAircraft &aircraft, const QString &originator) override;
//! \copydoc ISimulator::enableDebuggingMessages
virtual void enableDebugMessages(bool driver, bool interpolator) override;
@@ -95,7 +95,6 @@ namespace BlackSimPlugin
bool m_simTimeSynced = false; //!< Time synchronized?
BlackMisc::PhysicalQuantities::CTime m_syncTimeOffset; //!< time offset
BlackMisc::Aviation::CAirportList m_airportsInRange; //!< aiports in range of own aircraft
BlackCore::IInterpolator *m_interpolator = nullptr; //!< interpolator instance
// cockpit as set in SIM
BlackMisc::Aviation::CComSystem m_simCom1; //!< cockpit COM1 state in simulator

View File

@@ -151,9 +151,9 @@ namespace BlackSimPlugin
CLogMessage(this).warning("Have to remove aircraft %1 before I can add it") << callsign;
}
SIMCONNECT_DATA_INITPOSITION initialPosition = aircraftSituationToFsxInitPosition(newRemoteAircraft.getSituation());
initialPosition.Airspeed = 0;
initialPosition.OnGround = 0;
CSimulatedAircraft newRemoteAircraftCopy(newRemoteAircraft);
this->setInitialAircraftSituationAndParts(newRemoteAircraftCopy);
SIMCONNECT_DATA_INITPOSITION initialPosition = aircraftSituationToFsxInitPosition(newRemoteAircraftCopy.getSituation());
CSimConnectObject simObj;
simObj.setCallsign(callsign);
@@ -162,10 +162,11 @@ namespace BlackSimPlugin
++m_nextObjID;
// matched models
CAircraftModel aircraftModel = modelMatching(newRemoteAircraft);
CAircraftModel aircraftModel = modelMatching(newRemoteAircraftCopy);
Q_ASSERT(newRemoteAircraft.getCallsign() == aircraftModel.getCallsign());
providerUpdateAircraftModel(newRemoteAircraft.getCallsign(), aircraftModel, simulatorOriginator());
this->providerUpdateAircraftModel(newRemoteAircraft.getCallsign(), aircraftModel, simulatorOriginator());
CSimulatedAircraft aircraftAfterModelApplied = remoteAircraft().findFirstByCallsign(newRemoteAircraft.getCallsign());
aircraftAfterModelApplied.setRendered(true);
emit modelMatchingCompleted(aircraftAfterModelApplied);
// create AI
@@ -176,16 +177,15 @@ 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);
remoteAircraft().applyIfCallsign(callsign, CPropertyIndexVariantMap(CSimulatedAircraft::IndexRendered, CVariant::fromValue(true)));
CLogMessage(this).info("FSX: Added aircraft %1") << callsign.toQString();
return true;
}
else
{
remoteAircraft().applyIfCallsign(callsign, CPropertyIndexVariantMap(CSimulatedAircraft::IndexRendered, CVariant::fromValue(false)));
CLogMessage(this).warning("FSX: Not connected, not added aircraft %1") << callsign.toQString();
return false;
}
remoteAircraft().setRendered(callsign, false);
}
bool CSimulatorFsx::updateOwnSimulatorCockpit(const CAircraft &ownAircraft, const QString &originator)
@@ -294,6 +294,10 @@ namespace BlackSimPlugin
this->displayStatusMessage(message.asStatusMessage(true, true));
}
bool CSimulatorFsx::isRenderedAircraft(const CCallsign &callsign) const
{
return this->m_simConnectObjects.contains(callsign);
}
void CSimulatorFsx::onSimRunning()
{
@@ -510,11 +514,20 @@ namespace BlackSimPlugin
return removeRemoteAircraft(m_simConnectObjects.value(callsign));
}
void CSimulatorFsx::removeAllRemoteAircraft()
{
QList<CCallsign> callsigns(m_simConnectObjects.keys());
for (const CCallsign &cs : callsigns)
{
removeRemoteAircraft(cs);
}
}
bool CSimulatorFsx::removeRemoteAircraft(const CSimConnectObject &simObject)
{
m_simConnectObjects.remove(simObject.getCallsign());
SimConnect_AIRemoveObject(m_hSimConnect, simObject.getObjectId(), simObject.getRequestId());
remoteAircraft().applyIfCallsign(simObject.getCallsign(), CPropertyIndexVariantMap(CSimulatedAircraft::IndexRendered, CVariant::fromValue(false)));
remoteAircraft().setRendered(simObject.getCallsign(), false);
CLogMessage(this).info("FSX: Removed aircraft %1") << simObject.getCallsign().toQString();
return true;
}
@@ -633,7 +646,7 @@ namespace BlackSimPlugin
//! \todo The onGround in parts is nuts, as already mentioned in the discussion
// a) I am forced to read parts even if i just want to update position
// b) Unlike the other values it is not a fire aforget value, as I need it again in the next cycle
// b) Unlike the other values it is not a fire and forget value, as I need it again in the next cycle
if (partsStatus.supportsParts && !parts.isEmpty())
{
// we have parts, and use the closest ground

View File

@@ -110,6 +110,9 @@ namespace BlackSimPlugin
//! \copydoc ISimulator::remoteRenderedAircraft()
virtual bool removeRemoteAircraft(const BlackMisc::Aviation::CCallsign &callsign) override;
//! \copydoc BlackCore::ISimulator::removeAllRemoteAircraft
virtual void removeAllRemoteAircraft() override;
//! \copydoc ISimulator::updateOwnCockpit
virtual bool updateOwnSimulatorCockpit(const BlackMisc::Aviation::CAircraft &ownAircraft, const QString &originator) override;
@@ -119,6 +122,9 @@ namespace BlackSimPlugin
//! \copydoc ISimulator::displayTextMessage()
virtual void displayTextMessage(const BlackMisc::Network::CTextMessage &message) const override;
//! \copydoc ISimulator::isRenderedAircraft
virtual bool isRenderedAircraft(const BlackMisc::Aviation::CCallsign &callsign) const override;
//! Called when sim has started
void onSimRunning();
@@ -141,11 +147,11 @@ namespace BlackSimPlugin
void onSimExit();
protected:
//! Timer event
//! Timer event (our SimConnect event loop), runs \sa ps_dispatch
//! \sa m_simconnectTimerId
virtual void timerEvent(QTimerEvent *event);
private slots:
//! Dispatch SimConnect messages
void ps_dispatch();
@@ -153,7 +159,6 @@ namespace BlackSimPlugin
void ps_connectToFinished();
private:
//! Remove a remote aircraft
bool removeRemoteAircraft(const CSimConnectObject &simObject);
@@ -190,7 +195,6 @@ namespace BlackSimPlugin
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)
QHash<BlackMisc::Aviation::CCallsign, CSimConnectObject> m_simConnectObjects;
QFutureWatcher<bool> m_watcherConnect;

View File

@@ -50,7 +50,8 @@ namespace BlackSimPlugin
bool c = remoteAircraftProvider->connectRemoteAircraftProviderSignals(
std::bind(&CSimulatorXPlane::ps_addAircraftSituation, this, std::placeholders::_1),
std::bind(&CSimulatorXPlane::ps_addAircraftParts, this, std::placeholders::_1),
[](const BlackMisc::Aviation::CCallsign &) {});
std::bind(&CSimulatorXPlane::ps_removedAircraft, this, std::placeholders::_1)
);
Q_ASSERT(c);
Q_UNUSED(c);
}
@@ -313,6 +314,13 @@ namespace BlackSimPlugin
return CPixmap();
}
bool CSimulatorXPlane::isRenderedAircraft(const CCallsign &callsign) const
{
//! \todo XP implement isRenderedAircraft correctly
// work around, but not really telling me if callsign is really(!) visible in SIM
return remoteAircraft().findFirstByCallsign(callsign).isRendered();
}
bool CSimulatorXPlane::updateOwnSimulatorCockpit(const BlackMisc::Aviation::CAircraft &aircraft, const QString &originator)
{
if (originator == this->simulatorOriginator()) { return false; }
@@ -375,18 +383,31 @@ namespace BlackSimPlugin
m_traffic->setPlaneTransponder(parts.getCallsign().asString(), 2000, true, false); // TODO transponder
}
void CSimulatorXPlane::ps_removedAircraft(const CCallsign &callsign)
{
Q_UNUSED(callsign);
//! \todo call removeRemoteAircraft or just let removeRemoteAircraft handle it?
}
bool CSimulatorXPlane::removeRemoteAircraft(const BlackMisc::Aviation::CCallsign &callsign)
{
if (! isConnected()) { return false; }
m_traffic->removePlane(callsign.asString());
remoteAircraft().applyIfCallsign(callsign, CPropertyIndexVariantMap(CSimulatedAircraft::IndexRendered, CVariant::fromValue(false)));
remoteAircraft().setRendered(callsign, false);
CLogMessage(this).info("XP: Removed aircraft %1") << callsign.toQString();
return true;
}
void CSimulatorXPlane::removeAllRemoteAircraft()
{
m_traffic->removeAllPlanes();
remoteAircraft().markAllAsNotRendered();
CLogMessage(this).info("XP: Removed all aircraft");
}
bool CSimulatorXPlane::changeRemoteAircraftModel(const CSimulatedAircraft &aircraft, const QString &originator)
{
return this->changeAircraftEnabled(aircraft, originator);
return this->changeRemoteAircraftEnabled(aircraft, originator);
}
CAircraftIcao CSimulatorXPlane::getIcaoForModelString(const QString &modelString) const
@@ -395,7 +416,7 @@ namespace BlackSimPlugin
return CAircraftIcao();
}
bool CSimulatorXPlane::changeAircraftEnabled(const CSimulatedAircraft &aircraft, const QString &originator)
bool CSimulatorXPlane::changeRemoteAircraftEnabled(const CSimulatedAircraft &aircraft, const QString &originator)
{
if (originator == simulatorOriginator()) { return false; }
if (aircraft.isEnabled())

View File

@@ -74,11 +74,14 @@ namespace BlackSimPlugin
//! \copydoc BlackCore::ISimulator::removeRemoteAircraft
virtual bool removeRemoteAircraft(const BlackMisc::Aviation::CCallsign &callsign) override;
//! \copydoc BlackCore::ISimulator::removeAllRemoteAircraft
virtual void removeAllRemoteAircraft() override;
//! \copydoc ISimulator::changeRenderedAircraftModel
virtual bool changeRemoteAircraftModel(const BlackMisc::Simulation::CSimulatedAircraft &aircraft, const QString &originator) override;
//! \copydoc ISimulator::changeAircraftEnabled
virtual bool changeAircraftEnabled(const BlackMisc::Simulation::CSimulatedAircraft &aircraft, const QString &originator) override;
virtual bool changeRemoteAircraftEnabled(const BlackMisc::Simulation::CSimulatedAircraft &aircraft, const QString &originator) override;
//! \copydoc BlackCore::ISimulator::updateOwnSimulatorCockpit
virtual bool updateOwnSimulatorCockpit(const BlackMisc::Aviation::CAircraft &aircraft, const QString &originator) override;
@@ -107,6 +110,9 @@ namespace BlackSimPlugin
//! \copydoc ISimulator::iconForModel
virtual BlackMisc::CPixmap iconForModel(const QString &modelString) const override;
//! \copydoc ISimulator::isRenderedAircraft
virtual bool isRenderedAircraft(const BlackMisc::Aviation::CCallsign &callsign) const override;
private slots:
void ps_serviceRegistered(const QString &serviceName);
void ps_serviceUnregistered();
@@ -117,6 +123,7 @@ namespace BlackSimPlugin
void ps_addAircraftSituation(const BlackMisc::Aviation::CAircraftSituation &situ);
void ps_addAircraftParts(const BlackMisc::Aviation::CAircraftParts &parts);
void ps_removedAircraft(const BlackMisc::Aviation::CCallsign &callsign);
private:
QDBusConnection m_conn { "default" };