diff --git a/osu.Android.props b/osu.Android.props
index f0f16d3763..b7d08fb120 100644
--- a/osu.Android.props
+++ b/osu.Android.props
@@ -52,6 +52,6 @@
-
+
diff --git a/osu.Game.Rulesets.Catch/Objects/BananaShower.cs b/osu.Game.Rulesets.Catch/Objects/BananaShower.cs
index c3488aec11..3a0b5ace53 100644
--- a/osu.Game.Rulesets.Catch/Objects/BananaShower.cs
+++ b/osu.Game.Rulesets.Catch/Objects/BananaShower.cs
@@ -1,6 +1,7 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
+using System.Threading;
using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Objects.Types;
@@ -14,13 +15,13 @@ namespace osu.Game.Rulesets.Catch.Objects
public override Judgement CreateJudgement() => new IgnoreJudgement();
- protected override void CreateNestedHitObjects()
+ protected override void CreateNestedHitObjects(CancellationToken cancellationToken)
{
- base.CreateNestedHitObjects();
- createBananas();
+ base.CreateNestedHitObjects(cancellationToken);
+ createBananas(cancellationToken);
}
- private void createBananas()
+ private void createBananas(CancellationToken cancellationToken)
{
double spacing = Duration;
while (spacing > 100)
@@ -31,6 +32,8 @@ namespace osu.Game.Rulesets.Catch.Objects
for (double i = StartTime; i <= EndTime; i += spacing)
{
+ cancellationToken.ThrowIfCancellationRequested();
+
AddNested(new Banana
{
Samples = Samples,
diff --git a/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs
index 01011645bd..d32595c2e1 100644
--- a/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs
+++ b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs
@@ -3,6 +3,7 @@
using System.Collections.Generic;
using System.Linq;
+using System.Threading;
using osu.Game.Audio;
using osu.Game.Beatmaps;
using osu.Game.Beatmaps.ControlPoints;
@@ -45,9 +46,9 @@ namespace osu.Game.Rulesets.Catch.Objects
TickDistance = scoringDistance / difficulty.SliderTickRate;
}
- protected override void CreateNestedHitObjects()
+ protected override void CreateNestedHitObjects(CancellationToken cancellationToken)
{
- base.CreateNestedHitObjects();
+ base.CreateNestedHitObjects(cancellationToken);
var dropletSamples = Samples.Select(s => new HitSampleInfo
{
@@ -58,7 +59,7 @@ namespace osu.Game.Rulesets.Catch.Objects
SliderEventDescriptor? lastEvent = null;
- foreach (var e in SliderEventGenerator.Generate(StartTime, SpanDuration, Velocity, TickDistance, Path.Distance, this.SpanCount(), LegacyLastTickOffset))
+ foreach (var e in SliderEventGenerator.Generate(StartTime, SpanDuration, Velocity, TickDistance, Path.Distance, this.SpanCount(), LegacyLastTickOffset, cancellationToken))
{
// generate tiny droplets since the last point
if (lastEvent != null)
@@ -73,6 +74,8 @@ namespace osu.Game.Rulesets.Catch.Objects
for (double t = timeBetweenTiny; t < sinceLastTick; t += timeBetweenTiny)
{
+ cancellationToken.ThrowIfCancellationRequested();
+
AddNested(new TinyDroplet
{
StartTime = t + lastEvent.Value.Time,
diff --git a/osu.Game.Rulesets.Mania/Objects/HoldNote.cs b/osu.Game.Rulesets.Mania/Objects/HoldNote.cs
index eea2c31260..e6f722a8a9 100644
--- a/osu.Game.Rulesets.Mania/Objects/HoldNote.cs
+++ b/osu.Game.Rulesets.Mania/Objects/HoldNote.cs
@@ -2,6 +2,7 @@
// See the LICENCE file in the repository root for full licence text.
using System.Collections.Generic;
+using System.Threading;
using osu.Game.Audio;
using osu.Game.Beatmaps;
using osu.Game.Beatmaps.ControlPoints;
@@ -91,11 +92,11 @@ namespace osu.Game.Rulesets.Mania.Objects
tickSpacing = timingPoint.BeatLength / difficulty.SliderTickRate;
}
- protected override void CreateNestedHitObjects()
+ protected override void CreateNestedHitObjects(CancellationToken cancellationToken)
{
- base.CreateNestedHitObjects();
+ base.CreateNestedHitObjects(cancellationToken);
- createTicks();
+ createTicks(cancellationToken);
AddNested(Head = new Note
{
@@ -112,13 +113,15 @@ namespace osu.Game.Rulesets.Mania.Objects
});
}
- private void createTicks()
+ private void createTicks(CancellationToken cancellationToken)
{
if (tickSpacing == 0)
return;
for (double t = StartTime + tickSpacing; t <= EndTime - tickSpacing; t += tickSpacing)
{
+ cancellationToken.ThrowIfCancellationRequested();
+
AddNested(new HoldNoteTick
{
StartTime = t,
diff --git a/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs b/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs
index 9e7dc11fdd..de5c1e54d7 100644
--- a/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs
+++ b/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs
@@ -118,7 +118,8 @@ namespace osu.Game.Rulesets.Osu.Edit
var objects = selectedHitObjects.ToList();
if (objects.Count == 0)
- return createGrid(h => h.StartTime <= EditorClock.CurrentTime);
+ // use accurate time value to give more instantaneous feedback to the user.
+ return createGrid(h => h.StartTime <= EditorClock.CurrentTimeAccurate);
double minTime = objects.Min(h => h.StartTime);
return createGrid(h => h.StartTime < minTime, objects.Count + 1);
diff --git a/osu.Game.Rulesets.Osu/Objects/Slider.cs b/osu.Game.Rulesets.Osu/Objects/Slider.cs
index e5d6c20738..6ba0e1c6aa 100644
--- a/osu.Game.Rulesets.Osu/Objects/Slider.cs
+++ b/osu.Game.Rulesets.Osu/Objects/Slider.cs
@@ -6,6 +6,7 @@ using osu.Game.Rulesets.Objects.Types;
using System.Collections.Generic;
using osu.Game.Rulesets.Objects;
using System.Linq;
+using System.Threading;
using osu.Framework.Caching;
using osu.Game.Audio;
using osu.Game.Beatmaps;
@@ -133,12 +134,12 @@ namespace osu.Game.Rulesets.Osu.Objects
TickDistance = scoringDistance / difficulty.SliderTickRate * TickDistanceMultiplier;
}
- protected override void CreateNestedHitObjects()
+ protected override void CreateNestedHitObjects(CancellationToken cancellationToken)
{
- base.CreateNestedHitObjects();
+ base.CreateNestedHitObjects(cancellationToken);
foreach (var e in
- SliderEventGenerator.Generate(StartTime, SpanDuration, Velocity, TickDistance, Path.Distance, this.SpanCount(), LegacyLastTickOffset))
+ SliderEventGenerator.Generate(StartTime, SpanDuration, Velocity, TickDistance, Path.Distance, this.SpanCount(), LegacyLastTickOffset, cancellationToken))
{
switch (e.Type)
{
diff --git a/osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs b/osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs
index dc2f277e58..7b11bce520 100644
--- a/osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs
@@ -4,6 +4,7 @@
using osu.Game.Rulesets.Objects.Types;
using System;
using System.Collections.Generic;
+using System.Threading;
using osu.Game.Audio;
using osu.Game.Beatmaps;
using osu.Game.Beatmaps.ControlPoints;
@@ -73,17 +74,17 @@ namespace osu.Game.Rulesets.Taiko.Objects
overallDifficulty = difficulty.OverallDifficulty;
}
- protected override void CreateNestedHitObjects()
+ protected override void CreateNestedHitObjects(CancellationToken cancellationToken)
{
- createTicks();
+ createTicks(cancellationToken);
RequiredGoodHits = NestedHitObjects.Count * Math.Min(0.15, 0.05 + 0.10 / 6 * overallDifficulty);
RequiredGreatHits = NestedHitObjects.Count * Math.Min(0.30, 0.10 + 0.20 / 6 * overallDifficulty);
- base.CreateNestedHitObjects();
+ base.CreateNestedHitObjects(cancellationToken);
}
- private void createTicks()
+ private void createTicks(CancellationToken cancellationToken)
{
if (tickSpacing == 0)
return;
@@ -92,6 +93,8 @@ namespace osu.Game.Rulesets.Taiko.Objects
for (double t = StartTime; t < EndTime + tickSpacing / 2; t += tickSpacing)
{
+ cancellationToken.ThrowIfCancellationRequested();
+
AddNested(new DrumRollTick
{
FirstTick = first,
diff --git a/osu.Game.Rulesets.Taiko/Objects/Swell.cs b/osu.Game.Rulesets.Taiko/Objects/Swell.cs
index 2f06066a16..390f8d1f3b 100644
--- a/osu.Game.Rulesets.Taiko/Objects/Swell.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/Swell.cs
@@ -2,6 +2,7 @@
// See the LICENCE file in the repository root for full licence text.
using System;
+using System.Threading;
using osu.Game.Rulesets.Objects.Types;
using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Scoring;
@@ -29,12 +30,15 @@ namespace osu.Game.Rulesets.Taiko.Objects
set => throw new NotSupportedException($"{nameof(Swell)} cannot be a strong hitobject.");
}
- protected override void CreateNestedHitObjects()
+ protected override void CreateNestedHitObjects(CancellationToken cancellationToken)
{
- base.CreateNestedHitObjects();
+ base.CreateNestedHitObjects(cancellationToken);
for (int i = 0; i < RequiredHits; i++)
+ {
+ cancellationToken.ThrowIfCancellationRequested();
AddNested(new SwellTick());
+ }
}
public override Judgement CreateJudgement() => new TaikoSwellJudgement();
diff --git a/osu.Game.Rulesets.Taiko/Objects/TaikoHitObject.cs b/osu.Game.Rulesets.Taiko/Objects/TaikoHitObject.cs
index c41727557b..206bfcfdb2 100644
--- a/osu.Game.Rulesets.Taiko/Objects/TaikoHitObject.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/TaikoHitObject.cs
@@ -1,6 +1,7 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
+using System.Threading;
using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Scoring;
@@ -32,9 +33,9 @@ namespace osu.Game.Rulesets.Taiko.Objects
///
public virtual bool IsStrong { get; set; }
- protected override void CreateNestedHitObjects()
+ protected override void CreateNestedHitObjects(CancellationToken cancellationToken)
{
- base.CreateNestedHitObjects();
+ base.CreateNestedHitObjects(cancellationToken);
if (IsStrong)
AddNested(new StrongHitObject { StartTime = this.GetEndTime() });
diff --git a/osu.Game.Tests/Beatmaps/SliderEventGenerationTest.cs b/osu.Game.Tests/Beatmaps/SliderEventGenerationTest.cs
index 9fba0f1668..6c8133660f 100644
--- a/osu.Game.Tests/Beatmaps/SliderEventGenerationTest.cs
+++ b/osu.Game.Tests/Beatmaps/SliderEventGenerationTest.cs
@@ -16,7 +16,7 @@ namespace osu.Game.Tests.Beatmaps
[Test]
public void TestSingleSpan()
{
- var events = SliderEventGenerator.Generate(start_time, span_duration, 1, span_duration / 2, span_duration, 1, null).ToArray();
+ var events = SliderEventGenerator.Generate(start_time, span_duration, 1, span_duration / 2, span_duration, 1, null, default).ToArray();
Assert.That(events[0].Type, Is.EqualTo(SliderEventType.Head));
Assert.That(events[0].Time, Is.EqualTo(start_time));
@@ -31,7 +31,7 @@ namespace osu.Game.Tests.Beatmaps
[Test]
public void TestRepeat()
{
- var events = SliderEventGenerator.Generate(start_time, span_duration, 1, span_duration / 2, span_duration, 2, null).ToArray();
+ var events = SliderEventGenerator.Generate(start_time, span_duration, 1, span_duration / 2, span_duration, 2, null, default).ToArray();
Assert.That(events[0].Type, Is.EqualTo(SliderEventType.Head));
Assert.That(events[0].Time, Is.EqualTo(start_time));
@@ -52,7 +52,7 @@ namespace osu.Game.Tests.Beatmaps
[Test]
public void TestNonEvenTicks()
{
- var events = SliderEventGenerator.Generate(start_time, span_duration, 1, 300, span_duration, 2, null).ToArray();
+ var events = SliderEventGenerator.Generate(start_time, span_duration, 1, 300, span_duration, 2, null, default).ToArray();
Assert.That(events[0].Type, Is.EqualTo(SliderEventType.Head));
Assert.That(events[0].Time, Is.EqualTo(start_time));
@@ -85,7 +85,7 @@ namespace osu.Game.Tests.Beatmaps
[Test]
public void TestLegacyLastTickOffset()
{
- var events = SliderEventGenerator.Generate(start_time, span_duration, 1, span_duration / 2, span_duration, 1, 100).ToArray();
+ var events = SliderEventGenerator.Generate(start_time, span_duration, 1, span_duration / 2, span_duration, 1, 100, default).ToArray();
Assert.That(events[2].Type, Is.EqualTo(SliderEventType.LegacyLastTick));
Assert.That(events[2].Time, Is.EqualTo(900));
@@ -97,7 +97,7 @@ namespace osu.Game.Tests.Beatmaps
const double velocity = 5;
const double min_distance = velocity * 10;
- var events = SliderEventGenerator.Generate(start_time, span_duration, velocity, velocity, span_duration, 2, 0).ToArray();
+ var events = SliderEventGenerator.Generate(start_time, span_duration, velocity, velocity, span_duration, 2, 0, default).ToArray();
Assert.Multiple(() =>
{
diff --git a/osu.Game.Tests/Visual/Background/TestSceneUserDimBackgrounds.cs b/osu.Game.Tests/Visual/Background/TestSceneUserDimBackgrounds.cs
index 76d0c7a50f..d601f40afe 100644
--- a/osu.Game.Tests/Visual/Background/TestSceneUserDimBackgrounds.cs
+++ b/osu.Game.Tests/Visual/Background/TestSceneUserDimBackgrounds.cs
@@ -68,7 +68,7 @@ namespace osu.Game.Tests.Visual.Background
/// Check if properly triggers the visual settings preview when a user hovers over the visual settings panel.
///
[Test]
- public void PlayerLoaderSettingsHoverTest()
+ public void TestPlayerLoaderSettingsHover()
{
setupUserSettings();
AddStep("Start player loader", () => songSelect.Push(playerLoader = new TestPlayerLoader(player = new LoadBlockingTestPlayer { BlockLoad = true })));
@@ -79,11 +79,9 @@ namespace osu.Game.Tests.Visual.Background
InputManager.MoveMouseTo(playerLoader.ScreenPos);
InputManager.MoveMouseTo(playerLoader.VisualSettingsPos);
});
- waitForDim();
- AddAssert("Screen is dimmed and blur applied", () => songSelect.IsBackgroundDimmed() && songSelect.IsUserBlurApplied());
+ AddUntilStep("Screen is dimmed and blur applied", () => songSelect.IsBackgroundDimmed() && songSelect.IsUserBlurApplied());
AddStep("Stop background preview", () => InputManager.MoveMouseTo(playerLoader.ScreenPos));
- waitForDim();
- AddAssert("Screen is undimmed and user blur removed", () => songSelect.IsBackgroundUndimmed() && playerLoader.IsBlurCorrect());
+ AddUntilStep("Screen is undimmed and user blur removed", () => songSelect.IsBackgroundUndimmed() && playerLoader.IsBlurCorrect());
}
///
@@ -92,20 +90,19 @@ namespace osu.Game.Tests.Visual.Background
/// We need to check that in this scenario, the dim and blur is still properly applied after entering player.
///
[Test]
- public void PlayerLoaderTransitionTest()
+ public void TestPlayerLoaderTransition()
{
performFullSetup();
AddStep("Trigger hover event", () => playerLoader.TriggerOnHover());
AddAssert("Background retained from song select", () => songSelect.IsBackgroundCurrent());
- waitForDim();
- AddAssert("Screen is dimmed and blur applied", () => songSelect.IsBackgroundDimmed() && songSelect.IsUserBlurApplied());
+ AddUntilStep("Screen is dimmed and blur applied", () => songSelect.IsBackgroundDimmed() && songSelect.IsUserBlurApplied());
}
///
/// Make sure the background is fully invisible (Alpha == 0) when the background should be disabled by the storyboard.
///
[Test]
- public void StoryboardBackgroundVisibilityTest()
+ public void TestStoryboardBackgroundVisibility()
{
performFullSetup();
createFakeStoryboard();
@@ -114,52 +111,46 @@ namespace osu.Game.Tests.Visual.Background
player.ReplacesBackground.Value = true;
player.StoryboardEnabled.Value = true;
});
- waitForDim();
- AddAssert("Background is invisible, storyboard is visible", () => songSelect.IsBackgroundInvisible() && player.IsStoryboardVisible);
+ AddUntilStep("Background is invisible, storyboard is visible", () => songSelect.IsBackgroundInvisible() && player.IsStoryboardVisible);
AddStep("Disable Storyboard", () =>
{
player.ReplacesBackground.Value = false;
player.StoryboardEnabled.Value = false;
});
- waitForDim();
- AddAssert("Background is visible, storyboard is invisible", () => songSelect.IsBackgroundVisible() && !player.IsStoryboardVisible);
+ AddUntilStep("Background is visible, storyboard is invisible", () => songSelect.IsBackgroundVisible() && !player.IsStoryboardVisible);
}
///
/// When exiting player, the screen that it suspends/exits to needs to have a fully visible (Alpha == 1) background.
///
[Test]
- public void StoryboardTransitionTest()
+ public void TestStoryboardTransition()
{
performFullSetup();
createFakeStoryboard();
AddStep("Exit to song select", () => player.Exit());
- waitForDim();
- AddAssert("Background is visible", () => songSelect.IsBackgroundVisible());
+ AddUntilStep("Background is visible", () => songSelect.IsBackgroundVisible());
}
///
/// Ensure is properly accepting user-defined visual changes for a background.
///
[Test]
- public void DisableUserDimBackgroundTest()
+ public void TestDisableUserDimBackground()
{
performFullSetup();
- waitForDim();
- AddAssert("Screen is dimmed and blur applied", () => songSelect.IsBackgroundDimmed() && songSelect.IsUserBlurApplied());
+ AddUntilStep("Screen is dimmed and blur applied", () => songSelect.IsBackgroundDimmed() && songSelect.IsUserBlurApplied());
AddStep("Enable user dim", () => songSelect.DimEnabled.Value = false);
- waitForDim();
- AddAssert("Screen is undimmed and user blur removed", () => songSelect.IsBackgroundUndimmed() && songSelect.IsUserBlurDisabled());
+ AddUntilStep("Screen is undimmed and user blur removed", () => songSelect.IsBackgroundUndimmed() && songSelect.IsUserBlurDisabled());
AddStep("Disable user dim", () => songSelect.DimEnabled.Value = true);
- waitForDim();
- AddAssert("Screen is dimmed and blur applied", () => songSelect.IsBackgroundDimmed() && songSelect.IsUserBlurApplied());
+ AddUntilStep("Screen is dimmed and blur applied", () => songSelect.IsBackgroundDimmed() && songSelect.IsUserBlurApplied());
}
///
/// Ensure is properly accepting user-defined visual changes for a storyboard.
///
[Test]
- public void DisableUserDimStoryboardTest()
+ public void TestDisableUserDimStoryboard()
{
performFullSetup();
createFakeStoryboard();
@@ -170,41 +161,36 @@ namespace osu.Game.Tests.Visual.Background
});
AddStep("Enable user dim", () => player.DimmableStoryboard.EnableUserDim.Value = true);
AddStep("Set dim level to 1", () => songSelect.DimLevel.Value = 1f);
- waitForDim();
- AddAssert("Storyboard is invisible", () => !player.IsStoryboardVisible);
+ AddUntilStep("Storyboard is invisible", () => !player.IsStoryboardVisible);
AddStep("Disable user dim", () => player.DimmableStoryboard.EnableUserDim.Value = false);
- waitForDim();
- AddAssert("Storyboard is visible", () => player.IsStoryboardVisible);
+ AddUntilStep("Storyboard is visible", () => player.IsStoryboardVisible);
}
///
/// Check if the visual settings container retains dim and blur when pausing
///
[Test]
- public void PauseTest()
+ public void TestPause()
{
performFullSetup(true);
AddStep("Pause", () => player.Pause());
- waitForDim();
- AddAssert("Screen is dimmed and blur applied", () => songSelect.IsBackgroundDimmed() && songSelect.IsUserBlurApplied());
+ AddUntilStep("Screen is dimmed and blur applied", () => songSelect.IsBackgroundDimmed() && songSelect.IsUserBlurApplied());
AddStep("Unpause", () => player.Resume());
- waitForDim();
- AddAssert("Screen is dimmed and blur applied", () => songSelect.IsBackgroundDimmed() && songSelect.IsUserBlurApplied());
+ AddUntilStep("Screen is dimmed and blur applied", () => songSelect.IsBackgroundDimmed() && songSelect.IsUserBlurApplied());
}
///
/// Check if the visual settings container removes user dim when suspending for
///
[Test]
- public void TransitionTest()
+ public void TestTransition()
{
performFullSetup();
FadeAccessibleResults results = null;
AddStep("Transition to Results", () => player.Push(results =
new FadeAccessibleResults(new ScoreInfo { User = new User { Username = "osu!" } })));
AddUntilStep("Wait for results is current", () => results.IsCurrentScreen());
- waitForDim();
- AddAssert("Screen is undimmed, original background retained", () =>
+ AddUntilStep("Screen is undimmed, original background retained", () =>
songSelect.IsBackgroundUndimmed() && songSelect.IsBackgroundCurrent() && results.IsBlurCorrect());
}
@@ -212,32 +198,27 @@ namespace osu.Game.Tests.Visual.Background
/// Check if background gets undimmed and unblurred when leaving for
///
[Test]
- public void TransitionOutTest()
+ public void TestTransitionOut()
{
performFullSetup();
AddStep("Exit to song select", () => player.Exit());
- waitForDim();
- AddAssert("Screen is undimmed and user blur removed", () => songSelect.IsBackgroundUndimmed() && songSelect.IsBlurCorrect());
+ AddUntilStep("Screen is undimmed and user blur removed", () => songSelect.IsBackgroundUndimmed() && songSelect.IsBlurCorrect());
}
///
/// Check if hovering on the visual settings dialogue after resuming from player still previews the background dim.
///
[Test]
- public void ResumeFromPlayerTest()
+ public void TestResumeFromPlayer()
{
performFullSetup();
AddStep("Move mouse to Visual Settings", () => InputManager.MoveMouseTo(playerLoader.VisualSettingsPos));
AddStep("Resume PlayerLoader", () => player.Restart());
- waitForDim();
- AddAssert("Screen is dimmed and blur applied", () => songSelect.IsBackgroundDimmed() && songSelect.IsUserBlurApplied());
+ AddUntilStep("Screen is dimmed and blur applied", () => songSelect.IsBackgroundDimmed() && songSelect.IsUserBlurApplied());
AddStep("Move mouse to center of screen", () => InputManager.MoveMouseTo(playerLoader.ScreenPos));
- waitForDim();
- AddAssert("Screen is undimmed and user blur removed", () => songSelect.IsBackgroundUndimmed() && playerLoader.IsBlurCorrect());
+ AddUntilStep("Screen is undimmed and user blur removed", () => songSelect.IsBackgroundUndimmed() && playerLoader.IsBlurCorrect());
}
- private void waitForDim() => AddWaitStep("Wait for dim", 5);
-
private void createFakeStoryboard() => AddStep("Create storyboard", () =>
{
player.StoryboardEnabled.Value = false;
diff --git a/osu.Game/Beatmaps/WorkingBeatmap.cs b/osu.Game/Beatmaps/WorkingBeatmap.cs
index bf2b9944a4..8126311cbd 100644
--- a/osu.Game/Beatmaps/WorkingBeatmap.cs
+++ b/osu.Game/Beatmaps/WorkingBeatmap.cs
@@ -129,12 +129,19 @@ namespace osu.Game.Beatmaps
processor?.PreProcess();
// Compute default values for hitobjects, including creating nested hitobjects in-case they're needed
- foreach (var obj in converted.HitObjects)
+ try
{
- if (cancellationSource.IsCancellationRequested)
- throw new BeatmapLoadTimeoutException(BeatmapInfo);
+ foreach (var obj in converted.HitObjects)
+ {
+ if (cancellationSource.IsCancellationRequested)
+ throw new BeatmapLoadTimeoutException(BeatmapInfo);
- obj.ApplyDefaults(converted.ControlPointInfo, converted.BeatmapInfo.BaseDifficulty);
+ obj.ApplyDefaults(converted.ControlPointInfo, converted.BeatmapInfo.BaseDifficulty, cancellationSource.Token);
+ }
+ }
+ catch (OperationCanceledException)
+ {
+ throw new BeatmapLoadTimeoutException(BeatmapInfo);
}
foreach (var mod in mods.OfType())
diff --git a/osu.Game/IO/WrappedStorage.cs b/osu.Game/IO/WrappedStorage.cs
index 646faba9eb..1dd3afbfae 100644
--- a/osu.Game/IO/WrappedStorage.cs
+++ b/osu.Game/IO/WrappedStorage.cs
@@ -69,7 +69,7 @@ namespace osu.Game.IO
public override void DeleteDatabase(string name) => UnderlyingStorage.DeleteDatabase(MutatePath(name));
- public override void OpenInNativeExplorer() => UnderlyingStorage.OpenInNativeExplorer();
+ public override void OpenPathInNativeExplorer(string path) => UnderlyingStorage.OpenPathInNativeExplorer(MutatePath(path));
public override Storage GetStorageForDirectory(string path)
{
diff --git a/osu.Game/Rulesets/Edit/HitObjectComposer.cs b/osu.Game/Rulesets/Edit/HitObjectComposer.cs
index b26284c060..3453bfbf63 100644
--- a/osu.Game/Rulesets/Edit/HitObjectComposer.cs
+++ b/osu.Game/Rulesets/Edit/HitObjectComposer.cs
@@ -52,8 +52,6 @@ namespace osu.Game.Rulesets.Edit
protected readonly Container LayerBelowRuleset = new Container { RelativeSizeAxes = Axes.Both };
- private readonly List layerContainers = new List();
-
private InputManager inputManager;
private RadioButtonCollection toolboxCollection;
@@ -83,17 +81,6 @@ namespace osu.Game.Rulesets.Edit
return;
}
- var layerBelowRuleset = drawableRulesetWrapper.CreatePlayfieldAdjustmentContainer().WithChildren(new Drawable[]
- {
- LayerBelowRuleset,
- new EditorPlayfieldBorder { RelativeSizeAxes = Axes.Both }
- });
-
- var layerAboveRuleset = drawableRulesetWrapper.CreatePlayfieldAdjustmentContainer().WithChild(BlueprintContainer = CreateBlueprintContainer());
-
- layerContainers.Add(layerBelowRuleset);
- layerContainers.Add(layerAboveRuleset);
-
InternalChild = new GridContainer
{
RelativeSizeAxes = Axes.Both,
@@ -117,9 +104,16 @@ namespace osu.Game.Rulesets.Edit
RelativeSizeAxes = Axes.Both,
Children = new Drawable[]
{
- layerBelowRuleset,
+ // layers below playfield
+ drawableRulesetWrapper.CreatePlayfieldAdjustmentContainer().WithChildren(new Drawable[]
+ {
+ LayerBelowRuleset,
+ new EditorPlayfieldBorder { RelativeSizeAxes = Axes.Both }
+ }),
drawableRulesetWrapper,
- layerAboveRuleset
+ // layers above playfield
+ drawableRulesetWrapper.CreatePlayfieldAdjustmentContainer()
+ .WithChild(BlueprintContainer = CreateBlueprintContainer())
}
}
},
@@ -163,19 +157,6 @@ namespace osu.Game.Rulesets.Edit
inputManager = GetContainingInputManager();
}
- protected override void UpdateAfterChildren()
- {
- base.UpdateAfterChildren();
-
- layerContainers.ForEach(l =>
- {
- l.Anchor = drawableRulesetWrapper.Playfield.Anchor;
- l.Origin = drawableRulesetWrapper.Playfield.Origin;
- l.Position = drawableRulesetWrapper.Playfield.Position;
- l.Size = drawableRulesetWrapper.Playfield.Size;
- });
- }
-
private void selectionChanged(object sender, NotifyCollectionChangedEventArgs changedArgs)
{
if (EditorBeatmap.SelectedHitObjects.Any())
@@ -219,7 +200,7 @@ namespace osu.Game.Rulesets.Edit
EditorBeatmap.Add(hitObject);
if (EditorClock.CurrentTime < hitObject.StartTime)
- EditorClock.Seek(hitObject.StartTime);
+ EditorClock.SeekTo(hitObject.StartTime);
}
}
diff --git a/osu.Game/Rulesets/Edit/PlacementBlueprint.cs b/osu.Game/Rulesets/Edit/PlacementBlueprint.cs
index 3541a78faa..bb89ba8311 100644
--- a/osu.Game/Rulesets/Edit/PlacementBlueprint.cs
+++ b/osu.Game/Rulesets/Edit/PlacementBlueprint.cs
@@ -1,6 +1,7 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
+using System.Threading;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
@@ -94,7 +95,7 @@ namespace osu.Game.Rulesets.Edit
}
///
- /// Invokes ,
+ /// Invokes ,
/// refreshing and parameters for the .
///
protected void ApplyDefaultsToHitObject() => HitObject.ApplyDefaults(beatmap.Value.Beatmap.ControlPointInfo, beatmap.Value.Beatmap.BeatmapInfo.BaseDifficulty);
diff --git a/osu.Game/Rulesets/Objects/HitObject.cs b/osu.Game/Rulesets/Objects/HitObject.cs
index cffbdbae08..6f9053d7cb 100644
--- a/osu.Game/Rulesets/Objects/HitObject.cs
+++ b/osu.Game/Rulesets/Objects/HitObject.cs
@@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
+using System.Threading;
using JetBrains.Annotations;
using Newtonsoft.Json;
using osu.Framework.Bindables;
@@ -99,7 +100,8 @@ namespace osu.Game.Rulesets.Objects
///
/// The control points.
/// The difficulty settings to use.
- public void ApplyDefaults(ControlPointInfo controlPointInfo, BeatmapDifficulty difficulty)
+ /// The cancellation token.
+ public void ApplyDefaults(ControlPointInfo controlPointInfo, BeatmapDifficulty difficulty, CancellationToken cancellationToken = default)
{
ApplyDefaultsToSelf(controlPointInfo, difficulty);
@@ -108,7 +110,7 @@ namespace osu.Game.Rulesets.Objects
nestedHitObjects.Clear();
- CreateNestedHitObjects();
+ CreateNestedHitObjects(cancellationToken);
if (this is IHasComboInformation hasCombo)
{
@@ -122,7 +124,7 @@ namespace osu.Game.Rulesets.Objects
nestedHitObjects.Sort((h1, h2) => h1.StartTime.CompareTo(h2.StartTime));
foreach (var h in nestedHitObjects)
- h.ApplyDefaults(controlPointInfo, difficulty);
+ h.ApplyDefaults(controlPointInfo, difficulty, cancellationToken);
DefaultsApplied?.Invoke(this);
}
@@ -136,6 +138,14 @@ namespace osu.Game.Rulesets.Objects
HitWindows?.SetDifficulty(difficulty.OverallDifficulty);
}
+ protected virtual void CreateNestedHitObjects(CancellationToken cancellationToken)
+ {
+ // ReSharper disable once MethodSupportsCancellation (https://youtrack.jetbrains.com/issue/RIDER-44520)
+#pragma warning disable 618
+ CreateNestedHitObjects();
+#pragma warning restore 618
+ }
+
protected virtual void CreateNestedHitObjects()
{
}
diff --git a/osu.Game/Rulesets/Objects/SliderEventGenerator.cs b/osu.Game/Rulesets/Objects/SliderEventGenerator.cs
index e9ee3833b7..6df0041e7a 100644
--- a/osu.Game/Rulesets/Objects/SliderEventGenerator.cs
+++ b/osu.Game/Rulesets/Objects/SliderEventGenerator.cs
@@ -4,13 +4,22 @@
using System;
using System.Collections.Generic;
using System.Linq;
+using System.Threading;
namespace osu.Game.Rulesets.Objects
{
public static class SliderEventGenerator
{
+ [Obsolete("Use the overload with cancellation support instead.")] // can be removed 20201115
public static IEnumerable Generate(double startTime, double spanDuration, double velocity, double tickDistance, double totalDistance, int spanCount,
double? legacyLastTickOffset)
+ {
+ return Generate(startTime, spanDuration, velocity, tickDistance, totalDistance, spanCount, legacyLastTickOffset, default);
+ }
+
+ // ReSharper disable once MethodOverloadWithOptionalParameter
+ public static IEnumerable Generate(double startTime, double spanDuration, double velocity, double tickDistance, double totalDistance, int spanCount,
+ double? legacyLastTickOffset, CancellationToken cancellationToken = default)
{
// A very lenient maximum length of a slider for ticks to be generated.
// This exists for edge cases such as /b/1573664 where the beatmap has been edited by the user, and should never be reached in normal usage.
@@ -37,7 +46,7 @@ namespace osu.Game.Rulesets.Objects
var spanStartTime = startTime + span * spanDuration;
var reversed = span % 2 == 1;
- var ticks = generateTicks(span, spanStartTime, spanDuration, reversed, length, tickDistance, minDistanceFromEnd);
+ var ticks = generateTicks(span, spanStartTime, spanDuration, reversed, length, tickDistance, minDistanceFromEnd, cancellationToken);
if (reversed)
{
@@ -108,12 +117,15 @@ namespace osu.Game.Rulesets.Objects
/// The length of the path.
/// The distance between each tick.
/// The distance from the end of the path at which ticks are not allowed to be added.
+ /// The cancellation token.
/// A for each tick. If is true, the ticks will be returned in reverse-StartTime order.
private static IEnumerable generateTicks(int spanIndex, double spanStartTime, double spanDuration, bool reversed, double length, double tickDistance,
- double minDistanceFromEnd)
+ double minDistanceFromEnd, CancellationToken cancellationToken = default)
{
for (var d = tickDistance; d <= length; d += tickDistance)
{
+ cancellationToken.ThrowIfCancellationRequested();
+
if (d >= length - minDistanceFromEnd)
break;
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 82581dfc56..9e9ac93d23 100644
--- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/MarkerPart.cs
+++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/MarkerPart.cs
@@ -58,7 +58,7 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts
return;
float markerPos = Math.Clamp(ToLocalSpace(screenPosition).X, 0, DrawWidth);
- editorClock.Seek(markerPos / DrawWidth * editorClock.TrackLength);
+ editorClock.SeekTo(markerPos / DrawWidth * editorClock.TrackLength);
});
}
diff --git a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs
index fba7671fca..cc417bbb10 100644
--- a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs
+++ b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs
@@ -143,7 +143,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
if (clickedBlueprint == null)
return false;
- editorClock?.Seek(clickedBlueprint.HitObject.StartTime);
+ editorClock?.SeekTo(clickedBlueprint.HitObject.StartTime);
return true;
}
diff --git a/osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs b/osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs
index 764eae1056..9ecda9fdb8 100644
--- a/osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs
+++ b/osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs
@@ -244,14 +244,21 @@ namespace osu.Game.Screens.Edit.Compose.Components
#region Context Menu
- public virtual MenuItem[] ContextMenuItems
+ public MenuItem[] ContextMenuItems
{
get
{
if (!selectedBlueprints.Any(b => b.IsHovered))
return Array.Empty