From 75393a010eed1622c91f59b117508670653cb704 Mon Sep 17 00:00:00 2001 From: G2-Games Date: Sun, 29 Dec 2024 01:13:29 -0600 Subject: [PATCH] Created player monitor loop --- dmp-core/src/music_controller/controller.rs | 158 +++++++++++------- .../src/music_controller/controller_handle.rs | 2 +- dmp-core/src/music_storage/library.rs | 50 ++++-- src-tauri/src/lib.rs | 3 +- 4 files changed, 131 insertions(+), 82 deletions(-) diff --git a/dmp-core/src/music_controller/controller.rs b/dmp-core/src/music_controller/controller.rs index 9bd01e5..251b249 100644 --- a/dmp-core/src/music_controller/controller.rs +++ b/dmp-core/src/music_controller/controller.rs @@ -4,12 +4,14 @@ #![allow(while_true)] use chrono::TimeDelta; +use crossbeam::atomic::AtomicCell; use kushi::{Queue, QueueItemType}; use kushi::{QueueError, QueueItem}; use prismriver::{Prismriver, Volume, Error as PrismError}; use rayon::iter::{IndexedParallelIterator, IntoParallelIterator, ParallelIterator}; use serde::{Deserialize, Serialize}; use serde_json::to_string_pretty; +use std::collections::HashMap; use std::error::Error; use std::fs::OpenOptions; use std::io::Write; @@ -158,7 +160,7 @@ pub struct ControllerInput { ), library: MusicLibrary, config: Arc>, - playback_info: crossbeam::channel::Sender, + playback_info: Arc>, } pub struct ControllerHandle { @@ -168,11 +170,11 @@ pub struct ControllerHandle { } impl ControllerHandle { - pub fn new(library: MusicLibrary, config: Arc>) -> (Self, ControllerInput, crossbeam::channel::Receiver) { + pub fn new(library: MusicLibrary, config: Arc>) -> (Self, ControllerInput, Arc>) { let lib_mail = MailMan::double(); let player_mail = MailMan::double(); let queue_mail = MailMan::double(); - let (playback_info_rx, playback_info_tx) = crossbeam::channel::bounded(1); + let playback_info = Arc::new(AtomicCell::new(PlaybackInfo::default())); ( ControllerHandle { lib_mail: lib_mail.0.clone(), @@ -185,9 +187,9 @@ impl ControllerHandle { queue_mail, library, config, - playback_info: playback_info_rx, + playback_info: Arc::clone(&playback_info), }, - playback_info_tx, + playback_info, ) } } @@ -253,53 +255,46 @@ impl Controller { } }; - std::thread::scope(|scope| { - let queue_mail = queue_mail; - let a = scope.spawn(|| { - futures::executor::block_on(async { - moro::async_scope!(|scope| { - println!("async scope created"); - let player = Arc::new(RwLock::new(Prismriver::new())); + let player = Arc::new(RwLock::new(Prismriver::new())); - let _player = player.clone(); - let _lib_mail = lib_mail.0.clone(); - let _queue_mail = queue_mail.0.clone(); - scope - .spawn(async move { - Controller::player_command_loop( - _player, - player_mail.1, - _queue_mail, - _lib_mail, - state, - ) - .await - .unwrap(); - }); - scope - .spawn(async move { - Controller::player_monitor_loop( - player, - player_mail.0, - queue_mail.0, - playback_info, - ) + std::thread::scope(|scope| { + let a = scope.spawn({ + let player = Arc::clone(&player); + let queue_mail = queue_mail.clone(); + move || { + futures::executor::block_on(async { + moro::async_scope!(|scope| { + println!("async scope created"); + + let _player = player.clone(); + let _lib_mail = lib_mail.0.clone(); + let _queue_mail = queue_mail.0.clone(); + scope + .spawn(async move { + Controller::player_command_loop( + _player, + player_mail.1, + _queue_mail, + _lib_mail, + state, + ) .await .unwrap(); - }); - scope - .spawn(async { - Controller::library_loop( - lib_mail.1, - &mut library, - config, - ) - .await - .unwrap(); - }); + }); + scope + .spawn(async { + Controller::library_loop( + lib_mail.1, + &mut library, + config, + ) + .await + .unwrap(); + }); + }) + .await; }) - .await; - }) + } }); let b = scope.spawn(|| { @@ -307,8 +302,19 @@ impl Controller { Controller::queue_loop(queue, queue_mail.1).await; }) }); + + let c = scope.spawn(|| { + Controller::player_monitor_loop( + player, + player_mail.0, + queue_mail.0, + playback_info, + ).unwrap(); + }); + a.join().unwrap(); b.join().unwrap(); + c.join().unwrap(); }); Ok(()) @@ -532,20 +538,48 @@ impl Controller { Ok(()) } - async fn player_monitor_loop( + fn player_monitor_loop( player: Arc>, player_mail: MailMan, queue_mail: MailMan, - player_info: crossbeam_channel::Sender + player_info: Arc>, ) -> Result<(), ()> { + + let finished_recv = player.read().unwrap().get_finished_recv(); + + std::thread::scope(|s| { + // Thread for timing and metadata + s.spawn({ + let player = Arc::clone(&player); + move || { + while true { + let player = player.read().unwrap(); + player_info.store(PlaybackInfo { + duration: player.duration(), + position: player.position(), + metadata: player.metadata(), + }); + drop(player); + + std::thread::sleep(Duration::from_millis(100)); + } + } + }); + + // Thread for End of Track + s.spawn(move || { + while true { + let _ = finished_recv.recv(); + + std::thread::sleep(Duration::from_millis(100)); + } + }); + }); + + // Check for duration and spit it out + // Check for end of song to get the next + Ok(()) - // std::thread::scope(|s| { - // }); - - // // Check for duration and spit it out - // // Check for end of song to get the next - - // Ok(()) } @@ -590,6 +624,7 @@ impl Controller { } Ok(()) } + async fn queue_loop( mut queue: Queue, queue_mail: MailMan, @@ -646,8 +681,9 @@ impl Controller { } } -#[derive(Debug)] +#[derive(Debug, Default)] pub struct PlaybackInfo { - pub duration: TimeDelta, - pub position: TimeDelta -} \ No newline at end of file + pub duration: Option, + pub position: Option, + pub metadata: HashMap, +} diff --git a/dmp-core/src/music_controller/controller_handle.rs b/dmp-core/src/music_controller/controller_handle.rs index fcb289e..7752fa3 100644 --- a/dmp-core/src/music_controller/controller_handle.rs +++ b/dmp-core/src/music_controller/controller_handle.rs @@ -128,4 +128,4 @@ impl ControllerHandle { }; res } -} \ No newline at end of file +} diff --git a/dmp-core/src/music_storage/library.rs b/dmp-core/src/music_storage/library.rs index 808b1c2..89f37d5 100644 --- a/dmp-core/src/music_storage/library.rs +++ b/dmp-core/src/music_storage/library.rs @@ -1033,7 +1033,6 @@ impl MusicLibrary { sort_by: &Vec, // Tags to sort the resulting data by ) -> Option> { let songs = Arc::new(Mutex::new(Vec::new())); - //let matcher = SkimMatcherV2::default(); self.library.par_iter().for_each(|track| { for tag in target_tags { @@ -1048,18 +1047,6 @@ impl MusicLibrary { }, }; - /* - let match_level = match matcher.fuzzy_match(&normalize(&track_result), &normalize(query_string)) { - Some(conf) => conf, - None => continue - }; - - if match_level > 100 { - songs.lock().unwrap().push(track); - return; - } - */ - if normalize(&track_result.to_string()) .contains(&normalize(&query_string.to_owned())) { @@ -1249,13 +1236,13 @@ impl MusicLibrary { #[cfg(test)] mod test { - use std::{ - path::PathBuf, - sync::{Arc, RwLock}, - }; + use std::{path::PathBuf, time::Instant}; + use crate::music_storage::library::Tag; + + use uuid::Uuid; use crate::{ - config::{tests::new_config_lib, Config}, + config::Config, music_storage::library::MusicLibrary, }; @@ -1270,4 +1257,31 @@ mod test { .unwrap(); dbg!(a); } + + #[test] + fn library_search() { + let lib = MusicLibrary::init( + PathBuf::from("/media/g2/Storage4/Media-Files/Music/Albums/library.dlib"), + Uuid::new_v4(), + ).unwrap(); + + let timer = Instant::now(); + let result = lib.query_tracks( + &String::from(""), + &vec![], + &vec![ + Tag::Field("location".to_string()), + Tag::Album, + Tag::Disk, + Tag::Track, + ], + ).unwrap(); + println!("{} songs in {}ms", result.len(), timer.elapsed().as_millis()); + + /* + for song in result { + println!("{:?}", song.tags.get(&Tag::Title)); + } + */ + } } diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index 36b9b64..c29d545 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -20,7 +20,6 @@ pub fn run() { let (rx, tx) = unbounded::(); let (lib_rx, lib_tx) = unbounded::>(); let (handle_rx, handle_tx) = unbounded::(); - let (playback_handle_rx, playback_handle_tx) = unbounded::>(); let controller_thread = spawn(move || { let mut config = { tx.recv().unwrap() } ; @@ -55,7 +54,7 @@ pub fn run() { library.save(save_path).unwrap(); - let (handle, input, playback_tx) = ControllerHandle::new( + let (handle, input, playback_info) = ControllerHandle::new( library, std::sync::Arc::new(std::sync::RwLock::new(config)) );