Make FS9 works with ISimulatorListener

* The FS9 host is started in the Listener
* When FS9 starts up, it is called via the lobby to join the multiplayer
* Some minor changes in CContextSimulator
This commit is contained in:
Michał Garapich
2015-03-08 22:58:42 +01:00
committed by Roland Winklmeier
parent edc0646ab2
commit 570f4aa4ea
9 changed files with 196 additions and 125 deletions

View File

@@ -60,7 +60,7 @@ namespace BlackCore
if (factory) if (factory)
{ {
driver.factory = factory; driver.factory = factory;
CLogMessage(this).info("Loaded plugin: %1") << factory->getSimulatorInfo().toQString(); CLogMessage(this).debug() << "Loaded plugin: " << plugin->info.toQString();
} }
} else { } else {
QString errorMsg = loader.errorString().append(" ").append("Also check if required dll/libs of plugin exists"); QString errorMsg = loader.errorString().append(" ").append("Also check if required dll/libs of plugin exists");
@@ -342,14 +342,14 @@ namespace BlackCore
asyncConnectToSimulator(); asyncConnectToSimulator();
// info about what is going on // info about what is going on
CLogMessage(this).info("Simulator plugin loaded: '%1'") << this->m_simulator->getSimulatorInfo().toQString(true); CLogMessage(this).info("Simulator plugin loaded: %1") << this->m_simulator->getSimulatorInfo().toQString(true);
return true; return true;
} }
bool CContextSimulator::loadSimulatorPluginFromSettings() bool CContextSimulator::loadSimulatorPluginFromSettings()
{ {
Q_ASSERT(this->getIContextSettings()); Q_ASSERT(this->getIContextSettings());
if (!this->getIContextSettings()) { return false; } if (!this->getIContextSettings()) return false; // TODO assert or if?
// TODO warnings if we didn't load the plugin which the settings asked for // TODO warnings if we didn't load the plugin which the settings asked for
@@ -409,7 +409,7 @@ namespace BlackCore
ISimulatorListener *listener = m_simulatorDrivers[simulatorInfo].listener; ISimulatorListener *listener = m_simulatorDrivers[simulatorInfo].listener;
Q_ASSERT(listener); Q_ASSERT(listener);
listener->start(); listener->start();
CLogMessage(this).info("Listening for simulator: '%1'") << simulatorInfo.toQString(true); CLogMessage(this).debug() << "Listening for simulator:" << simulatorInfo.toQString(true);
} }
@@ -433,19 +433,25 @@ namespace BlackCore
void CContextSimulator::unloadSimulatorPlugin() void CContextSimulator::unloadSimulatorPlugin()
{ {
if (this->m_simulator) if (m_simulator) {
{
// depending on shutdown order, network might already have been deleted // depending on shutdown order, network might already have been deleted
IContextNetwork *networkContext = this->getIContextNetwork(); IContextNetwork *networkContext = this->getIContextNetwork();
Q_ASSERT(networkContext); Q_ASSERT(networkContext);
Q_ASSERT(networkContext->isLocalObject()); Q_ASSERT(networkContext->isLocalObject());
Q_UNUSED(networkContext); Q_UNUSED(networkContext);
this->m_simulator->disconnect(); // disconnect all simulator signals Q_ASSERT(m_simulator->simulator);
QObject::disconnect(this, nullptr, this->m_simulator, nullptr); // disconnect receiver simulator
this->m_simulator->disconnectFrom(); // disconnect from simulator m_simulator->simulator->disconnect();
this->m_simulator->deleteLater(); CLogHandler::instance()->disconnect(m_simulator->simulator);
this->disconnect(m_simulator->simulator);
if (m_simulator->simulator->isConnected())
m_simulator->simulator->disconnectFrom(); // disconnect from simulator
m_simulator->simulator->deleteLater();
m_simulator->simulator = nullptr;
m_simulator = nullptr;
} }
this->m_simulator = nullptr;
} }
void CContextSimulator::ps_addRemoteAircraft(const CSimulatedAircraft &remoteAircraft) void CContextSimulator::ps_addRemoteAircraft(const CSimulatedAircraft &remoteAircraft)
@@ -479,6 +485,7 @@ namespace BlackCore
void CContextSimulator::ps_textMessagesReceived(const Network::CTextMessageList &textMessages) void CContextSimulator::ps_textMessagesReceived(const Network::CTextMessageList &textMessages)
{ {
Q_ASSERT(this->m_simulator); // TODO Assert or if?
if (!this->m_simulator) { return; } if (!this->m_simulator) { return; }
foreach(CTextMessage tm, textMessages) foreach(CTextMessage tm, textMessages)
{ {
@@ -511,7 +518,7 @@ namespace BlackCore
void CContextSimulator::ps_updateSimulatorCockpitFromContext(const CAircraft &ownAircraft, const QString &originator) void CContextSimulator::ps_updateSimulatorCockpitFromContext(const CAircraft &ownAircraft, const QString &originator)
{ {
Q_ASSERT(this->m_simulator); Q_ASSERT(this->m_simulator); // TODO Assert or if?
if (!this->m_simulator) { return; } if (!this->m_simulator) { return; }
// avoid loops // avoid loops
@@ -583,7 +590,7 @@ namespace BlackCore
void CContextSimulator::ps_simulatorStarted(CSimulatorInfo simulatorInfo) void CContextSimulator::ps_simulatorStarted(CSimulatorInfo simulatorInfo)
{ {
CLogMessage(this).info("Simulator %1 started.") << simulatorInfo.toQString(); CLogMessage(this).debug() << simulatorInfo.toQString() << "started";
stopSimulatorListeners(); stopSimulatorListeners();
loadSimulatorPlugin(simulatorInfo); loadSimulatorPlugin(simulatorInfo);
} }
@@ -605,15 +612,19 @@ namespace BlackCore
continue; continue;
} }
CLogMessage(this).info("Try to load plugin: %1") << fileName; CLogMessage(this).debug() << "Try to load plugin: " << fileName;
QString pluginPath = m_pluginsDir.absoluteFilePath(fileName); QString pluginPath = m_pluginsDir.absoluteFilePath(fileName);
QPluginLoader loader(pluginPath); QPluginLoader loader(pluginPath);
QJsonObject json = loader.metaData(); QJsonObject json = loader.metaData();
CSimulatorInfo simulatorInfo(json); CSimulatorInfo simulatorInfo(json);
if (!simulatorInfo.isUnspecified()) { if (!simulatorInfo.isUnspecified())
{
m_simulatorDrivers.insert(simulatorInfo, { nullptr, nullptr, pluginPath} ); m_simulatorDrivers.insert(simulatorInfo, { nullptr, nullptr, pluginPath} );
CLogMessage(this).info("Found simulator driver: %1") << simulatorInfo.toQString(); CLogMessage(this).debug() << "Found simulator driver: " << simulatorInfo.toQString();
} else { }
else
{
CLogMessage(this).warning("Simulator driver in %1 is invalid") << pluginPath; CLogMessage(this).warning("Simulator driver in %1 is invalid") << pluginPath;
} }
} }

View File

@@ -291,8 +291,14 @@ namespace BlackSimPlugin
DPNSEND_SYNC | DPNSEND_NOLOOPBACK))) DPNSEND_SYNC | DPNSEND_NOLOOPBACK)))
{ {
CLogMessage(this).warning("DirectPlay: Failed to send message!"); CLogMessage(this).warning("DirectPlay: Failed to send message!");
qDebug() << message;
} }
return hr; return hr;
} }
void CDirectPlayPeer::reset()
{
m_playerUser = 0;
}
} }
} }

