Skip to main content

prns_runtime_embassy/manifold/driver/
host.rs

1use embassy_time::{Duration, Timer};
2
3use crate::engine::InstantMillis;
4use crate::manifold::timebase::EmbassyTimebase;
5use crate::manifold::Host;
6
7/// Embassy clock and caller-supplied entropy source.
8pub struct EmbassyHost<E> {
9    timebase: EmbassyTimebase,
10    draw_entropy: E,
11}
12
13pub trait ResumableHost: Host {
14    fn resume_at(&mut self, logical_start: InstantMillis);
15}
16
17impl<E> EmbassyHost<E>
18where
19    E: FnMut(&mut [u8]),
20{
21    pub fn new(draw_entropy: E) -> Self {
22        Self::new_with_timebase(EmbassyTimebase::capture_now(), draw_entropy)
23    }
24
25    pub fn new_with_timebase(timebase: EmbassyTimebase, draw_entropy: E) -> Self {
26        Self {
27            timebase,
28            draw_entropy,
29        }
30    }
31}
32
33impl<E> Host for EmbassyHost<E>
34where
35    E: FnMut(&mut [u8]),
36{
37    fn now(&self) -> InstantMillis {
38        self.timebase.now()
39    }
40
41    async fn sleep_until(&self, deadline: InstantMillis) {
42        let remaining = deadline.0.saturating_sub(self.timebase.now().0);
43        Timer::after(Duration::from_millis(remaining)).await;
44    }
45
46    fn fill_entropy(&mut self, bytes: &mut [u8]) {
47        (self.draw_entropy)(bytes);
48    }
49}
50
51impl<E> ResumableHost for EmbassyHost<E>
52where
53    E: FnMut(&mut [u8]),
54{
55    fn resume_at(&mut self, logical_start: InstantMillis) {
56        self.timebase = EmbassyTimebase::start_at(logical_start);
57    }
58}