1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_sdext.hxx" 30 31 #include "PresenterAnimator.hxx" 32 33 #include "PresenterTimer.hxx" 34 #include <osl/diagnose.h> 35 #include <osl/time.h> 36 #include <vos/timer.hxx> 37 #include <boost/bind.hpp> 38 #include <boost/function.hpp> 39 40 namespace sdext { namespace presenter { 41 42 43 44 //===== PresenterAnimator ===================================================== 45 46 PresenterAnimator::PresenterAnimator (void) 47 : maFutureAnimations(), 48 maActiveAnimations(), 49 mnCurrentTaskId(0), 50 mnNextTime(0) 51 { 52 } 53 54 55 56 57 PresenterAnimator::~PresenterAnimator (void) 58 { 59 PresenterTimer::CancelTask(mnCurrentTaskId); 60 } 61 62 63 64 65 66 void PresenterAnimator::AddAnimation (const SharedPresenterAnimation& rpAnimation) 67 { 68 ::osl::MutexGuard aGuard (m_aMutex); 69 70 maFutureAnimations.insert(AnimationList::value_type(rpAnimation->GetStartTime(), rpAnimation)); 71 ScheduleNextRun(); 72 } 73 74 75 76 77 void PresenterAnimator::Process (void) 78 { 79 ::osl::MutexGuard aGuard (m_aMutex); 80 81 mnNextTime = 0; 82 83 const sal_uInt64 nCurrentTime (GetCurrentTime()); 84 85 ActivateAnimations(nCurrentTime); 86 87 while ( ! maActiveAnimations.empty()) 88 { 89 sal_uInt64 nRequestedTime (maActiveAnimations.begin()->first); 90 SharedPresenterAnimation pAnimation (maActiveAnimations.begin()->second); 91 92 if (nRequestedTime > nCurrentTime) 93 break; 94 95 maActiveAnimations.erase(maActiveAnimations.begin()); 96 97 const double nTotalDuration (double(pAnimation->GetEndTime() - pAnimation->GetStartTime())); 98 double nProgress (nTotalDuration > 0 ? (nCurrentTime - pAnimation->GetStartTime()) / nTotalDuration : 1); 99 if (nProgress <= 0) 100 nProgress = 0; 101 else if (nProgress >= 1) 102 nProgress = 1; 103 104 OSL_TRACE("running animation step at %f (requested was %f) %f\n", 105 nCurrentTime/1e6, nRequestedTime/1e6, nProgress); 106 pAnimation->Run(nProgress, nCurrentTime); 107 108 if (nCurrentTime < pAnimation->GetEndTime()) 109 maActiveAnimations.insert( 110 AnimationList::value_type( 111 nCurrentTime + pAnimation->GetStepDuration(), 112 pAnimation)); 113 else 114 pAnimation->RunEndCallbacks(); 115 } 116 117 ScheduleNextRun(); 118 } 119 120 121 122 123 void PresenterAnimator::ActivateAnimations (const sal_uInt64 nCurrentTime) 124 { 125 while ( ! maFutureAnimations.empty() 126 && maFutureAnimations.begin()->first <= nCurrentTime) 127 { 128 SharedPresenterAnimation pAnimation (maFutureAnimations.begin()->second); 129 maActiveAnimations.insert(*maFutureAnimations.begin()); 130 maFutureAnimations.erase(maFutureAnimations.begin()); 131 pAnimation->RunStartCallbacks(); 132 } 133 } 134 135 136 137 138 void PresenterAnimator::ScheduleNextRun (void) 139 { 140 sal_uInt64 nStartTime (0); 141 142 if ( ! maActiveAnimations.empty()) 143 { 144 nStartTime = maActiveAnimations.begin()->first; 145 if ( ! maFutureAnimations.empty()) 146 if (maFutureAnimations.begin()->first < nStartTime) 147 nStartTime = maFutureAnimations.begin()->first; 148 } 149 else if ( ! maFutureAnimations.empty()) 150 nStartTime = maFutureAnimations.begin()->first; 151 152 if (nStartTime > 0) 153 ScheduleNextRun(nStartTime); 154 } 155 156 157 158 159 void PresenterAnimator::ScheduleNextRun (const sal_uInt64 nStartTime) 160 { 161 if (mnNextTime==0 || nStartTime<mnNextTime) 162 { 163 mnNextTime = nStartTime; 164 ::vos::TTimeValue aTimeValue (GetSeconds(mnNextTime), GetNanoSeconds(mnNextTime)); 165 PresenterTimer::ScheduleSingleTaskAbsolute ( 166 ::boost::bind(&PresenterAnimator::Process, this), 167 aTimeValue); 168 } 169 } 170 171 } } // end of namespace ::sdext::presenter 172