use core::marker::PhantomData;
use nodo::prelude::*;
pub struct ParameterGate<T>(PhantomData<T>);
#[derive(Config)]
pub struct ParameterGateConfig {
#[mutable]
pub is_open: bool,
}
#[derive(Status, Debug, Clone, Copy)]
pub enum ParameterGateStatus {
#[default]
#[skipped]
Unspecified,
#[skipped]
OpenIdle,
OpenBusy(usize),
#[skipped]
ClosedIdle,
ClosedBusy(usize),
}
impl<T> Default for ParameterGate<T> {
fn default() -> Self {
Self(PhantomData)
}
}
impl<T> Codelet for ParameterGate<T>
where
T: Send + Sync + Clone,
{
type Status = ParameterGateStatus;
type Config = ParameterGateConfig;
type Rx = DoubleBufferRx<T>;
type Tx = DoubleBufferTx<T>;
type Signals = ();
fn build_bundles(_config: &Self::Config) -> (Self::Rx, Self::Tx) {
(
DoubleBufferRx::new_auto_size(),
DoubleBufferTx::new_auto_size(),
)
}
fn step(
&mut self,
cx: Context<Self>,
rx: &mut Self::Rx,
tx: &mut Self::Tx,
) -> eyre::Result<ParameterGateStatus> {
let count = rx.len();
if cx.config.is_open {
if count == 0 {
Ok(ParameterGateStatus::OpenIdle)
} else {
tx.push_many(rx.drain(..))?;
Ok(ParameterGateStatus::OpenBusy(count))
}
} else {
if count == 0 {
Ok(ParameterGateStatus::ClosedIdle)
} else {
rx.clear();
Ok(ParameterGateStatus::ClosedBusy(count))
}
}
}
}