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 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
//! Calloop, a Callback-based Event Loop
//!
//! This crate provides an `EventLoop` type, which is a small abstraction
//! over an `mio`-based event loop. The main difference between this crate
//! and other traditional rust event loops is that it is based on callbacks:
//! you can register several event sources, each being associated with a callback
//! closure that will be invoked whenever the associated event source generates
//! events.
//!
//! This crate was initially an implementation detail of `wayland-server`, and has been
//! split-off for reuse. I expect it to be more useful for GUI programs or graphical
//! servers (like wayland-based apps) than performance critial networking code, which are
//! more versed towards `tokio` and async-await. It mostly shines in the conception of
//! modular infrastructures, allowing different modules to use the same event loop without
//! needing to know about each other.
//!
//! ## How to use it
//!
//! ```no_run
//! extern crate calloop;
//!
//! use std::time::Duration;
//!
//! fn main() {
//! // Create the event loop
//! let mut event_loop = calloop::EventLoop::new().expect("Failed to initialize the event loop!");
//! // Retrieve an handle. It is used to insert new sources into the event loop
//! // It can be cloned, allowing you to insert sources from within sources
//! let handle = event_loop.handle();
//!
//! /*
//! * Setup your program, inserting event sources in the loop
//! */
//!
//! // Actual run of your loop
//! loop {
//! // Dispatch received events to their callbacks, waiting at most 20 ms for
//! // new events
//! //
//! // The `&mut shared_data` is a mutable reference that will be forwarded to all
//! // your callbacks, allowing them to easily share some state
//! # let mut shared_data = unimplemented!();
//! event_loop.dispatch(Some(Duration::from_millis(20)), &mut shared_data);
//!
//! /*
//! * Insert here the processing you need to do do between each event loop run
//! * like your drawing logic if you're doing a GUI app for example.
//! */
//! }
//! }
//! ```
//!
//! ## Event source types
//!
//! The event loop is backed by `mio`, as such anything implementing the `mio::Evented` trait
//! can be used as an event source, with some adapter code (see the `EventSource` trait).
//!
//! This crate also provide some adapters for common event sources such as:
//!
//! - MPSC channels
//! - Timers
//! - unix signals
//!
//! As well as generic `mio::Evented` objects.
//!
//! It is also possible to insert "idle" callbacks. These callbacks represent computations that
//! need to be done at some point, but are not as urgent as processing the events. These callbacks
//! are stored and then executed during `EventLoop::dispatch(..)`, once all events from the sources
//! have been processed.
//!
//! ## Custom event sources
//!
//! You can create custom event sources can will be inserted in the event loop by
//! implementing the `EventSource` trait. This notably involves the creation of an
//! internal type implementing the `EventDispatcher` trait, that will convert
//! readiness notifications from `mio` into events generated by your sources. For example,
//! by reading the new messages from a display server socket and producing an event and
//! calling the user callback for each of them.
#![warn(missing_docs)]
pub extern crate mio;
extern crate mio_extras;
#[cfg(unix)]
extern crate nix;
pub use self::loop_logic::{EventLoop, InsertError, LoopHandle, LoopSignal};
pub use self::sources::*;
mod list;
mod loop_logic;
mod sources;