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: