2
2
// See the COPYRIGHT file at the top-level directory of this distribution.
3
3
// Licensed under the MIT license, see the LICENSE file or <http://opensource.org/licenses/MIT>
4
4
5
- //! GSourceFunc functions
5
+ //! Manages available sources of events for the main loop
6
6
7
7
use std:: cell:: RefCell ;
8
8
use std:: ops:: DerefMut ;
9
9
use std:: mem:: transmute;
10
10
use ffi:: { gboolean, gpointer, g_idle_add_full, g_timeout_add_full, g_timeout_add_seconds_full} ;
11
11
use translate:: ToGlib ;
12
12
13
+ /// Return type of idle and timeout functions.
14
+ ///
15
+ /// In the callback, return `Continue(true)` to continue scheduling the callback
16
+ /// in the main loop or `Continue(false)` to remove it from the main loop.
13
17
pub struct Continue ( pub bool ) ;
14
18
15
19
impl ToGlib for Continue {
@@ -37,30 +41,38 @@ extern "C" fn destroy_closure(ptr: gpointer) {
37
41
}
38
42
}
39
43
40
- const G_PRIORITY_DEFAULT : i32 = 0 ;
41
- const G_PRIORITY_DEFAULT_IDLE : i32 = 200 ;
44
+ const PRIORITY_DEFAULT : i32 = 0 ;
45
+ const PRIORITY_DEFAULT_IDLE : i32 = 200 ;
42
46
43
47
44
48
/// Adds a function to be called whenever there are no higher priority events pending to the default main loop.
45
- /// The function is given the default idle priority, G_PRIORITY_DEFAULT_IDLE.
46
- /// If the function returns FALSE it is automatically removed from
49
+ ///
50
+ /// The function is given the default idle priority, `PRIORITY_DEFAULT_IDLE`.
51
+ /// If the function returns `Continue(false)` it is automatically removed from
47
52
/// the list of event sources and will not be called again.
48
53
///
49
- /// This internally creates a main loop source using g_idle_source_new()
50
- /// and attaches it to the global GMainContext using g_source_attach(),
51
- /// so the callback will be invoked in whichever thread is running that main context.
52
- /// You can do these steps manually if you need greater control or to use a custom main context.
54
+ /// # Examples
55
+ ///
56
+ /// ```
57
+ /// let mut i = 0;
58
+ /// idle_add(move || {
59
+ /// println!("Idle: {}", i);
60
+ /// i += 1;
61
+ /// Continue(if i <= 10 { true } else { false })
62
+ /// });
63
+ /// ```
53
64
pub fn idle_add < F > ( func : F ) -> u32
54
65
where F : FnMut ( ) -> Continue + ' static {
55
66
let f: Box < RefCell < Box < FnMut ( ) -> Continue + ' static > > > = Box :: new ( RefCell :: new ( Box :: new ( func) ) ) ;
56
67
unsafe {
57
- g_idle_add_full ( G_PRIORITY_DEFAULT_IDLE , transmute ( trampoline) ,
68
+ g_idle_add_full ( PRIORITY_DEFAULT_IDLE , transmute ( trampoline) ,
58
69
into_raw ( f) as gpointer , destroy_closure)
59
70
}
60
71
}
61
72
62
- /// Sets a function to be called at regular intervals, with the default priority, G_PRIORITY_DEFAULT.
63
- /// The function is called repeatedly until it returns FALSE, at which point the timeout is
73
+ /// Sets a function to be called at regular intervals, with the default priority, `PRIORITY_DEFAULT`.
74
+ ///
75
+ /// The function is called repeatedly until it returns `Continue(false)`, at which point the timeout is
64
76
/// automatically destroyed and the function will not be called again. The first call to the
65
77
/// function will be at the end of the first interval .
66
78
///
@@ -70,41 +82,53 @@ pub fn idle_add<F>(func: F) -> u32
70
82
/// does not try to 'catch up' time lost in delays).
71
83
///
72
84
/// If you want to have a timer in the "seconds" range and do not care about the exact time of the
73
- /// first call of the timer, use the g_timeout_add_seconds() function; this function allows for more
85
+ /// first call of the timer, use the `timeout_add_seconds()` function; this function allows for more
74
86
/// optimizations and more efficient system power usage.
75
87
///
76
- /// This internally creates a main loop source using g_timeout_source_new() and attaches it to the
77
- /// global GMainContext using g_source_attach(), so the callback will be invoked in whichever thread
78
- /// is running that main context. You can do these steps manually if you need greater control or to
79
- /// use a custom main context.
88
+ /// The interval given is in terms of monotonic time, not wall clock time.
89
+ /// See `g_get_monotonic_time()` in glib documentation.
80
90
///
81
- /// The interval given is in terms of monotonic time, not wall clock time. See g_get_monotonic_time().
91
+ /// # Examples
92
+ ///
93
+ /// ```
94
+ /// timeout_add(3000, || {
95
+ /// println!("This prints once every 3 seconds");
96
+ /// Continue(true)
97
+ /// });
98
+ /// ```
82
99
pub fn timeout_add < F > ( interval : u32 , func : F ) -> u32
83
100
where F : FnMut ( ) -> Continue + ' static {
84
101
let f: Box < RefCell < Box < FnMut ( ) -> Continue + ' static > > > = Box :: new ( RefCell :: new ( Box :: new ( func) ) ) ;
85
102
unsafe {
86
- g_timeout_add_full ( G_PRIORITY_DEFAULT , interval, transmute ( trampoline) ,
103
+ g_timeout_add_full ( PRIORITY_DEFAULT , interval, transmute ( trampoline) ,
87
104
into_raw ( f) as gpointer , destroy_closure)
88
105
}
89
106
}
90
107
91
- /// Sets a function to be called at regular intervals with the default priority, G_PRIORITY_DEFAULT.
92
- /// The function is called repeatedly until it returns FALSE, at which point the timeout is automatically
93
- /// destroyed and the function will not be called again.
108
+ /// Sets a function to be called at regular intervals with the default priority, `PRIORITY_DEFAULT`.
94
109
///
95
- /// This internally creates a main loop source using g_timeout_source_new_seconds() and attaches it to
96
- /// the main loop context using g_source_attach(). You can do these steps manually if you need greater
97
- /// control. Also see g_timeout_add_seconds_full().
110
+ /// The function is called repeatedly until it returns `Continue(false)`, at which point the timeout
111
+ /// is automatically destroyed and the function will not be called again.
98
112
///
99
113
/// Note that the first call of the timer may not be precise for timeouts of one second. If you need
100
- /// finer precision and have such a timeout, you may want to use g_timeout_add() instead.
114
+ /// finer precision and have such a timeout, you may want to use `timeout_add()` instead.
115
+ ///
116
+ /// The interval given is in terms of monotonic time, not wall clock time.
117
+ /// See `g_get_monotonic_time()` in glib documentation.
118
+ ///
119
+ /// # Examples
101
120
///
102
- /// The interval given is in terms of monotonic time, not wall clock time. See g_get_monotonic_time().
121
+ /// ```
122
+ /// timeout_add_seconds(10, || {
123
+ /// println!("This prints once every 10 seconds");
124
+ /// Continue(true)
125
+ /// });
126
+ /// ```
103
127
pub fn timeout_add_seconds < F > ( interval : u32 , func : F ) -> u32
104
128
where F : FnMut ( ) -> Continue + ' static {
105
129
let f: Box < RefCell < Box < FnMut ( ) -> Continue + ' static > > > = Box :: new ( RefCell :: new ( Box :: new ( func) ) ) ;
106
130
unsafe {
107
- g_timeout_add_seconds_full ( G_PRIORITY_DEFAULT , interval, transmute ( trampoline) ,
131
+ g_timeout_add_seconds_full ( PRIORITY_DEFAULT , interval, transmute ( trampoline) ,
108
132
into_raw ( f) as gpointer , destroy_closure)
109
133
}
110
134
}
0 commit comments