summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Melcher <github@matthiasm.com>2023-02-09 14:48:39 +0100
committerGitHub <noreply@github.com>2023-02-09 14:48:39 +0100
commitffadc23cab725828a3a38646d3efa10bd551f7b2 (patch)
tree404e9a3326bfde284960e16a0e8fd63f320c6c64
parent880fc26857d068789119ac79acf58b57c7d94b9e (diff)
Expose elapsed time API (#670)
-rw-r--r--FL/Fl.H7
-rw-r--r--FL/platform_types.h21
-rw-r--r--src/Fl_Timeout.cxx129
3 files changed, 126 insertions, 31 deletions
diff --git a/FL/Fl.H b/FL/Fl.H
index d33ff393c..925daa591 100644
--- a/FL/Fl.H
+++ b/FL/Fl.H
@@ -470,6 +470,13 @@ public:
static void add_check(Fl_Timeout_Handler, void* = 0);
static int has_check(Fl_Timeout_Handler, void* = 0);
static void remove_check(Fl_Timeout_Handler, void* = 0);
+
+ static Fl_Timestamp now();
+ static double seconds_since(Fl_Timestamp& then);
+ static double seconds_between(Fl_Timestamp& back, Fl_Timestamp& further_back);
+ static long ticks_since(Fl_Timestamp& then);
+ static long ticks_between(Fl_Timestamp& back, Fl_Timestamp& further_back);
+
// private
static void run_idle();
static void run_checks();
diff --git a/FL/platform_types.h b/FL/platform_types.h
index b55544d4c..421a0b7c6 100644
--- a/FL/platform_types.h
+++ b/FL/platform_types.h
@@ -12,6 +12,9 @@
* https://www.fltk.org/bugs.php
*/
+#ifndef Fl_Platform_Types_H
+#define Fl_Platform_Types_H
+
/** \file
Definitions of platform-dependent types.
The exact nature of these types varies with the platform.
@@ -62,6 +65,13 @@ typedef opaque FL_SOCKET; /**< socket or file descriptor */
*/
typedef struct opaque *GLContext;
+/**
+ Platform-specific point in time, used for delta time calculation.
+ \note This type may be a struct. sizeof(Fl_Timestamp) may be different on
+ different platforms. Fl_Timestamp may change with future ABI changes.
+ */
+typedef opaque Fl_Timestamp;
+
# define FL_COMMAND opaque /**< An alias for FL_CTRL on Windows and X11, or FL_META on MacOS X */
# define FL_CONTROL opaque /**< An alias for FL_META on Windows and X11, or FL_CTRL on MacOS X */
@@ -127,4 +137,15 @@ extern FL_EXPORT int fl_control_modifier();
#endif /* FL_PLATFORM_TYPES_H */
+// This is currently the same for all platforms, but may change in the future
+struct Fl_Timestamp_t {
+ long sec;
+ long usec;
+};
+
+typedef struct Fl_Timestamp_t Fl_Timestamp;
+
#endif /* FL_DOXYGEN */
+
+#endif /* Fl_Platform_Types_H */
+
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;