diff --git a/src/blackcore/simulator.h b/src/blackcore/simulator.h index 2b7b36e8a..4ba379511 100644 --- a/src/blackcore/simulator.h +++ b/src/blackcore/simulator.h @@ -13,19 +13,18 @@ #define BLACKCORE_SIMULATOR_H #include "blacksim/simulatorinfo.h" +#include "blackmisc/simulation/aircraftmodellist.h" #include "blackmisc/statusmessagelist.h" -#include "blackmisc/avaircraft.h" +#include "blackmisc/simulation/simulatedaircraftlist.h" #include "blackmisc/avairportlist.h" -#include "blackmisc/nwaircraftmodellist.h" #include "blackmisc/nwtextmessage.h" #include "blackmisc/nwclient.h" +#include "blackmisc/pixmap.h" #include namespace BlackCore { - /*! - * Interface to a simulator. - */ + //! Interface to a simulator. class ISimulator : public QObject { Q_OBJECT @@ -73,16 +72,22 @@ namespace BlackCore virtual bool disconnectFrom() = 0; //! Return user aircraft object - virtual BlackMisc::Aviation::CAircraft getOwnAircraft() const = 0; + virtual BlackMisc::Simulation::CSimulatedAircraft getOwnAircraft() const = 0; //! Add new remote aircraft to the simulator - virtual void addRemoteAircraft(const BlackMisc::Aviation::CAircraft &remoteAircraft, const BlackMisc::Network::CClient &remoteClient) = 0; + virtual void addRemoteAircraft(const BlackMisc::Simulation::CSimulatedAircraft &remoteAircraft) = 0; + + //! Simulated other aircraft in range + virtual BlackMisc::Simulation::CSimulatedAircraftList getRemoteAircraft() const = 0; //! Add new aircraft situation virtual void addAircraftSituation(const BlackMisc::Aviation::CCallsign &callsign, const BlackMisc::Aviation::CAircraftSituation &situation) = 0; //! Remove remote aircraft from simulator - virtual void removeRemoteAircraft(const BlackMisc::Aviation::CCallsign &callsign) = 0; + virtual int removeRemoteAircraft(const BlackMisc::Aviation::CCallsign &callsign) = 0; + + //! Change remote aircraft per property + virtual int changeRemoteAircraft(const BlackMisc::Simulation::CSimulatedAircraft &changedAircraft, const BlackMisc::CPropertyIndexVariantMap &changeValues) = 0; //! Update own aircraft cockpit (usually from context) virtual bool updateOwnSimulatorCockpit(const BlackMisc::Aviation::CAircraft &aircraft) = 0; @@ -97,13 +102,10 @@ namespace BlackCore virtual void displayTextMessage(const BlackMisc::Network::CTextMessage &message) const = 0; //! Own aircraft Model - virtual BlackMisc::Network::CAircraftModel getOwnAircraftModel() const = 0; + virtual BlackMisc::Simulation::CAircraftModel getOwnAircraftModel() const = 0; //! Aircraft models for available remote aircrafts - virtual BlackMisc::Network::CAircraftModelList getInstalledModels() const = 0; - - //! Remote aircraft in range having a valid model matching (which should be all aircraft in range) - virtual BlackMisc::Network::CAircraftModelList getCurrentlyMatchedModels() const = 0; + virtual BlackMisc::Simulation::CAircraftModelList getInstalledModels() const = 0; //! Airports in range virtual BlackMisc::Aviation::CAirportList getAirportsInRange() const = 0; @@ -115,12 +117,15 @@ namespace BlackCore //! Time synchronization offset virtual BlackMisc::PhysicalQuantities::CTime getTimeSynchronizationOffset() const = 0; + //! Representing icon for model string + virtual BlackMisc::CPixmap iconForModel(const QString &modelString) const = 0; + signals: //! Emitted when the connection status has changed void connectionStatusChanged(ISimulator::ConnectionStatus status); //! Emitted when own aircraft model has changed - void ownAircraftModelChanged(BlackMisc::Network::CAircraftModel model); + void ownAircraftModelChanged(BlackMisc::Simulation::CSimulatedAircraft aircraft); //! Simulator combined status void simulatorStatusChanged(bool connected, bool running, bool paused); @@ -132,7 +137,10 @@ namespace BlackCore void simulatorStopped(); //! A single model has been matched - void modelMatchingCompleted(BlackMisc::Network::CAircraftModel model); + void modelMatchingCompleted(BlackMisc::Simulation::CSimulatedAircraft aircraft); + + //! Installed aircraft models ready or changed + void installedAircraftModelsChanged(); protected: //! Emit the combined status diff --git a/src/plugins/simulator/fs9/simulator_fs9.cpp b/src/plugins/simulator/fs9/simulator_fs9.cpp index e02a4abc8..845fd93b3 100644 --- a/src/plugins/simulator/fs9/simulator_fs9.cpp +++ b/src/plugins/simulator/fs9/simulator_fs9.cpp @@ -16,12 +16,14 @@ #include "multiplayer_packet_parser.h" #include "blacksim/simulatorinfo.h" #include "blackmisc/project.h" +#include "blackmisc/propertyindexallclasses.h" #include #include using namespace BlackMisc; using namespace BlackMisc::Aviation; using namespace BlackMisc::Network; +using namespace BlackMisc::Simulation; using namespace BlackMisc::PhysicalQuantities; using namespace BlackMisc::Geo; using namespace BlackSim; @@ -95,9 +97,8 @@ namespace BlackSimPlugin return true; } - void CSimulatorFs9::addRemoteAircraft(const CAircraft &remoteAircraft, const CClient &remoteClient) + void CSimulatorFs9::addRemoteAircraft(const CSimulatedAircraft &remoteAircraft) { - Q_UNUSED(remoteClient); CCallsign callsign = remoteAircraft.getCallsign(); CFs9Client *client = new CFs9Client(this, callsign.toQString(), CTime(25, CTimeUnit::ms())); client->setHostAddress(m_fs9Host->getHostAddress()); @@ -105,7 +106,7 @@ namespace BlackSimPlugin client->start(); m_hashFs9Clients.insert(callsign, client); - + m_remoteAircraft.replaceOrAdd(&CSimulatedAircraft::getCallsign, remoteAircraft.getCallsign(), remoteAircraft); addAircraftSituation(callsign, remoteAircraft.getSituation()); } @@ -120,15 +121,20 @@ namespace BlackSimPlugin client->addAircraftSituation(situation); } - void CSimulatorFs9::removeRemoteAircraft(const CCallsign &callsign) + int CSimulatorFs9::removeRemoteAircraft(const CCallsign &callsign) { - if(!m_hashFs9Clients.contains(callsign)) return; + if (!m_hashFs9Clients.contains(callsign)) { return 0; } auto fs9Client = m_hashFs9Clients.value(callsign); - fs9Client->quit(); - m_hashFs9Clients.remove(callsign); + return m_remoteAircraft.removeIf(&CSimulatedAircraft::getCallsign, callsign); + } + + int CSimulatorFs9::changeRemoteAircraft(const CSimulatedAircraft &changedAircraft, const CPropertyIndexVariantMap &changedValues) + { + return m_remoteAircraft.incrementalUpdateOrAdd(changedAircraft, changedValues); + //! \todo really update aircraft in SIM } bool CSimulatorFs9::updateOwnSimulatorCockpit(const CAircraft &ownAircraft) @@ -212,6 +218,12 @@ namespace BlackSimPlugin this->m_syncTimeOffset = offset; } + CPixmap CSimulatorFs9::iconForModel(const QString &modelString) const + { + Q_UNUSED(modelString); + return CPixmap(); + } + void CSimulatorFs9::timerEvent(QTimerEvent * /* event */) { ps_dispatch(); @@ -229,47 +241,49 @@ namespace BlackSimPlugin switch (messageType) { - case CFs9Sdk::MULTIPLAYER_PACKET_ID_PARAMS: + case CFs9Sdk::MULTIPLAYER_PACKET_ID_PARAMS: { break; } - case CFs9Sdk::MULTIPLAYER_PACKET_ID_CHANGE_PLAYER_PLANE: + case CFs9Sdk::MULTIPLAYER_PACKET_ID_CHANGE_PLAYER_PLANE: { MPChangePlayerPlane mpChangePlayerPlane; MultiPlayerPacketParser::readMessage(message, mpChangePlayerPlane); ps_changeOwnAircraftModel(mpChangePlayerPlane.aircraft_name); break; } - case CFs9Sdk::MULTIPLAYER_PACKET_ID_POSITION_VELOCITY: + case CFs9Sdk::MULTIPLAYER_PACKET_ID_POSITION_VELOCITY: { MPPositionVelocity mpPositionVelocity; MultiPlayerPacketParser::readMessage(message, mpPositionVelocity); m_ownAircraft.setSituation(aircraftSituationfromFS9(mpPositionVelocity)); break; } - case CFs9Sdk::MPCHAT_PACKET_ID_CHAT_TEXT_SEND: + case CFs9Sdk::MPCHAT_PACKET_ID_CHAT_TEXT_SEND: { MPChatText mpChatText; MultiPlayerPacketParser::readMessage(message, mpChatText); break; } - default: - break; + default: + break; } } void CSimulatorFs9::ps_changeOwnAircraftModel(const QString &modelname) { - m_aircraftModel.setQueriedModelString(modelname); - emit ownAircraftModelChanged(m_aircraftModel); + CAircraftModel model = m_ownAircraft.getModel(); + model.setModelString(modelname); + m_ownAircraft.setModel(model); + emit ownAircraftModelChanged(m_ownAircraft); } void CSimulatorFs9::ps_changeHostStatus(BlackSimPlugin::Fs9::CFs9Host::HostStatus status) { switch (status) { - case CFs9Host::Hosting: + case CFs9Host::Hosting: { m_isHosting = true; startTimer(50); @@ -281,14 +295,14 @@ namespace BlackSimPlugin } break; } - case CFs9Host::Terminated: + case CFs9Host::Terminated: { m_isHosting = false; emit connectionStatusChanged(Disconnected); break; } - default: - break; + default: + break; } } @@ -307,5 +321,5 @@ namespace BlackSimPlugin removeRemoteAircraft(fs9Client); } } - } -} + } // namespace +} // namespace diff --git a/src/plugins/simulator/fs9/simulator_fs9.h b/src/plugins/simulator/fs9/simulator_fs9.h index ed61731a9..6140854c3 100644 --- a/src/plugins/simulator/fs9/simulator_fs9.h +++ b/src/plugins/simulator/fs9/simulator_fs9.h @@ -16,9 +16,10 @@ #include "../fscommon/fsuipc.h" #include "blackcore/simulator.h" #include "blackcore/interpolator_linear.h" +#include "blackmisc/simulation/aircraftmodel.h" #include "blackmisc/avaircraft.h" -#include "blackmisc/nwaircraftmodel.h" #include "blacksim/simulatorinfo.h" +#include "blackmisc/pixmap.h" #include #include #include @@ -85,16 +86,22 @@ namespace BlackSimPlugin virtual bool disconnectFrom() override; //! \copydoc ISimulator::getOwnAircraft() - virtual BlackMisc::Aviation::CAircraft getOwnAircraft() const override { return m_ownAircraft; } + virtual BlackMisc::Simulation::CSimulatedAircraft getOwnAircraft() const override { return m_ownAircraft; } //! \copydoc ISimulator::addRemoteAircraft() - virtual void addRemoteAircraft(const BlackMisc::Aviation::CAircraft &remoteAircraft, const BlackMisc::Network::CClient &remoteClient) override; + virtual void addRemoteAircraft(const BlackMisc::Simulation::CSimulatedAircraft &remoteAircraft) override; + + //! \copydoc BlackCore::ISimulator::getRemoteAircraft + virtual BlackMisc::Simulation::CSimulatedAircraftList getRemoteAircraft() const override { return m_remoteAircraft; } //! \copydoc ISimulator::addAircraftSituation() virtual void addAircraftSituation(const BlackMisc::Aviation::CCallsign &callsign, const BlackMisc::Aviation::CAircraftSituation &initialSituation) override; //! \copydoc ISimulator::removeRemoteAircraft() - virtual void removeRemoteAircraft(const BlackMisc::Aviation::CCallsign &callsign) override; + virtual int removeRemoteAircraft(const BlackMisc::Aviation::CCallsign &callsign) override; + + //! \copydoc ISimulator::changeRemoteAircraft + virtual int changeRemoteAircraft(const BlackMisc::Simulation::CSimulatedAircraft &changedAircraft, const BlackMisc::CPropertyIndexVariantMap &changeValues) override; //! \copydoc ISimulator::updateOwnSimulatorCockpit() virtual bool updateOwnSimulatorCockpit(const BlackMisc::Aviation::CAircraft &ownAircraft) override; @@ -109,13 +116,10 @@ namespace BlackSimPlugin virtual void displayTextMessage(const BlackMisc::Network::CTextMessage &message) const override; //! \copydoc ISimulator::getAircraftModel() - virtual BlackMisc::Network::CAircraftModel getOwnAircraftModel() const override { return m_aircraftModel; } + virtual BlackMisc::Simulation::CAircraftModel getOwnAircraftModel() const override { return m_ownAircraft.getModel(); } //! \copydoc BlackCore::ISimulator::getInstalledModels - virtual BlackMisc::Network::CAircraftModelList getInstalledModels() const override { return {}; } - - //! \copydoc BlackCore::ISimulator::getCurrentlyMatchedModels - virtual BlackMisc::Network::CAircraftModelList getCurrentlyMatchedModels() const override { return BlackMisc::Network::CAircraftModelList(); } + virtual BlackMisc::Simulation::CAircraftModelList getInstalledModels() const override { return {}; } //! Airports in range virtual BlackMisc::Aviation::CAirportList getAirportsInRange() const override; @@ -127,6 +131,9 @@ namespace BlackSimPlugin //! Time synchronization offset virtual BlackMisc::PhysicalQuantities::CTime getTimeSynchronizationOffset() const override { return m_syncTimeOffset; } + //! \copydoc ISimulator::iconForModel + virtual BlackMisc::CPixmap iconForModel(const QString &modelString) const override; + protected: //! Timer event virtual void timerEvent(QTimerEvent *event); @@ -164,16 +171,15 @@ namespace BlackSimPlugin CLobbyClient *m_lobbyClient; - BlackSim::CSimulatorInfo m_simulatorInfo; - BlackMisc::Aviation::CAircraft m_ownAircraft; //!< Object representing our own aircraft from simulator - BlackMisc::Aviation::CAirportList m_airportsInRange; - BlackMisc::Network::CAircraftModel m_aircraftModel; - BlackMisc::PhysicalQuantities::CTime m_syncTimeOffset; + BlackSim::CSimulatorInfo m_simulatorInfo; + BlackMisc::Simulation::CSimulatedAircraft m_ownAircraft; //!< Object representing our own aircraft from simulator + BlackMisc::Aviation::CAirportList m_airportsInRange; + BlackMisc::PhysicalQuantities::CTime m_syncTimeOffset; + BlackMisc::Simulation::CSimulatedAircraftList m_remoteAircraft; QScopedPointer m_fsuipc; }; - } - -} // namespace BlackCore + } // namespace +} // namespace #endif // guard diff --git a/src/plugins/simulator/fscommon/fsuipc.h b/src/plugins/simulator/fscommon/fsuipc.h index 5aff20d57..bc427482e 100644 --- a/src/plugins/simulator/fscommon/fsuipc.h +++ b/src/plugins/simulator/fscommon/fsuipc.h @@ -6,8 +6,8 @@ #ifndef BLACKSIMPLUGIN_FSUIPC_H #define BLACKSIMPLUGIN_FSUIPC_H +#include "blackmisc/simulation/aircraftmodel.h" #include "blackmisc/avaircraft.h" -#include "blackmisc/nwaircraftmodel.h" #include namespace BlackSimPlugin @@ -92,7 +92,7 @@ namespace BlackSimPlugin QString m_lastErrorMessage; QString m_fsuipcVersion; BlackMisc::Aviation::CAircraft m_aircraft; //!< FSUIPC read aircraft - BlackMisc::Network::CAircraftModel m_model; //!< FSUIPC read model + BlackMisc::Simulation::CAircraftModel m_model; //!< FSUIPC read model //! Read data from FSUIPC void read(); diff --git a/src/plugins/simulator/fsx/simulator_fsx.cpp b/src/plugins/simulator/fsx/simulator_fsx.cpp index b8f929160..334c15ab9 100644 --- a/src/plugins/simulator/fsx/simulator_fsx.cpp +++ b/src/plugins/simulator/fsx/simulator_fsx.cpp @@ -15,10 +15,10 @@ #include "blacksim/fsx/simconnectutilities.h" #include "blacksim/fsx/fsxsimulatorsetup.h" #include "blacksim/simulatorinfo.h" +#include "blackmisc/simulation/aircraftmodel.h" #include "blackmisc/project.h" #include "blackmisc/avairportlist.h" #include "blackmisc/logmessage.h" -#include "blackmisc/nwaircraftmodel.h" #include "blackmisc/nwaircraftmappinglist.h" #include @@ -29,6 +29,7 @@ using namespace BlackMisc::Aviation; using namespace BlackMisc::PhysicalQuantities; using namespace BlackMisc::Geo; using namespace BlackMisc::Network; +using namespace BlackMisc::Simulation; using namespace BlackSim; using namespace BlackSim::FsCommon; using namespace BlackSim::Fsx; @@ -48,6 +49,7 @@ namespace BlackSimPlugin // hack to init mapper CAircraftMapper *mapper = mapperInstance(); + connect(mapper, &CAircraftMapper::initCompleted, this, &CSimulatorFsx::ps_mapperInitialized); mapper->initCompletelyInBackground(); } @@ -113,7 +115,6 @@ namespace BlackSimPlugin bool CSimulatorFsx::disconnectFrom() { if (!m_simConnected) { return true; } - if (m_hSimConnect) { SimConnect_Close(m_hSimConnect); @@ -143,12 +144,13 @@ namespace BlackSimPlugin return connect; } - void CSimulatorFsx::addRemoteAircraft(const CAircraft &remoteAircraft, const CClient &remoteClient) + void CSimulatorFsx::addRemoteAircraft(const Simulation::CSimulatedAircraft &remoteAircraft) { CCallsign callsign = remoteAircraft.getCallsign(); Q_ASSERT(!callsign.isEmpty()); if (callsign.isEmpty()) { return; } + bool aircraftAlreadyExists = m_remoteAircraft.containsCallsign(callsign); SIMCONNECT_DATA_INITPOSITION initialPosition = aircraftSituationToFsxInitPosition(remoteAircraft.getSituation()); initialPosition.Airspeed = 0; initialPosition.OnGround = 0; @@ -163,18 +165,24 @@ namespace BlackSimPlugin addAircraftSituation(callsign, remoteAircraft.getSituation()); // matched models - CAircraftModel aircraftModel = modelMatching(remoteAircraft, remoteClient); + CAircraftModel aircraftModel = modelMatching(remoteAircraft); Q_ASSERT(remoteAircraft.getCallsign() == aircraftModel.getCallsign()); - this->m_matchedModels.replaceOrAdd(&CAircraftModel::getCallsign, aircraftModel.getCallsign(), aircraftModel); - emit modelMatchingCompleted(aircraftModel); + CSimulatedAircraft mappedRemoteAircraft(remoteAircraft); + mappedRemoteAircraft.setModel(aircraftModel); + m_remoteAircraft.replaceOrAdd(&CSimulatedAircraft::getCallsign, callsign, mappedRemoteAircraft); + emit modelMatchingCompleted(mappedRemoteAircraft); // create AI //! \todo isConnected() or isSimulating() ?? if (isConnected()) { - QByteArray m = aircraftModel.getModelString().toLocal8Bit(); - 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 create AI traffic"); } + //! \todo if exists, recreate (new model?, new ICAO code) + if (!aircraftAlreadyExists) + { + QByteArray m = aircraftModel.getModelString().toLocal8Bit(); + 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"); } + } } } @@ -188,9 +196,38 @@ namespace BlackSimPlugin m_simConnectObjects.insert(callsign, simObj); } - void CSimulatorFsx::removeRemoteAircraft(const CCallsign &callsign) + int CSimulatorFsx::removeRemoteAircraft(const CCallsign &callsign) { removeRemoteAircraft(m_simConnectObjects.value(callsign)); + return m_remoteAircraft.removeIf(&CSimulatedAircraft::getCallsign, callsign); + } + + int CSimulatorFsx::changeRemoteAircraft(const CSimulatedAircraft &changedAircraft, const CPropertyIndexVariantMap &changedValues) + { + // EXPERIMENTAL VERSION + + const CCallsign callsign = changedAircraft.getCallsign(); + int c = m_remoteAircraft.incrementalUpdateOrAdd(changedAircraft, changedValues); + if (c == 0) { return 0; } // nothing was changed + const CSimulatedAircraft aircraftAfterChanges = m_remoteAircraft.findFirstByCallsign(callsign); + const QString modelBefore = changedAircraft.getModel().getModelString(); + const QString modelAfter = aircraftAfterChanges.getModel().getModelString(); + if (modelBefore != modelAfter) + { + // model did change + removeRemoteAircraft(m_simConnectObjects.value(callsign)); + } + + if (changedAircraft.isEnabled() && !m_simConnectObjects.contains(callsign)) + { + addRemoteAircraft(aircraftAfterChanges); + } + else if (!aircraftAfterChanges.isEnabled()) + { + removeRemoteAircraft(m_simConnectObjects.value(callsign)); + } + // apply other changes + return c; } CSimulatorInfo CSimulatorFsx::getSimulatorInfo() const @@ -198,12 +235,23 @@ namespace BlackSimPlugin return this->m_simulatorInfo; } - void CSimulatorFsx::setOwnAircraftModel(const BlackMisc::Network::CAircraftModel &model) + void CSimulatorFsx::setOwnAircraftModel(const BlackMisc::Simulation::CAircraftModel &model) { - if (m_ownAircraftModel != model) + if (m_ownAircraft.getModel() != model) { - m_ownAircraftModel = model; - emit ownAircraftModelChanged(model); + CAircraftModel newModel(model); + if (this->mapperInstance() && this->mapperInstance()->isInitialized()) + { + // reverse lookup of ICAO + CAircraftMappingList ml = this->mapperInstance()->getAircraftMappingList().findByModelString(model.getModelString()); + if (!ml.isEmpty()) + { + CAircraftMapping mapping = ml.front(); + newModel.setIcao(mapping.getIcao()); + } + } + m_ownAircraft.setModel(newModel); + emit ownAircraftModelChanged(m_ownAircraft); } } @@ -326,6 +374,11 @@ namespace BlackSimPlugin return mapperInstance()->getAircraftCfgEntriesList().toAircraftModelList(); } + CSimulatedAircraftList CSimulatorFsx::getRemoteAircraft() const + { + return this->m_remoteAircraft; + } + CAirportList CSimulatorFsx::getAirportsInRange() const { return this->m_airportsInRange; @@ -337,6 +390,37 @@ namespace BlackSimPlugin this->m_syncTimeOffset = offset; } + CPixmap CSimulatorFsx::iconForModel(const QString &modelString) const + { + static const CPixmap empty; + if (modelString.isEmpty() || !mapperInstance()->isInitialized()) { return empty; } + CAircraftCfgEntriesList cfgEntries = mapperInstance()->getAircraftCfgEntriesList().findByTitle(modelString); + if (cfgEntries.isEmpty()) + { + CLogMessage(this).warning("No FSX .cfg entry for '%1'") << modelString; + return empty; + } + + // normally we should have only one entry + if (cfgEntries.size() > 1) + { + CLogMessage(this).warning("Multiple FSX .cfg entries for '%1'") << modelString; + } + + // use first with icon + for (const CAircraftCfgEntries &entry : cfgEntries) + { + const QString thumbnail = entry.getThumbnailFileName(); + if (thumbnail.isEmpty()) { continue; } + QPixmap pm; + if (pm.load(thumbnail)) + { + return CPixmap(pm); + } + } + return empty; + } + void CSimulatorFsx::onSimRunning() { if (m_simRunning) { return; } @@ -502,6 +586,11 @@ namespace BlackSimPlugin } } + void CSimulatorFsx::ps_mapperInitialized(bool success) + { + if (success) { emit this->installedAircraftModelsChanged(); } + } + void CSimulatorFsx::removeRemoteAircraft(const CSimConnectObject &simObject) { SimConnect_AIRemoveObject(m_hSimConnect, simObject.getObjectId(), simObject.getRequestId()); @@ -669,7 +758,7 @@ namespace BlackSimPlugin return mapper; } - CAircraftModel CSimulatorFsx::modelMatching(const CAircraft &remoteAircraft, const CClient &remoteClient) + CAircraftModel CSimulatorFsx::modelMatching(const CSimulatedAircraft &remoteAircraft) { CAircraftModel aircraftModel(remoteAircraft); // set defaults @@ -680,10 +769,12 @@ namespace BlackSimPlugin // will be removed later, just for experimental version aircraftModel.setModelString("Boeing 737-800 Paint1"); aircraftModel.setDescription("Model mapper not ready"); + CLogMessage(static_cast(nullptr)).warning("Mapper not ready, set to default model"); return aircraftModel; } // Model by queried string + const CClient remoteClient = remoteAircraft.getClient(); if (remoteClient.getAircraftModel().hasQueriedModelString()) { QString directModelString = remoteClient.getAircraftModel().getModelString(); @@ -691,7 +782,6 @@ namespace BlackSimPlugin { aircraftModel = mapperInstance()->getModelWithTitle(directModelString); aircraftModel.setModelType(CAircraftModel::TypeQueriedFromNetwork); - aircraftModel.setDescription("Direct query from network"); } } @@ -716,6 +806,7 @@ namespace BlackSimPlugin { aircraftModel.setModelString("Boeing 737-800 Paint1"); aircraftModel.setDescription("Default model"); + aircraftModel.setModelType(CAircraftModel::TypeModelMatching); } else { @@ -730,6 +821,7 @@ namespace BlackSimPlugin aircraftModel.setCallsign(remoteAircraft.getCallsign()); Q_ASSERT(!aircraftModel.getCallsign().isEmpty()); Q_ASSERT(aircraftModel.hasModelString()); + Q_ASSERT(aircraftModel.getModelType() != CAircraftModel::TypeUnknown); return aircraftModel; } diff --git a/src/plugins/simulator/fsx/simulator_fsx.h b/src/plugins/simulator/fsx/simulator_fsx.h index ad20fd060..8e061c550 100644 --- a/src/plugins/simulator/fsx/simulator_fsx.h +++ b/src/plugins/simulator/fsx/simulator_fsx.h @@ -19,11 +19,12 @@ #include "blackcore/interpolator_linear.h" #include "blacksim/simulatorinfo.h" #include "blacksim/fscommon/aircraftmapper.h" -#include "blackmisc/avaircraft.h" +#include "blackmisc/simulation/aircraftmodel.h" +#include "blackmisc/simulation/simulatedaircraft.h" #include "blackmisc/avairportlist.h" #include "blackmisc/statusmessage.h" -#include "blackmisc/nwaircraftmodel.h" #include "blackmisc/nwclient.h" +#include "blackmisc/pixmap.h" #include #include @@ -104,16 +105,19 @@ namespace BlackSimPlugin virtual bool disconnectFrom() override; //! \copydoc ISimulator::getOwnAircraft() - virtual BlackMisc::Aviation::CAircraft getOwnAircraft() const override { return m_ownAircraft; } + virtual BlackMisc::Simulation::CSimulatedAircraft getOwnAircraft() const override { return m_ownAircraft; } //! \copydoc ISimulator::addRemoteAircraft() - virtual void addRemoteAircraft(const BlackMisc::Aviation::CAircraft &remoteAircraft, const BlackMisc::Network::CClient &remoteClient) override; + virtual void addRemoteAircraft(const BlackMisc::Simulation::CSimulatedAircraft &remoteAircraft) override; //! \copydoc ISimulator::addAircraftSituation() virtual void addAircraftSituation(const BlackMisc::Aviation::CCallsign &callsign, const BlackMisc::Aviation::CAircraftSituation &initialSituation) override; //! \copydoc ISimulator::removeRemoteAircraft() - virtual void removeRemoteAircraft(const BlackMisc::Aviation::CCallsign &callsign) override; + virtual int removeRemoteAircraft(const BlackMisc::Aviation::CCallsign &callsign) override; + + //! \copydoc ISimulator::changeRemoteAircraft + virtual int changeRemoteAircraft(const BlackMisc::Simulation::CSimulatedAircraft &changedAircraft, const BlackMisc::CPropertyIndexVariantMap &changeValues) override; //! \copydoc ISimulator::getSimulatorInfo() virtual BlackSim::CSimulatorInfo getSimulatorInfo() const override; @@ -128,13 +132,13 @@ namespace BlackSimPlugin virtual void displayTextMessage(const BlackMisc::Network::CTextMessage &message) const override; //! \copydoc ISimulator::getAircraftModel() - virtual BlackMisc::Network::CAircraftModel getOwnAircraftModel() const override { return m_ownAircraftModel; } + virtual BlackMisc::Simulation::CAircraftModel getOwnAircraftModel() const override { return m_ownAircraft.getModel(); } //! \copydoc BlackCore::ISimulator::getInstalledModels - virtual BlackMisc::Network::CAircraftModelList getInstalledModels() const override; + virtual BlackMisc::Simulation::CAircraftModelList getInstalledModels() const override; - //! \copydoc BlackCore::ISimulator::getCurrentlyMatchedModels - virtual BlackMisc::Network::CAircraftModelList getCurrentlyMatchedModels() const override { return m_matchedModels; } + //! \copydoc BlackCore::ISimulator::getRemoteAircraft + virtual BlackMisc::Simulation::CSimulatedAircraftList getRemoteAircraft() const override; //! \copydoc ISimulator::getAirportsInRange virtual BlackMisc::Aviation::CAirportList getAirportsInRange() const override; @@ -148,9 +152,12 @@ namespace BlackSimPlugin //! \copydoc ISimulator::getTimeSynchronizationOffset virtual BlackMisc::PhysicalQuantities::CTime getTimeSynchronizationOffset() const override { return m_syncTimeOffset; } - //! \copydoc ISimulator::isSimPaused + //! \copydoc ISimulator::isPaused virtual bool isPaused() const override { return m_simPaused; } + //! \copydoc IContextSimulator::iconForModel + virtual BlackMisc::CPixmap iconForModel(const QString &modelString) const override; + //! Called when sim has started void onSimRunning(); @@ -173,7 +180,7 @@ namespace BlackSimPlugin void onSimExit(); //! \private - void setOwnAircraftModel(const BlackMisc::Network::CAircraftModel &model); + void setOwnAircraftModel(const BlackMisc::Simulation::CAircraftModel &model); protected: //! Timer event @@ -187,6 +194,9 @@ namespace BlackSimPlugin //! Called when asynchronous connection to Simconnect has finished void ps_connectToFinished(); + //! Mapper has been initialized + void ps_mapperInitialized(bool success); + private: //! Remove a remote aircraft @@ -214,7 +224,7 @@ namespace BlackSimPlugin static BlackSim::FsCommon::CAircraftMapper *mapperInstance(); //! Experimental model matching - static BlackMisc::Network::CAircraftModel modelMatching(const BlackMisc::Aviation::CAircraft &remoteAircraft, const BlackMisc::Network::CClient &remoteClient); + static BlackMisc::Simulation::CAircraftModel modelMatching(const BlackMisc::Simulation::CSimulatedAircraft &remoteAircraft); //! SimObjects directory static QString simObjectsDir(); @@ -226,17 +236,16 @@ namespace BlackSimPlugin bool m_simTimeSynced = false; //!< Time synchronized? bool m_useSbOffsets = true; //!< with SB offsets int m_syncDeferredCounter = 0; //!< Set when synchronized, used to wait some time - int m_simconnectTimerId = -1; + int m_simconnectTimerId = -1; //!< Timer identifier int m_skipCockpitUpdateCycles = 0; //!< Skip some update cycles to allow changes in simulator cockpit to be set 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; - QString simulatorDetails; //!< describes version etc. - BlackSim::CSimulatorInfo m_simulatorInfo; //!< about the simulator - BlackMisc::Aviation::CAircraft m_ownAircraft; //!< Object representing our own aircraft from simulator - BlackMisc::Network::CAircraftModel m_ownAircraftModel; //!< own model - BlackMisc::Network::CAircraftModelList m_matchedModels; //!< mapped models - BlackMisc::Aviation::CAirportList m_airportsInRange; //!< airports in range + BlackMisc::PhysicalQuantities::CTime m_syncTimeOffset; //!< Time offset (if synchronized) + QString simulatorDetails; //!< describes version etc. + BlackSim::CSimulatorInfo m_simulatorInfo; //!< about the simulator + BlackMisc::Simulation::CSimulatedAircraft m_ownAircraft; //!< Object representing our own aircraft from simulator + BlackMisc::Simulation::CSimulatedAircraftList m_remoteAircraft; //!< mapped models + BlackMisc::Aviation::CAirportList m_airportsInRange; //!< airports in range QHash m_simConnectObjects; QFutureWatcher m_watcherConnect; diff --git a/src/plugins/simulator/fsx/simulator_fsx_simconnectproc.cpp b/src/plugins/simulator/fsx/simulator_fsx_simconnectproc.cpp index a059cd224..60d66ec19 100644 --- a/src/plugins/simulator/fsx/simulator_fsx_simconnectproc.cpp +++ b/src/plugins/simulator/fsx/simulator_fsx_simconnectproc.cpp @@ -18,6 +18,7 @@ #include "blackmisc/logmessage.h" using namespace BlackMisc; +using namespace BlackMisc::Simulation; using namespace BlackMisc::Aviation; using namespace BlackMisc::PhysicalQuantities; using namespace BlackMisc::Geo; @@ -136,7 +137,8 @@ namespace BlackSimPlugin { DataDefinitionOwnAircraftModel *dataDefinitionModel = (DataDefinitionOwnAircraftModel *) &pObjData->dwData; CAircraftModel model; - model.setQueriedModelString(dataDefinitionModel->title); + model.setModelString(dataDefinitionModel->title); + model.setModelType(CAircraftModel::TypeOwnSimulatorModel); simulatorFsx->setOwnAircraftModel(model); break; } diff --git a/src/plugins/simulator/xplane/simulator_xplane.cpp b/src/plugins/simulator/xplane/simulator_xplane.cpp index e0b963b24..ca852497e 100644 --- a/src/plugins/simulator/xplane/simulator_xplane.cpp +++ b/src/plugins/simulator/xplane/simulator_xplane.cpp @@ -13,6 +13,8 @@ using namespace BlackMisc; using namespace BlackMisc::Aviation; using namespace BlackMisc::Network; +using namespace BlackMisc::PhysicalQuantities; +using namespace BlackMisc::Simulation; namespace BlackSimPlugin { @@ -159,10 +161,16 @@ namespace BlackSimPlugin void CSimulatorXPlane::ps_emitOwnAircraftModelChanged(const QString &path, const QString &filename, const QString &livery, const QString &icao) { - emit ownAircraftModelChanged({ path, CAircraftModel::TypeOwnSimulatorModel }); - Q_UNUSED(filename); - Q_UNUSED(livery); - Q_UNUSED(icao); + //! \todo change as appropriate + CSimulatedAircraft aircraft(this->getOwnAircraft()); + CAircraftModel model(aircraft.getModel()); + model.setModelType(CAircraftModel::TypeOwnSimulatorModel); + model.setFileName(path + "/" + filename); + CAircraftIcao aircraftIcao(icao); + aircraftIcao.setLivery(livery); + aircraft.setModel(model); + aircraft.setIcaoInfo(aircraftIcao); + emit ownAircraftModelChanged(aircraft); } // convert xplane squawk mode to swift squawk mode @@ -178,11 +186,9 @@ namespace BlackSimPlugin return mode == BlackMisc::Aviation::CTransponder::StateStandby ? 1 : 2; } - BlackMisc::Aviation::CAircraft CSimulatorXPlane::getOwnAircraft() const + CSimulatedAircraft CSimulatorXPlane::getOwnAircraft() const { if (! isConnected()) { return {}; } - using namespace BlackMisc; - using namespace BlackMisc::PhysicalQuantities; Aviation::CAircraftSituation situation; situation.setPosition({ m_xplaneData.latitude, m_xplaneData.longitude, 0 }); situation.setAltitude({ m_xplaneData.altitude, Aviation::CAltitude::MeanSeaLevel, CLengthUnit::m() }); @@ -190,7 +196,9 @@ namespace BlackSimPlugin situation.setPitch({ m_xplaneData.pitch, CAngleUnit::deg() }); situation.setBank({ m_xplaneData.roll, CAngleUnit::deg() }); situation.setGroundspeed({ m_xplaneData.groundspeed, CSpeedUnit::m_s() }); - Aviation::CAircraft ac { {}, {}, situation }; + CSimulatedAircraft ac; + ac.setSituation(situation); + ac.setModel(this->getOwnAircraftModel()); ac.setIcaoInfo(Aviation::CAircraftIcao { m_xplaneData.aircraftIcaoCode }); ac.setCom1System(Aviation::CComSystem::getCom1System({ m_xplaneData.com1Active, CFrequencyUnit::kHz() }, { m_xplaneData.com1Standby, CFrequencyUnit::kHz() })); ac.setCom2System(Aviation::CComSystem::getCom2System({ m_xplaneData.com2Active, CFrequencyUnit::kHz() }, { m_xplaneData.com2Standby, CFrequencyUnit::kHz() })); @@ -212,13 +220,13 @@ namespace BlackSimPlugin Q_UNUSED(message); } - BlackMisc::Network::CAircraftModel CSimulatorXPlane::getOwnAircraftModel() const + BlackMisc::Simulation::CAircraftModel CSimulatorXPlane::getOwnAircraftModel() const { if (! isConnected()) { return {}; } return { m_xplaneData.aircraftModelPath, CAircraftModel::TypeOwnSimulatorModel }; } - BlackMisc::Network::CAircraftModelList CSimulatorXPlane::getInstalledModels() const + BlackMisc::Simulation::CAircraftModelList CSimulatorXPlane::getInstalledModels() const { // TODO return {}; @@ -259,6 +267,12 @@ namespace BlackSimPlugin } } + CPixmap CSimulatorXPlane::iconForModel(const QString &modelString) const + { + Q_UNUSED(modelString); + return CPixmap(); + } + bool CSimulatorXPlane::updateOwnSimulatorCockpit(const BlackMisc::Aviation::CAircraft &aircraft) { if (! isConnected()) { return false; } @@ -288,15 +302,15 @@ namespace BlackSimPlugin return false; } - void CSimulatorXPlane::addRemoteAircraft(const Aviation::CAircraft &remoteAircraft, const Network::CClient &remoteClient) + void CSimulatorXPlane::addRemoteAircraft(const CSimulatedAircraft &remoteAircraft) { - Q_UNUSED(remoteClient); if (! isConnected()) { return; } // 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()); addAircraftSituation(remoteAircraft.getCallsign(), remoteAircraft.getSituation()); + m_remoteAircraft.replaceOrAdd(&CSimulatedAircraft::getCallsign, remoteAircraft.getCallsign(), remoteAircraft); } void CSimulatorXPlane::addAircraftSituation(const BlackMisc::Aviation::CCallsign &callsign, @@ -315,11 +329,18 @@ namespace BlackSimPlugin m_traffic->setPlaneTransponder(callsign.asString(), 2000, true, false); // TODO transponder } - void CSimulatorXPlane::removeRemoteAircraft(const BlackMisc::Aviation::CCallsign &callsign) + int CSimulatorXPlane::removeRemoteAircraft(const BlackMisc::Aviation::CCallsign &callsign) { - if (! isConnected()) { return; } + if (! isConnected()) { return 0; } m_traffic->removePlane(callsign.asString()); + return m_remoteAircraft.removeIf(&CSimulatedAircraft::getCallsign, callsign); } - } -} + int CSimulatorXPlane::changeRemoteAircraft(const CSimulatedAircraft &changedAircraft, const CPropertyIndexVariantMap &changedValues) + { + return m_remoteAircraft.incrementalUpdateOrAdd(changedAircraft, changedValues); + //! \todo really update aircraft in SIM + } + + } // namespace +} // namespace diff --git a/src/plugins/simulator/xplane/simulator_xplane.h b/src/plugins/simulator/xplane/simulator_xplane.h index 0e07e85c1..4b5257482 100644 --- a/src/plugins/simulator/xplane/simulator_xplane.h +++ b/src/plugins/simulator/xplane/simulator_xplane.h @@ -1,14 +1,19 @@ -/* Copyright (C) 2013 VATSIM Community / contributors - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +/* Copyright (C) 2013 + * 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 BLACKSIMPLUGIN_SIMULATOR_XPLANE_H #define BLACKSIMPLUGIN_SIMULATOR_XPLANE_H -//! \file - #include "blackcore/simulator.h" +#include "blackmisc/pixmap.h" #include class QDBusServiceWatcher; @@ -58,17 +63,23 @@ namespace BlackSimPlugin virtual bool disconnectFrom() override; //! \copydoc BlackCore::ISimulator::getOwnAircraft - virtual BlackMisc::Aviation::CAircraft getOwnAircraft() const override; + virtual BlackMisc::Simulation::CSimulatedAircraft getOwnAircraft() const override; //! \copydoc ISimulator::addRemoteAircraft() - virtual void addRemoteAircraft(const BlackMisc::Aviation::CAircraft &remoteAircraft, const BlackMisc::Network::CClient &remoteClient) override; + virtual void addRemoteAircraft(const BlackMisc::Simulation::CSimulatedAircraft &remoteAircraft) override; + + //! \copydoc BlackCore::ISimulator::getRemoteAircraft + virtual BlackMisc::Simulation::CSimulatedAircraftList getRemoteAircraft() const override { return m_remoteAircraft; } //! \copydoc BlackCore::ISimulator::addAircraftSituation virtual void addAircraftSituation(const BlackMisc::Aviation::CCallsign &callsign, const BlackMisc::Aviation::CAircraftSituation &situation) override; //! \copydoc BlackCore::ISimulator::removeRemoteAircraft - virtual void removeRemoteAircraft(const BlackMisc::Aviation::CCallsign &callsign) override; + virtual int removeRemoteAircraft(const BlackMisc::Aviation::CCallsign &callsign) override; + + //! \copydoc ISimulator::changeRemoteAircraft + virtual int changeRemoteAircraft(const BlackMisc::Simulation::CSimulatedAircraft &changedAircraft, const BlackMisc::CPropertyIndexVariantMap &changeValues) override; //! \copydoc BlackCore::ISimulator::updateOwnSimulatorCockpit virtual bool updateOwnSimulatorCockpit(const BlackMisc::Aviation::CAircraft &aircraft) override; @@ -83,13 +94,10 @@ namespace BlackSimPlugin virtual void displayTextMessage(const BlackMisc::Network::CTextMessage &message) const override; //! \copydoc BlackCore::ISimulator::getAircraftModel - virtual BlackMisc::Network::CAircraftModel getOwnAircraftModel() const override; + virtual BlackMisc::Simulation::CAircraftModel getOwnAircraftModel() const override; //! \copydoc BlackCore::ISimulator::getInstalledModels - virtual BlackMisc::Network::CAircraftModelList getInstalledModels() const override; - - //! \copydoc BlackCore::ISimulator::getCurrentlyMatchedModels - virtual BlackMisc::Network::CAircraftModelList getCurrentlyMatchedModels() const override { return BlackMisc::Network::CAircraftModelList(); } + virtual BlackMisc::Simulation::CAircraftModelList getInstalledModels() const override; //! Airports in range virtual BlackMisc::Aviation::CAirportList getAirportsInRange() const override; @@ -100,6 +108,9 @@ namespace BlackSimPlugin //! \copydoc ISimulator::getTimeSynchronizationOffset virtual BlackMisc::PhysicalQuantities::CTime getTimeSynchronizationOffset() const override { return BlackMisc::PhysicalQuantities::CTime(0, BlackMisc::PhysicalQuantities::CTimeUnit::hrmin()); } + //! \copydoc ISimulator::iconForModel + virtual BlackMisc::CPixmap iconForModel(const QString &modelString) const override; + private slots: void ps_serviceRegistered(const QString &serviceName); void ps_serviceUnregistered(); @@ -117,6 +128,7 @@ namespace BlackSimPlugin QTimer *m_slowTimer { nullptr }; BlackMisc::Aviation::CAirportList m_airports; + BlackMisc::Simulation::CSimulatedAircraftList m_remoteAircraft; struct // data is written by DBus async method callbacks {