📄 rig/src/source.rs
//! The frame-source abstraction shared by live capture and replay.

use anyhow::Result;

use crate::splat::SplatBatch;

/// One processed rig frame, ready for rendering.
///
/// In the MVP (and the synthetic dataset) a frame is simply the freshly
/// constructed Gaussian list; recorded RGB/depth data rides along from
/// build-order step 2 on.
#[derive(Debug, Clone, PartialEq)]
pub struct Frame {
    /// Frame timestamp in seconds since the source started. Synthetic
    /// sources use deterministic timestamps (frame index / fps).
    pub timestamp_secs: f64,
    pub splats: SplatBatch,
}

/// A source of processed rig frames — the seam where live capture, replay
/// of recorded datasets, and synthetic generation are interchangeable.
///
/// Implementations must be deterministic when replaying: the same frame
/// sequence every run, so tests and recordings behave identically.
pub trait FrameSource {
    fn next_frame(&mut self) -> Result<Frame>;
}