refs #369, adjusted simulator drivers

* common base class BlackCore::CSimulatorCommon
* using providers IOwnAircraftProvider, IRenderedAircraftProvider
* using revers lookup in mapping
* using CSimulatedAircraft / CSimulatedAircraftList
* return values (success/failed) for member functions (e.g. setTimeSynchronization)
* getMaxRenderedAircraft / setMaxRenderedAircraft prepared
This commit is contained in:
Klaus Basan
2015-02-06 00:26:58 +01:00
parent f56a401505
commit 8c3547c33d
12 changed files with 347 additions and 215 deletions

View File

@@ -16,6 +16,7 @@
#include "multiplayer_packet_parser.h"
#include "blacksim/simulatorinfo.h"
#include "blackmisc/project.h"
#include "blackmisc/logmessage.h"
#include "blackmisc/propertyindexallclasses.h"
#include <QTimer>
#include <algorithm>
@@ -35,10 +36,13 @@ namespace BlackSimPlugin
{
namespace Fs9
{
BlackCore::ISimulator *CSimulatorFs9Factory::create(IOwnAircraftProvider *ownAircraft, QObject *parent)
BlackCore::ISimulator *CSimulatorFs9Factory::create(
IOwnAircraftProvider *ownAircraftProvider,
IRenderedAircraftProvider *renderedAircraftProvider,
QObject *parent)
{
registerMetadata();
return new Fs9::CSimulatorFs9(ownAircraft, parent);
return new Fs9::CSimulatorFs9(ownAircraftProvider, renderedAircraftProvider, parent);
}
BlackSim::CSimulatorInfo CSimulatorFs9Factory::getSimulatorInfo() const
@@ -46,10 +50,9 @@ namespace BlackSimPlugin
return CSimulatorInfo::FS9();
}
CSimulatorFs9::CSimulatorFs9(IOwnAircraftProvider *ownAircraft, QObject *parent) :
CSimulatorFsCommon(CSimulatorInfo::FS9(), ownAircraft, parent),
m_fs9Host(new CFs9Host(this)),
m_lobbyClient(new CLobbyClient(this))
CSimulatorFs9::CSimulatorFs9(IOwnAircraftProvider *ownAircraftProvider, IRenderedAircraftProvider *renderedAircraftProvider, QObject *parent) :
CSimulatorFsCommon(CSimulatorInfo::FS9(), ownAircraftProvider, renderedAircraftProvider, 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);
@@ -101,17 +104,25 @@ namespace BlackSimPlugin
return true;
}
void CSimulatorFs9::addRemoteAircraft(const CSimulatedAircraft &remoteAircraft)
bool CSimulatorFs9::addRemoteAircraft(const CSimulatedAircraft &remoteAircraft)
{
CCallsign callsign = remoteAircraft.getCallsign();
if (m_hashFs9Clients.contains(callsign))
{
// already exists, remove first
this->removeRenderedAircraft(callsign);
}
CFs9Client *client = new CFs9Client(this, callsign.toQString(), CTime(25, CTimeUnit::ms()));
client->setHostAddress(m_fs9Host->getHostAddress());
client->setPlayerUserId(m_fs9Host->getPlayerUserId());
client->start();
m_hashFs9Clients.insert(callsign, client);
m_remoteAircraft.replaceOrAdd(&CSimulatedAircraft::getCallsign, remoteAircraft.getCallsign(), remoteAircraft);
addAircraftSituation(callsign, remoteAircraft.getSituation());
renderedAircraft().applyIfCallsign(callsign, CPropertyIndexVariantMap(CSimulatedAircraft::IndexRendered, CVariant::fromValue(true)));
CLogMessage(this).info("FS9: Added aircraft %1") << callsign.toQString();
return true;
}
void CSimulatorFs9::addAircraftSituation(const CCallsign &callsign, const CAircraftSituation &situation)
@@ -125,20 +136,16 @@ namespace BlackSimPlugin
client->addAircraftSituation(situation);
}
int CSimulatorFs9::removeRemoteAircraft(const CCallsign &callsign)
bool CSimulatorFs9::removeRenderedAircraft(const CCallsign &callsign)
{
if (!m_hashFs9Clients.contains(callsign)) { return 0; }
if (!m_hashFs9Clients.contains(callsign)) { return false; }
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
renderedAircraft().applyIfCallsign(callsign, CPropertyIndexVariantMap(CSimulatedAircraft::IndexRendered, CVariant::fromValue(false)));
CLogMessage(this).info("FS9: Removed aircraft %1") << callsign.toQString();
return true;
}
bool CSimulatorFs9::updateOwnSimulatorCockpit(const CAircraft &ownAircraft, const QString &originator)
@@ -195,7 +202,9 @@ namespace BlackSimPlugin
if (message.getSeverity() != BlackMisc::CStatusMessage::SeverityDebug)
{
if (m_fs9Host)
{
QMetaObject::invokeMethod(m_fs9Host, "sendTextMessage", Q_ARG(QString, message.toQString()));
}
}
}
@@ -298,7 +307,7 @@ namespace BlackSimPlugin
// Stop all FS9 client tasks
for (auto fs9Client : m_hashFs9Clients.keys())
{
removeRemoteAircraft(fs9Client);
removeRenderedAircraft(fs9Client);
}
}
} // namespace

View File

