From ad9a963bd0fa831c30f7a79abf62a797aa087c3f Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Mon, 3 Mar 2025 14:19:19 +0900 Subject: [PATCH 1/3] Exit loop when cancellation requested The following manages to create all hitobjects but proceeds to get stuck in this method: `dotnet run -- difficulty 1607040 -r:2` --- osu.Game/Rulesets/Objects/HitObject.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Rulesets/Objects/HitObject.cs b/osu.Game/Rulesets/Objects/HitObject.cs index 9f980769e2..d9e62ccecb 100644 --- a/osu.Game/Rulesets/Objects/HitObject.cs +++ b/osu.Game/Rulesets/Objects/HitObject.cs @@ -114,6 +114,8 @@ namespace osu.Game.Rulesets.Objects { foreach (HitObject hitObject in nestedHitObjects) { + cancellationToken.ThrowIfCancellationRequested(); + if (hitObject is IHasComboInformation n) { n.ComboIndexBindable.BindTo(hasCombo.ComboIndexBindable); From 52dad09b2011c014b2ec5acb4947aacbc3ba4d90 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Mon, 3 Mar 2025 14:19:38 +0900 Subject: [PATCH 2/3] Cancel slider generation when requested Didn't notice a particular case with this one, just came up as I was looking through code. --- osu.Game/Rulesets/Objects/SliderEventGenerator.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Rulesets/Objects/SliderEventGenerator.cs b/osu.Game/Rulesets/Objects/SliderEventGenerator.cs index f5146d1675..e5e15042ff 100644 --- a/osu.Game/Rulesets/Objects/SliderEventGenerator.cs +++ b/osu.Game/Rulesets/Objects/SliderEventGenerator.cs @@ -46,6 +46,8 @@ namespace osu.Game.Rulesets.Objects for (int span = 0; span < spanCount; span++) { + cancellationToken.ThrowIfCancellationRequested(); + double spanStartTime = startTime + span * spanDuration; bool reversed = span % 2 == 1; From 033952029eecd814a62567c58eeafb5fe3fe5c99 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Mon, 3 Mar 2025 14:46:13 +0900 Subject: [PATCH 3/3] Cancel `ApplyDefaults()` when requested Also didn't notice a particular case here, but if all code passes up until we get to the `foreach (var h in nestedHitObjects)` below, then we could end up stuck here for quite a while. --- osu.Game/Rulesets/Objects/HitObject.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Rulesets/Objects/HitObject.cs b/osu.Game/Rulesets/Objects/HitObject.cs index d9e62ccecb..07e07b25d3 100644 --- a/osu.Game/Rulesets/Objects/HitObject.cs +++ b/osu.Game/Rulesets/Objects/HitObject.cs @@ -104,6 +104,8 @@ namespace osu.Game.Rulesets.Objects /// The cancellation token. public void ApplyDefaults(ControlPointInfo controlPointInfo, IBeatmapDifficultyInfo difficulty, CancellationToken cancellationToken = default) { + cancellationToken.ThrowIfCancellationRequested(); + ApplyDefaultsToSelf(controlPointInfo, difficulty); nestedHitObjects.Clear();