Create channel in spirc instead of in mercury and use MercuryResponseSender implemented by macro

This commit is contained in:
Daniel Romero 2017-01-31 21:38:52 +01:00
parent 37916330b4
commit c8ee08663d
3 changed files with 42 additions and 25 deletions

View file

@ -4,10 +4,10 @@ use protobuf::{self, Message};
use std::collections::HashMap; use std::collections::HashMap;
use std::io::{Cursor, Read, Write}; use std::io::{Cursor, Read, Write};
use std::mem::replace; use std::mem::replace;
use std::sync::mpsc;
use protocol; use protocol;
use session::{Session, PacketHandler}; use session::{Session, PacketHandler};
use spirc::MercuryResponseSender;
#[derive(Debug, PartialEq, Eq)] #[derive(Debug, PartialEq, Eq)]
pub enum MercuryMethod { pub enum MercuryMethod {
@ -32,7 +32,7 @@ pub struct MercuryResponse {
enum MercuryCallback { enum MercuryCallback {
Future(eventual::Complete<MercuryResponse, ()>), Future(eventual::Complete<MercuryResponse, ()>),
Subscription(mpsc::Sender<MercuryResponse>), Subscription(MercuryResponseSender),
Channel, Channel,
} }
@ -45,7 +45,7 @@ pub struct MercuryPending {
pub struct MercuryManager { pub struct MercuryManager {
next_seq: u32, next_seq: u32,
pending: HashMap<Vec<u8>, MercuryPending>, pending: HashMap<Vec<u8>, MercuryPending>,
subscriptions: HashMap<String, mpsc::Sender<MercuryResponse>>, subscriptions: HashMap<String, MercuryResponseSender>,
} }
impl ToString for MercuryMethod { impl ToString for MercuryMethod {
@ -103,9 +103,7 @@ impl MercuryManager {
rx rx
} }
pub fn subscribe(&mut self, session: &Session, uri: String) -> mpsc::Receiver<MercuryResponse> { pub fn subscribe(&mut self, session: &Session, uri: String, tx: MercuryResponseSender) {
let (tx, rx) = mpsc::channel();
self.request_with_callback(session, self.request_with_callback(session,
MercuryRequest { MercuryRequest {
method: MercuryMethod::SUB, method: MercuryMethod::SUB,
@ -114,8 +112,6 @@ impl MercuryManager {
payload: Vec::new(), payload: Vec::new(),
}, },
MercuryCallback::Subscription(tx)); MercuryCallback::Subscription(tx));
rx
} }
fn parse_part(mut s: &mut Read) -> Vec<u8> { fn parse_part(mut s: &mut Read) -> Vec<u8> {
@ -128,7 +124,7 @@ impl MercuryManager {
fn complete_subscription(&mut self, fn complete_subscription(&mut self,
response: MercuryResponse, response: MercuryResponse,
tx: mpsc::Sender<MercuryResponse>) { tx: MercuryResponseSender) {
for sub_data in response.payload { for sub_data in response.payload {
if let Ok(mut sub) = if let Ok(mut sub) =
protobuf::parse_from_bytes::<protocol::pubsub::Subscription>(&sub_data) { protobuf::parse_from_bytes::<protocol::pubsub::Subscription>(&sub_data) {

View file

@ -9,7 +9,7 @@ use protobuf::{self, Message};
use rand::thread_rng; use rand::thread_rng;
use std::io::{Read, Write, Cursor}; use std::io::{Read, Write, Cursor};
use std::result::Result; use std::result::Result;
use std::sync::{Mutex, RwLock, Arc, mpsc}; use std::sync::{Mutex, RwLock, Arc};
use std::str::FromStr; use std::str::FromStr;
use album_cover::AlbumCover; use album_cover::AlbumCover;
@ -24,6 +24,7 @@ use mercury::{MercuryManager, MercuryRequest, MercuryResponse};
use metadata::{MetadataManager, MetadataRef, MetadataTrait}; use metadata::{MetadataManager, MetadataRef, MetadataTrait};
use protocol; use protocol;
use stream::StreamManager; use stream::StreamManager;
use spirc::MercuryResponseSender;
use util::{self, SpotifyId, FileId, ReadSeek}; use util::{self, SpotifyId, FileId, ReadSeek};
use version; use version;
@ -320,8 +321,8 @@ impl Session {
self.0.mercury.lock().unwrap().request(self, req) self.0.mercury.lock().unwrap().request(self, req)
} }
pub fn mercury_sub(&self, uri: String) -> mpsc::Receiver<MercuryResponse> { pub fn mercury_sub(&self, uri: String, tx: MercuryResponseSender) {
self.0.mercury.lock().unwrap().subscribe(self, uri) self.0.mercury.lock().unwrap().subscribe(self, uri, tx)
} }
pub fn cache(&self) -> &Cache { pub fn cache(&self) -> &Cache {

View file

@ -1,10 +1,10 @@
use eventual::Async; use eventual::Async;
use protobuf::{self, Message, RepeatedField}; use protobuf::{self, Message, RepeatedField};
use std::borrow::Cow; use std::borrow::Cow;
use std::sync::{Mutex, Arc}; use std::sync::{mpsc, Mutex, Arc};
use std::collections::HashMap; use std::collections::HashMap;
use mercury::{MercuryRequest, MercuryMethod}; use mercury::{MercuryRequest, MercuryMethod, MercuryResponse};
use player::{Player, PlayerState}; use player::{Player, PlayerState};
use mixer::Mixer; use mixer::Mixer;
use session::Session; use session::Session;
@ -56,6 +56,18 @@ pub struct State {
pub end_of_track: bool, pub end_of_track: bool,
} }
pub struct UpdateMessage;
pub enum SpircMessage {
MercuryMsg(MercuryResponse),
UpdateMsg(UpdateMessage)
}
implement_sender!(name => MercuryResponseSender,
wrap => MercuryResponse,
with => SpircMessage,
variant => MercuryMsg);
impl SpircManager { impl SpircManager {
pub fn new(session: Session, player: Player, mixer: Box<Mixer + Send>) -> SpircManager { pub fn new(session: Session, player: Player, mixer: Box<Mixer + Send>) -> SpircManager {
let ident = session.device_id().to_owned(); let ident = session.device_id().to_owned();
@ -92,8 +104,11 @@ impl SpircManager {
pub fn run(&self) { pub fn run(&self) {
let rx = { let rx = {
let mut internal = self.0.lock().unwrap(); let mut internal = self.0.lock().unwrap();
let (tx, rx) = mpsc::channel::<SpircMessage>();
let rx = internal.session.mercury_sub(internal.uri()); let mercury_response_sender = MercuryResponseSender::create(tx.clone());
internal.session.mercury_sub(internal.uri(), mercury_response_sender);
internal.notify(true, None); internal.notify(true, None);
@ -110,7 +125,9 @@ impl SpircManager {
rx rx
}; };
for pkt in rx { for msg in rx {
match msg {
SpircMessage::MercuryMsg(pkt) => {
let data = pkt.payload.first().unwrap(); let data = pkt.payload.first().unwrap();
let frame = protobuf::parse_from_bytes::<protocol::spirc::Frame>(data).unwrap(); let frame = protobuf::parse_from_bytes::<protocol::spirc::Frame>(data).unwrap();
@ -123,6 +140,9 @@ impl SpircManager {
self.0.lock().unwrap().handle(frame); self.0.lock().unwrap().handle(frame);
} }
_ => {}
}
}
} }
pub fn devices(&self) -> HashMap<String, String> { pub fn devices(&self) -> HashMap<String, String> {