@@ -36,12 +36,15 @@ namespace BlackSimPlugin
class CSimulatorFs9Factory : public QObject, public BlackCore::ISimulatorFactory
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "net.vatsim.PilotClient.BlackCore.SimulatorInterface")
Q_PLUGIN_METADATA(IID "org.swift.PilotClient.BlackCore.SimulatorInterface")
Q_INTERFACES(BlackCore::ISimulatorFactory)
public:
//! \copydoc BlackCore::ISimulatorFactory::create()
virtual BlackCore::ISimulator *create(BlackMisc::Simulation::IOwnAircraftProvider *ownAircraft, QObject *parent) override;
virtual BlackCore::ISimulator *create(
BlackMisc::Simulation::IOwnAircraftProvider *ownAircraftProvider,
BlackMisc::Simulation::IRenderedAircraftProvider *renderedAircraftProvider,
QObject *parent) override;
//! Simulator info
virtual BlackSim::CSimulatorInfo getSimulatorInfo() const override;
@@ -53,8 +56,11 @@ namespace BlackSimPlugin
Q_OBJECT
public:
//! Constructor
CSimulatorFs9(BlackMisc::Simulation::IOwnAircraftProvider *ownAircraft, QObject *parent);
//! Constructor, parameters as in \sa BlackCore::ISimulatorFactory::create
CSimulatorFs9(
BlackMisc::Simulation::IOwnAircraftProvider *ownAircraftProvider,
BlackMisc::Simulation::IRenderedAircraftProvider *renderedAircraft,
QObject *parent = nullptr);
//! Destructor
virtual ~CSimulatorFs9();
@@ -80,19 +86,13 @@ namespace BlackSimPlugin
virtual bool disconnectFrom() override;
//! \copydoc ISimulator::addRemoteAircraft()
virtual void addRemoteAircraft(const BlackMisc::Simulation::CSimulatedAircraft &remoteAircraft) override;
//! \copydoc BlackCore::ISimulator::getRemoteAircraft
virtual BlackMisc::Simulation::CSimulatedAircraftList getRemoteAircraft() const override { return m_remoteAircraft; }
virtual bool 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 int removeRemoteAircraft(const BlackMisc::Aviation::CCallsign &callsign) override;
//! \copydoc ISimulator::changeRemoteAircraft
virtual int changeRemoteAircraft(const BlackMisc::Simulation::CSimulatedAircraft &changedAircraft, const BlackMisc::CPropertyIndexVariantMap &changeValues) override;
virtual bool removeRenderedAircraft(const BlackMisc::Aviation::CCallsign &callsign) override;
//! \copydoc ISimulator::updateOwnSimulatorCockpit()
virtual bool updateOwnSimulatorCockpit(const BlackMisc::Aviation::CAircraft &ownAircraft, const QString &originator) override;

View File

