From 5f4ad87a47562497a7ad28c3808aebd3c5066c06 Mon Sep 17 00:00:00 2001 From: BruebachL <44814898+BruebachL@users.noreply.github.com> Date: Tue, 5 Nov 2024 19:32:59 +0100 Subject: [PATCH] Refactor CardDatabase *db global variable to singleton CardDatabaseManager. (#5159) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Refactor CardDatabase *db global variable to singleton CardDatabaseManager. This commit refactors the global variable CardDatabase *db into a singleton encapsulated by the DatabaseManager class, accessible via DatabaseManager::getInstance(). This change centralizes access to the database instance, improving code modularity and encapsulation, resolving dependencies on main.h for code that requires access to the database instance. - Added DatabaseManager class with getInstance() method returning a pointer to the singleton CardDatabase. - Removed global db variable and updated references across the codebase. - Thread-safe static initialization for the singleton. Impact: This refactor should have no functional impact on the application, as it maintains the same interface for accessing the CardDatabase instance. However, the codebase now benefits from improved encapsulation, lifetime management, and thread-safety. * Refactor CardDatabase *db global variable to singleton CardDatabaseManager. This commit refactors the global variable CardDatabase *db into a singleton encapsulated by the DatabaseManager class, accessible via DatabaseManager::getInstance(). This change centralizes access to the database instance, improving code modularity and encapsulation, resolving dependencies on main.h for code that requires access to the database instance. - Added DatabaseManager class with getInstance() method returning a pointer to the singleton CardDatabase. - Removed global db variable and updated references across the codebase. - Thread-safe static initialization for the singleton. Impact: This refactor should have no functional impact on the application, as it maintains the same interface for accessing the CardDatabase instance. However, the codebase now benefits from improved encapsulation, lifetime management, and thread-safety. --------- Co-authored-by: Lukas BrĂ¼bach --- cockatrice/CMakeLists.txt | 1 + .../network/spoiler_background_updater.cpp | 3 +- .../src/client/tabs/tab_deck_editor.cpp | 8 ++++-- cockatrice/src/client/tabs/tab_game.cpp | 6 ++-- cockatrice/src/client/ui/picture_loader.cpp | 2 +- cockatrice/src/client/ui/window_main.cpp | 28 ++++++++++--------- cockatrice/src/deck/deck_list_model.cpp | 7 +++-- cockatrice/src/deck/deck_loader.cpp | 11 ++++---- cockatrice/src/dialogs/dlg_create_token.cpp | 3 +- cockatrice/src/dialogs/dlg_edit_tokens.cpp | 3 +- cockatrice/src/dialogs/dlg_manage_sets.cpp | 7 +++-- cockatrice/src/dialogs/dlg_settings.cpp | 3 +- .../src/game/cards/abstract_card_item.cpp | 3 +- .../src/game/cards/card_database_manager.cpp | 7 +++++ .../src/game/cards/card_database_manager.h | 23 +++++++++++++++ cockatrice/src/game/cards/card_frame.cpp | 5 ++-- .../src/game/cards/card_info_widget.cpp | 3 +- cockatrice/src/game/player/player.cpp | 15 +++++----- cockatrice/src/main.cpp | 3 -- dbconverter/src/main.h | 4 +-- oracle/CMakeLists.txt | 1 + tests/carddatabase/CMakeLists.txt | 1 + tests/carddatabase/filter_string_test.cpp | 8 ++---- 23 files changed, 100 insertions(+), 55 deletions(-) create mode 100644 cockatrice/src/game/cards/card_database_manager.cpp create mode 100644 cockatrice/src/game/cards/card_database_manager.h diff --git a/cockatrice/CMakeLists.txt b/cockatrice/CMakeLists.txt index 370f0738f..4c904f4d9 100644 --- a/cockatrice/CMakeLists.txt +++ b/cockatrice/CMakeLists.txt @@ -13,6 +13,7 @@ set(cockatrice_SOURCES src/game/board/arrow_item.cpp src/game/board/arrow_target.cpp src/game/cards/card_database.cpp + src/game/cards/card_database_manager.cpp src/game/cards/card_database_model.cpp src/game/cards/card_database_parser/card_database_parser.cpp src/game/cards/card_database_parser/cockatrice_xml_3.cpp diff --git a/cockatrice/src/client/network/spoiler_background_updater.cpp b/cockatrice/src/client/network/spoiler_background_updater.cpp index bc696dd31..e60eeb96a 100644 --- a/cockatrice/src/client/network/spoiler_background_updater.cpp +++ b/cockatrice/src/client/network/spoiler_background_updater.cpp @@ -1,6 +1,7 @@ #include "spoiler_background_updater.h" #include "../../game/cards/card_database.h" +#include "../../game/cards/card_database_manager.h" #include "../../main.h" #include "../../settings/cache_settings.h" #include "../ui/window_main.h" @@ -159,7 +160,7 @@ bool SpoilerBackgroundUpdater::saveDownloadedFile(QByteArray data) // Data written, so reload the card database qDebug() << "Spoiler Service Data Written"; - const auto reloadOk = QtConcurrent::run([] { db->loadCardDatabases(); }); + const auto reloadOk = QtConcurrent::run([] { CardDatabaseManager::getInstance()->loadCardDatabases(); }); // If the user has notifications enabled, let them know // when the database was last updated diff --git a/cockatrice/src/client/tabs/tab_deck_editor.cpp b/cockatrice/src/client/tabs/tab_deck_editor.cpp index b7e976f63..c6e4ff758 100644 --- a/cockatrice/src/client/tabs/tab_deck_editor.cpp +++ b/cockatrice/src/client/tabs/tab_deck_editor.cpp @@ -5,6 +5,7 @@ #include "../../deck/deck_list_model.h" #include "../../deck/deck_stats_interface.h" #include "../../dialogs/dlg_load_deck_from_clipboard.h" +#include "../../game/cards/card_database_manager.h" #include "../../game/cards/card_database_model.h" #include "../../game/cards/card_frame.h" #include "../../game/filters/filter_builder.h" @@ -406,7 +407,7 @@ void TabDeckEditor::createCentralFrame() connect(&searchKeySignals, SIGNAL(onCtrlC()), this, SLOT(copyDatabaseCellContents())); connect(help, &QAction::triggered, this, &TabDeckEditor::showSearchSyntaxHelp); - databaseModel = new CardDatabaseModel(db, true, this); + databaseModel = new CardDatabaseModel(CardDatabaseManager::getInstance(), true, this); databaseModel->setObjectName("databaseModel"); databaseDisplayModel = new CardDatabaseDisplayModel(this); databaseDisplayModel->setSourceModel(databaseModel); @@ -975,7 +976,7 @@ CardInfoPtr TabDeckEditor::currentCardInfo() const const QString cardName = currentIndex.sibling(currentIndex.row(), 0).data().toString(); - return db->getCard(cardName); + return CardDatabaseManager::getInstance()->getCard(cardName); } void TabDeckEditor::addCardHelper(QString zoneName) @@ -1112,7 +1113,8 @@ void TabDeckEditor::setDeck(DeckLoader *_deck) deckView->expandAll(); setModified(false); - PictureLoader::cacheCardPixmaps(db->getCards(deckModel->getDeckList()->getCardList())); + PictureLoader::cacheCardPixmaps( + CardDatabaseManager::getInstance()->getCards(deckModel->getDeckList()->getCardList())); deckView->expandAll(); setModified(false); diff --git a/cockatrice/src/client/tabs/tab_game.cpp b/cockatrice/src/client/tabs/tab_game.cpp index a400cbfa9..2b178e003 100644 --- a/cockatrice/src/client/tabs/tab_game.cpp +++ b/cockatrice/src/client/tabs/tab_game.cpp @@ -7,6 +7,7 @@ #include "../../dialogs/dlg_manage_sets.h" #include "../../game/board/arrow_item.h" #include "../../game/cards/card_database.h" +#include "../../game/cards/card_database_manager.h" #include "../../game/cards/card_frame.h" #include "../../game/cards/card_item.h" #include "../../game/game_scene.h" @@ -325,7 +326,7 @@ void DeckViewContainer::deckSelectFinished(const Response &r) { const Response_DeckDownload &resp = r.GetExtension(Response_DeckDownload::ext); DeckLoader newDeck(QString::fromStdString(resp.deck())); - PictureLoader::cacheCardPixmaps(db->getCards(newDeck.getCardList())); + PictureLoader::cacheCardPixmaps(CardDatabaseManager::getInstance()->getCards(newDeck.getCardList())); setDeck(newDeck); } @@ -1109,7 +1110,8 @@ void TabGame::eventGameStateChanged(const Event_GameStateChanged &event, DeckViewContainer *deckViewContainer = deckViewContainers.value(playerId); if (playerInfo.has_deck_list()) { DeckLoader newDeck(QString::fromStdString(playerInfo.deck_list())); - PictureLoader::cacheCardPixmaps(db->getCards(newDeck.getCardList())); + PictureLoader::cacheCardPixmaps( + CardDatabaseManager::getInstance()->getCards(newDeck.getCardList())); deckViewContainer->setDeck(newDeck); player->setDeck(newDeck); } diff --git a/cockatrice/src/client/ui/picture_loader.cpp b/cockatrice/src/client/ui/picture_loader.cpp index 087862651..54585c3d6 100644 --- a/cockatrice/src/client/ui/picture_loader.cpp +++ b/cockatrice/src/client/ui/picture_loader.cpp @@ -1,7 +1,7 @@ #include "picture_loader.h" #include "../../game/cards/card_database.h" -#include "../../main.h" +#include "../../game/cards/card_database_manager.h" #include "../../settings/cache_settings.h" #include "theme_manager.h" diff --git a/cockatrice/src/client/ui/window_main.cpp b/cockatrice/src/client/ui/window_main.cpp index 346fd24e6..773af2b37 100644 --- a/cockatrice/src/client/ui/window_main.cpp +++ b/cockatrice/src/client/ui/window_main.cpp @@ -31,6 +31,7 @@ #include "../../dialogs/dlg_update.h" #include "../../dialogs/dlg_view_log.h" #include "../../game/cards/card_database.h" +#include "../../game/cards/card_database_manager.h" #include "../../main.h" #include "../../server/local_client.h" #include "../../server/local_server.h" @@ -858,11 +859,12 @@ MainWindow::MainWindow(QWidget *parent) connect(&SettingsCache::instance().shortcuts(), SIGNAL(shortCutChanged()), this, SLOT(refreshShortcuts())); refreshShortcuts(); - - connect(db, SIGNAL(cardDatabaseLoadingFailed()), this, SLOT(cardDatabaseLoadingFailed())); - connect(db, SIGNAL(cardDatabaseNewSetsFound(int, QStringList)), this, + connect(CardDatabaseManager::getInstance(), SIGNAL(cardDatabaseLoadingFailed()), this, + SLOT(cardDatabaseLoadingFailed())); + connect(CardDatabaseManager::getInstance(), SIGNAL(cardDatabaseNewSetsFound(int, QStringList)), this, SLOT(cardDatabaseNewSetsFound(int, QStringList))); - connect(db, SIGNAL(cardDatabaseAllNewSetsEnabled()), this, SLOT(cardDatabaseAllNewSetsEnabled())); + connect(CardDatabaseManager::getInstance(), SIGNAL(cardDatabaseAllNewSetsEnabled()), this, + SLOT(cardDatabaseAllNewSetsEnabled())); tip = new DlgTipOfTheDay(); @@ -884,13 +886,13 @@ void MainWindow::startupConfigCheck() if (SettingsCache::instance().getNotifyAboutNewVersion()) { alertForcedOracleRun(VERSION_STRING, true); } else { - const auto reloadOk0 = QtConcurrent::run([] { db->loadCardDatabases(); }); + const auto reloadOk0 = QtConcurrent::run([] { CardDatabaseManager::getInstance()->loadCardDatabases(); }); } SettingsCache::instance().setClientVersion(VERSION_STRING); } else { // previous config from this version found qDebug() << "Startup: found config with current version"; - const auto reloadOk1 = QtConcurrent::run([] { db->loadCardDatabases(); }); + const auto reloadOk1 = QtConcurrent::run([] { CardDatabaseManager::getInstance()->loadCardDatabases(); }); // Run the tips dialog only on subsequent startups. // On the first run after an install/update the startup is already crowded enough @@ -1075,12 +1077,12 @@ void MainWindow::cardDatabaseNewSetsFound(int numUnknownSets, QStringList unknow msgBox.exec(); if (msgBox.clickedButton() == yesButton) { - db->enableAllUnknownSets(); - const auto reloadOk1 = QtConcurrent::run([] { db->loadCardDatabases(); }); + CardDatabaseManager::getInstance()->enableAllUnknownSets(); + const auto reloadOk1 = QtConcurrent::run([] { CardDatabaseManager::getInstance()->loadCardDatabases(); }); } else if (msgBox.clickedButton() == noButton) { - db->markAllSetsAsKnown(); + CardDatabaseManager::getInstance()->markAllSetsAsKnown(); } else if (msgBox.clickedButton() == settingsButton) { - db->markAllSetsAsKnown(); + CardDatabaseManager::getInstance()->markAllSetsAsKnown(); actManageSets(); } } @@ -1167,7 +1169,7 @@ void MainWindow::exitCardDatabaseUpdate() cardUpdateProcess->deleteLater(); cardUpdateProcess = nullptr; - const auto reloadOk1 = QtConcurrent::run([] { db->loadCardDatabases(); }); + const auto reloadOk1 = QtConcurrent::run([] { CardDatabaseManager::getInstance()->loadCardDatabases(); }); } void MainWindow::cardUpdateError(QProcess::ProcessError err) @@ -1297,7 +1299,7 @@ void MainWindow::actAddCustomSet() QMessageBox::information( this, tr("Load sets/cards"), tr("The new sets/cards have been added successfully.\nCockatrice will now reload the card database.")); - const auto reloadOk1 = QtConcurrent::run([] { db->loadCardDatabases(); }); + const auto reloadOk1 = QtConcurrent::run([] { CardDatabaseManager::getInstance()->loadCardDatabases(); }); } else { QMessageBox::warning(this, tr("Load sets/cards"), tr("Sets/cards failed to import.")); } @@ -1328,7 +1330,7 @@ void MainWindow::actEditTokens() { DlgEditTokens dlg(this); dlg.exec(); - db->saveCustomTokensToFile(); + CardDatabaseManager::getInstance()->saveCustomTokensToFile(); } void MainWindow::actForgotPasswordRequest() diff --git a/cockatrice/src/deck/deck_list_model.cpp b/cockatrice/src/deck/deck_list_model.cpp index 942d715ac..f2ef81307 100644 --- a/cockatrice/src/deck/deck_list_model.cpp +++ b/cockatrice/src/deck/deck_list_model.cpp @@ -1,6 +1,7 @@ #include "deck_list_model.h" #include "../game/cards/card_database.h" +#include "../game/cards/card_database_manager.h" #include "../main.h" #include "../settings/cache_settings.h" #include "deck_loader.h" @@ -49,7 +50,7 @@ void DeckListModel::rebuildTree() continue; } - CardInfoPtr info = db->getCard(currentCard->getName()); + CardInfoPtr info = CardDatabaseManager::getInstance()->getCard(currentCard->getName()); QString cardType = info ? info->getMainCardType() : "unknown"; auto *cardTypeNode = dynamic_cast(node->findChild(cardType)); @@ -289,7 +290,7 @@ DecklistModelCardNode *DeckListModel::findCardNode(const QString &cardName, cons return nullptr; } - info = db->getCard(cardName); + info = CardDatabaseManager::getInstance()->getCard(cardName); if (!info) { return nullptr; } @@ -317,7 +318,7 @@ QModelIndex DeckListModel::findCard(const QString &cardName, const QString &zone QModelIndex DeckListModel::addCard(const QString &cardName, const QString &zoneName, bool abAddAnyway) { - CardInfoPtr info = db->getCard(cardName); + CardInfoPtr info = CardDatabaseManager::getInstance()->getCard(cardName); if (info == nullptr) { if (abAddAnyway) { // We need to keep this card added no matter what diff --git a/cockatrice/src/deck/deck_loader.cpp b/cockatrice/src/deck/deck_loader.cpp index 3d7c5831b..685c033a3 100644 --- a/cockatrice/src/deck/deck_loader.cpp +++ b/cockatrice/src/deck/deck_loader.cpp @@ -1,6 +1,7 @@ #include "deck_loader.h" #include "../game/cards/card_database.h" +#include "../game/cards/card_database_manager.h" #include "../main.h" #include "decklist.h" @@ -124,7 +125,7 @@ struct FormatDeckListForExport void operator()(const InnerDecklistNode *node, const DecklistCardNode *card) const { // Get the card name - CardInfoPtr dbCard = db->getCard(card->getName()); + CardInfoPtr dbCard = CardDatabaseManager::getInstance()->getCard(card->getName()); if (!dbCard || dbCard->getIsToken()) { // If it's a token, we don't care about the card. return; @@ -227,7 +228,7 @@ void DeckLoader::saveToStream_DeckZone(QTextStream &out, const InnerDecklistNode for (int j = 0; j < zoneNode->size(); j++) { auto *card = dynamic_cast(zoneNode->at(j)); - CardInfoPtr info = db->getCard(card->getName()); + CardInfoPtr info = CardDatabaseManager::getInstance()->getCard(card->getName()); QString cardType = info ? info->getMainCardType() : "unknown"; cardsByType.insert(cardType, card); @@ -280,7 +281,7 @@ void DeckLoader::saveToStream_DeckZoneCards(QTextStream &out, QString DeckLoader::getCardZoneFromName(QString cardName, QString currentZoneName) { - CardInfoPtr card = db->getCard(cardName); + CardInfoPtr card = CardDatabaseManager::getInstance()->getCard(cardName); if (card && card->getIsToken()) { return DECK_ZONE_TOKENS; @@ -291,8 +292,8 @@ QString DeckLoader::getCardZoneFromName(QString cardName, QString currentZoneNam QString DeckLoader::getCompleteCardName(const QString &cardName) const { - if (db) { - CardInfoPtr temp = db->guessCard(cardName); + if (CardDatabaseManager::getInstance()) { + CardInfoPtr temp = CardDatabaseManager::getInstance()->guessCard(cardName); if (temp) { return temp->getName(); } diff --git a/cockatrice/src/dialogs/dlg_create_token.cpp b/cockatrice/src/dialogs/dlg_create_token.cpp index c668fe04b..b661d8651 100644 --- a/cockatrice/src/dialogs/dlg_create_token.cpp +++ b/cockatrice/src/dialogs/dlg_create_token.cpp @@ -1,5 +1,6 @@ #include "dlg_create_token.h" +#include "../game/cards/card_database_manager.h" #include "../game/cards/card_database_model.h" #include "../game/cards/card_info_picture.h" #include "../main.h" @@ -72,7 +73,7 @@ DlgCreateToken::DlgCreateToken(const QStringList &_predefinedTokens, QWidget *pa QGroupBox *tokenDataGroupBox = new QGroupBox(tr("Token data")); tokenDataGroupBox->setLayout(grid); - cardDatabaseModel = new CardDatabaseModel(db, false, this); + cardDatabaseModel = new CardDatabaseModel(CardDatabaseManager::getInstance(), false, this); cardDatabaseDisplayModel = new TokenDisplayModel(this); cardDatabaseDisplayModel->setSourceModel(cardDatabaseModel); diff --git a/cockatrice/src/dialogs/dlg_edit_tokens.cpp b/cockatrice/src/dialogs/dlg_edit_tokens.cpp index 6275e90bb..7d47f642c 100644 --- a/cockatrice/src/dialogs/dlg_edit_tokens.cpp +++ b/cockatrice/src/dialogs/dlg_edit_tokens.cpp @@ -2,6 +2,7 @@ #include "../client/get_text_with_max.h" #include "../game/cards/card_database.h" +#include "../game/cards/card_database_manager.h" #include "../game/cards/card_database_model.h" #include "../main.h" #include "trice_limits.h" @@ -66,7 +67,7 @@ DlgEditTokens::DlgEditTokens(QWidget *parent) : QDialog(parent), currentCard(nul QGroupBox *tokenDataGroupBox = new QGroupBox(tr("Token data")); tokenDataGroupBox->setLayout(grid); - databaseModel = new CardDatabaseModel(db, false, this); + databaseModel = new CardDatabaseModel(CardDatabaseManager::getInstance(), false, this); databaseModel->setObjectName("databaseModel"); cardDatabaseDisplayModel = new TokenEditModel(this); cardDatabaseDisplayModel->setSourceModel(databaseModel); diff --git a/cockatrice/src/dialogs/dlg_manage_sets.cpp b/cockatrice/src/dialogs/dlg_manage_sets.cpp index 153018a2d..b547a6ed0 100644 --- a/cockatrice/src/dialogs/dlg_manage_sets.cpp +++ b/cockatrice/src/dialogs/dlg_manage_sets.cpp @@ -3,6 +3,7 @@ #include "../client/network/sets_model.h" #include "../client/ui/picture_loader.h" #include "../deck/custom_line_edit.h" +#include "../game/cards/card_database_manager.h" #include "../main.h" #include "../settings/cache_settings.h" @@ -79,7 +80,7 @@ WndSets::WndSets(QWidget *parent) : QMainWindow(parent) filterBox->addWidget(defaultSortButton); // view - model = new SetsModel(db, this); + model = new SetsModel(CardDatabaseManager::getInstance(), this); displayModel = new SetsDisplayModel(this); displayModel->setSourceModel(model); displayModel->setDynamicSortFilter(false); @@ -239,14 +240,14 @@ void WndSets::rebuildMainLayout(int actionToTake) void WndSets::actSave() { - model->save(db); + model->save(CardDatabaseManager::getInstance()); PictureLoader::clearPixmapCache(); close(); } void WndSets::actRestore() { - model->restore(db); + model->restore(CardDatabaseManager::getInstance()); close(); } diff --git a/cockatrice/src/dialogs/dlg_settings.cpp b/cockatrice/src/dialogs/dlg_settings.cpp index 410c6d45c..3467f9404 100644 --- a/cockatrice/src/dialogs/dlg_settings.cpp +++ b/cockatrice/src/dialogs/dlg_settings.cpp @@ -7,6 +7,7 @@ #include "../client/ui/picture_loader.h" #include "../client/ui/theme_manager.h" #include "../game/cards/card_database.h" +#include "../game/cards/card_database_manager.h" #include "../main.h" #include "../settings/cache_settings.h" #include "../utility/sequence_edit.h" @@ -1429,7 +1430,7 @@ void DlgSettings::closeEvent(QCloseEvent *event) { bool showLoadError = true; QString loadErrorMessage = tr("Unknown Error loading card database"); - LoadStatus loadStatus = db->getLoadStatus(); + LoadStatus loadStatus = CardDatabaseManager::getInstance()->getLoadStatus(); qDebug() << "Card Database load status: " << loadStatus; switch (loadStatus) { case Ok: diff --git a/cockatrice/src/game/cards/abstract_card_item.cpp b/cockatrice/src/game/cards/abstract_card_item.cpp index e7d902b31..139ca6a08 100644 --- a/cockatrice/src/game/cards/abstract_card_item.cpp +++ b/cockatrice/src/game/cards/abstract_card_item.cpp @@ -5,6 +5,7 @@ #include "../../settings/cache_settings.h" #include "../game_scene.h" #include "card_database.h" +#include "card_database_manager.h" #include #include @@ -49,7 +50,7 @@ void AbstractCardItem::pixmapUpdated() void AbstractCardItem::cardInfoUpdated() { - info = db->getCard(name); + info = CardDatabaseManager::getInstance()->getCard(name); if (!info && !name.isEmpty()) { QVariantHash properties = QVariantHash(); diff --git a/cockatrice/src/game/cards/card_database_manager.cpp b/cockatrice/src/game/cards/card_database_manager.cpp new file mode 100644 index 000000000..3036402f0 --- /dev/null +++ b/cockatrice/src/game/cards/card_database_manager.cpp @@ -0,0 +1,7 @@ +#include "card_database_manager.h" + +CardDatabase *CardDatabaseManager::getInstance() +{ + static CardDatabase instance; // Created only once, on first access + return &instance; +} \ No newline at end of file diff --git a/cockatrice/src/game/cards/card_database_manager.h b/cockatrice/src/game/cards/card_database_manager.h new file mode 100644 index 000000000..f257dcdef --- /dev/null +++ b/cockatrice/src/game/cards/card_database_manager.h @@ -0,0 +1,23 @@ + +#ifndef CARD_DATABASE_ACCESSOR_H +#define CARD_DATABASE_ACCESSOR_H + +#pragma once +#include "card_database.h" + +class CardDatabaseManager +{ +public: + // Delete copy constructor and assignment operator to enforce singleton + CardDatabaseManager(const CardDatabaseManager &) = delete; + CardDatabaseManager &operator=(const CardDatabaseManager &) = delete; + + // Static method to access the singleton instance + static CardDatabase *getInstance(); + +private: + CardDatabaseManager() = default; // Private constructor + ~CardDatabaseManager() = default; +}; + +#endif // CARD_DATABASE_ACCESSOR_H diff --git a/cockatrice/src/game/cards/card_frame.cpp b/cockatrice/src/game/cards/card_frame.cpp index c8efb5643..46ef5b84e 100644 --- a/cockatrice/src/game/cards/card_frame.cpp +++ b/cockatrice/src/game/cards/card_frame.cpp @@ -2,6 +2,7 @@ #include "../../main.h" #include "../../settings/cache_settings.h" +#include "card_database_manager.h" #include "card_info_picture.h" #include "card_info_text.h" #include "card_item.h" @@ -57,7 +58,7 @@ CardFrame::CardFrame(const QString &cardName, QWidget *parent) : QTabWidget(pare setViewMode(SettingsCache::instance().getCardInfoViewMode()); - setCard(db->getCard(cardName)); + setCard(CardDatabaseManager::getInstance()->getCard(cardName)); } void CardFrame::retranslateUi() @@ -107,7 +108,7 @@ void CardFrame::setCard(CardInfoPtr card) void CardFrame::setCard(const QString &cardName) { - setCard(db->guessCard(cardName)); + setCard(CardDatabaseManager::getInstance()->guessCard(cardName)); } void CardFrame::setCard(AbstractCardItem *card) diff --git a/cockatrice/src/game/cards/card_info_widget.cpp b/cockatrice/src/game/cards/card_info_widget.cpp index 2dbea8d65..6cba8a8a6 100644 --- a/cockatrice/src/game/cards/card_info_widget.cpp +++ b/cockatrice/src/game/cards/card_info_widget.cpp @@ -1,6 +1,7 @@ #include "card_info_widget.h" #include "../../main.h" +#include "card_database_manager.h" #include "card_info_picture.h" #include "card_info_text.h" #include "card_item.h" @@ -56,7 +57,7 @@ void CardInfoWidget::setCard(CardInfoPtr card) void CardInfoWidget::setCard(const QString &cardName) { - setCard(db->guessCard(cardName)); + setCard(CardDatabaseManager::getInstance()->guessCard(cardName)); if (info == nullptr) { text->setInvalidCardName(cardName); } diff --git a/cockatrice/src/game/player/player.cpp b/cockatrice/src/game/player/player.cpp index 5cdfe7629..e20b60451 100644 --- a/cockatrice/src/game/player/player.cpp +++ b/cockatrice/src/game/player/player.cpp @@ -11,6 +11,7 @@ #include "../board/arrow_item.h" #include "../board/counter_general.h" #include "../cards/card_database.h" +#include "../cards/card_database_manager.h" #include "../cards/card_item.h" #include "../cards/card_list.h" #include "../game_scene.h" @@ -1642,7 +1643,7 @@ void Player::actCreateToken() lastTokenName = dlg.getName(); lastTokenPT = dlg.getPT(); - CardInfoPtr correctedCard = db->guessCard(lastTokenName); + CardInfoPtr correctedCard = CardDatabaseManager::getInstance()->guessCard(lastTokenName); if (correctedCard) { lastTokenName = correctedCard->getName(); lastTokenTableRow = TableZone::clampValidTableRow(2 - correctedCard->getTableRow()); @@ -1680,7 +1681,7 @@ void Player::actCreateAnotherToken() void Player::actCreatePredefinedToken() { auto *action = static_cast(sender()); - CardInfoPtr cardInfo = db->getCard(action->text()); + CardInfoPtr cardInfo = CardDatabaseManager::getInstance()->getCard(action->text()); if (!cardInfo) { return; } @@ -1706,7 +1707,7 @@ void Player::actCreateRelatedCard() * then let's allow it to be created via "create another token" */ if (createRelatedFromRelation(sourceCard, cardRelation) && cardRelation->getCanCreateAnother()) { - CardInfoPtr cardInfo = db->getCard(cardRelation->getName()); + CardInfoPtr cardInfo = CardDatabaseManager::getInstance()->getCard(cardRelation->getName()); setLastToken(cardInfo); } } @@ -1786,7 +1787,7 @@ void Player::actCreateAllRelatedCards() * then assign the first to the "Create another" shortcut. */ if (cardRelation != nullptr && cardRelation->getCanCreateAnother()) { - CardInfoPtr cardInfo = db->getCard(cardRelation->getName()); + CardInfoPtr cardInfo = CardDatabaseManager::getInstance()->getCard(cardRelation->getName()); setLastToken(cardInfo); } } @@ -1825,7 +1826,7 @@ void Player::createCard(const CardItem *sourceCard, CardRelation::AttachType attachType, bool persistent) { - CardInfoPtr cardInfo = db->getCard(dbCardName); + CardInfoPtr cardInfo = CardDatabaseManager::getInstance()->getCard(dbCardName); if (cardInfo == nullptr || sourceCard == nullptr) { return; @@ -3632,7 +3633,7 @@ void Player::addRelatedCardView(const CardItem *card, QMenu *cardMenu) bool atLeastOneGoodRelationFound = false; QList relatedCards = cardInfo->getAllRelatedCards(); for (const CardRelation *cardRelation : relatedCards) { - CardInfoPtr relatedCard = db->getCard(cardRelation->getName()); + CardInfoPtr relatedCard = CardDatabaseManager::getInstance()->getCard(cardRelation->getName()); if (relatedCard != nullptr) { atLeastOneGoodRelationFound = true; break; @@ -3672,7 +3673,7 @@ void Player::addRelatedCardActions(const CardItem *card, QMenu *cardMenu) int index = 0; QAction *createRelatedCards = nullptr; for (const CardRelation *cardRelation : relatedCards) { - CardInfoPtr relatedCard = db->getCard(cardRelation->getName()); + CardInfoPtr relatedCard = CardDatabaseManager::getInstance()->getCard(cardRelation->getName()); if (relatedCard == nullptr) continue; diff --git a/cockatrice/src/main.cpp b/cockatrice/src/main.cpp index cc5bc5967..96d521d23 100644 --- a/cockatrice/src/main.cpp +++ b/cockatrice/src/main.cpp @@ -47,7 +47,6 @@ #include #include -CardDatabase *db; QTranslator *translator, *qtTranslator; RNG_Abstract *rng; SoundEngine *soundEngine; @@ -151,7 +150,6 @@ int main(int argc, char *argv[]) rng = new RNG_SFMT; themeManager = new ThemeManager; soundEngine = new SoundEngine; - db = new CardDatabase; qtTranslator = new QTranslator; translator = new QTranslator; @@ -188,7 +186,6 @@ int main(int argc, char *argv[]) app.exec(); qDebug("Event loop finished, terminating..."); - delete db; delete rng; PingPixmapGenerator::clear(); CountryPixmapGenerator::clear(); diff --git a/dbconverter/src/main.h b/dbconverter/src/main.h index 67e64c14d..d0aafbff9 100644 --- a/dbconverter/src/main.h +++ b/dbconverter/src/main.h @@ -1,8 +1,8 @@ #ifndef MAIN_H #define MAIN_H -#include "../cockatrice/src/game/cards/card_database.h" -#include "../cockatrice/src/game/cards/card_database_parser/cockatrice_xml_4.h" +#include "../../cockatrice/src/game/cards/card_database.h" +#include "../../cockatrice/src/game/cards/card_database_parser/cockatrice_xml_4.h" class CardDatabaseConverter : public CardDatabase { diff --git a/oracle/CMakeLists.txt b/oracle/CMakeLists.txt index 155933308..218621317 100644 --- a/oracle/CMakeLists.txt +++ b/oracle/CMakeLists.txt @@ -17,6 +17,7 @@ set(oracle_SOURCES src/pagetemplates.cpp src/qt-json/json.cpp ../cockatrice/src/game/cards/card_database.cpp + ../cockatrice/src/game/cards/card_database_manager.cpp ../cockatrice/src/client/ui/picture_loader.cpp ../cockatrice/src/game/cards/card_database_parser/card_database_parser.cpp ../cockatrice/src/game/cards/card_database_parser/cockatrice_xml_3.cpp diff --git a/tests/carddatabase/CMakeLists.txt b/tests/carddatabase/CMakeLists.txt index a54432f54..3ca812c22 100644 --- a/tests/carddatabase/CMakeLists.txt +++ b/tests/carddatabase/CMakeLists.txt @@ -31,6 +31,7 @@ add_executable( ${MOCKS_SOURCES} ${VERSION_STRING_CPP} ../../cockatrice/src/game/cards/card_database.cpp + ../../cockatrice/src/game/cards/card_database_manager.cpp ../../cockatrice/src/game/cards/card_database_parser/card_database_parser.cpp ../../cockatrice/src/game/cards/card_database_parser/cockatrice_xml_3.cpp ../../cockatrice/src/game/cards/card_database_parser/cockatrice_xml_4.cpp diff --git a/tests/carddatabase/filter_string_test.cpp b/tests/carddatabase/filter_string_test.cpp index d8fa41ff1..4fa139514 100644 --- a/tests/carddatabase/filter_string_test.cpp +++ b/tests/carddatabase/filter_string_test.cpp @@ -1,10 +1,9 @@ +#include "../../cockatrice/src/game/cards/card_database_manager.h" #include "../../cockatrice/src/game/filters/filter_string.h" #include "mocks.h" #include "gtest/gtest.h" -CardDatabase *db; - #define QUERY(name, card, query, match) \ TEST_F(CardQuery, name) \ { \ @@ -19,7 +18,7 @@ class CardQuery : public ::testing::Test protected: void SetUp() override { - cat = db->getCardBySimpleName("Cat"); + cat = CardDatabaseManager::getInstance()->getCardBySimpleName("Cat"); } // void TearDown() override {} @@ -59,8 +58,7 @@ QUERY(Color4, cat, "c!gw", false) int main(int argc, char **argv) { settingsCache = new SettingsCache; - db = new CardDatabase; - db->loadCardDatabases(); + CardDatabaseManager::getInstance()->loadCardDatabases(); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS();