]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/common/stopwatch.cpp
Return NULL from wxWindow::GetCapture() when the capture is being lost.
[wxWidgets.git] / src / common / stopwatch.cpp
... / ...
CommitLineData
1///////////////////////////////////////////////////////////////////////////////
2// Name: src/common/stopwatch.cpp
3// Purpose: wxStopWatch and other non-GUI stuff from wx/timer.h
4// Author:
5// Original version by Julian Smart
6// Vadim Zeitlin got rid of all ifdefs (11.12.99)
7// Sylvain Bougnoux added wxStopWatch class
8// Guillermo Rodriguez <guille@iies.es> rewrote from scratch (Dic/99)
9// Modified by:
10// Created: 20.06.2003 (extracted from common/timercmn.cpp)
11// Copyright: (c) 1998-2003 wxWidgets Team
12// Licence: wxWindows licence
13///////////////////////////////////////////////////////////////////////////////
14
15// ============================================================================
16// declarations
17// ============================================================================
18
19// ----------------------------------------------------------------------------
20// headers
21// ----------------------------------------------------------------------------
22
23// for compilers that support precompilation, includes "wx.h".
24#include "wx/wxprec.h"
25
26#ifdef __BORLANDC__
27 #pragma hdrstop
28#endif
29
30#include "wx/stopwatch.h"
31
32#if wxUSE_STOPWATCH
33
34#ifndef WX_PRECOMP
35 #ifdef __WINDOWS__
36 #include "wx/msw/wrapwin.h"
37 #endif
38 #include "wx/log.h"
39 #include "wx/thread.h"
40#endif //WX_PRECOMP
41
42// ============================================================================
43// implementation
44// ============================================================================
45
46// ----------------------------------------------------------------------------
47// wxStopWatch
48// ----------------------------------------------------------------------------
49
50namespace
51{
52
53#ifdef __WINDOWS__
54
55struct PerfCounter
56{
57 PerfCounter()
58 {
59 init = false;
60 }
61
62 bool CanBeUsed() const
63 {
64 return freq.QuadPart != 0;
65 }
66
67 wxCRIT_SECT_DECLARE_MEMBER(cs);
68 LARGE_INTEGER freq;
69 bool init;
70} gs_perfCounter;
71
72#endif // __WINDOWS__
73
74const int MILLISECONDS_PER_SECOND = 1000;
75const int MICROSECONDS_PER_MILLISECOND = 1000;
76const int MICROSECONDS_PER_SECOND = 1000*1000;
77
78} // anonymous namespace
79
80void wxStopWatch::DoStart()
81{
82#ifdef __WINDOWS__
83 if ( !gs_perfCounter.init )
84 {
85 wxCRIT_SECT_LOCKER(lock, gs_perfCounter.cs);
86 ::QueryPerformanceFrequency(&gs_perfCounter.freq);
87
88 // Just a sanity check: it's not supposed to happen but verify that
89 // ::QueryPerformanceCounter() succeeds so that we can really use it.
90 LARGE_INTEGER counter;
91 if ( !::QueryPerformanceCounter(&counter) )
92 {
93 wxLogDebug("QueryPerformanceCounter() unexpected failed (%s), "
94 "will not use it.", wxSysErrorMsg());
95
96 gs_perfCounter.freq.QuadPart = 0;
97 }
98
99 gs_perfCounter.init = true;
100 }
101#endif // __WINDOWS__
102
103 m_t0 = GetCurrentClockValue();
104}
105
106wxLongLong wxStopWatch::GetClockFreq() const
107{
108#ifdef __WINDOWS__
109 // Under MSW we use the high resolution performance counter timer which has
110 // its own frequency (usually related to the CPU clock speed).
111 if ( gs_perfCounter.CanBeUsed() )
112 return gs_perfCounter.freq.QuadPart;
113#endif // __WINDOWS__
114
115#ifdef HAVE_GETTIMEOFDAY
116 // With gettimeofday() we can have nominally microsecond precision and
117 // while this is not the case in practice, it's still better than
118 // millisecond.
119 return MICROSECONDS_PER_SECOND;
120#else // !HAVE_GETTIMEOFDAY
121 // Currently milliseconds are used everywhere else.
122 return MILLISECONDS_PER_SECOND;
123#endif // HAVE_GETTIMEOFDAY/!HAVE_GETTIMEOFDAY
124}
125
126void wxStopWatch::Start(long t0)
127{
128 // Calling Start() makes the stop watch run however many times it was
129 // paused before.
130 m_pauseCount = 0;
131
132 DoStart();
133
134 m_t0 -= (wxLongLong(t0)*GetClockFreq())/MILLISECONDS_PER_SECOND;
135}
136
137wxLongLong wxStopWatch::GetCurrentClockValue() const
138{
139#ifdef __WINDOWS__
140 if ( gs_perfCounter.CanBeUsed() )
141 {
142 LARGE_INTEGER counter;
143 ::QueryPerformanceCounter(&counter);
144 return counter.QuadPart;
145 }
146#endif // __WINDOWS__
147
148#ifdef HAVE_GETTIMEOFDAY
149 return wxGetUTCTimeUSec();
150#else // !HAVE_GETTIMEOFDAY
151 return wxGetUTCTimeMillis();
152#endif // HAVE_GETTIMEOFDAY/!HAVE_GETTIMEOFDAY
153}
154
155wxLongLong wxStopWatch::TimeInMicro() const
156{
157 const wxLongLong elapsed(m_pauseCount ? m_elapsedBeforePause
158 : GetCurrentClockValue() - m_t0);
159
160 return (elapsed*MICROSECONDS_PER_SECOND)/GetClockFreq();
161}
162
163#endif // wxUSE_STOPWATCH
164
165// ----------------------------------------------------------------------------
166// old timer functions superceded by wxStopWatch
167// ----------------------------------------------------------------------------
168
169#if wxUSE_LONGLONG
170
171static wxLongLong wxStartTime = 0l;
172
173// starts the global timer
174void wxStartTimer()
175{
176 wxStartTime = wxGetUTCTimeMillis();
177}
178
179// Returns elapsed time in milliseconds
180long wxGetElapsedTime(bool resetTimer)
181{
182 wxLongLong oldTime = wxStartTime;
183 wxLongLong newTime = wxGetUTCTimeMillis();
184
185 if ( resetTimer )
186 wxStartTime = newTime;
187
188 return (newTime - oldTime).GetLo();
189}
190
191#endif // wxUSE_LONGLONG