Make use of callback serenity
This commit is contained in:
parent
de1beb11e7
commit
1fcd593f4d
3 changed files with 95 additions and 128 deletions
|
@ -5,7 +5,8 @@ use serenity::voice::LockedAudio;
|
||||||
|
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::ops::DerefMut;
|
use std::ops::{Deref, DerefMut};
|
||||||
|
use std::rc::Rc;
|
||||||
use std::sync::{Arc, MutexGuard};
|
use std::sync::{Arc, MutexGuard};
|
||||||
|
|
||||||
use rand::{seq::SliceRandom, thread_rng};
|
use rand::{seq::SliceRandom, thread_rng};
|
||||||
|
@ -84,7 +85,27 @@ impl Play {
|
||||||
|
|
||||||
Self::check_join_channel(&manager_lock, msg);
|
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(
|
fn handle_http_request(
|
||||||
|
|
|
@ -5,10 +5,8 @@ use serenity::voice::LockedAudio;
|
||||||
|
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::ops::DerefMut;
|
use std::ops::DerefMut;
|
||||||
|
use std::rc::Rc;
|
||||||
use std::sync::{Arc, Mutex, MutexGuard};
|
use std::sync::{Arc, Mutex, MutexGuard};
|
||||||
use std::thread;
|
|
||||||
use std::thread::JoinHandle;
|
|
||||||
use std::time;
|
|
||||||
|
|
||||||
use super::prelude::*;
|
use super::prelude::*;
|
||||||
|
|
||||||
|
@ -20,7 +18,7 @@ pub struct MediaData {
|
||||||
playlist: Mutex<RefCell<Vec<Song>>>,
|
playlist: Mutex<RefCell<Vec<Song>>>,
|
||||||
current_song: Mutex<RefCell<Option<LockedAudio>>>,
|
current_song: Mutex<RefCell<Option<LockedAudio>>>,
|
||||||
song_name: Mutex<RefCell<String>>,
|
song_name: Mutex<RefCell<String>>,
|
||||||
watcher_thread: Mutex<RefCell<Option<JoinHandle<()>>>>,
|
pub next_callback: RefCell<Option<Rc<Fn() -> ()>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MediaData {
|
impl MediaData {
|
||||||
|
@ -45,22 +43,30 @@ 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 mut manager = manager_lock.lock();
|
||||||
|
|
||||||
let guild_id = match guild_id(msg.channel_id) {
|
let guild_id = match guild_id(msg.channel_id) {
|
||||||
Some(guild_id) => guild_id,
|
Some(guild_id) => guild_id,
|
||||||
None => return Ok(()),
|
None => return Ok(()),
|
||||||
};
|
};
|
||||||
|
|
||||||
let handler = match handler(guild_id, &mut manager) {
|
{
|
||||||
Some(handler) => handler,
|
let handler = match handler(guild_id, &mut manager) {
|
||||||
None => return Ok(()),
|
Some(handler) => handler,
|
||||||
};
|
None => return Ok(()),
|
||||||
|
};
|
||||||
|
|
||||||
println!("stopped handler");
|
println!("stopped handler");
|
||||||
|
|
||||||
handler.stop();
|
handler.stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
manager.remove(guild_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -78,135 +84,75 @@ impl MediaData {
|
||||||
self.song_name.lock().unwrap()
|
self.song_name.lock().unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn reset_thread(&self) {
|
pub fn start_playing(
|
||||||
let thread_mutex = self.watcher_thread.lock().unwrap();
|
mediadata: &Arc<MediaData>,
|
||||||
*thread_mutex.borrow_mut() = None;
|
callback: Rc<Fn() -> ()>,
|
||||||
}
|
|
||||||
|
|
||||||
pub fn start_thread(
|
|
||||||
media: &Arc<MediaData>,
|
|
||||||
channel_id: ChannelId,
|
channel_id: ChannelId,
|
||||||
manager_lock: &Arc<
|
manager_lock: &Arc<
|
||||||
serenity::prelude::Mutex<serenity::client::bridge::voice::ClientVoiceManager>,
|
serenity::prelude::Mutex<serenity::client::bridge::voice::ClientVoiceManager>,
|
||||||
>,
|
>,
|
||||||
) {
|
) {
|
||||||
let media_clone = media.clone();
|
// check if there is already playing
|
||||||
let manager_clone = manager_lock.clone();
|
let already_started = {
|
||||||
|
let song_lock = mediadata.song_mut();
|
||||||
|
let song = song_lock.borrow();
|
||||||
|
song.is_some()
|
||||||
|
};
|
||||||
|
|
||||||
let thread_mutex = media.watcher_thread.lock().unwrap();
|
// if there isnt already a song playing, start a new one
|
||||||
let mut watcher_mut = thread_mutex.borrow_mut();
|
if !already_started {
|
||||||
|
*mediadata.next_callback.borrow_mut() = Some(callback.clone());
|
||||||
|
|
||||||
if watcher_mut.is_none() {
|
Self::next_song(mediadata, channel_id, manager_lock, callback);
|
||||||
*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;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
*borrow = Some(handler.play_returning(source));
|
|
||||||
let song_name = media_clone.name_mut();
|
|
||||||
*song_name.borrow_mut() = first.name.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);
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn next_song(
|
pub fn next_song(
|
||||||
song: &mut LockedAudio,
|
mediadata: &Arc<MediaData>,
|
||||||
name: &mut String,
|
|
||||||
playlist: &mut Vec<Song>,
|
|
||||||
channel_id: ChannelId,
|
channel_id: ChannelId,
|
||||||
manager_lock: &Arc<
|
manager_lock: &Arc<
|
||||||
serenity::prelude::Mutex<serenity::client::bridge::voice::ClientVoiceManager>,
|
serenity::prelude::Mutex<serenity::client::bridge::voice::ClientVoiceManager>,
|
||||||
>,
|
>,
|
||||||
) -> bool {
|
callback: Rc<Fn() -> ()>,
|
||||||
|
) {
|
||||||
let mut manager = manager_lock.lock();
|
let mut manager = manager_lock.lock();
|
||||||
|
|
||||||
let guild_id = match guild_id(channel_id) {
|
let guild_id = match guild_id(channel_id) {
|
||||||
Some(id) => 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() {
|
if playlist.is_empty() {
|
||||||
return false;
|
need_to_leave = true;
|
||||||
|
handler.stop();
|
||||||
|
*song = None;
|
||||||
|
*name = String::new();
|
||||||
|
*mediadata.next_callback.borrow_mut() = None;
|
||||||
} else {
|
} else {
|
||||||
handler.stop();
|
handler.stop();
|
||||||
|
|
||||||
|
@ -217,20 +163,20 @@ impl MediaData {
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
playlist.clear();
|
playlist.clear();
|
||||||
|
|
||||||
return false;
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
*song = handler.play_returning(source);
|
*song = Some(handler.play_returning_and_callback(source, callback));
|
||||||
*name = first.name.clone();
|
*name = first.name.clone();
|
||||||
|
|
||||||
print_error!(channel_id.say(format!("Playing song: {}", first.name)));
|
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())),
|
playlist: Mutex::new(RefCell::new(Vec::new())),
|
||||||
current_song: Mutex::new(RefCell::new(None)),
|
current_song: Mutex::new(RefCell::new(None)),
|
||||||
song_name: Mutex::new(RefCell::new(String::new())),
|
song_name: Mutex::new(RefCell::new(String::new())),
|
||||||
watcher_thread: Mutex::new(RefCell::new(None)),
|
next_callback: RefCell::new(None),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,7 +57,7 @@ pub fn channel_contains_author(
|
||||||
Some(id) => id,
|
Some(id) => id,
|
||||||
None => {
|
None => {
|
||||||
println!("error getting channel_id for bot");
|
println!("error getting channel_id for bot");
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in a new issue