Start implementing controller thread for playlist

This commit is contained in:
hodasemi 2019-12-15 15:25:48 +01:00
parent b5f2221379
commit c3af982983
9 changed files with 64 additions and 42 deletions

View file

@ -26,7 +26,9 @@ use serenity::{
// This imports `typemap`'s `Key` as `TypeMapKey`. // This imports `typemap`'s `Key` as `TypeMapKey`.
use serenity::prelude::*; use serenity::prelude::*;
use std::sync::Arc; use std::sync::{Arc, Mutex};
use std::thread;
use std::time::Duration;
use player::prelude::*; use player::prelude::*;
use std::collections::HashSet; use std::collections::HashSet;
@ -103,15 +105,17 @@ fn main() -> VerboseResult<()> {
let mut client = Client::new(&config.token, Handler).expect("Err creating client"); let mut client = Client::new(&config.token, Handler).expect("Err creating client");
let media_data = Arc::new(Mutex::new(
MediaData::new("Penis1", Arc::clone(&client.voice_manager), config.volume)
.expect("failed to create media data handle"),
));
// Obtain a lock to the data owned by the client, and insert the client's // Obtain a lock to the data owned by the client, and insert the client's
// voice manager into it. This allows the voice manager to be accessible by // voice manager into it. This allows the voice manager to be accessible by
// event handlers and framework commands. // event handlers and framework commands.
{ {
let mut data = client.data.write(); let mut data = client.data.write();
data.insert::<Media>( data.insert::<Media>(media_data.clone());
MediaData::new("Penis1", Arc::clone(&client.voice_manager), config.volume)
.expect("failed to create media data handle"),
);
} }
// We will fetch your bot's owners and id // We will fetch your bot's owners and id
@ -143,6 +147,29 @@ fn main() -> VerboseResult<()> {
.help(&MY_HELP), .help(&MY_HELP),
); );
thread::spawn(move || loop {
{
let mut media_lock = media_data.lock().unwrap();
// check if there is a song currently being played
let mut is_playing = false;
if let Some(song) = media_lock.song() {
let song_lock = song.lock();
if !song_lock.finished {
is_playing = true;
}
}
if !is_playing {
MediaData::next_song(&mut media_lock).unwrap();
}
}
thread::sleep(Duration::from_millis(1500));
});
let _ = client let _ = client
.start() .start()
.map_err(|why| println!("Client ended: {:?}", why)); .map_err(|why| println!("Client ended: {:?}", why));

View file

@ -24,7 +24,9 @@ fn list(ctx: &mut Context, msg: &Message, _: Args) -> CommandResult {
} }
}; };
let playlist = media.playlist(); let media_lock = media.lock().unwrap();
let playlist = media_lock.playlist();
output += &format!( output += &format!(
"{} {} queued\n", "{} {} queued\n",

View file

@ -24,7 +24,9 @@ fn pause(ctx: &mut Context, msg: &Message, _: Args) -> CommandResult {
} }
}; };
if let Some(song) = media.song() { let media_lock = media.lock().unwrap();
if let Some(song) = media_lock.song() {
let mut lock = song.lock(); let mut lock = song.lock();
lock.pause(); lock.pause();
} }

View file

@ -29,8 +29,10 @@ fn play(ctx: &mut Context, msg: &Message, mut args: Args) -> CommandResult {
} }
}; };
let mut media_lock = media.lock().unwrap();
if args.len() == 0 { if args.len() == 0 {
if !check_for_continue(media.song_mut()) { if !check_for_continue(media_lock.song_mut()) {
msg.channel_id msg.channel_id
.say(&ctx.http, "Must provide a URL to a video or audio")?; .say(&ctx.http, "Must provide a URL to a video or audio")?;
} }
@ -38,9 +40,9 @@ fn play(ctx: &mut Context, msg: &Message, mut args: Args) -> CommandResult {
let first_arg = args.current().unwrap(); let first_arg = args.current().unwrap();
if first_arg == "--local" { if first_arg == "--local" {
handle_local_request(media, ctx, msg)?; handle_local_request(&mut media_lock, ctx, msg)?;
} else if first_arg.starts_with("http") { } else if first_arg.starts_with("http") {
handle_http_request(media, ctx, msg, first_arg)?; handle_http_request(&mut media_lock, ctx, msg, first_arg)?;
} else { } else {
let mut arg_list = args.single::<String>()?; let mut arg_list = args.single::<String>()?;
@ -48,7 +50,7 @@ fn play(ctx: &mut Context, msg: &Message, mut args: Args) -> CommandResult {
arg_list += &format!(" {}", arg?.trim()); arg_list += &format!(" {}", arg?.trim());
} }
handle_song_request(media, ctx, msg, &arg_list)? handle_song_request(&mut media_lock, ctx, msg, &arg_list)?
} }
} }

View file

