1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
//! Generator
use super::*;
use crate::prelude::*;
impl<const D: Dep, P: Copy, R: Copy> I<ValidH<P, R>, D> {
/// Generator.
///
/// TODO: Documentation
pub fn generator<EP: Copy, S: Copy>(
self,
init: S,
f_write_state: impl Fn(P, R, S) -> S,
f_read_state: impl Fn(S) -> HOption<EP>,
) -> I<ValidH<EP, R>, { Dep::Helpful }> {
unsafe {
self.fsm::<_, { Dep::Helpful }, ValidH<EP, R>>(init, |ip, er, s| {
let ep = f_read_state(s);
let s_next = match ip {
Some(ip) => f_write_state(ip, er, s),
_ => s,
};
(ep, er, s_next)
})
}
}
}
impl<const D: Dep, P: Copy, R: Copy> I<VrH<P, R>, D> {
/// Generator.
///
/// # Input
/// - `init`: Initial state.
/// - `f_write_state`: Write state function. This will set the state when ingress ingress_transfer happens.
/// - `f_read_state`: Read state function. This will read the state and trigger egress transfer
/// when egess ready is `true` and the function returns `Some`. Also, the boolean value
/// returned by this function will work as the ready signal for the ingress transfer(i.e.,
/// backpressure).
pub fn generator<EP: Copy, S: Copy>(
self,
init: S,
f_write_state: impl Fn(P, R, S) -> S,
f_read_state: impl Fn(S) -> (HOption<EP>, bool),
) -> I<VrH<EP, R>, { Dep::Helpful }> {
unsafe {
self.fsm::<_, { Dep::Helpful }, VrH<EP, R>>(init, |ip, er, s| {
let (ep, ready) = f_read_state(s);
let s_next = match ip {
Some(ip) if ready => f_write_state(ip, er.inner, s),
_ => s,
};
let ir = Ready::new(ready, er.inner);
(ep, ir, s_next)
})
}
}
}