prns_runtime_embassy/manifold/driver/
host.rs1use embassy_time::{Duration, Timer};
2
3use crate::engine::InstantMillis;
4use crate::manifold::timebase::EmbassyTimebase;
5use crate::manifold::Host;
6
7pub 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}