Skip to main content

embassy_supervisor/
dataflow.rs

1use crate::{Coupling, TaskNode};
2
3#[cfg(feature = "macros")]
4pub use embassy_supervisor_macros::dataflow;
5
6#[cfg(feature = "macros")]
7pub use embassy_supervisor_macros::dataflow_bundle;
8
9pub use embassy_supervisor_observe::{Sink, Source};
10
11#[derive(Clone, Copy)]
12/// A typed handle to a signal declared in a `reads:`/`writes:` list.
13pub struct Sig<T: ?Sized + 'static> {
14    /// The call site's entry: path text plus the type-erased identity.
15    pub entry: &'static Coupling,
16    /// The signal, concretely typed.
17    pub target: &'static T,
18}
19
20impl TaskNode {
21    /// Write `v` into the signal `s`.
22    pub fn put<T: Sink + Sync>(&self, s: Sig<T>, v: T::Item) {
23        s.target.put(v);
24    }
25
26    #[cfg(feature = "liveness")]
27    /// Write `v` into `s` and record a heartbeat.
28    pub fn beat_put<T: Sink + Sync>(&self, s: Sig<T>, v: T::Item) {
29        self.beat();
30        s.target.put(v);
31    }
32
33    /// Read and return a snapshot of the signal `s`.
34    pub fn get<T: Source + Sync>(&self, s: Sig<T>) -> T::Item {
35        s.target.get()
36    }
37
38    /// Borrow the signal target for a direct write, bypassing the [`Sink`] trait.
39    pub fn writer<T: Sync + ?Sized>(&self, s: Sig<T>) -> &'static T {
40        s.target
41    }
42
43    /// [`writer`](Self::writer) that is also the node's sign of life — the
44    #[cfg(feature = "liveness")]
45    pub fn beat_writer<T: Sync + ?Sized>(&self, s: Sig<T>) -> &'static T {
46        self.beat();
47        s.target
48    }
49
50    /// Hand the signal back for a read — the wiring point for consuming reads,
51    /// which need per-consumer handle state no shared static can carry:
52    /// `node.reader(&ESTIMATE).receiver()`. A pass-through, like
53    /// [`get`](Self::get).
54    pub fn reader<T: Sync + ?Sized>(&self, s: Sig<T>) -> &'static T {
55        s.target
56    }
57}