sim_core/
recorder.rs

1//! Recorder subsystem types for data capture and metadata management.
2//!
3//! This module consolidates all recorder-related types previously split across
4//! `recorder_types` and `recorder_meta` modules for clearer organization.
5
6use bevy::math::UVec2;
7use bevy::prelude::{Resource, Timer, TimerMode};
8use std::path::PathBuf;
9use vision_core::prelude::Recorder;
10
11// Configuration and State ------------------------------------------------
12
13/// Configuration resource for the recorder subsystem.
14#[derive(Resource)]
15pub struct Config {
16    pub output_root: PathBuf,
17    pub capture_interval: Timer,
18    pub resolution: UVec2,
19    pub prune_empty: bool,
20    pub prune_output_root: Option<PathBuf>,
21}
22
23impl Default for Config {
24    fn default() -> Self {
25        Self {
26            output_root: PathBuf::from("assets/datasets/captures"),
27            capture_interval: Timer::from_seconds(0.33, TimerMode::Repeating),
28            resolution: UVec2::new(640, 360),
29            prune_empty: false,
30            prune_output_root: None,
31        }
32    }
33}
34
35/// Runtime state resource for the recorder subsystem.
36#[derive(Resource)]
37pub struct State {
38    pub enabled: bool,
39    pub session_dir: PathBuf,
40    pub frame_idx: u64,
41    pub last_toggle: f64,
42    pub last_image_ok: bool,
43    pub paused: bool,
44    pub overlays_done: bool,
45    pub prune_done: bool,
46    pub initialized: bool,
47    pub manifest_written: bool,
48}
49
50impl Default for State {
51    fn default() -> Self {
52        Self {
53            enabled: false,
54            session_dir: PathBuf::from("assets/datasets/captures/unsynced"),
55            frame_idx: 0,
56            last_toggle: 0.0,
57            last_image_ok: false,
58            paused: false,
59            overlays_done: false,
60            prune_done: false,
61            initialized: false,
62            manifest_written: false,
63        }
64    }
65}
66
67/// Motion tracking resource for recorder triggers.
68#[derive(Resource, Default)]
69pub struct Motion {
70    pub last_head_z: Option<f32>,
71    pub cumulative_forward: f32,
72    pub started: bool,
73}
74
75/// Auto-record timer resource.
76#[derive(Resource)]
77pub struct AutoRecordTimer {
78    pub timer: Timer,
79}
80
81impl Default for AutoRecordTimer {
82    fn default() -> Self {
83        Self {
84            timer: Timer::from_seconds(30.0, TimerMode::Once),
85        }
86    }
87}
88
89// Metadata Management ----------------------------------------------------
90
91/// Trait for providing metadata to the recorder (e.g., label seeds).
92pub trait MetadataProvider: Send + Sync + 'static {
93    fn label_seed(&self) -> u64;
94}
95
96/// Resource holding a boxed metadata provider.
97#[derive(Resource)]
98pub struct MetaProvider {
99    pub provider: Box<dyn MetadataProvider>,
100}
101
102/// Basic metadata provider implementation with a configurable seed.
103#[derive(Default)]
104pub struct BasicMeta {
105    pub seed: u64,
106}
107
108impl MetadataProvider for BasicMeta {
109    fn label_seed(&self) -> u64 {
110        self.seed
111    }
112}
113
114// Integration Types ------------------------------------------------------
115
116/// Resource holding the active recorder sink (trait object).
117#[derive(Resource, Default)]
118pub struct Sink {
119    pub writer: Option<Box<dyn Recorder + Send + Sync>>,
120}
121
122/// App-provided world state for recorder triggers (head position, stop flag).
123#[derive(Resource, Default)]
124pub struct RecorderWorldSnapshot {
125    pub head_z: Option<f32>,
126    pub stop_flag: bool,
127}