diff --git a/osu.Game.Rulesets.Osu/UI/DrawableOsuRuleset.cs b/osu.Game.Rulesets.Osu/UI/DrawableOsuRuleset.cs index 17fffbd974..d185d7d4c9 100644 --- a/osu.Game.Rulesets.Osu/UI/DrawableOsuRuleset.cs +++ b/osu.Game.Rulesets.Osu/UI/DrawableOsuRuleset.cs @@ -63,8 +63,10 @@ namespace osu.Game.Rulesets.Osu.UI { get { - var first = (OsuHitObject)Objects.First(); - return first.StartTime - Math.Max(2000, first.TimePreempt); + if (Objects.FirstOrDefault() is OsuHitObject first) + return first.StartTime - Math.Max(2000, first.TimePreempt); + + return 0; } } } diff --git a/osu.Game.Tests/Visual/Menus/TestCaseLoaderAnimation.cs b/osu.Game.Tests/Visual/Menus/TestCaseLoaderAnimation.cs index eb275cbceb..3f0d965c99 100644 --- a/osu.Game.Tests/Visual/Menus/TestCaseLoaderAnimation.cs +++ b/osu.Game.Tests/Visual/Menus/TestCaseLoaderAnimation.cs @@ -58,7 +58,7 @@ namespace osu.Game.Tests.Visual.Menus bool logoVisible = false; AddStep("begin loading", () => LoadScreen(loader = new TestLoader())); - AddWaitStep("wait", 2); + AddWaitStep("wait", 3); AddStep("finish loading", () => { logoVisible = loader.Logo?.Alpha > 0; diff --git a/osu.Game.Tests/Visual/TestCaseOsuGame.cs b/osu.Game.Tests/Visual/TestCaseOsuGame.cs index dd98ff088c..b87ea433fe 100644 --- a/osu.Game.Tests/Visual/TestCaseOsuGame.cs +++ b/osu.Game.Tests/Visual/TestCaseOsuGame.cs @@ -3,7 +3,6 @@ using System; using System.Collections.Generic; -using System.Linq; using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Bindables; @@ -23,6 +22,7 @@ using osu.Game.Online.API; using osu.Game.Online.Chat; using osu.Game.Overlays; using osu.Game.Rulesets; +using osu.Game.Rulesets.Mods; using osu.Game.Scoring; using osu.Game.Screens.Menu; using osu.Game.Skinning; @@ -43,8 +43,6 @@ namespace osu.Game.Tests.Visual { typeof(OsuGame), typeof(RavenLogger), - typeof(Bindable), - typeof(IBindable), typeof(OsuLogo), typeof(IdleTracker), typeof(OnScreenDisplay), @@ -60,12 +58,17 @@ namespace osu.Game.Tests.Visual typeof(MusicController), typeof(AccountCreationOverlay), typeof(DialogOverlay), + typeof(ScreenshotManager) }; private IReadOnlyList requiredGameBaseDependencies => new[] { typeof(OsuGameBase), typeof(DatabaseContextFactory), + typeof(Bindable), + typeof(IBindable), + typeof(Bindable>), + typeof(IBindable>), typeof(LargeTextureStore), typeof(OsuConfigManager), typeof(SkinManager), @@ -86,7 +89,7 @@ namespace osu.Game.Tests.Visual }; [BackgroundDependencyLoader] - private void load(GameHost host) + private void load(GameHost host, OsuGameBase gameBase) { OsuGame game = new OsuGame(); game.SetHost(host); @@ -103,8 +106,22 @@ namespace osu.Game.Tests.Visual AddUntilStep("wait for load", () => game.IsLoaded); - AddAssert("check OsuGame DI members", () => requiredGameDependencies.All(d => game.Dependencies.Get(d) != null)); - AddAssert("check OsuGameBase DI members", () => requiredGameBaseDependencies.All(d => Dependencies.Get(d) != null)); + AddAssert("check OsuGame DI members", () => + { + foreach (var type in requiredGameDependencies) + if (game.Dependencies.Get(type) == null) + throw new Exception($"{type} has not been cached"); + + return true; + }); + AddAssert("check OsuGameBase DI members", () => + { + foreach (var type in requiredGameBaseDependencies) + if (gameBase.Dependencies.Get(type) == null) + throw new Exception($"{type} has not been cached"); + + return true; + }); } } } diff --git a/osu.Game.Tests/Visual/UserInterface/TestCaseLoadingAnimation.cs b/osu.Game.Tests/Visual/UserInterface/TestCaseLoadingAnimation.cs index 43f6f0e4db..1cfd56e2c8 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestCaseLoadingAnimation.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestCaseLoadingAnimation.cs @@ -9,7 +9,7 @@ using osuTK.Graphics; namespace osu.Game.Tests.Visual.UserInterface { - public class TestCaseLoadingAnimation : GridTestCase + public class TestCaseLoadingAnimation : GridTestScene //todo: this should be an OsuTestCase { public TestCaseLoadingAnimation() : base(2, 2) diff --git a/osu.Game.Tests/Visual/UserInterface/TestCaseOsuIcon.cs b/osu.Game.Tests/Visual/UserInterface/TestCaseOsuIcon.cs index a57e11cb0c..cef122ff58 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestCaseOsuIcon.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestCaseOsuIcon.cs @@ -9,7 +9,6 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Cursor; using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Sprites; -using osu.Framework.Testing; using osu.Game.Graphics; using osuTK; using osuTK.Graphics; @@ -17,7 +16,7 @@ using osuTK.Graphics; namespace osu.Game.Tests.Visual.UserInterface { [TestFixture] - public class TestCaseOsuIcon : TestCase + public class TestCaseOsuIcon : OsuTestCase { public TestCaseOsuIcon() { diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index f8aa5a75fb..ab643b1469 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -31,11 +31,9 @@ using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Input; using osu.Game.Overlays.Notifications; -using osu.Game.Rulesets; using osu.Game.Screens.Play; using osu.Game.Input.Bindings; using osu.Game.Online.Chat; -using osu.Game.Rulesets.Mods; using osu.Game.Skinning; using osuTK.Graphics; using osu.Game.Overlays.Volume; @@ -89,7 +87,6 @@ namespace osu.Game private Intro introScreen; private Bindable configRuleset; - private readonly Bindable ruleset = new Bindable(); private Bindable configSkin; @@ -99,12 +96,9 @@ namespace osu.Game private readonly List overlays = new List(); - private readonly List visibleBlockingOverlays = new List(); + private readonly List toolbarElements = new List(); - // todo: move this to SongSelect once Screen has the ability to unsuspend. - [Cached] - [Cached(typeof(IBindable>))] - private readonly Bindable> mods = new Bindable>(Array.Empty()); + private readonly List visibleBlockingOverlays = new List(); public OsuGame(string[] args = null) { @@ -134,12 +128,17 @@ namespace osu.Game /// /// Close all game-wide overlays. /// - /// Whether the toolbar should also be hidden. - public void CloseAllOverlays(bool toolbar = true) + /// Whether the toolbar (and accompanying controls) should also be hidden. + public void CloseAllOverlays(bool hideToolbarElements = true) { foreach (var overlay in overlays) overlay.State = Visibility.Hidden; - if (toolbar) Toolbar.State = Visibility.Hidden; + + if (hideToolbarElements) + { + foreach (var overlay in toolbarElements) + overlay.State = Visibility.Hidden; + } } private DependencyContainer dependencies; @@ -169,15 +168,12 @@ namespace osu.Game dependencies.Cache(RavenLogger); - dependencies.CacheAs(ruleset); - dependencies.CacheAs>(ruleset); - dependencies.Cache(osuLogo = new OsuLogo { Alpha = 0 }); // bind config int to database RulesetInfo configRuleset = LocalConfig.GetBindable(OsuSetting.Ruleset); - ruleset.Value = RulesetStore.GetRuleset(configRuleset.Value) ?? RulesetStore.AvailableRulesets.First(); - ruleset.ValueChanged += r => configRuleset.Value = r.NewValue.ID ?? 0; + Ruleset.Value = RulesetStore.GetRuleset(configRuleset.Value) ?? RulesetStore.AvailableRulesets.First(); + Ruleset.ValueChanged += r => configRuleset.Value = r.NewValue.ID ?? 0; // bind config int to database SkinInfo configSkin = LocalConfig.GetBindable(OsuSetting.Skin); @@ -248,9 +244,9 @@ namespace osu.Game } // Use first beatmap available for current ruleset, else switch ruleset. - var first = databasedSet.Beatmaps.Find(b => b.Ruleset == ruleset.Value) ?? databasedSet.Beatmaps.First(); + var first = databasedSet.Beatmaps.Find(b => b.Ruleset == Ruleset.Value) ?? databasedSet.Beatmaps.First(); - ruleset.Value = first.Ruleset; + Ruleset.Value = first.Ruleset; Beatmap.Value = BeatmapManager.GetWorkingBeatmap(first); }, $"load {beatmap}", bypassScreenAllowChecks: true, targetScreen: typeof(PlaySongSelect)); } @@ -280,9 +276,9 @@ namespace osu.Game performFromMainMenu(() => { - ruleset.Value = databasedScoreInfo.Ruleset; + Ruleset.Value = databasedScoreInfo.Ruleset; Beatmap.Value = BeatmapManager.GetWorkingBeatmap(databasedBeatmap); - mods.Value = databasedScoreInfo.Mods; + Mods.Value = databasedScoreInfo.Mods; menuScreen.Push(new PlayerLoader(() => new ReplayPlayer(databasedScore))); }, $"watch {databasedScoreInfo}", bypassScreenAllowChecks: true); @@ -415,7 +411,11 @@ namespace osu.Game CloseAllOverlays(false); menuScreen?.MakeCurrent(); }, - }, topMostOverlayContent.Add); + }, d => + { + topMostOverlayContent.Add(d); + toolbarElements.Add(d); + }); loadComponentSingleFile(volume = new VolumeOverlay(), leftFloatingOverlayContent.Add); loadComponentSingleFile(new OnScreenDisplay(), Add, true); @@ -451,7 +451,11 @@ namespace osu.Game GetToolbarHeight = () => ToolbarOffset, Anchor = Anchor.TopRight, Origin = Anchor.TopRight, - }, rightFloatingOverlayContent.Add, true); + }, d => + { + rightFloatingOverlayContent.Add(d); + toolbarElements.Add(d); + }, true); loadComponentSingleFile(new AccountCreationOverlay(), topMostOverlayContent.Add, true); loadComponentSingleFile(new DialogOverlay(), topMostOverlayContent.Add, true); diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index 66552c43e0..7b9aed8364 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -29,6 +29,7 @@ using osu.Game.Input; using osu.Game.Input.Bindings; using osu.Game.IO; using osu.Game.Rulesets; +using osu.Game.Rulesets.Mods; using osu.Game.Scoring; using osu.Game.Skinning; using osuTK.Input; @@ -69,7 +70,16 @@ namespace osu.Game protected override Container Content => content; - private Bindable beatmap; + private Bindable beatmap; // cached via load() method + + [Cached] + [Cached(typeof(IBindable))] + protected readonly Bindable Ruleset = new Bindable(); + + // todo: move this to SongSelect once Screen has the ability to unsuspend. + [Cached] + [Cached(Type = typeof(IBindable>))] + protected readonly Bindable> Mods = new Bindable>(Array.Empty()); protected Bindable Beatmap => beatmap; @@ -220,8 +230,10 @@ namespace osu.Game // TODO: This is temporary until we reimplement the local FPS display. // It's just to allow end-users to access the framework FPS display without knowing the shortcut key. fpsDisplayVisible = LocalConfig.GetBindable(OsuSetting.ShowFpsDisplay); - fpsDisplayVisible.ValueChanged += visible => { FrameStatisticsMode = visible.NewValue ? FrameStatisticsMode.Minimal : FrameStatisticsMode.None; }; + fpsDisplayVisible.ValueChanged += visible => { FrameStatistics.Value = visible.NewValue ? FrameStatisticsMode.Minimal : FrameStatisticsMode.None; }; fpsDisplayVisible.TriggerChange(); + + FrameStatistics.ValueChanged += e => fpsDisplayVisible.Value = e.NewValue != FrameStatisticsMode.None; } private void runMigrations() diff --git a/osu.Game/Tests/Visual/OsuTestCase.cs b/osu.Game/Tests/Visual/OsuTestCase.cs index 1f475209a4..3a40db4571 100644 --- a/osu.Game/Tests/Visual/OsuTestCase.cs +++ b/osu.Game/Tests/Visual/OsuTestCase.cs @@ -15,7 +15,7 @@ using osu.Game.Rulesets.Mods; namespace osu.Game.Tests.Visual { - public abstract class OsuTestCase : TestCase + public abstract class OsuTestCase : TestScene { [Cached(typeof(Bindable))] [Cached(typeof(IBindable))] @@ -76,21 +76,21 @@ namespace osu.Game.Tests.Visual } } - protected override ITestCaseTestRunner CreateRunner() => new OsuTestCaseTestRunner(); + protected override ITestSceneTestRunner CreateRunner() => new OsuTestCaseTestRunner(); - public class OsuTestCaseTestRunner : OsuGameBase, ITestCaseTestRunner + public class OsuTestCaseTestRunner : OsuGameBase, ITestSceneTestRunner { - private TestCaseTestRunner.TestRunner runner; + private TestSceneTestRunner.TestRunner runner; protected override void LoadAsyncComplete() { // this has to be run here rather than LoadComplete because // TestCase.cs is checking the IsLoaded state (on another thread) and expects // the runner to be loaded at that point. - Add(runner = new TestCaseTestRunner.TestRunner()); + Add(runner = new TestSceneTestRunner.TestRunner()); } - public void RunTestBlocking(TestCase test) => runner.RunTestBlocking(test); + public void RunTestBlocking(TestScene test) => runner.RunTestBlocking(test); } private class OsuTestBeatmap : BindableBeatmap diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 8f733a5c55..66d298f8c1 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -15,7 +15,7 @@ - + diff --git a/osu.iOS.props b/osu.iOS.props index e5b4d61615..ccec475d98 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -105,8 +105,8 @@ - - + +