Bump version to 6.0-36
[LibreOffice.git] / slideshow / source / engine / activities / simplecontinuousactivitybase.cxx
blobe52705dec2c89cdc51d01c1cd06d53fc1ff2d260
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"
26 namespace slideshow
28 namespace internal
30 SimpleContinuousActivityBase::SimpleContinuousActivityBase(
31 const ActivityParameters& rParms ) :
32 ActivityBase( rParms ),
33 maTimer( rParms.mrActivitiesQueue.getTimer() ),
34 mnMinSimpleDuration( rParms.mnMinDuration ),
35 mnMinNumberOfFrames( rParms.mnMinNumberOfFrames ),
36 mnCurrPerformCalls( 0 )
40 void SimpleContinuousActivityBase::startAnimation()
42 // init timer. We measure animation time only when we're
43 // actually started.
44 maTimer.reset();
47 double SimpleContinuousActivityBase::calcTimeLag() const
49 ActivityBase::calcTimeLag();
50 if (! isActive())
51 return 0.0;
53 // retrieve locally elapsed time
54 const double nCurrElapsedTime( maTimer.getElapsedTime() );
56 // log time
57 SAL_INFO("slideshow.verbose", "SimpleContinuousActivityBase::calcTimeLag(): "
58 "next step is based on time: " << nCurrElapsedTime );
60 // go to great length to ensure a proper animation
61 // run. Since we don't know how often we will be called
62 // here, try to spread the animator calls uniquely over
63 // the [0,1] parameter range. Be aware of the fact that
64 // perform will be called at least mnMinNumberOfTurns
65 // times.
67 // fraction of time elapsed
68 const double nFractionElapsedTime(
69 nCurrElapsedTime / mnMinSimpleDuration );
71 // fraction of minimum calls performed
72 const double nFractionRequiredCalls(
73 double(mnCurrPerformCalls) / mnMinNumberOfFrames );
75 // okay, so now, the decision is easy:
77 // If the fraction of time elapsed is smaller than the
78 // number of calls required to be performed, then we calc
79 // the position on the animation range according to
80 // elapsed time. That is, we're so to say ahead of time.
82 // In contrary, if the fraction of time elapsed is larger,
83 // then we're lagging, and we thus calc the position on
84 // the animation time line according to the fraction of
85 // calls performed. Thus, the animation is forced to slow
86 // down, and take the required minimal number of steps,
87 // sufficiently equally distributed across the animation
88 // time line.
89 if( nFractionElapsedTime < nFractionRequiredCalls )
91 SAL_INFO("slideshow.verbose", "SimpleContinuousActivityBase::calcTimeLag(): t=" <<
92 nFractionElapsedTime <<
93 " is based on time");
94 return 0.0;
96 else
98 SAL_INFO("slideshow.verbose", "SimpleContinuousActivityBase::perform(): t=" <<
99 nFractionRequiredCalls <<
100 " is based on number of calls");
102 // lag global time, so all other animations lag, too:
103 return ((nFractionElapsedTime - nFractionRequiredCalls)
104 * mnMinSimpleDuration);
108 bool SimpleContinuousActivityBase::perform()
110 // call base class, for start() calls and end handling
111 if( !ActivityBase::perform() )
112 return false; // done, we're ended
115 // get relative animation position
116 // ===============================
118 const double nCurrElapsedTime( maTimer.getElapsedTime() );
119 double nT( nCurrElapsedTime / mnMinSimpleDuration );
122 // one of the stop criteria reached?
123 // =================================
125 // will be set to true below, if one of the termination criteria
126 // matched.
127 bool bActivityEnding( false );
129 if( isRepeatCountValid() )
131 // Finite duration
132 // ===============
134 // When we've autoreverse on, the repeat count
135 // doubles
136 const double nRepeatCount( getRepeatCount() );
137 const double nEffectiveRepeat( isAutoReverse() ?
138 2.0*nRepeatCount :
139 nRepeatCount );
141 // time (or frame count) elapsed?
142 if( nEffectiveRepeat <= nT )
144 // okee. done for now. Will not exit right here,
145 // to give animation the chance to render the last
146 // frame below
147 bActivityEnding = true;
149 // clamp animation to max permissible value
150 nT = nEffectiveRepeat;
155 // need to do auto-reverse?
156 // ========================
158 double nRepeats;
159 double nRelativeSimpleTime;
161 // TODO(Q3): Refactor this mess
162 if( isAutoReverse() )
164 // divert active duration into repeat and
165 // fractional part.
166 const double nFractionalActiveDuration( modf(nT, &nRepeats) );
168 // for auto-reverse, map ranges [1,2), [3,4), ...
169 // to ranges [0,1), [1,2), etc.
170 if( ((int)nRepeats) % 2 )
172 // we're in an odd range, reverse sweep
173 nRelativeSimpleTime = 1.0 - nFractionalActiveDuration;
175 else
177 // we're in an even range, pass on as is
178 nRelativeSimpleTime = nFractionalActiveDuration;
181 // effective repeat count for autoreverse is half of
182 // the input time's value (each run of an autoreverse
183 // cycle is half of a repeat)
184 nRepeats /= 2;
186 else
188 // determine repeat
189 // ================
191 // calc simple time and number of repeats from nT
192 // Now, that's easy, since the fractional part of
193 // nT gives the relative simple time, and the
194 // integer part the number of full repeats:
195 nRelativeSimpleTime = modf(nT, &nRepeats);
197 // clamp repeats to max permissible value (maRepeats.getValue() - 1.0)
198 if( isRepeatCountValid() &&
199 nRepeats >= getRepeatCount() )
201 // Note that this code here only gets
202 // triggered if maRepeats.getValue() is an
203 // _integer_. Otherwise, nRepeats will never
204 // reach nor exceed
205 // maRepeats.getValue(). Thus, the code below
206 // does not need to handle cases of fractional
207 // repeats, and can always assume that a full
208 // animation run has ended (with
209 // nRelativeSimpleTime=1.0 for
210 // non-autoreversed activities).
212 // with modf, nRelativeSimpleTime will never
213 // become 1.0, since nRepeats is incremented and
214 // nRelativeSimpleTime set to 0.0 then.
216 // For the animation to reach its final value,
217 // nRepeats must although become
218 // maRepeats.getValue()-1.0, and
219 // nRelativeSimpleTime=1.0.
220 nRelativeSimpleTime = 1.0;
221 nRepeats -= 1.0;
225 // actually perform something
226 // ==========================
228 simplePerform( nRelativeSimpleTime,
229 // nRepeats is already integer-valued
230 static_cast<sal_uInt32>( nRepeats ) );
233 // delayed endActivity() call from end condition check
234 // below. Issued after the simplePerform() call above, to
235 // give animations the chance to correctly reach the
236 // animation end value, without spurious bail-outs because
237 // of isActive() returning false.
238 if( bActivityEnding )
239 endActivity();
241 // one more frame successfully performed
242 ++mnCurrPerformCalls;
244 return isActive();
249 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */