Skip to main content

gwr_engine/
lib.rs

1// Copyright (c) 2023 Graphcore Ltd. All rights reserved.
2
3// TODO: enable this warning to ensure all public interfaces are documented.
4// Enable warnings for missing documentation
5// #![warn(missing_docs)]
6
7#![doc(test(attr(deny(unused_must_use))))]
8#![doc = std::include_str!(concat!(env!("OUT_DIR"), "/crate-docs.md"))]
9
10pub mod engine;
11pub mod events;
12pub mod executor;
13#[cfg(feature = "global_allocator")]
14mod global_allocator;
15pub mod port;
16pub mod test_helpers;
17pub mod time;
18pub mod traits;
19pub mod types;
20
21/// Spawn all component run() functions and then run the simulation.
22#[macro_export]
23macro_rules! run_simulation {
24    ($engine:ident) => {
25        $engine.run().unwrap();
26    };
27    ($engine:ident, $expect:expr) => {
28        match $engine.run() {
29            Ok(()) => panic!("Expected an error!"),
30            Err(e) => assert_eq!(&format!("{e}"), $expect),
31        }
32    };
33}
34
35/// Spawn a sub-component that is stored in an `RefCell<Option<>>`
36///
37/// This removes the sub-component from the Option and then spawns the `run()`
38/// function.
39#[macro_export]
40macro_rules! spawn_subcomponent {
41    ($($spawner:ident).+ ; $($block:ident).+) => {
42        let sub_block = $($block).+.borrow_mut().take().unwrap();
43        $($spawner).+.spawn(async move { sub_block.run().await } );
44    };
45}
46
47#[cfg(test)]
48mod tests {
49    use std::cell::{Cell, RefCell};
50    use std::rc::Rc;
51
52    use async_trait::async_trait;
53    use gwr_track::tracker::dev_null_tracker;
54
55    use crate::engine::Engine;
56    use crate::traits::Runnable;
57    use crate::types::SimResult;
58
59    struct TestComponent {
60        ran: Rc<Cell<bool>>,
61    }
62
63    #[async_trait(?Send)]
64    impl Runnable for TestComponent {
65        async fn run(&self) -> SimResult {
66            self.ran.set(true);
67            Ok(())
68        }
69    }
70
71    #[test]
72    fn spawn_subcomponent_spawns_and_runs_component() {
73        let tracker = dev_null_tracker();
74        let mut engine = Engine::new(&tracker);
75        let spawner = engine.spawner();
76        let ran = Rc::new(Cell::new(false));
77        let component = RefCell::new(Some(TestComponent { ran: ran.clone() }));
78
79        spawn_subcomponent!(spawner; component);
80
81        engine.run().unwrap();
82
83        assert!(ran.get());
84        assert!(component.borrow().is_none());
85    }
86}