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