diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/Fl_Timeout.cxx | 129 |
1 files changed, 98 insertions, 31 deletions
diff --git a/src/Fl_Timeout.cxx b/src/Fl_Timeout.cxx index f8ae8df94..e52573ff0 100644 --- a/src/Fl_Timeout.cxx +++ b/src/Fl_Timeout.cxx @@ -2,7 +2,7 @@ // Timeout support functions for the Fast Light Tool Kit (FLTK). // // Author: Albrecht Schlosser -// Copyright 2021-2022 by Bill Spitzak and others. +// Copyright 2021-2023 by Bill Spitzak and others. // // This library is free software. Distribution and use rights are outlined in // the file "COPYING" which should have been included with this file. If this @@ -34,40 +34,108 @@ Fl_Timeout *Fl_Timeout::current_timeout = 0; static int num_timers = 0; // DEBUG #endif -// Internal timestamp, used for delta time calculation. -// Note: FLTK naming convention is not used here to avoid potential conflicts -// in the future. +/** + Set a time stamp at this point in time. + + The time stamp is an opaque type and does not represent the time of day or + some time and date in the calendar. It is used with Fl::seconds_between() and + Fl::seconds_since() to measure elapsed time. + + \code + Fl_Timestamp start = Fl::now(); + // do something + double s = Fl::seconds_since(start); + printf("That operation took %g seconds\n", s); + \endcode + + Depending on the system the resolution may be milliseconds or microseconds. + Under certain conditions (particularly on Windows) the value in member `sec` + may wrap around and does not represent a real time (maybe runtime of the system). + Function seconds_since() below uses this to subtract two timestamps which is + always a correct delta time with milliseconds or microseconds resolution. + + \todo Fl::system_driver()->gettime() was implemented for the Forms library and + has a limited resolution (on Windows: milliseconds). On POSIX platforms it uses + gettimeofday() with microsecond resolution. + A new function could use a better resolution on Windows with its multimedia + timers which requires a new dependency: winmm.lib (dll). This could be a future + improvement, maybe set as a build option or generally (requires Win95 or 98?). + + \return this moment in time as an opaque time stamp + + \see Fl::seconds_since(Fl_Timestamp& then) + Fl::seconds_between(Fl_Timestamp& back, Fl_Timestamp& further_back) + Fl::ticks_since(Fl_Timestamp& then) + Fl::ticks_between(Fl_Timestamp& back, Fl_Timestamp& further_back) + */ +Fl_Timestamp Fl::now() { + Fl_Timestamp ts; + time_t sec; + int usec; + Fl::system_driver()->gettime(&sec, &usec); + ts.sec = (long)sec; + ts.usec = usec; + return ts; // C++ will copy the result into the lvalue for us +} -struct FlTimeStamp { - long sec; - long usec; -}; +/** + Return the time in seconds between now and a previously taken time stamp. -typedef struct FlTimeStamp FlTimeStamp_t; + \param[in] then a previously taken time stamp + \return elapsed seconds and fractions of a second -// Get a timestamp of type FlTimeStamp. + \see Fl::seconds_between(Fl_Timestamp& back, Fl_Timestamp& further_back) + Fl::now() + */ +double Fl::seconds_since(Fl_Timestamp& then) { + Fl_Timestamp ts_now = Fl::now(); + return Fl::seconds_between(ts_now, then); +} -// Depending on the system the resolution may be milliseconds or microseconds. -// Under certain conditions (particularly on Windows) the value in member `sec' -// may wrap around and does not represent a real time (maybe runtime of the system). -// Function elapsed_time() below uses this to subtract two timestamps which is always -// a correct delta time with milliseconds or microseconds resolution. +/** + Return the time in seconds between two time stamps. -// To do: Fl::system_driver()->gettime() was implemented for the Forms library and -// has a limited resolution (on Windows: milliseconds). On POSIX platforms it uses -// gettimeofday() with microsecond resolution. -// A new function could use a better resolution on Windows with its multimedia -// timers which requires a new dependency: winmm.lib (dll). This could be a future -// improvement, maybe set as a build option or generally (requires Win95 or 98?). + \param[in] back a previously taken time stamp + \param[in] further_back an even earlier time stamp + \return elapsed seconds and fractions of a second -static void get_timestamp(FlTimeStamp_t *ts) { - time_t sec; - int usec; - Fl::system_driver()->gettime(&sec, &usec); - ts->sec = (long)sec; - ts->usec = usec; + \see Fl::seconds_since(Fl_Timestamp& then), Fl::now() + */ +double Fl::seconds_between(Fl_Timestamp& back, Fl_Timestamp& further_back) { + return double((back.sec - further_back.sec) + (back.usec - further_back.usec) / 1000000.); } +/** + Return the time in ticks (60Hz) between now and a previously taken time stamp. + + Ticks are a convenient way to time animations 'per frame'. Even though + modern computers use all kinds of screen refresh rates, 60Hz is a very good + base for animation that is typically shown in user interface graphics. + + \param[in] then a previously taken time stamp + \return elapsed ticks in 60th of a second + + \see Fl::ticks_between(Fl_Timestamp& back, Fl_Timestamp& further_back), Fl::now() + */ +long Fl::ticks_since(Fl_Timestamp& then) { + Fl_Timestamp ts_now = Fl::now(); + return Fl::ticks_between(ts_now, then); +} + +/** + Return the time in ticks (60Hz) between two time stamps. + + \param[in] back a previously taken time stamp + \param[in] further_back an even earlier time stamp + \return elapsed ticks in 60th of a second + + \see Fl::ticks_since(Fl_Timestamp& then), Fl::now() + */ +long Fl::ticks_between(Fl_Timestamp& back, Fl_Timestamp& further_back) { + return (back.sec-further_back.sec)*60 + (back.usec-further_back.usec)/16666; +} + + // Returns 0 and initializes the "previous" timestamp when called for the first time. /* @@ -83,14 +151,13 @@ static void get_timestamp(FlTimeStamp_t *ts) { */ static double elapsed_time() { static int first = 1; // initialization - static FlTimeStamp_t prev; // previous timestamp - FlTimeStamp_t now; // current timestamp + static Fl_Timestamp prev; // previous timestamp + Fl_Timestamp now = Fl::now(); // current timestamp double elapsed = 0.0; - get_timestamp(&now); if (first) { first = 0; } else { - elapsed = double((now.sec - prev.sec) + (now.usec - prev.usec) / 1000000.); + elapsed = Fl::seconds_between(now, prev); } prev = now; return elapsed; |
