gwr_engine/events/mod.rs
1// Copyright (c) 2023 Graphcore Ltd. All rights reserved.
2
3//! Different types of events.
4//!
5//! Events should be used to coordinate between
6//! [spawned](crate::executor::Spawner) tasks so that they can run in an
7//! event-driven manner and yield until there is something ready to process.
8//!
9//! [Basic events](crate::events::once) are created to be triggered once using
10//! `notify()` method. Any number of other tasks can be waiting for the event
11//! to be triggered. The `listen()` method is used to wait for the event to be
12//! triggered.
13//!
14//! The engine provides a small set of event types that cover the common
15//! coordination patterns used by components and models:
16//!
17//! - [`Once`](crate::events::once::Once): fires exactly once and wakes every
18//! listener with a fixed result value. This is useful for completion,
19//! timeout, and one-off handshakes.
20//! - [`Repeated`](crate::events::repeated::Repeated): can fire many times and
21//! wakes listeners waiting for the next generation. This is useful for state
22//! changes, monitor updates, and reusable notifications.
23//! - [`AnyOf`](crate::events::any_of::AnyOf): combines several events and wakes
24//! when the first one fires, returning that event's result. This is useful
25//! for races such as response-or-timeout waits.
26//! - [`AllOf`](crate::events::all_of::AllOf): combines several events and wakes
27//! once they have all fired. This is useful for joining setup, drain, or
28//! completion conditions.
29//!
30//! # Example:
31//!
32//! An event being created to co-ordinate between two tasks.
33//!
34//! ```rust
35//! # use gwr_engine::engine::Engine;
36//! # use gwr_engine::events::once::Once;
37//! # use gwr_engine::run_simulation;
38//! # use gwr_engine::traits::Event;
39//! #
40//! fn spawn_listen<T>(engine: &mut Engine, event: Once<T>)
41//! where
42//! T: Copy + 'static,
43//! {
44//! engine.spawn(async move {
45//! event.listen().await;
46//! println!("After event");
47//! Ok(())
48//! });
49//! }
50//!
51//! fn spawn_notify<T>(engine: &mut Engine, event: Once<T>)
52//! where
53//! T: Copy + 'static,
54//! {
55//! let clock = engine.default_clock();
56//! engine.spawn(async move {
57//! clock.wait_ticks(10).await;
58//! println!("Trigger event");
59//! event.notify()?;
60//! Ok(())
61//! });
62//! }
63//!
64//! fn main() {
65//! let mut engine = Engine::default();
66//! let event = Once::default();
67//! spawn_listen(&mut engine, event.clone());
68//! spawn_notify(&mut engine, event);
69//! run_simulation!(engine);
70//! # assert_eq!(engine.time_now_ns(), 10.0);
71//! }
72//! ```
73
74pub mod all_of;
75pub mod any_of;
76pub mod once;
77pub mod repeated;
78mod waiting;