diff --git a/src/player.rs b/src/player.rs index 43c9df84..1f0ca4e6 100644 --- a/src/player.rs +++ b/src/player.rs @@ -8,7 +8,7 @@ use metadata::{FileFormat, Track, TrackRef}; use session::{Bitrate, Session}; use audio_decrypt::AudioDecrypt; use util::{self, SpotifyId, Subfile}; -use spirc::{SpircState, SpircDelegate, PlayStatus}; +use spirc::PlayStatus; pub struct Player { state: Arc<(Mutex, Condvar)>, @@ -72,6 +72,54 @@ impl Player { fn command(&self, cmd: PlayerCommand) { self.commands.send(cmd).unwrap(); } + + pub fn load(&self, track: SpotifyId, start_playing: bool, position_ms: u32) { + self.command(PlayerCommand::Load(track, start_playing, position_ms)); + } + + pub fn play(&self) { + self.command(PlayerCommand::Play) + } + + pub fn pause(&self) { + self.command(PlayerCommand::Pause) + } + + pub fn stop(&self) { + self.command(PlayerCommand::Stop) + } + + pub fn seek(&self, position_ms: u32) { + self.command(PlayerCommand::Seek(position_ms)); + } + + pub fn state(&self) -> MutexGuard { + self.state.0.lock().unwrap() + } + + pub fn volume(&self, vol: u16) { + self.command(PlayerCommand::Volume(vol)); + } + + pub fn updates(&self) -> mpsc::Receiver { + let state = self.state.clone(); + let (update_tx, update_rx) = mpsc::channel(); + + thread::spawn(move || { + let mut guard = state.0.lock().unwrap(); + let mut last_update; + loop { + last_update = guard.update_time; + update_tx.send(guard.update_time).unwrap(); + + while last_update >= guard.update_time { + guard = state.1.wait(guard).unwrap(); + } + } + }); + + update_rx + } } impl PlayerInternal { @@ -268,76 +316,24 @@ impl PlayerInternal { } } -impl SpircDelegate for Player { - type State = PlayerState; - - fn load(&self, track: SpotifyId, start_playing: bool, position_ms: u32) { - self.command(PlayerCommand::Load(track, start_playing, position_ms)); - } - - fn play(&self) { - self.command(PlayerCommand::Play) - } - - fn pause(&self) { - self.command(PlayerCommand::Pause) - } - - fn stop(&self) { - self.command(PlayerCommand::Stop) - } - - fn seek(&self, position_ms: u32) { - self.command(PlayerCommand::Seek(position_ms)); - } - - fn state(&self) -> MutexGuard { - self.state.0.lock().unwrap() - } - - fn volume(&self, vol: u16) { - self.command(PlayerCommand::Volume(vol)); - } - - fn updates(&self) -> mpsc::Receiver { - let state = self.state.clone(); - let (update_tx, update_rx) = mpsc::channel(); - - thread::spawn(move || { - let mut guard = state.0.lock().unwrap(); - let mut last_update; - loop { - last_update = guard.update_time; - update_tx.send(guard.update_time).unwrap(); - - while last_update >= guard.update_time { - guard = state.1.wait(guard).unwrap(); - } - } - }); - - update_rx - } -} - -impl SpircState for PlayerState { - fn status(&self) -> PlayStatus { +impl PlayerState { + pub fn status(&self) -> PlayStatus { self.status } - fn position(&self) -> (u32, i64) { + pub fn position(&self) -> (u32, i64) { (self.position_ms, self.position_measured_at) } - fn volume(&self) -> u16 { + pub fn volume(&self) -> u16 { self.volume } - fn update_time(&self) -> i64 { + pub fn update_time(&self) -> i64 { self.update_time } - fn end_of_track(&self) -> bool { + pub fn end_of_track(&self) -> bool { self.end_of_track } } diff --git a/src/spirc.rs b/src/spirc.rs index 66f7dd1d..09483baa 100644 --- a/src/spirc.rs +++ b/src/spirc.rs @@ -1,18 +1,18 @@ use eventual::Async; use protobuf::{self, Message}; -use std::sync::{mpsc, MutexGuard}; use util; use session::Session; use util::SpotifyId; use util::version::version_string; use mercury::{MercuryRequest, MercuryMethod}; +use player::Player; use librespot_protocol as protocol; pub use librespot_protocol::spirc::PlayStatus; -pub struct SpircManager { - delegate: D, +pub struct SpircManager { + player: Player, session: Session, state_update_id: i64, @@ -36,36 +36,13 @@ pub struct SpircManager { index: u32, } -pub trait SpircDelegate { - type State : SpircState; - - fn load(&self, track: SpotifyId, start_playing: bool, position_ms: u32); - fn play(&self); - fn pause(&self); - fn seek(&self, position_ms: u32); - fn volume(&self, vol: u16); - fn stop(&self); - - fn state(&self) -> MutexGuard; - fn updates(&self) -> mpsc::Receiver; -} - -pub trait SpircState { - fn status(&self) -> PlayStatus; - fn position(&self) -> (u32, i64); - fn update_time(&self) -> i64; - fn end_of_track(&self) -> bool; - fn volume(&self) -> u16; -} - -impl SpircManager { - pub fn new(session: Session, delegate: D) -> SpircManager { - +impl SpircManager { + pub fn new(session: Session, player: Player) -> SpircManager { let ident = session.0.data.read().unwrap().device_id.clone(); let name = session.0.config.device_name.clone(); SpircManager { - delegate: delegate, + player: player, session: session, state_update_id: 0, @@ -99,7 +76,7 @@ impl SpircManager { .unwrap() .canonical_username .clone())); - let updates = self.delegate.updates(); + let updates = self.player.updates(); self.notify(true, None); @@ -122,11 +99,11 @@ impl SpircManager { } }, update_time = updates.recv() => { - let end_of_track = self.delegate.state().end_of_track(); + let end_of_track = self.player.state().end_of_track(); if end_of_track { self.index = (self.index + 1) % self.tracks.len() as u32; let track = self.tracks[self.index as usize]; - self.delegate.load(track, true, 0); + self.player.load(track, true, 0); } else { self.state_update_id = update_time.unwrap(); self.notify(false, None); @@ -156,26 +133,26 @@ impl SpircManager { let play = frame.get_state().get_status() == PlayStatus::kPlayStatusPlay; let track = self.tracks[self.index as usize]; let position = frame.get_state().get_position_ms(); - self.delegate.load(track, play, position); + self.player.load(track, play, position); } protocol::spirc::MessageType::kMessageTypePlay => { - self.delegate.play(); + self.player.play(); } protocol::spirc::MessageType::kMessageTypePause => { - self.delegate.pause(); + self.player.pause(); } protocol::spirc::MessageType::kMessageTypeNext => { self.index = (self.index + 1) % self.tracks.len() as u32; let track = self.tracks[self.index as usize]; - self.delegate.load(track, true, 0); + self.player.load(track, true, 0); } protocol::spirc::MessageType::kMessageTypePrev => { self.index = (self.index - 1) % self.tracks.len() as u32; let track = self.tracks[self.index as usize]; - self.delegate.load(track, true, 0); + self.player.load(track, true, 0); } protocol::spirc::MessageType::kMessageTypeSeek => { - self.delegate.seek(frame.get_position()); + self.player.seek(frame.get_position()); } protocol::spirc::MessageType::kMessageTypeReplace => { self.reload_tracks(&frame); @@ -183,11 +160,11 @@ impl SpircManager { protocol::spirc::MessageType::kMessageTypeNotify => { if self.is_active && frame.get_device_state().get_is_active() { self.is_active = false; - self.delegate.stop(); + self.player.stop(); } } protocol::spirc::MessageType::kMessageTypeVolume => { - self.delegate.volume(frame.get_volume() as u16); + self.player.volume(frame.get_volume() as u16); } _ => (), } @@ -238,7 +215,7 @@ impl SpircManager { } fn spirc_state(&self) -> protocol::spirc::State { - let state = self.delegate.state(); + let state = self.player.state(); let (position_ms, position_measured_at) = state.position(); protobuf_init!(protocol::spirc::State::new(), { @@ -268,7 +245,7 @@ impl SpircManager { sw_version: version_string(), is_active: self.is_active, can_play: self.can_play, - volume: self.delegate.state().volume() as u32, + volume: self.player.state().volume() as u32, name: self.name.clone(), error_code: 0, became_active_at: if self.is_active { self.became_active_at as i64 } else { 0 },