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_canvas.hxx" 30 31 #include "osl/time.h" 32 #include "osl/diagnose.h" 33 #include "canvas/elapsedtime.hxx" 34 35 #if defined(WNT) 36 37 #if defined _MSC_VER 38 #pragma warning(push,1) 39 #endif 40 41 // TEMP!!! 42 // Awaiting corresponding functionality in OSL 43 // 44 #define WIN32_LEAN_AND_MEAN 45 #include <windows.h> 46 #include <winbase.h> 47 #include <mmsystem.h> 48 #endif 49 50 #if defined _MSC_VER 51 #pragma warning(pop) 52 #endif 53 54 #include <algorithm> 55 #include <limits> 56 57 namespace canvas { 58 namespace tools { 59 60 61 #if defined(WNT) 62 // TODO(Q2): is 0 okay for the failure case here? 63 double ElapsedTime::getSystemTime() 64 { 65 // TEMP!!! 66 // Awaiting corresponding functionality in OSL 67 // 68 69 // is there a performance counter available? 70 static bool bTimeSetupDone( false ); 71 static bool bPerfTimerAvailable( false ); 72 static LONGLONG nPerfCountFreq; 73 74 // TODO(F1): This _might_ cause problems, as it prevents correct 75 // time handling for very long lifetimes of this class's 76 // surrounding component in memory. When the difference between 77 // current sys time and nInitialCount exceeds IEEE double's 78 // mantissa, time will start to run jerky. 79 static LONGLONG nInitialCount; 80 81 if( !bTimeSetupDone ) 82 { 83 if( QueryPerformanceFrequency( 84 reinterpret_cast<LARGE_INTEGER *>(&nPerfCountFreq) ) ) 85 { 86 // read initial time: 87 QueryPerformanceCounter( 88 reinterpret_cast<LARGE_INTEGER *>(&nInitialCount) ); 89 bPerfTimerAvailable = true; 90 } 91 bTimeSetupDone = true; 92 } 93 94 if( bPerfTimerAvailable ) 95 { 96 LONGLONG nCurrCount; 97 QueryPerformanceCounter( 98 reinterpret_cast<LARGE_INTEGER *>(&nCurrCount) ); 99 nCurrCount -= nInitialCount; 100 return double(nCurrCount) / nPerfCountFreq; 101 } 102 else 103 { 104 LONGLONG nCurrTime = timeGetTime(); 105 return double(nCurrTime) / 1000.0; 106 } 107 } 108 109 #else // ! WNT 110 111 // TODO(Q2): is 0 okay for the failure case here? 112 double ElapsedTime::getSystemTime() 113 { 114 TimeValue aTimeVal; 115 if( osl_getSystemTime( &aTimeVal ) ) 116 return ((aTimeVal.Nanosec * 10e-10) + aTimeVal.Seconds); 117 else 118 return 0.0; 119 } 120 121 #endif 122 123 ElapsedTime::ElapsedTime() 124 : m_pTimeBase(), 125 m_fLastQueriedTime( 0.0 ), 126 m_fStartTime( getSystemTime() ), 127 m_fFrozenTime( 0.0 ), 128 m_bInPauseMode( false ), 129 m_bInHoldMode( false ) 130 { 131 } 132 133 ElapsedTime::ElapsedTime( 134 boost::shared_ptr<ElapsedTime> const & pTimeBase ) 135 : m_pTimeBase( pTimeBase ), 136 m_fLastQueriedTime( 0.0 ), 137 m_fStartTime( getCurrentTime() ), 138 m_fFrozenTime( 0.0 ), 139 m_bInPauseMode( false ), 140 m_bInHoldMode( false ) 141 { 142 } 143 144 boost::shared_ptr<ElapsedTime> const & ElapsedTime::getTimeBase() const 145 { 146 return m_pTimeBase; 147 } 148 149 void ElapsedTime::reset() 150 { 151 m_fLastQueriedTime = 0.0; 152 m_fStartTime = getCurrentTime(); 153 m_fFrozenTime = 0.0; 154 m_bInPauseMode = false; 155 m_bInHoldMode = false; 156 } 157 158 void ElapsedTime::adjustTimer( double fOffset, bool /*bLimitToLastQueriedTime*/ ) 159 { 160 // to make getElapsedTime() become _larger_, have to reduce 161 // m_fStartTime. 162 m_fStartTime -= fOffset; 163 164 // also adjust frozen time, this method must _always_ affect the 165 // value returned by getElapsedTime()! 166 if (m_bInHoldMode || m_bInPauseMode) 167 m_fFrozenTime += fOffset; 168 } 169 170 double ElapsedTime::getCurrentTime() const 171 { 172 return m_pTimeBase.get() == 0 173 ? getSystemTime() : m_pTimeBase->getElapsedTimeImpl(); 174 } 175 176 double ElapsedTime::getElapsedTime() const 177 { 178 m_fLastQueriedTime = getElapsedTimeImpl(); 179 return m_fLastQueriedTime; 180 } 181 182 double ElapsedTime::getElapsedTimeImpl() const 183 { 184 if (m_bInHoldMode || m_bInPauseMode) 185 return m_fFrozenTime; 186 187 return getCurrentTime() - m_fStartTime; 188 } 189 190 void ElapsedTime::pauseTimer() 191 { 192 m_fFrozenTime = getElapsedTimeImpl(); 193 m_bInPauseMode = true; 194 } 195 196 void ElapsedTime::continueTimer() 197 { 198 m_bInPauseMode = false; 199 200 // stop pausing, time runs again. Note that 201 // getElapsedTimeImpl() honors hold mode, i.e. a 202 // continueTimer() in hold mode will preserve the latter 203 const double fPauseDuration( getElapsedTimeImpl() - m_fFrozenTime ); 204 205 // adjust start time, such that subsequent getElapsedTime() calls 206 // will virtually start from m_fFrozenTime. 207 m_fStartTime += fPauseDuration; 208 } 209 210 void ElapsedTime::holdTimer() 211 { 212 // when called during hold mode (e.g. more than once per time 213 // object), the original hold time will be maintained. 214 m_fFrozenTime = getElapsedTimeImpl(); 215 m_bInHoldMode = true; 216 } 217 218 void ElapsedTime::releaseTimer() 219 { 220 m_bInHoldMode = false; 221 } 222 223 } // namespace tools 224 } // namespace canvas 225