Make use of callback serenity

This commit is contained in:
hodasemi 2018-11-23 22:06:35 +01:00
parent de1beb11e7
commit 1fcd593f4d
3 changed files with 95 additions and 128 deletions

View file

@ -5,7 +5,8 @@ use serenity::voice::LockedAudio;
use std::cell::RefCell;
use std::fs;
use std::ops::DerefMut;
use std::ops::{Deref, DerefMut};
use std::rc::Rc;
use std::sync::{Arc, MutexGuard};
use rand::{seq::SliceRandom, thread_rng};
@ -84,7 +85,27 @@ impl Play {
Self::check_join_channel(&manager_lock, msg);
MediaData::start_thread(&self.media, msg.channel_id, &manager_lock);
let check_finished = {
let media_clone = self.media.clone();
let channel_id = msg.channel_id;
let manager_lock_clone = manager_lock.clone();
Rc::new(move || {
let callback = match media_clone.next_callback.borrow().deref() {
Some(callback) => callback.clone(),
None => {
println!("next_callback not set!");
return;
}
};
MediaData::next_song(&media_clone, channel_id, &manager_lock_clone, callback);
})
};
MediaData::start_playing(&self.media, check_finished, msg.channel_id, &manager_lock);
//MediaData::start_thread(&self.media, msg.channel_id, &manager_lock);
}
fn handle_http_request(

View file

@ -5,10 +5,8 @@ use serenity::voice::LockedAudio;
use std::cell::RefCell;
use std::ops::DerefMut;
use std::rc::Rc;
use std::sync::{Arc, Mutex, MutexGuard};
use std::thread;
use std::thread::JoinHandle;
use std::time;
use super::prelude::*;
@ -20,7 +18,7 @@ pub struct MediaData {
playlist: Mutex<RefCell<Vec<Song>>>,
current_song: Mutex<RefCell<Option<LockedAudio>>>,
song_name: Mutex<RefCell<String>>,
watcher_thread: Mutex<RefCell<Option<JoinHandle<()>>>>,
pub next_callback: RefCell<Option<Rc<Fn() -> ()>>>,
}
impl MediaData {
@ -45,14 +43,19 @@ impl MediaData {
}
{
let manager_lock = ctx.data.lock().get::<VoiceManager>().cloned().unwrap();
*self.next_callback.borrow_mut() = None;
}
{
let manager_lock = ctx.data.lock().get::<VoiceManager>().cloned().unwrap();
let mut manager = manager_lock.lock();
let guild_id = match guild_id(msg.channel_id) {
Some(guild_id) => guild_id,
None => return Ok(()),
};
{
let handler = match handler(guild_id, &mut manager) {
Some(handler) => handler,
None => return Ok(()),
@ -63,6 +66,9 @@ impl MediaData {
handler.stop();
}
manager.remove(guild_id);
}
Ok(())
}
@ -78,135 +84,75 @@ impl MediaData {
self.song_name.lock().unwrap()
}
pub fn reset_thread(&self) {
let thread_mutex = self.watcher_thread.lock().unwrap();
*thread_mutex.borrow_mut() = None;
}
pub fn start_thread(
media: &Arc<MediaData>,
pub fn start_playing(
mediadata: &Arc<MediaData>,
callback: Rc<Fn() -> ()>,
channel_id: ChannelId,
manager_lock: &Arc<
serenity::prelude::Mutex<serenity::client::bridge::voice::ClientVoiceManager>,
>,
) {
let media_clone = media.clone();
let manager_clone = manager_lock.clone();
let thread_mutex = media.watcher_thread.lock().unwrap();
let mut watcher_mut = thread_mutex.borrow_mut();
if watcher_mut.is_none() {
*watcher_mut = Some(thread::spawn(move || loop {
{
let song_lock = media_clone.song_mut();
let mut borrow = song_lock.borrow_mut();
// if there is currently something playing
if let Some(ref mut song) = borrow.deref_mut() {
let song_lock = song.clone();
let audio = song_lock.lock();
if audio.finished {
let playlist = media_clone.playlist_mut();
let song_name = media_clone.name_mut();
if !Self::next_song(
song,
song_name.borrow_mut().deref_mut(),
playlist.borrow_mut().deref_mut(),
channel_id,
&manager_clone,
) {
manager_clone
.lock()
.remove(check_option!(guild_id(channel_id)));
media_clone.reset_thread();
println!("left channel");
return;
}
}
continue;
}
// nothing is playing
{
let playlist_mutex = media_clone.playlist_mut();
let mut playlist = playlist_mutex.borrow_mut();
if !playlist.is_empty() {
let mut manager = manager_clone.lock();
if let Some(handler) =
handler(check_option!(guild_id(channel_id)), &mut manager)
{
let first = playlist.remove(0);
let source = match ffmpeg(first.name.clone()) {
Ok(mpeg) => mpeg,
Err(_) => {
playlist.clear();
*borrow = None;
handler.stop();
media_clone.reset_thread();
return;
}
// check if there is already playing
let already_started = {
let song_lock = mediadata.song_mut();
let song = song_lock.borrow();
song.is_some()
};
*borrow = Some(handler.play_returning(source));
let song_name = media_clone.name_mut();
*song_name.borrow_mut() = first.name.clone();
// if there isnt already a song playing, start a new one
if !already_started {
*mediadata.next_callback.borrow_mut() = Some(callback.clone());
print_error!(
channel_id.say(format!("Playing song: {}", first.name))
);
} else {
return;
}
} else {
manager_clone
.lock()
.remove(check_option!(guild_id(channel_id)));
media_clone.reset_thread();
println!("left channel");
return;
}
}
}
let two_sec = time::Duration::from_secs(2);
thread::sleep(two_sec);
}));
Self::next_song(mediadata, channel_id, manager_lock, callback);
}
}
fn next_song(
song: &mut LockedAudio,
name: &mut String,
playlist: &mut Vec<Song>,
pub fn next_song(
mediadata: &Arc<MediaData>,
channel_id: ChannelId,
manager_lock: &Arc<
serenity::prelude::Mutex<serenity::client::bridge::voice::ClientVoiceManager>,
>,
) -> bool {
callback: Rc<Fn() -> ()>,
) {
let mut manager = manager_lock.lock();
let guild_id = match guild_id(channel_id) {
Some(id) => id,
None => return false,
None => {
println!("error getting guild_id");
return;
}
};
if let Some(handler) = handler(guild_id, &mut manager) {
let mut need_to_leave = false;
{
let handler = {
match handler(guild_id, &mut manager) {
Some(handler) => handler,
None => {
println!("error getting handler");
return;
}
}
};
let playlist_lock = mediadata.playlist_mut();
let mut playlist = playlist_lock.borrow_mut();
let song_name_lock = mediadata.name_mut();
let mut name = song_name_lock.borrow_mut();
let song_lock = mediadata.song_mut();
let mut song = song_lock.borrow_mut();
if playlist.is_empty() {
return false;
need_to_leave = true;
handler.stop();
*song = None;
*name = String::new();
*mediadata.next_callback.borrow_mut() = None;
} else {
handler.stop();
@ -217,20 +163,20 @@ impl MediaData {
Err(_) => {
playlist.clear();
return false;
return;
}
};
*song = handler.play_returning(source);
*song = Some(handler.play_returning_and_callback(source, callback));
*name = first.name.clone();
print_error!(channel_id.say(format!("Playing song: {}", first.name)));
return true;
}
}
return false;
if need_to_leave {
manager.remove(guild_id);
}
}
}
@ -240,7 +186,7 @@ impl Default for MediaData {
playlist: Mutex::new(RefCell::new(Vec::new())),
current_song: Mutex::new(RefCell::new(None)),
song_name: Mutex::new(RefCell::new(String::new())),
watcher_thread: Mutex::new(RefCell::new(None)),
next_callback: RefCell::new(None),
}
}
}

View file

@ -57,7 +57,7 @@ pub fn channel_contains_author(
Some(id) => id,
None => {
println!("error getting channel_id for bot");
return false;
return true;
}
},
)