fltk/src/Fl_Timeout.h
Albrecht Schlosser 456d53c403
Add Fl::remove_next_timeout(...) to remove only one timeout (#992)
This method also returns the data pointer of the removed timeout.

This new method is generally useful for user code and particularly
necessary to fix issue #991.

Co-authored-by: Albrecht Schlosser <albrechts.fltk@online.de>
2024-06-21 17:35:01 +02:00

170 lines
5.0 KiB
C++

//
// Header for timeout support functions for the Fast Light Tool Kit (FLTK).
//
// Author: Albrecht Schlosser
// Copyright 2021-2024 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
// file is missing or damaged, see the license at:
//
// https://www.fltk.org/COPYING.php
//
// Please see the following page on how to report bugs and issues:
//
// https://www.fltk.org/bugs.php
//
#ifndef _src_Fl_Timeout_h_
#define _src_Fl_Timeout_h_
#include <FL/Fl.H>
#define FL_TIMEOUT_DEBUG 0 // 1 = include debugging features, 0 = no
/** \file
Fl_Timeout handling.
This file contains implementations of:
- Fl::add_timeout()
- Fl::repeat_timeout()
- Fl::has_timeout()
- Fl::remove_timeout()
- Fl::remove_next_timeout()
and related methods of class Fl_Timeout.
*/
/**
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)
- Fl::remove_next_timeout(Fl_Timeout_Handler cb, void *data, void **data_return)
*/
class Fl_Timeout {
protected:
Fl_Timeout *next; // ** Link to next timeout
Fl_Timeout_Handler callback; // the user's callback
void *data; // the user's callback data
double time; // delay until timeout
int skip; // skip "new" (inserted) timers (issue #450)
// constructor
Fl_Timeout() {
next = 0;
callback = 0;
data = 0;
time = 0;
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
void insert();
// remove this timer from the active timer queue and
// add it to the "current" timer stack
void make_current();
// remove this timer from the current timer stack and
// add it to the list of free timers
void release();
/** Get the timer's delay in seconds. */
double delay() {
return time;
}
/** Set the timer's delay in seconds. */
void delay(double t) {
time = t;
}
public:
// Returns whether the given timeout is active.
static int has_timeout(Fl_Timeout_Handler cb, void *data);
// Add or remove timeouts
static void add_timeout(double time, Fl_Timeout_Handler cb, void *data);
static void repeat_timeout(double time, Fl_Timeout_Handler cb, void *data);
static void remove_timeout(Fl_Timeout_Handler cb, void *data);
static int remove_next_timeout(Fl_Timeout_Handler cb, void *data = NULL, void **data_return = NULL);
// Elapse timeouts, i.e. calculate new delay time of all timers.
// This does not call the timer callbacks.
static void elapse_timeouts();
// Elapse timeouts and call timer callbacks.
static void do_timeouts();
// Return the delay in seconds until the next timer expires.
static double time_to_wait(double ttw);
#if FL_TIMEOUT_DEBUG
// Write some statistics to stdout
static void debug(int level = 1);
#endif
protected:
static Fl_Timeout *current();
/**
List of active timeouts.
These timeouts can be triggered when due, which calls their callbacks.
The lifetime of a timeout:
- active, in this queue
- callback running, in queue \p current_timeout
- done, in list of free timeouts, ready to be reused.
*/
static Fl_Timeout *first_timeout;
/**
List of free timeouts after use.
Timeouts can be reused many times.
*/
static Fl_Timeout *free_timeout;
/**
The list of current timeouts is used to store the timeout whose callback
is called while the callback is executed. This is used like a stack, the
current timeout is pushed to the front of the list and once the callback
is finished, that timeout is removed and entered into the free list.
Background: Fl::repeat_timeout() needs to know which timeout triggered it
and the exact schedule time and/or the delay of that timeout, i.e. how
long the scheduled time was missed before the callback was called.
A static, global variable is not sufficient since the user code can call
other functions, e.g. dialogs, that run a nested event loop which can
run another timeout callback. Hence this list of "current" timeouts is
used like a stack (last in, first out).
\see Fl_Timeout::push() Member function (method)
*/
static Fl_Timeout *current_timeout; // list of "current" timeouts
}; // class Fl_Timeout
#endif // _src_Fl_Timeout_h_