pub struct Rocket<P: AsRef<Path>> { /* private fields */ }
Expand description
Implementations§
Source§impl<P: AsRef<Path>> Rocket<P>
impl<P: AsRef<Path>> Rocket<P>
Sourcepub fn new(path: P, bpm: f32) -> Result<Self, DecodeError>
pub fn new(path: P, bpm: f32) -> Result<Self, DecodeError>
Initializes rocket.
§Without player
feature
Attemps to connect to a rocket tracker, and retries indefinitely every 1s if connection can’t be established, during which the function doesn’t return and the caller is blocked.
§With player
feature
Loads tracks from file specified by path
using bincode
.
§Errors
Any errors that occur are first printed to stderr, then returned to the caller.
An error is returned If the file specified by path
cannot be read or its contents cannot be decoded.
The return value can be handled by calling unwrap
if you want to panic,
or ok
if you want to ignore the error and continue without using rocket.
Examples found in repository?
46fn main() {
47 let mut rocket = Rocket::new("tracks.bin", 60.).unwrap();
48 let mut time_source = TimeSource::new();
49 let mut previous_time = Duration::ZERO;
50
51 'main: loop {
52 // <Handle other event sources such as SDL here>
53
54 // Get current frame's time
55 let time = time_source.get_time();
56
57 // Keep the rocket tracker in sync.
58 // It's recommended to combine consecutive seek events to a single seek.
59 let mut seek = None;
60 while let Some(event) = rocket.poll_events().ok().flatten() {
61 match event {
62 Event::Seek(to) => seek = Some(to),
63 Event::Pause(state) => time_source.pause(state),
64 Event::NotConnected => /* Alternatively: break the loop here and keep rendering frames */ {
65 std::thread::sleep(Duration::from_millis(10));
66 continue 'main;
67 }
68 }
69 }
70 // It's recommended to call set_time only when necessary.
71 // This ensures the smoothest scrolling in the editor.
72 match seek {
73 Some(to) => {
74 time_source.seek(to);
75 continue;
76 }
77 None => rocket.set_time(&time),
78 }
79
80 // <In a full demo you would render a frame here>
81
82 // Filter redundant output
83 if time != previous_time {
84 println!("{:?}: test = {}", time, rocket.get_value("test"));
85 }
86 previous_time = time;
87 thread::sleep(Duration::from_millis(10));
88 }
89}
Sourcepub fn get_value(&mut self, track: &str) -> f32
pub fn get_value(&mut self, track: &str) -> f32
Get value based on previous call to set_time
, by track name.
§Panics
With player
feature: if the file specified in call to new
doesn’t contain track with name
,
the function handles the error by printing to stderr and panicking.
Examples found in repository?
46fn main() {
47 let mut rocket = Rocket::new("tracks.bin", 60.).unwrap();
48 let mut time_source = TimeSource::new();
49 let mut previous_time = Duration::ZERO;
50
51 'main: loop {
52 // <Handle other event sources such as SDL here>
53
54 // Get current frame's time
55 let time = time_source.get_time();
56
57 // Keep the rocket tracker in sync.
58 // It's recommended to combine consecutive seek events to a single seek.
59 let mut seek = None;
60 while let Some(event) = rocket.poll_events().ok().flatten() {
61 match event {
62 Event::Seek(to) => seek = Some(to),
63 Event::Pause(state) => time_source.pause(state),
64 Event::NotConnected => /* Alternatively: break the loop here and keep rendering frames */ {
65 std::thread::sleep(Duration::from_millis(10));
66 continue 'main;
67 }
68 }
69 }
70 // It's recommended to call set_time only when necessary.
71 // This ensures the smoothest scrolling in the editor.
72 match seek {
73 Some(to) => {
74 time_source.seek(to);
75 continue;
76 }
77 None => rocket.set_time(&time),
78 }
79
80 // <In a full demo you would render a frame here>
81
82 // Filter redundant output
83 if time != previous_time {
84 println!("{:?}: test = {}", time, rocket.get_value("test"));
85 }
86 previous_time = time;
87 thread::sleep(Duration::from_millis(10));
88 }
89}
Sourcepub fn set_time(&mut self, time: &Duration)
pub fn set_time(&mut self, time: &Duration)
Update rocket with the current time from your time source, e.g. music player.
Examples found in repository?
46fn main() {
47 let mut rocket = Rocket::new("tracks.bin", 60.).unwrap();
48 let mut time_source = TimeSource::new();
49 let mut previous_time = Duration::ZERO;
50
51 'main: loop {
52 // <Handle other event sources such as SDL here>
53
54 // Get current frame's time
55 let time = time_source.get_time();
56
57 // Keep the rocket tracker in sync.
58 // It's recommended to combine consecutive seek events to a single seek.
59 let mut seek = None;
60 while let Some(event) = rocket.poll_events().ok().flatten() {
61 match event {
62 Event::Seek(to) => seek = Some(to),
63 Event::Pause(state) => time_source.pause(state),
64 Event::NotConnected => /* Alternatively: break the loop here and keep rendering frames */ {
65 std::thread::sleep(Duration::from_millis(10));
66 continue 'main;
67 }
68 }
69 }
70 // It's recommended to call set_time only when necessary.
71 // This ensures the smoothest scrolling in the editor.
72 match seek {
73 Some(to) => {
74 time_source.seek(to);
75 continue;
76 }
77 None => rocket.set_time(&time),
78 }
79
80 // <In a full demo you would render a frame here>
81
82 // Filter redundant output
83 if time != previous_time {
84 println!("{:?}: test = {}", time, rocket.get_value("test"));
85 }
86 previous_time = time;
87 thread::sleep(Duration::from_millis(10));
88 }
89}
Sourcepub fn poll_events(&mut self) -> Result<Option<Event>, EncodeError>
pub fn poll_events(&mut self) -> Result<Option<Event>, EncodeError>
Poll for new events from rocket.
§Without player
feature
This polls from events from the tracker.
You should call this at least once per frame.
It is recommended to keep calling this in a while
loop until you receive Ok(None)
.
§Errors
Any errors that occur are first printed to stderr, then returned to the caller.
An error is returned if the file specified in call to new
cannot be written to.
The return value can be handled by calling unwrap
if you want to panic,
or .ok().flatten()
if you want to ignore the error and continue.
§Example
while let Some(event) = rocket.poll_events().ok().flatten() {
match event {
Event::Seek(to) => music.seek(to),
Event::Pause(state) => music.pause(state),
Event::NotConnected => break,
}
}
§Tips
There are three sensible ways to handle the Event::NotConnected
variant:
break
: End your event pollingwhile let
-loop and proceed to rendering the frame. AllRocket
methods keep working, but without control from the tracker.continue 'main
: Restart your main loop, don’t render the frame. This lets you keep calling other event polling functions from other libraries, e.g. SDL or winit.{}
: Ignore it and let your event polling loop continue.
Options 2 and 3 result is a busy wait, e.g. waste a lot of CPU time.
It’s better to combine them with std::thread::sleep
for at least a few milliseconds in order to mitigate that.
§With player
feature
The function is a no-op.
Examples found in repository?
46fn main() {
47 let mut rocket = Rocket::new("tracks.bin", 60.).unwrap();
48 let mut time_source = TimeSource::new();
49 let mut previous_time = Duration::ZERO;
50
51 'main: loop {
52 // <Handle other event sources such as SDL here>
53
54 // Get current frame's time
55 let time = time_source.get_time();
56
57 // Keep the rocket tracker in sync.
58 // It's recommended to combine consecutive seek events to a single seek.
59 let mut seek = None;
60 while let Some(event) = rocket.poll_events().ok().flatten() {
61 match event {
62 Event::Seek(to) => seek = Some(to),
63 Event::Pause(state) => time_source.pause(state),
64 Event::NotConnected => /* Alternatively: break the loop here and keep rendering frames */ {
65 std::thread::sleep(Duration::from_millis(10));
66 continue 'main;
67 }
68 }
69 }
70 // It's recommended to call set_time only when necessary.
71 // This ensures the smoothest scrolling in the editor.
72 match seek {
73 Some(to) => {
74 time_source.seek(to);
75 continue;
76 }
77 None => rocket.set_time(&time),
78 }
79
80 // <In a full demo you would render a frame here>
81
82 // Filter redundant output
83 if time != previous_time {
84 println!("{:?}: test = {}", time, rocket.get_value("test"));
85 }
86 previous_time = time;
87 thread::sleep(Duration::from_millis(10));
88 }
89}
Sourcepub fn save_tracks(&self) -> Result<(), EncodeError>
pub fn save_tracks(&self) -> Result<(), EncodeError>
Save a snapshot of the tracks in the session, overwriting the file specified in call to new
.
§Errors
Any errors that occur are first printed to stderr, then returned to the caller.
An error is returned if the file specified in call to new
cannot be written to.
The return value can be handled by calling unwrap
if you want to panic,
or ok
if you want to ignore the error and continue.
§With player
feature
The function is a no-op.
Source§impl Rocket<&str>
impl Rocket<&str>
Sourcepub fn from_std_read<R: Read>(
read: &mut R,
bpm: f32,
) -> Result<Self, DecodeError>
pub fn from_std_read<R: Read>( read: &mut R, bpm: f32, ) -> Result<Self, DecodeError>
An escape hatch constructor for advanced users who want to handle track loading via other means than File
.
This function is only available when the player
feature is enabled, so you should not default to using it.
§Usage
The function makes it possible to load from e.g. std::include_bytes!
in release builds.
// const SYNC_DATA: &[u8] = include_bytes!("tracks.bin");
#[cfg(feature = "player")]
let rocket = Rocket::from_std_read(&mut SYNC_DATA, 120.).unwrap_or_else(|_| unsafe {
std::hint::unreachable_unchecked()
});