@@ -26,9 +26,9 @@ namespace BlackSimPlugin
{
namespace FsCommon
{
CSimulatorFsCommon::CSimulatorFsCommon(const BlackSim::CSimulatorInfo &simInfo, BlackMisc::Simulation::IOwnAircraftProvider *ownAircraft, QObject *parent) :
ISimulator(parent), COwnAircraftProviderSupport(ownAircraft), m_simulatorInfo(simInfo), m_fsuipc(new FsCommon::CFsuipc())
CSimulatorFsCommon::CSimulatorFsCommon(const BlackSim::CSimulatorInfo &simInfo, BlackMisc::Simulation::IOwnAircraftProvider *ownAircraftProvider, IRenderedAircraftProvider *renderedAircraftProvider, QObject *parent) :
CSimulatorCommon(simInfo, ownAircraftProvider, renderedAircraftProvider, parent),
m_fsuipc(new FsCommon::CFsuipc())
{
// hack to init mapper
CAircraftMapper *mapper = mapperInstance();
@@ -60,28 +60,18 @@ namespace BlackSimPlugin
return m_syncTimeOffset;
}
void CSimulatorFsCommon::setTimeSynchronization(bool enable, BlackMisc::PhysicalQuantities::CTime offset)
bool CSimulatorFsCommon::setTimeSynchronization(bool enable, BlackMisc::PhysicalQuantities::CTime offset)
{
this->m_simTimeSynced = enable;
this->m_syncTimeOffset = offset;
}
BlackSim::CSimulatorInfo CSimulatorFsCommon::getSimulatorInfo() const
{
return this->m_simulatorInfo;
}
CSimulatedAircraftList CSimulatorFsCommon::getRemoteAircraft() const
{
return this->m_remoteAircraft;
return true;
}
CAirportList CSimulatorFsCommon::getAirportsInRange() const
{
return this->m_airportsInRange;
return m_airportsInRange;
}
void CSimulatorFsCommon::setOwnAircraftModel(const QString &modelName)
{
CAircraftModel model = ownAircraft().getModel();
@@ -95,21 +85,22 @@ namespace BlackSimPlugin
{
CAircraftModel newModel(model);
newModel.setModelType(CAircraftModel::TypeOwnSimulatorModel);
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());
}
}
CSimulatorFsCommon::reverseLookupIcaoData(newModel);
ownAircraft().setModel(newModel);
emit ownAircraftModelChanged(ownAircraft());
}
}
void CSimulatorFsCommon::reverseLookupIcaoData(CAircraftModel &model)
{
if (mapperInstance() && mapperInstance()->isInitialized())
{
// reverse lookup of ICAO
CAircraftIcao icao = mapperInstance()->getIcaoForModelString(model.getModelString());
icao.updateMissingParts(icao);
}
}
CAircraftMapper *CSimulatorFsCommon::mapperInstance()
{
static CAircraftMapper *mapper = new CAircraftMapper(
@@ -121,24 +112,26 @@ namespace BlackSimPlugin
CAircraftModel CSimulatorFsCommon::modelMatching(const CSimulatedAircraft &remoteAircraft)
{
// Manually set string?
if (remoteAircraft.getModel().hasManuallySetString())
{
// manual set model
return remoteAircraft.getModel();
}
//! \todo Model Matching before models are read
// default model
CAircraftModel aircraftModel(remoteAircraft); // set defaults
// Manually set string?
if (remoteAircraft.getModel().hasManuallySetString())
{
// manual set model, maybe update missing parts
aircraftModel.updateMissingParts(remoteAircraft.getModel());
CSimulatorFsCommon::reverseLookupIcaoData(aircraftModel);
return aircraftModel;
}
// mapper ready?
if (!mapperInstance()->isInitialized())
{
//! \todo Model Matching before models are read
// will be removed later, just for experimental version
aircraftModel.setModelString("Boeing 737-800 Paint1");
aircraftModel.setDescription("Model mapper not ready");
aircraftModel = CAircraftMapper::getDefaultModel();
aircraftModel.setCallsign(remoteAircraft.getCallsign());
CLogMessage(static_cast<CSimulatorFsCommon *>(nullptr)).warning("Mapper not ready, set to default model");
return aircraftModel;
}
@@ -174,9 +167,7 @@ namespace BlackSimPlugin
// default or sanity check
if (!aircraftModel.hasModelString())
{
aircraftModel.setModelString("Boeing 737-800 Paint1");
aircraftModel.setDescription("Default model");
aircraftModel.setModelType(CAircraftModel::TypeModelMatching);
aircraftModel = CAircraftMapper::getDefaultModel();
}
else
{
@@ -187,8 +178,8 @@ namespace BlackSimPlugin
Q_ASSERT_X(false, "modelMatching", m.toLocal8Bit().constData());
}
}
aircraftModel.setCallsign(remoteAircraft.getCallsign());
Q_ASSERT(!aircraftModel.getCallsign().isEmpty());
Q_ASSERT(aircraftModel.hasModelString());
Q_ASSERT(aircraftModel.getModelType() != CAircraftModel::TypeUnknown);
@@ -210,6 +201,12 @@ namespace BlackSimPlugin
return mapperInstance()->getAircraftCfgEntriesList().toAircraftModelList();
}
CAircraftIcao CSimulatorFsCommon::getIcaoForModelString(const QString &modelString) const
{
if (!mapperInstance()) { return CAircraftIcao(); }
return mapperInstance()->getIcaoForModelString(modelString);
}
CPixmap CSimulatorFsCommon::iconForModel(const QString &modelString) const
{
static const CPixmap empty;
@@ -241,7 +238,34 @@ namespace BlackSimPlugin
return empty;
}
int CSimulatorFsCommon::getMaxRenderedAircraft() const
{
return this->m_maxRenderedAircraft;
}
void CSimulatorFsCommon::setMaxRenderedAircraft(int maxRenderedAircraft)
{
this->m_maxRenderedAircraft = maxRenderedAircraft;
}
bool CSimulatorFsCommon::changeRenderedAircraftModel(const BlackMisc::Simulation::CSimulatedAircraft &aircraft, const QString &originator)
{
return this->changeAircraftEnabled(aircraft, originator);
}
bool CSimulatorFsCommon::changeAircraftEnabled(const CSimulatedAircraft &aircraft, const QString &originator)
{
if (originator == simulatorOriginator()) { return false; }
if (aircraft.isEnabled())
{
this->addRemoteAircraft(aircraft);
}
else
{
this->removeRenderedAircraft(aircraft.getCallsign());
}
return true;
}
} // namespace
} // namespace

View File

