LibreOffice Module slideshow (master) 1
screenupdater.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20#include <screenupdater.hxx>
21#include <listenercontainer.hxx>
22
23#include <osl/diagnose.h>
24
25#include <functional>
26#include <memory>
27#include <vector>
28#include <algorithm>
29
30namespace {
32 {
33 public:
34 explicit UpdateLock (::slideshow::internal::ScreenUpdater& rUpdater);
35 virtual ~UpdateLock();
36 virtual void Activate() override;
37 private:
39 bool mbIsActivated;
40 };
41}
42
43namespace slideshow::internal
44{
45 typedef std::vector<
46 std::pair<UnoViewSharedPtr,bool> > UpdateRequestVector;
47
49 {
55 std::vector<ViewUpdateSharedPtr> > maUpdaters;
56
59
62
65
68
70 sal_Int32 mnLockCount;
71
72 explicit ImplScreenUpdater( UnoViewContainer const& rViewContainer ) :
73 maUpdaters(),
75 mrViewContainer(rViewContainer),
76 mbUpdateAllRequest(false),
77 mbViewClobbered(false),
79 {}
80 };
81
83 mpImpl(new ImplScreenUpdater(rViewContainer) )
84 {
85 }
86
88 {
89 // outline because of pimpl
90 }
91
93 {
94 mpImpl->mbUpdateAllRequest = true;
95 }
96
98 bool bViewClobbered )
99 {
100 mpImpl->maViewUpdateRequests.emplace_back(rView, bViewClobbered );
101
102 if( bViewClobbered )
103 mpImpl->mbViewClobbered = true;
104 }
105
107 {
108 if (mpImpl->mnLockCount > 0)
109 return;
110
111 // cases:
112
113 // (a) no update necessary at all
114
115 // (b) no ViewUpdate-generated update
116 // I. update all views requested -> for_each( mrViewContainer )
117 // II. update some views requested -> for_each( maViewUpdateRequests )
118
119 // (c) ViewUpdate-triggered update - update all views
120
121
122 // any ViewUpdate-triggered updates?
123 const bool bViewUpdatesNeeded(
124 mpImpl->maUpdaters.apply(
125 std::mem_fn(&ViewUpdate::needsUpdate)) );
126
127 if( bViewUpdatesNeeded )
128 {
129 mpImpl->maUpdaters.applyAll(
130 std::mem_fn(&ViewUpdate::update) );
131 }
132
133 if( bViewUpdatesNeeded ||
134 mpImpl->mbUpdateAllRequest )
135 {
136 // unconditionally update all views
137 for( const auto& pView : mpImpl->mrViewContainer )
138 {
139 if( mpImpl->mbViewClobbered )
140 pView->paintScreen();
141 else
142 pView->updateScreen();
143 }
144 }
145 else if( !mpImpl->maViewUpdateRequests.empty() )
146 {
147 // update notified views only
148 for( const auto& rViewUpdateRequest : mpImpl->maViewUpdateRequests )
149 {
150 // TODO(P1): this is O(n^2) in the number of views, if
151 // lots of views notify updates.
152 const UnoViewVector::const_iterator aEndOfViews(
153 mpImpl->mrViewContainer.end() );
154 UnoViewVector::const_iterator aFoundView;
155 if( (aFoundView=std::find(mpImpl->mrViewContainer.begin(),
156 aEndOfViews,
157 rViewUpdateRequest.first)) != aEndOfViews )
158 {
159 if( rViewUpdateRequest.second )
160 (*aFoundView)->paintScreen(); // force-paint
161 else
162 (*aFoundView)->updateScreen(); // update changes only
163 }
164 }
165 }
166
167 // done - clear requests
168 mpImpl->mbViewClobbered = false;
169 mpImpl->mbUpdateAllRequest = false;
170 UpdateRequestVector().swap( mpImpl->maViewUpdateRequests );
171 }
172
174 {
175 mpImpl->maUpdaters.add( rViewUpdate );
176 }
177
179 {
180 mpImpl->maUpdaters.remove( rViewUpdate );
181 }
182
184 {
185 if (mpImpl->mnLockCount > 0)
186 return;
187
188 // TODO(F2): This will interfere with other updates, since it
189 // happens out-of-sync with main animation loop. Might cause
190 // artifacts.
191 for( auto const& pView : mpImpl->mrViewContainer )
192 pView->updateScreen();
193 }
194
196 {
197 ++mpImpl->mnLockCount;
198 OSL_ASSERT(mpImpl->mnLockCount>0);
199 }
200
202 {
203 OSL_ASSERT(mpImpl->mnLockCount>0);
204 if (mpImpl->mnLockCount > 0)
205 {
206 --mpImpl->mnLockCount;
207 if (mpImpl->mnLockCount)
209 }
210 }
211
212 ::std::shared_ptr<ScreenUpdater::UpdateLock> ScreenUpdater::createLock()
213 {
214 return ::std::make_shared<::UpdateLock>(*this);
215 }
216
217
218} // namespace slideshow::internal
219
220namespace {
221
222UpdateLock::UpdateLock (
224 : mrUpdater(rUpdater),
225 mbIsActivated(false)
226{
227}
228
229
230UpdateLock::~UpdateLock()
231{
232 if (mbIsActivated)
233 mrUpdater.unlockUpdates();
234}
235
236
237void UpdateLock::Activate()
238{
239 if ( ! mbIsActivated)
240 {
241 mbIsActivated = true;
242 mrUpdater.lockUpdates();
243 }
244}
245
246}
247
248/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
void removeViewUpdate(ViewUpdateSharedPtr const &)
Unregister ViewUpdate.
void addViewUpdate(ViewUpdateSharedPtr const &rViewUpdate)
Register ViewUpdate.
ScreenUpdater(UnoViewContainer const &rViewContainer)
::std::shared_ptr< UpdateLock > createLock()
Call this method to create a lock instead of calling lockUpdates() and unlockUpdates() directly.
void notifyUpdate()
Notify screen update.
void unlockUpdates()
When called as often as lockUpdates() then commitUpdates() is called.
void lockUpdates()
Lock updates to prevent intermediate repaints.
std::unique_ptr< ImplScreenUpdater > mpImpl
void commitUpdates()
Commits collected update actions.
ListenerContainer variant that does not serialize access.
virtual bool update()=0
Perform the update action on all views.
virtual bool needsUpdate() const =0
Query whether updates are pending.
std::vector< std::pair< UnoViewSharedPtr, bool > > UpdateRequestVector
::std::shared_ptr< ViewUpdate > ViewUpdateSharedPtr
Definition: viewupdate.hxx:54
std::shared_ptr< UnoView > UnoViewSharedPtr
SpriteRedrawManager::SpriteConnectedRanges & mrUpdater
bool mbUpdateAllRequest
True, if a notifyUpdate() for all views has been issued.
ImplScreenUpdater(UnoViewContainer const &rViewContainer)
UnoViewContainer const & mrViewContainer
List of View. Used to issue screen updates on.
ThreadUnsafeListenerContainer< ViewUpdateSharedPtr, std::vector< ViewUpdateSharedPtr > > maUpdaters
List of registered ViewUpdaters, to consult for necessary updates.
sal_Int32 mnLockCount
The screen is updated only when mnLockCount==0.
UpdateRequestVector maViewUpdateRequests
Views that have been notified for update.
bool mbViewClobbered
True, if at least one notifyUpdate() call had bViewClobbered set.