use serenity::all::GuildId; use songbird::input::YoutubeDl; use tokio::sync::{Mutex, MutexGuard}; use std::collections::HashMap; use std::sync::Arc; type MusicQueueItem = Arc>; lazy_static! { static ref HASHMAP: Mutex> = Mutex::new(HashMap::new()); } async fn get_music_queue(guild_id: &GuildId) -> MusicQueueItem { let mut queues = HASHMAP.lock().await; queues .entry(*guild_id) .or_insert(Arc::new(Mutex::new(MusicQueue { guild_id: *guild_id, queue: Vec::new(), now_playing: None, }))) .clone() } pub async fn with_music_queue(guild_id: &GuildId, f: F) -> T where F: FnOnce(&mut MusicQueue) -> T, T: Send, { let queue = get_music_queue(guild_id).await; let mut queue = queue.lock().await; f(&mut *queue) } #[derive(Debug)] pub struct MusicQueue { // God this sucks. This needs to be reprogrammed properly. pub guild_id: GuildId, pub queue: Vec, pub now_playing: Option, } pub async fn delete_queue(guild_id: &GuildId) { with_music_queue(guild_id, |queue| { queue.now_playing = None; queue.queue.clear(); }) .await; } pub async fn add_to_queue(guild_id: &GuildId, input: YoutubeDl) { with_music_queue(guild_id, |queue| { queue.queue.push(input); }) .await; } pub async fn get_head(guild_id: &GuildId) -> Option { with_music_queue(guild_id, |queue| { if queue.queue.is_empty() { None } else { Some(queue.queue.remove(0)) } }) .await } pub async fn set_now_playing(guild_id: &GuildId, now_playing: Option) { let queue = get_music_queue(guild_id).await; let mut queue = queue.lock().await; queue.now_playing = now_playing; } pub async fn get_now_playing(guild_id: &GuildId) -> Option { let queue = get_queue(guild_id).await; queue.now_playing.to_owned() } pub async fn is_empty(guild_id: &GuildId) -> bool { with_music_queue(guild_id, |queue| queue.queue.is_empty()).await }