@@ -23,7 +23,7 @@ namespace BlackSimPlugin
namespace FsCommon
{
//! Common base class for MS flight simulators
class CSimulatorFsCommon : public BlackCore::ISimulator, public BlackMisc::Simulation::COwnAircraftProviderSupport
class CSimulatorFsCommon : public BlackCore::CSimulatorCommon
{
public:
//! Destructor
@@ -53,35 +53,46 @@ namespace BlackSimPlugin
virtual BlackMisc::PhysicalQuantities::CTime getTimeSynchronizationOffset() const override;
//! \copydoc ISimulator::setTimeSynchronization
virtual void setTimeSynchronization(bool enable, BlackMisc::PhysicalQuantities::CTime offset) override;
virtual bool setTimeSynchronization(bool enable, BlackMisc::PhysicalQuantities::CTime offset) override;
//! \copydoc ISimulator::getSimulatorInfo
virtual BlackSim::CSimulatorInfo getSimulatorInfo() const override;
//! \copydoc BlackCore::ISimulator::getRemoteAircraft
virtual BlackMisc::Simulation::CSimulatedAircraftList getRemoteAircraft() const override;
//! \copydoc ISimulator::getAirportsInRange
virtual BlackMisc::Aviation::CAirportList getAirportsInRange() const override;
//! \copydoc BlackCore::ISimulator::getAirportsInRange
virtual BlackMisc::Aviation::CAirportList getAirportsInRange() const;
//! \copydoc BlackCore::ISimulator::getInstalledModels
virtual BlackMisc::Simulation::CAircraftModelList getInstalledModels() const override;
//! \copydoc BlackCore::ISimulator::getIcaoForModelString
virtual BlackMisc::Aviation::CAircraftIcao getIcaoForModelString(const QString &modelString) const override;
//! \copydoc IContextSimulator::iconForModel
virtual BlackMisc::CPixmap iconForModel(const QString &modelString) const override;
//! \copydoc ISimulator::getMaxRenderedAircraft
virtual int getMaxRenderedAircraft() const override;
//! \copydoc ISimulator::setMaxRenderedAircraft
virtual void setMaxRenderedAircraft(int maxRenderedAircraft) override;
//! \copydoc ISimulator::changeRenderedAircraftModel
virtual bool changeRenderedAircraftModel(const BlackMisc::Simulation::CSimulatedAircraft &aircraft, const QString &originator) override;
//! \copydoc ISimulator::changeAircraftEnabled
virtual bool changeAircraftEnabled(const BlackMisc::Simulation::CSimulatedAircraft &aircraft, const QString &originator) override;
protected:
//! Constructor
CSimulatorFsCommon(const BlackSim::CSimulatorInfo &simInfo, BlackMisc::Simulation::IOwnAircraftProvider *ownAircraft, QObject *parent = nullptr);
CSimulatorFsCommon(
const BlackSim::CSimulatorInfo &simInfo,
BlackMisc::Simulation::IOwnAircraftProvider *ownAircraftProvider,
BlackMisc::Simulation::IRenderedAircraftProvider *renderedAircraftProvider,
QObject *parent = nullptr);
QString simulatorDetails; //!< describes version etc.
BlackSim::CSimulatorInfo m_simulatorInfo; //!< about the simulator
QScopedPointer<FsCommon::CFsuipc> m_fsuipc; //!< FSUIPC
bool m_simPaused = false; //!< Simulator paused?
bool m_simTimeSynced = false; //!< Time synchronized?
BlackMisc::PhysicalQuantities::CTime m_syncTimeOffset; //!< time offset
BlackMisc::Simulation::CSimulatedAircraftList m_remoteAircraft; //!< mapped models
BlackMisc::Aviation::CAirportList m_airportsInRange; //!< airports in range
BlackMisc::Aviation::CAirportList m_airportsInRange; //!< aiports in range of own aircraft
// cockpit as set in SIM
BlackMisc::Aviation::CComSystem m_simCom1; //!< cockpit COM1 state in simulator
@@ -91,9 +102,12 @@ namespace BlackSimPlugin
//! Set own model
void setOwnAircraftModel(const BlackMisc::Simulation::CAircraftModel &model);
//! Own aircraft has to be be changed
//! Set own model
void setOwnAircraftModel(const QString &modelName);
//! Reverse lookup
static void reverseLookupIcaoData(BlackMisc::Simulation::CAircraftModel &model);
//! Get the mapper singleton
static BlackSim::FsCommon::CAircraftMapper *mapperInstance();

View File

@@ -36,10 +36,11 @@ namespace BlackSimPlugin
{
namespace Fsx
{
CSimulatorFsx::CSimulatorFsx(IOwnAircraftProvider *ownAircraft, QObject *parent) :
CSimulatorFsCommon(CSimulatorInfo::FSX(), ownAircraft, parent)
CSimulatorFsx::CSimulatorFsx(IOwnAircraftProvider *ownAircraftProvider, IRenderedAircraftProvider *renderedAircraftProvider, QObject *parent) :
CSimulatorFsCommon(CSimulatorInfo::FSX(), ownAircraftProvider, renderedAircraftProvider, parent)
{
Q_ASSERT(ownAircraft);
Q_ASSERT(ownAircraftProvider);
Q_ASSERT(renderedAircraftProvider);
CFsxSimulatorSetup setup;
setup.init(); // this fetches important settings on local side
this->m_simulatorInfo.setSimulatorSetup(setup.getSettings());
@@ -131,13 +132,20 @@ namespace BlackSimPlugin
return connect;
}
void CSimulatorFsx::addRemoteAircraft(const Simulation::CSimulatedAircraft &remoteAircraft)
bool CSimulatorFsx::addRemoteAircraft(const Simulation::CSimulatedAircraft &remoteAircraft)
{
CCallsign callsign = remoteAircraft.getCallsign();
Q_ASSERT(!callsign.isEmpty());
if (callsign.isEmpty()) { return; }
if (callsign.isEmpty()) { return false; }
bool aircraftAlreadyExistsInSim = this->m_simConnectObjects.contains(callsign);
if (aircraftAlreadyExistsInSim)
{
// remove first
this->removeRenderedAircraft(callsign);
Q_ASSERT(false);
}
bool aircraftAlreadyExists = m_remoteAircraft.containsCallsign(callsign);
SIMCONNECT_DATA_INITPOSITION initialPosition = aircraftSituationToFsxInitPosition(remoteAircraft.getSituation());
initialPosition.Airspeed = 0;
initialPosition.OnGround = 0;
@@ -146,7 +154,6 @@ namespace BlackSimPlugin
simObj.setCallsign(callsign);
simObj.setRequestId(m_nextObjID);
simObj.setObjectId(0);
m_simConnectObjects.insert(callsign, simObj);
++m_nextObjID;
addAircraftSituation(callsign, remoteAircraft.getSituation());
@@ -154,22 +161,27 @@ namespace BlackSimPlugin
// matched models
CAircraftModel aircraftModel = modelMatching(remoteAircraft);
Q_ASSERT(remoteAircraft.getCallsign() == aircraftModel.getCallsign());
CSimulatedAircraft mappedRemoteAircraft(remoteAircraft);
mappedRemoteAircraft.setModel(aircraftModel);
m_remoteAircraft.replaceOrAdd(&CSimulatedAircraft::getCallsign, callsign, mappedRemoteAircraft);
emit modelMatchingCompleted(mappedRemoteAircraft);
providerUpdateAircraftModel(remoteAircraft.getCallsign(), aircraftModel, simulatorOriginator());
CSimulatedAircraft aircraftAfterModelApplied = renderedAircraft().findFirstByCallsign(remoteAircraft.getCallsign());
emit modelMatchingCompleted(aircraftAfterModelApplied);
// create AI
//! \todo isConnected() or isSimulating() ??
if (isConnected())
if (isSimulating())
{
//! \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"); }
}
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"); }
m_simConnectObjects.insert(callsign, simObj);
renderedAircraft().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)));
CLogMessage(this).warning("FSX: Not connected, not added aircraft %1") << callsign.toQString();
return false;
}
}
@@ -183,38 +195,10 @@ namespace BlackSimPlugin
m_simConnectObjects.insert(callsign, simObj);
}
int CSimulatorFsx::removeRemoteAircraft(const CCallsign &callsign)
bool CSimulatorFsx::removeRenderedAircraft(const CCallsign &callsign)
{
removeRemoteAircraft(m_simConnectObjects.value(callsign));
return m_remoteAircraft.removeIf(&CSimulatedAircraft::getCallsign, callsign);
}
int CSimulatorFsx::changeRemoteAircraft(const CSimulatedAircraft &toChangeAircraft, const CPropertyIndexVariantMap &changedValues)
{
// EXPERIMENTAL VERSION
const CCallsign callsign = toChangeAircraft.getCallsign();
int c = m_remoteAircraft.incrementalUpdateOrAdd(toChangeAircraft, changedValues);
if (c == 0) { return 0; } // nothing was changed
const CSimulatedAircraft aircraftAfterChanges = m_remoteAircraft.findFirstByCallsign(callsign);
const QString modelBefore = toChangeAircraft.getModel().getModelString();
const QString modelAfter = aircraftAfterChanges.getModel().getModelString();
if (modelBefore != modelAfter)
{
// model did change
removeRemoteAircraft(m_simConnectObjects.value(callsign));
}
if (toChangeAircraft.isEnabled() && !m_simConnectObjects.contains(callsign))
{
addRemoteAircraft(aircraftAfterChanges);
}
else if (!aircraftAfterChanges.isEnabled())
{
removeRemoteAircraft(m_simConnectObjects.value(callsign));
}
// apply other changes
return c;
// only remove from sim
return removeRenderedAircraft(m_simConnectObjects.value(callsign));
}
bool CSimulatorFsx::updateOwnSimulatorCockpit(const CAircraft &ownAircraft, const QString &originator)
@@ -511,10 +495,13 @@ namespace BlackSimPlugin
}
}
void CSimulatorFsx::removeRemoteAircraft(const CSimConnectObject &simObject)
bool CSimulatorFsx::removeRenderedAircraft(const CSimConnectObject &simObject)
{
SimConnect_AIRemoveObject(m_hSimConnect, simObject.getObjectId(), simObject.getRequestId());
m_simConnectObjects.remove(simObject.getCallsign());
renderedAircraft().applyIfCallsign(simObject.getCallsign(), CPropertyIndexVariantMap(CSimulatedAircraft::IndexRendered, CVariant::fromValue(false)));
CLogMessage(this).info("FSX: Removed aircraft %1") << simObject.getCallsign().toQString();
return true;
}
HRESULT CSimulatorFsx::initEvents()