View File

@@ -48,6 +48,8 @@ namespace BlackSimPlugin
//! Send a custom DirectPlay message //! Send a custom DirectPlay message
HRESULT sendMessage(const QByteArray &data); HRESULT sendMessage(const QByteArray &data);
void reset();
signals: signals:
//! Received custom FS9 packet //! Received custom FS9 packet
void customPacketReceived(const QByteArray &data); void customPacketReceived(const QByteArray &data);

View File

@@ -72,6 +72,7 @@ namespace BlackSimPlugin
MultiPlayerPacketParser::writeType(message, CFs9Sdk::MPCHAT_PACKET_ID_CHAT_TEXT_SEND); MultiPlayerPacketParser::writeType(message, CFs9Sdk::MPCHAT_PACKET_ID_CHAT_TEXT_SEND);
MultiPlayerPacketParser::writeSize(message, mpChatText.chat_data.size() + 1); MultiPlayerPacketParser::writeSize(message, mpChatText.chat_data.size() + 1);
message = MultiPlayerPacketParser::writeMessage(message, mpChatText); message = MultiPlayerPacketParser::writeMessage(message, mpChatText);
qDebug() << "Message:" << textMessage;
sendMessage(message); sendMessage(message);
} }
@@ -87,7 +88,6 @@ namespace BlackSimPlugin
stopHosting(); stopHosting();
} }
HRESULT CFs9Host::startHosting(const QString &session, const QString &callsign) HRESULT CFs9Host::startHosting(const QString &session, const QString &callsign)
{ {
HRESULT hr = S_OK; HRESULT hr = S_OK;

View File

@@ -92,9 +92,6 @@ namespace BlackSimPlugin
GUID pAppGuid = CFs9Sdk::guid(); GUID pAppGuid = CFs9Sdk::guid();
// Set to true in order to automatically launch FS9. Perfect for testing.
bool bLaunchNotFound = false;
// Setup the DPL_CONNECT_INFO struct // Setup the DPL_CONNECT_INFO struct
DPL_CONNECT_INFO dnConnectInfo; DPL_CONNECT_INFO dnConnectInfo;
ZeroMemory(&dnConnectInfo, sizeof(DPL_CONNECT_INFO)); ZeroMemory(&dnConnectInfo, sizeof(DPL_CONNECT_INFO));
@@ -102,7 +99,6 @@ namespace BlackSimPlugin
dnConnectInfo.pvLobbyConnectData = nullptr; dnConnectInfo.pvLobbyConnectData = nullptr;
dnConnectInfo.dwLobbyConnectDataSize = 0; dnConnectInfo.dwLobbyConnectDataSize = 0;
dnConnectInfo.dwFlags = 0; dnConnectInfo.dwFlags = 0;
if (bLaunchNotFound) dnConnectInfo.dwFlags |= DPLCONNECT_LAUNCHNOTFOUND;
dnConnectInfo.guidApplication = pAppGuid; dnConnectInfo.guidApplication = pAppGuid;
if (FAILED(hr = allocAndInitConnectSettings(address, &pAppGuid, &dnConnectInfo.pdplConnectionSettings))) if (FAILED(hr = allocAndInitConnectSettings(address, &pAppGuid, &dnConnectInfo.pdplConnectionSettings)))
@@ -113,21 +109,18 @@ namespace BlackSimPlugin
&m_applicationHandle, &m_applicationHandle,
INFINITE, INFINITE,
0); 0);
if (FAILED(hr)) if (FAILED(hr)) {
{ return hr == DPNERR_NOCONNECTION ? S_FALSE : printDirectPlayError(hr);
if (hr == DPNERR_NOCONNECTION && !bLaunchNotFound) } else {
qWarning() << "There were no waiting application.";
else
return printDirectPlayError(hr);
}
else
{
qDebug() << "Connected!"; qDebug() << "Connected!";
freeConnectSettings(dnConnectInfo.pdplConnectionSettings);
return S_OK;
}
} }
freeConnectSettings(dnConnectInfo.pdplConnectionSettings); void CLobbyClient::cleanup()
{
return S_OK;
} }
HRESULT CLobbyClient::allocAndInitConnectSettings(const QString &address, GUID *pAppGuid, DPL_CONNECTION_SETTINGS **ppdplConnectSettings) HRESULT CLobbyClient::allocAndInitConnectSettings(const QString &address, GUID *pAppGuid, DPL_CONNECTION_SETTINGS **ppdplConnectSettings)
@@ -247,7 +240,9 @@ namespace BlackSimPlugin
{ {
PDPL_MESSAGE_DISCONNECT pDisconnectMsg; PDPL_MESSAGE_DISCONNECT pDisconnectMsg;
pDisconnectMsg = (PDPL_MESSAGE_DISCONNECT)msgBuffer; pDisconnectMsg = (PDPL_MESSAGE_DISCONNECT)msgBuffer;
Q_UNUSED(pDisconnectMsg) Q_UNUSED(pDisconnectMsg);
emit disconnected();
// We should free any data associated with the // We should free any data associated with the
// app here, but there is none. // app here, but there is none.

View File

@@ -13,6 +13,10 @@ namespace BlackSimPlugin
{ {
Q_OBJECT Q_OBJECT
signals:
//! Emitted when FS9 is closed
void disconnected();
public: public:
//! Constructor //! Constructor
@@ -27,6 +31,9 @@ namespace BlackSimPlugin
//! Connect FS9 simulator to our host //! Connect FS9 simulator to our host
HRESULT connectFs9ToHost(const QString address); HRESULT connectFs9ToHost(const QString address);
//! Cleanup & be ready to another connection
void cleanup();
private: private:
//! Alloc and fill up a DPL_CONNECTION_SETTINGS. Call FreeConnectSettings later to free it. //! Alloc and fill up a DPL_CONNECTION_SETTINGS. Call FreeConnectSettings later to free it.

View File

@@ -16,6 +16,7 @@
#include "multiplayer_packet_parser.h" #include "multiplayer_packet_parser.h"
#include "blackcore/interpolator_linear.h" #include "blackcore/interpolator_linear.h"
#include "blacksim/simulatorinfo.h" #include "blacksim/simulatorinfo.h"
#include "blackmisc/logmessage.h"
#include "blackmisc/project.h" #include "blackmisc/project.h"
#include "blackmisc/logmessage.h" #include "blackmisc/logmessage.h"
#include "blackmisc/propertyindexallclasses.h" #include "blackmisc/propertyindexallclasses.h"
@@ -37,36 +38,49 @@ namespace BlackSimPlugin
{ {
namespace Fs9 namespace Fs9
{ {
CSimulatorFs9Factory::CSimulatorFs9Factory(QObject *parent) :
QObject(parent),
m_fs9Host(new CFs9Host(this), [](CFs9Host* host){
host->quit();
host->deleteLater();
}),
m_lobbyClient(new CLobbyClient(this))
{
registerMetadata();
}
BlackCore::ISimulator *CSimulatorFs9Factory::create( BlackCore::ISimulator *CSimulatorFs9Factory::create(
IOwnAircraftProvider *ownAircraftProvider, IOwnAircraftProvider *ownAircraftProvider,
IRemoteAircraftProvider *remoteAircraftProvider, IRemoteAircraftProvider *remoteAircraftProvider,
QObject *parent) QObject *parent)
{ {
registerMetadata();
return new Fs9::CSimulatorFs9(ownAircraftProvider, remoteAircraftProvider, parent); return new Fs9::CSimulatorFs9(ownAircraftProvider, remoteAircraftProvider, parent);
} }
BlackCore::ISimulatorListener *CSimulatorFs9Factory::createListener(QObject *parent)
{
return new CSimulatorFs9Listener(m_fs9Host, m_lobbyClient, parent);
}
BlackSim::CSimulatorInfo CSimulatorFs9Factory::getSimulatorInfo() const BlackSim::CSimulatorInfo CSimulatorFs9Factory::getSimulatorInfo() const
{ {
return CSimulatorInfo::FS9(); return CSimulatorInfo::FS9();
} }
CSimulatorFs9::CSimulatorFs9(IOwnAircraftProvider *ownAircraftProvider, IRemoteAircraftProvider *remoteAircraftProvider, QObject *parent) : CSimulatorFs9::CSimulatorFs9(IOwnAircraftProvider *ownAircraftProvider,
IRemoteAircraftProvider *remoteAircraftProvider,
const QSharedPointer<CFs9Host> &fs9Host,
const QSharedPointer<CLobbyClient> &lobbyClient, QObject *parent) :
CSimulatorFsCommon(CSimulatorInfo::FS9(), ownAircraftProvider, remoteAircraftProvider, parent), CSimulatorFsCommon(CSimulatorInfo::FS9(), ownAircraftProvider, remoteAircraftProvider, parent),
m_fs9Host(new CFs9Host(this)), m_lobbyClient(new CLobbyClient(this)) m_fs9Host(new CFs9Host(this)),
m_lobbyClient(new CLobbyClient(this))
{ {
connect(m_lobbyClient.data(), &CLobbyClient::disconnected, this, std::bind(&CSimulatorFs9::simulatorStatusChanged, this, 0));
connect(m_fs9Host.data(), &CFs9Host::customPacketReceived, this, &CSimulatorFs9::ps_processFs9Message); connect(m_fs9Host.data(), &CFs9Host::customPacketReceived, this, &CSimulatorFs9::ps_processFs9Message);
connect(m_fs9Host.data(), &CFs9Host::statusChanged, this, &CSimulatorFs9::ps_changeHostStatus);
m_fs9Host->start();
this->m_interpolator = new BlackCore::CInterpolatorLinear(remoteAircraftProvider, this); this->m_interpolator = new BlackCore::CInterpolatorLinear(remoteAircraftProvider, this);
this->m_interpolator->start(); this->m_interpolator->start();
} }
CSimulatorFs9::~CSimulatorFs9()
{
Q_ASSERT(!m_isHosting);
}
bool CSimulatorFs9::isConnected() const bool CSimulatorFs9::isConnected() const
{ {
return m_fs9Host->isConnected(); return m_fs9Host->isConnected();
@@ -74,19 +88,11 @@ namespace BlackSimPlugin
bool CSimulatorFs9::connectTo() bool CSimulatorFs9::connectTo()
{ {
Q_ASSERT(m_fsuipc); Q_ASSERT(m_fs9Host->isConnected());
if (m_useFsuipc) { m_fsuipc->connect(); } // connect FSUIPC too m_fsuipc->connect(); // connect FSUIPC too
startTimer(50);
emitSimulatorCombinedStatus();
// If we are already hosting, connect FS0 through lobby connection
if (m_isHosting)
{
m_lobbyClient->connectFs9ToHost(m_fs9Host->getHostAddress());
}
// If not, deferre connection until host is setup
else
{
m_startedLobbyConnection = true;
}
return true; return true;
} }
@@ -99,11 +105,7 @@ namespace BlackSimPlugin
bool CSimulatorFs9::disconnectFrom() bool CSimulatorFs9::disconnectFrom()
{ {
disconnectAllClients(); disconnectAllClients();
m_fsuipc->disconnect();
emit connectionStatusChanged(ISimulator::Disconnected);
if (m_fs9Host) { m_fs9Host->quit(); }
CSimulatorFsCommon::disconnectFrom();
m_isHosting = false;
return true; return true;
} }
@@ -199,12 +201,13 @@ namespace BlackSimPlugin
void CSimulatorFs9::displayStatusMessage(const BlackMisc::CStatusMessage &message) const void CSimulatorFs9::displayStatusMessage(const BlackMisc::CStatusMessage &message) const
{ {
/* Avoid errors from CDirectPlayPeer as it may end in infinite loop */
if (message.getSeverity() == BlackMisc::CStatusMessage::SeverityError && message.isFromClass<CDirectPlayPeer>())
return;
if (message.getSeverity() != BlackMisc::CStatusMessage::SeverityDebug) if (message.getSeverity() != BlackMisc::CStatusMessage::SeverityDebug)
{ {
if (m_fs9Host) QMetaObject::invokeMethod(m_fs9Host.data(), "sendTextMessage", Q_ARG(QString, message.toQString()));
{
QMetaObject::invokeMethod(m_fs9Host, "sendTextMessage", Q_ARG(QString, message.toQString()));
}
} }
} }
@@ -272,34 +275,7 @@ namespace BlackSimPlugin
} }
} }
void CSimulatorFs9::ps_changeHostStatus(BlackSimPlugin::Fs9::CFs9Host::HostStatus status) void CSimulatorFs9::updateOwnAircraftFromSim(const CAircraft &ownAircraft)
{
switch (status)
{
case CFs9Host::Hosting:
{
m_isHosting = true;
startTimer(50);
emit connectionStatusChanged(Connected);
if (m_startedLobbyConnection)
{
m_lobbyClient->connectFs9ToHost(m_fs9Host->getHostAddress());
m_startedLobbyConnection = false;
}
break;
}
case CFs9Host::Terminated:
{
m_isHosting = false;
emit connectionStatusChanged(Disconnected);
break;
}
default:
break;
}
}
void CSimulatorFs9::updateOwnAircraftFromSimulator(const CAircraft &simDataOwnAircraft)
{ {
this->providerUpdateCockpit( this->providerUpdateCockpit(
simDataOwnAircraft.getCom1System(), simDataOwnAircraft.getCom1System(),
@@ -316,5 +292,48 @@ namespace BlackSimPlugin
removeRemoteAircraft(fs9Client); removeRemoteAircraft(fs9Client);
} }
} }
} // namespace
} // namespace CSimulatorFs9Listener::CSimulatorFs9Listener(const QSharedPointer<CFs9Host> &fs9Host,
const QSharedPointer<CLobbyClient> &lobbyClient,
QObject *parent) :
BlackCore::ISimulatorListener(parent),
m_timer(new QTimer(this)),
m_fs9Host(fs9Host),
m_lobbyClient(lobbyClient)
{
Q_CONSTEXPR int QueryInterval = 5 * 1000; // 5 seconds
m_timer->setInterval(QueryInterval);
connect(m_timer, &QTimer::timeout, [this]()
{
if (m_fs9Host->getHostAddress().isEmpty()) // host not yet set up
return;
if (m_lobbyConnected || m_lobbyClient->connectFs9ToHost(m_fs9Host->getHostAddress()) == S_OK) {
m_lobbyConnected = true;
CLogMessage(this).info("Swift is joining FS9 to the multiplayer session...");
}
if (m_lobbyConnected && m_fs9Host->isConnected()) {
emit simulatorStarted(m_simulatorInfo);
m_lobbyConnected = false;
}
});
m_fs9Host->start();
// After FS9 is disconnected, reset its data stored in the host
connect(m_lobbyClient.data(), &CLobbyClient::disconnected, m_fs9Host.data(), &CFs9Host::reset);
}
void CSimulatorFs9Listener::start()
{
m_timer->start();
}
void CSimulatorFs9Listener::stop()
{
m_timer->stop();
}
}
}

View File

@@ -32,24 +32,6 @@ namespace BlackSimPlugin
{ {
namespace Fs9 namespace Fs9
{ {
//! Factory implementation to create CSimulatorFs9 instances
class CSimulatorFs9Factory : public QObject, public BlackCore::ISimulatorFactory
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.swift.pilotclient.BlackCore.SimulatorInterface" FILE "simulator_fs9.json")
Q_INTERFACES(BlackCore::ISimulatorFactory)
public:
//! \copydoc BlackCore::ISimulatorFactory::create(ownAircraftProvider, remoteAircraftProvider, parent)
virtual BlackCore::ISimulator *create(
BlackMisc::Simulation::IOwnAircraftProvider *ownAircraftProvider,
BlackMisc::Simulation::IRemoteAircraftProvider *remoteAircraftProvider,
QObject *parent) override;
//! Simulator info
virtual BlackSim::CSimulatorInfo getSimulatorInfo() const override;
};
//! FSX Simulator Implementation //! FSX Simulator Implementation
class CSimulatorFs9 : public BlackSimPlugin::FsCommon::CSimulatorFsCommon class CSimulatorFs9 : public BlackSimPlugin::FsCommon::CSimulatorFsCommon
{ {
@@ -63,7 +45,7 @@ namespace BlackSimPlugin
QObject *parent = nullptr); QObject *parent = nullptr);
//! Destructor //! Destructor
virtual ~CSimulatorFs9(); virtual ~CSimulatorFs9() = default;
//! \copydoc ISimulator::isConnected() //! \copydoc ISimulator::isConnected()
virtual bool isConnected() const override; virtual bool isConnected() const override;
@@ -116,9 +98,6 @@ namespace BlackSimPlugin
//! Process incoming FS9 message //! Process incoming FS9 message
void ps_processFs9Message(const QByteArray &message); void ps_processFs9Message(const QByteArray &message);
//! Change DirectPlay host status
void ps_changeHostStatus(BlackSimPlugin::Fs9::CFs9Host::HostStatus status);
private: private:
//! Called when data about our own aircraft are received //! Called when data about our own aircraft are received
@@ -126,14 +105,63 @@ namespace BlackSimPlugin
void disconnectAllClients(); void disconnectAllClients();
// DirectPlay object handling QSharedPointer<CFs9Host> m_fs9Host;
QPointer<CFs9Host> m_fs9Host;
bool m_isHosting = false; //!< Is sim connected?
bool m_startedLobbyConnection = false;
QHash<BlackMisc::Aviation::CCallsign, QPointer<CFs9Client>> m_hashFs9Clients; QHash<BlackMisc::Aviation::CCallsign, QPointer<CFs9Client>> m_hashFs9Clients;
CLobbyClient *m_lobbyClient; QSharedPointer<CLobbyClient> m_lobbyClient;
}; };
} // namespace
} // namespace //! Listener for FS9
//! Listener starts the FS9 multiplayer host and tries to make the running instance
//! of simulator to connect to it. When emitting the simulatorStarted() signal,
//! FS9 is already connected.
class CSimulatorFs9Listener : public BlackCore::ISimulatorListener {
Q_OBJECT
public:
//! Constructor
CSimulatorFs9Listener(const QSharedPointer<CFs9Host> &fs9Host, const QSharedPointer<CLobbyClient> &lobbyClient, QObject* parent);
//! \copydoc BlackCore::ISimulatorListener::start
virtual void start() override;
//! \copydoc BlackCore::ISimulatorListener::stop
virtual void stop() override;
private:
QTimer* m_timer = nullptr;
QSharedPointer<CFs9Host> m_fs9Host;
QSharedPointer<CLobbyClient> m_lobbyClient;
bool m_lobbyConnected = false;
const BlackSim::CSimulatorInfo m_simulatorInfo = BlackSim::CSimulatorInfo::FS9();
};
//! Factory implementation to create CSimulatorFs9 instances
class CSimulatorFs9Factory : public QObject, public BlackCore::ISimulatorFactory
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.swift.pilotclient.BlackCore.SimulatorInterface" FILE "simulator_fs9.json")
Q_INTERFACES(BlackCore::ISimulatorFactory)
public:
CSimulatorFs9Factory(QObject* parent = nullptr);
//! \copydoc BlackCore::ISimulatorFactory::create()
virtual BlackCore::ISimulator *create(QObject *parent) override;
//! Simulator info
virtual BlackSim::CSimulatorInfo getSimulatorInfo() const override;
//! \copydoc BlackCore::ISimulatorFactory::getListener
virtual BlackCore::ISimulatorListener *createListener(QObject *parent = nullptr) override;
private:
QSharedPointer<CFs9Host> m_fs9Host;
QSharedPointer<CLobbyClient> m_lobbyClient;
};
} // namespace Fs9
} // namespace BlackCore
#endif // guard #endif // guard

View File

@@ -54,6 +54,9 @@ namespace BlackSimPlugin
//! //!
bool read(BlackMisc::Simulation::CSimulatedAircraft &aircraft, bool cockpit, bool situation, bool aircraftParts); bool read(BlackMisc::Simulation::CSimulatedAircraft &aircraft, bool cockpit, bool situation, bool aircraftParts);
//! Find out whether we can connect to FSUIPC or not
static bool canConnect();
//! Error messages //! Error messages
static const QStringList &errorMessages() static const QStringList &errorMessages()
{ {