mirror of
https://github.com/fltk/fltk.git
synced 2026-05-27 02:46:34 +08:00
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.
This commit is contained in:
@@ -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 */
|
/** 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);
|
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);
|
typedef void (*Fl_Timeout_Handler)(void *data);
|
||||||
|
|
||||||
/** Signature of some wakeup callback functions passed as parameters */
|
/** 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 void program_should_quit(int should_i) { program_should_quit_ = should_i; }
|
||||||
|
|
||||||
static Fl_Widget* readqueue();
|
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().
|
// cross-platform timer support
|
||||||
|
//
|
||||||
|
|
||||||
If you need more accurate, repeated timeouts, use Fl::repeat_timeout() to
|
static void add_timeout(double t, Fl_Timeout_Handler cb, void *data = 0);
|
||||||
reschedule the subsequent timeouts.
|
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
|
|
||||||
#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.
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
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 void add_check(Fl_Timeout_Handler, void* = 0);
|
||||||
static int has_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 void remove_check(Fl_Timeout_Handler, void* = 0);
|
||||||
|
|||||||
+113
-17
@@ -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.
|
||||||
}
|
|
||||||
|
|
||||||
void Fl::repeat_timeout(double time, Fl_Timeout_Handler cb, void *argp) {
|
The callback function \p cb will be called by Fl::wait() at \p time seconds
|
||||||
Fl_Timeout::repeat_timeout(time, cb, argp);
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Returns true if the timeout exists and has not been called yet.
|
Repeats a timeout callback from the expiration of the previous timeout,
|
||||||
*/
|
allowing for more accurate timing.
|
||||||
int Fl::has_timeout(Fl_Timeout_Handler cb, void *argp) {
|
|
||||||
return Fl_Timeout::has_timeout(cb, argp);
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Removes a timeout callback. It is harmless to remove a timeout
|
Returns true if the timeout exists and has not been called yet.
|
||||||
callback that no longer exists.
|
|
||||||
|
|
||||||
\note This version removes all matching timeouts, not just the first one.
|
Both arguments \p cb and \p data must match with at least one timer
|
||||||
This may change in the future.
|
in the queue of active timers to return true (1).
|
||||||
*/
|
|
||||||
void Fl::remove_timeout(Fl_Timeout_Handler cb, void *argp) {
|
\note It is a known inconsistency that Fl::has_timeout() does not use
|
||||||
Fl_Timeout::remove_timeout(cb, argp);
|
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 from the timer queue.
|
||||||
|
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+42
-21
@@ -112,29 +112,19 @@ void Fl_Timeout::insert() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Returns whether the given timeout is active.
|
Returns true if the timeout exists and has not been called yet.
|
||||||
|
|
||||||
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)
|
|
||||||
|
|
||||||
\param[in] cb Timer callback (must match)
|
\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
|
\returns whether the timer was found in the queue
|
||||||
\retval 0 not found
|
\retval 0 not found
|
||||||
\retval 1 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) {
|
int Fl_Timeout::has_timeout(Fl_Timeout_Handler cb, void *data) {
|
||||||
for (Fl_Timeout *t = first_timeout; t; t = t->next) {
|
for (Fl_Timeout *t = first_timeout; t; t = t->next) {
|
||||||
if (t->callback == cb && t->data == data)
|
if (t->callback == cb && t->data == data)
|
||||||
@@ -143,12 +133,39 @@ int Fl_Timeout::has_timeout(Fl_Timeout_Handler cb, void *data) {
|
|||||||
return 0;
|
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) {
|
void Fl_Timeout::add_timeout(double time, Fl_Timeout_Handler cb, void *data) {
|
||||||
elapse_timeouts();
|
elapse_timeouts();
|
||||||
Fl_Timeout *t = get(time, cb, data);
|
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) {
|
void Fl_Timeout::repeat_timeout(double time, Fl_Timeout_Handler cb, void *data) {
|
||||||
elapse_timeouts();
|
elapse_timeouts();
|
||||||
Fl_Timeout *t = (Fl_Timeout *)get(time, cb, data);
|
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
|
Remove a timeout callback.
|
||||||
callback that no longer exists.
|
|
||||||
|
|
||||||
\note This version removes all matching timeouts, not just the first one.
|
This method removes all matching timeouts, not just the first one.
|
||||||
This may change in the future.
|
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)
|
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) {
|
void Fl_Timeout::remove_timeout(Fl_Timeout_Handler cb, void *data) {
|
||||||
for (Fl_Timeout** p = &first_timeout; *p;) {
|
for (Fl_Timeout** p = &first_timeout; *p;) {
|
||||||
|
|||||||
+16
-6
@@ -29,19 +29,27 @@
|
|||||||
|
|
||||||
- Fl::add_timeout()
|
- Fl::add_timeout()
|
||||||
- Fl::repeat_timeout()
|
- Fl::repeat_timeout()
|
||||||
- Fl::remove_timeout()
|
|
||||||
- Fl::has_timeout()
|
- Fl::has_timeout()
|
||||||
|
- Fl::remove_timeout()
|
||||||
|
|
||||||
and related methods of class Fl_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 {
|
class Fl_Timeout {
|
||||||
|
|
||||||
@@ -62,8 +70,10 @@ protected:
|
|||||||
skip = 0;
|
skip = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// destructor
|
||||||
~Fl_Timeout() {}
|
~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);
|
static Fl_Timeout *get(double time, Fl_Timeout_Handler cb, void *data);
|
||||||
|
|
||||||
// insert this timer into the active timer queue, sorted by expiration time
|
// insert this timer into the active timer queue, sorted by expiration time
|
||||||
|
|||||||
Reference in New Issue
Block a user