mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-06-12 17:14:52 -07:00
Compute deck hashes lazily (#5707)
* Calculate deck hashes lazily * rename
This commit is contained in:
parent
9b00bdcaea
commit
ec536126b9
3 changed files with 43 additions and 21 deletions
|
|
@ -262,7 +262,7 @@ bool DeckListModel::setData(const QModelIndex &index, const QVariant &value, con
|
||||||
}
|
}
|
||||||
|
|
||||||
emitRecursiveUpdates(index);
|
emitRecursiveUpdates(index);
|
||||||
deckList->updateDeckHash();
|
deckList->refreshDeckHash();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -398,7 +398,7 @@ QModelIndex DeckListModel::addCard(const QString &cardName,
|
||||||
cardNode->setCardSetShortName(cardSetName);
|
cardNode->setCardSetShortName(cardSetName);
|
||||||
cardNode->setCardCollectorNumber(cardInfoSet.getProperty("num"));
|
cardNode->setCardCollectorNumber(cardInfoSet.getProperty("num"));
|
||||||
cardNode->setCardProviderId(cardInfoSet.getProperty("uuid"));
|
cardNode->setCardProviderId(cardInfoSet.getProperty("uuid"));
|
||||||
deckList->updateDeckHash();
|
deckList->refreshDeckHash();
|
||||||
}
|
}
|
||||||
sort(lastKnownColumn, lastKnownOrder);
|
sort(lastKnownColumn, lastKnownOrder);
|
||||||
emitRecursiveUpdates(parentIndex);
|
emitRecursiveUpdates(parentIndex);
|
||||||
|
|
|
||||||
|
|
@ -368,8 +368,8 @@ DeckList::DeckList()
|
||||||
|
|
||||||
// TODO: https://qt-project.org/doc/qt-4.8/qobject.html#no-copy-constructor-or-assignment-operator
|
// TODO: https://qt-project.org/doc/qt-4.8/qobject.html#no-copy-constructor-or-assignment-operator
|
||||||
DeckList::DeckList(const DeckList &other)
|
DeckList::DeckList(const DeckList &other)
|
||||||
: QObject(), name(other.name), comments(other.comments), bannerCard(other.bannerCard), deckHash(other.deckHash),
|
: QObject(), name(other.name), comments(other.comments), bannerCard(other.bannerCard),
|
||||||
lastLoadedTimestamp(other.lastLoadedTimestamp), tags(other.tags)
|
lastLoadedTimestamp(other.lastLoadedTimestamp), tags(other.tags), cachedDeckHash(other.cachedDeckHash)
|
||||||
{
|
{
|
||||||
root = new InnerDecklistNode(other.getRoot());
|
root = new InnerDecklistNode(other.getRoot());
|
||||||
|
|
||||||
|
|
@ -378,7 +378,6 @@ DeckList::DeckList(const DeckList &other)
|
||||||
spIterator.next();
|
spIterator.next();
|
||||||
sideboardPlans.insert(spIterator.key(), new SideboardPlan(spIterator.key(), spIterator.value()->getMoveList()));
|
sideboardPlans.insert(spIterator.key(), new SideboardPlan(spIterator.key(), spIterator.value()->getMoveList()));
|
||||||
}
|
}
|
||||||
updateDeckHash();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DeckList::DeckList(const QString &nativeString)
|
DeckList::DeckList(const QString &nativeString)
|
||||||
|
|
@ -507,7 +506,7 @@ bool DeckList::loadFromXml(QXmlStreamReader *xml)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
updateDeckHash();
|
refreshDeckHash();
|
||||||
if (xml->error()) {
|
if (xml->error()) {
|
||||||
qDebug() << "Error loading deck from xml: " << xml->errorString();
|
qDebug() << "Error loading deck from xml: " << xml->errorString();
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -734,7 +733,7 @@ bool DeckList::loadFromStream_Plain(QTextStream &in)
|
||||||
new DecklistCardNode(cardName, amount, getZoneObjFromName(zoneName), setCode, collectorNumber);
|
new DecklistCardNode(cardName, amount, getZoneObjFromName(zoneName), setCode, collectorNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
updateDeckHash();
|
refreshDeckHash();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -808,8 +807,7 @@ void DeckList::cleanList()
|
||||||
setName();
|
setName();
|
||||||
setComments();
|
setComments();
|
||||||
setTags();
|
setTags();
|
||||||
deckHash = QString();
|
refreshDeckHash();
|
||||||
emit deckHashChanged();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeckList::getCardListHelper(InnerDecklistNode *item, QSet<QString> &result) const
|
void DeckList::getCardListHelper(InnerDecklistNode *item, QSet<QString> &result) const
|
||||||
|
|
@ -881,7 +879,7 @@ DecklistCardNode *DeckList::addCard(const QString &cardName,
|
||||||
}
|
}
|
||||||
|
|
||||||
auto *node = new DecklistCardNode(cardName, 1, zoneNode, cardSetName, cardSetCollectorNumber, cardProviderId);
|
auto *node = new DecklistCardNode(cardName, 1, zoneNode, cardSetName, cardSetCollectorNumber, cardProviderId);
|
||||||
updateDeckHash();
|
refreshDeckHash();
|
||||||
|
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
@ -907,7 +905,7 @@ bool DeckList::deleteNode(AbstractDecklistNode *node, InnerDecklistNode *rootNod
|
||||||
}
|
}
|
||||||
|
|
||||||
if (updateHash) {
|
if (updateHash) {
|
||||||
updateDeckHash();
|
refreshDeckHash();
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -918,7 +916,7 @@ bool DeckList::deleteNode(AbstractDecklistNode *node, InnerDecklistNode *rootNod
|
||||||
if (inner) {
|
if (inner) {
|
||||||
if (deleteNode(node, inner)) {
|
if (deleteNode(node, inner)) {
|
||||||
if (updateHash) {
|
if (updateHash) {
|
||||||
updateDeckHash();
|
refreshDeckHash();
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -929,7 +927,7 @@ bool DeckList::deleteNode(AbstractDecklistNode *node, InnerDecklistNode *rootNod
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeckList::updateDeckHash()
|
static QString computeDeckHash(const InnerDecklistNode *root)
|
||||||
{
|
{
|
||||||
QStringList cardList;
|
QStringList cardList;
|
||||||
QSet<QString> hashZones, optionalZones;
|
QSet<QString> hashZones, optionalZones;
|
||||||
|
|
@ -955,7 +953,30 @@ void DeckList::updateDeckHash()
|
||||||
(((quint64)(unsigned char)deckHashArray[1]) << 24) +
|
(((quint64)(unsigned char)deckHashArray[1]) << 24) +
|
||||||
(((quint64)(unsigned char)deckHashArray[2] << 16)) +
|
(((quint64)(unsigned char)deckHashArray[2] << 16)) +
|
||||||
(((quint64)(unsigned char)deckHashArray[3]) << 8) + (quint64)(unsigned char)deckHashArray[4];
|
(((quint64)(unsigned char)deckHashArray[3]) << 8) + (quint64)(unsigned char)deckHashArray[4];
|
||||||
deckHash = QString::number(number, 32).rightJustified(8, '0');
|
return QString::number(number, 32).rightJustified(8, '0');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the deck hash.
|
||||||
|
* The hash is computed on the first call to this method, and is cached until the decklist is modified.
|
||||||
|
*
|
||||||
|
* @return The deck hash
|
||||||
|
*/
|
||||||
|
QString DeckList::getDeckHash() const
|
||||||
|
{
|
||||||
|
if (!cachedDeckHash.isEmpty()) {
|
||||||
|
return cachedDeckHash;
|
||||||
|
}
|
||||||
|
|
||||||
|
cachedDeckHash = computeDeckHash(root);
|
||||||
|
return cachedDeckHash;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invalidates the cached deckHash and emits the deckHashChanged signal.
|
||||||
|
*/
|
||||||
|
void DeckList::refreshDeckHash()
|
||||||
|
{
|
||||||
|
cachedDeckHash = QString();
|
||||||
emit deckHashChanged();
|
emit deckHashChanged();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -252,7 +252,6 @@ class DeckList : public QObject
|
||||||
private:
|
private:
|
||||||
QString name, comments;
|
QString name, comments;
|
||||||
QPair<QString, QString> bannerCard;
|
QPair<QString, QString> bannerCard;
|
||||||
QString deckHash;
|
|
||||||
QString lastLoadedTimestamp;
|
QString lastLoadedTimestamp;
|
||||||
QStringList tags;
|
QStringList tags;
|
||||||
QMap<QString, SideboardPlan *> sideboardPlans;
|
QMap<QString, SideboardPlan *> sideboardPlans;
|
||||||
|
|
@ -261,6 +260,11 @@ private:
|
||||||
void getCardListWithProviderIdHelper(InnerDecklistNode *item, QMap<QString, QString> &result) const;
|
void getCardListWithProviderIdHelper(InnerDecklistNode *item, QMap<QString, QString> &result) const;
|
||||||
InnerDecklistNode *getZoneObjFromName(const QString &zoneName);
|
InnerDecklistNode *getZoneObjFromName(const QString &zoneName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Empty string indicates invalidated cache.
|
||||||
|
*/
|
||||||
|
mutable QString cachedDeckHash;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual QString getCardZoneFromName(const QString /*cardName*/, QString currentZoneName)
|
virtual QString getCardZoneFromName(const QString /*cardName*/, QString currentZoneName)
|
||||||
{
|
{
|
||||||
|
|
@ -363,12 +367,6 @@ public:
|
||||||
|
|
||||||
int getSideboardSize() const;
|
int getSideboardSize() const;
|
||||||
|
|
||||||
QString getDeckHash() const
|
|
||||||
{
|
|
||||||
return deckHash;
|
|
||||||
}
|
|
||||||
void updateDeckHash();
|
|
||||||
|
|
||||||
InnerDecklistNode *getRoot() const
|
InnerDecklistNode *getRoot() const
|
||||||
{
|
{
|
||||||
return root;
|
return root;
|
||||||
|
|
@ -380,6 +378,9 @@ public:
|
||||||
const QString &cardProviderId = QString());
|
const QString &cardProviderId = QString());
|
||||||
bool deleteNode(AbstractDecklistNode *node, InnerDecklistNode *rootNode = nullptr);
|
bool deleteNode(AbstractDecklistNode *node, InnerDecklistNode *rootNode = nullptr);
|
||||||
|
|
||||||
|
QString getDeckHash() const;
|
||||||
|
void refreshDeckHash();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calls a given function object for each card in the deck. It must
|
* Calls a given function object for each card in the deck. It must
|
||||||
* take a InnerDecklistNode* as its first argument and a
|
* take a InnerDecklistNode* as its first argument and a
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue