Skip to main content

animato_devtools/
recorder_controls.rs

1//! Recorder controls built on `animato-driver`.
2
3use animato_driver::{AnimationRecorder, RecordedTrack, RecorderError};
4
5/// Start/stop/export controls for animation recording.
6#[derive(Clone, Debug, Default, PartialEq)]
7pub struct RecorderControls {
8    recorder: AnimationRecorder,
9}
10
11impl RecorderControls {
12    /// Create empty recorder controls.
13    pub fn new() -> Self {
14        Self::default()
15    }
16
17    /// Start recording.
18    pub fn start(&mut self) {
19        self.recorder.start();
20    }
21
22    /// Stop recording.
23    pub fn stop(&mut self) {
24        self.recorder.stop();
25    }
26
27    /// Whether the recorder is active.
28    pub fn is_recording(&self) -> bool {
29        self.recorder.is_recording()
30    }
31
32    /// Clear recorded tracks.
33    pub fn clear(&mut self) {
34        self.recorder.clear();
35    }
36
37    /// Record one scalar sample.
38    pub fn record(&mut self, label: &str, time: f32, value: f64) {
39        self.recorder.record(label, time, value);
40    }
41
42    /// Export deterministic JSON.
43    pub fn export_json(&self) -> String {
44        self.recorder.export_json()
45    }
46
47    /// Export deterministic binary data.
48    pub fn export_binary(&self) -> Vec<u8> {
49        self.recorder.export_binary()
50    }
51
52    /// Replace the current recording from JSON.
53    pub fn import_json(&mut self, json: &str) -> Result<(), RecorderError> {
54        self.recorder = AnimationRecorder::import_json(json)?;
55        Ok(())
56    }
57
58    /// Replace the current recording from binary data.
59    pub fn import_binary(&mut self, bytes: &[u8]) -> Result<(), RecorderError> {
60        self.recorder = AnimationRecorder::import_binary(bytes)?;
61        Ok(())
62    }
63
64    /// Replay a label at seconds.
65    pub fn replay(&self, label: &str, time: f32) -> Option<f64> {
66        self.recorder.replay(label, time)
67    }
68
69    /// Recorded tracks.
70    pub fn tracks(&self) -> &[RecordedTrack] {
71        self.recorder.tracks()
72    }
73
74    /// Access the underlying recorder.
75    pub fn recorder(&self) -> &AnimationRecorder {
76        &self.recorder
77    }
78
79    /// Mutable access to the underlying recorder.
80    pub fn recorder_mut(&mut self) -> &mut AnimationRecorder {
81        &mut self.recorder
82    }
83}
84
85#[cfg(test)]
86mod tests {
87    use super::*;
88
89    #[test]
90    fn round_trips_json_and_replays() {
91        let mut controls = RecorderControls::new();
92        controls.start();
93        controls.record("x", 0.0, 0.0);
94        controls.record("x", 1.0, 10.0);
95        controls.stop();
96
97        let json = controls.export_json();
98        let mut imported = RecorderControls::new();
99        imported.import_json(&json).unwrap();
100        assert_eq!(imported.replay("x", 0.5), Some(5.0));
101
102        let binary = imported.export_binary();
103        let mut from_binary = RecorderControls::new();
104        from_binary.import_binary(&binary).unwrap();
105        assert_eq!(from_binary.replay("x", 0.5), Some(5.0));
106    }
107}