mirror of
https://github.com/osukey/osukey.git
synced 2025-08-07 00:23:59 +09:00
Merge pull request #12665 from frenzibyte/stable-frame-sort
This commit is contained in:
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Game.Replays;
|
using osu.Game.Replays;
|
||||||
using osu.Game.Rulesets.Replays;
|
using osu.Game.Rulesets.Replays;
|
||||||
@ -278,6 +279,54 @@ namespace osu.Game.Tests.NonVisual
|
|||||||
setTime(-100, -100);
|
setTime(-100, -100);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestReplayFramesSortStability()
|
||||||
|
{
|
||||||
|
const double repeating_time = 5000;
|
||||||
|
|
||||||
|
// add a collection of frames in shuffled order time-wise; each frame also stores its original index to check stability later.
|
||||||
|
// data is hand-picked and breaks if the unstable List<T>.Sort() is used.
|
||||||
|
// in theory this can still return a false-positive with another unstable algorithm if extremely unlucky,
|
||||||
|
// but there is no conceivable fool-proof way to prevent that anyways.
|
||||||
|
replay.Frames.AddRange(new[]
|
||||||
|
{
|
||||||
|
repeating_time,
|
||||||
|
0,
|
||||||
|
3000,
|
||||||
|
repeating_time,
|
||||||
|
repeating_time,
|
||||||
|
6000,
|
||||||
|
9000,
|
||||||
|
repeating_time,
|
||||||
|
repeating_time,
|
||||||
|
1000,
|
||||||
|
11000,
|
||||||
|
21000,
|
||||||
|
4000,
|
||||||
|
repeating_time,
|
||||||
|
repeating_time,
|
||||||
|
8000,
|
||||||
|
2000,
|
||||||
|
7000,
|
||||||
|
repeating_time,
|
||||||
|
repeating_time,
|
||||||
|
10000
|
||||||
|
}.Select((time, index) => new TestReplayFrame(time, true, index)));
|
||||||
|
|
||||||
|
replay.HasReceivedAllFrames = true;
|
||||||
|
|
||||||
|
// create a new handler with the replay for the sort to be performed.
|
||||||
|
handler = new TestInputHandler(replay);
|
||||||
|
|
||||||
|
// ensure sort stability by checking that the frames with time == repeating_time are sorted in ascending frame index order themselves.
|
||||||
|
var repeatingTimeFramesData = replay.Frames
|
||||||
|
.Cast<TestReplayFrame>()
|
||||||
|
.Where(f => f.Time == repeating_time)
|
||||||
|
.Select(f => f.FrameIndex);
|
||||||
|
|
||||||
|
Assert.That(repeatingTimeFramesData, Is.Ordered.Ascending);
|
||||||
|
}
|
||||||
|
|
||||||
private void setReplayFrames()
|
private void setReplayFrames()
|
||||||
{
|
{
|
||||||
replay.Frames = new List<ReplayFrame>
|
replay.Frames = new List<ReplayFrame>
|
||||||
@ -324,11 +373,13 @@ namespace osu.Game.Tests.NonVisual
|
|||||||
private class TestReplayFrame : ReplayFrame
|
private class TestReplayFrame : ReplayFrame
|
||||||
{
|
{
|
||||||
public readonly bool IsImportant;
|
public readonly bool IsImportant;
|
||||||
|
public readonly int FrameIndex;
|
||||||
|
|
||||||
public TestReplayFrame(double time, bool isImportant = false)
|
public TestReplayFrame(double time, bool isImportant = false, int frameIndex = 0)
|
||||||
: base(time)
|
: base(time)
|
||||||
{
|
{
|
||||||
IsImportant = isImportant;
|
IsImportant = isImportant;
|
||||||
|
FrameIndex = frameIndex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
using osu.Game.Input.Handlers;
|
using osu.Game.Input.Handlers;
|
||||||
using osu.Game.Replays;
|
using osu.Game.Replays;
|
||||||
@ -97,7 +98,7 @@ namespace osu.Game.Rulesets.Replays
|
|||||||
{
|
{
|
||||||
// TODO: This replay frame ordering should be enforced on the Replay type.
|
// TODO: This replay frame ordering should be enforced on the Replay type.
|
||||||
// Currently, the ordering can be broken if the frames are added after this construction.
|
// Currently, the ordering can be broken if the frames are added after this construction.
|
||||||
replay.Frames.Sort((x, y) => x.Time.CompareTo(y.Time));
|
replay.Frames = replay.Frames.OrderBy(f => f.Time).ToList();
|
||||||
|
|
||||||
this.replay = replay;
|
this.replay = replay;
|
||||||
currentFrameIndex = -1;
|
currentFrameIndex = -1;
|
||||||
|
Reference in New Issue
Block a user