From bf6815b2a7496042bf63538349eaf048594c1a25 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 26 Feb 2019 18:02:24 +0900 Subject: [PATCH 01/11] Fix OsuGame test case not working --- osu.Game.Tests/Visual/TestCaseOsuGame.cs | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseOsuGame.cs b/osu.Game.Tests/Visual/TestCaseOsuGame.cs index c527bce683..9e649b92e4 100644 --- a/osu.Game.Tests/Visual/TestCaseOsuGame.cs +++ b/osu.Game.Tests/Visual/TestCaseOsuGame.cs @@ -4,10 +4,10 @@ using System; using System.Collections.Generic; using NUnit.Framework; +using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Shapes; -using osu.Framework.Screens; -using osu.Game.Screens; +using osu.Framework.Platform; using osu.Game.Screens.Menu; using osuTK.Graphics; @@ -21,8 +21,12 @@ namespace osu.Game.Tests.Visual typeof(OsuLogo), }; - public TestCaseOsuGame() + [BackgroundDependencyLoader] + private void load(GameHost host) { + OsuGame game = new OsuGame(); + game.SetHost(host); + Children = new Drawable[] { new Box @@ -30,10 +34,7 @@ namespace osu.Game.Tests.Visual RelativeSizeAxes = Axes.Both, Colour = Color4.Black, }, - new ScreenStack(new Loader()) - { - RelativeSizeAxes = Axes.Both, - } + game }; } } From 5b4319a80f3d35d3be052231acc95b257725b7e0 Mon Sep 17 00:00:00 2001 From: Joehu Date: Tue, 26 Feb 2019 21:01:28 -0800 Subject: [PATCH 02/11] Fix home button being cancelled by mod select again --- osu.Game/Screens/Select/SongSelect.cs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 5ecbaf8d1f..de0ead3b7a 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -512,12 +512,6 @@ namespace osu.Game.Screens.Select if (base.OnExiting(next)) return true; - if (ModSelect.State == Visibility.Visible) - { - ModSelect.Hide(); - return true; - } - beatmapInfoWedge.State = Visibility.Hidden; this.FadeOut(100); From 8c4a59e57ea48c8b9a0b1845bde8f3ce11d2e4da Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 27 Feb 2019 16:42:09 +0900 Subject: [PATCH 03/11] Fix SquareGraph more --- osu.Game/Screens/Play/SquareGraph.cs | 29 +++++++++++++--------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/osu.Game/Screens/Play/SquareGraph.cs b/osu.Game/Screens/Play/SquareGraph.cs index ad52c31108..aa6a657ed3 100644 --- a/osu.Game/Screens/Play/SquareGraph.cs +++ b/osu.Game/Screens/Play/SquareGraph.cs @@ -12,6 +12,8 @@ using osu.Framework.Graphics.Containers; using osuTK; using osuTK.Graphics; using osu.Framework.Graphics.Shapes; +using osu.Framework.MathUtils; +using osu.Framework.Allocation; namespace osu.Game.Screens.Play { @@ -66,20 +68,16 @@ namespace osu.Game.Screens.Play private Cached layout = new Cached(); - public override bool Invalidate(Invalidation invalidation = Invalidation.All, Drawable source = null, bool shallPropagate = true) - { - if ((invalidation & Invalidation.DrawSize) > 0) - layout.Invalidate(); - return base.Invalidate(invalidation, source, shallPropagate); - } + private float lastDrawWidth; protected override void Update() { base.Update(); - if (!layout.IsValid) + if (values != null && (!layout.IsValid || !Precision.AlmostEquals(lastDrawWidth, DrawWidth, 5))) { recreateGraph(); + lastDrawWidth = DrawWidth; layout.Validate(); } } @@ -203,21 +201,20 @@ namespace osu.Game.Screens.Play } } - public Column() + public Column(float height) { Width = WIDTH; + Height = height; } - protected override void LoadComplete() + [BackgroundDependencyLoader] + private void load() { - for (int r = 0; r < cubeCount; r++) + drawableRows.AddRange(Enumerable.Range(0, (int)cubeCount).Select(r => new Box { - drawableRows.Add(new Box - { - Size = new Vector2(cube_size), - Position = new Vector2(0, r * WIDTH + padding), - }); - } + Size = new Vector2(cube_size), + Position = new Vector2(0, r * WIDTH + padding), + })); Children = drawableRows; From 6f5d4ce2e25a40c354b8cfe4b4e487c1c0b7d377 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 27 Feb 2019 17:01:44 +0900 Subject: [PATCH 04/11] Debounce SquareGraph some more --- osu.Game/Screens/Play/SquareGraph.cs | 109 ++++++++++++++++----------- 1 file changed, 67 insertions(+), 42 deletions(-) diff --git a/osu.Game/Screens/Play/SquareGraph.cs b/osu.Game/Screens/Play/SquareGraph.cs index aa6a657ed3..69f9bff550 100644 --- a/osu.Game/Screens/Play/SquareGraph.cs +++ b/osu.Game/Screens/Play/SquareGraph.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Threading; using osu.Framework; using osu.Framework.Caching; using osu.Framework.Extensions.Color4Extensions; @@ -12,18 +13,19 @@ using osu.Framework.Graphics.Containers; using osuTK; using osuTK.Graphics; using osu.Framework.Graphics.Shapes; -using osu.Framework.MathUtils; using osu.Framework.Allocation; +using osu.Framework.Threading; namespace osu.Game.Screens.Play { - public class SquareGraph : BufferedContainer + public class SquareGraph : Container { - private Column[] columns = { }; + private BufferedContainer columns; - public int ColumnCount => columns.Length; + public int ColumnCount => columns?.Children.Count ?? 0; private int progress; + public int Progress { get { return progress; } @@ -38,6 +40,7 @@ namespace osu.Game.Screens.Play private float[] calculatedValues = { }; // values but adjusted to fit the amount of columns private int[] values; + public int[] Values { get { return values; } @@ -50,6 +53,7 @@ namespace osu.Game.Screens.Play } private Color4 fillColour; + public Color4 FillColour { get { return fillColour; } @@ -61,35 +65,83 @@ namespace osu.Game.Screens.Play } } - public SquareGraph() + public override bool Invalidate(Invalidation invalidation = Invalidation.All, Drawable source = null, bool shallPropagate = true) { - CacheDrawnFrameBuffer = true; + if ((invalidation & Invalidation.DrawSize) > 0) + layout.Invalidate(); + return base.Invalidate(invalidation, source, shallPropagate); } private Cached layout = new Cached(); - private float lastDrawWidth; - protected override void Update() { base.Update(); - if (values != null && (!layout.IsValid || !Precision.AlmostEquals(lastDrawWidth, DrawWidth, 5))) + if (values != null && !layout.IsValid) { - recreateGraph(); - lastDrawWidth = DrawWidth; + schedulerRecreateGraph(); layout.Validate(); } } + private ScheduledDelegate scheduledCreate; + + /// + /// Recreates the entire graph. + /// + private void schedulerRecreateGraph() + { + columns?.FadeOut(500, Easing.OutQuint).Expire(); + + scheduledCreate?.Cancel(); + scheduledCreate = Scheduler.AddDelayed(recreateGraph, 500); + } + + private CancellationTokenSource cts; + + private void recreateGraph() + { + var newColumns = new BufferedContainer + { + CacheDrawnFrameBuffer = true, + RelativeSizeAxes = Axes.Both, + }; + + for (float x = 0; x < DrawWidth; x += Column.WIDTH) + { + newColumns.Add(new Column(DrawHeight) + { + LitColour = fillColour, + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + Position = new Vector2(x, 0), + State = ColumnState.Dimmed, + }); + } + + cts?.Cancel(); + cts = new CancellationTokenSource(); + + LoadComponentAsync(newColumns, c => + { + Child = columns = c; + columns.FadeInFromZero(500, Easing.OutQuint); + + recalculateValues(); + redrawFilled(); + redrawProgress(); + }, cts.Token); + } + /// /// Redraws all the columns to match their lit/dimmed state. /// private void redrawProgress() { - for (int i = 0; i < columns.Length; i++) + for (int i = 0; i < ColumnCount; i++) columns[i].State = i <= progress ? ColumnState.Lit : ColumnState.Dimmed; - ForceRedraw(); + columns?.ForceRedraw(); } /// @@ -99,7 +151,7 @@ namespace osu.Game.Screens.Play { for (int i = 0; i < ColumnCount; i++) columns[i].Filled = calculatedValues.ElementAtOrDefault(i); - ForceRedraw(); + columns?.ForceRedraw(); } /// @@ -128,34 +180,6 @@ namespace osu.Game.Screens.Play calculatedValues = newValues.ToArray(); } - /// - /// Recreates the entire graph. - /// - private void recreateGraph() - { - var newColumns = new List(); - - for (float x = 0; x < DrawWidth; x += Column.WIDTH) - { - newColumns.Add(new Column - { - LitColour = fillColour, - Anchor = Anchor.BottomLeft, - Origin = Anchor.BottomLeft, - Height = DrawHeight, - Position = new Vector2(x, 0), - State = ColumnState.Dimmed, - }); - } - - columns = newColumns.ToArray(); - Children = columns; - - recalculateValues(); - redrawFilled(); - redrawProgress(); - } - public class Column : Container, IStateful { protected readonly Color4 EmptyColour = Color4.White.Opacity(20); @@ -172,6 +196,7 @@ namespace osu.Game.Screens.Play private readonly List drawableRows = new List(); private float filled; + public float Filled { get { return filled; } From 43a1df6e5c61a46f322d8f3404c9ad614c68560b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 27 Feb 2019 17:30:20 +0900 Subject: [PATCH 05/11] Inline cancellation token source creation --- osu.Game/Screens/Play/SquareGraph.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/osu.Game/Screens/Play/SquareGraph.cs b/osu.Game/Screens/Play/SquareGraph.cs index 69f9bff550..4ba390c165 100644 --- a/osu.Game/Screens/Play/SquareGraph.cs +++ b/osu.Game/Screens/Play/SquareGraph.cs @@ -121,7 +121,6 @@ namespace osu.Game.Screens.Play } cts?.Cancel(); - cts = new CancellationTokenSource(); LoadComponentAsync(newColumns, c => { @@ -131,7 +130,7 @@ namespace osu.Game.Screens.Play recalculateValues(); redrawFilled(); redrawProgress(); - }, cts.Token); + }, (cts = new CancellationTokenSource()).Token); } /// From 3af7d4939c58ab4703f2385aa1d55cb84a8d3647 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 27 Feb 2019 19:11:09 +0900 Subject: [PATCH 06/11] Add debounce testing --- osu.Game.Tests/Visual/TestCaseSongProgress.cs | 32 ++++++++++++++++--- osu.Game/Screens/Play/SquareGraph.cs | 21 +++++------- 2 files changed, 36 insertions(+), 17 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseSongProgress.cs b/osu.Game.Tests/Visual/TestCaseSongProgress.cs index 9ce33f21d6..9a0050eaa8 100644 --- a/osu.Game.Tests/Visual/TestCaseSongProgress.cs +++ b/osu.Game.Tests/Visual/TestCaseSongProgress.cs @@ -15,7 +15,7 @@ namespace osu.Game.Tests.Visual public class TestCaseSongProgress : OsuTestCase { private readonly SongProgress progress; - private readonly SongProgressGraph graph; + private readonly TestSongProgressGraph graph; private readonly StopwatchClock clock; @@ -31,7 +31,7 @@ namespace osu.Game.Tests.Visual Origin = Anchor.BottomLeft, }); - Add(graph = new SongProgressGraph + Add(graph = new TestSongProgressGraph { RelativeSizeAxes = Axes.X, Height = 200, @@ -39,13 +39,24 @@ namespace osu.Game.Tests.Visual Origin = Anchor.TopLeft, }); + AddWaitStep(5); + AddAssert("ensure not created", () => graph.CreationCount == 0); + + AddStep("display values", displayNewValues); + AddWaitStep(5); + AddUntilStep(() => graph.CreationCount == 1, "wait for creation count"); + AddStep("Toggle Bar", () => progress.AllowSeeking = !progress.AllowSeeking); AddWaitStep(5); + AddUntilStep(() => graph.CreationCount == 1, "wait for creation count"); + AddStep("Toggle Bar", () => progress.AllowSeeking = !progress.AllowSeeking); - AddWaitStep(2); + AddWaitStep(5); + AddUntilStep(() => graph.CreationCount == 1, "wait for creation count"); AddRepeatStep("New Values", displayNewValues, 5); - displayNewValues(); + AddWaitStep(5); + AddAssert("ensure debounced", () => graph.CreationCount == 2); } private void displayNewValues() @@ -60,5 +71,18 @@ namespace osu.Game.Tests.Visual progress.AudioClock = clock; progress.OnSeek = pos => clock.Seek(pos); } + + + private class TestSongProgressGraph : SongProgressGraph + { + public int CreationCount { get; private set; } + + protected override void RecreateGraph() + { + base.RecreateGraph(); + CreationCount++; + } + + } } } diff --git a/osu.Game/Screens/Play/SquareGraph.cs b/osu.Game/Screens/Play/SquareGraph.cs index 4ba390c165..15102edc42 100644 --- a/osu.Game/Screens/Play/SquareGraph.cs +++ b/osu.Game/Screens/Play/SquareGraph.cs @@ -73,6 +73,7 @@ namespace osu.Game.Screens.Play } private Cached layout = new Cached(); + private ScheduledDelegate scheduledCreate; protected override void Update() { @@ -80,27 +81,21 @@ namespace osu.Game.Screens.Play if (values != null && !layout.IsValid) { - schedulerRecreateGraph(); + columns?.FadeOut(500, Easing.OutQuint).Expire(); + + scheduledCreate?.Cancel(); + scheduledCreate = Scheduler.AddDelayed(RecreateGraph, 500); + layout.Validate(); } } - private ScheduledDelegate scheduledCreate; + private CancellationTokenSource cts; /// /// Recreates the entire graph. /// - private void schedulerRecreateGraph() - { - columns?.FadeOut(500, Easing.OutQuint).Expire(); - - scheduledCreate?.Cancel(); - scheduledCreate = Scheduler.AddDelayed(recreateGraph, 500); - } - - private CancellationTokenSource cts; - - private void recreateGraph() + protected virtual void RecreateGraph() { var newColumns = new BufferedContainer { From 9f8d03e1b69a42fdbfe6fe235c8cc44aba471ad3 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 27 Feb 2019 21:03:35 +0900 Subject: [PATCH 07/11] Remove excess newlines --- osu.Game.Tests/Visual/TestCaseSongProgress.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseSongProgress.cs b/osu.Game.Tests/Visual/TestCaseSongProgress.cs index 9a0050eaa8..9845df7461 100644 --- a/osu.Game.Tests/Visual/TestCaseSongProgress.cs +++ b/osu.Game.Tests/Visual/TestCaseSongProgress.cs @@ -72,7 +72,6 @@ namespace osu.Game.Tests.Visual progress.OnSeek = pos => clock.Seek(pos); } - private class TestSongProgressGraph : SongProgressGraph { public int CreationCount { get; private set; } @@ -82,7 +81,6 @@ namespace osu.Game.Tests.Visual base.RecreateGraph(); CreationCount++; } - } } } From 7fa4262207443aa6bcf45ff5b2323eb498d9d77e Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 27 Feb 2019 21:04:14 +0900 Subject: [PATCH 08/11] Clear delegate list rather than relying on unbinds --- osu.Game/Skinning/LocalSkinOverrideContainer.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/osu.Game/Skinning/LocalSkinOverrideContainer.cs b/osu.Game/Skinning/LocalSkinOverrideContainer.cs index 36e95f4038..cd332ed629 100644 --- a/osu.Game/Skinning/LocalSkinOverrideContainer.cs +++ b/osu.Game/Skinning/LocalSkinOverrideContainer.cs @@ -96,6 +96,9 @@ namespace osu.Game.Skinning protected override void Dispose(bool isDisposing) { + // Must be done before base.Dispose() + SourceChanged = null; + base.Dispose(isDisposing); if (fallbackSource != null) From 42442edf5a2fa3d5a3881adb609ff5c08314011a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 27 Feb 2019 22:41:46 +0900 Subject: [PATCH 09/11] Update framework --- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index f464dafd3f..82c23fc491 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -16,7 +16,7 @@ - + diff --git a/osu.iOS.props b/osu.iOS.props index bf38335e0c..f95f42d933 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -105,8 +105,8 @@ - - + + From 0faf83f7d129edfe6d90d0602b1e96afccdd6b20 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 27 Feb 2019 23:30:13 +0900 Subject: [PATCH 10/11] Fix nullref in tests --- osu.Game/Overlays/Direct/DownloadTrackingComposite.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Direct/DownloadTrackingComposite.cs b/osu.Game/Overlays/Direct/DownloadTrackingComposite.cs index 58be491daf..e37156b39d 100644 --- a/osu.Game/Overlays/Direct/DownloadTrackingComposite.cs +++ b/osu.Game/Overlays/Direct/DownloadTrackingComposite.cs @@ -63,8 +63,11 @@ namespace osu.Game.Overlays.Direct { base.Dispose(isDisposing); - beatmaps.BeatmapDownloadBegan -= attachDownload; - beatmaps.ItemAdded -= setAdded; + if (beatmaps != null) + { + beatmaps.BeatmapDownloadBegan -= attachDownload; + beatmaps.ItemAdded -= setAdded; + } State.UnbindAll(); From 43b02212cef02528437b950deb9eb0bb41cece9c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 28 Feb 2019 12:24:56 +0900 Subject: [PATCH 11/11] Add disposal check in single file load path --- osu.Game/OsuGame.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 9f6adc373c..59b7120d95 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -626,6 +626,10 @@ namespace osu.Game try { Logger.Log($"Loading {d}...", level: LogLevel.Debug); + + if (IsDisposed) + return; + await LoadComponentAsync(d, add); Logger.Log($"Loaded {d}!", level: LogLevel.Debug); }