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