mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-03-31 21:15:33 +08:00
Ref T730, Ref T739 update from own aircraft in one step
* update all values from own aircraft in "one step" * rational: avoid "single property" updates and numerous round trips (signals, transceiver updates) * also allow updates of not yet connect, as "a kind of preset" * do NOT send to network if not authenticated
This commit is contained in:
committed by
Mat Sutcliffe
parent
caa78395a9
commit
ef9e7b0bf1
@@ -51,9 +51,9 @@ namespace BlackCore
|
||||
connect(m_input, &CInput::opusDataAvailable, this, &CAfvClient::opusDataAvailable);
|
||||
connect(m_input, &CInput::inputVolumeStream, this, &CAfvClient::inputVolumeStream);
|
||||
|
||||
connect(m_output, &Output::outputVolumeStream, this, &CAfvClient::outputVolumeStream);
|
||||
connect(m_output, &Output::outputVolumeStream, this, &CAfvClient::outputVolumeStream);
|
||||
connect(m_connection, &CClientConnection::audioReceived, this, &CAfvClient::audioOutDataAvailable);
|
||||
connect(m_voiceServerPositionTimer, &QTimer::timeout, this, &CAfvClient::onPositionUpdateTimer);
|
||||
connect(m_voiceServerPositionTimer, &QTimer::timeout, this, &CAfvClient::onPositionUpdateTimer);
|
||||
|
||||
// deferred init
|
||||
QTimer::singleShot(1000, this, &CAfvClient::deferredInit);
|
||||
@@ -87,11 +87,9 @@ namespace BlackCore
|
||||
|
||||
// init with context values
|
||||
this->connectWithContexts();
|
||||
if (m_connectedWithContext && hasContext())
|
||||
{
|
||||
// update from context
|
||||
this->updateTransceivers();
|
||||
}
|
||||
|
||||
// update from context
|
||||
this->onPositionUpdateTimer();
|
||||
}
|
||||
|
||||
void CAfvClient::connectWithContexts()
|
||||
@@ -119,12 +117,12 @@ namespace BlackCore
|
||||
this->setCallsign(callsign);
|
||||
|
||||
m_connection->connectTo(cid, password, callsign);
|
||||
this->updateTransceivers(); // uses context if available
|
||||
m_aliasedStations = m_connection->getAllAliasedStations();
|
||||
|
||||
this->onPositionUpdateTimer();
|
||||
|
||||
if (m_connection->isConnected()) { emit this->connectionStatusChanged(Connected); }
|
||||
else { emit this->connectionStatusChanged(Disconnected); }
|
||||
|
||||
m_aliasedStations = m_connection->getAllAliasedStations();
|
||||
}
|
||||
|
||||
void CAfvClient::disconnectFrom()
|
||||
@@ -221,6 +219,8 @@ namespace BlackCore
|
||||
this->onSettingsChanged(); // make sure all settings are applied
|
||||
m_isStarted = true;
|
||||
CLogMessage(this).info(u"Started [Input: %1] [Output: %2]") << inputDevice.getName() << outputDevice.getName();
|
||||
|
||||
this->onPositionUpdateTimer(); // update values
|
||||
}
|
||||
|
||||
void CAfvClient::startAudio(const QString &inputDeviceName, const QString &outputDeviceName)
|
||||
@@ -249,13 +249,6 @@ namespace BlackCore
|
||||
m_isStarted = false;
|
||||
m_connection->setReceiveAudio(false);
|
||||
|
||||
// transceivers
|
||||
{
|
||||
QMutexLocker lock(&m_mutexTransceivers);
|
||||
m_transceivers.clear();
|
||||
}
|
||||
this->updateTransceivers(false);
|
||||
|
||||
// stop input/output
|
||||
m_updateTimer.stop();
|
||||
m_input->stop();
|
||||
@@ -304,19 +297,7 @@ namespace BlackCore
|
||||
|
||||
// Fix rounding issues like 128074999 Hz -> 128075000 Hz
|
||||
quint32 roundedFrequencyHz = static_cast<quint32>(qRound(frequencyHz / 1000.0)) * 1000;
|
||||
{
|
||||
QMutexLocker lock(&m_mutex);
|
||||
auto it = std::find_if(m_aliasedStations.begin(), m_aliasedStations.end(), [roundedFrequencyHz](const StationDto & d)
|
||||
{
|
||||
return d.frequencyAliasHz == roundedFrequencyHz;
|
||||
});
|
||||
|
||||
if (it != m_aliasedStations.end())
|
||||
{
|
||||
CLogMessage(this).debug(u"Aliasing %1Hz [VHF] to %2Hz [HF]") << frequencyHz << it->frequencyHz;
|
||||
roundedFrequencyHz = it->frequencyHz;
|
||||
}
|
||||
}
|
||||
roundedFrequencyHz = this->getAliasFrequencyHz(roundedFrequencyHz);
|
||||
|
||||
bool updateTransceivers = false;
|
||||
{
|
||||
@@ -363,7 +344,8 @@ namespace BlackCore
|
||||
|
||||
void CAfvClient::updateTransceivers(bool updateFrequencies)
|
||||
{
|
||||
if (!m_connection->isConnected()) { return; }
|
||||
// also update if NOT connected, values will be preset
|
||||
|
||||
if (hasContext())
|
||||
{
|
||||
const CSimulatedAircraft ownAircraft = sApp->getIContextOwnAircraft()->getOwnAircraft();
|
||||
@@ -400,7 +382,7 @@ namespace BlackCore
|
||||
|
||||
void CAfvClient::setTransmittingTransceiver(quint16 transceiverID)
|
||||
{
|
||||
TxTransceiverDto tx = { transceiverID };
|
||||
const TxTransceiverDto tx = { transceiverID };
|
||||
this->setTransmittingTransceivers({ tx });
|
||||
}
|
||||
|
||||
@@ -475,7 +457,7 @@ namespace BlackCore
|
||||
|
||||
if (!active)
|
||||
{
|
||||
//AGC
|
||||
// AGC
|
||||
// if (maxDbReadingInPTTInterval > -1) InputVolumeDb = InputVolumeDb - 1;
|
||||
// if (maxDbReadingInPTTInterval < -4) InputVolumeDb = InputVolumeDb + 1;
|
||||
m_maxDbReadingInPTTInterval = -100;
|
||||
@@ -485,6 +467,12 @@ namespace BlackCore
|
||||
emit this->ptt(active, com, this->identifier());
|
||||
}
|
||||
|
||||
double CAfvClient::getInputVolumeDb() const
|
||||
{
|
||||
QMutexLocker lock(&m_mutex);
|
||||
return m_inputVolumeDb;
|
||||
}
|
||||
|
||||
void CAfvClient::setInputVolumeDb(double valueDb)
|
||||
{
|
||||
if (valueDb > MaxDbIn) { valueDb = MaxDbIn; }
|
||||
@@ -498,6 +486,12 @@ namespace BlackCore
|
||||
}
|
||||
}
|
||||
|
||||
double CAfvClient::getOutputVolumeDb() const
|
||||
{
|
||||
QMutexLocker lock(&m_mutex);
|
||||
return m_outputVolumeDb;
|
||||
}
|
||||
|
||||
int CAfvClient::getNormalizedInputVolume() const
|
||||
{
|
||||
const double db = this->getInputVolumeDb();
|
||||
@@ -635,26 +629,20 @@ namespace BlackCore
|
||||
QString CAfvClient::getReceivingCallsignsCom1()
|
||||
{
|
||||
QMutexLocker lock(&m_mutex);
|
||||
if (m_soundcardSampleProvider)
|
||||
{
|
||||
return m_soundcardSampleProvider->getReceivingCallsigns(0);
|
||||
}
|
||||
return {};
|
||||
if (!m_soundcardSampleProvider) return {};
|
||||
return m_soundcardSampleProvider->getReceivingCallsigns(0);
|
||||
}
|
||||
|
||||
QString CAfvClient::getReceivingCallsignsCom2()
|
||||
{
|
||||
QMutexLocker lock(&m_mutex);
|
||||
if (m_soundcardSampleProvider)
|
||||
{
|
||||
return m_soundcardSampleProvider->getReceivingCallsigns(1);
|
||||
}
|
||||
return {};
|
||||
if (!m_soundcardSampleProvider) return {};
|
||||
return m_soundcardSampleProvider->getReceivingCallsigns(1);
|
||||
}
|
||||
|
||||
bool CAfvClient::updateVoiceServerUrl(const QString &url)
|
||||
{
|
||||
if (m_connection) { return false; }
|
||||
if (!m_connection) { return false; }
|
||||
return m_connection->updateVoiceServerUrl(url);
|
||||
}
|
||||
|
||||
@@ -665,7 +653,16 @@ namespace BlackCore
|
||||
|
||||
void CAfvClient::onPositionUpdateTimer()
|
||||
{
|
||||
this->updateTransceivers();
|
||||
if (hasContext())
|
||||
{
|
||||
// for pilot client
|
||||
this->updateFromOwnAircraft(sApp->getIContextOwnAircraft()->getOwnAircraft(), false);
|
||||
}
|
||||
else
|
||||
{
|
||||
// for AFV sample client
|
||||
this->updateTransceivers();
|
||||
}
|
||||
}
|
||||
|
||||
void CAfvClient::onSettingsChanged()
|
||||
@@ -676,38 +673,101 @@ namespace BlackCore
|
||||
this->setBypassEffects(!audioSettings.isAudioEffectsEnabled());
|
||||
}
|
||||
|
||||
void CAfvClient::onUpdateTransceiversFromContext(const CSimulatedAircraft &aircraft, const CIdentifier &originator)
|
||||
void CAfvClient::updateFromOwnAircraft(const CSimulatedAircraft &aircraft, bool withSignals)
|
||||
{
|
||||
Q_UNUSED(originator)
|
||||
this->updatePosition(aircraft.latitude().value(CAngleUnit::deg()),
|
||||
aircraft.longitude().value(CAngleUnit::deg()),
|
||||
aircraft.getAltitude().value(CLengthUnit::ft()));
|
||||
if (!sApp || sApp->isShuttingDown()) { return; }
|
||||
|
||||
TransceiverDto transceiverCom1;
|
||||
TransceiverDto transceiverCom2;
|
||||
transceiverCom1.id = comUnitToTransceiverId(CComSystem::Com1);
|
||||
transceiverCom2.id = comUnitToTransceiverId(CComSystem::Com2);
|
||||
|
||||
// position
|
||||
const double latDeg = aircraft.latitude().value(CAngleUnit::deg());
|
||||
const double lngDeg = aircraft.longitude().value(CAngleUnit::deg());
|
||||
const double altM = aircraft.getAltitude().value(CLengthUnit::m());
|
||||
|
||||
transceiverCom1.LatDeg = transceiverCom2.LatDeg = latDeg;
|
||||
transceiverCom1.LonDeg = transceiverCom2.LonDeg = lngDeg;
|
||||
transceiverCom1.HeightAglM = transceiverCom2.HeightAglM = altM;
|
||||
transceiverCom1.HeightMslM = transceiverCom2.HeightMslM = altM;
|
||||
|
||||
// enabled, rx/tx, frequency
|
||||
const CComSystem com1 = aircraft.getCom1System();
|
||||
const CComSystem com2 = aircraft.getCom2System();
|
||||
this->updateComFrequency(CComSystem::Com1, com1);
|
||||
this->updateComFrequency(CComSystem::Com2, com2);
|
||||
const quint32 f1 = static_cast<quint32>(com1.getFrequencyActive().valueInteger(CFrequencyUnit::Hz()));
|
||||
const quint32 f2 = static_cast<quint32>(com2.getFrequencyActive().valueInteger(CFrequencyUnit::Hz()));
|
||||
|
||||
transceiverCom1.frequencyHz = this->getAliasFrequencyHz(f1);
|
||||
transceiverCom2.frequencyHz = this->getAliasFrequencyHz(f2);
|
||||
|
||||
const bool tx1 = com1.isTransmitEnabled();
|
||||
const bool rx1 = com1.isReceiveEnabled();
|
||||
const bool tx2 = com2.isTransmitEnabled();
|
||||
const bool tx2 = com2.isTransmitEnabled(); // we only allow one (1) transmit
|
||||
const bool rx2 = com2.isReceiveEnabled();
|
||||
|
||||
this->enableComUnit(CComSystem::Com1, tx1 || rx1);
|
||||
this->enableComUnit(CComSystem::Com2, tx2 || rx2);
|
||||
// enable, we currently treat receive as enable
|
||||
// flight sim cockpits normally use rx and tx
|
||||
// AFV uses tx and enable
|
||||
const bool e1 = rx1;
|
||||
const bool e2 = rx2;
|
||||
|
||||
// currently only transmitting at one unit
|
||||
if (tx1)
|
||||
// transceivers
|
||||
QSet<quint16> newEnabledTransceiverIds;
|
||||
QVector<TransceiverDto> newTransceivers { transceiverCom1, transceiverCom2 };
|
||||
QVector<TransceiverDto> newEnabledTransceivers;
|
||||
QVector<TxTransceiverDto> newTransmittingTransceivers;
|
||||
if (e1) { newEnabledTransceivers.push_back(transceiverCom1); newEnabledTransceiverIds.insert(transceiverCom1.id); }
|
||||
if (e2) { newEnabledTransceivers.push_back(transceiverCom2); newEnabledTransceiverIds.insert(transceiverCom2.id); }
|
||||
|
||||
// Transmitting transceivers, currently ALLOW ONLY ONE
|
||||
if (tx1 && e1) { newTransmittingTransceivers.push_back(transceiverCom1); }
|
||||
else if (tx2 && e2) { newTransmittingTransceivers.push_back(transceiverCom2); }
|
||||
|
||||
// lock and update
|
||||
{
|
||||
this->setTransmittingComUnit(CComSystem::Com1);
|
||||
QMutexLocker lock(&m_mutexTransceivers);
|
||||
m_transceivers = newTransceivers;
|
||||
m_enabledTransceivers = newEnabledTransceiverIds;
|
||||
m_transmittingTransceivers = newTransmittingTransceivers;
|
||||
}
|
||||
else if (tx2)
|
||||
// in connection and soundcard only use the enabled tarnsceivers
|
||||
const QString callsign = this->getCallsign();
|
||||
{
|
||||
this->setTransmittingComUnit(CComSystem::Com2);
|
||||
QMutexLocker lock(&m_mutex);
|
||||
if (m_connection) { m_connection->updateTransceivers(callsign, newEnabledTransceivers); }
|
||||
if (m_soundcardSampleProvider) { m_soundcardSampleProvider->updateRadioTransceivers(newEnabledTransceivers); }
|
||||
}
|
||||
|
||||
this->updateTransceivers();
|
||||
emit this->updatedFromOwnAircraftCockpit();
|
||||
if (withSignals) { emit this->updatedFromOwnAircraftCockpit(); }
|
||||
}
|
||||
|
||||
void CAfvClient::onUpdateTransceiversFromContext(const CSimulatedAircraft &aircraft, const CIdentifier &originator)
|
||||
{
|
||||
if (originator == this->identifier()) { return; }
|
||||
this->updateFromOwnAircraft(aircraft);
|
||||
}
|
||||
|
||||
quint32 CAfvClient::getAliasFrequencyHz(quint32 frequencyHz) const
|
||||
{
|
||||
// void rounding issues from float/double
|
||||
quint32 roundedFrequencyHz = static_cast<quint32>(qRound(frequencyHz / 1000.0)) * 1000;
|
||||
|
||||
// change to aliased frequency if needed
|
||||
{
|
||||
QMutexLocker lock(&m_mutex);
|
||||
auto it = std::find_if(m_aliasedStations.begin(), m_aliasedStations.end(), [roundedFrequencyHz](const StationDto & d)
|
||||
{
|
||||
return d.frequencyAliasHz == roundedFrequencyHz;
|
||||
});
|
||||
|
||||
if (it != m_aliasedStations.end())
|
||||
{
|
||||
CLogMessage(this).debug(u"Aliasing %1Hz [VHF] to %2Hz [HF]") << frequencyHz << it->frequencyHz;
|
||||
roundedFrequencyHz = it->frequencyHz;
|
||||
}
|
||||
}
|
||||
return roundedFrequencyHz;
|
||||
}
|
||||
|
||||
quint16 CAfvClient::comUnitToTransceiverId(CComSystem::ComUnit comUnit)
|
||||
@@ -716,8 +776,7 @@ namespace BlackCore
|
||||
{
|
||||
case CComSystem::Com1: return 0;
|
||||
case CComSystem::Com2: return 1;
|
||||
default:
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -106,10 +106,12 @@ namespace BlackCore
|
||||
void setMuted(bool mute);
|
||||
//! @}
|
||||
|
||||
//! Start/stop client @{
|
||||
bool restartWithNewDevices(const BlackMisc::Audio::CAudioDeviceInfo &inputDevice, const BlackMisc::Audio::CAudioDeviceInfo &outputDevice);
|
||||
void startAudio(const BlackMisc::Audio::CAudioDeviceInfo &inputDevice, const BlackMisc::Audio::CAudioDeviceInfo &outputDevice, const QVector<quint16> &transceiverIDs);
|
||||
Q_INVOKABLE void startAudio(const QString &inputDeviceName, const QString &outputDeviceName);
|
||||
void stopAudio();
|
||||
//! @}
|
||||
|
||||
//! Enable COM unit/transceiver
|
||||
//! \threadsafe
|
||||
@@ -155,6 +157,11 @@ namespace BlackCore
|
||||
//! \threadsafe
|
||||
Q_INVOKABLE void updatePosition(double latitudeDeg, double longitudeDeg, double heightMeters);
|
||||
|
||||
//! Update from own aircraft
|
||||
//! \remark full update of frequency, position and enabled transceivers in one step
|
||||
//! \threadsafe
|
||||
void updateFromOwnAircraft(const BlackMisc::Simulation::CSimulatedAircraft &aircraft, bool withSignals = true);
|
||||
|
||||
//! Push to talk @{
|
||||
Q_INVOKABLE void setPtt(bool active);
|
||||
void setPttForCom(bool active, BlackMisc::Audio::PTTCOM com);
|
||||
@@ -167,34 +174,46 @@ namespace BlackCore
|
||||
Q_INVOKABLE bool isLoopback() const { return m_loopbackOn; }
|
||||
//! @}
|
||||
|
||||
//! Input volume in dB, +-18dB @{
|
||||
double getInputVolumeDb() const { return m_inputVolumeDb; }
|
||||
//! Input volume in dB, +-18dB
|
||||
//! \threadsafe
|
||||
//! @{
|
||||
double getInputVolumeDb() const;
|
||||
Q_INVOKABLE void setInputVolumeDb(double valueDb);
|
||||
//! @}
|
||||
|
||||
//! Output volume in dB, +-18dB @{
|
||||
double getOutputVolumeDb() const { return m_outputVolumeDb; }
|
||||
//! Output volume in dB, +-18dB
|
||||
//! \threadsafe
|
||||
//! @{
|
||||
double getOutputVolumeDb() const;
|
||||
Q_INVOKABLE void setOutputVolumeDb(double valueDb);
|
||||
//! @}
|
||||
|
||||
//! Normalized volumes 0..100 @{
|
||||
//! Normalized volumes 0..100
|
||||
//! \threadsafe
|
||||
//! @{
|
||||
int getNormalizedInputVolume() const;
|
||||
int getNormalizedOutputVolume() const;
|
||||
void setNormalizedInputVolume(int volume);
|
||||
void setNormalizedOutputVolume(int volume);
|
||||
//! @}
|
||||
|
||||
//! VU values, 0..1 @{
|
||||
//! VU values, 0..1
|
||||
//! \threadsafe
|
||||
//! @{
|
||||
double getInputVolumePeakVU() const;
|
||||
double getOutputVolumePeakVU() const;
|
||||
//! @}
|
||||
|
||||
//! Recently used device @{
|
||||
//! Recently used device
|
||||
//! \threadsafe
|
||||
//! @{
|
||||
const BlackMisc::Audio::CAudioDeviceInfo &getInputDevice() const;
|
||||
const BlackMisc::Audio::CAudioDeviceInfo &getOutputDevice() const;
|
||||
//! @}
|
||||
|
||||
//! Callsigns currently received @{
|
||||
//! Callsigns currently received
|
||||
//! \threadsafe
|
||||
//! @{
|
||||
QString getReceivingCallsignsCom1();
|
||||
QString getReceivingCallsignsCom2();
|
||||
//! @}
|
||||
@@ -238,6 +257,10 @@ namespace BlackCore
|
||||
void updateTransceivers(bool updateFrequencies = true);
|
||||
void onUpdateTransceiversFromContext(const BlackMisc::Simulation::CSimulatedAircraft &aircraft, const BlackMisc::CIdentifier &originator);
|
||||
|
||||
//! Frequency from aliased stations
|
||||
//! \threadsafe
|
||||
quint32 getAliasFrequencyHz(quint32 frequencyHz) const;
|
||||
|
||||
static constexpr int PositionUpdatesMs = 5000; //!< position timer
|
||||
static constexpr int SampleRate = 48000;
|
||||
static constexpr int FrameSize = 960; // 20ms
|
||||
@@ -276,8 +299,8 @@ namespace BlackCore
|
||||
double m_outputVolume = 1.0;
|
||||
double m_maxDbReadingInPTTInterval = -100;
|
||||
|
||||
QTimer *m_voiceServerPositionTimer = nullptr;
|
||||
QVector<StationDto> m_aliasedStations;
|
||||
QTimer *m_voiceServerPositionTimer = nullptr;
|
||||
QVector<StationDto> m_aliasedStations;
|
||||
|
||||
Audio::InputVolumeStreamArgs m_inputVolumeStream;
|
||||
Audio::OutputVolumeStreamArgs m_outputVolumeStream;
|
||||
|
||||
@@ -138,6 +138,7 @@ namespace BlackCore
|
||||
|
||||
void CApiServerConnection::updateTransceivers(const QString &callsign, const QVector<TransceiverDto> &transceivers)
|
||||
{
|
||||
if (!this->sendToNetworkIfAuthenticated()) { return; }
|
||||
QJsonArray array;
|
||||
for (const TransceiverDto &tx : transceivers)
|
||||
{
|
||||
@@ -239,13 +240,7 @@ namespace BlackCore
|
||||
|
||||
void CApiServerConnection::postNoResponse(const QString &resource, const QJsonDocument &json)
|
||||
{
|
||||
if (isShuttingDown()) { return; } // avoid crash
|
||||
if (!m_isAuthenticated)
|
||||
{
|
||||
CLogMessage(this).debug(u"AFV not authenticated");
|
||||
return;
|
||||
}
|
||||
|
||||
if (isShuttingDown()) { return; }
|
||||
this->checkExpiry();
|
||||
|
||||
QUrl url(m_addressUrl);
|
||||
@@ -273,8 +268,7 @@ namespace BlackCore
|
||||
|
||||
void CApiServerConnection::deleteResource(const QString &resource)
|
||||
{
|
||||
if (isShuttingDown()) { return; }
|
||||
if (!m_isAuthenticated) { return; }
|
||||
if (isShuttingDown()) { return; }
|
||||
|
||||
QUrl url(m_addressUrl);
|
||||
url.setPath(resource);
|
||||
@@ -345,6 +339,11 @@ namespace BlackCore
|
||||
return loop;
|
||||
}
|
||||
|
||||
bool CApiServerConnection::sendToNetworkIfAuthenticated() const
|
||||
{
|
||||
return m_isAuthenticated && !isShuttingDown();
|
||||
}
|
||||
|
||||
bool CApiServerConnection::isShuttingDown()
|
||||
{
|
||||
return !sApp || sApp->isShuttingDown();
|
||||
|
||||
@@ -80,9 +80,9 @@ namespace BlackCore
|
||||
template<typename TResponse>
|
||||
TResponse postNoRequest(const QString &resource)
|
||||
{
|
||||
if (!m_isAuthenticated)
|
||||
if (!this->sendToNetworkIfAuthenticated())
|
||||
{
|
||||
BlackMisc::CLogMessage(this).debug(u"AFV not authenticated");
|
||||
// BlackMisc::CLogMessage(this).debug(u"AFV not authenticated");
|
||||
return {};
|
||||
}
|
||||
|
||||
@@ -103,9 +103,9 @@ namespace BlackCore
|
||||
template<typename TResponse>
|
||||
QVector<TResponse> getAsVector(const QString &resource)
|
||||
{
|
||||
if (! m_isAuthenticated)
|
||||
if (!this->sendToNetworkIfAuthenticated())
|
||||
{
|
||||
BlackMisc::CLogMessage(this).debug(u"AFV not authenticated");
|
||||
// BlackMisc::CLogMessage(this).debug(u"AFV not authenticated");
|
||||
return {};
|
||||
}
|
||||
|
||||
@@ -156,6 +156,9 @@ namespace BlackCore
|
||||
//! Get QLoop for network access, using class must delete the loop
|
||||
QEventLoop *newEventLoop();
|
||||
|
||||
//! Send to network
|
||||
bool sendToNetworkIfAuthenticated() const;
|
||||
|
||||
//! Application shutting down
|
||||
static bool isShuttingDown();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user