Skip to main content

ranvier_runtime/
replay.rs

1use ranvier_core::timeline::{Timeline, TimelineEvent};
2
3/// ReplayEngine reconstructs the execution state from a Timeline.
4/// It creates a "virtual" cursor that moves through the circuit based on recorded events.
5pub struct ReplayEngine {
6    timeline: Timeline,
7    cursor: usize,
8}
9
10#[derive(Debug, Clone)]
11pub struct ReplayFrame {
12    pub current_node_id: Option<String>,
13    pub event: TimelineEvent,
14}
15
16impl ReplayEngine {
17    pub fn new(timeline: Timeline) -> Self {
18        Self {
19            timeline,
20            cursor: 0,
21        }
22    }
23
24    /// Advance the replay by one step.
25    /// Returns the current frame or None if finished.
26    pub fn next_step(&mut self) -> Option<ReplayFrame> {
27        if self.cursor >= self.timeline.events.len() {
28            return None;
29        }
30
31        let event = self.timeline.events[self.cursor].clone();
32        self.cursor += 1;
33
34        let current_node_id = match &event {
35            TimelineEvent::NodeEnter { node_id, .. } => Some(node_id.clone()),
36            TimelineEvent::NodeExit { node_id, .. } => Some(node_id.clone()),
37            TimelineEvent::Branchtaken { .. } => None, // Branches happen "between" nodes conceptually or part of outcome
38        };
39
40        Some(ReplayFrame {
41            current_node_id,
42            event,
43        })
44    }
45
46    /// Reset replay to start
47    pub fn reset(&mut self) {
48        self.cursor = 0;
49    }
50}