don't update the deckhash on load

add a new property to decklists that tracks if the deck needs to update
the deckhash

only update the deckhash if needed when it is asked for

this saves computing the deckhash for every loaded deck as performed by
the visual deck selector with impunity

the copy constructor also now no longer computes the deck hash again

the deck hash is now only computed once, on deck load, as expected,
resulting in massive amounts of cpu cycles not being wasted
This commit is contained in:
ebbit1q 2025-03-10 19:21:10 +01:00
parent 0a1d0f650f
commit 1b62022f25
2 changed files with 27 additions and 17 deletions

View file

@ -361,15 +361,14 @@ QVector<QPair<int, int>> InnerDecklistNode::sort(Qt::SortOrder order)
return result; return result;
} }
DeckList::DeckList() DeckList::DeckList() : QObject(), deckHashDirty(true)
{ {
root = new InnerDecklistNode; root = new InnerDecklistNode;
} }
// 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), deckHash(other.deckHash), deckHashDirty(other.deckHashDirty), lastLoadedTimestamp(other.lastLoadedTimestamp), tags(other.tags)
lastLoadedTimestamp(other.lastLoadedTimestamp), tags(other.tags)
{ {
root = new InnerDecklistNode(other.getRoot()); root = new InnerDecklistNode(other.getRoot());
@ -378,10 +377,9 @@ 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) : QObject()
{ {
root = new InnerDecklistNode; root = new InnerDecklistNode;
loadFromString_Native(nativeString); loadFromString_Native(nativeString);
@ -507,7 +505,8 @@ bool DeckList::loadFromXml(QXmlStreamReader *xml)
} }
} }
} }
updateDeckHash(); deckHashDirty = true;
emit deckHashChanged();
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,8 @@ bool DeckList::loadFromStream_Plain(QTextStream &in)
new DecklistCardNode(cardName, amount, getZoneObjFromName(zoneName), setCode, collectorNumber); new DecklistCardNode(cardName, amount, getZoneObjFromName(zoneName), setCode, collectorNumber);
} }
updateDeckHash(); deckHashDirty = true;
emit deckHashChanged();
return true; return true;
} }
@ -809,6 +809,7 @@ void DeckList::cleanList()
setComments(); setComments();
setTags(); setTags();
deckHash = QString(); deckHash = QString();
deckHashDirty = false;
emit deckHashChanged(); emit deckHashChanged();
} }
@ -881,7 +882,8 @@ 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(); deckHashDirty = true;
emit deckHashChanged();
return node; return node;
} }
@ -907,7 +909,8 @@ bool DeckList::deleteNode(AbstractDecklistNode *node, InnerDecklistNode *rootNod
} }
if (updateHash) { if (updateHash) {
updateDeckHash(); deckHashDirty = true;
emit deckHashChanged();
} }
return true; return true;
@ -918,7 +921,8 @@ bool DeckList::deleteNode(AbstractDecklistNode *node, InnerDecklistNode *rootNod
if (inner) { if (inner) {
if (deleteNode(node, inner)) { if (deleteNode(node, inner)) {
if (updateHash) { if (updateHash) {
updateDeckHash(); deckHashDirty = true;
emit deckHashChanged();
} }
return true; return true;
@ -929,6 +933,14 @@ bool DeckList::deleteNode(AbstractDecklistNode *node, InnerDecklistNode *rootNod
return false; return false;
} }
QString DeckList::getDeckHash()
{
if (deckHashDirty) {
updateDeckHash();
}
return deckHash;
}
void DeckList::updateDeckHash() void DeckList::updateDeckHash()
{ {
QStringList cardList; QStringList cardList;
@ -955,7 +967,7 @@ 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');
emit deckHashChanged(); deckHash = QString::number(number, 32).rightJustified(8, '0');
deckHashDirty = false;
} }

View file

@ -253,6 +253,7 @@ private:
QString name, comments; QString name, comments;
QPair<QString, QString> bannerCard; QPair<QString, QString> bannerCard;
QString deckHash; QString deckHash;
bool deckHashDirty;
QString lastLoadedTimestamp; QString lastLoadedTimestamp;
QStringList tags; QStringList tags;
QMap<QString, SideboardPlan *> sideboardPlans; QMap<QString, SideboardPlan *> sideboardPlans;
@ -363,10 +364,7 @@ public:
int getSideboardSize() const; int getSideboardSize() const;
QString getDeckHash() const QString getDeckHash();
{
return deckHash;
}
void updateDeckHash(); void updateDeckHash();
InnerDecklistNode *getRoot() const InnerDecklistNode *getRoot() const