From 719437eae2d9d60bf1ee5469eafdf19b458e3e9e Mon Sep 17 00:00:00 2001 From: Gaimoydev <106746080+Gaimoydev@users.noreply.github.com> Date: Thu, 29 Oct 2026 20:29:48 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E4=B8=80=E8=B5=B7=E5=90=AC=E6=96=B0?= =?UTF-8?q?=E5=A2=9E=E9=9A=8F=E6=9C=BA=E6=92=AD=E6=94=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../IOrderedRandomPlayListController.cs | 8 ++++ HyPlayer.PlayCore.Abstraction/PlayCoreBase.cs | 6 +++ .../PlayCore.PlaylistModification.cs | 8 ++++ .../OrderedRollPlayController.cs | 43 +++++++++++++++++-- 4 files changed, 61 insertions(+), 4 deletions(-) create mode 100644 HyPlayer.PlayCore.Abstraction/Interfaces/PlayListController/IOrderedRandomPlayListController.cs diff --git a/HyPlayer.PlayCore.Abstraction/Interfaces/PlayListController/IOrderedRandomPlayListController.cs b/HyPlayer.PlayCore.Abstraction/Interfaces/PlayListController/IOrderedRandomPlayListController.cs new file mode 100644 index 0000000..b78f608 --- /dev/null +++ b/HyPlayer.PlayCore.Abstraction/Interfaces/PlayListController/IOrderedRandomPlayListController.cs @@ -0,0 +1,8 @@ +using HyPlayer.PlayCore.Abstraction.Models.SingleItems; + +namespace HyPlayer.PlayCore.Abstraction.Interfaces.PlayListController; + +public interface IOrderedRandomPlayListController : IRandomizablePlayListController +{ + public Task ApplyRandomOrderAsync(IReadOnlyList order, CancellationToken ctk = new()); +} diff --git a/HyPlayer.PlayCore.Abstraction/PlayCoreBase.cs b/HyPlayer.PlayCore.Abstraction/PlayCoreBase.cs index 0514b9a..2b602de 100644 --- a/HyPlayer.PlayCore.Abstraction/PlayCoreBase.cs +++ b/HyPlayer.PlayCore.Abstraction/PlayCoreBase.cs @@ -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 order, CancellationToken ctk = new()) + { + return Task.CompletedTask; + } + public abstract Task SetPlayModeAsync(string playModeId, CancellationToken ctk = new()); public abstract Task> GetPlaylistAsync(CancellationToken ctk = new()); public abstract Task> GetOrderedPlaylistAsync(CancellationToken ctk = new()); diff --git a/HyPlayer.PlayCore/PlayCoreComponents/PlayCore.PlaylistModification.cs b/HyPlayer.PlayCore/PlayCoreComponents/PlayCore.PlaylistModification.cs index 02d07a2..f730673 100644 --- a/HyPlayer.PlayCore/PlayCoreComponents/PlayCore.PlaylistModification.cs +++ b/HyPlayer.PlayCore/PlayCoreComponents/PlayCore.PlaylistModification.cs @@ -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 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")) diff --git a/HyPlayer.PlayCore/PlayListControllers/OrderedRollPlayController.cs b/HyPlayer.PlayCore/PlayListControllers/OrderedRollPlayController.cs index 6c2f859..0b6aeb5 100644 --- a/HyPlayer.PlayCore/PlayListControllers/OrderedRollPlayController.cs +++ b/HyPlayer.PlayCore/PlayListControllers/OrderedRollPlayController.cs @@ -12,7 +12,7 @@ public class OrderedRollPlayController : PlayControllerBase, INavigateSongPlayListController, IIndexedPlayListController, IPlayListGettablePlaylistController, - IRandomizablePlayListController, + IOrderedRandomPlayListController, INotifyDependencyChanged, INotificationSubscriber { @@ -24,6 +24,7 @@ public class OrderedRollPlayController : PlayControllerBase, private List _originalList = new(); private bool _isRandom; private int _randomSeed = -1; + private List? _randomOrderKeys; public OrderedRollPlayController(IDepository depository, PlayListManagerBase? playListManager, INotificationHub notificationHub) { @@ -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); } @@ -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 order, CancellationToken ctk = new()) + { + var currentSong = GetCurrentSong(); + _isRandom = true; + _randomOrderKeys = order.Select(SongKey).ToList(); RebuildOrderedList(currentSong); await PublishOrderedPlaylistChangedAsync(ctk).ConfigureAwait(false); } @@ -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) { @@ -176,6 +190,27 @@ private static int IndexOfSong(IReadOnlyList list, SingleSongBas return -1; } + private List ArrangeOriginalList(IReadOnlyList keys) + { + var remaining = _originalList.ToList(); + var arranged = new List(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 ShuffleOriginalList(int seed) { var random = new Random(seed);