View File

@@ -71,8 +71,11 @@ namespace BlackSimPlugin
Q_OBJECT
public:
//! Constructor
CSimulatorFsx(BlackMisc::Simulation::IOwnAircraftProvider *ownAircraft, QObject *parent = nullptr);
//! Constructor, parameters as in \sa BlackCore::ISimulatorFactory::create
CSimulatorFsx(
BlackMisc::Simulation::IOwnAircraftProvider *ownAircraftProvider,
BlackMisc::Simulation::IRenderedAircraftProvider *renderedAircraftProvider,
QObject *parent = nullptr);
//! Destructor
virtual ~CSimulatorFsx();
@@ -101,16 +104,13 @@ namespace BlackSimPlugin
virtual bool disconnectFrom() override;
//! \copydoc ISimulator::addRemoteAircraft()
virtual void addRemoteAircraft(const BlackMisc::Simulation::CSimulatedAircraft &remoteAircraft) override;
virtual bool 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 int removeRemoteAircraft(const BlackMisc::Aviation::CCallsign &callsign) override;
//! \copydoc ISimulator::changeRemoteAircraft
virtual int changeRemoteAircraft(const BlackMisc::Simulation::CSimulatedAircraft &toChangeAircraft, const BlackMisc::CPropertyIndexVariantMap &changeValues) override;
//! \copydoc ISimulator::removeRenderedAircraft()
virtual bool removeRenderedAircraft(const BlackMisc::Aviation::CCallsign &callsign) override;
//! \copydoc ISimulator::updateOwnCockpit
virtual bool updateOwnSimulatorCockpit(const BlackMisc::Aviation::CAircraft &ownAircraft, const QString &originator) override;
@@ -157,7 +157,7 @@ namespace BlackSimPlugin
private:
//! Remove a remote aircraft
void removeRemoteAircraft(const CSimConnectObject &simObject);
bool removeRenderedAircraft(const CSimConnectObject &simObject);
//! Init when connected
HRESULT initWhenConnected();
@@ -186,7 +186,7 @@ namespace BlackSimPlugin
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; //!< Time offset (if synchronized)
BlackMisc::PhysicalQuantities::CTime m_syncTimeOffset; //!< Time offset (if synchronized)
QHash<BlackMisc::Aviation::CCallsign, CSimConnectObject> m_simConnectObjects;
QFutureWatcher<bool> m_watcherConnect;
};

