X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/b8f049904074a64d799709686ebc7a4576683314..0ca5105b3419d5c808f823c0a63885f07c0d170f:/src/common/timercmn.cpp diff --git a/src/common/timercmn.cpp b/src/common/timercmn.cpp index c96067d1d2..3bf88317e8 100644 --- a/src/common/timercmn.cpp +++ b/src/common/timercmn.cpp @@ -1,14 +1,17 @@ ///////////////////////////////////////////////////////////////////////////// // Name: common/timercmn.cpp // Purpose: Common timer implementation -// Author: Julian Smart -// Modified by: Vadim Zeitlin on 12.11.99 to get rid of all ifdefs -// Sylvain Bougnoux on ?? to add wxStopWatch class -// Guillermo Rodriguez , 12/99 complete rewrite. +// Author: +// Original version by Julian Smart +// Vadim Zeitlin got rid of all ifdefs (11.12.99) +// Sylvain Bougnoux added wxStopWatch class +// Guillermo Rodriguez rewrote from scratch (Dic/99) +// Modified by: // Created: 04/01/98 // RCS-ID: $Id$ // Copyright: (c) Julian Smart and Markus Holzem -// Licence: wxWindows license +// (c) 1999 Guillermo Rodriguez +// Licence: wxWindows license ///////////////////////////////////////////////////////////////////////////// // ============================================================================ @@ -16,7 +19,7 @@ // ============================================================================ // ---------------------------------------------------------------------------- -// headers +// wxWin headers // ---------------------------------------------------------------------------- #ifdef __GNUG__ @@ -38,10 +41,30 @@ #include "wx/timer.h" #include "wx/longlong.h" +// ---------------------------------------------------------------------------- +// System headers +// ---------------------------------------------------------------------------- + #if defined(__WIN32__) #include #endif +#if defined(__WIN32__) && !defined(HAVE_FTIME) && !defined(__MWERKS__) + #define HAVE_FTIME +#endif + +#if defined(__VISAGECPP__) && !defined(HAVE_FTIME) + #define HAVE_FTIME +# if __IBMCPP__ >= 400 + # define ftime(x) _ftime(x) +# endif +#endif + +#if defined(__MWERKS__) && defined(__WXMSW__) +# undef HAVE_FTIME +# undef HAVE_GETTIMEOFDAY +#endif + #include #ifndef __WXMAC__ #include // for time_t @@ -54,6 +77,18 @@ #include #endif +#ifdef __WXMAC__ + #include + #include +#endif +// ---------------------------------------------------------------------------- +// wxWin macros +// ---------------------------------------------------------------------------- + +#if wxUSE_GUI && wxUSE_TIMER + IMPLEMENT_DYNAMIC_CLASS(wxTimerEvent, wxEvent) +#endif // wxUSE_GUI + // ---------------------------------------------------------------------------- // macros // ---------------------------------------------------------------------------- @@ -73,34 +108,80 @@ // implementation // ============================================================================ -wxLongLong wxGetLocalTimeMillis(); +// ---------------------------------------------------------------------------- +// wxTimerBase +// ---------------------------------------------------------------------------- + +#if wxUSE_GUI && wxUSE_TIMER + +wxTimerBase::~wxTimerBase() +{ + // this destructor is required for Darwin +} + +void wxTimerBase::Notify() +{ + // the base class version generates an event if it has owner - which it + // should because otherwise nobody can process timer events + wxCHECK_RET( m_owner, _T("wxTimer::Notify() should be overridden.") ); + + wxTimerEvent event(m_idTimer, m_milli); + (void)m_owner->ProcessEvent(event); +} + +bool wxTimerBase::Start(int milliseconds, bool oneShot) +{ + if ( IsRunning() ) + { + // not stopping the already running timer might work for some + // platforms (no problems under MSW) but leads to mysterious crashes + // on the others (GTK), so to be on the safe side do it here + Stop(); + } + + if ( milliseconds != -1 ) + { + m_milli = milliseconds; + } + + m_oneShot = oneShot; + + return TRUE; +} + +#endif // wxUSE_GUI // ---------------------------------------------------------------------------- // wxStopWatch // ---------------------------------------------------------------------------- +#if wxUSE_LONGLONG + void wxStopWatch::Start(long t) { m_t0 = wxGetLocalTimeMillis() - t; - m_pause = 0; } -long wxStopWatch::Time() const +long wxStopWatch::GetElapsedTime() const { - return (m_pause ? m_pause : GetElapsedTime()); + return (wxGetLocalTimeMillis() - m_t0).GetLo(); } -long wxStopWatch::GetElapsedTime() const +long wxStopWatch::Time() const { - return (wxGetLocalTimeMillis() - m_t0).GetLo(); + return m_pauseCount ? m_pause : GetElapsedTime(); } +#endif // wxUSE_LONGLONG + // ---------------------------------------------------------------------------- // old timer functions superceded by wxStopWatch // ---------------------------------------------------------------------------- -static wxLongLong wxStartTime = 0; +#if wxUSE_LONGLONG + +static wxLongLong wxStartTime = 0l; // starts the global timer void wxStartTimer() @@ -120,6 +201,7 @@ long wxGetElapsedTime(bool resetTimer) return (newTime - oldTime).GetLo(); } +#endif // wxUSE_LONGLONG // ---------------------------------------------------------------------------- // the functions to get the current time and timezone info @@ -159,7 +241,8 @@ long wxGetLocalTime() // Get UTC time as seconds since 00:00:00, Jan 1st 1970 long wxGetUTCTime() { - struct tm tm, *ptm; + struct tm tm; + struct tm *ptm; time_t t0, t1; // This cannot be made static because mktime can overwrite it @@ -192,44 +275,121 @@ long wxGetUTCTime() if (t0 != (time_t)-1 ) return (long)difftime(t1, t0) + (60 * 60 * 24 * 4); - wxLogSysError(_("Failed 2nd mktime")); + wxLogSysError(_("mktime() failed")); + } + else + { + wxLogSysError(_("gmtime() failed")); } - wxLogSysError(_("Failed gmtime")); } - wxLogSysError(_("Failed to get the UTC system time")); + + wxLogError(_("Failed to get the UTC system time.")); + return -1; } +#if wxUSE_LONGLONG // Get local time as milliseconds since 00:00:00, Jan 1st 1970 wxLongLong wxGetLocalTimeMillis() { - // We use wxGetLocalTime() to get the seconds since - // 00:00:00 Jan 1st 1970 and then whatever is available - // to get millisecond resolution. - // - wxLongLong val = 1000 * wxGetLocalTime(); + wxLongLong val = 1000l; - // If we got here, do not fail even if we can't get - // millisecond resolution. - // -#if defined(__WIN32__) - SYSTEMTIME st; - ::GetLocalTime(&st); - return (val + st.wMilliseconds); + // If possible, use a function which avoids conversions from + // broken-up time structures to milliseconds + +#if defined(__WXMSW__) && defined(__MWERKS__) + // This should probably be the way all WXMSW compilers should do it + // Go direct to the OS for time + + SYSTEMTIME thenst = { 1970, 1, 4, 1, 0, 0, 0, 0 }; // 00:00:00 Jan 1st 1970 + FILETIME thenft; + SystemTimeToFileTime( &thenst, &thenft ); + wxLongLong then( thenft.dwHighDateTime, thenft.dwLowDateTime ); // time in 100 nanoseconds + + SYSTEMTIME nowst; + GetLocalTime( &nowst ); + FILETIME nowft; + SystemTimeToFileTime( &nowst, &nowft ); + wxLongLong now( nowft.dwHighDateTime, nowft.dwLowDateTime ); // time in 100 nanoseconds + + return ( now - then ) / 10000.0; // time from 00:00:00 Jan 1st 1970 to now in milliseconds + #elif defined(HAVE_GETTIMEOFDAY) struct timeval tp; if ( wxGetTimeOfDay(&tp, (struct timezone *)NULL) != -1 ) { + val *= tp.tv_sec; return (val + (tp.tv_usec / 1000)); } + else + { + wxLogError(_("wxGetTimeOfDay failed.")); + return 0; + } #elif defined(HAVE_FTIME) struct timeb tp; - if ( ftime(&tp) == 0 ) + + // ftime() is void and not int in some mingw32 headers, so don't + // test the return code (well, it shouldn't fail anyhow...) + (void)ftime(&tp); + val *= tp.time; + return (val + tp.millitm); +#elif defined(__WXMAC__) + + UInt64 gMilliAtStart = 0 ; + Nanoseconds upTime = AbsoluteToNanoseconds( UpTime() ) ; + if ( gMilliAtStart == 0 ) { - return (val + tp.millitm); + time_t start = time(NULL) ; + gMilliAtStart = ((UInt64) start) * 1000L ; + gMilliAtStart -= upTime.lo / 1000 ; + gMilliAtStart -= ( ( (UInt64) upTime.hi ) << 32 ) / 1000 ; } + UInt64 millival = gMilliAtStart ; + millival += upTime.lo / 1000 ; + millival += ( ( (UInt64) upTime.hi ) << 32 ) / 1000 ; + val = millival ; + return val ; +#else // no gettimeofday() nor ftime() + // We use wxGetLocalTime() to get the seconds since + // 00:00:00 Jan 1st 1970 and then whatever is available + // to get millisecond resolution. + // + // NOTE that this might lead to a problem if the clocks + // use different sources, so this approach should be + // avoided where possible. + + val *= wxGetLocalTime(); + +// GRG: This will go soon as all WIN32 seem to have ftime +#if defined (__WIN32__) + // If your platform/compiler needs to use two different functions + // to get ms resolution, please do NOT just shut off these warnings, + // drop me a line instead at + #warning "Possible clock skew bug in wxGetLocalTimeMillis()!" + + SYSTEMTIME st; + ::GetLocalTime(&st); + val += st.wMilliseconds; +#else // !Win32 + // If your platform/compiler does not support ms resolution please + // do NOT just shut off these warnings, drop me a line instead at + // + + #if defined(__VISUALC__) || defined (__WATCOMC__) + #pragma message("wxStopWatch will be up to second resolution!") + #elif defined(__BORLANDC__) + #pragma message "wxStopWatch will be up to second resolution!" + #else + #warning "wxStopWatch will be up to second resolution!" + #endif // compiler #endif return val; + +#endif // time functions } + +#endif // wxUSE_LONGLONG +