rust_rocket/player.rs
1//! Player code for playing previously saved tracks, [`RocketPlayer`].
2
3use crate::{track::Track, Tracks};
4use std::collections::HashMap;
5
6/// A player for tracks from
7/// [`RocketClient::save_tracks`](crate::RocketClient::save_tracks).
8///
9/// # Usage
10///
11/// See [module-level documentation](crate::player#Usage).
12///
13/// # Examples
14///
15/// ```rust,no_run
16/// # use rust_rocket::{RocketPlayer, Tracks};
17/// # use std::fs::File;
18/// // Run the demo and edit your sync tracks (see top level documentation),
19/// // then call save_tracks and serialize tracks to a file (see save_tracks documentation)
20///
21/// // And deserialize from a file in your release build
22/// let mut file = File::open("tracks.bin").expect("Failed to open tracks.bin");
23/// # #[cfg(feature = "bincode")]
24/// # {
25/// let tracks = bincode::decode_from_std_read(&mut file, bincode::config::standard())
26/// .expect("Failed to decode tracks.bin");
27/// let player = RocketPlayer::new(tracks);
28/// println!("Value at row 123: {}", player.get_track("test").unwrap().get_value(123.));
29/// # }
30/// # Ok::<(), rust_rocket::client::Error>(())
31/// ```
32pub struct RocketPlayer {
33 tracks: HashMap<Box<str>, Track>,
34}
35
36impl RocketPlayer {
37 /// Constructs a `RocketPlayer` from `Track`s.
38 pub fn new(tracks: Tracks) -> Self {
39 // Convert to a HashMap for perf (not benchmarked)
40 let tracks: HashMap<Box<str>, Track> = tracks
41 .into_iter()
42 .map(|track| (String::from(track.get_name()).into_boxed_str(), track))
43 .collect();
44
45 Self { tracks }
46 }
47
48 /// Get track by name.
49 pub fn get_track(&self, name: &str) -> Option<&Track> {
50 self.tracks.get(name)
51 }
52}
53
54#[cfg(test)]
55mod tests {
56 use super::*;
57 use crate::interpolation::Interpolation;
58 use crate::track::Key;
59
60 fn get_test_tracks() -> Tracks {
61 vec![
62 {
63 let mut track = Track::new("test1");
64 track.set_key(Key::new(0, 1.0, Interpolation::Step));
65 track.set_key(Key::new(5, 0.0, Interpolation::Step));
66 track.set_key(Key::new(10, 1.0, Interpolation::Step));
67 track
68 },
69 {
70 let mut track = Track::new("test2");
71 track.set_key(Key::new(0, 2.0, Interpolation::Step));
72 track.set_key(Key::new(5, 0.0, Interpolation::Step));
73 track.set_key(Key::new(10, 2.0, Interpolation::Step));
74 track
75 },
76 ]
77 }
78
79 #[test]
80 fn finds_all_tracks() {
81 let tracks = get_test_tracks();
82 let player = RocketPlayer::new(tracks);
83
84 // Ugly repeated calls to get_track to reflect average use case :)
85
86 assert_eq!(player.get_track("test1").unwrap().get_value(0.), 1.0);
87 assert_eq!(player.get_track("test2").unwrap().get_value(0.), 2.0);
88 }
89
90 #[test]
91 fn no_surprise_tracks() {
92 let tracks = get_test_tracks();
93 let player = RocketPlayer::new(tracks);
94 assert!(player
95 .get_track("hello this track should not exist")
96 .is_none());
97 }
98}