added some comments

This commit is contained in:
Mark
2023-08-14 00:58:31 +02:00
parent 5add9c477e
commit 0ae0126f04
11 changed files with 89 additions and 24 deletions

View File

@@ -18,7 +18,9 @@ use super::{
};
pub struct Database {
/// the path to the file used to save/load the data
db_file: PathBuf,
/// the path to the directory containing the actual music and cover image files
pub lib_directory: PathBuf,
artists: HashMap<ArtistId, Artist>,
albums: HashMap<AlbumId, Album>,
@@ -26,13 +28,18 @@ pub struct Database {
covers: HashMap<CoverId, DatabaseLocation>,
// TODO! make sure this works out for the server AND clients
// cover_cache: HashMap<CoverId, Vec<u8>>,
// These will be used for autosave once that gets implemented
db_data_file_change_first: Option<Instant>,
db_data_file_change_last: Option<Instant>,
pub queue: Queue,
/// if the database receives an update, it will inform all of its clients so they can stay in sync.
/// this is a list containing all the clients.
pub update_endpoints: Vec<UpdateEndpoint>,
/// true if a song is/should be playing
pub playing: bool,
pub command_sender: Option<mpsc::Sender<Command>>,
}
// for custom server implementations, this enum should allow you to deal with updates from any context (writers such as tcp streams, sync/async mpsc senders, or via closure as a fallback)
pub enum UpdateEndpoint {
Bytes(Box<dyn Write + Sync + Send>),
CmdChannel(mpsc::Sender<Arc<Command>>),
@@ -41,6 +48,7 @@ pub enum UpdateEndpoint {
}
impl Database {
/// TODO!
fn panic(&self, msg: &str) -> ! {
// custom panic handler
// make a backup
@@ -50,6 +58,7 @@ impl Database {
pub fn get_path(&self, location: &DatabaseLocation) -> PathBuf {
self.lib_directory.join(&location.rel_path)
}
// NOTE: just use `songs` directly? not sure yet...
pub fn get_song(&self, song: &SongId) -> Option<&Song> {
self.songs.get(song)
}
@@ -72,6 +81,7 @@ impl Database {
}
id
}
/// used internally
pub fn add_song_new_nomagic(&mut self, mut song: Song) -> SongId {
for key in 0.. {
if !self.songs.contains_key(&key) {
@@ -89,6 +99,7 @@ impl Database {
let id = self.add_artist_new_nomagic(artist);
id
}
/// used internally
fn add_artist_new_nomagic(&mut self, mut artist: Artist) -> ArtistId {
for key in 0.. {
if !self.artists.contains_key(&key) {
@@ -110,6 +121,7 @@ impl Database {
}
id
}
/// used internally
fn add_album_new_nomagic(&mut self, mut album: Album) -> AlbumId {
for key in 0.. {
if !self.albums.contains_key(&key) {

View File

@@ -17,11 +17,13 @@ pub type ArtistId = u64;
pub type CoverId = u64;
#[derive(Clone, Default, Debug)]
/// general data for songs, albums and artists
pub struct GeneralData {
pub tags: Vec<String>,
}
#[derive(Clone, Debug)]
/// the location of a file relative to the lib directory, often Artist/Album/Song.ext or similar
pub struct DatabaseLocation {
pub rel_path: PathBuf,
}

View File

@@ -81,6 +81,8 @@ pub fn run_server(
sender_sender: Option<tokio::sync::mpsc::Sender<mpsc::Sender<Command>>>,
) {
let mut player = Player::new().unwrap();
// commands sent to this will be handeled later in this function in an infinite loop.
// these commands are sent to the database asap.
let (command_sender, command_receiver) = mpsc::channel();
if let Some(s) = sender_sender {
s.blocking_send(command_sender.clone()).unwrap();
@@ -91,6 +93,7 @@ pub fn run_server(
Ok(v) => {
let command_sender = command_sender.clone();
let db = Arc::clone(&database);
// each connection gets its own thread, but they will be idle most of the time (waiting for data on the tcp stream)
thread::spawn(move || loop {
if let Ok((mut connection, con_addr)) = v.accept() {
eprintln!("[info] TCP connection accepted from {con_addr}.");
@@ -100,10 +103,15 @@ pub fn run_server(
// sync database
let mut db = db.lock().unwrap();
db.init_connection(&mut connection)?;
// keep the client in sync:
// the db will send all updates to the client once it is added to update_endpoints
db.update_endpoints.push(UpdateEndpoint::Bytes(Box::new(
// try_clone is used here to split a TcpStream into Writer and Reader
connection.try_clone().unwrap(),
)));
// drop the mutex lock
drop(db);
// read updates from the tcp stream and send them to the database, exit on EOF or Err
loop {
if let Ok(command) = Command::from_bytes(&mut connection) {
command_sender.send(command).unwrap();
@@ -121,6 +129,8 @@ pub fn run_server(
}
}
}
// for now, update the player 10 times a second so it can detect when a song has finished and start a new one.
// TODO: player should send a NextSong update to the mpsc::Sender to wake up this thread
let dur = Duration::from_secs_f32(0.1);
loop {
player.update(&mut database.lock().unwrap());