Skip to main content

Stream

Struct Stream 

Source
pub struct Stream { /* private fields */ }
Expand description

A streaming session for outputting points to a DAC.

Use run() to stream with buffer-driven timing. The callback is invoked when the buffer needs filling, providing automatic backpressure handling and zero allocations in the hot path.

The stream owns pacing, backpressure, and the timebase (StreamInstant).

Implementations§

Source§

impl Stream

Source

pub fn info(&self) -> &DacInfo

Returns the device info.

Source

pub fn config(&self) -> &StreamConfig

Returns the stream configuration.

Source

pub fn control(&self) -> StreamControl

Returns a thread-safe control handle.

Source

pub fn status(&self) -> Result<StreamStatus>

Returns the current stream status.

Source

pub fn stop(&mut self) -> Result<()>

Stop the stream and terminate output.

Disarms the output (software blanking + hardware shutter) before stopping the backend to prevent the “freeze on last bright point” hazard. Use disarm() instead if you want to keep the stream alive but safe.

Source

pub fn into_dac(self) -> (Dac, StreamStats)

Consume the stream and recover the device for reuse.

This method disarms and stops the stream (software blanking + hardware shutter), then returns the underlying Dac along with the final StreamStats. The device can then be used to start a new stream with different configuration.

§Example
use laser_dac::StreamConfig;

// device: Dac, config: StreamConfig (from prior setup)
let (stream, info) = device.start_stream(config)?;
// ... stream for a while ...
let (device, stats) = stream.into_dac();
println!("Streamed {} points", stats.points_written);

// Restart with different config
let new_config = StreamConfig::new(60_000);
let (stream2, _) = device.start_stream(new_config)?;
Source

pub fn run<F, E>(self, producer: F, on_error: E) -> Result<RunExit>
where F: FnMut(&ChunkRequest, &mut [LaserPoint]) -> ChunkResult + Send + 'static, E: FnMut(Error) + Send + 'static,

Run the stream with the zero-allocation callback API.

This method uses pure buffer-driven timing:

  • Callback is invoked when buffered < target_buffer
  • Points requested varies based on buffer headroom (min_points, target_points)
  • Callback fills a library-owned buffer (zero allocations in hot path)
§Callback Contract

The callback receives a ChunkRequest describing buffer state and requirements, and a mutable slice to fill with points. It returns:

  • ChunkResult::Filled(n): Wrote n points to the buffer
  • ChunkResult::Starved: No data available (underrun policy applies)
  • ChunkResult::End: Stream should end gracefully
§Exit Conditions
  • RunExit::Stopped: Stop requested via StreamControl::stop().
  • RunExit::ProducerEnded: Callback returned ChunkResult::End.
  • RunExit::Disconnected: Device disconnected.
§Example
use laser_dac::{ChunkRequest, ChunkResult, LaserPoint};

stream.run(
    |req: &ChunkRequest, buffer: &mut [LaserPoint]| {
        let n = req.target_points;
        for i in 0..n {
            let t = req.start.as_secs_f64(req.pps) + (i as f64 / req.pps as f64);
            let angle = (t * std::f64::consts::TAU) as f32;
            buffer[i] = LaserPoint::new(angle.cos(), angle.sin(), 65535, 0, 0, 65535);
        }
        ChunkResult::Filled(n)
    },
    |err| eprintln!("Error: {}", err),
)?;

Trait Implementations§

Source§

impl Drop for Stream

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more

Auto Trait Implementations§

§

impl Freeze for Stream

§

impl !RefUnwindSafe for Stream

§

impl Send for Stream

§

impl !Sync for Stream

§

impl Unpin for Stream

§

impl UnsafeUnpin for Stream

§

impl !UnwindSafe for Stream

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> 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<S> FromSample<S> for S

Source§

fn from_sample_(s: S) -> S

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> ToSample<U> for T
where U: FromSample<T>,

Source§

fn to_sample_(self) -> U

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.
Source§

impl<S, T> Duplex<S> for T
where T: FromSample<S> + ToSample<S>,