tdf#130857 qt weld: Implement QtInstanceWidget::strip_mnemonic
[LibreOffice.git] / sd / source / ui / slidesorter / cache / SlsRequestQueue.cxx
blob1bad31cc1e19cf30db6a299b55e9f52fd96b95bc
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "SlsRequestQueue.hxx"
22 #include <sal/log.hxx>
24 #include <svx/svdpage.hxx>
26 #include <set>
27 #include <utility>
29 namespace sd::slidesorter::cache {
31 namespace {
33 /** This class extends the actual request data with additional information
34 that is used by the priority queues.
36 class Request
38 public:
39 Request (
40 CacheKey aKey, sal_Int32 nPriority, RequestPriorityClass eClass)
41 : maKey(aKey), mnPriorityInClass(nPriority), meClass(eClass)
43 /** Sort requests according to priority classes and then to priorities.
45 class Comparator { public:
46 bool operator() (const Request& rRequest1, const Request& rRequest2)
47 const
49 if (rRequest1.meClass == rRequest2.meClass)
51 if (rRequest1.mnPriorityInClass == rRequest2.mnPriorityInClass)
53 return rRequest1.maKey < rRequest2.maKey;
55 return rRequest1.mnPriorityInClass > rRequest2.mnPriorityInClass;
57 return rRequest1.meClass < rRequest2.meClass;
60 /** Request data is compared arbitrarily by their addresses in memory.
61 This just establishes an order so that the STL containers are happy.
62 The order is not semantically interpreted.
64 class DataComparator
66 public:
67 explicit DataComparator (const CacheKey aKey)
68 : maKey(aKey)
71 bool operator() (const Request& rRequest) const
73 return maKey == rRequest.maKey;
75 private:
76 const CacheKey maKey;
79 CacheKey maKey;
80 sal_Int32 mnPriorityInClass;
81 RequestPriorityClass meClass;
86 class RequestQueue::Container
87 : public ::std::set<
88 Request,
89 Request::Comparator>
93 //===== GenericRequestQueue =================================================
95 RequestQueue::RequestQueue (SharedCacheContext pCacheContext)
96 : mpRequestQueue(new Container),
97 mpCacheContext(std::move(pCacheContext)),
98 mnMinimumPriority(0),
99 mnMaximumPriority(1)
103 RequestQueue::~RequestQueue()
105 Clear();
108 void RequestQueue::AddRequest (
109 CacheKey aKey,
110 RequestPriorityClass eRequestClass)
112 ::osl::MutexGuard aGuard (maMutex);
114 assert(eRequestClass>=MIN_CLASS && eRequestClass<=MAX_CLASS);
116 // If the request is already a member of the queue then remove it so
117 // that the following insertion will use the new prioritization.
118 #if OSL_DEBUG_LEVEL >=2
119 bool bRemoved =
120 #endif
121 RemoveRequest(aKey);
123 // The priority of the request inside its priority class is defined by
124 // the page number. This ensures a strict top-to-bottom, left-to-right
125 // order.
126 sal_Int32 nPriority (mpCacheContext->GetPriority(aKey));
127 Request aRequest (aKey, nPriority, eRequestClass);
129 std::pair<Container::iterator,bool> ret = mpRequestQueue->insert(aRequest);
130 bool bInserted = ret.second;
132 if (bInserted)
134 SdrPage *pPage = const_cast<SdrPage*>(aRequest.maKey);
135 pPage->AddPageUser(*this);
138 #if OSL_DEBUG_LEVEL >=2
139 SAL_INFO("sd.sls", __func__ << ": " << (bRemoved?"replaced":"added")
140 << " request for page " << ((aKey->GetPageNum()-1)/2)
141 << " with priority class " << static_cast<int>(eRequestClass));
142 #endif
145 void RequestQueue::PageInDestruction(const SdrPage& rPage)
147 //remove any requests pending for this page which is going away now
148 RemoveRequest(&rPage);
151 #if OSL_DEBUG_LEVEL >=2
152 bool
153 #else
154 void
155 #endif
156 RequestQueue::RemoveRequest(
157 CacheKey aKey)
159 ::osl::MutexGuard aGuard (maMutex);
160 #if OSL_DEBUG_LEVEL >=2
161 bool bIsRemoved = false;
162 #endif
163 while(true)
165 Container::const_iterator aRequestIterator = ::std::find_if (
166 mpRequestQueue->begin(),
167 mpRequestQueue->end(),
168 Request::DataComparator(aKey));
169 if (aRequestIterator != mpRequestQueue->end())
171 if (aRequestIterator->mnPriorityInClass == mnMinimumPriority+1)
172 mnMinimumPriority++;
173 else if (aRequestIterator->mnPriorityInClass == mnMaximumPriority-1)
174 mnMaximumPriority--;
176 SdrPage *pPage = const_cast<SdrPage*>(aRequestIterator->maKey);
177 pPage->RemovePageUser(*this);
178 mpRequestQueue->erase(aRequestIterator);
179 #if OSL_DEBUG_LEVEL >=2
180 bIsRemoved = true;
181 #endif
183 else
184 break;
186 #if OSL_DEBUG_LEVEL >=2
187 return bIsRemoved;
188 #endif
192 void RequestQueue::ChangeClass (
193 CacheKey aKey,
194 RequestPriorityClass eNewRequestClass)
196 ::osl::MutexGuard aGuard (maMutex);
198 assert(eNewRequestClass>=MIN_CLASS && eNewRequestClass<=MAX_CLASS);
200 Container::const_iterator iRequest (
201 ::std::find_if (
202 mpRequestQueue->begin(),
203 mpRequestQueue->end(),
204 Request::DataComparator(aKey)));
205 if (iRequest!=mpRequestQueue->end() && iRequest->meClass!=eNewRequestClass)
207 AddRequest(aKey, eNewRequestClass);
211 CacheKey RequestQueue::GetFront()
213 ::osl::MutexGuard aGuard (maMutex);
215 if (mpRequestQueue->empty())
216 throw css::uno::RuntimeException(u"RequestQueue::GetFront(): queue is empty"_ustr,
217 nullptr);
219 return mpRequestQueue->begin()->maKey;
222 RequestPriorityClass RequestQueue::GetFrontPriorityClass()
224 ::osl::MutexGuard aGuard (maMutex);
226 if (mpRequestQueue->empty())
227 throw css::uno::RuntimeException(u"RequestQueue::GetFrontPriorityClass(): queue is empty"_ustr,
228 nullptr);
230 return mpRequestQueue->begin()->meClass;
233 void RequestQueue::PopFront()
235 ::osl::MutexGuard aGuard (maMutex);
237 if ( mpRequestQueue->empty())
238 return;
240 Container::const_iterator aIter(mpRequestQueue->begin());
241 SdrPage *pPage = const_cast<SdrPage*>(aIter->maKey);
242 pPage->RemovePageUser(*this);
243 mpRequestQueue->erase(aIter);
245 // Reset the priority counter if possible.
246 if (mpRequestQueue->empty())
248 mnMinimumPriority = 0;
249 mnMaximumPriority = 1;
253 bool RequestQueue::IsEmpty()
255 ::osl::MutexGuard aGuard (maMutex);
256 return mpRequestQueue->empty();
259 void RequestQueue::Clear()
261 ::osl::MutexGuard aGuard (maMutex);
263 for (const auto& rItem : *mpRequestQueue)
265 SdrPage *pPage = const_cast<SdrPage*>(rItem.maKey);
266 pPage->RemovePageUser(*this);
269 mpRequestQueue->clear();
270 mnMinimumPriority = 0;
271 mnMaximumPriority = 1;
274 } // end of namespace ::sd::slidesorter::cache
276 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */