summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlbrecht Schlosser <albrechts.fltk@online.de>2022-10-20 19:36:03 +0200
committerAlbrecht Schlosser <albrechts.fltk@online.de>2022-10-20 19:36:03 +0200
commitda11526bb878e009b93fadd163d18d24e5ca203a (patch)
treee9690244cb6e8abf8b974876e573948f6f7079b0
parenteca61ab98abb588b3b964795595b41e9dd5e00dd (diff)
Improve and clarify documentation of timeout functions
Some functions didn't document the handling of arguments properly, particularly Fl::has_timeout() and Fl::remove_timeout(). This is now fixed by documenting the correct behavior that was preserved (re-implemented) from FLTK 1.3.x in the new class Fl_Timeout. Unfortunately there have been some inconsistencies (likely unexpected behavior) which have been preserved and which are now documented.
-rw-r--r--FL/Fl.H65
-rw-r--r--src/Fl.cxx128
-rw-r--r--src/Fl_Timeout.cxx63
-rw-r--r--src/Fl_Timeout.h22
4 files changed, 180 insertions, 98 deletions
diff --git a/FL/Fl.H b/FL/Fl.H
index b0f8e6007..fe4a9a746 100644
--- a/FL/Fl.H
+++ b/FL/Fl.H
@@ -90,7 +90,9 @@ typedef void (Fl_Label_Measure_F)(const Fl_Label *label, int &width, int &height
/** Signature of some box drawing functions passed as parameters */
typedef void (Fl_Box_Draw_F)(int x, int y, int w, int h, Fl_Color color);
-/** Signature of some timeout callback functions passed as parameters */
+/** Signature of timeout callback functions passed as parameters.
+ Please see Fl::add_timeout() for details.
+*/
typedef void (*Fl_Timeout_Handler)(void *data);
/** Signature of some wakeup callback functions passed as parameters */
@@ -451,63 +453,16 @@ public:
static void program_should_quit(int should_i) { program_should_quit_ = should_i; }
static Fl_Widget* readqueue();
- /**
- Adds a one-shot timeout callback. The function will be called by
- Fl::wait() at <i>t</i> seconds after this function is called.
- The optional void* argument is passed to the callback.
-
- You can have multiple timeout callbacks. To remove a timeout
- callback use Fl::remove_timeout().
-
- If you need more accurate, repeated timeouts, use Fl::repeat_timeout() to
- reschedule the subsequent timeouts.
-
- The following code will print "TICK" each second on
- stdout with a fair degree of accuracy:
- \code
-#include <stdio.h>
-#include <FL/Fl.H>
-#include <FL/Fl_Window.H>
-void callback(void*) {
- printf("TICK\n");
- Fl::repeat_timeout(1.0, callback); // retrigger timeout
-}
-int main() {
- Fl_Window win(100,100);
- win.show();
- Fl::add_timeout(1.0, callback); // set up first timeout
- return Fl::run();
-}
- \endcode
- */
- static void add_timeout(double t, Fl_Timeout_Handler,void* = 0); // platform dependent
- /**
- Repeats a timeout callback from the expiration of the
- previous timeout, allowing for more accurate timing.
+ //
+ // cross-platform timer support
+ //
- You may only call this method inside a timeout callback of the same timer
- or at least a closely related timer, otherwise the timing accuracy can't
- be improved and the behavior is undefined.
+ static void add_timeout(double t, Fl_Timeout_Handler cb, void *data = 0);
+ static void repeat_timeout(double t, Fl_Timeout_Handler cb, void *data = 0);
+ static int has_timeout(Fl_Timeout_Handler cb, void *data = 0);
+ static void remove_timeout(Fl_Timeout_Handler cb, void *data = 0);
- The following code will print "TICK" each second on
- stdout with a fair degree of accuracy:
-
- \code
- void callback(void*) {
- puts("TICK");
- Fl::repeat_timeout(1.0, callback);
- }
-
- int main() {
- Fl::add_timeout(1.0, callback);
- return Fl::run();
- }
- \endcode
- */
- static void repeat_timeout(double t, Fl_Timeout_Handler, void* = 0); // platform dependent
- static int has_timeout(Fl_Timeout_Handler, void* = 0);
- static void remove_timeout(Fl_Timeout_Handler, void* = 0);
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);
diff --git a/src/Fl.cxx b/src/Fl.cxx
index b7fe35157..29f3f5839 100644
--- a/src/Fl.cxx
+++ b/src/Fl.cxx
@@ -231,33 +231,129 @@ int Fl::event_inside(const Fl_Widget *o) /*const*/ {
}
//
-// cross-platform timer support
+// Cross-platform timer support
//
+// User (doxygen) documentation is in this file but the implementation
+// of all functions is in class Fl_Timeout in Fl_Timeout.cxx.
-void Fl::add_timeout(double time, Fl_Timeout_Handler cb, void *argp) {
- Fl_Timeout::add_timeout(time, cb, argp);
+/**
+ Adds a one-shot timeout callback.
+
+ The callback function \p cb will be called by Fl::wait() at \p time seconds
+ after this function is called.
+ The callback function must have the signature \ref Fl_Timeout_Handler.
+ The optional \p data argument is passed to the callback (default: NULL).
+
+ The timer is removed from the timer queue before the callback function is
+ called. It is safe to reschedule the timeout inside the callback function.
+
+ You can have multiple timeout callbacks, even the same timeout callback
+ with different timeout values and/or different \p data values. They are
+ all considered different timer objects.
+
+ To remove a timeout while it is active (pending) use Fl::remove_timeout().
+
+ If you need more accurate, repeated timeouts, use Fl::repeat_timeout() to
+ reschedule the subsequent timeouts. Please see Fl::repeat_timeout() for
+ an example.
+
+ \param[in] time delta time in seconds until the timer expires
+ \param[in] cb callback function
+ \param[in] data optional user data (default: \p NULL)
+
+ \see Fl_Timeout_Handler
+ \see Fl::repeat_timeout(double time, Fl_Timeout_Handler cb, void *data)
+ \see Fl::remove_timeout(Fl_Timeout_Handler cb, void *data)
+ \see Fl::has_timeout(Fl_Timeout_Handler cb, void *data)
+
+*/
+void Fl::add_timeout(double time, Fl_Timeout_Handler cb, void *data) {
+ Fl_Timeout::add_timeout(time, cb, data);
}
-void Fl::repeat_timeout(double time, Fl_Timeout_Handler cb, void *argp) {
- Fl_Timeout::repeat_timeout(time, cb, argp);
+/**
+ Repeats a timeout callback from the expiration of the previous timeout,
+ allowing for more accurate timing.
+
+ You should call this method only inside a timeout callback of the same or
+ a logically related timer from whose expiration time the new timeout shall
+ be scheduled. Otherwise the timing accuracy can't be improved and the
+ exact behavior is undefined.
+
+ If you call this outside a timeout callback the behavior is the same as
+ Fl::add_timeout().
+
+ Example: The following code will print "TICK" each second on stdout with
+ a fair degree of accuracy:
+
+ \code
+ #include <FL/Fl.H>
+ #include <FL/Fl_Window.H>
+ #include <stdio.h>
+
+ void callback(void *) {
+ printf("TICK\n");
+ Fl::repeat_timeout(1.0, callback); // retrigger timeout
+ }
+
+ int main() {
+ Fl_Window win(100, 100);
+ win.show();
+ Fl::add_timeout(1.0, callback); // set up first timeout
+ return Fl::run();
+ }
+ \endcode
+
+ \param[in] time delta time in seconds until the timer expires
+ \param[in] cb callback function
+ \param[in] data optional user data (default: \p NULL)
+*/
+void Fl::repeat_timeout(double time, Fl_Timeout_Handler cb, void *data) {
+ Fl_Timeout::repeat_timeout(time, cb, data);
}
/**
- Returns true if the timeout exists and has not been called yet.
- */
-int Fl::has_timeout(Fl_Timeout_Handler cb, void *argp) {
- return Fl_Timeout::has_timeout(cb, argp);
+ Returns true if the timeout exists and has not been called yet.
+
+ Both arguments \p cb and \p data must match with at least one timer
+ in the queue of active timers to return true (1).
+
+ \note It is a known inconsistency that Fl::has_timeout() does not use
+ the \p data argument as a wildcard (match all) if it is zero (NULL)
+ which Fl::remove_timeout() does.
+ This is so for backwards compatibility with FLTK 1.3.x.
+ Therefore using 0 (zero, NULL) as the timeout \p data value is discouraged
+ unless you're sure that you don't need to use
+ <kbd>Fl::has_timeout(callback, (void *)0);</kbd> or
+ <kbd>Fl::remove_timeout(callback, (void *)0);</kbd>.
+
+ \param[in] cb Timer callback
+ \param[in] data User data
+
+ \returns whether the timer was found in the queue
+ \retval 0 not found
+ \retval 1 found
+*/
+int Fl::has_timeout(Fl_Timeout_Handler cb, void *data) {
+ return Fl_Timeout::has_timeout(cb, data);
}
/**
- Removes a timeout callback. It is harmless to remove a timeout
- callback that no longer exists.
+ Removes a timeout callback from the timer queue.
- \note This version removes all matching timeouts, not just the first one.
- This may change in the future.
- */
-void Fl::remove_timeout(Fl_Timeout_Handler cb, void *argp) {
- Fl_Timeout::remove_timeout(cb, argp);
+ This method removes all matching timeouts, not just the first one.
+ This may change in the future.
+
+ If the \p data argument is \p NULL (the default!) only the callback
+ \p cb must match, i.e. all timer entries with this callback are removed.
+
+ It is harmless to remove a timeout callback that no longer exists.
+
+ \param[in] cb Timer callback to be removed (must match)
+ \param[in] data Wildcard if NULL (default), must match otherwise
+*/
+void Fl::remove_timeout(Fl_Timeout_Handler cb, void *data) {
+ Fl_Timeout::remove_timeout(cb, data);
}
diff --git a/src/Fl_Timeout.cxx b/src/Fl_Timeout.cxx
index d530a87df..f8ae8df94 100644
--- a/src/Fl_Timeout.cxx
+++ b/src/Fl_Timeout.cxx
@@ -112,29 +112,19 @@ void Fl_Timeout::insert() {
}
/**
- Returns whether the given timeout is active.
-
- This returns whether a timeout handler already exists in the queue
- of active timers.
-
- If \p data == NULL only the Fl_Timeout_Handler \p cb must match to return
- true, otherwise \p data must also match.
-
- \note It is a restriction that there is no way to look for a timeout whose
- \p data is NULL (zero). Therefore using 0 (zero, NULL) as the timeout
- \p data value is discouraged, unless you're sure that you will never
- need to use <kbd>Fl::has_timeout(callback, (void *)0);</kbd>.
-
- Implements Fl::has_timeout(Fl_Timeout_Handler cb, void *data)
+ Returns true if the timeout exists and has not been called yet.
\param[in] cb Timer callback (must match)
- \param[in] data Wildcard if NULL, must match otherwise
+ \param[in] data Callback user data (must match)
\returns whether the timer was found in the queue
\retval 0 not found
\retval 1 found
-*/
+ Implements Fl::has_timeout(Fl_Timeout_Handler cb, void *data)
+
+ \see Fl::has_timeout(Fl_Timeout_Handler cb, void *data)
+*/
int Fl_Timeout::has_timeout(Fl_Timeout_Handler cb, void *data) {
for (Fl_Timeout *t = first_timeout; t; t = t->next) {
if (t->callback == cb && t->data == data)
@@ -143,12 +133,39 @@ int Fl_Timeout::has_timeout(Fl_Timeout_Handler cb, void *data) {
return 0;
}
+/**
+ Adds a one-shot timeout callback.
+
+ The callback function \p cb will be called by Fl::wait() at \p time seconds
+ after this function is called.
+
+ \param[in] time delta time in seconds until the timer expires
+ \param[in] cb callback function
+ \param[in] data optional user data (default: \p NULL)
+
+ Implements Fl::add_timeout(double time, Fl_Timeout_Handler cb, void *data)
+
+ \see Fl::add_timeout(double time, Fl_Timeout_Handler cb, void *data)
+*/
void Fl_Timeout::add_timeout(double time, Fl_Timeout_Handler cb, void *data) {
elapse_timeouts();
Fl_Timeout *t = get(time, cb, data);
- t->Fl_Timeout::insert();
+ t->insert();
}
+/**
+ Repeats a timeout callback from the expiration of the previous timeout,
+ allowing for more accurate timing.
+
+ \param[in] time delta time in seconds until the timer expires
+ \param[in] cb callback function
+ \param[in] data optional user data (default: \p NULL)
+
+ Implements Fl::repeat_timeout(double time, Fl_Timeout_Handler cb, void *data)
+
+ \see Fl::repeat_timeout(double time, Fl_Timeout_Handler cb, void *data)
+*/
+
void Fl_Timeout::repeat_timeout(double time, Fl_Timeout_Handler cb, void *data) {
elapse_timeouts();
Fl_Timeout *t = (Fl_Timeout *)get(time, cb, data);
@@ -162,13 +179,17 @@ void Fl_Timeout::repeat_timeout(double time, Fl_Timeout_Handler cb, void *data)
}
/**
- Remove a timeout callback. It is harmless to remove a timeout
- callback that no longer exists.
+ Remove a timeout callback.
- \note This version removes all matching timeouts, not just the first one.
- This may change in the future.
+ This method removes all matching timeouts, not just the first one.
+ This may change in the future.
+
+ \param[in] cb Timer callback to be removed (must match)
+ \param[in] data Wildcard if NULL, must match otherwise
Implements Fl::remove_timeout(Fl_Timeout_Handler cb, void *data)
+
+ \see Fl::remove_timeout(Fl_Timeout_Handler cb, void *data)
*/
void Fl_Timeout::remove_timeout(Fl_Timeout_Handler cb, void *data) {
for (Fl_Timeout** p = &first_timeout; *p;) {
diff --git a/src/Fl_Timeout.h b/src/Fl_Timeout.h
index 8cff84689..f6a54a7a6 100644
--- a/src/Fl_Timeout.h
+++ b/src/Fl_Timeout.h
@@ -29,19 +29,27 @@
- Fl::add_timeout()
- Fl::repeat_timeout()
- - Fl::remove_timeout()
- Fl::has_timeout()
+ - Fl::remove_timeout()
and related methods of class Fl_Timeout.
*/
/**
- Class Fl_Timeout handles all timeout related functions.
+ The internal class Fl_Timeout handles all timeout related functions.
+
+ All code is platform independent except retrieving a timestamp which
+ requires calling a system driver function and potentially results in
+ different timer resolutions (from milliseconds to microseconds).
+
+ Related user documentation:
+
+ - \ref Fl_Timeout_Handler
+ - Fl::add_timeout(double time, Fl_Timeout_Handler cb, void *data)
+ - Fl::repeat_timeout(double time, Fl_Timeout_Handler cb, void *data)
+ - Fl::has_timeout(Fl_Timeout_Handler cb, void *data)
+ - Fl::remove_timeout(Fl_Timeout_Handler cb, void *data)
- All code is platform independent except retrieving a timestamp
- which requires calling a system driver function and potentially
- results in different timer resolutions (from milliseconds to
- microseconds).
*/
class Fl_Timeout {
@@ -62,8 +70,10 @@ protected:
skip = 0;
}
+ // destructor
~Fl_Timeout() {}
+ // get a new timer entry from the pool or allocate a new one
static Fl_Timeout *get(double time, Fl_Timeout_Handler cb, void *data);
// insert this timer into the active timer queue, sorted by expiration time