1
0
mirror of https://github.com/ppy/osu.git synced 2024-11-11 13:37:25 +08:00

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

View File

@ -10,6 +10,7 @@ using System.Linq;
using JetBrains.Annotations; using JetBrains.Annotations;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Bindables; using osu.Framework.Bindables;
using osu.Framework.Threading;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Beatmaps.ControlPoints; using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Beatmaps.Legacy; using osu.Game.Beatmaps.Legacy;
@ -22,6 +23,15 @@ namespace osu.Game.Screens.Edit
{ {
public class EditorBeatmap : TransactionalCommitComponent, IBeatmap, IBeatSnapProvider 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> /// <summary>
/// Invoked when a <see cref="HitObject"/> is added to this <see cref="EditorBeatmap"/>. /// Invoked when a <see cref="HitObject"/> is added to this <see cref="EditorBeatmap"/>.
/// </summary> /// </summary>
@ -225,8 +235,12 @@ namespace osu.Game.Screens.Edit
{ {
// updates are debounced regardless of whether a batch is active. // updates are debounced regardless of whether a batch is active.
batchPendingUpdates.Add(hitObject); batchPendingUpdates.Add(hitObject);
advertiseUpdateInProgress();
} }
private ScheduledDelegate updateCompleteDelegate;
/// <summary> /// <summary>
/// Update all hit objects with potentially changed difficulty or control point data. /// Update all hit objects with potentially changed difficulty or control point data.
/// </summary> /// </summary>
@ -234,6 +248,8 @@ namespace osu.Game.Screens.Edit
{ {
foreach (var h in HitObjects) foreach (var h in HitObjects)
batchPendingUpdates.Add(h); batchPendingUpdates.Add(h);
advertiseUpdateInProgress();
} }
/// <summary> /// <summary>
@ -333,6 +349,15 @@ namespace osu.Game.Screens.Edit
/// </summary> /// </summary>
public void Clear() => RemoveRange(HitObjects.ToArray()); 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 processHitObject(HitObject hitObject) => hitObject.ApplyDefaults(ControlPointInfo, PlayableBeatmap.Difficulty);
private void trackStartTime(HitObject hitObject) private void trackStartTime(HitObject hitObject)