From c54f47efbf1186720d7a4d93e9a72d2af5723680 Mon Sep 17 00:00:00 2001 From: BruebachL <44814898+BruebachL@users.noreply.github.com> Date: Sun, 10 Nov 2024 23:49:11 +0100 Subject: [PATCH] Change CardInfo's PixmapCacheKey to be the UUID of the card in the preferred set after database loading has finished. Otherwise, and if no UUID of a preferred set is available, default to the card name. (#5158) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Change CardInfo's PixmapCacheKey to be the UUID of the preferred set after database loading has finished. Otherwise, and if no UUID of a preferred set is available, default to the card name. * Clean up some variable names, clarify preferred Set insertion for PictureLoader, use the new CardDatabaseManager. * Code formatting. --------- Co-authored-by: Lukas BrĂ¼bach --- cockatrice/src/client/ui/picture_loader.cpp | 15 +++- cockatrice/src/game/cards/card_database.cpp | 73 ++++++++++++++++++++ cockatrice/src/game/cards/card_database.h | 25 +++++++ cockatrice/src/utility/card_set_comparator.h | 24 +++++++ 4 files changed, 135 insertions(+), 2 deletions(-) create mode 100644 cockatrice/src/utility/card_set_comparator.h diff --git a/cockatrice/src/client/ui/picture_loader.cpp b/cockatrice/src/client/ui/picture_loader.cpp index 54585c3d6..e30e5fc58 100644 --- a/cockatrice/src/client/ui/picture_loader.cpp +++ b/cockatrice/src/client/ui/picture_loader.cpp @@ -43,6 +43,14 @@ PictureToLoad::PictureToLoad(CardInfoPtr _card) sortedSets << CardSet::newInstance("", "", "", QDate()); } std::sort(sortedSets.begin(), sortedSets.end(), SetDownloadPriorityComparator()); + // If the pixmapCacheKey corresponds to a specific set, we have to try to load it first. + for (const auto &set : card->getSets()) { + if (QLatin1String("card_") + QString(set.getProperty("uuid")) == card->getPixmapCacheKey()) { + long long setIndex = sortedSets.indexOf(set.getPtr()); + CardSetPtr setForCardUUID = sortedSets.takeAt(setIndex); + sortedSets.prepend(setForCardUUID); + } + } // The first time called, nextSet will also populate the Urls for the first set. nextSet(); } @@ -170,8 +178,11 @@ void PictureLoaderWorker::processLoadQueue() qDebug().nospace() << "PictureLoader: [card: " << cardName << " set: " << setName << "]: Trying to load picture"; - if (cardImageExistsOnDisk(setName, correctedCardName)) { - continue; + if (CardDatabaseManager::getInstance()->isUuidForPreferredPrinting( + cardName, cardBeingLoaded.getCard()->getPixmapCacheKey())) { + if (cardImageExistsOnDisk(setName, correctedCardName)) { + continue; + } } qDebug().nospace() << "PictureLoader: [card: " << cardName << " set: " << setName diff --git a/cockatrice/src/game/cards/card_database.cpp b/cockatrice/src/game/cards/card_database.cpp index 881005590..9cff3d199 100644 --- a/cockatrice/src/game/cards/card_database.cpp +++ b/cockatrice/src/game/cards/card_database.cpp @@ -3,6 +3,7 @@ #include "../../client/network/spoiler_background_updater.h" #include "../../client/ui/picture_loader.h" #include "../../settings/cache_settings.h" +#include "../../utility/card_set_comparator.h" #include "../game_specific_terms.h" #include "./card_database_parser/cockatrice_xml_3.h" #include "./card_database_parser/cockatrice_xml_4.h" @@ -440,6 +441,19 @@ QList CardDatabase::getCards(const QStringList &cardNames) const return cardInfos; } +CardInfoPtr CardDatabase::getCardByNameAndUUID(const QString &cardName, const QString &uuid) const +{ + auto info = getCard(cardName); + for (const auto &set : info->getSets()) { + if (set.getProperty("uuid") == uuid) { + CardInfoPtr cardFromSpecificSet = info->clone(); + cardFromSpecificSet->setPixmapCacheKey(QLatin1String("card_") + QString(set.getProperty("uuid"))); + return cardFromSpecificSet; + } + } + return {}; +} + CardInfoPtr CardDatabase::getCardBySimpleName(const QString &cardName) const { return getCardFromMap(simpleNameCards, CardInfo::simplifyName(cardName)); @@ -561,6 +575,8 @@ LoadStatus CardDatabase::loadCardDatabases() // AFTER all the cards have been loaded + // Refresh the pixmap cache keys for all cards by setting them to the UUID of the preferred printing + refreshPreferredPrintings(); // resolve the reverse-related tags refreshCachedReverseRelatedCards(); @@ -577,6 +593,63 @@ LoadStatus CardDatabase::loadCardDatabases() return loadStatus; } +void CardDatabase::refreshPreferredPrintings() +{ + for (const CardInfoPtr &card : cards) { + card->setPixmapCacheKey(QLatin1String("card_") + QString(getPreferredPrintingUUIDForCard(card->getName()))); + } +} + +CardInfoPerSet CardDatabase::getPreferredSetForCard(const QString &cardName) +{ + CardInfoPtr cardInfo = getCard(cardName); + if (!cardInfo) { + return CardInfoPerSet(nullptr); + } + + CardInfoPerSetMap setMap = cardInfo->getSets(); + if (setMap.empty()) { + return CardInfoPerSet(nullptr); + } + + CardSetPtr preferredSet = nullptr; + CardInfoPerSet preferredCard; + SetPriorityComparator comparator; + + for (auto &cardInfoForSet : setMap) { + CardSetPtr currentSet = cardInfoForSet.getPtr(); + if (!preferredSet || comparator(currentSet, preferredSet)) { + preferredSet = currentSet; + preferredCard = cardInfoForSet; + } + } + + if (preferredSet) { + return preferredCard; + } + + return CardInfoPerSet(nullptr); +} + +QString CardDatabase::getPreferredPrintingUUIDForCard(const QString &cardName) +{ + CardInfoPerSet preferredSetCardInfo = getPreferredSetForCard(cardName); + QString preferredPrintingUUID = preferredSetCardInfo.getProperty(QString("uuid")); + if (preferredPrintingUUID.isEmpty()) { + CardInfoPtr defaultCardInfo = getCard(cardName); + if (defaultCardInfo.isNull()) { + return cardName; + } + return defaultCardInfo->getName(); + } + return preferredPrintingUUID; +} + +bool CardDatabase::isUuidForPreferredPrinting(const QString &cardName, const QString &uuid) +{ + return uuid == getPreferredPrintingUUIDForCard(cardName); +} + void CardDatabase::refreshCachedReverseRelatedCards() { for (const CardInfoPtr &card : cards) diff --git a/cockatrice/src/game/cards/card_database.h b/cockatrice/src/game/cards/card_database.h index 9cb0e85a6..5d360d39d 100644 --- a/cockatrice/src/game/cards/card_database.h +++ b/cockatrice/src/game/cards/card_database.h @@ -188,6 +188,14 @@ public: bool _cipt = false, int _tableRow = 0, bool _upsideDownArt = false); + CardInfo(const CardInfo &other) + : QObject(other.parent()), name(other.name), simpleName(other.simpleName), pixmapCacheKey(other.pixmapCacheKey), + text(other.text), isToken(other.isToken), properties(other.properties), relatedCards(other.relatedCards), + reverseRelatedCards(other.reverseRelatedCards), reverseRelatedCardsToMe(other.reverseRelatedCardsToMe), + sets(other.sets), setsNames(other.setsNames), cipt(other.cipt), tableRow(other.tableRow), + upsideDownArt(other.upsideDownArt) + { + } ~CardInfo() override; static CardInfoPtr newInstance(const QString &_name = QString(), @@ -201,6 +209,14 @@ public: int _tableRow = 0, bool _upsideDownArt = false); + CardInfoPtr clone() const + { + // Use the copy constructor to create a new instance + CardInfoPtr newCardInfo = CardInfoPtr(new CardInfo(*this)); + newCardInfo->setSmartPointer(newCardInfo); // Set the smart pointer for the new instance + return newCardInfo; + } + void setSmartPointer(CardInfoPtr _ptr) { smartThis = std::move(_ptr); @@ -215,6 +231,10 @@ public: { return simpleName; } + void setPixmapCacheKey(QString _pixmapCacheKey) + { + pixmapCacheKey = _pixmapCacheKey; + } const QString &getPixmapCacheKey() const { return pixmapCacheKey; @@ -394,6 +414,8 @@ protected: private: CardInfoPtr getCardFromMap(const CardNameMap &cardMap, const QString &cardName) const; void checkUnknownSets(); + CardInfoPerSet getPreferredSetForCard(const QString &cardName); + QString getPreferredPrintingUUIDForCard(const QString &cardName); void refreshCachedReverseRelatedCards(); QBasicMutex *reloadDatabaseMutex = new QBasicMutex(), *clearDatabaseMutex = new QBasicMutex(), @@ -409,6 +431,7 @@ public: void removeCard(CardInfoPtr card); CardInfoPtr getCard(const QString &cardName) const; QList getCards(const QStringList &cardNames) const; + CardInfoPtr getCardByNameAndUUID(const QString &cardName, const QString &uuid) const; CardInfoPtr guessCard(const QString &cardName) const; /* @@ -418,6 +441,7 @@ public: CardInfoPtr getCardBySimpleName(const QString &cardName) const; CardSetPtr getSet(const QString &setName); + bool isUuidForPreferredPrinting(const QString &cardName, const QString &uuid); QList getCardList() const { return cards.values(); @@ -436,6 +460,7 @@ public: public slots: LoadStatus loadCardDatabases(); + void refreshPreferredPrintings(); void addCard(CardInfoPtr card); void addSet(CardSetPtr set); protected slots: diff --git a/cockatrice/src/utility/card_set_comparator.h b/cockatrice/src/utility/card_set_comparator.h new file mode 100644 index 000000000..1aa1500fb --- /dev/null +++ b/cockatrice/src/utility/card_set_comparator.h @@ -0,0 +1,24 @@ +#ifndef SET_PRIORITY_COMPARATOR_H +#define SET_PRIORITY_COMPARATOR_H + +#include "../game/cards/card_database.h" + +class SetPriorityComparator +{ +public: + /* + * Returns true if a has higher download priority than b + * Enabled sets have priority over disabled sets + * Both groups follow the user-defined order + */ + inline bool operator()(const CardSetPtr &a, const CardSetPtr &b) const + { + if (a->getEnabled()) { + return !b->getEnabled() || a->getSortKey() < b->getSortKey(); + } else { + return !b->getEnabled() && a->getSortKey() < b->getSortKey(); + } + } +}; + +#endif // SET_PRIORITY_COMPARATOR_H \ No newline at end of file