mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-04-06 18:25:37 +08:00
* changed to CSimulatedAircraft / Simulation::CAircraftModel * added new functions such as icons for model
This commit is contained in:
@@ -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 <QTimer>
|
||||
@@ -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<CSimulatorFsx *>(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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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 <simconnect/SimConnect.h>
|
||||
#include <QObject>
|
||||
@@ -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<BlackMisc::Aviation::CCallsign, CSimConnectObject> m_simConnectObjects;
|
||||
QFutureWatcher<bool> m_watcherConnect;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user