Bump version to 6.4-15
[LibreOffice.git] / slideshow / source / engine / activities / simplecontinuousactivitybase.cxx
blob5566b5883f784a3466fb9e94112576bc5ef9acdb
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 .
21 // must be first
23 #include "simplecontinuousactivitybase.hxx"
25 #include <sal/log.hxx>
27 namespace slideshow
29 namespace internal
31 SimpleContinuousActivityBase::SimpleContinuousActivityBase(
32 const ActivityParameters& rParms ) :
33 ActivityBase( rParms ),
34 maTimer( rParms.mrActivitiesQueue.getTimer() ),
35 mnMinSimpleDuration( rParms.mnMinDuration ),
36 mnMinNumberOfFrames( rParms.mnMinNumberOfFrames ),
37 mnCurrPerformCalls( 0 )
41 void SimpleContinuousActivityBase::startAnimation()
43 // init timer. We measure animation time only when we're
44 // actually started.
45 maTimer.reset();
48 double SimpleContinuousActivityBase::calcTimeLag() const
50 ActivityBase::calcTimeLag();
51 if (! isActive())
52 return 0.0;
54 // retrieve locally elapsed time
55 const double nCurrElapsedTime( maTimer.getElapsedTime() );
57 // log time
58 SAL_INFO("slideshow.verbose", "SimpleContinuousActivityBase::calcTimeLag(): "
59 "next step is based on time: " << nCurrElapsedTime );
61 // go to great length to ensure a proper animation
62 // run. Since we don't know how often we will be called
63 // here, try to spread the animator calls uniquely over
64 // the [0,1] parameter range. Be aware of the fact that
65 // perform will be called at least mnMinNumberOfTurns
66 // times.
68 // fraction of time elapsed
69 const double nFractionElapsedTime(
70 nCurrElapsedTime / mnMinSimpleDuration );
72 // fraction of minimum calls performed
73 const double nFractionRequiredCalls(
74 double(mnCurrPerformCalls) / mnMinNumberOfFrames );
76 // okay, so now, the decision is easy:
78 // If the fraction of time elapsed is smaller than the
79 // number of calls required to be performed, then we calc
80 // the position on the animation range according to
81 // elapsed time. That is, we're so to say ahead of time.
83 // In contrary, if the fraction of time elapsed is larger,
84 // then we're lagging, and we thus calc the position on
85 // the animation time line according to the fraction of
86 // calls performed. Thus, the animation is forced to slow
87 // down, and take the required minimal number of steps,
88 // sufficiently equally distributed across the animation
89 // time line.
90 if( nFractionElapsedTime < nFractionRequiredCalls )
92 SAL_INFO("slideshow.verbose", "SimpleContinuousActivityBase::calcTimeLag(): t=" <<
93 nFractionElapsedTime <<
94 " is based on time");
95 return 0.0;
97 else
99 SAL_INFO("slideshow.verbose", "SimpleContinuousActivityBase::perform(): t=" <<
100 nFractionRequiredCalls <<
101 " is based on number of calls");
103 // lag global time, so all other animations lag, too:
104 return ((nFractionElapsedTime - nFractionRequiredCalls)
105 * mnMinSimpleDuration);
109 bool SimpleContinuousActivityBase::perform()
111 // call base class, for start() calls and end handling
112 if( !ActivityBase::perform() )
113 return false; // done, we're ended
116 // get relative animation position
117 // ===============================
119 const double nCurrElapsedTime( maTimer.getElapsedTime() );
120 double nT( nCurrElapsedTime / mnMinSimpleDuration );
123 // one of the stop criteria reached?
124 // =================================
126 // will be set to true below, if one of the termination criteria
127 // matched.
128 bool bActivityEnding( false );
130 if( isRepeatCountValid() )
132 // Finite duration
133 // ===============
135 // When we've autoreverse on, the repeat count
136 // doubles
137 const double nRepeatCount( getRepeatCount() );
138 const double nEffectiveRepeat( isAutoReverse() ?
139 2.0*nRepeatCount :
140 nRepeatCount );
142 // time (or frame count) elapsed?
143 if( nEffectiveRepeat <= nT )
145 // okee. done for now. Will not exit right here,
146 // to give animation the chance to render the last
147 // frame below
148 bActivityEnding = true;
150 // clamp animation to max permissible value
151 nT = nEffectiveRepeat;
156 // need to do auto-reverse?
157 // ========================
159 double nRepeats;
160 double nRelativeSimpleTime;
162 // TODO(Q3): Refactor this mess
163 if( isAutoReverse() )
165 // divert active duration into repeat and
166 // fractional part.
167 const double nFractionalActiveDuration( modf(nT, &nRepeats) );
169 // for auto-reverse, map ranges [1,2), [3,4), ...
170 // to ranges [0,1), [1,2), etc.
171 if( static_cast<int>(nRepeats) % 2 )
173 // we're in an odd range, reverse sweep
174 nRelativeSimpleTime = 1.0 - nFractionalActiveDuration;
176 else
178 // we're in an even range, pass on as is
179 nRelativeSimpleTime = nFractionalActiveDuration;
182 // effective repeat count for autoreverse is half of
183 // the input time's value (each run of an autoreverse
184 // cycle is half of a repeat)
185 nRepeats /= 2;
187 else
189 // determine repeat
190 // ================
192 // calc simple time and number of repeats from nT
193 // Now, that's easy, since the fractional part of
194 // nT gives the relative simple time, and the
195 // integer part the number of full repeats:
196 nRelativeSimpleTime = modf(nT, &nRepeats);
198 // clamp repeats to max permissible value (maRepeats.getValue() - 1.0)
199 if( isRepeatCountValid() &&
200 nRepeats >= getRepeatCount() )
202 // Note that this code here only gets
203 // triggered if maRepeats.getValue() is an
204 // _integer_. Otherwise, nRepeats will never
205 // reach nor exceed
206 // maRepeats.getValue(). Thus, the code below
207 // does not need to handle cases of fractional
208 // repeats, and can always assume that a full
209 // animation run has ended (with
210 // nRelativeSimpleTime=1.0 for
211 // non-autoreversed activities).
213 // with modf, nRelativeSimpleTime will never
214 // become 1.0, since nRepeats is incremented and
215 // nRelativeSimpleTime set to 0.0 then.
217 // For the animation to reach its final value,
218 // nRepeats must although become
219 // maRepeats.getValue()-1.0, and
220 // nRelativeSimpleTime=1.0.
221 nRelativeSimpleTime = 1.0;
222 nRepeats -= 1.0;
226 // actually perform something
227 // ==========================
229 simplePerform( nRelativeSimpleTime,
230 // nRepeats is already integer-valued
231 static_cast<sal_uInt32>( nRepeats ) );
234 // delayed endActivity() call from end condition check
235 // below. Issued after the simplePerform() call above, to
236 // give animations the chance to correctly reach the
237 // animation end value, without spurious bail-outs because
238 // of isActive() returning false.
239 if( bActivityEnding )
240 endActivity();
242 // one more frame successfully performed
243 ++mnCurrPerformCalls;
245 return isActive();
250 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */