diff --git a/src/lib.rs b/src/lib.rs index c44058c..0c31acc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -90,17 +90,13 @@ clippy::module_name_repetitions, clippy::missing_errors_doc )] +#![cfg_attr(docsrs, feature(doc_cfg))] 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, @@ -112,10 +108,12 @@ use sdl2::{ video::{Window, WindowBuildError, WindowContext}, EventPump, IntegerOrSdlError, }; -use std::fs::File; -use std::io::BufReader; -#[cfg(feature = "audio")] -use rodio::{self, Decoder, OutputStream, source::Source}; +use std::{ + cell::Cell, + ops::{Deref, DerefMut}, + path::Path, + slice::IterMut, +}; use vec2::Vec2Int; #[doc(no_inline)] @@ -165,6 +163,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) @@ -761,7 +767,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 +779,35 @@ 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)); -/// ``` -#[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(); - // 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)); - }) - } +#[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); +/// ``` +pub fn play + Send + 'static>( + path: P, + time: u64, +) -> std::thread::JoinHandle> { + use std::fs::File; + use std::io::BufReader; + use std::thread; + + 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(path)?); + // Decode that sound file into a source + let source = Decoder::new(file)?; + // Play the sound directly on the device + 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(time)); + + Ok(()) + }) +} diff --git a/src/main.rs b/src/main.rs index 2c2b047..4980e07 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,6 @@ #![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, Game, Sprite, SpriteCollection}; use sdl2::keyboard::Scancode; fn main() { @@ -19,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);