rewrite started

This commit is contained in:
Kwoth 2016-07-21 02:13:16 +02:00
parent 7567f28baa
commit b506064d37

View File

@ -2,7 +2,9 @@
using Discord.Audio;
using NadekoBot.Extensions;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace NadekoBot.Modules.Music.Classes
@ -52,6 +54,8 @@ namespace NadekoBot.Modules.Music.Classes
public bool Autoplay { get; set; } = false;
public uint MaxQueueSize { get; set; } = 0;
private ConcurrentQueue<Action> actionQueue { get; set; } = new ConcurrentQueue<Action>();
public MusicPlayer(Channel startingVoiceChannel, float? defaultVolume)
{
if (startingVoiceChannel == null)
@ -65,66 +69,93 @@ namespace NadekoBot.Modules.Music.Classes
cancelToken = SongCancelSource.Token;
Task.Run(async () =>
{
try
{
while (!Destroyed)
{
try
{
if (audioClient?.State != ConnectionState.Connected)
audioClient = await PlaybackVoiceChannel.JoinAudio().ConfigureAwait(false);
}
catch
Action action;
if (actionQueue.TryDequeue(out action))
{
await Task.Delay(1000).ConfigureAwait(false);
continue;
action();
}
CurrentSong = GetNextSong();
var curSong = CurrentSong;
if (curSong != null)
}
finally
{
await Task.Delay(100).ConfigureAwait(false);
}
}
}
catch (Exception ex)
{
Console.WriteLine("Action queue crashed");
Console.WriteLine(ex);
}
}).ConfigureAwait(false);
var t = new Thread(new ThreadStart(async () =>
{
try
{
OnStarted(this, curSong);
await curSong.Play(audioClient, cancelToken).ConfigureAwait(false);
while (!Destroyed)
{
try
{
if (audioClient.State != ConnectionState.Connected)
{
audioClient = await PlaybackVoiceChannel.JoinAudio();
continue;
}
var song = CurrentSong;
if (song == null)
continue;
try
{
await song.Play(audioClient, cancelToken);
}
catch (OperationCanceledException)
{
Console.WriteLine("Song canceled");
}
catch (Exception ex)
{
Console.WriteLine($"Exception in PlaySong: {ex}");
}
OnCompleted(this, curSong);
curSong = CurrentSong; //to check if its null now
if (curSong != null)
if (RepeatSong)
playlist.Insert(0, curSong);
else if (RepeatPlaylist)
playlist.Insert(playlist.Count, curSong);
SongCancelSource = new CancellationTokenSource();
cancelToken = SongCancelSource.Token;
}
await Task.Delay(1000).ConfigureAwait(false);
OnCompleted(this, song);
if (RepeatPlaylist)
AddSong(song, song.QueuerName);
if (RepeatSong)
AddSong(song, 0);
}
});
finally
{
await Task.Delay(300).ConfigureAwait(false);
}
}
}
catch (Exception ex) {
Console.WriteLine("Music thread crashed.");
Console.WriteLine(ex);
}
}));
t.Start();
}
public void Next()
{
lock (playlistLock)
{
if (!SongCancelSource.IsCancellationRequested)
{
Paused = false;
SongCancelSource.Cancel();
}
}
}
public void Stop()
{
lock (playlistLock)
actionQueue.Enqueue(() =>
{
playlist.Clear();
CurrentSong = null;
@ -132,19 +163,11 @@ namespace NadekoBot.Modules.Music.Classes
RepeatSong = false;
if (!SongCancelSource.IsCancellationRequested)
SongCancelSource.Cancel();
}
});
}
public void TogglePause() => Paused = !Paused;
public void Shuffle()
{
lock (playlistLock)
{
playlist.Shuffle();
}
}
public int SetVolume(int volume)
{
if (volume < 0)
@ -156,16 +179,15 @@ namespace NadekoBot.Modules.Music.Classes
return volume;
}
private Song GetNextSong()
private Song GetNextSong() =>
playlist.FirstOrDefault();
public void Shuffle()
{
lock (playlistLock)
actionQueue.Enqueue(() =>
{
if (playlist.Count == 0)
return null;
var toReturn = playlist[0];
playlist.RemoveAt(0);
return toReturn;
}
playlist.Shuffle();
});
}
public void AddSong(Song s, string username)
@ -173,42 +195,63 @@ namespace NadekoBot.Modules.Music.Classes
if (s == null)
throw new ArgumentNullException(nameof(s));
ThrowIfQueueFull();
lock (playlistLock)
actionQueue.Enqueue(() =>
{
s.MusicPlayer = this;
s.QueuerName = username.TrimTo(10);
playlist.Add(s);
}
});
}
public void AddSong(Song s, int index)
{
if (s == null)
throw new ArgumentNullException(nameof(s));
lock (playlistLock)
actionQueue.Enqueue(() =>
{
playlist.Insert(index, s);
}
});
}
public void RemoveSong(Song s)
{
if (s == null)
throw new ArgumentNullException(nameof(s));
lock (playlistLock)
actionQueue.Enqueue(() =>
{
playlist.Remove(s);
}
});
}
public void RemoveSongAt(int index)
{
lock (playlistLock)
actionQueue.Enqueue(() =>
{
if (index < 0 || index >= playlist.Count)
throw new ArgumentException("Invalid index");
return;
playlist.RemoveAt(index);
});
}
internal void ClearQueue()
{
actionQueue.Enqueue(() =>
{
playlist.Clear();
});
}
public void Destroy()
{
actionQueue.Enqueue(() =>
{
playlist.Clear();
Destroyed = true;
CurrentSong = null;
if (!SongCancelSource.IsCancellationRequested)
SongCancelSource.Cancel();
audioClient.Disconnect();
});
}
internal Task MoveToVoiceChannel(Channel voiceChannel)
@ -219,27 +262,6 @@ namespace NadekoBot.Modules.Music.Classes
return PlaybackVoiceChannel.JoinAudio();
}
internal void ClearQueue()
{
lock (playlistLock)
{
playlist.Clear();
}
}
public void Destroy()
{
lock (playlistLock)
{
playlist.Clear();
Destroyed = true;
CurrentSong = null;
if (!SongCancelSource.IsCancellationRequested)
SongCancelSource.Cancel();
audioClient.Disconnect();
}
}
internal bool ToggleRepeatSong() => this.RepeatSong = !this.RepeatSong;
internal bool ToggleRepeatPlaylist() => this.RepeatPlaylist = !this.RepeatPlaylist;