Skip to main content

dope_runtime/executor/raw/
activate.rs

1use std::{mem, pin};
2
3use dope_core::driver::{
4    retained,
5    route::{self, kind},
6    schedule,
7};
8
9use crate::executor;
10
11/// Route activation authority for one exact retained root and scheduler turn.
12#[must_use]
13pub struct Activate<'driver, 'turn, 'root, 'd: 'root> {
14    drive: executor::raw::Drive<'driver, 'turn, 'root, 'd>,
15    target: route::Erased<'d, kind::Any>,
16}
17
18impl<'driver, 'turn, 'root, 'd: 'root> Activate<'driver, 'turn, 'root, 'd> {
19    pub(crate) const fn new(
20        target: route::Erased<'d, kind::Any>,
21        turn: schedule::Turn<'turn, 'd>,
22        driver: retained::Context<'driver, 'root, 'd>,
23    ) -> Self {
24        Self {
25            drive: executor::raw::Drive { turn, driver },
26            target,
27        }
28    }
29
30    pub const fn target(&self) -> route::Erased<'d, kind::Any> {
31        self.target
32    }
33
34    pub fn reborrow(&mut self) -> Activate<'_, '_, 'root, 'd> {
35        Activate {
36            drive: self.drive.reborrow(),
37            target: self.target,
38        }
39    }
40
41    pub(crate) fn wake<R>(self, app: pin::Pin<&mut R>)
42    where
43        R: executor::raw::App<'d>,
44    {
45        if !R::WAKE_ROUTES.has_route(self.target.route()) {
46            return;
47        }
48        // SAFETY: the session view admits only a target declared by the
49        // activation route set and supplies its exact installed pinned root.
50        unsafe { R::activate(app, self) };
51    }
52
53    pub fn into_driver(
54        self,
55    ) -> (
56        route::Erased<'d, kind::Any>,
57        retained::Context<'driver, 'root, 'd>,
58    ) {
59        (self.target, self.drive.driver)
60    }
61
62    pub fn map<R>(
63        self,
64        map: impl FnOnce(
65            route::Erased<'d, kind::Any>,
66            schedule::Turn<'turn, 'd>,
67            retained::Context<'driver, 'root, 'd>,
68        ) -> R,
69    ) -> R {
70        let executor::raw::Drive { turn, driver } = self.drive;
71        map(self.target, turn, driver)
72    }
73}
74
75const _: () = {
76    assert!(
77        mem::size_of::<Activate<'static, 'static, 'static, 'static>>()
78            == mem::size_of::<executor::raw::Drive<'static, 'static, 'static, 'static>>()
79                + mem::size_of::<route::Erased<'static, kind::Any>>()
80    );
81    assert!(
82        mem::align_of::<Activate<'static, 'static, 'static, 'static>>() == mem::align_of::<usize>()
83    );
84};