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: discreteactivitybase.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 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_slideshow.hxx"
35 #include <canvas/debug.hxx>
36 #include <tools/diagnose_ex.h>
37 #include <canvas/verbosetrace.hxx>
39 #include <discreteactivitybase.hxx>
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?" );
60 // check parameters: rDiscreteTimes must be sorted in
61 // ascending order, and contain values only from the range
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?
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
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
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
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
) );
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() )
148 // schedule next frame, if either repeat is indefinite
149 // (repeat forever), or we've not yet reached the requested
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
161 // Somewhat condensed, the argument for setNextTimeout below could
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(
180 nVectorSize
) ] ) ) );
182 getEventQueue().addEvent( mpWakeupEvent
);
186 // release event reference (relation to wakeup event
188 mpWakeupEvent
.reset();
190 // done with this activity
194 return false; // remove from queue, will be added back by the wakeup event.
197 void DiscreteActivityBase::dispose()
201 mpWakeupEvent
->dispose();
203 // release references
204 mpWakeupEvent
.reset();
206 ActivityBase::dispose();