View File

@@ -21,10 +21,10 @@ namespace BlackSimPlugin
{
namespace Fsx
{
BlackCore::ISimulator *CSimulatorFsxFactory::create(BlackMisc::Simulation::IOwnAircraftProvider *ownAircraft, QObject *parent)
BlackCore::ISimulator *CSimulatorFsxFactory::create(BlackMisc::Simulation::IOwnAircraftProvider *ownAircraftProvider, BlackMisc::Simulation::IRenderedAircraftProvider *renderedAircraftProvider, QObject *parent)
{
Q_ASSERT(ownAircraft);
return new CSimulatorFsx(ownAircraft, parent);
Q_ASSERT(ownAircraftProvider);
return new CSimulatorFsx(ownAircraftProvider, renderedAircraftProvider, parent);
}
CSimulatorInfo CSimulatorFsxFactory::getSimulatorInfo() const

View File

@@ -28,12 +28,15 @@ namespace BlackSimPlugin
{
Q_OBJECT
// TODO: @RW, move this string into CProject please
Q_PLUGIN_METADATA(IID "net.vatsim.PilotClient.BlackCore.SimulatorInterface")
Q_PLUGIN_METADATA(IID "org.swift.PilotClient.BlackCore.SimulatorInterface")
Q_INTERFACES(BlackCore::ISimulatorFactory)
public:
//! \copydoc BlackCore::ISimulatorFactory::create
virtual BlackCore::ISimulator *create(BlackMisc::Simulation::IOwnAircraftProvider *ownAircraft, QObject *parent) override;
virtual BlackCore::ISimulator *create(
BlackMisc::Simulation::IOwnAircraftProvider *ownAircraftProvider,
BlackMisc::Simulation::IRenderedAircraftProvider *renderedAircraftProvider,
QObject *parent) override;
//! \copydoc BlackCore::ISimulatorFactory::getSimulatorInfo
virtual BlackSim::CSimulatorInfo getSimulatorInfo() const override;

View File

@@ -21,14 +21,15 @@ using namespace BlackMisc::Network;
using namespace BlackMisc::PhysicalQuantities;
using namespace BlackMisc::Simulation;
using namespace BlackMisc::Geo;
using namespace BlackSim;
namespace BlackSimPlugin
{
namespace XPlane
{
CSimulatorXPlane::CSimulatorXPlane(IOwnAircraftProvider *ownAircraft, QObject *parent) :
BlackCore::ISimulator(parent), COwnAircraftProviderSupport(ownAircraft)
CSimulatorXPlane::CSimulatorXPlane(IOwnAircraftProvider *ownAircraftProvider, IRenderedAircraftProvider *renderedAircraftProvider, QObject *parent) :
CSimulatorCommon(CSimulatorInfo::XP(), ownAircraftProvider, renderedAircraftProvider, parent)
{
m_watcher = new QDBusServiceWatcher(this);
m_watcher->setWatchMode(QDBusServiceWatcher::WatchForRegistration | QDBusServiceWatcher::WatchForUnregistration);
@@ -234,7 +235,7 @@ namespace BlackSimPlugin
void CSimulatorXPlane::ps_setAirportsInRange(const QStringList &icaos, const QStringList &names, const BlackMisc::CSequence<double> &lats, const BlackMisc::CSequence<double> &lons, const BlackMisc::CSequence<double> &alts)
{
qDebug() << alts;
m_airports.clear();
m_airportsInRange.clear();
auto icaoIt = icaos.begin();
auto nameIt = names.begin();
auto latIt = lats.begin();
@@ -245,26 +246,27 @@ namespace BlackSimPlugin
using namespace BlackMisc::PhysicalQuantities;
using namespace BlackMisc::Geo;
m_airports.push_back({ *icaoIt, { CLatitude(*latIt, CAngleUnit::deg()), CLongitude(*lonIt, CAngleUnit::deg()), CLength(*altIt, CLengthUnit::ft()) }, *nameIt });
m_airportsInRange.push_back({ *icaoIt, { CLatitude(*latIt, CAngleUnit::deg()), CLongitude(*lonIt, CAngleUnit::deg()), CLength(*altIt, CLengthUnit::ft()) }, *nameIt });
}
using namespace BlackMisc::Math;
}
BlackMisc::Aviation::CAirportList CSimulatorXPlane::getAirportsInRange() const
{
auto copy = m_airports;
auto copy = m_airportsInRange;
//! \todo Check if units match, xPlaneData has now hints what the values are
copy.sortByRange(CCoordinateGeodetic(m_xplaneData.latitude, m_xplaneData.longitude, 0), true);
copy.truncate(20);
return copy;
}
void CSimulatorXPlane::setTimeSynchronization(bool enable, BlackMisc::PhysicalQuantities::CTime)
bool CSimulatorXPlane::setTimeSynchronization(bool enable, BlackMisc::PhysicalQuantities::CTime)
{
if (enable)
{
CLogMessage(this).warning("X-Plane already provides real time synchronization");
}
return false;
}
CPixmap CSimulatorXPlane::iconForModel(const QString &modelString) const
@@ -301,15 +303,19 @@ namespace BlackSimPlugin
return false;
}
void CSimulatorXPlane::addRemoteAircraft(const CSimulatedAircraft &remoteAircraft)
bool CSimulatorXPlane::addRemoteAircraft(const CSimulatedAircraft &remoteAircraft)
{
if (! isConnected()) { return; }
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());
addAircraftSituation(remoteAircraft.getCallsign(), remoteAircraft.getSituation());
m_remoteAircraft.replaceOrAdd(&CSimulatedAircraft::getCallsign, remoteAircraft.getCallsign(), remoteAircraft);
renderedAircraft().applyIfCallsign(remoteAircraft.getCallsign(), CPropertyIndexVariantMap(CSimulatedAircraft::IndexRendered, CVariant::fromValue(true)));
CLogMessage(this).info("XP: Added aircraft %1") << remoteAircraft.getCallsign().toQString();
return true;
}
void CSimulatorXPlane::addAircraftSituation(const BlackMisc::Aviation::CCallsign &callsign,
@@ -328,22 +334,43 @@ namespace BlackSimPlugin
m_traffic->setPlaneTransponder(callsign.asString(), 2000, true, false); // TODO transponder
}
int CSimulatorXPlane::removeRemoteAircraft(const BlackMisc::Aviation::CCallsign &callsign)
bool CSimulatorXPlane::removeRenderedAircraft(const BlackMisc::Aviation::CCallsign &callsign)
{
if (! isConnected()) { return 0; }
if (! isConnected()) { return false; }
m_traffic->removePlane(callsign.asString());
return m_remoteAircraft.removeIf(&CSimulatedAircraft::getCallsign, callsign);
renderedAircraft().applyIfCallsign(callsign, CPropertyIndexVariantMap(CSimulatedAircraft::IndexRendered, CVariant::fromValue(false)));
CLogMessage(this).info("XP: Removed aircraft %1") << callsign.toQString();
return true;
}
int CSimulatorXPlane::changeRemoteAircraft(const CSimulatedAircraft &changedAircraft, const CPropertyIndexVariantMap &changedValues)
bool CSimulatorXPlane::changeRenderedAircraftModel(const CSimulatedAircraft &aircraft, const QString &originator)
{
return m_remoteAircraft.incrementalUpdateOrAdd(changedAircraft, changedValues);
//! \todo really update aircraft in SIM
return this->changeAircraftEnabled(aircraft, originator);
}
BlackCore::ISimulator *CSimulatorXPlaneFactory::create(IOwnAircraftProvider *ownAircraft, QObject *parent)
CAircraftIcao CSimulatorXPlane::getIcaoForModelString(const QString &modelString) const
{
return new CSimulatorXPlane(ownAircraft, parent);
Q_UNUSED(modelString);
return CAircraftIcao();
}
bool CSimulatorXPlane::changeAircraftEnabled(const CSimulatedAircraft &aircraft, const QString &originator)
{
if (originator == simulatorOriginator()) { return false; }
if (aircraft.isEnabled())
{
this->addRemoteAircraft(aircraft);
}
else
{
this->removeRenderedAircraft(aircraft.getCallsign());
}
return true;
}
BlackCore::ISimulator *CSimulatorXPlaneFactory::create(IOwnAircraftProvider *ownAircraftProvider, IRenderedAircraftProvider *renderedAircraftProvider, QObject *parent)
{
return new CSimulatorXPlane(ownAircraftProvider, renderedAircraftProvider, parent);
}
} // namespace

View File

@@ -23,20 +23,22 @@ namespace BlackSimPlugin
{
namespace XPlane
{
class CXBusServiceProxy;
class CXBusTrafficProxy;
/*!
* X-Plane ISimulator implementation
*/
class CSimulatorXPlane : public BlackCore::ISimulator, BlackMisc::Simulation::COwnAircraftProviderSupport
class CSimulatorXPlane : public BlackCore::CSimulatorCommon
{
Q_OBJECT
public:
//! Constructor
CSimulatorXPlane(BlackMisc::Simulation::IOwnAircraftProvider *ownAircraft, QObject *parent = nullptr);
//! Constructor, parameters as in \sa BlackCore::ISimulatorFactory::create
CSimulatorXPlane(
BlackMisc::Simulation::IOwnAircraftProvider *ownAircraftProvider,
BlackMisc::Simulation::IRenderedAircraftProvider *renderedAircraft,
QObject *parent = nullptr);
//! \copydoc BlackCore::ISimulator::isConnected
virtual bool isConnected() const override;
@@ -53,6 +55,9 @@ namespace BlackSimPlugin
//! \copydoc ISimulator::isSimulating
virtual bool isSimulating() const override { return isConnected(); }
//! \copydoc BlackCore::ISimulator::getIcaoForModelString
virtual BlackMisc::Aviation::CAircraftIcao getIcaoForModelString(const QString &modelString) const override;
public slots:
//! \copydoc BlackCore::ISimulator::connectTo
virtual bool connectTo() override;
@@ -64,27 +69,24 @@ namespace BlackSimPlugin
virtual bool disconnectFrom() override;
//! \copydoc ISimulator::addRemoteAircraft()
virtual void addRemoteAircraft(const BlackMisc::Simulation::CSimulatedAircraft &remoteAircraft) override;
//! \copydoc BlackCore::ISimulator::getRemoteAircraft
virtual BlackMisc::Simulation::CSimulatedAircraftList getRemoteAircraft() const override { return m_remoteAircraft; }
virtual bool addRemoteAircraft(const BlackMisc::Simulation::CSimulatedAircraft &remoteAircraft) override;
//! \copydoc BlackCore::ISimulator::addAircraftSituation
virtual void addAircraftSituation(const BlackMisc::Aviation::CCallsign &callsign,
const BlackMisc::Aviation::CAircraftSituation &situation) override;
//! \copydoc BlackCore::ISimulator::removeRemoteAircraft
virtual int removeRemoteAircraft(const BlackMisc::Aviation::CCallsign &callsign) override;
virtual bool removeRenderedAircraft(const BlackMisc::Aviation::CCallsign &callsign) override;
//! \copydoc ISimulator::changeRemoteAircraft
virtual int changeRemoteAircraft(const BlackMisc::Simulation::CSimulatedAircraft &changedAircraft, const BlackMisc::CPropertyIndexVariantMap &changeValues) override;
//! \copydoc ISimulator::changeRenderedAircraftModel
virtual bool changeRenderedAircraftModel(const BlackMisc::Simulation::CSimulatedAircraft &aircraft, const QString &originator) override;
//! \copydoc ISimulator::changeAircraftEnabled
virtual bool changeAircraftEnabled(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;
//! \copydoc BlackCore::ISimulator::getSimulatorInfo
virtual BlackSim::CSimulatorInfo getSimulatorInfo() const override { return BlackSim::CSimulatorInfo::XP(); }
//! \copydoc BlackCore::ISimulator::displayStatusMessage
virtual void displayStatusMessage(const BlackMisc::CStatusMessage &message) const override;
@@ -94,11 +96,11 @@ namespace BlackSimPlugin
//! \copydoc BlackCore::ISimulator::getInstalledModels
virtual BlackMisc::Simulation::CAircraftModelList getInstalledModels() const override;
//! Airports in range
virtual BlackMisc::Aviation::CAirportList getAirportsInRange() const override;
//! \copydoc BlackCore::ISimulator::getAirportsInRange
virtual BlackMisc::Aviation::CAirportList getAirportsInRange() const;
//! \copydoc ISimulator::setTimeSynchronization
virtual void setTimeSynchronization(bool enable, BlackMisc::PhysicalQuantities::CTime offset) override;
virtual bool setTimeSynchronization(bool enable, BlackMisc::PhysicalQuantities::CTime offset) override;
//! \copydoc ISimulator::getTimeSynchronizationOffset
virtual BlackMisc::PhysicalQuantities::CTime getTimeSynchronizationOffset() const override { return BlackMisc::PhysicalQuantities::CTime(0, BlackMisc::PhysicalQuantities::CTimeUnit::hrmin()); }
@@ -121,10 +123,7 @@ namespace BlackSimPlugin
CXBusTrafficProxy *m_traffic { nullptr };
QTimer *m_fastTimer { nullptr };
QTimer *m_slowTimer { nullptr };
BlackMisc::Aviation::CAirportList m_airports;
BlackMisc::Simulation::CSimulatedAircraftList m_remoteAircraft;
BlackMisc::Aviation::CAirportList m_airportsInRange; //!< aiports in range of own aircraft
BlackMisc::Simulation::CSimulatedAircraft xplaneDataToSimulatedAircraft() const;
//! \todo Add units to members? pitchDeg?, altitudeFt?
@@ -158,12 +157,15 @@ namespace BlackSimPlugin
class CSimulatorXPlaneFactory : public QObject, public BlackCore::ISimulatorFactory
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "net.vatsim.PilotClient.BlackCore.SimulatorInterface")
Q_PLUGIN_METADATA(IID "org.swift.PilotClient.BlackCore.SimulatorInterface")
Q_INTERFACES(BlackCore::ISimulatorFactory)
public:
//! \copydoc BlackCore::ISimulatorFactory::create
virtual BlackCore::ISimulator *create(BlackMisc::Simulation::IOwnAircraftProvider *ownAircraft, QObject *parent = nullptr) override;
//! \copydoc BlackCore::ISimulatorFactory::create()
virtual BlackCore::ISimulator *create(
BlackMisc::Simulation::IOwnAircraftProvider *ownAircraftProvider,
BlackMisc::Simulation::IRenderedAircraftProvider *renderedAircraftProvider,
QObject *parent) override;
//! \copydoc BlackCore::ISimulatorFactory::getSimulatorInfo
virtual BlackSim::CSimulatorInfo getSimulatorInfo() const override { return BlackSim::CSimulatorInfo::XP(); }