From 11838c8e1623660e6b4e59f8c7e3bcf79b35a4ad Mon Sep 17 00:00:00 2001 From: pajlada Date: Wed, 17 Jan 2024 23:53:10 +0100 Subject: [PATCH] refactor: Move TwitchBadges to Application (#5096) * refactor: Move TwitchBadges to Application * refactor: Use named initializers * refactor: Use `empty()` instead of `size() > 0` * refactor: use emplace instead of push into the callback queue --- CHANGELOG.md | 1 + mocks/include/mocks/EmptyApplication.hpp | 6 ++ src/Application.cpp | 10 +++ src/Application.hpp | 4 ++ .../highlights/BadgeHighlightModel.cpp | 2 +- src/providers/twitch/TwitchBadges.cpp | 63 ++++++++----------- src/providers/twitch/TwitchBadges.hpp | 5 +- src/providers/twitch/TwitchMessageBuilder.cpp | 2 +- src/widgets/dialogs/BadgePickerDialog.cpp | 3 +- 9 files changed, 52 insertions(+), 44 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index baddc3d87..e5d7d1076 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -106,6 +106,7 @@ - Dev: Move `clang-tidy` checker to its own CI job. (#4996) - Dev: Refactored the Image Uploader feature. (#4971) - Dev: Refactored the SplitOverlay code. (#5082) +- Dev: Refactored the TwitchBadges structure, making it less of a singleton. (#5096) - Dev: Moved the Network files to their own folder. (#5089) - Dev: Fixed deadlock and use-after-free in tests. (#4981) - Dev: Moved all `.clang-format` files to the root directory. (#5037) diff --git a/mocks/include/mocks/EmptyApplication.hpp b/mocks/include/mocks/EmptyApplication.hpp index 26395e079..06dc6a7c8 100644 --- a/mocks/include/mocks/EmptyApplication.hpp +++ b/mocks/include/mocks/EmptyApplication.hpp @@ -122,6 +122,12 @@ public: return nullptr; } + TwitchBadges *getTwitchBadges() override + { + assert(false && "getTwitchBadges was called without being initialized"); + return nullptr; + } + Logging *getChatLogger() override { assert(!"getChatLogger was called without being initialized"); diff --git a/src/Application.cpp b/src/Application.cpp index 786bb5bf8..1890bcf4d 100644 --- a/src/Application.cpp +++ b/src/Application.cpp @@ -12,6 +12,7 @@ #include "controllers/notifications/NotificationController.hpp" #include "controllers/sound/ISoundController.hpp" #include "providers/seventv/SeventvAPI.hpp" +#include "providers/twitch/TwitchBadges.hpp" #include "singletons/ImageUploader.hpp" #ifdef CHATTERINO_HAVE_PLUGINS # include "controllers/plugins/PluginController.hpp" @@ -133,6 +134,7 @@ Application::Application(Settings &_settings, const Paths &paths, , sound(&this->emplace(makeSoundController(_settings))) , twitchLiveController(&this->emplace()) , twitchPubSub(new PubSub(TWITCH_PUBSUB_URL)) + , twitchBadges(new TwitchBadges) , logging(new Logging(_settings)) #ifdef CHATTERINO_HAVE_PLUGINS , plugins(&this->emplace(new PluginController(paths))) @@ -153,6 +155,7 @@ Application::~Application() = default; void Application::fakeDtor() { this->twitchPubSub.reset(); + this->twitchBadges.reset(); } void Application::initialize(Settings &settings, const Paths &paths) @@ -320,6 +323,13 @@ ITwitchLiveController *Application::getTwitchLiveController() return this->twitchLiveController; } +TwitchBadges *Application::getTwitchBadges() +{ + assert(this->twitchBadges); + + return this->twitchBadges.get(); +} + ITwitchIrcServer *Application::getTwitch() { return this->twitch; diff --git a/src/Application.hpp b/src/Application.hpp index 716d0f476..2e0d46fc9 100644 --- a/src/Application.hpp +++ b/src/Application.hpp @@ -28,6 +28,7 @@ class ISoundController; class SoundController; class ITwitchLiveController; class TwitchLiveController; +class TwitchBadges; #ifdef CHATTERINO_HAVE_PLUGINS class PluginController; #endif @@ -78,6 +79,7 @@ public: virtual IUserDataController *getUserData() = 0; virtual ISoundController *getSound() = 0; virtual ITwitchLiveController *getTwitchLiveController() = 0; + virtual TwitchBadges *getTwitchBadges() = 0; virtual ImageUploader *getImageUploader() = 0; virtual SeventvAPI *getSeventvAPI() = 0; virtual Updates &getUpdates() = 0; @@ -141,6 +143,7 @@ public: private: TwitchLiveController *const twitchLiveController{}; std::unique_ptr twitchPubSub; + std::unique_ptr twitchBadges; const std::unique_ptr logging; public: @@ -215,6 +218,7 @@ public: IUserDataController *getUserData() override; ISoundController *getSound() override; ITwitchLiveController *getTwitchLiveController() override; + TwitchBadges *getTwitchBadges() override; ImageUploader *getImageUploader() override { return this->imageUploader; diff --git a/src/controllers/highlights/BadgeHighlightModel.cpp b/src/controllers/highlights/BadgeHighlightModel.cpp index ffca5b289..e1d93c3bc 100644 --- a/src/controllers/highlights/BadgeHighlightModel.cpp +++ b/src/controllers/highlights/BadgeHighlightModel.cpp @@ -53,7 +53,7 @@ void BadgeHighlightModel::getRowFromItem(const HighlightBadge &item, setFilePathItem(row[Column::SoundPath], item.getSoundUrl()); setColorItem(row[Column::Color], *item.getColor()); - TwitchBadges::instance()->getBadgeIcon( + getIApp()->getTwitchBadges()->getBadgeIcon( item.badgeName(), [item, row](QString /*name*/, const QIconPtr pixmap) { row[Column::Badge]->setData(QVariant(*pixmap), Qt::DecorationRole); }); diff --git a/src/providers/twitch/TwitchBadges.cpp b/src/providers/twitch/TwitchBadges.cpp index 36ba7b1ea..6eb5c6cd9 100644 --- a/src/providers/twitch/TwitchBadges.cpp +++ b/src/providers/twitch/TwitchBadges.cpp @@ -1,4 +1,4 @@ -#include "TwitchBadges.hpp" +#include "providers/twitch/TwitchBadges.hpp" #include "common/network/NetworkRequest.hpp" #include "common/network/NetworkResult.hpp" @@ -45,14 +45,15 @@ void TwitchBadges::loadTwitchBadges() for (const auto &version : badgeSet.versions) { const auto &emote = Emote{ - EmoteName{}, - ImageSet{ - Image::fromUrl(version.imageURL1x, 1), - Image::fromUrl(version.imageURL2x, .5), - Image::fromUrl(version.imageURL4x, .25), - }, - Tooltip{version.title}, - version.clickURL, + .name = EmoteName{}, + .images = + ImageSet{ + Image::fromUrl(version.imageURL1x, 1), + Image::fromUrl(version.imageURL2x, .5), + Image::fromUrl(version.imageURL4x, .25), + }, + .tooltip = Tooltip{version.title}, + .homePage = version.clickURL, }; (*badgeSets)[setID][version.id] = std::make_shared(emote); @@ -112,20 +113,19 @@ void TwitchBadges::parseTwitchBadges(QJsonObject root) auto versionObj = vIt.value().toObject(); auto emote = Emote{ - {""}, - ImageSet{ - Image::fromUrl( - {versionObj.value("image_url_1x").toString()}, 1), - Image::fromUrl( - {versionObj.value("image_url_2x").toString()}, .5), - Image::fromUrl( - {versionObj.value("image_url_4x").toString()}, .25), - }, - Tooltip{versionObj.value("title").toString()}, - Url{versionObj.value("click_url").toString()}, + .name = {""}, + .images = + ImageSet{ + Image::fromUrl( + {versionObj.value("image_url_1x").toString()}, 1), + Image::fromUrl( + {versionObj.value("image_url_2x").toString()}, .5), + Image::fromUrl( + {versionObj.value("image_url_4x").toString()}, .25), + }, + .tooltip = Tooltip{versionObj.value("title").toString()}, + .homePage = Url{versionObj.value("click_url").toString()}, }; - // "title" - // "clickAction" (*badgeSets)[key][vIt.key()] = std::make_shared(emote); } @@ -176,9 +176,10 @@ std::optional TwitchBadges::badge(const QString &set) const auto it = badgeSets->find(set); if (it != badgeSets->end()) { - if (it->second.size() > 0) + const auto &badges = it->second; + if (!badges.empty()) { - return it->second.begin()->second; + return badges.begin()->second; } } return std::nullopt; @@ -193,7 +194,7 @@ void TwitchBadges::getBadgeIcon(const QString &name, BadgeIconCallback callback) { // Badges have not been loaded yet, store callback in a queue std::unique_lock queueLock(this->queueMutex_); - this->callbackQueue_.push({name, std::move(callback)}); + this->callbackQueue_.emplace(name, std::move(callback)); return; } } @@ -279,16 +280,4 @@ void TwitchBadges::loadEmoteImage(const QString &name, ImagePtr image, .execute(); } -TwitchBadges *TwitchBadges::instance_; - -TwitchBadges *TwitchBadges::instance() -{ - if (TwitchBadges::instance_ == nullptr) - { - TwitchBadges::instance_ = new TwitchBadges(); - } - - return TwitchBadges::instance_; -} - } // namespace chatterino diff --git a/src/providers/twitch/TwitchBadges.hpp b/src/providers/twitch/TwitchBadges.hpp index 4ca4c42b6..cb56207a9 100644 --- a/src/providers/twitch/TwitchBadges.hpp +++ b/src/providers/twitch/TwitchBadges.hpp @@ -32,7 +32,7 @@ class TwitchBadges using BadgeIconCallback = std::function; public: - static TwitchBadges *instance(); + TwitchBadges(); // Get badge from name and version std::optional badge(const QString &set, @@ -46,9 +46,6 @@ public: BadgeIconCallback callback); private: - static TwitchBadges *instance_; - - TwitchBadges(); void loadTwitchBadges(); void parseTwitchBadges(QJsonObject root); void loaded(); diff --git a/src/providers/twitch/TwitchMessageBuilder.cpp b/src/providers/twitch/TwitchMessageBuilder.cpp index fe053aa3e..9b14c6cd3 100644 --- a/src/providers/twitch/TwitchMessageBuilder.cpp +++ b/src/providers/twitch/TwitchMessageBuilder.cpp @@ -163,7 +163,7 @@ namespace { } if (auto globalBadge = - TwitchBadges::instance()->badge(badge.key_, badge.value_)) + getIApp()->getTwitchBadges()->badge(badge.key_, badge.value_)) { return globalBadge; } diff --git a/src/widgets/dialogs/BadgePickerDialog.cpp b/src/widgets/dialogs/BadgePickerDialog.cpp index b339b0415..143372492 100644 --- a/src/widgets/dialogs/BadgePickerDialog.cpp +++ b/src/widgets/dialogs/BadgePickerDialog.cpp @@ -1,5 +1,6 @@ #include "BadgePickerDialog.hpp" +#include "Application.hpp" #include "providers/twitch/TwitchBadges.hpp" #include "singletons/Resources.hpp" @@ -57,7 +58,7 @@ BadgePickerDialog::BadgePickerDialog(QList badges, updateBadge(0); // Set icons. - TwitchBadges::instance()->getBadgeIcons( + getIApp()->getTwitchBadges()->getBadgeIcons( badges, [&dropdown = this->dropdown_](QString identifier, const QIconPtr icon) { if (!dropdown)