1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
// Playback control methods for TimelinePlayer
impl TimelinePlayer {
/// Start auto-advance playback
///
/// Sets `is_playing` to true. The UI layer is responsible for implementing
/// timer-based frame advancement at the current playback speed.
///
/// # Example
///
/// ```rust,no_run
/// # use pmat::services::dap::{Recording, TimelinePlayer};
/// # let recording = Recording::new("test".to_string(), vec![]);
/// let mut player = TimelinePlayer::new(recording);
///
/// assert!(!player.is_playing());
/// player.play();
/// assert!(player.is_playing());
/// ```
#[provable_contracts_macros::contract("pmat-core.yaml", equation = "check_compliance")]
pub fn play(&mut self) {
self.is_playing = true;
}
/// Stop auto-advance playback
///
/// Sets `is_playing` to false, pausing frame advancement.
///
/// # Example
///
/// ```rust,no_run
/// # use pmat::services::dap::{Recording, TimelinePlayer};
/// # let recording = Recording::new("test".to_string(), vec![]);
/// let mut player = TimelinePlayer::new(recording);
///
/// player.play();
/// assert!(player.is_playing());
///
/// player.pause();
/// assert!(!player.is_playing());
/// ```
#[provable_contracts_macros::contract("pmat-core.yaml", equation = "check_compliance")]
pub fn pause(&mut self) {
self.is_playing = false;
}
/// Check if playback is currently active
///
/// Returns true if play() has been called without a subsequent pause().
///
/// # Example
///
/// ```rust,no_run
/// # use pmat::services::dap::{Recording, TimelinePlayer};
/// # let recording = Recording::new("test".to_string(), vec![]);
/// let mut player = TimelinePlayer::new(recording);
///
/// assert!(!player.is_playing());
/// player.play();
/// assert!(player.is_playing());
/// ```
#[provable_contracts_macros::contract("pmat-core.yaml", equation = "check_compliance")]
pub fn is_playing(&self) -> bool {
self.is_playing
}
/// Set the playback speed multiplier
///
/// The speed affects how fast frames advance during auto-play mode:
/// - 0.5 = half speed (2x slower)
/// - 1.0 = normal speed
/// - 2.0 = double speed (2x faster)
///
/// The UI layer implements the timing logic using this value.
///
/// # Example
///
/// ```rust,no_run
/// # use pmat::services::dap::{Recording, TimelinePlayer};
/// # let recording = Recording::new("test".to_string(), vec![]);
/// let mut player = TimelinePlayer::new(recording);
///
/// assert_eq!(player.playback_speed(), 1.0);
///
/// player.set_speed(2.0);
/// assert_eq!(player.playback_speed(), 2.0);
///
/// player.set_speed(0.5);
/// assert_eq!(player.playback_speed(), 0.5);
/// ```
#[provable_contracts_macros::contract("pmat-core.yaml", equation = "check_compliance")]
pub fn set_speed(&mut self, speed: f64) {
self.playback_speed = speed;
}
/// Get the current playback speed
///
/// Returns the playback speed multiplier (default: 1.0).
///
/// # Example
///
/// ```rust,no_run
/// # use pmat::services::dap::{Recording, TimelinePlayer};
/// # let recording = Recording::new("test".to_string(), vec![]);
/// let mut player = TimelinePlayer::new(recording);
///
/// assert_eq!(player.playback_speed(), 1.0);
/// player.set_speed(2.0);
/// assert_eq!(player.playback_speed(), 2.0);
/// ```
#[provable_contracts_macros::contract("pmat-core.yaml", equation = "check_compliance")]
pub fn playback_speed(&self) -> f64 {
self.playback_speed
}
/// Get a reference to the underlying recording
///
/// Provides access to recording metadata and all snapshots.
///
/// # Example
///
/// ```rust,no_run
/// # use pmat::services::dap::{Recording, TimelinePlayer};
/// # let recording = Recording::new("test_program".to_string(), vec![]);
/// let player = TimelinePlayer::new(recording);
///
/// let metadata = player.recording().metadata();
/// println!("Program: {}", metadata.program);
/// ```
#[provable_contracts_macros::contract("pmat-core.yaml", equation = "check_compliance")]
pub fn recording(&self) -> &Recording {
&self.recording
}
}