From 596e42b7d8a478baaf24b920ea4cc2bd95992add Mon Sep 17 00:00:00 2001 From: pgScorpio Date: Fri, 13 Sep 2024 22:42:37 +0200 Subject: [PATCH] Refactor Connect and Disconnect out to CClient This is an extract from https://github.com/jamulussoftware/jamulus/pull/2550 Co-authored-by: ann0see <20726856+ann0see@users.noreply.github.com> --- src/client.cpp | 55 ++++++++++++++++------ src/client.h | 11 ++++- src/clientdlg.cpp | 116 ++++++++++++++++------------------------------ src/clientdlg.h | 7 ++- src/main.cpp | 14 +++++- 5 files changed, 106 insertions(+), 97 deletions(-) diff --git a/src/client.cpp b/src/client.cpp index d3d2c51c9a..bd9156760e 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -27,7 +27,6 @@ /* Implementation *************************************************************/ CClient::CClient ( const quint16 iPortNumber, const quint16 iQosNumber, - const QString& strConnOnStartupAddress, const QString& strMIDISetup, const bool bNoAutoJackConnect, const QString& strNClientName, @@ -122,7 +121,7 @@ CClient::CClient ( const quint16 iPortNumber, QObject::connect ( &Channel, &CChannel::ConClientListMesReceived, this, &CClient::OnConClientListMesReceived ); QObject::connect ( &Channel, &CChannel::ConClientListMesReceived, this, &CClient::ConClientListMesReceived ); - QObject::connect ( &Channel, &CChannel::Disconnected, this, &CClient::Disconnected ); + QObject::connect ( &Channel, &CChannel::Disconnected, this, &CClient::Stop ); QObject::connect ( &Channel, &CChannel::NewConnection, this, &CClient::OnNewConnection ); @@ -184,13 +183,6 @@ CClient::CClient ( const quint16 iPortNumber, // start the socket (it is important to start the socket after all // initializations and connections) Socket.Start(); - - // do an immediate start if a server address is given - if ( !strConnOnStartupAddress.isEmpty() ) - { - SetServerAddr ( strConnOnStartupAddress ); - Start(); - } } CClient::~CClient() @@ -773,11 +765,8 @@ void CClient::OnHandledSignal ( int sigNum ) { case SIGINT: case SIGTERM: - // if connected, terminate connection (needed for headless mode) - if ( IsRunning() ) - { - Stop(); - } + // if connected, Stop client (needed for headless mode) + Stop(); // this should trigger OnAboutToQuit QCoreApplication::instance()->exit(); @@ -874,6 +863,10 @@ void CClient::Start() Sound.Start(); } +/// @method +/// @brief Stops client and disconnects from server +/// @emit Disconnected +/// Use to set CClientDlg to show not being connected void CClient::Stop() { // stop audio interface @@ -906,6 +899,40 @@ void CClient::Stop() // reset current signal level and LEDs bJitterBufferOK = true; SignalLevelMeter.Reset(); + + // emit Disconnected() to inform UI of disconnection + emit Disconnected(); +} + +/// @method +/// @brief Connects to strServerAddress +/// @emit Connecting (strServerName) if the client wasn't running and SetServerAddr was valid. +/// Use to set CClientDlg to show being connected +/// @emit ConnectingFailed (error) if an error occurred +/// Use to display error message in CClientDlg +/// @param strServerAddress - the server address to connect to +/// @param strServerName - the String argument to be passed to Connecting() +void CClient::Connect ( QString strServerAddress, QString strServerName ) +{ + try { + if ( !IsRunning() ) + { + // Set server address and connect if valid address was supplied + if ( SetServerAddr ( strServerAddress ) ) + { + Start(); + emit Connecting ( strServerName ); + } + else { + throw CGenErr ( "Received invalid server address. Please check for typos in the provided server address." ); + } + } + } + catch ( const CGenErr& generr ) + { + Stop(); + emit ConnectingFailed ( generr.GetErrorText() ); + } } void CClient::Init() diff --git a/src/client.h b/src/client.h index 1fc33d8430..9090e027a2 100644 --- a/src/client.h +++ b/src/client.h @@ -110,7 +110,6 @@ class CClient : public QObject public: CClient ( const quint16 iPortNumber, const quint16 iQosNumber, - const QString& strConnOnStartupAddress, const QString& strMIDISetup, const bool bNoAutoJackConnect, const QString& strNClientName, @@ -121,6 +120,8 @@ class CClient : public QObject void Start(); void Stop(); + void Connect ( QString strServerAddress, QString strServerName ); + bool IsRunning() { return Sound.IsRunning(); } bool IsCallbackEntered() const { return Sound.IsCallbackEntered(); } bool SetServerAddr ( QString strNAddr ); @@ -387,7 +388,8 @@ protected slots: { if ( InetAddr == Channel.GetAddress() ) { - emit Disconnected(); + // Stop client in case it received a Disconnection request + Stop(); } } void OnCLPingReceived ( CHostAddress InetAddr, int iMs ); @@ -427,7 +429,12 @@ protected slots: void CLChannelLevelListReceived ( CHostAddress InetAddr, CVector vecLevelList ); + void ConnectClient ( QString strServerAddress ); + void Connecting ( QString strServerName ); + void ConnectingFailed ( QString errorMessage ); + void DisconnectClient(); void Disconnected(); + void SoundDeviceChanged ( QString strError ); void ControllerInFaderLevel ( int iChannelIdx, int iValue ); void ControllerInPanValue ( int iChannelIdx, int iValue ); diff --git a/src/clientdlg.cpp b/src/clientdlg.cpp index 99b9fa6433..1ec605a99a 100644 --- a/src/clientdlg.cpp +++ b/src/clientdlg.cpp @@ -27,7 +27,6 @@ /* Implementation *************************************************************/ CClientDlg::CClientDlg ( CClient* pNCliP, CClientSettings* pNSetP, - const QString& strConnOnStartupAddress, const QString& strMIDISetup, const bool bNewShowComplRegConnList, const bool bShowAnalyzerConsole, @@ -272,14 +271,6 @@ CClientDlg::CClientDlg ( CClient* pNCliP, TimerCheckAudioDeviceOk.setSingleShot ( true ); // only check once after connection TimerDetectFeedback.setSingleShot ( true ); - // Connect on startup ------------------------------------------------------ - if ( !strConnOnStartupAddress.isEmpty() ) - { - // initiate connection (always show the address in the mixer board - // (no alias)) - Connect ( strConnOnStartupAddress, strConnOnStartupAddress ); - } - // File menu -------------------------------------------------------------- QMenu* pFileMenu = new QMenu ( tr ( "&File" ), this ); @@ -473,7 +464,11 @@ CClientDlg::CClientDlg ( CClient* pNCliP, // other QObject::connect ( pClient, &CClient::ConClientListMesReceived, this, &CClientDlg::OnConClientListMesReceived ); - QObject::connect ( pClient, &CClient::Disconnected, this, &CClientDlg::OnDisconnected ); + QObject::connect ( pClient, &CClient::Connecting, this, &CClientDlg::OnConnect ); + + QObject::connect ( pClient, &CClient::ConnectingFailed, this, &CClientDlg::OnConnectingFailed ); + + QObject::connect ( pClient, &CClient::Disconnected, this, &CClientDlg::OnDisconnect ); QObject::connect ( pClient, &CClient::ChatTextReceived, this, &CClientDlg::OnChatTextReceived ); @@ -608,11 +603,8 @@ void CClientDlg::closeEvent ( QCloseEvent* Event ) ConnectDlg.close(); AnalyzerConsole.close(); - // if connected, terminate connection - if ( pClient->IsRunning() ) - { - pClient->Stop(); - } + // Disconnect if needed + pClient->Stop(); // make sure all current fader settings are applied to the settings struct MainMixerBoard->StoreAllFaderSettings(); @@ -730,15 +722,9 @@ void CClientDlg::OnConnectDlgAccepted() } } - // first check if we are already connected, if this is the case we have to - // disconnect the old server first - if ( pClient->IsRunning() ) - { - Disconnect(); - } - // initiate connection - Connect ( strSelectedAddress, strMixerBoardLabel ); + + pClient->Connect ( strSelectedAddress, strMixerBoardLabel ); // reset flag bConnectDlgWasShown = false; @@ -750,11 +736,12 @@ void CClientDlg::OnConnectDisconBut() // the connect/disconnect button implements a toggle functionality if ( pClient->IsRunning() ) { - Disconnect(); - SetMixerBoardDeco ( RS_UNDEFINED, pClient->GetGUIDesign() ); + pClient->Stop(); } else { + // If the client isn't running, we assume that we weren't connected. Thus show the connect dialog + // TODO: Refactor to have robust error handling ShowConnectionSetupDialog(); } } @@ -859,7 +846,7 @@ void CClientDlg::OnLicenceRequired ( ELicenceType eLicenceType ) // disconnect from that server. if ( !LicenceDlg.exec() ) { - Disconnect(); + pClient->Stop(); } // unmute the client output stream if local mute button is not pressed @@ -1164,7 +1151,7 @@ void CClientDlg::OnSoundDeviceChanged ( QString strError ) // the sound device setup has a problem, disconnect any active connection if ( pClient->IsRunning() ) { - Disconnect(); + pClient->Stop(); } // show the error message of the device setup @@ -1193,65 +1180,41 @@ void CClientDlg::OnCLPingTimeWithNumClientsReceived ( CHostAddress InetAddr, int ConnectDlg.SetPingTimeAndNumClientsResult ( InetAddr, iPingTime, iNumClients ); } -void CClientDlg::Connect ( const QString& strSelectedAddress, const QString& strMixerBoardLabel ) +void CClientDlg::OnConnect ( const QString& strMixerBoardLabel ) { - // set address and check if address is valid - if ( pClient->SetServerAddr ( strSelectedAddress ) ) - { - // try to start client, if error occurred, do not go in - // running state but show error message - try - { - if ( !pClient->IsRunning() ) - { - pClient->Start(); - } - } - catch ( const CGenErr& generr ) - { - // show error message and return the function - QMessageBox::critical ( this, APP_NAME, generr.GetErrorText(), "Close", nullptr ); - return; - } + // hide label connect to server + lblConnectToServer->hide(); + lbrInputLevelL->setEnabled ( true ); + lbrInputLevelR->setEnabled ( true ); - // hide label connect to server - lblConnectToServer->hide(); - lbrInputLevelL->setEnabled ( true ); - lbrInputLevelR->setEnabled ( true ); + // change connect button text to "disconnect" + butConnect->setText ( tr ( "&Disconnect" ) ); - // change connect button text to "disconnect" - butConnect->setText ( tr ( "&Disconnect" ) ); + // set server name in audio mixer group box title + MainMixerBoard->SetServerName ( strMixerBoardLabel ); - // set server name in audio mixer group box title - MainMixerBoard->SetServerName ( strMixerBoardLabel ); + // start timer for level meter bar and ping time measurement + TimerSigMet.start ( LEVELMETER_UPDATE_TIME_MS ); + TimerBuffersLED.start ( BUFFER_LED_UPDATE_TIME_MS ); + TimerPing.start ( PING_UPDATE_TIME_MS ); + TimerCheckAudioDeviceOk.start ( CHECK_AUDIO_DEV_OK_TIME_MS ); // is single shot timer - // start timer for level meter bar and ping time measurement - TimerSigMet.start ( LEVELMETER_UPDATE_TIME_MS ); - TimerBuffersLED.start ( BUFFER_LED_UPDATE_TIME_MS ); - TimerPing.start ( PING_UPDATE_TIME_MS ); - TimerCheckAudioDeviceOk.start ( CHECK_AUDIO_DEV_OK_TIME_MS ); // is single shot timer - - // audio feedback detection - if ( pSettings->bEnableFeedbackDetection ) - { - TimerDetectFeedback.start ( DETECT_FEEDBACK_TIME_MS ); // single shot timer - bDetectFeedback = true; - } + // audio feedback detection + if ( pSettings->bEnableFeedbackDetection ) + { + TimerDetectFeedback.start ( DETECT_FEEDBACK_TIME_MS ); // single shot timer + bDetectFeedback = true; } } -void CClientDlg::Disconnect() +void CClientDlg::OnConnectingFailed ( const QString& strError ) { - // only stop client if currently running, in case we received - // the stopped message, the client is already stopped but the - // connect/disconnect button and other GUI controls must be - // updated - if ( pClient->IsRunning() ) - { - pClient->Stop(); - } + QMessageBox::critical ( this, APP_NAME, strError, "Close", nullptr ); +} +void CClientDlg::OnDisconnect() +{ // change connect button text to "connect" butConnect->setText ( tr ( "C&onnect" ) ); @@ -1293,6 +1256,9 @@ void CClientDlg::Disconnect() // clear mixer board (remove all faders) MainMixerBoard->HideAll(); + + // Reset the deco + SetMixerBoardDeco ( RS_UNDEFINED, pClient->GetGUIDesign() ); } void CClientDlg::UpdateDisplay() diff --git a/src/clientdlg.h b/src/clientdlg.h index 9737bcd2ca..362baa0cd0 100644 --- a/src/clientdlg.h +++ b/src/clientdlg.h @@ -76,7 +76,6 @@ class CClientDlg : public CBaseDlg, private Ui_CClientDlgBase public: CClientDlg ( CClient* pNCliP, CClientSettings* pNSetP, - const QString& strConnOnStartupAddress, const QString& strMIDISetup, const bool bNewShowComplRegConnList, const bool bShowAnalyzerConsole, @@ -94,8 +93,6 @@ class CClientDlg : public CBaseDlg, private Ui_CClientDlgBase void ShowAnalyzerConsole(); void UpdateAudioFaderSlider(); void UpdateRevSelection(); - void Connect ( const QString& strSelectedAddress, const QString& strMixerBoardLabel ); - void Disconnect(); void ManageDragNDrop ( QDropEvent* Event, const bool bCheckAccept ); void SetPingTime ( const int iPingTime, const int iOverallDelayMs, const CMultiColorLED::ELightColor eOverallDelayLEDColor ); @@ -127,6 +124,9 @@ class CClientDlg : public CBaseDlg, private Ui_CClientDlgBase CAnalyzerConsole AnalyzerConsole; public slots: + void OnConnect ( const QString& strServerName ); + void OnConnectingFailed ( const QString& strErrorText ); + void OnDisconnect(); void OnConnectDisconBut(); void OnTimerSigMet(); void OnTimerBuffersLED(); @@ -232,7 +232,6 @@ public slots: } void OnConnectDlgAccepted(); - void OnDisconnected() { Disconnect(); } void OnGUIDesignChanged(); void OnMeterStyleChanged(); void OnRecorderStateReceived ( ERecorderState eRecorderState ); diff --git a/src/main.cpp b/src/main.cpp index 42d17a8dea..aa419274fa 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -921,7 +921,6 @@ int main ( int argc, char** argv ) // actual client object CClient Client ( iPortNumber, iQosNumber, - strConnOnStartupAddress, strMIDISetup, bNoAutoJackConnect, strClientName, @@ -952,7 +951,6 @@ int main ( int argc, char** argv ) // GUI object CClientDlg ClientDlg ( &Client, &Settings, - strConnOnStartupAddress, strMIDISetup, bShowComplRegConnList, bShowAnalyzerConsole, @@ -963,6 +961,12 @@ int main ( int argc, char** argv ) // show dialog ClientDlg.show(); + // Connect on startup if requested + if ( !strConnOnStartupAddress.isEmpty() ) + { + Client.Connect ( strConnOnStartupAddress, strConnOnStartupAddress ); + } + pApp->exec(); } else @@ -971,6 +975,12 @@ int main ( int argc, char** argv ) // only start application without using the GUI qInfo() << qUtf8Printable ( GetVersionAndNameStr ( false ) ); + // Connect on startup if requested + if ( !strConnOnStartupAddress.isEmpty() ) + { + Client.Connect ( strConnOnStartupAddress, strConnOnStartupAddress ); + } + pApp->exec(); } }