@ -23,8 +23,10 @@ fn remove(ctx: &mut Context, msg: &Message, _: Args) -> CommandResult {
} }
}; };
let song_name = media.song_name(); let media_lock = media.lock().unwrap();
let sql = media.db();
let song_name = media_lock.song_name();
let sql = media_lock.db();
if let Err(_) = sql.execute("DELETE FROM Vulva3 WHERE name = ?", params![song_name]) { if let Err(_) = sql.execute("DELETE FROM Vulva3 WHERE name = ?", params![song_name]) {
return Err(serenity::framework::standard::CommandError( return Err(serenity::framework::standard::CommandError(

View file

@ -19,21 +19,23 @@ fn skip(ctx: &mut Context, msg: &Message, _: Args) -> CommandResult {
let mut data = ctx.data.write(); let mut data = ctx.data.write();
if let Some(media) = data.get_mut::<Media>() { if let Some(media) = data.get_mut::<Media>() {
let voice_manager = media.voice_manager.clone(); let mut media_lock = media.lock().unwrap();
let voice_manager = media_lock.voice_manager.clone();
let mut manager = voice_manager.lock(); let mut manager = voice_manager.lock();
let guild_id = guild_id(ctx, msg)?; let guild_id = guild_id(ctx, msg)?;
if let Some(handler) = handler(guild_id, &mut manager) { if let Some(handler) = handler(guild_id, &mut manager) {
// if current song is the last song in this playlist, just return // if current song is the last song in this playlist, just return
if media.playlist().is_empty() { if media_lock.playlist().is_empty() {
msg.channel_id msg.channel_id
.say(&ctx.http, "playlist is empty, no next song available")?; .say(&ctx.http, "playlist is empty, no next song available")?;
return Ok(()); return Ok(());
} else { } else {
// remove the current song from the playlist // remove the current song from the playlist
let first = media.playlist_mut().remove(0); let first = media_lock.playlist_mut().remove(0);
// stop the current song from playing // stop the current song from playing
handler.stop(); handler.stop();
@ -42,30 +44,15 @@ fn skip(ctx: &mut Context, msg: &Message, _: Args) -> CommandResult {
let source = match ffmpeg(first.name.clone()) { let source = match ffmpeg(first.name.clone()) {
Ok(mpeg) => mpeg, Ok(mpeg) => mpeg,
Err(_) => { Err(_) => {
media.playlist_mut().clear(); media_lock.playlist_mut().clear();
*media.song_mut() = None; *media_lock.song_mut() = None;
return Ok(()); return Ok(());
} }
}; };
// start the next song if possible *media_lock.song_mut() = Some(handler.play_returning(source));
/* *media_lock.song_name_mut() = first.name.clone();
match self.media.next_callback.borrow().as_ref() {
Some(callback) => {
*song = Some(handler.play_returning_and_callback(source, callback.clone()));
let song_name = self.media.name_mut()?;
*song_name.borrow_mut() = first.name.clone();
print_error!(msg
.channel_id
.say(format!("Skipped current song, now playing: {}", first.name)));
}
None => println!("error getting callback from media"),
}
*/
*media.song_mut() = Some(handler.play_returning(source));
*media.song_name_mut() = first.name.clone();
msg.channel_id.say( msg.channel_id.say(
&ctx.http, &ctx.http,

View file

@ -22,7 +22,9 @@ fn stop(ctx: &mut Context, msg: &Message, _: Args) -> CommandResult {
} }
}; };
media.reset(ctx, msg)?; let mut media_lock = media.lock().unwrap();
media_lock.reset(ctx, msg)?;
Ok(()) Ok(())
} }

View file

@ -7,7 +7,7 @@ use serenity::voice::LockedAudio;
use parking_lot::lock_api::{MutexGuard, RawMutex}; use parking_lot::lock_api::{MutexGuard, RawMutex};
use serenity::client::bridge::voice::ClientVoiceManager; use serenity::client::bridge::voice::ClientVoiceManager;
use serenity::prelude::Mutex; use serenity::prelude::Mutex;
use std::sync::Arc; use std::sync::{Arc, Mutex as StdMutex};
use super::prelude::*; use super::prelude::*;
@ -27,7 +27,6 @@ pub struct MediaData {
playlist: Vec<Song>, playlist: Vec<Song>,
current_song: Option<LockedAudio>, current_song: Option<LockedAudio>,
song_name: String, song_name: String,
pub next_callback: Option<Arc<dyn Fn() -> ()>>,
sql_data_base: Connection, sql_data_base: Connection,
@ -64,7 +63,6 @@ impl MediaData {
playlist: Vec::new(), playlist: Vec::new(),
current_song: None, current_song: None,
song_name: String::new(), song_name: String::new(),
next_callback: None,
sql_data_base: connection, sql_data_base: connection,
@ -80,7 +78,6 @@ impl MediaData {
self.playlist.clear(); self.playlist.clear();
self.current_song = None; self.current_song = None;
self.song_name = String::new(); self.song_name = String::new();
self.next_callback = None;
let mut manager = self.voice_manager.lock(); let mut manager = self.voice_manager.lock();
@ -293,5 +290,5 @@ unsafe impl Sync for MediaData {}
pub struct Media; pub struct Media;
impl TypeMapKey for Media { impl TypeMapKey for Media {
type Value = MediaData; type Value = Arc<StdMutex<MediaData>>;
} }

View file

@ -62,7 +62,8 @@ pub fn channel_contains_author(
}; };
if let Some(media) = ctx.data.read().get::<Media>() { if let Some(media) = ctx.data.read().get::<Media>() {
let manager = media.voice_manager.lock(); let media_lock = media.lock().unwrap();
let manager = media_lock.voice_manager.lock();
if let Some(handler) = manager.get(guild_id) { if let Some(handler) = manager.get(guild_id) {
// check if the bot is in a channel // check if the bot is in a channel