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!");
}
|