1
0
Fork 0
mirror of https://github.com/librespot-org/librespot.git synced 2025-10-05 19:42:03 +02:00

Refactor the whole architecture.

Use less threads, makes it much simpler to reason about.
This commit is contained in:
Paul Lietar 2015-07-02 19:24:25 +02:00
parent c1ce87dbbd
commit 2a2f227bef
10 changed files with 299 additions and 542 deletions

View file

@ -3,18 +3,9 @@ use std::collections::HashMap;
use std::io::{Cursor, Seek, SeekFrom, Write};
use std::sync::mpsc;
use connection::Packet;
use util::{ArcVec, FileId};
use util::Either::{Left, Right};
use subsystem::Subsystem;
pub type StreamCallback = mpsc::Sender<StreamEvent>;
pub struct StreamRequest {
pub id: FileId,
pub offset: u32,
pub size: u32,
pub callback: StreamCallback
}
use connection::PacketHandler;
use session::Session;
#[derive(Debug)]
pub enum StreamEvent {
@ -31,36 +22,28 @@ enum ChannelMode {
struct Channel {
mode: ChannelMode,
callback: StreamCallback
callback: mpsc::Sender<StreamEvent>
}
pub struct StreamManager {
next_id: ChannelId,
channels: HashMap<ChannelId, Channel>,
requests: mpsc::Receiver<StreamRequest>,
packet_rx: mpsc::Receiver<Packet>,
packet_tx: mpsc::Sender<Packet>,
}
impl StreamManager {
pub fn new(tx: mpsc::Sender<Packet>) -> (StreamManager,
mpsc::Sender<StreamRequest>,
mpsc::Sender<Packet>) {
let (req_tx, req_rx) = mpsc::channel();
let (pkt_tx, pkt_rx) = mpsc::channel();
(StreamManager {
pub fn new() -> StreamManager {
StreamManager {
next_id: 0,
channels: HashMap::new(),
requests: req_rx,
packet_rx: pkt_rx,
packet_tx: tx
}, req_tx, pkt_tx)
}
}
fn request(&mut self, req: StreamRequest) {
pub fn request(&mut self, session: &Session,
file: FileId, offset: u32, size: u32)
-> mpsc::Receiver<StreamEvent> {
let (tx, rx) = mpsc::channel();
let channel_id = self.next_id;
self.next_id += 1;
@ -72,22 +55,23 @@ impl StreamManager {
data.write_u32::<BigEndian>(0x00000000).unwrap();
data.write_u32::<BigEndian>(0x00009C40).unwrap();
data.write_u32::<BigEndian>(0x00020000).unwrap();
data.write(&req.id).unwrap();
data.write_u32::<BigEndian>(req.offset).unwrap();
data.write_u32::<BigEndian>(req.offset + req.size).unwrap();
data.write(&file).unwrap();
data.write_u32::<BigEndian>(offset).unwrap();
data.write_u32::<BigEndian>(offset + size).unwrap();
self.packet_tx.send(Packet {
cmd: 0x8,
data: data
}).unwrap();
session.send_packet(0x8, &data).unwrap();
self.channels.insert(channel_id, Channel {
mode: ChannelMode::Header,
callback: req.callback
callback: tx
});
}
fn packet(&mut self, data: Vec<u8>) {
rx
}
}
impl PacketHandler for StreamManager {
fn handle(&mut self, _cmd: u8, data: Vec<u8>) {
let data = ArcVec::new(data);
let mut packet = Cursor::new(&data as &[u8]);
@ -140,27 +124,3 @@ impl StreamManager {
}
}
impl Subsystem for StreamManager {
fn run(mut self) {
loop {
match {
let requests = &self.requests;
let packets = &self.packet_rx;
select!{
r = requests.recv() => {
Left(r.unwrap())
},
p = packets.recv() => {
Right(p.unwrap())
}
}
} {
Left(req) => self.request(req),
Right(pkt) => self.packet(pkt.data)
}
}
}
}