[FS9] Let IDirectPlay8Client::Connect process request asynchronously

This commit is contained in:
Roland Rossgotterer
2019-12-21 10:24:55 +01:00
committed by Mat Sutcliffe
parent a6a787fdd7
commit b7c2775ea2
6 changed files with 69 additions and 41 deletions

View File

@@ -150,11 +150,23 @@ namespace BlackSimPlugin
}
break;
}
case DPN_MSGID_CONNECT_COMPLETE:
{
const PDPNMSG_CONNECT_COMPLETE connectCompleteMsg = static_cast<PDPNMSG_CONNECT_COMPLETE>(msgBuffer);
if (connectCompleteMsg->hResultCode == DPN_OK)
{
emit connectionComplete();
}
else
{
CLogMessage(this).warning(u"DirectPlay connection returned: %1") << connectCompleteMsg->hResultCode;
}
}
}
// Directx9 SDK: Unless otherwise noted, this function should return S_OK.
// http://doc.51windows.net/Directx9_SDK/play/ref/callbacks/pfndpnmessagehandler.htm
return S_OK;
return DPN_OK;
}
HRESULT CDirectPlayPeer::initDirectPlay()

View File

@@ -26,6 +26,9 @@ namespace BlackSimPlugin
{
namespace Fs9
{
HRESULT inline s_success_pending() { return DPNSUCCESS_PENDING; }
bool inline isPending(HRESULT hr) { return hr == s_success_pending(); }
//! DirectPlay peer implementation
//! More information can be found in the DirectX9 SDK documentation
//! http://doc.51windows.net/Directx9_SDK/?url=/Directx9_SDK/play/dplay.htm
@@ -49,6 +52,8 @@ namespace BlackSimPlugin
//! Log categories
static const BlackMisc::CLogCategoryList &getLogCategories();
public slots:
//! Send a custom DirectPlay message
HRESULT sendMessage(const QByteArray &data);
@@ -60,6 +65,9 @@ namespace BlackSimPlugin
//! Received custom FS9 packet
void customPacketReceived(const QByteArray &data);
//! Async operatione complete
void connectionComplete();
protected:
//! DirectPlay message handler
HRESULT directPlayMessageHandler(DWORD messageId, void *msgBuffer);

View File

@@ -32,16 +32,19 @@ namespace BlackSimPlugin
{
namespace Fs9
{
CFs9Client::CFs9Client(const CCallsign &callsign, const QString &modelName,
CFs9Client::CFs9Client(const CSimulatedAircraft &remoteAircraft,
const CTime &updateInterval,
CInterpolationLogger *logger, ISimulator *simulator) :
CDirectPlayPeer(simulator, callsign),
CDirectPlayPeer(simulator, remoteAircraft.getCallsign()),
m_remoteAircraft(remoteAircraft),
m_updateInterval(updateInterval),
m_interpolator(callsign, simulator, simulator, simulator->getRemoteAircraftProvider(), logger),
m_modelName(modelName)
m_interpolator(remoteAircraft.getCallsign(), simulator, simulator, simulator->getRemoteAircraftProvider(), logger),
m_modelName(remoteAircraft.getModelString())
{
m_interpolator.attachLogger(logger);
Q_ASSERT_X(this->simulator(), Q_FUNC_INFO, "Wrong owner, expect simulator object");
connect(this, &CFs9Client::connectionComplete, this, &CFs9Client::handleConnectionCompleted);
}
MPPositionVelocity aircraftSituationToFS9(const CAircraftSituation &oldSituation, const CAircraftSituation &newSituation, double updateInterval)
@@ -282,10 +285,8 @@ namespace BlackSimPlugin
m_player.dwDataSize = sizeof(PLAYER_INFO_STRUCT);
m_player.dwInfoFlags = DPNINFO_NAME | DPNINFO_DATA;
m_player.pwszName = wszPlayername.data();
if (isFailure(hr = m_directPlayPeer->SetPeerInfo(&m_player, nullptr, nullptr, DPNSETPEERINFO_SYNC)))
{
return logDirectPlayError(hr);
}
hr = m_directPlayPeer->SetPeerInfo(&m_player, nullptr, nullptr, DPNSETPEERINFO_SYNC);
if (isFailure(hr)) { return logDirectPlayError(hr); }
// Now set up the Application Description
DPN_APPLICATION_DESC dpAppDesc;
@@ -293,8 +294,8 @@ namespace BlackSimPlugin
dpAppDesc.dwSize = sizeof(DPN_APPLICATION_DESC);
dpAppDesc.guidApplication = CFs9Sdk::guid();
// We are now ready to host the app
if (isFailure(hr = m_directPlayPeer->Connect(&dpAppDesc, // AppDesc
DPNHANDLE asyncOpHandle;
hr = m_directPlayPeer->Connect(&dpAppDesc,
m_hostAddress,
m_deviceAddress,
nullptr,
@@ -302,21 +303,9 @@ namespace BlackSimPlugin
nullptr, 0,
nullptr,
nullptr,
nullptr,
DPNCONNECT_SYNC)))
{
return logDirectPlayError(hr);
}
CLogMessage(this).info(u"Callsign '%1' connected to session.") << m_callsign;
sendMultiplayerChangePlayerPlane();
sendMultiplayerPosition();
sendMultiplayerParamaters();
m_timerId = startTimer(m_updateInterval.valueInteger(CTimeUnit::ms()));
m_clientStatus = Connected;
emit statusChanged(m_callsign, m_clientStatus);
&asyncOpHandle,
0);
if (!isPending(hr) && isFailure(hr)) { return logDirectPlayError(hr); }
return hr;
}
@@ -332,7 +321,7 @@ namespace BlackSimPlugin
}
m_clientStatus = Disconnected;
emit statusChanged(m_callsign, m_clientStatus);
emit statusChanged(m_remoteAircraft, m_clientStatus);
return hr;
}
@@ -387,6 +376,18 @@ namespace BlackSimPlugin
sendMessage(message);
}
void CFs9Client::handleConnectionCompleted()
{
CLogMessage(this).info(u"Callsign '%1' connected to session.") << m_callsign;
sendMultiplayerChangePlayerPlane();
sendMultiplayerPosition();
sendMultiplayerParamaters();
m_timerId = startTimer(m_updateInterval.valueInteger(CTimeUnit::ms()));
m_clientStatus = Connected;
emit statusChanged(m_remoteAircraft, m_clientStatus);
}
const ISimulator *CFs9Client::simulator() const
{
return qobject_cast<const ISimulator *>(this->parent());

View File

@@ -38,8 +38,7 @@ namespace BlackSimPlugin
};
//! Constructor
CFs9Client(const BlackMisc::Aviation::CCallsign &callsign,
const QString &modelName,
CFs9Client(const BlackMisc::Simulation::CSimulatedAircraft &remoteAircraft,
const BlackMisc::PhysicalQuantities::CTime &updateInterval,
BlackMisc::Simulation::CInterpolationLogger *logger,
BlackCore::ISimulator *simulator);
@@ -69,7 +68,7 @@ namespace BlackSimPlugin
signals:
//! Client status changed
void statusChanged(const BlackMisc::Aviation::CCallsign &callsign, BlackSimPlugin::Fs9::CFs9Client::ClientStatus);
void statusChanged(const BlackMisc::Simulation::CSimulatedAircraft &remoteAircraft, BlackSimPlugin::Fs9::CFs9Client::ClientStatus);
protected:
//! \copydoc QObject::timerEvent
@@ -95,9 +94,12 @@ namespace BlackSimPlugin
void sendMultiplayerChangePlayerPlane();
//! @}
void handleConnectionCompleted();
//! Simulator interface
const BlackCore::ISimulator *simulator() const;
BlackMisc::Simulation::CSimulatedAircraft m_remoteAircraft;
BlackMisc::PhysicalQuantities::CTime m_updateInterval;
BlackMisc::Simulation::CInterpolatorMulti m_interpolator;
QString m_modelName;

View File

@@ -174,22 +174,13 @@ namespace BlackSimPlugin
this->physicallyRemoveRemoteAircraft(callsign);
}
bool rendered = true;
updateAircraftRendered(callsign, rendered);
CFs9Client *client = new CFs9Client(callsign, newRemoteAircraft.getModelString(), CTime(25, CTimeUnit::ms()), &m_interpolationLogger, this);
CFs9Client *client = new CFs9Client(newRemoteAircraft, CTime(25, CTimeUnit::ms()), &m_interpolationLogger, this);
client->setHostAddress(m_fs9Host->getHostAddress());
client->setPlayerUserId(m_fs9Host->getPlayerUserId());
connect(client, &CFs9Client::statusChanged, this, &CSimulatorFs9::updateRenderStatus);
client->start();
m_hashFs9Clients.insert(callsign, client);
const bool updated = updateAircraftRendered(callsign, rendered);
CSimulatedAircraft remoteAircraftCopy(newRemoteAircraft);
remoteAircraftCopy.setRendered(rendered);
if (updated)
{
emit aircraftRenderingChanged(remoteAircraftCopy);
}
CLogMessage(this).info(u"FS9: Added aircraft '%1'") << callsign.toQString();
return true;
}
@@ -428,6 +419,18 @@ namespace BlackSimPlugin
m_ownAircraftUpdateCycles++;
}
void CSimulatorFs9::updateRenderStatus(const CSimulatedAircraft &remoteAircraft, CFs9Client::ClientStatus)
{
const bool updated = updateAircraftRendered(remoteAircraft.getCallsign(), true);
CSimulatedAircraft remoteAircraftCopy(remoteAircraft);
remoteAircraftCopy.setRendered(true);
if (updated)
{
emit aircraftRenderingChanged(remoteAircraftCopy);
}
CLogMessage(this).info(u"FS9: Added aircraft '%1'") << remoteAircraft.getCallsignAsString();
}
void CSimulatorFs9::disconnectAllClients()
{
// Stop all FS9 client tasks

View File

@@ -98,6 +98,8 @@ namespace BlackSimPlugin
//! Called when data about our own aircraft are received
void updateOwnAircraftFromSimulator(const BlackMisc::Simulation::CSimulatedAircraft &ownAircraft);
void updateRenderStatus(const BlackMisc::Simulation::CSimulatedAircraft &remoteAircraft, BlackSimPlugin::Fs9::CFs9Client::ClientStatus);
//! Disconnect all clients
void disconnectAllClients();