From 76446e0d696e52e30def0df850f5cb9da01015aa Mon Sep 17 00:00:00 2001 From: Jason Dove Date: Mon, 15 Mar 2021 11:28:07 +0000 Subject: [PATCH] prevent repeated playout items when reshuffling (#80) --- .../Scheduling/ShuffledContentTests.cs | 48 +++++++++++++++++++ .../ShuffledMediaCollectionEnumerator.cs | 18 +++++-- 2 files changed, 61 insertions(+), 5 deletions(-) diff --git a/ErsatzTV.Core.Tests/Scheduling/ShuffledContentTests.cs b/ErsatzTV.Core.Tests/Scheduling/ShuffledContentTests.cs index 9240de89f..3784f3d97 100644 --- a/ErsatzTV.Core.Tests/Scheduling/ShuffledContentTests.cs +++ b/ErsatzTV.Core.Tests/Scheduling/ShuffledContentTests.cs @@ -15,6 +15,54 @@ namespace ErsatzTV.Core.Tests.Scheduling // this seed will produce (shuffle) 1-10 in order private const int MagicSeed = 670596; + [Test] + public void Episodes_Should_Not_Duplicate_When_Reshuffling() + { + List contents = Episodes(10); + + // normally returns 10 5 7 4 3 6 2 8 9 1 1 (note duplicate 1 at end) + var state = new CollectionEnumeratorState { Seed = 8 }; + + var shuffledContent = new ShuffledMediaCollectionEnumerator(contents, state); + + var list = new List(); + for (var i = 1; i <= 1000; i++) + { + shuffledContent.Current.IsSome.Should().BeTrue(); + shuffledContent.Current.Do(x => list.Add(x.Id)); + shuffledContent.MoveNext(); + } + + for (var i = 0; i < list.Count - 1; i++) + { + if (list[i] == list[i + 1]) + { + Assert.Fail("List contains duplicate items"); + } + } + } + + [Test] + [Timeout(2000)] + public void Duplicate_Check_Should_Ignore_Single_Item() + { + List contents = Episodes(1); + + var state = new CollectionEnumeratorState(); + + var shuffledContent = new ShuffledMediaCollectionEnumerator(contents, state); + + var list = new List(); + for (var i = 1; i <= 10; i++) + { + shuffledContent.Current.IsSome.Should().BeTrue(); + shuffledContent.Current.Do(x => list.Add(x.Id)); + shuffledContent.MoveNext(); + } + + list.Should().Equal(1, 1, 1, 1, 1, 1, 1, 1, 1, 1); + } + [Test] public void Episodes_Should_Shuffle() { diff --git a/ErsatzTV.Core/Scheduling/ShuffledMediaCollectionEnumerator.cs b/ErsatzTV.Core/Scheduling/ShuffledMediaCollectionEnumerator.cs index d51ca9fb1..e45d4f049 100644 --- a/ErsatzTV.Core/Scheduling/ShuffledMediaCollectionEnumerator.cs +++ b/ErsatzTV.Core/Scheduling/ShuffledMediaCollectionEnumerator.cs @@ -34,13 +34,21 @@ namespace ErsatzTV.Core.Scheduling public void MoveNext() { - State.Index++; - if (State.Index % _shuffled.Count == 0) + if ((State.Index + 1) % _shuffled.Count == 0) { + Option tail = Current; + State.Index = 0; - State.Seed = _random.Next(); - _random = new Random(State.Seed); - _shuffled = Shuffle(_mediaItems, _random); + do + { + State.Seed = _random.Next(); + _random = new Random(State.Seed); + _shuffled = Shuffle(_mediaItems, _random); + } while (_mediaItems.Count > 1 && Current == tail); + } + else + { + State.Index++; } State.Index %= _shuffled.Count;