1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sdext.hxx"
26
27 #include "PresenterAnimator.hxx"
28
29 #include "PresenterTimer.hxx"
30 #include <osl/diagnose.h>
31 #include <osl/time.h>
32 #include <vos/timer.hxx>
33 #include <boost/bind.hpp>
34 #include <boost/function.hpp>
35
36 namespace sdext { namespace presenter {
37
38
39
40 //===== PresenterAnimator =====================================================
41
PresenterAnimator(void)42 PresenterAnimator::PresenterAnimator (void)
43 : maFutureAnimations(),
44 maActiveAnimations(),
45 mnCurrentTaskId(0),
46 mnNextTime(0)
47 {
48 }
49
50
51
52
~PresenterAnimator(void)53 PresenterAnimator::~PresenterAnimator (void)
54 {
55 PresenterTimer::CancelTask(mnCurrentTaskId);
56 }
57
58
59
60
61
AddAnimation(const SharedPresenterAnimation & rpAnimation)62 void PresenterAnimator::AddAnimation (const SharedPresenterAnimation& rpAnimation)
63 {
64 ::osl::MutexGuard aGuard (m_aMutex);
65
66 maFutureAnimations.insert(AnimationList::value_type(rpAnimation->GetStartTime(), rpAnimation));
67 ScheduleNextRun();
68 }
69
70
71
72
Process(void)73 void PresenterAnimator::Process (void)
74 {
75 ::osl::MutexGuard aGuard (m_aMutex);
76
77 mnNextTime = 0;
78
79 const sal_uInt64 nCurrentTime (GetCurrentTime());
80
81 ActivateAnimations(nCurrentTime);
82
83 while ( ! maActiveAnimations.empty())
84 {
85 sal_uInt64 nRequestedTime (maActiveAnimations.begin()->first);
86 SharedPresenterAnimation pAnimation (maActiveAnimations.begin()->second);
87
88 if (nRequestedTime > nCurrentTime)
89 break;
90
91 maActiveAnimations.erase(maActiveAnimations.begin());
92
93 const double nTotalDuration (double(pAnimation->GetEndTime() - pAnimation->GetStartTime()));
94 double nProgress (nTotalDuration > 0 ? (nCurrentTime - pAnimation->GetStartTime()) / nTotalDuration : 1);
95 if (nProgress <= 0)
96 nProgress = 0;
97 else if (nProgress >= 1)
98 nProgress = 1;
99
100 OSL_TRACE("running animation step at %f (requested was %f) %f\n",
101 nCurrentTime/1e6, nRequestedTime/1e6, nProgress);
102 pAnimation->Run(nProgress, nCurrentTime);
103
104 if (nCurrentTime < pAnimation->GetEndTime())
105 maActiveAnimations.insert(
106 AnimationList::value_type(
107 nCurrentTime + pAnimation->GetStepDuration(),
108 pAnimation));
109 else
110 pAnimation->RunEndCallbacks();
111 }
112
113 ScheduleNextRun();
114 }
115
116
117
118
ActivateAnimations(const sal_uInt64 nCurrentTime)119 void PresenterAnimator::ActivateAnimations (const sal_uInt64 nCurrentTime)
120 {
121 while ( ! maFutureAnimations.empty()
122 && maFutureAnimations.begin()->first <= nCurrentTime)
123 {
124 SharedPresenterAnimation pAnimation (maFutureAnimations.begin()->second);
125 maActiveAnimations.insert(*maFutureAnimations.begin());
126 maFutureAnimations.erase(maFutureAnimations.begin());
127 pAnimation->RunStartCallbacks();
128 }
129 }
130
131
132
133
ScheduleNextRun(void)134 void PresenterAnimator::ScheduleNextRun (void)
135 {
136 sal_uInt64 nStartTime (0);
137
138 if ( ! maActiveAnimations.empty())
139 {
140 nStartTime = maActiveAnimations.begin()->first;
141 if ( ! maFutureAnimations.empty())
142 if (maFutureAnimations.begin()->first < nStartTime)
143 nStartTime = maFutureAnimations.begin()->first;
144 }
145 else if ( ! maFutureAnimations.empty())
146 nStartTime = maFutureAnimations.begin()->first;
147
148 if (nStartTime > 0)
149 ScheduleNextRun(nStartTime);
150 }
151
152
153
154
ScheduleNextRun(const sal_uInt64 nStartTime)155 void PresenterAnimator::ScheduleNextRun (const sal_uInt64 nStartTime)
156 {
157 if (mnNextTime==0 || nStartTime<mnNextTime)
158 {
159 mnNextTime = nStartTime;
160 ::vos::TTimeValue aTimeValue (GetSeconds(mnNextTime), GetNanoSeconds(mnNextTime));
161 PresenterTimer::ScheduleSingleTaskAbsolute (
162 ::boost::bind(&PresenterAnimator::Process, this),
163 aTimeValue);
164 }
165 }
166
167 } } // end of namespace ::sdext::presenter
168