diff --git a/cockatrice/CMakeLists.txt b/cockatrice/CMakeLists.txt index d020046d7..3b5d43b6e 100644 --- a/cockatrice/CMakeLists.txt +++ b/cockatrice/CMakeLists.txt @@ -110,6 +110,7 @@ set(cockatrice_SOURCES src/client/ui/widgets/printing_selector/printing_selector_view_options_widget.cpp src/client/ui/widgets/printing_selector/set_name_and_collectors_number_display_widget.cpp src/client/network/release_channel.cpp + src/client/network/client_update_checker.cpp src/server/remote/remote_client.cpp src/server/remote/remote_decklist_tree_widget.cpp src/server/remote/remote_replay_list_tree_widget.cpp diff --git a/cockatrice/src/client/network/client_update_checker.cpp b/cockatrice/src/client/network/client_update_checker.cpp new file mode 100644 index 000000000..23c52d08d --- /dev/null +++ b/cockatrice/src/client/network/client_update_checker.cpp @@ -0,0 +1,35 @@ +#include "client_update_checker.h" + +#include "../../settings/cache_settings.h" +#include "release_channel.h" + +ClientUpdateChecker::ClientUpdateChecker(QObject *parent) : QObject(parent) +{ +} + +void ClientUpdateChecker::check() +{ + auto releaseChannel = SettingsCache::instance().getUpdateReleaseChannel(); + + finishedCheckConnection = + connect(releaseChannel, &ReleaseChannel::finishedCheck, this, &ClientUpdateChecker::actFinishedCheck); + errorConnection = connect(releaseChannel, &ReleaseChannel::error, this, &ClientUpdateChecker::actError); + + releaseChannel->checkForUpdates(); +} + +void ClientUpdateChecker::actFinishedCheck(bool needToUpdate, bool isCompatible, Release *release) +{ + disconnect(finishedCheckConnection); + disconnect(errorConnection); + + emit finishedCheck(needToUpdate, isCompatible, release); +} + +void ClientUpdateChecker::actError(const QString &errorString) +{ + disconnect(finishedCheckConnection); + disconnect(errorConnection); + + emit error(errorString); +} \ No newline at end of file diff --git a/cockatrice/src/client/network/client_update_checker.h b/cockatrice/src/client/network/client_update_checker.h new file mode 100644 index 000000000..96a7213b1 --- /dev/null +++ b/cockatrice/src/client/network/client_update_checker.h @@ -0,0 +1,45 @@ +#ifndef CLIENT_UPDATE_CHECKER_H +#define CLIENT_UPDATE_CHECKER_H +#include + +class Release; + +/** + * We use a singleton instance of UpdateChannel, which can cause interference and feedback loops when multiple objects + * connect to it. + * + * This class encapsulates the usage of that UpdateChannel to ensure that the check only happens once per connection and + * the connection is destroyed after it's been used. + */ +class ClientUpdateChecker : public QObject +{ + Q_OBJECT + + QMetaObject::Connection finishedCheckConnection; + QMetaObject::Connection errorConnection; + + void actFinishedCheck(bool needToUpdate, bool isCompatible, Release *release); + void actError(const QString &errorString); + +public: + explicit ClientUpdateChecker(QObject *parent = nullptr); + /** + * Actually performs the check, using the currently selected update channel in the settings. + * Any resulting signals will only be sent once. + * This method should only be called ONCE per instance. + */ + void check(); + +signals: + /** + * Forwarded from UpdateChannel::finishedCheck + */ + void finishedCheck(bool needToUpdate, bool isCompatible, Release *release); + + /** + * Forwarded from UpdateChannel::error + */ + void error(const QString &errorString); +}; + +#endif // CLIENT_UPDATE_CHECKER_H diff --git a/cockatrice/src/dialogs/dlg_update.cpp b/cockatrice/src/dialogs/dlg_update.cpp index 21f08f827..8ef8ea09b 100644 --- a/cockatrice/src/dialogs/dlg_update.cpp +++ b/cockatrice/src/dialogs/dlg_update.cpp @@ -1,5 +1,6 @@ #include "dlg_update.h" +#include "../client/network/client_update_checker.h" #include "../client/network/release_channel.h" #include "../client/ui/window_main.h" #include "../settings/cache_settings.h" @@ -71,11 +72,6 @@ DlgUpdate::DlgUpdate(QWidget *parent) : QDialog(parent) connect(uDownloader, SIGNAL(progressMade(qint64, qint64)), this, SLOT(downloadProgressMade(qint64, qint64))); connect(uDownloader, SIGNAL(error(QString)), this, SLOT(downloadError(QString))); - ReleaseChannel *channel = SettingsCache::instance().getUpdateReleaseChannel(); - connect(channel, SIGNAL(finishedCheck(bool, bool, Release *)), this, - SLOT(finishedUpdateCheck(bool, bool, Release *))); - connect(channel, SIGNAL(error(QString)), this, SLOT(updateCheckError(QString))); - // Check for updates beginUpdateCheck(); } @@ -110,7 +106,12 @@ void DlgUpdate::beginUpdateCheck() progress->setMinimum(0); progress->setMaximum(0); setLabel(tr("Checking for updates...")); - SettingsCache::instance().getUpdateReleaseChannel()->checkForUpdates(); + + auto checker = new ClientUpdateChecker(this); + connect(checker, SIGNAL(finishedCheck(bool, bool, Release *)), this, + SLOT(finishedUpdateCheck(bool, bool, Release *))); + connect(checker, SIGNAL(error(QString)), this, SLOT(updateCheckError(QString))); + checker->check(); } void DlgUpdate::finishedUpdateCheck(bool needToUpdate, bool isCompatible, Release *release)