From 853836a48bb8dd232e94d3398977a74d0f5d9b7d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 30 Dec 2025 23:16:08 +0900 Subject: [PATCH] Fix editor seeks not being debounced enough Could lead to huge slowdowns when running multi-threaded and performing a long drag. --- .../Timelines/Summary/Parts/MarkerPart.cs | 22 +++++++++++++------ 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/MarkerPart.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/MarkerPart.cs index d3d5de389e..1fedd6f589 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/MarkerPart.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/MarkerPart.cs @@ -63,16 +63,24 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts /// Whether the seek should be instant (drag end, mouse button press) or debounced (drag in progress). private void seekToPosition(Vector2 screenPosition, bool instant) { - float markerPos = Math.Clamp(ToLocalSpace(screenPosition).X, 0, DrawWidth); - double seekDestination = markerPos / DrawWidth * editorClock.TrackLength; - marker.X = (float)seekDestination; + // Debounce seeks to ensure we only run one per update frame at most. + // + // Without this, we could end up seeking 1000+ times per second, leading to + // unexpected performance overheads as the editor tries to prepare for displaying + // each of the destinations. + Scheduler.AddOnce(data => + { + float markerPos = Math.Clamp(ToLocalSpace(data.screenPosition).X, 0, DrawWidth); + double seekDestination = markerPos / DrawWidth * editorClock.TrackLength; + marker.X = (float)seekDestination; - if (editorClock.IsRunning && !instant && lastSeekTime != null && Time.Current - lastSeekTime < NowPlayingOverlay.TRACK_DRAG_SEEK_DEBOUNCE) - return; + if (editorClock.IsRunning && !data.instant && lastSeekTime != null && Time.Current - lastSeekTime < NowPlayingOverlay.TRACK_DRAG_SEEK_DEBOUNCE) + return; - editorClock.Seek(seekDestination); + editorClock.Seek(seekDestination); - lastSeekTime = instant ? null : Time.Current; + lastSeekTime = data.instant ? null : Time.Current; + }, (screenPosition, instant)); } protected override void Update()