From bf1b7ed39ceb07e9270d81d739f213f691683694 Mon Sep 17 00:00:00 2001 From: Yash Karandikar Date: Thu, 6 Oct 2022 08:50:47 -0500 Subject: [PATCH 1/4] Fix doctest --- src/lib.rs | 52 +++++++++++++++++++++++++++------------------------- src/main.rs | 4 +++- 2 files changed, 30 insertions(+), 26 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index c44058c..65a0e4e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -94,13 +94,8 @@ pub mod physics; pub mod vec2; -use std::{ - cell::Cell, - ops::{Deref, DerefMut}, - path::Path, - slice::IterMut, -}; -use std::{thread}; +#[cfg(feature = "audio")] +use rodio::{self, source::Source, Decoder, OutputStream}; use sdl2::{ image::ImageRWops, mouse::MouseButton, @@ -114,8 +109,13 @@ use sdl2::{ }; use std::fs::File; use std::io::BufReader; -#[cfg(feature = "audio")] -use rodio::{self, Decoder, OutputStream, source::Source}; +use std::thread; +use std::{ + cell::Cell, + ops::{Deref, DerefMut}, + path::Path, + slice::IterMut, +}; use vec2::Vec2Int; #[doc(no_inline)] @@ -761,7 +761,7 @@ impl Game { Ok(()) } - + /// Stops the game loop. This method should be called inside the closure that you passed to [`Self::run()`]. /// ``` /// # use cat_box::Game; @@ -773,23 +773,25 @@ impl Game { self.stopped.set(true); } } + /// Plays an audio file given the path of file and plays it for y seconds -/// ``` -/// play(String::from("/path/to/song.mp3", 15)); +/// ```no_run +/// # use cat_box::play; +/// play("/path/to/song.mp3", 15); /// ``` #[cfg(feature = "audio")] pub fn play + std::marker::Send + 'static>(x: P, y: u64) -> thread::JoinHandle<()> { - thread::spawn(move || { - let (_stream, stream_handle) = OutputStream::try_default().unwrap(); - // Load a sound from a file, using a path relative to Cargo.toml - let file = BufReader::new(File::open(x).unwrap()); - // Decode that sound file into a source - let source = Decoder::new(file).unwrap(); - // Play the sound directly on the device - stream_handle.play_raw(source.convert_samples()).unwrap(); + thread::spawn(move || { + let (_stream, stream_handle) = OutputStream::try_default().unwrap(); + // Load a sound from a file, using a path relative to Cargo.toml + let file = BufReader::new(File::open(x).unwrap()); + // Decode that sound file into a source + let source = Decoder::new(file).unwrap(); + // Play the sound directly on the device + stream_handle.play_raw(source.convert_samples()).unwrap(); - // The sound plays in a separate audio thread, - // so we need to keep the main thread alive while it's playing. - std::thread::sleep(std::time::Duration::from_secs(y)); - }) - } + // The sound plays in a separate audio thread, + // so we need to keep the main thread alive while it's playing. + std::thread::sleep(std::time::Duration::from_secs(y)); + }) +} diff --git a/src/main.rs b/src/main.rs index 2c2b047..757f848 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,8 @@ #![warn(clippy::pedantic)] -use cat_box::{draw_text, get_keyboard_state, get_mouse_state, Game, Sprite, SpriteCollection, play}; +use cat_box::{ + draw_text, get_keyboard_state, get_mouse_state, play, Game, Sprite, SpriteCollection, +}; use sdl2::keyboard::Scancode; fn main() { From b891ff76b4b4325a4e3a7deb2eba40e2e2b4a74a Mon Sep 17 00:00:00 2001 From: Yash Karandikar Date: Thu, 6 Oct 2022 16:08:59 -0500 Subject: [PATCH 2/4] Use proper error handling and not `unwrap()` --- src/lib.rs | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 65a0e4e..8d4c229 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -165,6 +165,14 @@ error_from_format! { InitError } +#[cfg(feature = "audio")] +error_from_format! { + rodio::StreamError, + std::io::Error, + rodio::decoder::DecoderError, + rodio::PlayError +} + impl std::fmt::Display for CatboxError { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { self.0.fmt(f) @@ -782,16 +790,18 @@ impl Game { #[cfg(feature = "audio")] pub fn play + std::marker::Send + 'static>(x: P, y: u64) -> thread::JoinHandle<()> { thread::spawn(move || { - let (_stream, stream_handle) = OutputStream::try_default().unwrap(); + let (_stream, stream_handle) = OutputStream::try_default()?; // Load a sound from a file, using a path relative to Cargo.toml - let file = BufReader::new(File::open(x).unwrap()); + let file = BufReader::new(File::open(p)?); // Decode that sound file into a source - let source = Decoder::new(file).unwrap(); + let source = Decoder::new(file)?; // Play the sound directly on the device - stream_handle.play_raw(source.convert_samples()).unwrap(); + stream_handle.play_raw(source.convert_samples())?; // The sound plays in a separate audio thread, // so we need to keep the main thread alive while it's playing. - std::thread::sleep(std::time::Duration::from_secs(y)); + std::thread::sleep(std::time::Duration::from_secs(time)); + + Ok(()) }) } From 884b23c5a530761cfbb0497de302120e9dfbb67e Mon Sep 17 00:00:00 2001 From: Yash Karandikar Date: Thu, 6 Oct 2022 16:09:53 -0500 Subject: [PATCH 3/4] Minor fixes --- src/lib.rs | 16 +++++++++++----- src/main.rs | 7 +++---- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 8d4c229..40546bd 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -90,6 +90,7 @@ clippy::module_name_repetitions, clippy::missing_errors_doc )] +#![cfg_attr(docsrs, feature(doc_cfg))] pub mod physics; pub mod vec2; @@ -107,9 +108,6 @@ use sdl2::{ video::{Window, WindowBuildError, WindowContext}, EventPump, IntegerOrSdlError, }; -use std::fs::File; -use std::io::BufReader; -use std::thread; use std::{ cell::Cell, ops::{Deref, DerefMut}, @@ -782,13 +780,21 @@ impl Game { } } +#[cfg(feature = "audio")] +#[cfg_attr(docsrs, doc(cfg(feature = "audio")))] /// Plays an audio file given the path of file and plays it for y seconds /// ```no_run /// # use cat_box::play; /// play("/path/to/song.mp3", 15); /// ``` -#[cfg(feature = "audio")] -pub fn play + std::marker::Send + 'static>(x: P, y: u64) -> thread::JoinHandle<()> { +pub fn play>(path: P, time: u64) -> std::thread::JoinHandle> { + use std::fs::File; + use std::io::BufReader; + use std::thread; + + // bypass the Send + 'static requirement + let p = path.as_ref(); + thread::spawn(move || { let (_stream, stream_handle) = OutputStream::try_default()?; // Load a sound from a file, using a path relative to Cargo.toml diff --git a/src/main.rs b/src/main.rs index 757f848..4980e07 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,8 +1,6 @@ #![warn(clippy::pedantic)] -use cat_box::{ - draw_text, get_keyboard_state, get_mouse_state, play, Game, Sprite, SpriteCollection, -}; +use cat_box::{draw_text, get_keyboard_state, get_mouse_state, Game, Sprite, SpriteCollection}; use sdl2::keyboard::Scancode; fn main() { @@ -21,7 +19,8 @@ fn main() { coll.push(x); } } - play(String::from("output.mp3"), 120); + #[cfg(feature = "audio")] + cat_box::play("output.mp3", 120); game.run(|ctx| { i = (i + 1) % 255; ctx.set_background_colour(i as u8, 64, 255); From 07198829cfa0f47dccb33d1f385eff701c12b4b3 Mon Sep 17 00:00:00 2001 From: Yash Karandikar Date: Thu, 6 Oct 2022 16:12:07 -0500 Subject: [PATCH 4/4] oops --- src/lib.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 40546bd..0c31acc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -787,18 +787,18 @@ impl Game { /// # use cat_box::play; /// play("/path/to/song.mp3", 15); /// ``` -pub fn play>(path: P, time: u64) -> std::thread::JoinHandle> { +pub fn play + Send + 'static>( + path: P, + time: u64, +) -> std::thread::JoinHandle> { use std::fs::File; use std::io::BufReader; use std::thread; - // bypass the Send + 'static requirement - let p = path.as_ref(); - thread::spawn(move || { let (_stream, stream_handle) = OutputStream::try_default()?; // Load a sound from a file, using a path relative to Cargo.toml - let file = BufReader::new(File::open(p)?); + let file = BufReader::new(File::open(path)?); // Decode that sound file into a source let source = Decoder::new(file)?; // Play the sound directly on the device