Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using HyPlayer.PlayCore.Abstraction.Models.SingleItems;

namespace HyPlayer.PlayCore.Abstraction.Interfaces.PlayListController;

public interface IOrderedRandomPlayListController : IRandomizablePlayListController
{
public Task ApplyRandomOrderAsync(IReadOnlyList<SingleSongBase> order, CancellationToken ctk = new());
}
6 changes: 6 additions & 0 deletions HyPlayer.PlayCore.Abstraction/PlayCoreBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,12 @@ public abstract class PlayCoreBase : IPlayCoreService,
public abstract Task RemoveAllSongAsync(CancellationToken ctk = new());
public abstract Task SetRandomAsync(bool isRandom, CancellationToken ctk = new());
public abstract Task ReRandomAsync(CancellationToken ctk = new());

public virtual Task ApplyRandomOrderAsync(IReadOnlyList<SingleSongBase> order, CancellationToken ctk = new())
{
return Task.CompletedTask;
}

public abstract Task SetPlayModeAsync(string playModeId, CancellationToken ctk = new());
public abstract Task<List<SingleSongBase>> GetPlaylistAsync(CancellationToken ctk = new());
public abstract Task<List<SingleSongBase>> GetOrderedPlaylistAsync(CancellationToken ctk = new());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,14 @@ await randomizablePlayListController.RandomizeAsync(isRandom ? DateTime.Now.Mill
await randomizablePlayListController.RandomizeAsync(DateTime.Now.Millisecond, ctk).ConfigureAwait(false);
}

public override async Task ApplyRandomOrderAsync(IReadOnlyList<SingleSongBase> order, CancellationToken ctk = new())
{
if (CurrentPlayListController is not IOrderedRandomPlayListController ordered) return;
IsRandom = true;
ActivePlayModeId = "shn";
await ordered.ApplyRandomOrderAsync(order, ctk).ConfigureAwait(false);
}

public override async Task SetPlayModeAsync(string playModeId, CancellationToken ctk = new())
{
if (playModeId is not ("seq" or "sgl" or "shn" or "pfm" or "ltg"))
Expand Down
43 changes: 39 additions & 4 deletions HyPlayer.PlayCore/PlayListControllers/OrderedRollPlayController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public class OrderedRollPlayController : PlayControllerBase,
INavigateSongPlayListController,
IIndexedPlayListController,
IPlayListGettablePlaylistController,
IRandomizablePlayListController,
IOrderedRandomPlayListController,
INotifyDependencyChanged<PlayListManagerBase>,
INotificationSubscriber<InnerPlayListChangedNotification>
{
Expand All @@ -24,6 +24,7 @@ public class OrderedRollPlayController : PlayControllerBase,
private List<SingleSongBase> _originalList = new();
private bool _isRandom;
private int _randomSeed = -1;
private List<string>? _randomOrderKeys;

public OrderedRollPlayController(IDepository depository, PlayListManagerBase? playListManager, INotificationHub notificationHub)
{
Expand Down Expand Up @@ -74,6 +75,7 @@ public OrderedRollPlayController(IDepository depository, PlayListManagerBase? pl
_list.Reverse();
_isRandom = false;
_randomSeed = -1;
_randomOrderKeys = null;
_index = currentSong is null ? -1 : _list.IndexOf(currentSong);
await PublishOrderedPlaylistChangedAsync(ctk).ConfigureAwait(false);
}
Expand Down Expand Up @@ -112,6 +114,16 @@ public OrderedRollPlayController(IDepository depository, PlayListManagerBase? pl
var currentSong = GetCurrentSong();
_isRandom = seed != -1;
_randomSeed = seed;
_randomOrderKeys = null;
RebuildOrderedList(currentSong);
await PublishOrderedPlaylistChangedAsync(ctk).ConfigureAwait(false);
}

public async Task ApplyRandomOrderAsync(IReadOnlyList<SingleSongBase> order, CancellationToken ctk = new())
{
var currentSong = GetCurrentSong();
_isRandom = true;
_randomOrderKeys = order.Select(SongKey).ToList();
RebuildOrderedList(currentSong);
await PublishOrderedPlaylistChangedAsync(ctk).ConfigureAwait(false);
}
Expand Down Expand Up @@ -147,9 +159,11 @@ public async Task HandleNotificationAsync(

private void RebuildOrderedList(SingleSongBase? currentSong)
{
_list = _isRandom
? ShuffleOriginalList(_randomSeed)
: _originalList.ToList();
_list = !_isRandom
? _originalList.ToList()
: _randomOrderKeys is { } keys
? ArrangeOriginalList(keys)
: ShuffleOriginalList(_randomSeed);

if (_list.Count == 0)
{
Expand All @@ -176,6 +190,27 @@ private static int IndexOfSong(IReadOnlyList<SingleSongBase> list, SingleSongBas
return -1;
}

private List<SingleSongBase> ArrangeOriginalList(IReadOnlyList<string> keys)
{
var remaining = _originalList.ToList();
var arranged = new List<SingleSongBase>(remaining.Count);
foreach (var key in keys)
{
var index = remaining.FindIndex(song => SongKey(song) == key);
if (index < 0) continue;
arranged.Add(remaining[index]);
remaining.RemoveAt(index);
}

arranged.AddRange(remaining);
return arranged;
}

private static string SongKey(SingleSongBase song)
{
return $"{song.ProviderId}|{song.TypeId}|{song.ActualId}";
}

private List<SingleSongBase> ShuffleOriginalList(int seed)
{
var random = new Random(seed);
Expand Down
Loading