dope_runtime/executor/raw/
dispatch.rs1use std::{mem, ops, pin};
2
3use dope_core::{
4 driver::{retained, route::Route, schedule},
5 io,
6};
7
8use crate::executor;
9
10#[must_use]
12pub struct Dispatch<'app, 'driver, 'turn, 'root, 'd: 'root, R> {
13 app: pin::Pin<&'app mut R>,
14 drive: executor::raw::Drive<'driver, 'turn, 'root, 'd>,
15 event: io::Event<'d>,
16}
17
18impl<'app, 'driver, 'turn, 'root, 'd: 'root, R> Dispatch<'app, 'driver, 'turn, 'root, 'd, R> {
19 pub const fn new(
21 app: pin::Pin<&'app mut R>,
22 event: io::Event<'d>,
23 turn: schedule::Turn<'turn, 'd>,
24 driver: retained::Context<'driver, 'root, 'd>,
25 ) -> Self {
26 Self {
27 app,
28 drive: executor::raw::Drive::new(turn, driver),
29 event,
30 }
31 }
32
33 pub fn route(&self) -> Route {
34 self.event.route()
35 }
36
37 pub fn map(
38 mut self,
39 map: impl FnOnce(
40 pin::Pin<&mut R>,
41 io::Event<'d>,
42 schedule::Turn<'_, 'd>,
43 retained::Context<'_, 'root, 'd>,
44 ) -> ops::ControlFlow<io::Event<'d>>,
45 ) -> ops::ControlFlow<Self> {
46 let (turn, driver) = self.drive.reborrow().into_parts();
47 match map(self.app.as_mut(), self.event, turn, driver) {
48 ops::ControlFlow::Continue(()) => ops::ControlFlow::Continue(()),
49 ops::ControlFlow::Break(event) => {
50 self.event = event;
51 ops::ControlFlow::Break(self)
52 }
53 }
54 }
55
56 pub fn into_event(self) -> io::Event<'d> {
57 self.event
58 }
59
60 pub fn into_parts(self) -> (pin::Pin<&'app mut R>, io::Event<'d>) {
61 (self.app, self.event)
62 }
63}
64
65const fn assert_layout() {
66 type Call<'a> = Dispatch<'a, 'a, 'a, 'a, 'a, ()>;
67 type Drive<'a> = executor::raw::Drive<'a, 'a, 'a, 'a>;
68
69 assert!(
70 mem::size_of::<Call<'static>>()
71 == mem::size_of::<Drive<'static>>()
72 + mem::size_of::<io::Event<'static>>()
73 + mem::size_of::<pin::Pin<&'static mut ()>>()
74 );
75 assert!(mem::align_of::<Call<'static>>() == mem::align_of::<usize>());
76}
77
78const _: () = assert_layout();