song_queue.rs 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. use std::{
  2. sync::Arc,
  3. collections::VecDeque,
  4. mem::drop,
  5. cmp::min,
  6. };
  7. use tokio::sync::{Semaphore, Mutex};
  8. use rand::seq::SliceRandom;
  9. use super::{
  10. song::{
  11. Song,
  12. SongUrlState,
  13. },
  14. youtube_loader::YoutubeLoader,
  15. work::Work,
  16. };
  17. pub struct SongQueue{
  18. loader: Arc<Mutex<YoutubeLoader>>,
  19. queue: Arc<Mutex<VecDeque<Song>>>,
  20. queue_sem: Semaphore,
  21. }
  22. impl SongQueue{
  23. pub fn new() -> SongQueue {
  24. SongQueue{
  25. loader: Arc::new(Mutex::new(YoutubeLoader::new())),
  26. queue: Arc::new(Mutex::new(VecDeque::new())),
  27. queue_sem: Semaphore::new(0),
  28. }
  29. }
  30. pub async fn push(&self, songs: Vec<(Song, Option<Work>)>){
  31. let mut queue = self.queue.lock().await;
  32. let count = songs.len();
  33. let loader = self.loader.lock().await;
  34. for item in songs.into_iter(){
  35. queue.push_back(item.0);
  36. if let Some(work) = item.1{
  37. loader.add_work(work).await;
  38. };
  39. //self.loader.add_work(item.1).await;
  40. }
  41. drop(queue);
  42. self.queue_sem.add_permits(count);
  43. }
  44. pub async fn pop(&self) -> Song {
  45. self.queue_sem.acquire().await.expect("Error SongQueue.pop: semaphore acquire() failed").forget();
  46. let mut queue = self.queue.lock().await;
  47. queue.pop_front().expect("Error SongQueue.pop: semaphore sync failure")
  48. }
  49. pub async fn shuffle(&self) -> Result<(), String> {
  50. let mut queue = self.queue.lock().await;
  51. if queue.len() == 0 {
  52. return Err("queue is empty".to_string());
  53. }
  54. queue.make_contiguous().shuffle(&mut rand::thread_rng());
  55. self.reset_loader().await;
  56. let loader = self.loader.lock().await;
  57. for song in queue.iter(){
  58. match &song.url_state{
  59. SongUrlState::Proc{work,..} => loader.add_work(work.clone()).await,
  60. };
  61. };
  62. Ok(())
  63. }
  64. pub async fn clear(&self) -> Result<(), String>{
  65. let mut queue = self.queue.lock().await;
  66. if queue.len() == 0 {
  67. return Err("queue is empty".to_string());
  68. };
  69. queue.clear();
  70. Ok(())
  71. }
  72. async fn reset_loader(&self) {
  73. let mut loader = self.loader.lock().await;
  74. loader.cleanup().await;
  75. *loader = YoutubeLoader::new();
  76. }
  77. pub async fn cleanup(&self) {
  78. let mut loader = self.loader.lock().await;
  79. loader.cleanup().await;
  80. }
  81. pub async fn get_string(&self) -> String{
  82. let queue = self.queue.lock().await;
  83. if queue.len() == 0 {
  84. return "*empty*".to_string();
  85. };
  86. let mut s = String::new();
  87. s.push_str(&format!("*Showing {} of {} songs*\n", min(20, queue.len()), queue.len()));
  88. for (i, song) in queue.iter().take(20).enumerate(){
  89. s += &format!("{}: ", i);
  90. s += &song.get_string().await;
  91. s += "\n";
  92. }
  93. s
  94. }
  95. }