File indexing completed on 2024-05-05 04:22:00

0001 // SPDX-FileCopyrightText: 2003-2010 Jesper K. Pedersen <blackie@kde.org>
0002 // SPDX-FileCopyrightText: 2022 Johannes Zarl-Zierl <johannes@zarl-zierl.at>
0003 //
0004 // SPDX-License-Identifier: GPL-2.0-or-later
0005 
0006 #include "RequestQueue.h"
0007 
0008 #include "AsyncLoader.h"
0009 #include "CancelEvent.h"
0010 #include "ImageClientInterface.h"
0011 #include "ImageRequest.h"
0012 
0013 #include <QApplication>
0014 
0015 bool ImageManager::RequestQueue::addRequest(ImageRequest *request)
0016 {
0017     const ImageRequestReference ref(request);
0018     if (m_uniquePending.contains(ref)) {
0019         // We have this very same request already in the queue. Ignore this one.
0020         delete request;
0021         return false;
0022     }
0023 
0024     m_queues[request->priority()].enqueue(request);
0025     m_uniquePending.insert(ref);
0026 
0027     if (request->client())
0028         m_activeRequests.insert(request);
0029 
0030     return true;
0031 }
0032 
0033 ImageManager::ImageRequest *ImageManager::RequestQueue::popNext()
0034 {
0035     QueueType::iterator it = m_queues.end(); // m_queues is initialized to non-zero size
0036     do {
0037         --it;
0038         while (!it->empty()) {
0039             ImageRequest *request = it->dequeue();
0040 
0041             if (!request->stillNeeded()) {
0042                 removeRequest(request);
0043                 request->setLoadedOK(false);
0044                 CancelEvent *event = new CancelEvent(request);
0045                 QApplication::postEvent(AsyncLoader::instance(), event);
0046             } else {
0047                 const ImageRequestReference ref(request);
0048                 m_uniquePending.remove(ref);
0049                 return request;
0050             }
0051         }
0052         if (AsyncLoader::instance()->isExiting())
0053             return new ImageRequest(ImageRequest::RequestType::ExitRequest);
0054     } while (it != m_queues.begin());
0055 
0056     return nullptr;
0057 }
0058 
0059 void ImageManager::RequestQueue::cancelRequests(ImageClientInterface *client, StopAction action)
0060 {
0061     // remove from active map
0062     for (auto it = m_activeRequests.begin(); it != m_activeRequests.end();) {
0063         ImageRequest *request = *it;
0064         ++it; // We need to increase it before removing the element.
0065         if (client == request->client() && (action == StopAll || (request->priority() < ThumbnailVisible))) {
0066             m_activeRequests.remove(request);
0067             // active requests are not deleted - they might already have been
0068             // popNext()ed and are being processed. They will be deleted
0069             // in Manger::customEvent().
0070         }
0071     }
0072 
0073     for (QueueType::iterator qit = m_queues.begin(); qit != m_queues.end(); ++qit) {
0074         for (QQueue<ImageRequest *>::iterator it = qit->begin(); it != qit->end(); /* no increment here */) {
0075             ImageRequest *request = *it;
0076             if (request->client() == client && (action == StopAll || request->priority() < ThumbnailVisible)) {
0077                 it = qit->erase(it);
0078                 const ImageRequestReference ref(request);
0079                 m_uniquePending.remove(ref);
0080                 delete request;
0081             } else {
0082                 ++it;
0083             }
0084         }
0085     }
0086 }
0087 
0088 bool ImageManager::RequestQueue::isRequestStillValid(ImageRequest *request)
0089 {
0090     return m_activeRequests.contains(request);
0091 }
0092 
0093 void ImageManager::RequestQueue::removeRequest(ImageRequest *request)
0094 {
0095     const ImageRequestReference ref(request);
0096     m_activeRequests.remove(request);
0097     m_uniquePending.remove(ref);
0098 }
0099 
0100 ImageManager::RequestQueue::RequestQueue()
0101 {
0102     for (int i = 0; i < LastPriority; ++i)
0103         m_queues.append(QQueue<ImageRequest *>());
0104 }
0105 
0106 // vi:expandtab:tabstop=4 shiftwidth=4: