From 2d15529d488405514a74a51f56fecb5677afe3eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20Br=C3=BCbach?= Date: Sun, 20 Sep 2026 20:17:07 +0200 Subject: [PATCH] [PublicDecks] Drop stale deck-list replies after the loading timeout A reply that lands after its own loading timeout (the reverse of the ping sweep dropping the command) could stop the newer request's timeout timer and repaint the grid with out-of-date data. Each refresh now captures a monotonically increasing request id, and only the newest request's reply updates the grid. --- .../remote_public_decks_model.cpp | 13 ++++++++++++- .../visual_deck_storage/remote_public_decks_model.h | 1 + 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/cockatrice/src/interface/widgets/visual_deck_storage/remote_public_decks_model.cpp b/cockatrice/src/interface/widgets/visual_deck_storage/remote_public_decks_model.cpp index 3eec66559..a1cabd729 100644 --- a/cockatrice/src/interface/widgets/visual_deck_storage/remote_public_decks_model.cpp +++ b/cockatrice/src/interface/widgets/visual_deck_storage/remote_public_decks_model.cpp @@ -131,12 +131,23 @@ void RemotePublicDecksModel::refresh(const QString &userName) if (loading) { return; } + // Every refresh captures its own request id so a reply that lands after its + // loading timeout (the reverse of the ping sweep dropping the command) is + // recognised as stale: it must not stop the newer request's timer or paint + // the grid with out-of-date data. + const int seq = ++requestSequence; setLoading(true); loadingTimeoutTimer->start(); Command_DeckListOtherUser cmd; cmd.set_user_name(userName.toStdString()); PendingCommand *pend = client->prepareSessionCommand(cmd); - connect(pend, &PendingCommand::finished, this, &RemotePublicDecksModel::decksReceived); + connect(pend, &PendingCommand::finished, this, + [this, seq](const Response &response, const CommandContainer &commandContainer) { + if (seq != requestSequence) { + return; // a newer refresh superseded this one + } + decksReceived(response, commandContainer); + }); client->sendCommand(pend); } diff --git a/cockatrice/src/interface/widgets/visual_deck_storage/remote_public_decks_model.h b/cockatrice/src/interface/widgets/visual_deck_storage/remote_public_decks_model.h index 3c562b847..eeb606442 100644 --- a/cockatrice/src/interface/widgets/visual_deck_storage/remote_public_decks_model.h +++ b/cockatrice/src/interface/widgets/visual_deck_storage/remote_public_decks_model.h @@ -117,6 +117,7 @@ private: QList decks; QList visibleIndices; ///< Row indices into `decks` that pass the current filters. bool loading = false; + int requestSequence = 0; ///< Monotonically increases per refresh; only the newest request may update the grid. QString searchText; VisualDeckStorageSortFilterProxyModel::FilterMode colorFilterMode = VisualDeckStorageSortFilterProxyModel::Includes;