1
0
mirror of https://github.com/ppy/osu.git synced 2024-11-11 09:17:51 +08:00

Fix taiko test scene failing due to missing gameplay clock dependency

`GameplayClock` is inscrutable.

`TestManualClock` is lifted from another test scene because of
`FramedBeatmapClock`'s intensely confusing tendency to not work if it is
given a non-adjustable `ManuelClock` instead.
This commit is contained in:
Bartłomiej Dach 2023-06-20 22:00:02 +02:00
parent 2f77675fe7
commit 29697d4999
No known key found for this signature in database

View File

@ -6,7 +6,6 @@ using System.Linq;
using NUnit.Framework; using NUnit.Framework;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Timing; using osu.Framework.Timing;
using osu.Game.Audio; using osu.Game.Audio;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
@ -17,14 +16,13 @@ using osu.Game.Rulesets.Taiko.Objects.Drawables;
using osu.Game.Rulesets.Taiko.UI; using osu.Game.Rulesets.Taiko.UI;
using osu.Game.Rulesets.UI; using osu.Game.Rulesets.UI;
using osu.Game.Rulesets.UI.Scrolling; using osu.Game.Rulesets.UI.Scrolling;
using osu.Game.Screens.Play;
using osu.Game.Tests.Visual; using osu.Game.Tests.Visual;
namespace osu.Game.Rulesets.Taiko.Tests namespace osu.Game.Rulesets.Taiko.Tests
{ {
public partial class TestSceneDrumSampleTriggerSource : OsuTestScene public partial class TestSceneDrumSampleTriggerSource : OsuTestScene
{ {
private readonly ManualClock manualClock = new ManualClock();
[Cached(typeof(IScrollingInfo))] [Cached(typeof(IScrollingInfo))]
private ScrollingTestContainer.TestScrollingInfo info = new ScrollingTestContainer.TestScrollingInfo private ScrollingTestContainer.TestScrollingInfo info = new ScrollingTestContainer.TestScrollingInfo
{ {
@ -34,23 +32,25 @@ namespace osu.Game.Rulesets.Taiko.Tests
private ScrollingHitObjectContainer hitObjectContainer = null!; private ScrollingHitObjectContainer hitObjectContainer = null!;
private TestDrumSampleTriggerSource triggerSource = null!; private TestDrumSampleTriggerSource triggerSource = null!;
private readonly ManualClock manualClock = new TestManualClock();
private GameplayClockContainer gameplayClock = null!;
[SetUp] [SetUp]
public void SetUp() => Schedule(() => public void SetUp() => Schedule(() =>
{ {
hitObjectContainer = new ScrollingHitObjectContainer(); gameplayClock = new GameplayClockContainer(manualClock)
manualClock.CurrentTime = 0;
Child = new Container
{ {
Clock = new FramedClock(manualClock),
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
Children = new Drawable[] Children = new Drawable[]
{ {
hitObjectContainer, hitObjectContainer = new ScrollingHitObjectContainer(),
triggerSource = new TestDrumSampleTriggerSource(hitObjectContainer) triggerSource = new TestDrumSampleTriggerSource(hitObjectContainer)
} }
}; };
gameplayClock.Reset(0);
hitObjectContainer.Clock = gameplayClock;
Child = gameplayClock;
}); });
[Test] [Test]
@ -75,7 +75,7 @@ namespace osu.Game.Rulesets.Taiko.Tests
checkSound(HitType.Centre, HitSampleInfo.HIT_NORMAL, SampleControlPoint.DEFAULT_BANK); checkSound(HitType.Centre, HitSampleInfo.HIT_NORMAL, SampleControlPoint.DEFAULT_BANK);
checkSound(HitType.Rim, HitSampleInfo.HIT_CLAP, SampleControlPoint.DEFAULT_BANK); checkSound(HitType.Rim, HitSampleInfo.HIT_CLAP, SampleControlPoint.DEFAULT_BANK);
AddStep("seek past hit", () => manualClock.CurrentTime = 200); AddStep("seek past hit", () => gameplayClock.Seek(200));
AddAssert("most valid object is hit", () => triggerSource.GetMostValidObject(), Is.InstanceOf<Hit>); AddAssert("most valid object is hit", () => triggerSource.GetMostValidObject(), Is.InstanceOf<Hit>);
checkSound(HitType.Centre, HitSampleInfo.HIT_NORMAL, SampleControlPoint.DEFAULT_BANK); checkSound(HitType.Centre, HitSampleInfo.HIT_NORMAL, SampleControlPoint.DEFAULT_BANK);
checkSound(HitType.Rim, HitSampleInfo.HIT_CLAP, SampleControlPoint.DEFAULT_BANK); checkSound(HitType.Rim, HitSampleInfo.HIT_CLAP, SampleControlPoint.DEFAULT_BANK);
@ -103,12 +103,67 @@ namespace osu.Game.Rulesets.Taiko.Tests
checkSound(HitType.Centre, HitSampleInfo.HIT_NORMAL, HitSampleInfo.BANK_SOFT); checkSound(HitType.Centre, HitSampleInfo.HIT_NORMAL, HitSampleInfo.BANK_SOFT);
checkSound(HitType.Rim, HitSampleInfo.HIT_CLAP, HitSampleInfo.BANK_SOFT); checkSound(HitType.Rim, HitSampleInfo.HIT_CLAP, HitSampleInfo.BANK_SOFT);
AddStep("seek past hit", () => manualClock.CurrentTime = 200); seekTo(200);
AddAssert("most valid object is hit", () => triggerSource.GetMostValidObject(), Is.InstanceOf<Hit>); AddAssert("most valid object is hit", () => triggerSource.GetMostValidObject(), Is.InstanceOf<Hit>);
checkSound(HitType.Centre, HitSampleInfo.HIT_NORMAL, HitSampleInfo.BANK_SOFT); checkSound(HitType.Centre, HitSampleInfo.HIT_NORMAL, HitSampleInfo.BANK_SOFT);
checkSound(HitType.Rim, HitSampleInfo.HIT_CLAP, HitSampleInfo.BANK_SOFT); checkSound(HitType.Rim, HitSampleInfo.HIT_CLAP, HitSampleInfo.BANK_SOFT);
} }
[Test]
public void TestBetweenHits()
{
Hit first = null!, second = null!;
AddStep("add hit with normal samples", () =>
{
first = new Hit
{
StartTime = 100,
Samples = new List<HitSampleInfo>
{
new HitSampleInfo(HitSampleInfo.HIT_NORMAL)
}
};
first.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty());
var drawableHit = new DrawableHit(first);
hitObjectContainer.Add(drawableHit);
});
AddStep("add hit with soft samples", () =>
{
second = new Hit
{
StartTime = 500,
Samples = new List<HitSampleInfo>
{
new HitSampleInfo(HitSampleInfo.HIT_NORMAL, HitSampleInfo.BANK_SOFT),
new HitSampleInfo(HitSampleInfo.HIT_CLAP, HitSampleInfo.BANK_SOFT)
}
};
second.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty());
var drawableHit = new DrawableHit(second);
hitObjectContainer.Add(drawableHit);
});
AddAssert("most valid object is first hit", () => triggerSource.GetMostValidObject(), () => Is.EqualTo(first));
checkSound(HitType.Centre, HitSampleInfo.HIT_NORMAL, HitSampleInfo.BANK_NORMAL);
checkSound(HitType.Rim, HitSampleInfo.HIT_CLAP, HitSampleInfo.BANK_NORMAL);
seekTo(120);
AddAssert("most valid object is first hit", () => triggerSource.GetMostValidObject(), () => Is.EqualTo(first));
checkSound(HitType.Centre, HitSampleInfo.HIT_NORMAL, HitSampleInfo.BANK_NORMAL);
checkSound(HitType.Rim, HitSampleInfo.HIT_CLAP, HitSampleInfo.BANK_NORMAL);
seekTo(480);
AddAssert("most valid object is second hit", () => triggerSource.GetMostValidObject(), () => Is.EqualTo(second));
checkSound(HitType.Centre, HitSampleInfo.HIT_NORMAL, HitSampleInfo.BANK_SOFT);
checkSound(HitType.Rim, HitSampleInfo.HIT_CLAP, HitSampleInfo.BANK_SOFT);
seekTo(700);
AddAssert("most valid object is second hit", () => triggerSource.GetMostValidObject(), () => Is.EqualTo(second));
checkSound(HitType.Centre, HitSampleInfo.HIT_NORMAL, HitSampleInfo.BANK_SOFT);
checkSound(HitType.Rim, HitSampleInfo.HIT_CLAP, HitSampleInfo.BANK_SOFT);
}
[Test] [Test]
public void TestDrumStrongHit() public void TestDrumStrongHit()
{ {
@ -128,11 +183,11 @@ namespace osu.Game.Rulesets.Taiko.Tests
hitObjectContainer.Add(drawableHit); hitObjectContainer.Add(drawableHit);
}); });
AddAssert("most valid object is strong nested hit", () => triggerSource.GetMostValidObject(), Is.InstanceOf<Hit.StrongNestedHit>); AddAssert("most valid object is nested strong hit", () => triggerSource.GetMostValidObject(), Is.InstanceOf<Hit.StrongNestedHit>);
checkSound(HitType.Centre, HitSampleInfo.HIT_NORMAL, "drum"); checkSound(HitType.Centre, HitSampleInfo.HIT_NORMAL, "drum");
checkSound(HitType.Rim, HitSampleInfo.HIT_CLAP, "drum"); checkSound(HitType.Rim, HitSampleInfo.HIT_CLAP, "drum");
AddStep("seek past hit", () => manualClock.CurrentTime = 200); seekTo(200);
AddAssert("most valid object is hit", () => triggerSource.GetMostValidObject(), Is.InstanceOf<Hit>); AddAssert("most valid object is hit", () => triggerSource.GetMostValidObject(), Is.InstanceOf<Hit>);
checkSound(HitType.Centre, HitSampleInfo.HIT_NORMAL, "drum"); checkSound(HitType.Centre, HitSampleInfo.HIT_NORMAL, "drum");
checkSound(HitType.Rim, HitSampleInfo.HIT_CLAP, "drum"); checkSound(HitType.Rim, HitSampleInfo.HIT_CLAP, "drum");
@ -161,12 +216,12 @@ namespace osu.Game.Rulesets.Taiko.Tests
checkSound(HitType.Centre, HitSampleInfo.HIT_NORMAL, SampleControlPoint.DEFAULT_BANK); checkSound(HitType.Centre, HitSampleInfo.HIT_NORMAL, SampleControlPoint.DEFAULT_BANK);
checkSound(HitType.Rim, HitSampleInfo.HIT_CLAP, SampleControlPoint.DEFAULT_BANK); checkSound(HitType.Rim, HitSampleInfo.HIT_CLAP, SampleControlPoint.DEFAULT_BANK);
AddStep("seek to middle of drum roll", () => manualClock.CurrentTime = 600); seekTo(600);
AddAssert("most valid object is drum roll tick", () => triggerSource.GetMostValidObject(), Is.InstanceOf<DrumRollTick>); AddAssert("most valid object is drum roll tick", () => triggerSource.GetMostValidObject(), Is.InstanceOf<DrumRollTick>);
checkSound(HitType.Centre, HitSampleInfo.HIT_NORMAL, SampleControlPoint.DEFAULT_BANK); checkSound(HitType.Centre, HitSampleInfo.HIT_NORMAL, SampleControlPoint.DEFAULT_BANK);
checkSound(HitType.Rim, HitSampleInfo.HIT_CLAP, SampleControlPoint.DEFAULT_BANK); checkSound(HitType.Rim, HitSampleInfo.HIT_CLAP, SampleControlPoint.DEFAULT_BANK);
AddStep("seek past drum roll", () => manualClock.CurrentTime = 1200); seekTo(1200);
AddAssert("most valid object is drum roll", () => triggerSource.GetMostValidObject(), Is.InstanceOf<DrumRoll>); AddAssert("most valid object is drum roll", () => triggerSource.GetMostValidObject(), Is.InstanceOf<DrumRoll>);
checkSound(HitType.Centre, HitSampleInfo.HIT_NORMAL, SampleControlPoint.DEFAULT_BANK); checkSound(HitType.Centre, HitSampleInfo.HIT_NORMAL, SampleControlPoint.DEFAULT_BANK);
checkSound(HitType.Rim, HitSampleInfo.HIT_CLAP, SampleControlPoint.DEFAULT_BANK); checkSound(HitType.Rim, HitSampleInfo.HIT_CLAP, SampleControlPoint.DEFAULT_BANK);
@ -195,12 +250,12 @@ namespace osu.Game.Rulesets.Taiko.Tests
checkSound(HitType.Centre, HitSampleInfo.HIT_NORMAL, HitSampleInfo.BANK_SOFT); checkSound(HitType.Centre, HitSampleInfo.HIT_NORMAL, HitSampleInfo.BANK_SOFT);
checkSound(HitType.Rim, HitSampleInfo.HIT_CLAP, HitSampleInfo.BANK_SOFT); checkSound(HitType.Rim, HitSampleInfo.HIT_CLAP, HitSampleInfo.BANK_SOFT);
AddStep("seek to middle of drum roll", () => manualClock.CurrentTime = 600); seekTo(600);
AddAssert("most valid object is drum roll tick", () => triggerSource.GetMostValidObject(), Is.InstanceOf<DrumRollTick>); AddAssert("most valid object is drum roll tick", () => triggerSource.GetMostValidObject(), Is.InstanceOf<DrumRollTick>);
checkSound(HitType.Centre, HitSampleInfo.HIT_NORMAL, HitSampleInfo.BANK_SOFT); checkSound(HitType.Centre, HitSampleInfo.HIT_NORMAL, HitSampleInfo.BANK_SOFT);
checkSound(HitType.Rim, HitSampleInfo.HIT_CLAP, HitSampleInfo.BANK_SOFT); checkSound(HitType.Rim, HitSampleInfo.HIT_CLAP, HitSampleInfo.BANK_SOFT);
AddStep("seek past drum roll", () => manualClock.CurrentTime = 1200); seekTo(1200);
AddAssert("most valid object is drum roll", () => triggerSource.GetMostValidObject(), Is.InstanceOf<DrumRoll>); AddAssert("most valid object is drum roll", () => triggerSource.GetMostValidObject(), Is.InstanceOf<DrumRoll>);
checkSound(HitType.Centre, HitSampleInfo.HIT_NORMAL, HitSampleInfo.BANK_SOFT); checkSound(HitType.Centre, HitSampleInfo.HIT_NORMAL, HitSampleInfo.BANK_SOFT);
checkSound(HitType.Rim, HitSampleInfo.HIT_CLAP, HitSampleInfo.BANK_SOFT); checkSound(HitType.Rim, HitSampleInfo.HIT_CLAP, HitSampleInfo.BANK_SOFT);
@ -226,16 +281,16 @@ namespace osu.Game.Rulesets.Taiko.Tests
hitObjectContainer.Add(drawableDrumRoll); hitObjectContainer.Add(drawableDrumRoll);
}); });
AddAssert("most valid object is drum roll tick's nested strong hit", () => triggerSource.GetMostValidObject(), Is.InstanceOf<DrumRollTick.StrongNestedHit>); AddAssert("most valid object is drum roll tick", () => triggerSource.GetMostValidObject(), Is.InstanceOf<DrumRollTick>);
checkSound(HitType.Centre, HitSampleInfo.HIT_NORMAL, "drum"); checkSound(HitType.Centre, HitSampleInfo.HIT_NORMAL, "drum");
checkSound(HitType.Rim, HitSampleInfo.HIT_CLAP, "drum"); checkSound(HitType.Rim, HitSampleInfo.HIT_CLAP, "drum");
AddStep("seek to middle of drum roll", () => manualClock.CurrentTime = 600); seekTo(600);
AddAssert("most valid object is drum roll tick's nested strong hit", () => triggerSource.GetMostValidObject(), Is.InstanceOf<DrumRollTick.StrongNestedHit>); AddAssert("most valid object is drum roll tick", () => triggerSource.GetMostValidObject(), Is.InstanceOf<DrumRollTick>);
checkSound(HitType.Centre, HitSampleInfo.HIT_NORMAL, "drum"); checkSound(HitType.Centre, HitSampleInfo.HIT_NORMAL, "drum");
checkSound(HitType.Rim, HitSampleInfo.HIT_CLAP, "drum"); checkSound(HitType.Rim, HitSampleInfo.HIT_CLAP, "drum");
AddStep("seek past drum roll", () => manualClock.CurrentTime = 1200); seekTo(1200);
AddAssert("most valid object is drum roll", () => triggerSource.GetMostValidObject(), Is.InstanceOf<DrumRoll>); AddAssert("most valid object is drum roll", () => triggerSource.GetMostValidObject(), Is.InstanceOf<DrumRoll>);
checkSound(HitType.Centre, HitSampleInfo.HIT_NORMAL, "drum"); checkSound(HitType.Centre, HitSampleInfo.HIT_NORMAL, "drum");
checkSound(HitType.Rim, HitSampleInfo.HIT_CLAP, "drum"); checkSound(HitType.Rim, HitSampleInfo.HIT_CLAP, "drum");
@ -260,16 +315,16 @@ namespace osu.Game.Rulesets.Taiko.Tests
hitObjectContainer.Add(drawableSwell); hitObjectContainer.Add(drawableSwell);
}); });
AddAssert("most valid object is swell tick", () => triggerSource.GetMostValidObject(), Is.InstanceOf<SwellTick>); AddAssert("most valid object is swell", () => triggerSource.GetMostValidObject(), Is.InstanceOf<Swell>);
checkSound(HitType.Centre, HitSampleInfo.HIT_NORMAL, SampleControlPoint.DEFAULT_BANK); checkSound(HitType.Centre, HitSampleInfo.HIT_NORMAL, SampleControlPoint.DEFAULT_BANK);
checkSound(HitType.Rim, HitSampleInfo.HIT_CLAP, SampleControlPoint.DEFAULT_BANK); checkSound(HitType.Rim, HitSampleInfo.HIT_CLAP, SampleControlPoint.DEFAULT_BANK);
AddStep("seek to middle of swell", () => manualClock.CurrentTime = 600); seekTo(600);
AddAssert("most valid object is swell tick", () => triggerSource.GetMostValidObject(), Is.InstanceOf<SwellTick>); AddAssert("most valid object is swell", () => triggerSource.GetMostValidObject(), Is.InstanceOf<Swell>);
checkSound(HitType.Centre, HitSampleInfo.HIT_NORMAL, SampleControlPoint.DEFAULT_BANK); checkSound(HitType.Centre, HitSampleInfo.HIT_NORMAL, SampleControlPoint.DEFAULT_BANK);
checkSound(HitType.Rim, HitSampleInfo.HIT_CLAP, SampleControlPoint.DEFAULT_BANK); checkSound(HitType.Rim, HitSampleInfo.HIT_CLAP, SampleControlPoint.DEFAULT_BANK);
AddStep("seek past swell", () => manualClock.CurrentTime = 1200); seekTo(1200);
AddAssert("most valid object is swell", () => triggerSource.GetMostValidObject(), Is.InstanceOf<Swell>); AddAssert("most valid object is swell", () => triggerSource.GetMostValidObject(), Is.InstanceOf<Swell>);
checkSound(HitType.Centre, HitSampleInfo.HIT_NORMAL, SampleControlPoint.DEFAULT_BANK); checkSound(HitType.Centre, HitSampleInfo.HIT_NORMAL, SampleControlPoint.DEFAULT_BANK);
checkSound(HitType.Rim, HitSampleInfo.HIT_CLAP, SampleControlPoint.DEFAULT_BANK); checkSound(HitType.Rim, HitSampleInfo.HIT_CLAP, SampleControlPoint.DEFAULT_BANK);
@ -294,16 +349,16 @@ namespace osu.Game.Rulesets.Taiko.Tests
hitObjectContainer.Add(drawableSwell); hitObjectContainer.Add(drawableSwell);
}); });
AddAssert("most valid object is swell tick", () => triggerSource.GetMostValidObject(), Is.InstanceOf<SwellTick>); AddAssert("most valid object is swell", () => triggerSource.GetMostValidObject(), Is.InstanceOf<Swell>);
checkSound(HitType.Centre, HitSampleInfo.HIT_NORMAL, "drum"); checkSound(HitType.Centre, HitSampleInfo.HIT_NORMAL, "drum");
checkSound(HitType.Rim, HitSampleInfo.HIT_CLAP, "drum"); checkSound(HitType.Rim, HitSampleInfo.HIT_CLAP, "drum");
AddStep("seek to middle of swell", () => manualClock.CurrentTime = 600); seekTo(600);
AddAssert("most valid object is swell tick", () => triggerSource.GetMostValidObject(), Is.InstanceOf<SwellTick>); AddAssert("most valid object is swell", () => triggerSource.GetMostValidObject(), Is.InstanceOf<Swell>);
checkSound(HitType.Centre, HitSampleInfo.HIT_NORMAL, "drum"); checkSound(HitType.Centre, HitSampleInfo.HIT_NORMAL, "drum");
checkSound(HitType.Rim, HitSampleInfo.HIT_CLAP, "drum"); checkSound(HitType.Rim, HitSampleInfo.HIT_CLAP, "drum");
AddStep("seek past swell", () => manualClock.CurrentTime = 1200); seekTo(1200);
AddAssert("most valid object is swell", () => triggerSource.GetMostValidObject(), Is.InstanceOf<Swell>); AddAssert("most valid object is swell", () => triggerSource.GetMostValidObject(), Is.InstanceOf<Swell>);
checkSound(HitType.Centre, HitSampleInfo.HIT_NORMAL, "drum"); checkSound(HitType.Centre, HitSampleInfo.HIT_NORMAL, "drum");
checkSound(HitType.Rim, HitSampleInfo.HIT_CLAP, "drum"); checkSound(HitType.Rim, HitSampleInfo.HIT_CLAP, "drum");
@ -316,6 +371,8 @@ namespace osu.Game.Rulesets.Taiko.Tests
AddAssert($"last played sample has {expectedBank} bank", () => triggerSource.LastPlayedSamples!.OfType<HitSampleInfo>().Single().Bank, () => Is.EqualTo(expectedBank)); AddAssert($"last played sample has {expectedBank} bank", () => triggerSource.LastPlayedSamples!.OfType<HitSampleInfo>().Single().Bank, () => Is.EqualTo(expectedBank));
} }
private void seekTo(double time) => AddStep($"seek to {time}", () => gameplayClock.Seek(time));
private partial class TestDrumSampleTriggerSource : DrumSampleTriggerSource private partial class TestDrumSampleTriggerSource : DrumSampleTriggerSource
{ {
public ISampleInfo[]? LastPlayedSamples { get; private set; } public ISampleInfo[]? LastPlayedSamples { get; private set; }
@ -333,5 +390,31 @@ namespace osu.Game.Rulesets.Taiko.Tests
public new HitObject? GetMostValidObject() => base.GetMostValidObject(); public new HitObject? GetMostValidObject() => base.GetMostValidObject();
} }
private class TestManualClock : ManualClock, IAdjustableClock
{
public TestManualClock()
{
IsRunning = true;
}
public void Start() => IsRunning = true;
public void Stop() => IsRunning = false;
public bool Seek(double position)
{
CurrentTime = position;
return true;
}
public void Reset()
{
}
public void ResetSpeedAdjustments()
{
}
}
} }
} }