Skip to main content

dope_runtime/executor/raw/
dispatch.rs

1use std::{mem, ops, pin};
2
3use dope_core::{
4    driver::{retained, route::Route, schedule},
5    io,
6};
7
8use crate::executor;
9
10/// Event dispatch authority for one exact retained root and scheduler turn.
11#[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    /// Binds one event to its exact pinned root and retained driver authority.
20    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 { 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 executor::raw::Drive { turn, driver } = self.drive.reborrow();
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();