Fix slider ticks playing back at infinite rate while making changes to a slider in the editor

This commit is contained in:
Dean Herbert 2022-08-16 15:26:29 +09:00
parent 26568f7ac9
commit ea50936d71
2 changed files with 31 additions and 13 deletions

View File

@ -225,8 +225,6 @@ namespace osu.Game.Screens.Edit
dependencies.CacheAs(clock);
AddInternal(clock);
clock.SeekingOrStopped.BindValueChanged(_ => updateSampleDisabledState());
// todo: remove caching of this and consume via editorBeatmap?
dependencies.Cache(beatDivisor);
@ -428,7 +426,12 @@ namespace osu.Game.Screens.Edit
protected override void Update()
{
base.Update();
clock.ProcessFrame();
samplePlaybackDisabled.Value = clock.SeekingOrStopped.Value
|| currentScreen is not ComposeScreen
|| editorBeatmap.UpdateInProgress;
}
public bool OnPressed(KeyBindingPressEvent<PlatformAction> e)
@ -822,16 +825,10 @@ namespace osu.Game.Screens.Edit
}
finally
{
updateSampleDisabledState();
rebindClipboardBindables();
}
}
private void updateSampleDisabledState()
{
samplePlaybackDisabled.Value = clock.SeekingOrStopped.Value || !(currentScreen is ComposeScreen);
}
private void seek(UIEvent e, int direction)
{
double amount = e.ShiftPressed ? 4 : 1;
@ -936,11 +933,7 @@ namespace osu.Game.Screens.Edit
protected void SwitchToDifficulty(BeatmapInfo nextBeatmap) => loader?.ScheduleSwitchToExistingDifficulty(nextBeatmap, GetState(nextBeatmap.Ruleset));
private void cancelExit()
{
updateSampleDisabledState();
loader?.CancelPendingDifficultySwitch();
}
private void cancelExit() => loader?.CancelPendingDifficultySwitch();
public double SnapTime(double time, double? referenceTime) => editorBeatmap.SnapTime(time, referenceTime);

View File

@ -10,6 +10,7 @@ using System.Linq;
using JetBrains.Annotations;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Threading;
using osu.Game.Beatmaps;
using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Beatmaps.Legacy;
@ -22,6 +23,15 @@ namespace osu.Game.Screens.Edit
{
public class EditorBeatmap : TransactionalCommitComponent, IBeatmap, IBeatSnapProvider
{
/// <summary>
/// While performing updates on hitobjects, this will momentarily become true.
/// </summary>
/// <remarks>
/// This is intended to be used to avoid performing operations (like playback of samples)
/// while mutating hitobjects.
/// </remarks>
public bool UpdateInProgress { get; private set; }
/// <summary>
/// Invoked when a <see cref="HitObject"/> is added to this <see cref="EditorBeatmap"/>.
/// </summary>
@ -225,8 +235,12 @@ namespace osu.Game.Screens.Edit
{
// updates are debounced regardless of whether a batch is active.
batchPendingUpdates.Add(hitObject);
advertiseUpdateInProgress();
}
private ScheduledDelegate updateCompleteDelegate;
/// <summary>
/// Update all hit objects with potentially changed difficulty or control point data.
/// </summary>
@ -234,6 +248,8 @@ namespace osu.Game.Screens.Edit
{
foreach (var h in HitObjects)
batchPendingUpdates.Add(h);
advertiseUpdateInProgress();
}
/// <summary>
@ -333,6 +349,15 @@ namespace osu.Game.Screens.Edit
/// </summary>
public void Clear() => RemoveRange(HitObjects.ToArray());
private void advertiseUpdateInProgress()
{
UpdateInProgress = true;
// Debounce is arbitrarily high enough to avoid flip-flopping the value each other frame.
updateCompleteDelegate?.Cancel();
updateCompleteDelegate = Scheduler.AddDelayed(() => UpdateInProgress = false, 50);
}
private void processHitObject(HitObject hitObject) => hitObject.ApplyDefaults(ControlPointInfo, PlayableBeatmap.Difficulty);
private void trackStartTime(HitObject hitObject)