mirror of
https://github.com/ppy/osu.git
synced 2025-01-21 08:12:56 +08:00
Add ability to disable mistimed event firings
This commit is contained in:
parent
3197f599bb
commit
b6996d647e
@ -25,7 +25,7 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class TestSceneBeatSyncedContainer : OsuTestScene
|
public class TestSceneBeatSyncedContainer : OsuTestScene
|
||||||
{
|
{
|
||||||
private BeatContainer beatContainer;
|
private TestBeatSyncedContainer beatContainer;
|
||||||
|
|
||||||
private MasterGameplayClockContainer gameplayClockContainer;
|
private MasterGameplayClockContainer gameplayClockContainer;
|
||||||
|
|
||||||
@ -43,7 +43,7 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
{
|
{
|
||||||
gameplayClockContainer = new MasterGameplayClockContainer(Beatmap.Value, 0)
|
gameplayClockContainer = new MasterGameplayClockContainer(Beatmap.Value, 0)
|
||||||
{
|
{
|
||||||
Child = beatContainer = new BeatContainer
|
Child = beatContainer = new TestBeatSyncedContainer
|
||||||
{
|
{
|
||||||
Anchor = Anchor.BottomCentre,
|
Anchor = Anchor.BottomCentre,
|
||||||
Origin = Anchor.BottomCentre,
|
Origin = Anchor.BottomCentre,
|
||||||
@ -55,13 +55,16 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
AddStep("Start playback", () => gameplayClockContainer.Start());
|
AddStep("Start playback", () => gameplayClockContainer.Start());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[TestCase(false)]
|
||||||
public void TestSeekBackDoesntPlayMidBeat()
|
[TestCase(true)]
|
||||||
|
public void TestDisallowMistimedEventFiring(bool allowMistimed)
|
||||||
{
|
{
|
||||||
int? lastBeatIndex = null;
|
int? lastBeatIndex = null;
|
||||||
double? lastActuationTime = null;
|
double? lastActuationTime = null;
|
||||||
TimingControlPoint lastTimingPoint = null;
|
TimingControlPoint lastTimingPoint = null;
|
||||||
|
|
||||||
|
AddStep("set mistimed to disallow", () => beatContainer.AllowMistimedEventFiring = allowMistimed);
|
||||||
|
|
||||||
AddStep("bind event", () =>
|
AddStep("bind event", () =>
|
||||||
{
|
{
|
||||||
beatContainer.NewBeat = (i, timingControlPoint, effectControlPoint, channelAmplitudes) =>
|
beatContainer.NewBeat = (i, timingControlPoint, effectControlPoint, channelAmplitudes) =>
|
||||||
@ -79,7 +82,15 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
});
|
});
|
||||||
|
|
||||||
AddUntilStep("wait for trigger", () => lastBeatIndex != null);
|
AddUntilStep("wait for trigger", () => lastBeatIndex != null);
|
||||||
AddAssert("trigger is near beat length", () => lastActuationTime != null && lastBeatIndex != null && Precision.AlmostEquals(lastTimingPoint.Time + lastBeatIndex.Value * lastTimingPoint.BeatLength, lastActuationTime.Value, 32));
|
|
||||||
|
if (!allowMistimed)
|
||||||
|
{
|
||||||
|
AddAssert("trigger is near beat length", () => lastActuationTime != null && lastBeatIndex != null && Precision.AlmostEquals(lastTimingPoint.Time + lastBeatIndex.Value * lastTimingPoint.BeatLength, lastActuationTime.Value, BeatSyncedContainer.MISTIMED_ALLOWANCE));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AddAssert("trigger is not near beat length", () => lastActuationTime != null && lastBeatIndex != null && !Precision.AlmostEquals(lastTimingPoint.Time + lastBeatIndex.Value * lastTimingPoint.BeatLength, lastActuationTime.Value, BeatSyncedContainer.MISTIMED_ALLOWANCE));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
@ -132,10 +143,16 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
AddAssert("bpm is from beatmap", () => lastBpm != null && Precision.AlmostEquals(lastBpm.Value, 60));
|
AddAssert("bpm is from beatmap", () => lastBpm != null && Precision.AlmostEquals(lastBpm.Value, 60));
|
||||||
}
|
}
|
||||||
|
|
||||||
private class BeatContainer : BeatSyncedContainer
|
private class TestBeatSyncedContainer : BeatSyncedContainer
|
||||||
{
|
{
|
||||||
private const int flash_layer_height = 150;
|
private const int flash_layer_height = 150;
|
||||||
|
|
||||||
|
public new bool AllowMistimedEventFiring
|
||||||
|
{
|
||||||
|
get => base.AllowMistimedEventFiring;
|
||||||
|
set => base.AllowMistimedEventFiring = value;
|
||||||
|
}
|
||||||
|
|
||||||
private readonly InfoString timingPointCount;
|
private readonly InfoString timingPointCount;
|
||||||
private readonly InfoString currentTimingPoint;
|
private readonly InfoString currentTimingPoint;
|
||||||
private readonly InfoString beatCount;
|
private readonly InfoString beatCount;
|
||||||
@ -148,7 +165,7 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
|
|
||||||
private readonly Box flashLayer;
|
private readonly Box flashLayer;
|
||||||
|
|
||||||
public BeatContainer()
|
public TestBeatSyncedContainer()
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.X;
|
RelativeSizeAxes = Axes.X;
|
||||||
AutoSizeAxes = Axes.Y;
|
AutoSizeAxes = Axes.Y;
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using System;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Audio.Track;
|
using osu.Framework.Audio.Track;
|
||||||
@ -35,6 +36,19 @@ namespace osu.Game.Graphics.Containers
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
protected double EarlyActivationMilliseconds;
|
protected double EarlyActivationMilliseconds;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// While this container automatically applied an animation delay (meaning any animations inside a <see cref="OnNewBeat"/> implementation will
|
||||||
|
/// always be correctly timed), the event itself can potentially fire away from the related beat.
|
||||||
|
///
|
||||||
|
/// By setting this to false, cases where the event is to be fired more than <see cref="MISTIMED_ALLOWANCE"/> from the related beat will be skipped.
|
||||||
|
/// </summary>
|
||||||
|
protected bool AllowMistimedEventFiring = true;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The maximum deviance from the actual beat that an <see cref="OnNewBeat"/> can fire when <see cref="AllowMistimedEventFiring"/> is set to false.
|
||||||
|
/// </summary>
|
||||||
|
public const double MISTIMED_ALLOWANCE = 16;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The time in milliseconds until the next beat.
|
/// The time in milliseconds until the next beat.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -145,8 +159,13 @@ namespace osu.Game.Graphics.Containers
|
|||||||
if (timingPoint == lastTimingPoint && beatIndex == lastBeat)
|
if (timingPoint == lastTimingPoint && beatIndex == lastBeat)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// as this event is sometimes used for sound triggers where `BeginDelayedSequence` has no effect, avoid firing it if too far away from the beat.
|
||||||
|
// this can happen after a seek operation.
|
||||||
|
if (AllowMistimedEventFiring || Math.Abs(TimeSinceLastBeat) < MISTIMED_ALLOWANCE)
|
||||||
|
{
|
||||||
using (BeginDelayedSequence(-TimeSinceLastBeat))
|
using (BeginDelayedSequence(-TimeSinceLastBeat))
|
||||||
OnNewBeat(beatIndex, timingPoint, effectPoint, track?.CurrentAmplitudes ?? ChannelAmplitudes.Empty);
|
OnNewBeat(beatIndex, timingPoint, effectPoint, track?.CurrentAmplitudes ?? ChannelAmplitudes.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
lastBeat = beatIndex;
|
lastBeat = beatIndex;
|
||||||
lastTimingPoint = timingPoint;
|
lastTimingPoint = timingPoint;
|
||||||
|
Loading…
Reference in New Issue
Block a user