Module client

Source
Expand description

Main client code, including the RocketClient type.

§Usage

The usual workflow with the low level client API can be described in a few steps:

  1. Install a rocket tracker (original Qt editor or emoon’s OpenGL-based editor)
  2. Connect the RocketClient to the running tracker by calling RocketClient::new
  3. Create tracks with get_track_mut
  4. In your main loop, poll for updates from the Rocket tracker by calling poll_events.
  5. Keep the tracker in sync by calling set_row (see tips below)
  6. Get values from the tracks with Track::get_value

See the linked documentation items and the examples-directory for more examples.

§Tips

The library is agnostic to your source of time. In a typical production, some kind of music player library determines the time for everything else, including the rocket tracks. It’s recommended that you treat every 8th row as a beat of music instead of real time in seconds.

struct MusicPlayer; // Your music player, not included in this crate

const ROWS_PER_BEAT: f32 = 8.;
const BEATS_PER_MIN: f32 = 123.; // This depends on your choice of music track
const SECS_PER_MIN: f32  = 60.;

fn time_to_row(time: Duration) -> f32 {
    let secs = time.as_secs_f32();
    let beats = secs * BEATS_PER_MIN / SECS_PER_MIN;
    beats * ROWS_PER_BEAT
}

fn row_to_time(row: u32) -> Duration {
    let beats = row as f32 / ROWS_PER_BEAT;
    let secs = beats / (BEATS_PER_MIN / SECS_PER_MIN);
    Duration::from_secs_f32(secs)
}

fn get(rocket: &mut RocketClient, track: &str, row: f32) -> f32 {
    let track = rocket.get_track_mut(track).unwrap();
    track.get_value(row)
}

fn main() -> Result<(), Error> {
    let mut music = MusicPlayer::new(/* ... */);
    let mut rocket = RocketClient::new()?;

    // Create window, render resources etc...

    loop {
        // Get current frame's time
        let time = music.get_time();
        let row = time_to_row(time);

        // Keep the rocket tracker in sync.
        // When using the low level API, it's recommended to combine consecutive seek events to a single seek.
        // This ensures the smoothest scrolling in editor.
        let mut seek = None;
        while let Some(event) = rocket.poll_events()? {
            match event {
                Event::SetRow(to) => seek = Some(to),
                Event::Pause(state) => music.pause(state),
                Event::SaveTracks => {/* Call save_tracks and write to a file */}
            }
        }
        // When using the low level API, it's recommended to call set_time only when the not seeking.
        if let Some(seek) = seek {
            music.seek(row_to_time(seek));
            continue;
        }
        rocket.set_row(row as u32)?;

        // Render frame and read values with Track's get_value function
        let _ = get(&mut rocket, "track0", row);
    }
}

Structs§

RocketClient
The RocketClient type. This contains the connected socket and other fields.

Enums§

Error
The Error Type. This is the main error type.
Event
The Event Type. These are the various events from the tracker.