Skip to main content

SignalEngine

Struct SignalEngine 

Source
pub struct SignalEngine<T: Transcendental, const BUF_SIZE: usize> { /* private fields */ }
Expand description

Real-time safe signal engine for a static signal graph.

Owns the mutable node state and provides:

  1. Clock boundaryprocess_tick: drains commands (with anti-ack) and runs pre_process (feedback mix).
  2. Block processingprocess_block: iterates nodes in topological order: for each node, calls process_block, then snapshot_feedback, then propagate to downstream nodes via pre-established port connections.
  3. Thread managementstart/stop manage a cooperative running flag; spawn consumes the engine and runs it in a dedicated signal thread.

A separate control thread communicates via command/telemetry queues.

§Type Parameters

  • T — floating-point type (f32 or f64)
  • BUF_SIZE — block size (must match the graph)

Implementations§

Source§

impl<T: Transcendental, const BUF_SIZE: usize> SignalEngine<T, BUF_SIZE>

Source

pub fn new( nodes: Vec<NodeVariant<T, BUF_SIZE>>, topo_order: Vec<usize>, cmd_rx: Option<Receiver<CommandEnum>>, tel_tx: Option<Sender<Telemetry>>, ) -> Self

Create a new engine from graph parts.

Source

pub fn process_tick(&mut self, tick: &ClockTick) -> usize

Process a clock tick — called from the I/O callback when hardware fires.

Drains pending commands (with anti-ack telemetry on overwrite), then runs pre_process on all input ports (mixes feedback from previous block), then applies any pending SetParameter commands to their target nodes.

Returns the number of commands applied this tick.

Source

pub fn process_block(&mut self, tick: &ClockTick) -> ProcessResult<usize>

Convenience: run a full processing cycle for one block.

Calls process_tick, then iterates nodes in topological order: process → snapshot_feedback → propagate for each node. This ensures data flows naturally: Source → propagate → Processor → Sink.

Note: copies port buffers to build input slices for ProcessContext. Production I/O callbacks should call process_tick and handle data propagation themselves for zero-copy processing.

Source

pub fn nodes(&self) -> &[NodeVariant<T, BUF_SIZE>]

Access nodes for external processing (I/O layer). The caller should iterate in topo_order.

Source

pub fn nodes_mut(&mut self) -> &mut [NodeVariant<T, BUF_SIZE>]

Mutable access to nodes for external processing.

Source

pub fn topo_order(&self) -> &[usize]

Topological order — indices into nodes().

Source

pub fn start(&mut self)

Set the running flag for cooperative thread shutdown.

Source

pub fn stop(&self)

Clear the running flag.

Source

pub fn is_running(&self) -> bool

Check if the engine is running.

Source

pub fn spawn(self) -> JoinHandle<()>

Spawn a dedicated signal thread that runs process_block in a loop. The engine is moved into the thread; communication happens through command/telemetry queues.

Returns a handle for joining the thread. Signal shutdown by setting the running flag to false via running_flag.

Source

pub fn running_flag(&self) -> Arc<AtomicBool>

Clone of the running flag, for signaling shutdown from another thread.

Source

pub fn attach_command_rx(&mut self, rx: Receiver<CommandEnum>)

Attach a command receiver after construction.

Source

pub fn attach_telemetry_tx(&mut self, tx: Sender<Telemetry>)

Attach a telemetry sender after construction.

Source

pub fn cmd_slots(&self) -> &[Option<CommandEnum>]

Borrow the command slots (for external processing that needs to check or consume pending commands).

Source

pub fn cmd_slots_mut(&mut self) -> &mut [Option<CommandEnum>]

Mutably borrow the command slots.

Auto Trait Implementations§

§

impl<T, const BUF_SIZE: usize> Freeze for SignalEngine<T, BUF_SIZE>

§

impl<T, const BUF_SIZE: usize> !RefUnwindSafe for SignalEngine<T, BUF_SIZE>

§

impl<T, const BUF_SIZE: usize> Send for SignalEngine<T, BUF_SIZE>

§

impl<T, const BUF_SIZE: usize> Sync for SignalEngine<T, BUF_SIZE>

§

impl<T, const BUF_SIZE: usize> Unpin for SignalEngine<T, BUF_SIZE>

§

impl<T, const BUF_SIZE: usize> UnsafeUnpin for SignalEngine<T, BUF_SIZE>

§

impl<T, const BUF_SIZE: usize> !UnwindSafe for SignalEngine<T, BUF_SIZE>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> AsAny for T
where T: 'static,

Source§

fn as_any(&self) -> &(dyn Any + 'static)

Convert to &dyn std::any::Any
Source§

fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)

Convert to &mut dyn std::any::Any
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.