diff --git a/cockatrice/src/client/ui/picture_loader/picture_loader_worker.cpp b/cockatrice/src/client/ui/picture_loader/picture_loader_worker.cpp index b0ab0b4c0..d2d9fc237 100644 --- a/cockatrice/src/client/ui/picture_loader/picture_loader_worker.cpp +++ b/cockatrice/src/client/ui/picture_loader/picture_loader_worker.cpp @@ -12,7 +12,10 @@ #include #include -PictureLoaderWorker::PictureLoaderWorker() : QObject(nullptr), picDownload(SettingsCache::instance().getPicDownload()) +static constexpr int MAX_REQUESTS_PER_SEC = 10; + +PictureLoaderWorker::PictureLoaderWorker() + : QObject(nullptr), picDownload(SettingsCache::instance().getPicDownload()), requestCounter(MAX_REQUESTS_PER_SEC) { networkManager = new QNetworkAccessManager(this); // We need a timeout to ensure requests don't hang indefinitely in case of @@ -48,7 +51,7 @@ PictureLoaderWorker::PictureLoaderWorker() : QObject(nullptr), picDownload(Setti connect(this, &PictureLoaderWorker::imageLoadEnqueued, this, &PictureLoaderWorker::handleImageLoadEnqueued); - connect(&requestTimer, &QTimer::timeout, this, &PictureLoaderWorker::processQueuedRequests); + connect(&requestTimer, &QTimer::timeout, this, &PictureLoaderWorker::resetRequestCounter); requestTimer.setInterval(1000); requestTimer.start(); } @@ -70,6 +73,7 @@ void PictureLoaderWorker::queueRequest(const QUrl &url, PictureLoaderWorkerWork } else { requestLoadQueue.append(qMakePair(url, worker)); emit imageLoadQueued(url, worker); + processQueuedRequests(); } } @@ -95,22 +99,31 @@ QNetworkReply *PictureLoaderWorker::makeRequest(const QUrl &url, PictureLoaderWo return reply; } +void PictureLoaderWorker::resetRequestCounter() +{ + requestCounter = MAX_REQUESTS_PER_SEC; + processQueuedRequests(); +} + void PictureLoaderWorker::processQueuedRequests() { - for (int i = 0; i < 10; i++) { - processSingleRequest(); + while (requestCounter > 0 && processSingleRequest()) { + --requestCounter; } } /** - * Immediately processes a single queued request + * Immediately processes a single queued request. No-ops if the load queue is empty + * @return If a request was processed */ -void PictureLoaderWorker::processSingleRequest() +bool PictureLoaderWorker::processSingleRequest() { if (!requestLoadQueue.isEmpty()) { auto request = requestLoadQueue.takeFirst(); makeRequest(request.first, request.second); + return true; } + return false; } void PictureLoaderWorker::enqueueImageLoad(const CardInfoPtr &card) diff --git a/cockatrice/src/client/ui/picture_loader/picture_loader_worker.h b/cockatrice/src/client/ui/picture_loader/picture_loader_worker.h index 2f0a737ad..3c1cdd7ab 100644 --- a/cockatrice/src/client/ui/picture_loader/picture_loader_worker.h +++ b/cockatrice/src/client/ui/picture_loader/picture_loader_worker.h @@ -38,7 +38,7 @@ public: public slots: QNetworkReply *makeRequest(const QUrl &url, PictureLoaderWorkerWork *workThread); void processQueuedRequests(); - void processSingleRequest(); + bool processSingleRequest(); void imageLoadedSuccessfully(const CardInfoPtr &card, const QImage &image); void cacheRedirect(const QUrl &originalUrl, const QUrl &redirectUrl); void removedCachedUrl(const QUrl &url); @@ -52,7 +52,9 @@ private: static constexpr int CacheTTLInDays = 30; // TODO: Make user configurable bool picDownload; QQueue> requestLoadQueue; - QTimer requestTimer; // Timer for processing delayed requests + + int requestCounter; + QTimer requestTimer; // Timer for refreshing request counter PictureLoaderLocal *localLoader; QSet currentlyLoading; // for deduplication purposes @@ -63,6 +65,7 @@ private: void cleanStaleEntries(); private slots: + void resetRequestCounter(); void handleImageLoadEnqueued(const CardInfoPtr &card); signals: