|
| 1 | +use std::error::Error; |
| 2 | +use std::io::BufReader; |
| 3 | +use std::sync::atomic::{AtomicU32, Ordering}; |
| 4 | +use std::sync::Arc; |
| 5 | + |
| 6 | +fn main() -> Result<(), Box<dyn Error>> { |
| 7 | + let stream_handle = rodio::OutputStreamBuilder::open_default_stream()?; |
| 8 | + let sink = rodio::Sink::connect_new(&stream_handle.mixer()); |
| 9 | + |
| 10 | + let file = std::fs::File::open("assets/music.wav")?; |
| 11 | + sink.append(rodio::Decoder::new(BufReader::new(file))?); |
| 12 | + |
| 13 | + // lets increment a number after `music.wav` has played. We are going to use atomics |
| 14 | + // however you could also use a `Mutex` or send a message through a `std::sync::mpsc`. |
| 15 | + let playlist_pos = Arc::new(AtomicU32::new(0)); |
| 16 | + |
| 17 | + // The closure needs to own everything it uses. We move a clone of |
| 18 | + // playlist_pos into the closure. That way we can still access playlist_pos |
| 19 | + // after appending the EmptyCallback. |
| 20 | + let playlist_pos_clone = playlist_pos.clone(); |
| 21 | + sink.append(rodio::source::EmptyCallback::<f32>::new(Box::new( |
| 22 | + move || { |
| 23 | + println!("empty callback is now running"); |
| 24 | + playlist_pos_clone.fetch_add(1, Ordering::Relaxed); |
| 25 | + }, |
| 26 | + ))); |
| 27 | + |
| 28 | + assert_eq!(playlist_pos.load(Ordering::Relaxed), 0); |
| 29 | + println!( |
| 30 | + "playlist position is: {}", |
| 31 | + playlist_pos.load(Ordering::Relaxed) |
| 32 | + ); |
| 33 | + sink.sleep_until_end(); |
| 34 | + assert_eq!(playlist_pos.load(Ordering::Relaxed), 1); |
| 35 | + println!( |
| 36 | + "playlist position is: {}", |
| 37 | + playlist_pos.load(Ordering::Relaxed) |
| 38 | + ); |
| 39 | + |
| 40 | + Ok(()) |
| 41 | +} |
0 commit comments