xdevs/simulator/
embassy.rs

1use crate::{
2    simulator::Config,
3    traits::{AsyncInput, Bag},
4};
5use core::time::Duration;
6use embassy_time::{Instant, Timer};
7
8/// A simple asynchronous input handler that sleeps until the next state transition of the model.
9#[derive(Default)]
10pub struct SleepAsync<T: Bag> {
11    /// The last recorded real time instant.
12    last_rt: Option<Instant>,
13    /// Phantom data to associate with the input bag type.
14    input: core::marker::PhantomData<T>,
15}
16
17impl<T: Bag> SleepAsync<T> {
18    /// Creates a new `SleepAsync` instance.
19    pub fn new() -> Self {
20        Self {
21            last_rt: None,
22            input: core::marker::PhantomData,
23        }
24    }
25}
26
27impl<T: Bag> AsyncInput for SleepAsync<T> {
28    type Input = T;
29
30    async fn handle(
31        &mut self,
32        config: &Config,
33        t_from: f64,
34        t_until: f64,
35        _input: &mut Self::Input,
36    ) -> f64 {
37        let last_rt = self.last_rt.unwrap_or_else(Instant::now);
38        let duration = Duration::from_secs_f64((t_until - t_from) * config.time_scale);
39        let next_rt = last_rt + duration.try_into().unwrap();
40        Timer::at(next_rt).await;
41        self.last_rt = Some(next_rt);
42        t_until
43    }
44}