1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
use calloop::{
timer::{TimeoutAction, Timer},
EventLoop, LoopSignal,
};
fn main() {
// Create the event loop. The loop is parameterised by the kind of shared
// data you want the callbacks to use. In this case, we want to be able to
// stop the loop when the timer fires, so we provide the loop with a
// LoopSignal, which has the ability to stop the loop from within events. We
// just annotate the type here; the actual data is provided later in the
// run() call.
let mut event_loop: EventLoop<LoopSignal> =
EventLoop::try_new().expect("Failed to initialize the event loop!");
// Retrieve a handle. It is used to insert new sources into the event loop
// It can be cloned, allowing you to insert sources from within source
// callbacks.
let handle = event_loop.handle();
// Create our event source, a timer, that will expire in 2 seconds
let source = Timer::from_duration(std::time::Duration::from_secs(2));
// Inserting an event source takes this general form. It can also be done
// from within the callback of another event source.
handle
.insert_source(
// a type which implements the EventSource trait
source,
// a callback that is invoked whenever this source generates an event
|event, _metadata, shared_data| {
// This callback is given 3 values:
// - the event generated by the source (in our case, timer events are the Instant
// representing the deadline for which it has fired)
// - &mut access to some metadata, specific to the event source (in our case, a
// timer handle)
// - &mut access to the global shared data that was passed to EventLoop::run or
// EventLoop::dispatch (in our case, a LoopSignal object to stop the loop)
//
// The return type is just () because nothing uses it. Some
// sources will expect a Result of some kind instead.
println!("Timeout for {:?} expired!", event);
// notify the event loop to stop running using the signal in the shared data
// (see below)
shared_data.stop();
// The timer event source requires us to return a TimeoutAction to
// specify if the timer should be rescheduled. In our case we just drop it.
TimeoutAction::Drop
},
)
.expect("Failed to insert event source!");
// Create the shared data for our loop.
let mut shared_data = event_loop.get_signal();
// Actually run the event loop. This will dispatch received events to their
// callbacks, waiting at most 20ms for new events between each invocation of
// the provided callback (pass None for the timeout argument if you want to
// wait indefinitely between events).
//
// This is where we pass the *value* of the shared data, as a mutable
// reference that will be forwarded to all your callbacks, allowing them to
// share some state
event_loop
.run(
std::time::Duration::from_millis(20),
&mut shared_data,
|_shared_data| {
// Finally, this is where you can insert the processing you need
// to do do between each waiting event eg. drawing logic if
// you're doing a GUI app.
},
)
.expect("Error during event loop!");
}