mirror of
https://github.com/Dummi26/musicdb.git
synced 2025-12-14 11:56:16 +01:00
added some comments
This commit is contained in:
@@ -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) {
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
|
||||
Reference in New Issue
Block a user