Update ooo320-m1
[ooovba.git] / slideshow / source / engine / activities / discreteactivitybase.cxx
blob179c33853da79dbf109dc18c8bc563542dbfde65
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: discreteactivitybase.cxx,v $
10 * $Revision: 1.10 $
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 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_slideshow.hxx"
34 // must be first
35 #include <canvas/debug.hxx>
36 #include <tools/diagnose_ex.h>
37 #include <canvas/verbosetrace.hxx>
39 #include <discreteactivitybase.hxx>
42 namespace slideshow
44 namespace internal
46 DiscreteActivityBase::DiscreteActivityBase( const ActivityParameters& rParms ) :
47 ActivityBase( rParms ),
48 mpWakeupEvent( rParms.mpWakeupEvent ),
49 maDiscreteTimes( rParms.maDiscreteTimes ),
50 mnSimpleDuration( rParms.mnMinDuration ),
51 mnCurrPerformCalls( 0 )
53 ENSURE_OR_THROW( mpWakeupEvent,
54 "DiscreteActivityBase::DiscreteActivityBase(): Invalid wakeup event" );
56 ENSURE_OR_THROW( !maDiscreteTimes.empty(),
57 "DiscreteActivityBase::DiscreteActivityBase(): time vector is empty, why do you create me?" );
59 #ifdef DBG_UTIL
60 // check parameters: rDiscreteTimes must be sorted in
61 // ascending order, and contain values only from the range
62 // [0,1]
63 for( ::std::size_t i=1, len=maDiscreteTimes.size(); i<len; ++i )
65 if( maDiscreteTimes[i] < 0.0 ||
66 maDiscreteTimes[i] > 1.0 ||
67 maDiscreteTimes[i-1] < 0.0 ||
68 maDiscreteTimes[i-1] > 1.0 )
70 ENSURE_OR_THROW( false, "DiscreteActivityBase::DiscreteActivityBase(): time values not within [0,1] range!" );
73 if( maDiscreteTimes[i-1] > maDiscreteTimes[i] )
74 ENSURE_OR_THROW( false, "DiscreteActivityBase::DiscreteActivityBase(): time vector is not sorted in ascending order!" );
77 // TODO(E2): check this also in production code?
78 #endif
81 void DiscreteActivityBase::startAnimation()
83 // start timer on wakeup event
84 mpWakeupEvent->start();
87 sal_uInt32 DiscreteActivityBase::calcFrameIndex( sal_uInt32 nCurrCalls,
88 ::std::size_t nVectorSize ) const
90 if( isAutoReverse() )
92 // every full repeat run consists of one
93 // forward and one backward traversal.
94 sal_uInt32 nFrameIndex( nCurrCalls % (2*nVectorSize) );
96 // nFrameIndex values >= nVectorSize belong to
97 // the backward traversal
98 if( nFrameIndex >= nVectorSize )
99 nFrameIndex = 2*nVectorSize - nFrameIndex; // invert sweep
101 return nFrameIndex;
103 else
105 return nCurrCalls % nVectorSize ;
109 sal_uInt32 DiscreteActivityBase::calcRepeatCount( sal_uInt32 nCurrCalls,
110 ::std::size_t nVectorSize ) const
112 if( isAutoReverse() )
113 return nCurrCalls / (2*nVectorSize); // we've got 2 cycles per repeat
114 else
115 return nCurrCalls / nVectorSize;
118 bool DiscreteActivityBase::perform()
120 // call base class, for start() calls and end handling
121 if( !ActivityBase::perform() )
122 return false; // done, we're ended
124 const ::std::size_t nVectorSize( maDiscreteTimes.size() );
126 // actually perform something
127 // ==========================
129 // TODO(Q3): Refactor this mess
131 // call derived class with current frame index (modulo
132 // vector size, to cope with repeats)
133 perform( calcFrameIndex( mnCurrPerformCalls, nVectorSize ),
134 calcRepeatCount( mnCurrPerformCalls, nVectorSize ) );
136 // calc next index
137 ++mnCurrPerformCalls;
139 // calc currently reached repeat count
140 double nCurrRepeat( double(mnCurrPerformCalls) / nVectorSize );
142 // if auto-reverse is specified, halve the
143 // effective repeat count, since we pass every
144 // repeat run twice: once forward, once backward.
145 if( isAutoReverse() )
146 nCurrRepeat /= 2.0;
148 // schedule next frame, if either repeat is indefinite
149 // (repeat forever), or we've not yet reached the requested
150 // repeat count
151 if( !isRepeatCountValid() ||
152 nCurrRepeat < getRepeatCount() )
154 // add wake-up event to queue (modulo
155 // vector size, to cope with repeats).
157 // repeat is handled locally, only apply acceleration/deceleration.
158 // Scale time vector with simple duration, offset with full repeat
159 // times.
161 // Somewhat condensed, the argument for setNextTimeout below could
162 // be written as
164 // mnSimpleDuration*(nFullRepeats + calcAcceleratedTime( currentRepeatTime )),
166 // with currentRepeatTime = maDiscreteTimes[ currentRepeatIndex ]
168 // Note that calcAcceleratedTime() is only applied to the current repeat's value,
169 // not to the total resulting time. This is in accordance with the SMIL spec.
171 mpWakeupEvent->setNextTimeout(
172 mnSimpleDuration*(
173 calcRepeatCount(
174 mnCurrPerformCalls,
175 nVectorSize ) +
176 calcAcceleratedTime(
177 maDiscreteTimes[
178 calcFrameIndex(
179 mnCurrPerformCalls,
180 nVectorSize ) ] ) ) );
182 getEventQueue().addEvent( mpWakeupEvent );
184 else
186 // release event reference (relation to wakeup event
187 // is circular!)
188 mpWakeupEvent.reset();
190 // done with this activity
191 endActivity();
194 return false; // remove from queue, will be added back by the wakeup event.
197 void DiscreteActivityBase::dispose()
199 // dispose event
200 if( mpWakeupEvent )
201 mpWakeupEvent->dispose();
203 // release references
204 mpWakeupEvent.reset();
206 ActivityBase::dispose();