1use serde::{Deserialize, Serialize};
2
3use crate::backend::Backend;
4use crate::device::{MouseButton, PadId};
5use crate::event::InputEvent;
6use crate::rumble::MotorCommand;
7use crate::state::{ActionState, Active};
8
9pub const RECORDING_VERSION: u32 = 1;
10
11#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
12pub struct Start {
13 pub events: Vec<InputEvent>,
14 pub states: Vec<ActionState>,
15 pub active: Active,
16 pub last_pad: Option<PadId>,
17 pub anchor: Option<[f32; 2]>,
18 #[serde(default, skip_serializing_if = "Vec::is_empty")]
19 pub outside: Vec<MouseButton>,
20}
21
22#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
23pub struct Recording {
24 pub version: u32,
25 pub step_us: u32,
26 pub start: Start,
27 pub steps: Vec<Vec<InputEvent>>,
28}
29
30impl Recording {
31 pub fn new(step_us: u32, start: Start) -> Self {
32 Self {
33 version: RECORDING_VERSION,
34 step_us,
35 start,
36 steps: Vec::new(),
37 }
38 }
39
40 pub fn len(&self) -> usize {
41 self.steps.len()
42 }
43
44 pub fn is_empty(&self) -> bool {
45 self.steps.is_empty()
46 }
47
48 pub fn player(&self) -> Player<'_> {
49 Player {
50 recording: self,
51 at: 0,
52 motors: Vec::new(),
53 }
54 }
55}
56
57#[derive(Clone, Debug)]
58pub struct Player<'a> {
59 recording: &'a Recording,
60 at: usize,
61 pub motors: Vec<MotorCommand>,
62}
63
64impl Player<'_> {
65 pub fn at(&self) -> usize {
66 self.at
67 }
68
69 pub fn finished(&self) -> bool {
70 self.at >= self.recording.steps.len()
71 }
72}
73
74impl Backend for Player<'_> {
75 fn poll(&mut self, events: &mut Vec<InputEvent>) {
76 if let Some(step) = self.recording.steps.get(self.at) {
77 events.extend(step.iter().cloned());
78 }
79 self.at += 1;
80 }
81
82 fn set_motors(&mut self, command: &MotorCommand) -> bool {
83 self.motors.push(*command);
84 false
85 }
86}