From 39fb5712f1a331720014ee5f8a62ca2261ba4741 Mon Sep 17 00:00:00 2001 From: David Zhao Date: Thu, 9 May 2019 15:31:37 +0900 Subject: [PATCH 1/8] Only combo-incrementing results add to result count --- osu.Game/Rulesets/Scoring/ScoreProcessor.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs index 0ca92a8861..6beb393367 100644 --- a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs +++ b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs @@ -314,11 +314,11 @@ namespace osu.Game.Rulesets.Scoring JudgedHits++; - if (result.Type != HitResult.None) - scoreResultCounts[result.Type] = scoreResultCounts.GetOrDefault(result.Type) + 1; - if (result.Judgement.AffectsCombo) { + if (result.Type != HitResult.None) + scoreResultCounts[result.Type] = scoreResultCounts.GetOrDefault(result.Type) + 1; + switch (result.Type) { case HitResult.None: From b0e34d86d5016cb069a388dfe187decd0502a890 Mon Sep 17 00:00:00 2001 From: David Zhao Date: Thu, 9 May 2019 16:16:20 +0900 Subject: [PATCH 2/8] Subtract a result from count if its been reverted --- osu.Game/Rulesets/Scoring/ScoreProcessor.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs index 6beb393367..2944b784ad 100644 --- a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs +++ b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs @@ -360,6 +360,12 @@ namespace osu.Game.Rulesets.Scoring JudgedHits--; + if (result.Judgement.AffectsCombo) + { + if (result.Type != HitResult.None) + scoreResultCounts[result.Type] = scoreResultCounts.GetOrDefault(result.Type) - 1; + } + if (result.Judgement.IsBonus) { if (result.IsHit) From 66594b7a1b39ce1ec12049e2458a466030ffb5bc Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 9 May 2019 16:36:47 +0900 Subject: [PATCH 3/8] Pass GameplayStartTime to FrameStabilityContainer to allow bypassing prior to start --- .../TestCaseFrameStabilityContainer.cs | 20 +++++++++++++++++++ osu.Game/Rulesets/UI/DrawableRuleset.cs | 2 +- .../Rulesets/UI/FrameStabilityContainer.cs | 8 +++++++- 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestCaseFrameStabilityContainer.cs b/osu.Game.Tests/Visual/Gameplay/TestCaseFrameStabilityContainer.cs index 5cd01fe9a8..584fbe5729 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestCaseFrameStabilityContainer.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestCaseFrameStabilityContainer.cs @@ -73,6 +73,26 @@ namespace osu.Game.Tests.Visual.Gameplay checkFrameCount(2); } + [Test] + public void TestInitialSeekWithGameplayStart() + { + seekManualTo(1000); + createStabilityContainer(30000); + + confirmSeek(1000); + checkFrameCount(0); + + seekManualTo(10000); + confirmSeek(10000); + + checkFrameCount(1); + + seekManualTo(130000); + confirmSeek(130000); + + checkFrameCount(6002); + } + [Test] public void TestInitialSeek() { diff --git a/osu.Game/Rulesets/UI/DrawableRuleset.cs b/osu.Game/Rulesets/UI/DrawableRuleset.cs index 77d1e60b87..75526ae50a 100644 --- a/osu.Game/Rulesets/UI/DrawableRuleset.cs +++ b/osu.Game/Rulesets/UI/DrawableRuleset.cs @@ -144,7 +144,7 @@ namespace osu.Game.Rulesets.UI { InternalChildren = new Drawable[] { - frameStabilityContainer = new FrameStabilityContainer + frameStabilityContainer = new FrameStabilityContainer(GameplayStartTime) { Child = KeyBindingInputManager .WithChild(CreatePlayfieldAdjustmentContainer() diff --git a/osu.Game/Rulesets/UI/FrameStabilityContainer.cs b/osu.Game/Rulesets/UI/FrameStabilityContainer.cs index ad15bcf057..16a5ca4387 100644 --- a/osu.Game/Rulesets/UI/FrameStabilityContainer.cs +++ b/osu.Game/Rulesets/UI/FrameStabilityContainer.cs @@ -17,10 +17,14 @@ namespace osu.Game.Rulesets.UI /// public class FrameStabilityContainer : Container, IHasReplayHandler { - public FrameStabilityContainer() + private readonly double gameplayStartTime; + + public FrameStabilityContainer(double gameplayStartTime = double.MinValue) { RelativeSizeAxes = Axes.Both; gameplayClock = new GameplayClock(framedClock = new FramedClock(manualClock = new ManualClock())); + + this.gameplayStartTime = gameplayStartTime; } private readonly ManualClock manualClock; @@ -116,6 +120,8 @@ namespace osu.Game.Rulesets.UI firstConsumption = false; } + else if (manualClock.CurrentTime < gameplayStartTime) + manualClock.CurrentTime = newProposedTime = Math.Min(gameplayStartTime, newProposedTime); else if (Math.Abs(manualClock.CurrentTime - newProposedTime) > sixty_frame_time * 1.2f) { newProposedTime = newProposedTime > manualClock.CurrentTime From 3bcfc86b9c92c0640d29fda24537bf47c0b26076 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 9 May 2019 16:37:34 +0900 Subject: [PATCH 4/8] Allow custom MaxCatchUpFrames to be specified Also adjusts the default to allow for smoother seeking. --- .../Visual/Gameplay/TestCaseFrameStabilityContainer.cs | 6 +++++- osu.Game/Rulesets/UI/FrameStabilityContainer.cs | 9 ++++++--- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestCaseFrameStabilityContainer.cs b/osu.Game.Tests/Visual/Gameplay/TestCaseFrameStabilityContainer.cs index 584fbe5729..7d6430a2cc 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestCaseFrameStabilityContainer.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestCaseFrameStabilityContainer.cs @@ -103,7 +103,11 @@ namespace osu.Game.Tests.Visual.Gameplay checkFrameCount(0); } - private void createStabilityContainer() => AddStep("create container", () => mainContainer.Child = new FrameStabilityContainer().WithChild(consumer = new ClockConsumingChild())); + private const int max_frames_catchup = 50; + + private void createStabilityContainer(double gameplayStartTime = double.MinValue) => AddStep("create container", () => + mainContainer.Child = new FrameStabilityContainer(gameplayStartTime) { MaxCatchUpFrames = max_frames_catchup } + .WithChild(consumer = new ClockConsumingChild())); private void seekManualTo(double time) => AddStep($"seek manual clock to {time}", () => manualClock.CurrentTime = time); diff --git a/osu.Game/Rulesets/UI/FrameStabilityContainer.cs b/osu.Game/Rulesets/UI/FrameStabilityContainer.cs index 16a5ca4387..9f2bf33628 100644 --- a/osu.Game/Rulesets/UI/FrameStabilityContainer.cs +++ b/osu.Game/Rulesets/UI/FrameStabilityContainer.cs @@ -19,6 +19,11 @@ namespace osu.Game.Rulesets.UI { private readonly double gameplayStartTime; + /// + /// The number of frames (per parent frame) which can be run in an attempt to catch-up to real-time. + /// + public int MaxCatchUpFrames { get; set; } = 5; + public FrameStabilityContainer(double gameplayStartTime = double.MinValue) { RelativeSizeAxes = Axes.Both; @@ -68,8 +73,6 @@ namespace osu.Game.Rulesets.UI private bool isAttached => ReplayInputHandler != null; - private const int max_catch_up_updates_per_frame = 50; - private const double sixty_frame_time = 1000.0 / 60; private bool firstConsumption = true; @@ -81,7 +84,7 @@ namespace osu.Game.Rulesets.UI int loops = 0; - while (validState && requireMoreUpdateLoops && loops++ < max_catch_up_updates_per_frame) + while (validState && requireMoreUpdateLoops && loops++ < MaxCatchUpFrames) { updateClock(); From 9e0af723cca8acca9bb4fad33e60da8ed5cadae8 Mon Sep 17 00:00:00 2001 From: David Zhao Date: Thu, 9 May 2019 18:56:19 +0900 Subject: [PATCH 5/8] Split out affectscombo change --- osu.Game/Rulesets/Scoring/ScoreProcessor.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs index 2944b784ad..4adc29853d 100644 --- a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs +++ b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs @@ -314,11 +314,11 @@ namespace osu.Game.Rulesets.Scoring JudgedHits++; + if (result.Type != HitResult.None) + scoreResultCounts[result.Type] = scoreResultCounts.GetOrDefault(result.Type) + 1; + if (result.Judgement.AffectsCombo) { - if (result.Type != HitResult.None) - scoreResultCounts[result.Type] = scoreResultCounts.GetOrDefault(result.Type) + 1; - switch (result.Type) { case HitResult.None: From 5c096cbc910172aab8948576912acab0da033593 Mon Sep 17 00:00:00 2001 From: David Zhao Date: Thu, 9 May 2019 18:59:00 +0900 Subject: [PATCH 6/8] Revert mirroring condition too --- osu.Game/Rulesets/Scoring/ScoreProcessor.cs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs index 4adc29853d..cf42a70640 100644 --- a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs +++ b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs @@ -360,11 +360,8 @@ namespace osu.Game.Rulesets.Scoring JudgedHits--; - if (result.Judgement.AffectsCombo) - { - if (result.Type != HitResult.None) - scoreResultCounts[result.Type] = scoreResultCounts.GetOrDefault(result.Type) - 1; - } + if (result.Type != HitResult.None) + scoreResultCounts[result.Type] = scoreResultCounts.GetOrDefault(result.Type) - 1; if (result.Judgement.IsBonus) { From d25d39b3154e8bfea6c0b9aa7af31ae9a16b6df6 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 10 May 2019 16:31:09 +0900 Subject: [PATCH 7/8] Add cancellation to storyboard/hitobject loading --- osu.Game/Rulesets/UI/DrawableRuleset.cs | 15 ++++++++++++--- .../Storyboards/Drawables/DrawableStoryboard.cs | 8 +++++++- .../Drawables/DrawableStoryboardLayer.cs | 6 +++++- 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/osu.Game/Rulesets/UI/DrawableRuleset.cs b/osu.Game/Rulesets/UI/DrawableRuleset.cs index 77d1e60b87..7f13c8e469 100644 --- a/osu.Game/Rulesets/UI/DrawableRuleset.cs +++ b/osu.Game/Rulesets/UI/DrawableRuleset.cs @@ -12,6 +12,7 @@ using osu.Game.Rulesets.Objects.Drawables; using System; using System.Collections.Generic; using System.Linq; +using System.Threading; using osu.Framework.Bindables; using osu.Framework.Graphics.Cursor; using osu.Framework.Input; @@ -140,7 +141,7 @@ namespace osu.Game.Rulesets.UI public virtual PlayfieldAdjustmentContainer CreatePlayfieldAdjustmentContainer() => new PlayfieldAdjustmentContainer(); [BackgroundDependencyLoader] - private void load(OsuConfigManager config) + private void load(OsuConfigManager config, CancellationToken cancellationToken) { InternalChildren = new Drawable[] { @@ -163,16 +164,24 @@ namespace osu.Game.Rulesets.UI applyRulesetMods(mods, config); - loadObjects(); + loadObjects(cancellationToken); } /// /// Creates and adds drawable representations of hit objects to the play field. /// - private void loadObjects() + private void loadObjects(CancellationToken cancellationToken) { foreach (TObject h in Beatmap.HitObjects) + { + if (cancellationToken.IsCancellationRequested) + break; + addHitObject(h); + } + + if (cancellationToken.IsCancellationRequested) + return; Playfield.PostProcess(); diff --git a/osu.Game/Storyboards/Drawables/DrawableStoryboard.cs b/osu.Game/Storyboards/Drawables/DrawableStoryboard.cs index 1182cacfc1..6af9d4d7f9 100644 --- a/osu.Game/Storyboards/Drawables/DrawableStoryboard.cs +++ b/osu.Game/Storyboards/Drawables/DrawableStoryboard.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 osuTK; using osu.Framework.Allocation; using osu.Framework.Graphics; @@ -57,7 +58,7 @@ namespace osu.Game.Storyboards.Drawables } [BackgroundDependencyLoader(true)] - private void load(FileStore fileStore, GameplayClock clock) + private void load(FileStore fileStore, GameplayClock clock, CancellationToken cancellationToken) { if (clock != null) Clock = clock; @@ -65,7 +66,12 @@ namespace osu.Game.Storyboards.Drawables dependencies.Cache(new TextureStore(new TextureLoaderStore(fileStore.Store), false, scaleAdjust: 1)); foreach (var layer in Storyboard.Layers) + { + if (cancellationToken.IsCancellationRequested) + break; + Add(layer.CreateDrawable()); + } } private void updateLayerVisibility() diff --git a/osu.Game/Storyboards/Drawables/DrawableStoryboardLayer.cs b/osu.Game/Storyboards/Drawables/DrawableStoryboardLayer.cs index 106ebfaf5d..e82b0df4f4 100644 --- a/osu.Game/Storyboards/Drawables/DrawableStoryboardLayer.cs +++ b/osu.Game/Storyboards/Drawables/DrawableStoryboardLayer.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.Graphics; using osu.Framework.Graphics.Containers; @@ -24,10 +25,13 @@ namespace osu.Game.Storyboards.Drawables } [BackgroundDependencyLoader] - private void load() + private void load(CancellationToken cancellationToken) { foreach (var element in Layer.Elements) { + if (cancellationToken.IsCancellationRequested) + break; + if (element.IsDrawable) AddInternal(element.CreateDrawable()); } From f6dfcc4dcf80673156ceecb3a757a9d0026eaeb9 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 10 May 2019 16:31:22 +0900 Subject: [PATCH 8/8] Remove unnecessary Storyboard disposal --- osu.Game/Storyboards/Storyboard.cs | 28 +--------------------------- 1 file changed, 1 insertion(+), 27 deletions(-) diff --git a/osu.Game/Storyboards/Storyboard.cs b/osu.Game/Storyboards/Storyboard.cs index 0cc753ff7e..3d988c5fe3 100644 --- a/osu.Game/Storyboards/Storyboard.cs +++ b/osu.Game/Storyboards/Storyboard.cs @@ -5,11 +5,10 @@ using osu.Game.Beatmaps; using osu.Game.Storyboards.Drawables; using System.Collections.Generic; using System.Linq; -using System; namespace osu.Game.Storyboards { - public class Storyboard : IDisposable + public class Storyboard { private readonly Dictionary layers = new Dictionary(); public IEnumerable Layers => layers.Values; @@ -56,30 +55,5 @@ namespace osu.Game.Storyboards drawable.Width = drawable.Height * (BeatmapInfo.WidescreenStoryboard ? 16 / 9f : 4 / 3f); return drawable; } - - #region Disposal - - ~Storyboard() - { - Dispose(false); - } - - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - private bool isDisposed; - - protected virtual void Dispose(bool isDisposing) - { - if (isDisposed) - return; - - isDisposed = true; - } - - #endregion } }