xref: /trunk/main/canvas/source/tools/elapsedtime.cxx (revision cdf0e10c)
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