1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: screenupdater.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
30 #include "precompiled_slideshow.hxx"
32 #include "screenupdater.hxx"
33 #include "listenercontainer.hxx"
35 #include <boost/bind.hpp>
40 class UpdateLock
: public ::slideshow::internal::ScreenUpdater::UpdateLock
43 UpdateLock (::slideshow::internal::ScreenUpdater
& rUpdater
, const bool bStartLocked
);
44 virtual ~UpdateLock (void);
45 virtual void Activate (void);
47 ::slideshow::internal::ScreenUpdater
& mrUpdater
;
57 std::pair
<UnoViewSharedPtr
,bool> > UpdateRequestVector
;
59 struct ScreenUpdater::ImplScreenUpdater
61 /** List of registered ViewUpdaters, to consult for necessary
64 ThreadUnsafeListenerContainer
<
66 std::vector
<ViewUpdateSharedPtr
> > maUpdaters
;
68 /// Views that have been notified for update
69 UpdateRequestVector maViewUpdateRequests
;
71 /// List of View. Used to issue screen updates on.
72 UnoViewContainer
const& mrViewContainer
;
74 /// True, if a notifyUpdate() for all views has been issued.
75 bool mbUpdateAllRequest
;
77 /// True, if at least one notifyUpdate() call had bViewClobbered set
80 /// The screen is updated only when mnLockCount==0
81 sal_Int32 mnLockCount
;
83 explicit ImplScreenUpdater( UnoViewContainer
const& rViewContainer
) :
85 maViewUpdateRequests(),
86 mrViewContainer(rViewContainer
),
87 mbUpdateAllRequest(false),
88 mbViewClobbered(false),
93 ScreenUpdater::ScreenUpdater( UnoViewContainer
const& rViewContainer
) :
94 mpImpl(new ImplScreenUpdater(rViewContainer
) )
98 ScreenUpdater::~ScreenUpdater()
100 // outline because of pimpl
103 void ScreenUpdater::notifyUpdate()
105 mpImpl
->mbUpdateAllRequest
= true;
108 void ScreenUpdater::notifyUpdate( const UnoViewSharedPtr
& rView
,
109 bool bViewClobbered
)
111 mpImpl
->maViewUpdateRequests
.push_back(
112 std::make_pair(rView
, bViewClobbered
) );
115 mpImpl
->mbViewClobbered
= true;
118 void ScreenUpdater::commitUpdates()
120 if (mpImpl
->mnLockCount
> 0)
125 // (a) no update necessary at all
127 // (b) no ViewUpdate-generated update
128 // I. update all views requested -> for_each( mrViewContainer )
129 // II. update some views requested -> for_each( maViewUpdateRequests )
131 // (c) ViewUpdate-triggered update - update all views
134 // any ViewUpdate-triggered updates?
135 const bool bViewUpdatesNeeded(
136 mpImpl
->maUpdaters
.apply(
137 boost::mem_fn(&ViewUpdate::needsUpdate
)) );
139 if( bViewUpdatesNeeded
)
141 mpImpl
->maUpdaters
.applyAll(
142 boost::mem_fn((bool (ViewUpdate::*)())&ViewUpdate::update
) );
145 if( bViewUpdatesNeeded
||
146 mpImpl
->mbUpdateAllRequest
)
148 // unconditionally update all views
149 std::for_each( mpImpl
->mrViewContainer
.begin(),
150 mpImpl
->mrViewContainer
.end(),
151 mpImpl
->mbViewClobbered
?
152 boost::mem_fn(&View::paintScreen
) :
153 boost::mem_fn(&View::updateScreen
) );
155 else if( !mpImpl
->maViewUpdateRequests
.empty() )
157 // update notified views only
158 UpdateRequestVector::const_iterator
aIter(
159 mpImpl
->maViewUpdateRequests
.begin() );
160 const UpdateRequestVector::const_iterator
aEnd(
161 mpImpl
->maViewUpdateRequests
.end() );
162 while( aIter
!= aEnd
)
164 // TODO(P1): this is O(n^2) in the number of views, if
165 // lots of views notify updates.
166 const UnoViewVector::const_iterator
aEndOfViews(
167 mpImpl
->mrViewContainer
.end() );
168 UnoViewVector::const_iterator aFoundView
;
169 if( (aFoundView
=std::find(mpImpl
->mrViewContainer
.begin(),
171 aIter
->first
)) != aEndOfViews
)
174 (*aFoundView
)->paintScreen(); // force-paint
176 (*aFoundView
)->updateScreen(); // update changes only
183 // done - clear requests
184 mpImpl
->mbViewClobbered
= false;
185 mpImpl
->mbUpdateAllRequest
= false;
186 UpdateRequestVector().swap( mpImpl
->maViewUpdateRequests
);
189 void ScreenUpdater::addViewUpdate( ViewUpdateSharedPtr
const& rViewUpdate
)
191 mpImpl
->maUpdaters
.add( rViewUpdate
);
194 void ScreenUpdater::removeViewUpdate( ViewUpdateSharedPtr
const& rViewUpdate
)
196 mpImpl
->maUpdaters
.remove( rViewUpdate
);
199 void ScreenUpdater::requestImmediateUpdate()
201 if (mpImpl
->mnLockCount
> 0)
204 // TODO(F2): This will interfere with other updates, since it
205 // happens out-of-sync with main animation loop. Might cause
207 std::for_each( mpImpl
->mrViewContainer
.begin(),
208 mpImpl
->mrViewContainer
.end(),
209 boost::mem_fn(&View::updateScreen
) );
212 void ScreenUpdater::lockUpdates (void)
214 ++mpImpl
->mnLockCount
;
215 OSL_ASSERT(mpImpl
->mnLockCount
>0);
218 void ScreenUpdater::unlockUpdates (void)
220 OSL_ASSERT(mpImpl
->mnLockCount
>0);
221 if (mpImpl
->mnLockCount
> 0)
223 --mpImpl
->mnLockCount
;
224 if (mpImpl
->mnLockCount
)
229 ::boost::shared_ptr
<ScreenUpdater::UpdateLock
> ScreenUpdater::createLock (const bool bStartLocked
)
231 return ::boost::shared_ptr
<ScreenUpdater::UpdateLock
>(new ::UpdateLock(*this, bStartLocked
));
235 } // namespace internal
236 } // namespace slideshow
240 UpdateLock::UpdateLock (
241 ::slideshow::internal::ScreenUpdater
& rUpdater
,
242 const bool bStartLocked
)
243 : mrUpdater(rUpdater
),
253 UpdateLock::~UpdateLock (void)
256 mrUpdater
.unlockUpdates();
262 void UpdateLock::Activate (void)
264 if ( ! mbIsActivated
)
266 mbIsActivated
= true;
267 mrUpdater
.lockUpdates();