From 45225646684d9f28b19650b3fffaa3d9791695d6 Mon Sep 17 00:00:00 2001 From: Lucas A Date: Sat, 1 Aug 2020 19:44:30 +0200 Subject: [PATCH 001/320] Add GameplayDisableOverlays setting. --- osu.Game/Configuration/OsuConfigManager.cs | 4 +++- .../Overlays/Settings/Sections/Gameplay/GeneralSettings.cs | 5 +++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs index a8a8794320..44c0fbde82 100644 --- a/osu.Game/Configuration/OsuConfigManager.cs +++ b/osu.Game/Configuration/OsuConfigManager.cs @@ -100,6 +100,7 @@ namespace osu.Game.Configuration Set(OsuSetting.IncreaseFirstObjectVisibility, true); Set(OsuSetting.GameplayDisableWinKey, true); + Set(OsuSetting.GameplayDisableOverlayActivation, true); // Update Set(OsuSetting.ReleaseStream, ReleaseStream.Lazer); @@ -231,6 +232,7 @@ namespace osu.Game.Configuration UIHoldActivationDelay, HitLighting, MenuBackgroundSource, - GameplayDisableWinKey + GameplayDisableWinKey, + GameplayDisableOverlayActivation } } diff --git a/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs b/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs index 0149e6c3a6..c2e668fe68 100644 --- a/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs @@ -77,6 +77,11 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay { LabelText = "Score display mode", Bindable = config.GetBindable(OsuSetting.ScoreDisplayMode) + }, + new SettingsCheckbox + { + LabelText = "Disable overlays during gameplay", + Bindable = config.GetBindable(OsuSetting.GameplayDisableOverlayActivation) } }; From f1ba576438eb84e9303619fb6bec9f54ad3c5a1c Mon Sep 17 00:00:00 2001 From: Lucas A Date: Sun, 2 Aug 2020 21:34:35 +0200 Subject: [PATCH 002/320] Disable overlay activation when in gameplay. --- osu.Game/Screens/Play/Player.cs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 541275cf55..24c27fde8d 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -63,6 +63,8 @@ namespace osu.Game.Screens.Play private Bindable mouseWheelDisabled; + private Bindable gameplayOverlaysDisabled; + private readonly Bindable storyboardReplacesBackground = new Bindable(); public int RestartCount; @@ -77,6 +79,9 @@ namespace osu.Game.Screens.Play [Resolved] private IAPIProvider api { get; set; } + [Resolved] + private OsuGame game { get; set; } + private SampleChannel sampleRestart; public BreakOverlay BreakOverlay; @@ -165,6 +170,7 @@ namespace osu.Game.Screens.Play sampleRestart = audio.Samples.Get(@"Gameplay/restart"); mouseWheelDisabled = config.GetBindable(OsuSetting.MouseDisableWheel); + gameplayOverlaysDisabled = config.GetBindable(OsuSetting.GameplayDisableOverlayActivation); DrawableRuleset = ruleset.CreateDrawableRulesetWith(playableBeatmap, Mods.Value); @@ -197,6 +203,13 @@ namespace osu.Game.Screens.Play skipOverlay.Hide(); } + gameplayOverlaysDisabled.ValueChanged += disabled => + { + game.OverlayActivationMode.Value = disabled.NewValue && !DrawableRuleset.IsPaused.Value ? OverlayActivation.Disabled : OverlayActivation.All; + }; + DrawableRuleset.IsPaused.BindValueChanged(_ => gameplayOverlaysDisabled.TriggerChange()); + + DrawableRuleset.HasReplayLoaded.BindValueChanged(_ => updatePauseOnFocusLostState(), true); // bind clock into components that require it @@ -627,6 +640,8 @@ namespace osu.Game.Screens.Play foreach (var mod in Mods.Value.OfType()) mod.ApplyToHUD(HUDOverlay); + + gameplayOverlaysDisabled.TriggerChange(); } public override void OnSuspending(IScreen next) From fe97d472dfafa30cdd7686074191d6b04815446f Mon Sep 17 00:00:00 2001 From: Lucas A Date: Sun, 2 Aug 2020 21:53:13 +0200 Subject: [PATCH 003/320] Enable back overlays when a replay is loaded. --- osu.Game/Screens/Play/Player.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 24c27fde8d..9d4a4741d5 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -205,10 +205,13 @@ namespace osu.Game.Screens.Play gameplayOverlaysDisabled.ValueChanged += disabled => { - game.OverlayActivationMode.Value = disabled.NewValue && !DrawableRuleset.IsPaused.Value ? OverlayActivation.Disabled : OverlayActivation.All; + if (DrawableRuleset.HasReplayLoaded.Value) + game.OverlayActivationMode.Value = OverlayActivation.UserTriggered; + else + game.OverlayActivationMode.Value = disabled.NewValue && !DrawableRuleset.IsPaused.Value ? OverlayActivation.Disabled : OverlayActivation.UserTriggered; }; DrawableRuleset.IsPaused.BindValueChanged(_ => gameplayOverlaysDisabled.TriggerChange()); - + DrawableRuleset.HasReplayLoaded.BindValueChanged(_ => gameplayOverlaysDisabled.TriggerChange()); DrawableRuleset.HasReplayLoaded.BindValueChanged(_ => updatePauseOnFocusLostState(), true); From 25ebb8619d2cbaa6fc232ed742d33da91b80d703 Mon Sep 17 00:00:00 2001 From: Lucas A Date: Mon, 3 Aug 2020 16:00:10 +0200 Subject: [PATCH 004/320] Add tests. --- .../Gameplay/TestSceneOverlayActivation.cs | 54 +++++++++++++++++++ osu.Game/Screens/Play/Player.cs | 11 ++-- 2 files changed, 62 insertions(+), 3 deletions(-) create mode 100644 osu.Game.Tests/Visual/Gameplay/TestSceneOverlayActivation.cs diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneOverlayActivation.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneOverlayActivation.cs new file mode 100644 index 0000000000..107a3a2a4b --- /dev/null +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneOverlayActivation.cs @@ -0,0 +1,54 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using NUnit.Framework; +using osu.Framework.Allocation; +using osu.Game.Configuration; +using osu.Game.Overlays; +using osu.Game.Rulesets; + +namespace osu.Game.Tests.Visual.Gameplay +{ + public class TestSceneOverlayActivation : OsuPlayerTestScene + { + private OverlayTestPlayer testPlayer; + + [Resolved] + private OsuConfigManager mng { get; set; } + + public override void SetUpSteps() + { + AddStep("disable overlay activation during gameplay", () => mng.Set(OsuSetting.GameplayDisableOverlayActivation, true)); + base.SetUpSteps(); + } + + [Test] + public void TestGameplayOverlayActivationSetting() + { + AddAssert("activation mode is disabled", () => testPlayer.OverlayActivationMode == OverlayActivation.Disabled); + } + + [Test] + public void TestGameplayOverlayActivationPaused() + { + AddUntilStep("activation mode is disabled", () => testPlayer.OverlayActivationMode == OverlayActivation.Disabled); + AddStep("pause gameplay", () => testPlayer.Pause()); + AddUntilStep("activation mode is user triggered", () => testPlayer.OverlayActivationMode == OverlayActivation.UserTriggered); + } + + [Test] + public void TestGameplayOverlayActivationReplayLoaded() + { + AddAssert("activation mode is disabled", () => testPlayer.OverlayActivationMode == OverlayActivation.Disabled); + AddStep("load a replay", () => testPlayer.DrawableRuleset.HasReplayLoaded.Value = true); + AddAssert("activation mode is user triggered", () => testPlayer.OverlayActivationMode == OverlayActivation.UserTriggered); + } + + protected override TestPlayer CreatePlayer(Ruleset ruleset) => testPlayer = new OverlayTestPlayer(); + + private class OverlayTestPlayer : TestPlayer + { + public new OverlayActivation OverlayActivationMode => base.OverlayActivationMode.Value; + } + } +} diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 9d4a4741d5..45a9b442be 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -79,7 +79,7 @@ namespace osu.Game.Screens.Play [Resolved] private IAPIProvider api { get; set; } - [Resolved] + [Resolved(CanBeNull = true)] private OsuGame game { get; set; } private SampleChannel sampleRestart; @@ -90,6 +90,8 @@ namespace osu.Game.Screens.Play private SkipOverlay skipOverlay; + protected readonly Bindable OverlayActivationMode = new Bindable(OverlayActivation.Disabled); + protected ScoreProcessor ScoreProcessor { get; private set; } protected HealthProcessor HealthProcessor { get; private set; } @@ -203,12 +205,15 @@ namespace osu.Game.Screens.Play skipOverlay.Hide(); } + if (game != null) + OverlayActivationMode.BindTo(game.OverlayActivationMode); + gameplayOverlaysDisabled.ValueChanged += disabled => { if (DrawableRuleset.HasReplayLoaded.Value) - game.OverlayActivationMode.Value = OverlayActivation.UserTriggered; + OverlayActivationMode.Value = OverlayActivation.UserTriggered; else - game.OverlayActivationMode.Value = disabled.NewValue && !DrawableRuleset.IsPaused.Value ? OverlayActivation.Disabled : OverlayActivation.UserTriggered; + OverlayActivationMode.Value = disabled.NewValue && !DrawableRuleset.IsPaused.Value ? OverlayActivation.Disabled : OverlayActivation.UserTriggered; }; DrawableRuleset.IsPaused.BindValueChanged(_ => gameplayOverlaysDisabled.TriggerChange()); DrawableRuleset.HasReplayLoaded.BindValueChanged(_ => gameplayOverlaysDisabled.TriggerChange()); From 242a035f7e693dcbd00c0f0d381cd6f16c211f9e Mon Sep 17 00:00:00 2001 From: Lucas A Date: Mon, 3 Aug 2020 21:25:45 +0200 Subject: [PATCH 005/320] Apply review suggestions. --- .../Gameplay/TestSceneOverlayActivation.cs | 4 +-- osu.Game/Screens/Play/Player.cs | 25 +++++++++++-------- 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneOverlayActivation.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneOverlayActivation.cs index 107a3a2a4b..9e93cf363d 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneOverlayActivation.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneOverlayActivation.cs @@ -14,11 +14,11 @@ namespace osu.Game.Tests.Visual.Gameplay private OverlayTestPlayer testPlayer; [Resolved] - private OsuConfigManager mng { get; set; } + private OsuConfigManager config { get; set; } public override void SetUpSteps() { - AddStep("disable overlay activation during gameplay", () => mng.Set(OsuSetting.GameplayDisableOverlayActivation, true)); + AddStep("disable overlay activation during gameplay", () => config.Set(OsuSetting.GameplayDisableOverlayActivation, true)); base.SetUpSteps(); } diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 45a9b442be..7906f5bfe1 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -90,7 +90,10 @@ namespace osu.Game.Screens.Play private SkipOverlay skipOverlay; - protected readonly Bindable OverlayActivationMode = new Bindable(OverlayActivation.Disabled); + /// + /// The current activation mode for overlays. + /// + protected readonly Bindable OverlayActivationMode = new Bindable(OverlayActivation.UserTriggered); protected ScoreProcessor ScoreProcessor { get; private set; } @@ -208,15 +211,9 @@ namespace osu.Game.Screens.Play if (game != null) OverlayActivationMode.BindTo(game.OverlayActivationMode); - gameplayOverlaysDisabled.ValueChanged += disabled => - { - if (DrawableRuleset.HasReplayLoaded.Value) - OverlayActivationMode.Value = OverlayActivation.UserTriggered; - else - OverlayActivationMode.Value = disabled.NewValue && !DrawableRuleset.IsPaused.Value ? OverlayActivation.Disabled : OverlayActivation.UserTriggered; - }; - DrawableRuleset.IsPaused.BindValueChanged(_ => gameplayOverlaysDisabled.TriggerChange()); - DrawableRuleset.HasReplayLoaded.BindValueChanged(_ => gameplayOverlaysDisabled.TriggerChange()); + gameplayOverlaysDisabled.ValueChanged += disabled => updateOverlayActivationMode(); + DrawableRuleset.IsPaused.BindValueChanged(_ => updateOverlayActivationMode()); + DrawableRuleset.HasReplayLoaded.BindValueChanged(_ => updateOverlayActivationMode()); DrawableRuleset.HasReplayLoaded.BindValueChanged(_ => updatePauseOnFocusLostState(), true); @@ -362,6 +359,14 @@ namespace osu.Game.Screens.Play HUDOverlay.KeyCounter.IsCounting = !isBreakTime.NewValue; } + private void updateOverlayActivationMode() + { + if (DrawableRuleset.HasReplayLoaded.Value) + OverlayActivationMode.Value = OverlayActivation.UserTriggered; + else + OverlayActivationMode.Value = gameplayOverlaysDisabled.Value && !DrawableRuleset.IsPaused.Value ? OverlayActivation.Disabled : OverlayActivation.UserTriggered; + } + private void updatePauseOnFocusLostState() => HUDOverlay.HoldToQuit.PauseOnFocusLost = PauseOnFocusLost && !DrawableRuleset.HasReplayLoaded.Value From 30c7a6f6a72d9c711c32e4dc351c6d74ed39a6b2 Mon Sep 17 00:00:00 2001 From: Lucas A Date: Mon, 3 Aug 2020 21:33:18 +0200 Subject: [PATCH 006/320] Fix CI issue and use method instead of triggering change on bindable. --- osu.Game/Screens/Play/Player.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 7906f5bfe1..819942e6af 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -211,7 +211,7 @@ namespace osu.Game.Screens.Play if (game != null) OverlayActivationMode.BindTo(game.OverlayActivationMode); - gameplayOverlaysDisabled.ValueChanged += disabled => updateOverlayActivationMode(); + gameplayOverlaysDisabled.BindValueChanged(_ => updateOverlayActivationMode()); DrawableRuleset.IsPaused.BindValueChanged(_ => updateOverlayActivationMode()); DrawableRuleset.HasReplayLoaded.BindValueChanged(_ => updateOverlayActivationMode()); @@ -654,7 +654,7 @@ namespace osu.Game.Screens.Play foreach (var mod in Mods.Value.OfType()) mod.ApplyToHUD(HUDOverlay); - gameplayOverlaysDisabled.TriggerChange(); + updateOverlayActivationMode(); } public override void OnSuspending(IScreen next) From 71895964f408c1fec6c8b6ca8155ca03aca0e044 Mon Sep 17 00:00:00 2001 From: Lucas A Date: Wed, 5 Aug 2020 11:21:09 +0200 Subject: [PATCH 007/320] Refactor overlay activation logic and reword tip. --- osu.Game/Screens/Menu/Disclaimer.cs | 2 +- osu.Game/Screens/Play/Player.cs | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Menu/Disclaimer.cs b/osu.Game/Screens/Menu/Disclaimer.cs index 986de1edf0..fcb9aacd76 100644 --- a/osu.Game/Screens/Menu/Disclaimer.cs +++ b/osu.Game/Screens/Menu/Disclaimer.cs @@ -190,7 +190,7 @@ namespace osu.Game.Screens.Menu { "You can press Ctrl-T anywhere in the game to toggle the toolbar!", "You can press Ctrl-O anywhere in the game to access options!", - "All settings are dynamic and take effect in real-time. Try changing the skin while playing!", + "All settings are dynamic and take effect in real-time. Try pausing and changing the skin while playing!", "New features are coming online every update. Make sure to stay up-to-date!", "If you find the UI too large or small, try adjusting UI scale in settings!", "Try adjusting the \"Screen Scaling\" mode to change your gameplay or UI area, even in fullscreen!", diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 819942e6af..8f8128abfc 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -361,10 +361,12 @@ namespace osu.Game.Screens.Play private void updateOverlayActivationMode() { - if (DrawableRuleset.HasReplayLoaded.Value) + bool canTriggerOverlays = DrawableRuleset.IsPaused.Value || !gameplayOverlaysDisabled.Value; + + if (DrawableRuleset.HasReplayLoaded.Value || canTriggerOverlays) OverlayActivationMode.Value = OverlayActivation.UserTriggered; else - OverlayActivationMode.Value = gameplayOverlaysDisabled.Value && !DrawableRuleset.IsPaused.Value ? OverlayActivation.Disabled : OverlayActivation.UserTriggered; + OverlayActivationMode.Value = OverlayActivation.Disabled; } private void updatePauseOnFocusLostState() => From 6e42b8219c4510b856923aa08712c50dbf37fa87 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 4 Aug 2020 21:53:00 +0900 Subject: [PATCH 008/320] Move track to MusicController, compiles --- .../TestSceneHoldNoteInput.cs | 2 +- .../TestSceneOutOfOrderHits.cs | 2 +- .../TestSceneSliderInput.cs | 2 +- .../TestSceneSliderSnaking.cs | 15 +- .../TestSceneSpinnerRotation.cs | 13 +- .../Skinning/TestSceneDrawableTaikoMascot.cs | 4 +- .../Skinning/TestSceneTaikoPlayfield.cs | 2 +- .../Skins/TestSceneBeatmapSkinResources.cs | 3 +- .../Visual/Editing/TimelineTestScene.cs | 11 +- .../TestSceneCompletionCancellation.cs | 15 +- .../Gameplay/TestSceneGameplayRewinding.cs | 15 +- .../TestSceneNightcoreBeatContainer.cs | 4 +- .../Visual/Gameplay/TestScenePause.cs | 2 +- .../Visual/Gameplay/TestScenePlayerLoader.cs | 6 +- .../Visual/Gameplay/TestSceneStoryboard.cs | 10 +- .../Visual/Menus/TestSceneIntroWelcome.cs | 7 +- .../Navigation/TestSceneScreenNavigation.cs | 23 +- .../TestSceneBeatSyncedContainer.cs | 5 +- .../TestSceneNowPlayingOverlay.cs | 4 +- osu.Game/Beatmaps/BeatmapManager.cs | 2 +- .../Beatmaps/BeatmapManager_WorkingBeatmap.cs | 16 -- osu.Game/Beatmaps/IWorkingBeatmap.cs | 5 - osu.Game/Beatmaps/WorkingBeatmap.cs | 22 +- .../Containers/BeatSyncedContainer.cs | 16 +- osu.Game/OsuGame.cs | 23 +- osu.Game/OsuGameBase.cs | 10 - osu.Game/Overlays/Music/PlaylistOverlay.cs | 10 +- osu.Game/Overlays/MusicController.cs | 221 ++++++++++++++++-- osu.Game/Overlays/NowPlayingOverlay.cs | 10 +- osu.Game/Rulesets/Mods/IApplicableToTrack.cs | 2 +- osu.Game/Rulesets/Mods/ModDaycore.cs | 6 +- osu.Game/Rulesets/Mods/ModNightcore.cs | 6 +- osu.Game/Rulesets/Mods/ModRateAdjust.cs | 4 +- osu.Game/Rulesets/Mods/ModTimeRamp.cs | 4 +- .../Edit/Components/BottomBarContainer.cs | 2 - .../Edit/Components/PlaybackControl.cs | 8 +- .../Timelines/Summary/Parts/MarkerPart.cs | 5 +- .../Timelines/Summary/Parts/TimelinePart.cs | 8 +- .../Compose/Components/Timeline/Timeline.cs | 34 +-- .../Timeline/TimelineTickDisplay.cs | 7 +- osu.Game/Screens/Edit/Editor.cs | 8 +- osu.Game/Screens/Edit/EditorClock.cs | 22 +- osu.Game/Screens/Menu/IntroScreen.cs | 8 +- osu.Game/Screens/Menu/IntroTriangles.cs | 2 +- osu.Game/Screens/Menu/IntroWelcome.cs | 6 +- osu.Game/Screens/Menu/LogoVisualisation.cs | 12 +- osu.Game/Screens/Menu/MainMenu.cs | 16 +- osu.Game/Screens/Menu/OsuLogo.cs | 9 +- .../Multi/Match/Components/ReadyButton.cs | 6 +- osu.Game/Screens/Multi/Multiplayer.cs | 23 +- osu.Game/Screens/Play/FailAnimation.cs | 12 +- .../Screens/Play/GameplayClockContainer.cs | 46 +--- osu.Game/Screens/Select/SongSelect.cs | 34 ++- osu.Game/Tests/Beatmaps/TestWorkingBeatmap.cs | 2 - osu.Game/Tests/Visual/EditorClockTestScene.cs | 2 +- osu.Game/Tests/Visual/OsuTestScene.cs | 8 +- .../Visual/RateAdjustedBeatmapTestScene.cs | 2 +- 57 files changed, 438 insertions(+), 346 deletions(-) diff --git a/osu.Game.Rulesets.Mania.Tests/TestSceneHoldNoteInput.cs b/osu.Game.Rulesets.Mania.Tests/TestSceneHoldNoteInput.cs index 95072cf4f8..c3e0c277a0 100644 --- a/osu.Game.Rulesets.Mania.Tests/TestSceneHoldNoteInput.cs +++ b/osu.Game.Rulesets.Mania.Tests/TestSceneHoldNoteInput.cs @@ -343,7 +343,7 @@ namespace osu.Game.Rulesets.Mania.Tests judgementResults = new List(); }); - AddUntilStep("Beatmap at 0", () => Beatmap.Value.Track.CurrentTime == 0); + AddUntilStep("Beatmap at 0", () => MusicController.CurrentTrackTime == 0); AddUntilStep("Wait until player is loaded", () => currentPlayer.IsCurrentScreen()); AddUntilStep("Wait for completion", () => currentPlayer.ScoreProcessor.HasCompleted.Value); } diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneOutOfOrderHits.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneOutOfOrderHits.cs index 854626d362..dc7e59b40d 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneOutOfOrderHits.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneOutOfOrderHits.cs @@ -385,7 +385,7 @@ namespace osu.Game.Rulesets.Osu.Tests judgementResults = new List(); }); - AddUntilStep("Beatmap at 0", () => Beatmap.Value.Track.CurrentTime == 0); + AddUntilStep("Beatmap at 0", () => MusicController.CurrentTrackTime == 0); AddUntilStep("Wait until player is loaded", () => currentPlayer.IsCurrentScreen()); AddUntilStep("Wait for completion", () => currentPlayer.ScoreProcessor.HasCompleted.Value); } diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs index b543b6fa94..2dffcfeabb 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs @@ -366,7 +366,7 @@ namespace osu.Game.Rulesets.Osu.Tests judgementResults = new List(); }); - AddUntilStep("Beatmap at 0", () => Beatmap.Value.Track.CurrentTime == 0); + AddUntilStep("Beatmap at 0", () => MusicController.CurrentTrackTime == 0); AddUntilStep("Wait until player is loaded", () => currentPlayer.IsCurrentScreen()); AddUntilStep("Wait for completion", () => currentPlayer.ScoreProcessor.HasCompleted.Value); } diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderSnaking.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderSnaking.cs index a69646507a..cd46e8c545 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderSnaking.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderSnaking.cs @@ -22,7 +22,6 @@ using osu.Game.Rulesets.Osu.Objects.Drawables; using osu.Game.Rulesets.Osu.Objects.Drawables.Pieces; using osu.Game.Storyboards; using osuTK; -using static osu.Game.Tests.Visual.OsuTestScene.ClockBackedTestWorkingBeatmap; namespace osu.Game.Rulesets.Osu.Tests { @@ -32,8 +31,6 @@ namespace osu.Game.Rulesets.Osu.Tests [Resolved] private AudioManager audioManager { get; set; } - private TrackVirtualManual track; - protected override bool Autoplay => autoplay; private bool autoplay; @@ -44,11 +41,7 @@ namespace osu.Game.Rulesets.Osu.Tests private const double fade_in_modifier = -1200; protected override WorkingBeatmap CreateWorkingBeatmap(IBeatmap beatmap, Storyboard storyboard = null) - { - var working = new ClockBackedTestWorkingBeatmap(beatmap, storyboard, new FramedClock(new ManualClock { Rate = 1 }), audioManager); - track = (TrackVirtualManual)working.Track; - return working; - } + => new ClockBackedTestWorkingBeatmap(beatmap, storyboard, new FramedClock(new ManualClock { Rate = 1 }), audioManager); [BackgroundDependencyLoader] private void load(RulesetConfigCache configCache) @@ -72,7 +65,7 @@ namespace osu.Game.Rulesets.Osu.Tests { AddStep("enable autoplay", () => autoplay = true); base.SetUpSteps(); - AddUntilStep("wait for track to start running", () => track.IsRunning); + AddUntilStep("wait for track to start running", () => MusicController.IsPlaying); double startTime = hitObjects[sliderIndex].StartTime; retrieveDrawableSlider(sliderIndex); @@ -97,7 +90,7 @@ namespace osu.Game.Rulesets.Osu.Tests { AddStep("have autoplay", () => autoplay = true); base.SetUpSteps(); - AddUntilStep("wait for track to start running", () => track.IsRunning); + AddUntilStep("wait for track to start running", () => MusicController.IsPlaying); double startTime = hitObjects[sliderIndex].StartTime; retrieveDrawableSlider(sliderIndex); @@ -201,7 +194,7 @@ namespace osu.Game.Rulesets.Osu.Tests private void addSeekStep(double time) { - AddStep($"seek to {time}", () => track.Seek(time)); + AddStep($"seek to {time}", () => MusicController.SeekTo(time)); AddUntilStep("wait for seek to finish", () => Precision.AlmostEquals(time, Player.DrawableRuleset.FrameStableClock.CurrentTime, 100)); } diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerRotation.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerRotation.cs index b46964e8b7..105e19a73c 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerRotation.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerRotation.cs @@ -24,7 +24,6 @@ using osu.Game.Scoring; using osu.Game.Storyboards; using osu.Game.Tests.Visual; using osuTK; -using static osu.Game.Tests.Visual.OsuTestScene.ClockBackedTestWorkingBeatmap; namespace osu.Game.Rulesets.Osu.Tests { @@ -33,18 +32,12 @@ namespace osu.Game.Rulesets.Osu.Tests [Resolved] private AudioManager audioManager { get; set; } - private TrackVirtualManual track; - protected override bool Autoplay => true; protected override TestPlayer CreatePlayer(Ruleset ruleset) => new ScoreExposedPlayer(); protected override WorkingBeatmap CreateWorkingBeatmap(IBeatmap beatmap, Storyboard storyboard = null) - { - var working = new ClockBackedTestWorkingBeatmap(beatmap, storyboard, new FramedClock(new ManualClock { Rate = 1 }), audioManager); - track = (TrackVirtualManual)working.Track; - return working; - } + => new ClockBackedTestWorkingBeatmap(beatmap, storyboard, new FramedClock(new ManualClock { Rate = 1 }), audioManager); private DrawableSpinner drawableSpinner; private SpriteIcon spinnerSymbol => drawableSpinner.ChildrenOfType().Single(); @@ -54,7 +47,7 @@ namespace osu.Game.Rulesets.Osu.Tests { base.SetUpSteps(); - AddUntilStep("wait for track to start running", () => track.IsRunning); + AddUntilStep("wait for track to start running", () => MusicController.IsPlaying); AddStep("retrieve spinner", () => drawableSpinner = (DrawableSpinner)Player.DrawableRuleset.Playfield.AllHitObjects.First()); } @@ -198,7 +191,7 @@ namespace osu.Game.Rulesets.Osu.Tests private void addSeekStep(double time) { - AddStep($"seek to {time}", () => track.Seek(time)); + AddStep($"seek to {time}", () => MusicController.SeekTo(time)); AddUntilStep("wait for seek to finish", () => Precision.AlmostEquals(time, Player.DrawableRuleset.FrameStableClock.CurrentTime, 100)); } diff --git a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableTaikoMascot.cs b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableTaikoMascot.cs index 47d8a5c012..ba5aef5968 100644 --- a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableTaikoMascot.cs +++ b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableTaikoMascot.cs @@ -175,11 +175,11 @@ namespace osu.Game.Rulesets.Taiko.Tests.Skinning private void createDrawableRuleset() { - AddUntilStep("wait for beatmap to be loaded", () => Beatmap.Value.Track.IsLoaded); + AddUntilStep("wait for beatmap to be loaded", () => MusicController.TrackLoaded); AddStep("create drawable ruleset", () => { - Beatmap.Value.Track.Start(); + MusicController.Play(true); SetContents(() => { diff --git a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneTaikoPlayfield.cs b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneTaikoPlayfield.cs index 7b7e2c43d1..5c54393fb8 100644 --- a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneTaikoPlayfield.cs +++ b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneTaikoPlayfield.cs @@ -34,7 +34,7 @@ namespace osu.Game.Rulesets.Taiko.Tests.Skinning beatmap.ControlPointInfo.Add(0, new TimingControlPoint { BeatLength = 1000 }); - Beatmap.Value.Track.Start(); + MusicController.Play(true); }); AddStep("Load playfield", () => SetContents(() => new TaikoPlayfield(new ControlPointInfo()) diff --git a/osu.Game.Tests/Skins/TestSceneBeatmapSkinResources.cs b/osu.Game.Tests/Skins/TestSceneBeatmapSkinResources.cs index 4d3b73fb32..1a19326ac4 100644 --- a/osu.Game.Tests/Skins/TestSceneBeatmapSkinResources.cs +++ b/osu.Game.Tests/Skins/TestSceneBeatmapSkinResources.cs @@ -3,7 +3,6 @@ using NUnit.Framework; using osu.Framework.Allocation; -using osu.Framework.Audio.Track; using osu.Framework.Testing; using osu.Game.Audio; using osu.Game.Beatmaps; @@ -32,6 +31,6 @@ namespace osu.Game.Tests.Skins public void TestRetrieveOggSample() => AddAssert("sample is non-null", () => beatmap.Skin.GetSample(new SampleInfo("sample")) != null); [Test] - public void TestRetrieveOggTrack() => AddAssert("track is non-null", () => !(beatmap.Track is TrackVirtual)); + public void TestRetrieveOggTrack() => AddAssert("track is non-null", () => !MusicController.IsDummyDevice); } } diff --git a/osu.Game.Tests/Visual/Editing/TimelineTestScene.cs b/osu.Game.Tests/Visual/Editing/TimelineTestScene.cs index fdb8781563..5d6136d9fb 100644 --- a/osu.Game.Tests/Visual/Editing/TimelineTestScene.cs +++ b/osu.Game.Tests/Visual/Editing/TimelineTestScene.cs @@ -3,12 +3,11 @@ using osu.Framework.Allocation; using osu.Framework.Audio; -using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; -using osu.Game.Beatmaps; using osu.Game.Graphics.UserInterface; +using osu.Game.Overlays; using osu.Game.Rulesets.Edit; using osu.Game.Screens.Edit; using osu.Game.Screens.Edit.Compose.Components.Timeline; @@ -65,10 +64,10 @@ namespace osu.Game.Tests.Visual.Editing private readonly Drawable marker; [Resolved] - private IBindable beatmap { get; set; } + private EditorClock editorClock { get; set; } [Resolved] - private EditorClock editorClock { get; set; } + private MusicController musicController { get; set; } public AudioVisualiser() { @@ -94,8 +93,8 @@ namespace osu.Game.Tests.Visual.Editing { base.Update(); - if (beatmap.Value.Track.IsLoaded) - marker.X = (float)(editorClock.CurrentTime / beatmap.Value.Track.Length); + if (musicController.TrackLoaded) + marker.X = (float)(editorClock.CurrentTime / musicController.TrackLength); } } diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneCompletionCancellation.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneCompletionCancellation.cs index 79275d70a7..b39cfc3699 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneCompletionCancellation.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneCompletionCancellation.cs @@ -4,7 +4,6 @@ using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Audio; -using osu.Framework.Audio.Track; using osu.Framework.Screens; using osu.Framework.Testing; using osu.Framework.Timing; @@ -18,8 +17,6 @@ namespace osu.Game.Tests.Visual.Gameplay { public class TestSceneCompletionCancellation : OsuPlayerTestScene { - private Track track; - [Resolved] private AudioManager audio { get; set; } @@ -34,7 +31,7 @@ namespace osu.Game.Tests.Visual.Gameplay base.SetUpSteps(); // Ensure track has actually running before attempting to seek - AddUntilStep("wait for track to start running", () => track.IsRunning); + AddUntilStep("wait for track to start running", () => MusicController.IsPlaying); } [Test] @@ -73,13 +70,13 @@ namespace osu.Game.Tests.Visual.Gameplay private void complete() { - AddStep("seek to completion", () => track.Seek(5000)); + AddStep("seek to completion", () => MusicController.SeekTo(5000)); AddUntilStep("completion set by processor", () => Player.ScoreProcessor.HasCompleted.Value); } private void cancel() { - AddStep("rewind to cancel", () => track.Seek(4000)); + AddStep("rewind to cancel", () => MusicController.SeekTo(4000)); AddUntilStep("completion cleared by processor", () => !Player.ScoreProcessor.HasCompleted.Value); } @@ -91,11 +88,7 @@ namespace osu.Game.Tests.Visual.Gameplay } protected override WorkingBeatmap CreateWorkingBeatmap(IBeatmap beatmap, Storyboard storyboard = null) - { - var working = new ClockBackedTestWorkingBeatmap(beatmap, storyboard, new FramedClock(new ManualClock { Rate = 1 }), audio); - track = working.Track; - return working; - } + => new ClockBackedTestWorkingBeatmap(beatmap, storyboard, new FramedClock(new ManualClock { Rate = 1 }), audio); protected override IBeatmap CreateBeatmap(RulesetInfo ruleset) { diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneGameplayRewinding.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneGameplayRewinding.cs index 2a119f5199..6bdc65078a 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneGameplayRewinding.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneGameplayRewinding.cs @@ -5,10 +5,10 @@ using System.Linq; using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Audio; -using osu.Framework.Audio.Track; using osu.Framework.Utils; using osu.Framework.Timing; using osu.Game.Beatmaps; +using osu.Game.Overlays; using osu.Game.Rulesets; using osu.Game.Rulesets.Osu.Objects; using osu.Game.Storyboards; @@ -21,19 +21,16 @@ namespace osu.Game.Tests.Visual.Gameplay [Resolved] private AudioManager audioManager { get; set; } - private Track track; + [Resolved] + private MusicController musicController { get; set; } protected override WorkingBeatmap CreateWorkingBeatmap(IBeatmap beatmap, Storyboard storyboard = null) - { - var working = new ClockBackedTestWorkingBeatmap(beatmap, storyboard, new FramedClock(new ManualClock { Rate = 1 }), audioManager); - track = working.Track; - return working; - } + => new ClockBackedTestWorkingBeatmap(beatmap, storyboard, new FramedClock(new ManualClock { Rate = 1 }), audioManager); [Test] public void TestNoJudgementsOnRewind() { - AddUntilStep("wait for track to start running", () => track.IsRunning); + AddUntilStep("wait for track to start running", () => MusicController.IsPlaying); addSeekStep(3000); AddAssert("all judged", () => Player.DrawableRuleset.Playfield.AllHitObjects.All(h => h.Judged)); AddUntilStep("key counter counted keys", () => Player.HUDOverlay.KeyCounter.Children.All(kc => kc.CountPresses >= 7)); @@ -46,7 +43,7 @@ namespace osu.Game.Tests.Visual.Gameplay private void addSeekStep(double time) { - AddStep($"seek to {time}", () => track.Seek(time)); + AddStep($"seek to {time}", () => MusicController.SeekTo(time)); // Allow a few frames of lenience AddUntilStep("wait for seek to finish", () => Precision.AlmostEquals(time, Player.DrawableRuleset.FrameStableClock.CurrentTime, 100)); diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneNightcoreBeatContainer.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneNightcoreBeatContainer.cs index 951ee1489d..ce99d85e92 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneNightcoreBeatContainer.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneNightcoreBeatContainer.cs @@ -19,8 +19,8 @@ namespace osu.Game.Tests.Visual.Gameplay Beatmap.Value = CreateWorkingBeatmap(new OsuRuleset().RulesetInfo); - Beatmap.Value.Track.Start(); - Beatmap.Value.Track.Seek(Beatmap.Value.Beatmap.HitObjects.First().StartTime - 1000); + MusicController.Play(true); + MusicController.SeekTo(Beatmap.Value.Beatmap.HitObjects.First().StartTime - 1000); Add(new ModNightcore.NightcoreBeatContainer()); diff --git a/osu.Game.Tests/Visual/Gameplay/TestScenePause.cs b/osu.Game.Tests/Visual/Gameplay/TestScenePause.cs index 420bf29429..8f14de1578 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestScenePause.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestScenePause.cs @@ -288,7 +288,7 @@ namespace osu.Game.Tests.Visual.Gameplay private void confirmNoTrackAdjustments() { - AddAssert("track has no adjustments", () => Beatmap.Value.Track.AggregateFrequency.Value == 1); + AddAssert("track has no adjustments", () => MusicController.AggregateFrequency.Value == 1); } private void restart() => AddStep("restart", () => Player.Restart()); diff --git a/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs b/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs index 4c73065087..2f86db1b25 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs @@ -57,7 +57,7 @@ namespace osu.Game.Tests.Visual.Gameplay Beatmap.Value = CreateWorkingBeatmap(new OsuRuleset().RulesetInfo); foreach (var mod in SelectedMods.Value.OfType()) - mod.ApplyToTrack(Beatmap.Value.Track); + mod.ApplyToTrack(MusicController); InputManager.Child = container = new TestPlayerLoaderContainer( loader = new TestPlayerLoader(() => @@ -77,12 +77,12 @@ namespace osu.Game.Tests.Visual.Gameplay { AddStep("load dummy beatmap", () => ResetPlayer(false, () => SelectedMods.Value = new[] { new OsuModNightcore() })); AddUntilStep("wait for current", () => loader.IsCurrentScreen()); - AddAssert("mod rate applied", () => Beatmap.Value.Track.Rate != 1); + AddAssert("mod rate applied", () => MusicController.Rate != 1); AddStep("exit loader", () => loader.Exit()); AddUntilStep("wait for not current", () => !loader.IsCurrentScreen()); AddAssert("player did not load", () => !player.IsLoaded); AddUntilStep("player disposed", () => loader.DisposalTask?.IsCompleted == true); - AddAssert("mod rate still applied", () => Beatmap.Value.Track.Rate != 1); + AddAssert("mod rate still applied", () => MusicController.Rate != 1); } [Test] diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboard.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboard.cs index 9f1492a25f..a4b558fce2 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboard.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboard.cs @@ -87,11 +87,9 @@ namespace osu.Game.Tests.Visual.Gameplay private void restart() { - var track = Beatmap.Value.Track; - - track.Reset(); + MusicController.Reset(); loadStoryboard(Beatmap.Value); - track.Start(); + MusicController.Play(true); } private void loadStoryboard(WorkingBeatmap working) @@ -106,7 +104,7 @@ namespace osu.Game.Tests.Visual.Gameplay storyboard.Passing = false; storyboardContainer.Add(storyboard); - decoupledClock.ChangeSource(working.Track); + decoupledClock.ChangeSource(musicController.GetTrackClock()); } private void loadStoryboardNoVideo() @@ -129,7 +127,7 @@ namespace osu.Game.Tests.Visual.Gameplay storyboard = sb.CreateDrawable(Beatmap.Value); storyboardContainer.Add(storyboard); - decoupledClock.ChangeSource(Beatmap.Value.Track); + decoupledClock.ChangeSource(musicController.GetTrackClock()); } } } diff --git a/osu.Game.Tests/Visual/Menus/TestSceneIntroWelcome.cs b/osu.Game.Tests/Visual/Menus/TestSceneIntroWelcome.cs index 8f20e38494..36f98b7a0c 100644 --- a/osu.Game.Tests/Visual/Menus/TestSceneIntroWelcome.cs +++ b/osu.Game.Tests/Visual/Menus/TestSceneIntroWelcome.cs @@ -2,7 +2,6 @@ // See the LICENCE file in the repository root for full licence text. using NUnit.Framework; -using osu.Framework.Audio.Track; using osu.Framework.Screens; using osu.Game.Screens.Menu; @@ -15,11 +14,9 @@ namespace osu.Game.Tests.Visual.Menus public TestSceneIntroWelcome() { - AddUntilStep("wait for load", () => getTrack() != null); + AddUntilStep("wait for load", () => MusicController.TrackLoaded); - AddAssert("check if menu music loops", () => getTrack().Looping); + AddAssert("check if menu music loops", () => MusicController.Looping); } - - private Track getTrack() => (IntroStack?.CurrentScreen as MainMenu)?.Track; } } diff --git a/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs b/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs index 8ccaca8630..455b7e56e6 100644 --- a/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs +++ b/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs @@ -4,7 +4,6 @@ using System.Linq; using NUnit.Framework; using osu.Framework.Allocation; -using osu.Framework.Audio.Track; using osu.Framework.Graphics.Containers; using osu.Framework.Screens; using osu.Game.Beatmaps; @@ -46,7 +45,6 @@ namespace osu.Game.Tests.Visual.Navigation Player player = null; WorkingBeatmap beatmap() => Game.Beatmap.Value; - Track track() => beatmap().Track; PushAndConfirm(() => new TestSongSelect()); @@ -62,30 +60,27 @@ namespace osu.Game.Tests.Visual.Navigation AddUntilStep("wait for player", () => (player = Game.ScreenStack.CurrentScreen as Player) != null); AddUntilStep("wait for fail", () => player.HasFailed); - AddUntilStep("wait for track stop", () => !track().IsRunning); - AddAssert("Ensure time before preview point", () => track().CurrentTime < beatmap().Metadata.PreviewTime); + AddUntilStep("wait for track stop", () => !MusicController.IsPlaying); + AddAssert("Ensure time before preview point", () => MusicController.CurrentTrackTime < beatmap().Metadata.PreviewTime); pushEscape(); - AddUntilStep("wait for track playing", () => track().IsRunning); - AddAssert("Ensure time wasn't reset to preview point", () => track().CurrentTime < beatmap().Metadata.PreviewTime); + AddUntilStep("wait for track playing", () => MusicController.IsPlaying); + AddAssert("Ensure time wasn't reset to preview point", () => MusicController.CurrentTrackTime < beatmap().Metadata.PreviewTime); } [Test] public void TestMenuMakesMusic() { - WorkingBeatmap beatmap() => Game.Beatmap.Value; - Track track() => beatmap().Track; - TestSongSelect songSelect = null; PushAndConfirm(() => songSelect = new TestSongSelect()); - AddUntilStep("wait for no track", () => track() is TrackVirtual); + AddUntilStep("wait for no track", () => MusicController.IsDummyDevice); AddStep("return to menu", () => songSelect.Exit()); - AddUntilStep("wait for track", () => !(track() is TrackVirtual) && track().IsRunning); + AddUntilStep("wait for track", () => !MusicController.IsDummyDevice && MusicController.IsPlaying); } [Test] @@ -140,12 +135,12 @@ namespace osu.Game.Tests.Visual.Navigation AddUntilStep("Wait for music controller", () => Game.MusicController.IsLoaded); AddStep("Seek close to end", () => { - Game.MusicController.SeekTo(Game.Beatmap.Value.Track.Length - 1000); - Game.Beatmap.Value.Track.Completed += () => trackCompleted = true; + Game.MusicController.SeekTo(MusicController.TrackLength - 1000); + // MusicController.Completed += () => trackCompleted = true; }); AddUntilStep("Track was completed", () => trackCompleted); - AddUntilStep("Track was restarted", () => Game.Beatmap.Value.Track.IsRunning); + AddUntilStep("Track was restarted", () => MusicController.IsPlaying); } private void pushEscape() => diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneBeatSyncedContainer.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneBeatSyncedContainer.cs index dd5ceec739..f3fef8c355 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneBeatSyncedContainer.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneBeatSyncedContainer.cs @@ -71,6 +71,9 @@ namespace osu.Game.Tests.Visual.UserInterface private readonly Box flashLayer; + [Resolved] + private MusicController musicController { get; set; } + public BeatContainer() { RelativeSizeAxes = Axes.X; @@ -165,7 +168,7 @@ namespace osu.Game.Tests.Visual.UserInterface if (timingPoints.Count == 0) return 0; if (timingPoints[^1] == current) - return (int)Math.Ceiling((Beatmap.Value.Track.Length - current.Time) / current.BeatLength); + return (int)Math.Ceiling((musicController.TrackLength - current.Time) / current.BeatLength); return (int)Math.Ceiling((getNextTimingPoint(current).Time - current.Time) / current.BeatLength); } diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneNowPlayingOverlay.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneNowPlayingOverlay.cs index 532744a0fc..3ecd8ab550 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneNowPlayingOverlay.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneNowPlayingOverlay.cs @@ -80,12 +80,12 @@ namespace osu.Game.Tests.Visual.UserInterface AddStep("Store track", () => currentBeatmap = Beatmap.Value); AddStep(@"Seek track to 6 second", () => musicController.SeekTo(6000)); - AddUntilStep(@"Wait for current time to update", () => currentBeatmap.Track.CurrentTime > 5000); + AddUntilStep(@"Wait for current time to update", () => musicController.CurrentTrackTime > 5000); AddStep(@"Set previous", () => musicController.PreviousTrack()); AddAssert(@"Check beatmap didn't change", () => currentBeatmap == Beatmap.Value); - AddUntilStep("Wait for current time to update", () => currentBeatmap.Track.CurrentTime < 5000); + AddUntilStep("Wait for current time to update", () => musicController.CurrentTrackTime < 5000); AddStep(@"Set previous", () => musicController.PreviousTrack()); AddAssert(@"Check beatmap did change", () => currentBeatmap != Beatmap.Value); diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index b4b341634c..b2329f58ad 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -255,7 +255,7 @@ namespace osu.Game.Beatmaps new LargeTextureStore(host?.CreateTextureLoaderStore(Files.Store)), beatmapInfo, audioManager)); } - previous?.TransferTo(working); + // previous?.TransferTo(working); return working; } } diff --git a/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs b/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs index 39c5ccab27..33945a9eb1 100644 --- a/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs @@ -79,22 +79,6 @@ namespace osu.Game.Beatmaps } } - public override void RecycleTrack() - { - base.RecycleTrack(); - - trackStore?.Dispose(); - trackStore = null; - } - - public override void TransferTo(WorkingBeatmap other) - { - base.TransferTo(other); - - if (other is BeatmapManagerWorkingBeatmap owb && textureStore != null && BeatmapInfo.BackgroundEquals(other.BeatmapInfo)) - owb.textureStore = textureStore; - } - protected override Waveform GetWaveform() { try diff --git a/osu.Game/Beatmaps/IWorkingBeatmap.cs b/osu.Game/Beatmaps/IWorkingBeatmap.cs index 31975157a0..086b7502a2 100644 --- a/osu.Game/Beatmaps/IWorkingBeatmap.cs +++ b/osu.Game/Beatmaps/IWorkingBeatmap.cs @@ -26,11 +26,6 @@ namespace osu.Game.Beatmaps /// Texture Background { get; } - /// - /// Retrieves the audio track for this . - /// - Track Track { get; } - /// /// Retrieves the for the of this . /// diff --git a/osu.Game/Beatmaps/WorkingBeatmap.cs b/osu.Game/Beatmaps/WorkingBeatmap.cs index ac399e37c4..171201ca68 100644 --- a/osu.Game/Beatmaps/WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/WorkingBeatmap.cs @@ -40,7 +40,6 @@ namespace osu.Game.Beatmaps BeatmapSetInfo = beatmapInfo.BeatmapSet; Metadata = beatmapInfo.Metadata ?? BeatmapSetInfo?.Metadata ?? new BeatmapMetadata(); - track = new RecyclableLazy(() => GetTrack() ?? GetVirtualTrack(1000)); background = new RecyclableLazy(GetBackground, BackgroundStillValid); waveform = new RecyclableLazy(GetWaveform); storyboard = new RecyclableLazy(GetStoryboard); @@ -250,10 +249,9 @@ namespace osu.Game.Beatmaps protected abstract Texture GetBackground(); private readonly RecyclableLazy background; - public virtual bool TrackLoaded => track.IsResultAvailable; - public Track Track => track.Value; + public Track GetRealTrack() => GetTrack() ?? GetVirtualTrack(1000); + protected abstract Track GetTrack(); - private RecyclableLazy track; public bool WaveformLoaded => waveform.IsResultAvailable; public Waveform Waveform => waveform.Value; @@ -271,22 +269,6 @@ namespace osu.Game.Beatmaps protected virtual ISkin GetSkin() => new DefaultSkin(); private readonly RecyclableLazy skin; - /// - /// Transfer pieces of a beatmap to a new one, where possible, to save on loading. - /// - /// The new beatmap which is being switched to. - public virtual void TransferTo(WorkingBeatmap other) - { - if (track.IsResultAvailable && Track != null && BeatmapInfo.AudioEquals(other.BeatmapInfo)) - other.track = track; - } - - /// - /// Eagerly dispose of the audio track associated with this (if any). - /// Accessing track again will load a fresh instance. - /// - public virtual void RecycleTrack() => track.Recycle(); - ~WorkingBeatmap() { total_count.Value--; diff --git a/osu.Game/Graphics/Containers/BeatSyncedContainer.cs b/osu.Game/Graphics/Containers/BeatSyncedContainer.cs index df063f57d5..2dd28a01dc 100644 --- a/osu.Game/Graphics/Containers/BeatSyncedContainer.cs +++ b/osu.Game/Graphics/Containers/BeatSyncedContainer.cs @@ -7,6 +7,7 @@ using osu.Framework.Bindables; using osu.Framework.Graphics.Containers; using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; +using osu.Game.Overlays; namespace osu.Game.Graphics.Containers { @@ -14,6 +15,9 @@ namespace osu.Game.Graphics.Containers { protected readonly IBindable Beatmap = new Bindable(); + [Resolved] + private MusicController musicController { get; set; } + private int lastBeat; private TimingControlPoint lastTimingPoint; @@ -47,22 +51,18 @@ namespace osu.Game.Graphics.Containers protected override void Update() { - Track track = null; IBeatmap beatmap = null; double currentTrackTime = 0; TimingControlPoint timingPoint = null; EffectControlPoint effectPoint = null; - if (Beatmap.Value.TrackLoaded && Beatmap.Value.BeatmapLoaded) - { - track = Beatmap.Value.Track; + if (musicController.TrackLoaded && Beatmap.Value.BeatmapLoaded) beatmap = Beatmap.Value.Beatmap; - } - if (track != null && beatmap != null && track.IsRunning && track.Length > 0) + if (beatmap != null && musicController.IsPlaying && musicController.TrackLength > 0) { - currentTrackTime = track.CurrentTime + EarlyActivationMilliseconds; + currentTrackTime = musicController.CurrentTrackTime + EarlyActivationMilliseconds; timingPoint = beatmap.ControlPointInfo.TimingPointAt(currentTrackTime); effectPoint = beatmap.ControlPointInfo.EffectPointAt(currentTrackTime); @@ -98,7 +98,7 @@ namespace osu.Game.Graphics.Containers return; using (BeginDelayedSequence(-TimeSinceLastBeat, true)) - OnNewBeat(beatIndex, timingPoint, effectPoint, track?.CurrentAmplitudes ?? ChannelAmplitudes.Empty); + OnNewBeat(beatIndex, timingPoint, effectPoint, musicController.CurrentAmplitudes); lastBeat = beatIndex; lastTimingPoint = timingPoint; diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 26f7c3b93b..929254e8ad 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -431,19 +431,19 @@ namespace osu.Game if (newBeatmap != null) { - newBeatmap.Track.Completed += () => Scheduler.AddOnce(() => trackCompleted(newBeatmap)); + // MusicController.Completed += () => Scheduler.AddOnce(() => trackCompleted(newBeatmap)); newBeatmap.BeginAsyncLoad(); } - void trackCompleted(WorkingBeatmap b) - { - // the source of track completion is the audio thread, so the beatmap may have changed before firing. - if (Beatmap.Value != b) - return; - - if (!Beatmap.Value.Track.Looping && !Beatmap.Disabled) - MusicController.NextTrack(); - } + // void trackCompleted(WorkingBeatmap b) + // { + // // the source of track completion is the audio thread, so the beatmap may have changed before firing. + // if (Beatmap.Value != b) + // return; + // + // if (!MusicController.Looping && !Beatmap.Disabled) + // MusicController.NextTrack(); + // } } private void modsChanged(ValueChangedEvent> mods) @@ -555,6 +555,7 @@ namespace osu.Game BackButton.Receptor receptor; dependencies.CacheAs(idleTracker = new GameIdleTracker(6000)); + dependencies.CacheAs(MusicController = new MusicController()); AddRange(new Drawable[] { @@ -617,7 +618,7 @@ namespace osu.Game loadComponentSingleFile(new OnScreenDisplay(), Add, true); - loadComponentSingleFile(MusicController = new MusicController(), Add, true); + loadComponentSingleFile(MusicController, Add); loadComponentSingleFile(notifications.With(d => { diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index 98f60d52d3..24c1f7849c 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -238,16 +238,6 @@ namespace osu.Game Beatmap = new NonNullableBindable(defaultBeatmap); - // ScheduleAfterChildren is safety against something in the current frame accessing the previous beatmap's track - // and potentially causing a reload of it after just unloading. - // Note that the reason for this being added *has* been resolved, so it may be feasible to removed this if required. - Beatmap.BindValueChanged(b => ScheduleAfterChildren(() => - { - // compare to last beatmap as sometimes the two may share a track representation (optimisation, see WorkingBeatmap.TransferTo) - if (b.OldValue?.TrackLoaded == true && b.OldValue?.Track != b.NewValue?.Track) - b.OldValue.RecycleTrack(); - })); - dependencies.CacheAs>(Beatmap); dependencies.CacheAs(Beatmap); diff --git a/osu.Game/Overlays/Music/PlaylistOverlay.cs b/osu.Game/Overlays/Music/PlaylistOverlay.cs index b878aba489..c089158c01 100644 --- a/osu.Game/Overlays/Music/PlaylistOverlay.cs +++ b/osu.Game/Overlays/Music/PlaylistOverlay.cs @@ -30,6 +30,9 @@ namespace osu.Game.Overlays.Music [Resolved] private BeatmapManager beatmaps { get; set; } + [Resolved] + private MusicController musicController { get; set; } + private FilterControl filter; private Playlist list; @@ -80,10 +83,7 @@ namespace osu.Game.Overlays.Music BeatmapInfo toSelect = list.FirstVisibleSet?.Beatmaps?.FirstOrDefault(); if (toSelect != null) - { beatmap.Value = beatmaps.GetWorkingBeatmap(toSelect); - beatmap.Value.Track.Restart(); - } }; } @@ -116,12 +116,12 @@ namespace osu.Game.Overlays.Music { if (set.ID == (beatmap.Value?.BeatmapSetInfo?.ID ?? -1)) { - beatmap.Value?.Track?.Seek(0); + musicController.SeekTo(0); return; } beatmap.Value = beatmaps.GetWorkingBeatmap(set.Beatmaps.First()); - beatmap.Value.Track.Restart(); + musicController.Play(true); } } diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index a990f9a6ab..f5ca5a3a49 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -4,13 +4,18 @@ using System; using System.Collections.Generic; using System.Linq; +using JetBrains.Annotations; using osu.Framework.Allocation; +using osu.Framework.Audio; using osu.Framework.Audio.Track; using osu.Framework.Bindables; using osu.Framework.Graphics; +using osu.Framework.Graphics.Audio; +using osu.Framework.Graphics.Containers; using osu.Framework.Input.Bindings; using osu.Framework.Utils; using osu.Framework.Threading; +using osu.Framework.Timing; using osu.Game.Beatmaps; using osu.Game.Input.Bindings; using osu.Game.Overlays.OSD; @@ -21,7 +26,7 @@ namespace osu.Game.Overlays /// /// Handles playback of the global music track. /// - public class MusicController : Component, IKeyBindingHandler + public class MusicController : CompositeDrawable, IKeyBindingHandler, ITrack { [Resolved] private BeatmapManager beatmaps { get; set; } @@ -61,9 +66,23 @@ namespace osu.Game.Overlays [Resolved(canBeNull: true)] private OnScreenDisplay onScreenDisplay { get; set; } + [NotNull] + private readonly TrackContainer trackContainer; + + [CanBeNull] + private DrawableTrack drawableTrack; + + [CanBeNull] + private Track track; + private IBindable> managerUpdated; private IBindable> managerRemoved; + public MusicController() + { + InternalChild = trackContainer = new TrackContainer { RelativeSizeAxes = Axes.Both }; + } + [BackgroundDependencyLoader] private void load() { @@ -95,9 +114,35 @@ namespace osu.Game.Overlays } /// - /// Returns whether the current beatmap track is playing. + /// Returns whether the beatmap track is playing. /// - public bool IsPlaying => current?.Track.IsRunning ?? false; + public bool IsPlaying => drawableTrack?.IsRunning ?? false; + + /// + /// Returns whether the beatmap track is loaded. + /// + public bool TrackLoaded => drawableTrack?.IsLoaded == true; + + /// + /// Returns the current time of the beatmap track. + /// + public double CurrentTrackTime => drawableTrack?.CurrentTime ?? 0; + + /// + /// Returns the length of the beatmap track. + /// + public double TrackLength => drawableTrack?.Length ?? 0; + + public void AddAdjustment(AdjustableProperty type, BindableNumber adjustBindable) + => trackContainer.AddAdjustment(type, adjustBindable); + + public void RemoveAdjustment(AdjustableProperty type, BindableNumber adjustBindable) + => trackContainer.RemoveAdjustment(type, adjustBindable); + + public void Reset() => drawableTrack?.Reset(); + + [CanBeNull] + public IAdjustableClock GetTrackClock() => track; private void beatmapUpdated(ValueChangedEvent> weakSet) { @@ -130,7 +175,7 @@ namespace osu.Game.Overlays seekDelegate = Schedule(() => { if (!beatmap.Disabled) - current?.Track.Seek(position); + drawableTrack?.Seek(position); }); } @@ -142,9 +187,7 @@ namespace osu.Game.Overlays { if (IsUserPaused) return; - var track = current?.Track; - - if (track == null || track is TrackVirtual) + if (drawableTrack == null || drawableTrack.IsDummyDevice) { if (beatmap.Disabled) return; @@ -163,17 +206,15 @@ namespace osu.Game.Overlays /// Whether the operation was successful. public bool Play(bool restart = false) { - var track = current?.Track; - IsUserPaused = false; - if (track == null) + if (drawableTrack == null) return false; if (restart) - track.Restart(); + drawableTrack.Restart(); else if (!IsPlaying) - track.Start(); + drawableTrack.Start(); return true; } @@ -183,11 +224,9 @@ namespace osu.Game.Overlays /// public void Stop() { - var track = current?.Track; - IsUserPaused = true; - if (track?.IsRunning == true) - track.Stop(); + if (drawableTrack?.IsRunning == true) + drawableTrack.Stop(); } /// @@ -196,9 +235,7 @@ namespace osu.Game.Overlays /// Whether the operation was successful. public bool TogglePause() { - var track = current?.Track; - - if (track?.IsRunning == true) + if (drawableTrack?.IsRunning == true) Stop(); else Play(); @@ -220,7 +257,7 @@ namespace osu.Game.Overlays if (beatmap.Disabled) return PreviousTrackResult.None; - var currentTrackPosition = current?.Track.CurrentTime; + var currentTrackPosition = drawableTrack?.CurrentTime; if (currentTrackPosition >= restart_cutoff_point) { @@ -274,7 +311,7 @@ namespace osu.Game.Overlays { // if not scheduled, the previously track will be stopped one frame later (see ScheduleAfterChildren logic in GameBase). // we probably want to move this to a central method for switching to a new working beatmap in the future. - Schedule(() => beatmap.Value.Track.Restart()); + Schedule(() => drawableTrack?.Restart()); } private WorkingBeatmap current; @@ -307,6 +344,14 @@ namespace osu.Game.Overlays } current = beatmap.NewValue; + + drawableTrack?.Expire(); + drawableTrack = null; + track = null; + + if (current != null) + trackContainer.Add(drawableTrack = new DrawableTrack(track = current.GetRealTrack())); + TrackChanged?.Invoke(current, direction); ResetTrackAdjustments(); @@ -334,16 +379,15 @@ namespace osu.Game.Overlays public void ResetTrackAdjustments() { - var track = current?.Track; - if (track == null) + if (drawableTrack == null) return; - track.ResetSpeedAdjustments(); + drawableTrack.ResetSpeedAdjustments(); if (allowRateAdjustments) { foreach (var mod in mods.Value.OfType()) - mod.ApplyToTrack(track); + mod.ApplyToTrack(drawableTrack); } } @@ -394,6 +438,133 @@ namespace osu.Game.Overlays { } } + + private class TrackContainer : AudioContainer + { + } + + #region ITrack + + /// + /// The volume of this component. + /// + public BindableNumber Volume => drawableTrack?.Volume; // Todo: Bad + + /// + /// The playback balance of this sample (-1 .. 1 where 0 is centered) + /// + public BindableNumber Balance => drawableTrack?.Balance; // Todo: Bad + + /// + /// Rate at which the component is played back (affects pitch). 1 is 100% playback speed, or default frequency. + /// + public BindableNumber Frequency => drawableTrack?.Frequency; // Todo: Bad + + /// + /// Rate at which the component is played back (does not affect pitch). 1 is 100% playback speed. + /// + public BindableNumber Tempo => drawableTrack?.Tempo; // Todo: Bad + + public IBindable AggregateVolume => drawableTrack?.AggregateVolume; // Todo: Bad + + public IBindable AggregateBalance => drawableTrack?.AggregateBalance; // Todo: Bad + + public IBindable AggregateFrequency => drawableTrack?.AggregateFrequency; // Todo: Bad + + public IBindable AggregateTempo => drawableTrack?.AggregateTempo; // Todo: Bad + + /// + /// Overall playback rate (1 is 100%, -1 is reversed at 100%). + /// + public double Rate => AggregateFrequency.Value * AggregateTempo.Value; + + event Action ITrack.Completed + { + add + { + if (drawableTrack != null) + drawableTrack.Completed += value; + } + remove + { + if (drawableTrack != null) + drawableTrack.Completed -= value; + } + } + + event Action ITrack.Failed + { + add + { + if (drawableTrack != null) + drawableTrack.Failed += value; + } + remove + { + if (drawableTrack != null) + drawableTrack.Failed -= value; + } + } + + public bool Looping + { + get => drawableTrack?.Looping ?? false; + set + { + if (drawableTrack != null) + drawableTrack.Looping = value; + } + } + + public bool IsDummyDevice => drawableTrack?.IsDummyDevice ?? true; + + public double RestartPoint + { + get => drawableTrack?.RestartPoint ?? 0; + set + { + if (drawableTrack != null) + drawableTrack.RestartPoint = value; + } + } + + double ITrack.CurrentTime => CurrentTrackTime; + + double ITrack.Length + { + get => TrackLength; + set + { + if (drawableTrack != null) + drawableTrack.Length = value; + } + } + + public int? Bitrate => drawableTrack?.Bitrate; + + bool ITrack.IsRunning => IsPlaying; + + public bool IsReversed => drawableTrack?.IsReversed ?? false; + + public bool HasCompleted => drawableTrack?.HasCompleted ?? false; + + void ITrack.Reset() => drawableTrack?.Reset(); + + void ITrack.Restart() => Play(true); + + void ITrack.ResetSpeedAdjustments() => ResetTrackAdjustments(); + + bool ITrack.Seek(double seek) + { + SeekTo(seek); + return true; + } + + void ITrack.Start() => Play(); + + public ChannelAmplitudes CurrentAmplitudes => drawableTrack?.CurrentAmplitudes ?? ChannelAmplitudes.Empty; + + #endregion } public enum TrackChangeDirection diff --git a/osu.Game/Overlays/NowPlayingOverlay.cs b/osu.Game/Overlays/NowPlayingOverlay.cs index ebb4a96d14..fde6a52fee 100644 --- a/osu.Game/Overlays/NowPlayingOverlay.cs +++ b/osu.Game/Overlays/NowPlayingOverlay.cs @@ -234,14 +234,12 @@ namespace osu.Game.Overlays pendingBeatmapSwitch = null; } - var track = beatmap.Value?.TrackLoaded ?? false ? beatmap.Value.Track : null; - - if (track?.IsDummyDevice == false) + if (musicController.IsDummyDevice == false) { - progressBar.EndTime = track.Length; - progressBar.CurrentTime = track.CurrentTime; + progressBar.EndTime = musicController.TrackLength; + progressBar.CurrentTime = musicController.CurrentTrackTime; - playButton.Icon = track.IsRunning ? FontAwesome.Regular.PauseCircle : FontAwesome.Regular.PlayCircle; + playButton.Icon = musicController.IsPlaying ? FontAwesome.Regular.PauseCircle : FontAwesome.Regular.PlayCircle; } else { diff --git a/osu.Game/Rulesets/Mods/IApplicableToTrack.cs b/osu.Game/Rulesets/Mods/IApplicableToTrack.cs index 4d6d958e82..9b840cea08 100644 --- a/osu.Game/Rulesets/Mods/IApplicableToTrack.cs +++ b/osu.Game/Rulesets/Mods/IApplicableToTrack.cs @@ -10,6 +10,6 @@ namespace osu.Game.Rulesets.Mods /// public interface IApplicableToTrack : IApplicableMod { - void ApplyToTrack(Track track); + void ApplyToTrack(ITrack track); } } diff --git a/osu.Game/Rulesets/Mods/ModDaycore.cs b/osu.Game/Rulesets/Mods/ModDaycore.cs index bd98e735e5..9cefeb3340 100644 --- a/osu.Game/Rulesets/Mods/ModDaycore.cs +++ b/osu.Game/Rulesets/Mods/ModDaycore.cs @@ -27,11 +27,11 @@ namespace osu.Game.Rulesets.Mods }, true); } - public override void ApplyToTrack(Track track) + public override void ApplyToTrack(ITrack track) { // base.ApplyToTrack() intentionally not called (different tempo adjustment is applied) - track.AddAdjustment(AdjustableProperty.Frequency, freqAdjust); - track.AddAdjustment(AdjustableProperty.Tempo, tempoAdjust); + (track as Track)?.AddAdjustment(AdjustableProperty.Frequency, freqAdjust); + (track as Track)?.AddAdjustment(AdjustableProperty.Tempo, tempoAdjust); } } } diff --git a/osu.Game/Rulesets/Mods/ModNightcore.cs b/osu.Game/Rulesets/Mods/ModNightcore.cs index ed8eb2fb66..b34affa77f 100644 --- a/osu.Game/Rulesets/Mods/ModNightcore.cs +++ b/osu.Game/Rulesets/Mods/ModNightcore.cs @@ -38,11 +38,11 @@ namespace osu.Game.Rulesets.Mods }, true); } - public override void ApplyToTrack(Track track) + public override void ApplyToTrack(ITrack track) { // base.ApplyToTrack() intentionally not called (different tempo adjustment is applied) - track.AddAdjustment(AdjustableProperty.Frequency, freqAdjust); - track.AddAdjustment(AdjustableProperty.Tempo, tempoAdjust); + (track as Track)?.AddAdjustment(AdjustableProperty.Frequency, freqAdjust); + (track as Track)?.AddAdjustment(AdjustableProperty.Tempo, tempoAdjust); } public void ApplyToDrawableRuleset(DrawableRuleset drawableRuleset) diff --git a/osu.Game/Rulesets/Mods/ModRateAdjust.cs b/osu.Game/Rulesets/Mods/ModRateAdjust.cs index 874384686f..ee1280da39 100644 --- a/osu.Game/Rulesets/Mods/ModRateAdjust.cs +++ b/osu.Game/Rulesets/Mods/ModRateAdjust.cs @@ -12,9 +12,9 @@ namespace osu.Game.Rulesets.Mods { public abstract BindableNumber SpeedChange { get; } - public virtual void ApplyToTrack(Track track) + public virtual void ApplyToTrack(ITrack track) { - track.AddAdjustment(AdjustableProperty.Tempo, SpeedChange); + (track as Track)?.AddAdjustment(AdjustableProperty.Tempo, SpeedChange); } public virtual void ApplyToSample(SampleChannel sample) diff --git a/osu.Game/Rulesets/Mods/ModTimeRamp.cs b/osu.Game/Rulesets/Mods/ModTimeRamp.cs index 839d97f04e..0257e241b8 100644 --- a/osu.Game/Rulesets/Mods/ModTimeRamp.cs +++ b/osu.Game/Rulesets/Mods/ModTimeRamp.cs @@ -51,9 +51,9 @@ namespace osu.Game.Rulesets.Mods AdjustPitch.BindValueChanged(applyPitchAdjustment); } - public void ApplyToTrack(Track track) + public void ApplyToTrack(ITrack track) { - this.track = track; + this.track = track as Track; FinalRate.TriggerChange(); AdjustPitch.TriggerChange(); diff --git a/osu.Game/Screens/Edit/Components/BottomBarContainer.cs b/osu.Game/Screens/Edit/Components/BottomBarContainer.cs index cb5078a479..8d8c59b2ee 100644 --- a/osu.Game/Screens/Edit/Components/BottomBarContainer.cs +++ b/osu.Game/Screens/Edit/Components/BottomBarContainer.cs @@ -2,7 +2,6 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Allocation; -using osu.Framework.Audio.Track; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -18,7 +17,6 @@ namespace osu.Game.Screens.Edit.Components private const float contents_padding = 15; protected readonly IBindable Beatmap = new Bindable(); - protected Track Track => Beatmap.Value.Track; private readonly Drawable background; private readonly Container content; diff --git a/osu.Game/Screens/Edit/Components/PlaybackControl.cs b/osu.Game/Screens/Edit/Components/PlaybackControl.cs index 59b3d1c565..0a9b4f06a7 100644 --- a/osu.Game/Screens/Edit/Components/PlaybackControl.cs +++ b/osu.Game/Screens/Edit/Components/PlaybackControl.cs @@ -16,6 +16,7 @@ using osu.Framework.Input.Events; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; +using osu.Game.Overlays; using osuTK.Input; namespace osu.Game.Screens.Edit.Components @@ -27,6 +28,9 @@ namespace osu.Game.Screens.Edit.Components [Resolved] private EditorClock editorClock { get; set; } + [Resolved] + private MusicController musicController { get; set; } + private readonly BindableNumber tempo = new BindableDouble(1); [BackgroundDependencyLoader] @@ -62,12 +66,12 @@ namespace osu.Game.Screens.Edit.Components } }; - Track?.AddAdjustment(AdjustableProperty.Tempo, tempo); + musicController.AddAdjustment(AdjustableProperty.Tempo, tempo); } protected override void Dispose(bool isDisposing) { - Track?.RemoveAdjustment(AdjustableProperty.Tempo, tempo); + musicController?.RemoveAdjustment(AdjustableProperty.Tempo, tempo); base.Dispose(isDisposing); } 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 9e9ac93d23..a353f79ef4 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/MarkerPart.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/MarkerPart.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System; +using System.Diagnostics; using osuTK; using osu.Framework.Allocation; using osu.Framework.Graphics; @@ -58,7 +59,9 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts return; float markerPos = Math.Clamp(ToLocalSpace(screenPosition).X, 0, DrawWidth); - editorClock.SeekTo(markerPos / DrawWidth * editorClock.TrackLength); + + Debug.Assert(editorClock.TrackLength != null); + editorClock.SeekTo(markerPos / DrawWidth * editorClock.TrackLength.Value); }); } diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs index 4a7c3f26bc..446f7fdf88 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs @@ -8,6 +8,7 @@ using osuTK; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Beatmaps; +using osu.Game.Overlays; namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts { @@ -26,6 +27,9 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts protected override Container Content => content; + [Resolved] + private MusicController musicController { get; set; } + public TimelinePart(Container content = null) { AddInternal(this.content = content ?? new Container { RelativeSizeAxes = Axes.Both }); @@ -46,14 +50,14 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts private void updateRelativeChildSize() { // the track may not be loaded completely (only has a length once it is). - if (!Beatmap.Value.Track.IsLoaded) + if (!musicController.TrackLoaded) { content.RelativeChildSize = Vector2.One; Schedule(updateRelativeChildSize); return; } - content.RelativeChildSize = new Vector2((float)Math.Max(1, Beatmap.Value.Track.Length), 1); + content.RelativeChildSize = new Vector2((float)Math.Max(1, musicController.TrackLength), 1); } protected virtual void LoadBeatmap(WorkingBeatmap beatmap) diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs index 717d60b4f3..f35e5defd8 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs @@ -3,7 +3,6 @@ using System; using osu.Framework.Allocation; -using osu.Framework.Audio.Track; using osu.Framework.Bindables; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; @@ -11,6 +10,7 @@ using osu.Framework.Graphics.Audio; using osu.Framework.Input.Events; using osu.Game.Beatmaps; using osu.Game.Graphics; +using osu.Game.Overlays; using osu.Game.Rulesets.Edit; using osuTK; @@ -26,6 +26,9 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline [Resolved] private EditorClock editorClock { get; set; } + [Resolved] + private MusicController musicController { get; set; } + public Timeline() { ZoomDuration = 200; @@ -57,18 +60,21 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline Beatmap.BindValueChanged(b => { waveform.Waveform = b.NewValue.Waveform; - track = b.NewValue.Track; - if (track.Length > 0) + // Todo: Wrong. + Schedule(() => { - MaxZoom = getZoomLevelForVisibleMilliseconds(500); - MinZoom = getZoomLevelForVisibleMilliseconds(10000); - Zoom = getZoomLevelForVisibleMilliseconds(2000); - } + if (musicController.TrackLength > 0) + { + MaxZoom = getZoomLevelForVisibleMilliseconds(500); + MinZoom = getZoomLevelForVisibleMilliseconds(10000); + Zoom = getZoomLevelForVisibleMilliseconds(2000); + } + }); }, true); } - private float getZoomLevelForVisibleMilliseconds(double milliseconds) => (float)(track.Length / milliseconds); + private float getZoomLevelForVisibleMilliseconds(double milliseconds) => (float)(musicController.TrackLength / milliseconds); /// /// The timeline's scroll position in the last frame. @@ -90,8 +96,6 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline /// private bool trackWasPlaying; - private Track track; - protected override void Update() { base.Update(); @@ -129,18 +133,18 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline private void seekTrackToCurrent() { - if (!track.IsLoaded) + if (!musicController.TrackLoaded) return; - editorClock.Seek(Current / Content.DrawWidth * track.Length); + editorClock.Seek(Current / Content.DrawWidth * musicController.TrackLength); } private void scrollToTrackTime() { - if (!track.IsLoaded || track.Length == 0) + if (!musicController.TrackLoaded || musicController.TrackLength == 0) return; - ScrollTo((float)(editorClock.CurrentTime / track.Length) * Content.DrawWidth, false); + ScrollTo((float)(editorClock.CurrentTime / musicController.TrackLength) * Content.DrawWidth, false); } protected override bool OnMouseDown(MouseDownEvent e) @@ -184,7 +188,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline new SnapResult(screenSpacePosition, beatSnapProvider.SnapTime(getTimeFromPosition(Content.ToLocalSpace(screenSpacePosition)))); private double getTimeFromPosition(Vector2 localPosition) => - (localPosition.X / Content.DrawWidth) * track.Length; + (localPosition.X / Content.DrawWidth) * musicController.TrackLength; public float GetBeatSnapDistanceAt(double referenceTime) => throw new NotImplementedException(); diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineTickDisplay.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineTickDisplay.cs index 36ee976bf7..a833b354ed 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineTickDisplay.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineTickDisplay.cs @@ -3,10 +3,9 @@ using System.Linq; using osu.Framework.Allocation; -using osu.Framework.Bindables; using osu.Framework.Graphics; -using osu.Game.Beatmaps; using osu.Game.Graphics; +using osu.Game.Overlays; using osu.Game.Screens.Edit.Components.Timelines.Summary.Parts; using osu.Game.Screens.Edit.Components.Timelines.Summary.Visualisations; @@ -18,7 +17,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline private EditorBeatmap beatmap { get; set; } [Resolved] - private Bindable working { get; set; } + private MusicController musicController { get; set; } [Resolved] private BindableBeatDivisor beatDivisor { get; set; } @@ -44,7 +43,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline for (var i = 0; i < beatmap.ControlPointInfo.TimingPoints.Count; i++) { var point = beatmap.ControlPointInfo.TimingPoints[i]; - var until = i + 1 < beatmap.ControlPointInfo.TimingPoints.Count ? beatmap.ControlPointInfo.TimingPoints[i + 1].Time : working.Value.Track.Length; + var until = i + 1 < beatmap.ControlPointInfo.TimingPoints.Count ? beatmap.ControlPointInfo.TimingPoints[i + 1].Time : musicController.TrackLength; int beat = 0; diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index d92f3922c3..756b03d049 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -28,6 +28,7 @@ using osu.Framework.Logging; using osu.Game.Beatmaps; using osu.Game.Graphics.Cursor; using osu.Game.Input.Bindings; +using osu.Game.Overlays; using osu.Game.Rulesets.Edit; using osu.Game.Screens.Edit.Compose; using osu.Game.Screens.Edit.Setup; @@ -53,6 +54,9 @@ namespace osu.Game.Screens.Edit [Resolved] private BeatmapManager beatmapManager { get; set; } + [Resolved] + private MusicController musicController { get; set; } + private Box bottomBackground; private Container screenContainer; @@ -79,7 +83,7 @@ namespace osu.Game.Screens.Edit beatDivisor.BindValueChanged(divisor => Beatmap.Value.BeatmapInfo.BeatDivisor = divisor.NewValue); // Todo: should probably be done at a DrawableRuleset level to share logic with Player. - var sourceClock = (IAdjustableClock)Beatmap.Value.Track ?? new StopwatchClock(); + var sourceClock = musicController.GetTrackClock() ?? new StopwatchClock(); clock = new EditorClock(Beatmap.Value, beatDivisor) { IsCoupled = false }; clock.ChangeSource(sourceClock); @@ -346,7 +350,7 @@ namespace osu.Game.Screens.Edit private void resetTrack(bool seekToStart = false) { - Beatmap.Value.Track?.Stop(); + musicController.Stop(); if (seekToStart) { diff --git a/osu.Game/Screens/Edit/EditorClock.cs b/osu.Game/Screens/Edit/EditorClock.cs index d4d0feb813..4cb24f90a6 100644 --- a/osu.Game/Screens/Edit/EditorClock.cs +++ b/osu.Game/Screens/Edit/EditorClock.cs @@ -2,13 +2,16 @@ // See the LICENCE file in the repository root for full licence text. using System; +using System.Diagnostics; using System.Linq; +using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Transforms; using osu.Framework.Utils; using osu.Framework.Timing; using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; +using osu.Game.Overlays; namespace osu.Game.Screens.Edit { @@ -17,7 +20,7 @@ namespace osu.Game.Screens.Edit /// public class EditorClock : Component, IFrameBasedClock, IAdjustableClock, ISourceChangeableClock { - public readonly double TrackLength; + public double? TrackLength { get; private set; } public ControlPointInfo ControlPointInfo; @@ -25,12 +28,15 @@ namespace osu.Game.Screens.Edit private readonly DecoupleableInterpolatingFramedClock underlyingClock; + [Resolved] + private MusicController musicController { get; set; } + public EditorClock(WorkingBeatmap beatmap, BindableBeatDivisor beatDivisor) - : this(beatmap.Beatmap.ControlPointInfo, beatmap.Track.Length, beatDivisor) + : this(beatmap.Beatmap.ControlPointInfo, null, beatDivisor) { } - public EditorClock(ControlPointInfo controlPointInfo, double trackLength, BindableBeatDivisor beatDivisor) + public EditorClock(ControlPointInfo controlPointInfo, double? trackLength, BindableBeatDivisor beatDivisor) { this.beatDivisor = beatDivisor; @@ -45,6 +51,13 @@ namespace osu.Game.Screens.Edit { } + [BackgroundDependencyLoader] + private void load() + { + // Todo: What. + TrackLength ??= musicController.TrackLength; + } + /// /// Seek to the closest snappable beat from a time. /// @@ -135,7 +148,8 @@ namespace osu.Game.Screens.Edit seekTime = timingPoint.Time; // Ensure the sought point is within the boundaries - seekTime = Math.Clamp(seekTime, 0, TrackLength); + Debug.Assert(TrackLength != null); + seekTime = Math.Clamp(seekTime, 0, TrackLength.Value); SeekTo(seekTime); } diff --git a/osu.Game/Screens/Menu/IntroScreen.cs b/osu.Game/Screens/Menu/IntroScreen.cs index 5f91aaad15..7da5df2723 100644 --- a/osu.Game/Screens/Menu/IntroScreen.cs +++ b/osu.Game/Screens/Menu/IntroScreen.cs @@ -12,6 +12,7 @@ using osu.Framework.Screens; using osu.Game.Beatmaps; using osu.Game.Configuration; using osu.Game.IO.Archives; +using osu.Game.Overlays; using osu.Game.Screens.Backgrounds; using osu.Game.Skinning; using osuTK; @@ -43,7 +44,8 @@ namespace osu.Game.Screens.Menu private WorkingBeatmap initialBeatmap; - protected Track Track => initialBeatmap?.Track; + [Resolved] + protected MusicController MusicController { get; private set; } private readonly BindableDouble exitingVolumeFade = new BindableDouble(1); @@ -111,7 +113,7 @@ namespace osu.Game.Screens.Menu if (setInfo != null) { initialBeatmap = beatmaps.GetWorkingBeatmap(setInfo.Beatmaps[0]); - UsingThemedIntro = !(Track is TrackVirtual); + UsingThemedIntro = !MusicController.IsDummyDevice; } return UsingThemedIntro; @@ -150,7 +152,7 @@ namespace osu.Game.Screens.Menu { // Only start the current track if it is the menu music. A beatmap's track is started when entering the Main Menu. if (UsingThemedIntro) - Track.Restart(); + MusicController.Play(true); } protected override void LogoArriving(OsuLogo logo, bool resuming) diff --git a/osu.Game/Screens/Menu/IntroTriangles.cs b/osu.Game/Screens/Menu/IntroTriangles.cs index a9ef20436f..86a6fa3802 100644 --- a/osu.Game/Screens/Menu/IntroTriangles.cs +++ b/osu.Game/Screens/Menu/IntroTriangles.cs @@ -59,7 +59,7 @@ namespace osu.Game.Screens.Menu LoadComponentAsync(new TrianglesIntroSequence(logo, background) { RelativeSizeAxes = Axes.Both, - Clock = new FramedClock(UsingThemedIntro ? Track : null), + Clock = new FramedClock(UsingThemedIntro ? MusicController.GetTrackClock() : null), LoadMenu = LoadMenu }, t => { diff --git a/osu.Game/Screens/Menu/IntroWelcome.cs b/osu.Game/Screens/Menu/IntroWelcome.cs index bf42e36e8c..62cada577d 100644 --- a/osu.Game/Screens/Menu/IntroWelcome.cs +++ b/osu.Game/Screens/Menu/IntroWelcome.cs @@ -11,6 +11,7 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Textures; +using osu.Game.Overlays; using osu.Game.Screens.Backgrounds; using osuTK.Graphics; @@ -30,6 +31,9 @@ namespace osu.Game.Screens.Menu Alpha = 0, }; + [Resolved] + private MusicController musicController { get; set; } + private BackgroundScreenDefault background; [BackgroundDependencyLoader] @@ -40,7 +44,7 @@ namespace osu.Game.Screens.Menu pianoReverb = audio.Samples.Get(@"Intro/Welcome/welcome_piano"); - Track.Looping = true; + musicController.Looping = true; } protected override void LogoArriving(OsuLogo logo, bool resuming) diff --git a/osu.Game/Screens/Menu/LogoVisualisation.cs b/osu.Game/Screens/Menu/LogoVisualisation.cs index ebbb19636c..349654165f 100644 --- a/osu.Game/Screens/Menu/LogoVisualisation.cs +++ b/osu.Game/Screens/Menu/LogoVisualisation.cs @@ -20,6 +20,7 @@ using osu.Framework.Audio; using osu.Framework.Audio.Track; using osu.Framework.Bindables; using osu.Framework.Utils; +using osu.Game.Overlays; namespace osu.Game.Screens.Menu { @@ -74,6 +75,9 @@ namespace osu.Game.Screens.Menu /// public float Magnitude { get; set; } = 1; + [Resolved] + private MusicController musicController { get; set; } + private readonly float[] frequencyAmplitudes = new float[256]; private IShader shader; @@ -103,15 +107,15 @@ namespace osu.Game.Screens.Menu private void updateAmplitudes() { - var effect = beatmap.Value.BeatmapLoaded && beatmap.Value.TrackLoaded - ? beatmap.Value.Beatmap?.ControlPointInfo.EffectPointAt(beatmap.Value.Track.CurrentTime) + var effect = beatmap.Value.BeatmapLoaded && musicController.TrackLoaded + ? beatmap.Value.Beatmap?.ControlPointInfo.EffectPointAt(musicController.CurrentTrackTime) : null; for (int i = 0; i < temporalAmplitudes.Length; i++) temporalAmplitudes[i] = 0; - if (beatmap.Value.TrackLoaded) - addAmplitudesFromSource(beatmap.Value.Track); + if (musicController.TrackLoaded) + addAmplitudesFromSource(musicController); foreach (var source in amplitudeSources) addAmplitudesFromSource(source); diff --git a/osu.Game/Screens/Menu/MainMenu.cs b/osu.Game/Screens/Menu/MainMenu.cs index 57252d557e..c422f57332 100644 --- a/osu.Game/Screens/Menu/MainMenu.cs +++ b/osu.Game/Screens/Menu/MainMenu.cs @@ -5,7 +5,6 @@ using System.Linq; using osuTK; using osuTK.Graphics; using osu.Framework.Allocation; -using osu.Framework.Audio.Track; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Platform; @@ -62,8 +61,6 @@ namespace osu.Game.Screens.Menu protected override BackgroundScreen CreateBackground() => background; - internal Track Track { get; private set; } - private Bindable holdDelay; private Bindable loginDisplayed; @@ -172,20 +169,23 @@ namespace osu.Game.Screens.Menu [Resolved] private Storage storage { get; set; } + [Resolved] + private MusicController musicController { get; set; } + public override void OnEntering(IScreen last) { base.OnEntering(last); buttons.FadeInFromZero(500); - Track = Beatmap.Value.Track; var metadata = Beatmap.Value.Metadata; - if (last is IntroScreen && Track != null) + if (last is IntroScreen && musicController.TrackLoaded) { - if (!Track.IsRunning) + // Todo: Wrong. + if (!musicController.IsPlaying) { - Track.Seek(metadata.PreviewTime != -1 ? metadata.PreviewTime : 0.4f * Track.Length); - Track.Start(); + musicController.SeekTo(metadata.PreviewTime != -1 ? metadata.PreviewTime : 0.4f * musicController.TrackLength); + musicController.Play(); } } diff --git a/osu.Game/Screens/Menu/OsuLogo.cs b/osu.Game/Screens/Menu/OsuLogo.cs index f5e4b078da..1feb2481c3 100644 --- a/osu.Game/Screens/Menu/OsuLogo.cs +++ b/osu.Game/Screens/Menu/OsuLogo.cs @@ -17,6 +17,7 @@ using osu.Framework.Utils; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Graphics.Backgrounds; using osu.Game.Graphics.Containers; +using osu.Game.Overlays; using osuTK; using osuTK.Graphics; using osuTK.Input; @@ -46,7 +47,6 @@ namespace osu.Game.Screens.Menu private SampleChannel sampleBeat; private readonly Container colourAndTriangles; - private readonly Triangles triangles; /// @@ -319,6 +319,9 @@ namespace osu.Game.Screens.Menu intro.Delay(length + fade).FadeOut(); } + [Resolved] + private MusicController musicController { get; set; } + protected override void Update() { base.Update(); @@ -327,9 +330,9 @@ namespace osu.Game.Screens.Menu const float velocity_adjust_cutoff = 0.98f; const float paused_velocity = 0.5f; - if (Beatmap.Value.Track.IsRunning) + if (musicController.IsPlaying) { - var maxAmplitude = lastBeatIndex >= 0 ? Beatmap.Value.Track.CurrentAmplitudes.Maximum : 0; + var maxAmplitude = lastBeatIndex >= 0 ? musicController.CurrentAmplitudes.Maximum : 0; logoAmplitudeContainer.Scale = new Vector2((float)Interpolation.Damp(logoAmplitudeContainer.Scale.X, 1 - Math.Max(0, maxAmplitude - scale_adjust_cutoff) * 0.04f, 0.9f, Time.Elapsed)); if (maxAmplitude > velocity_adjust_cutoff) diff --git a/osu.Game/Screens/Multi/Match/Components/ReadyButton.cs b/osu.Game/Screens/Multi/Match/Components/ReadyButton.cs index a64f24dd7e..032c8d5ca9 100644 --- a/osu.Game/Screens/Multi/Match/Components/ReadyButton.cs +++ b/osu.Game/Screens/Multi/Match/Components/ReadyButton.cs @@ -10,6 +10,7 @@ using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Graphics.UserInterface; using osu.Game.Online.Multiplayer; +using osu.Game.Overlays; namespace osu.Game.Screens.Multi.Match.Components { @@ -26,6 +27,9 @@ namespace osu.Game.Screens.Multi.Match.Components [Resolved] private BeatmapManager beatmaps { get; set; } + [Resolved] + private MusicController musicController { get; set; } + private bool hasBeatmap; public ReadyButton() @@ -100,7 +104,7 @@ namespace osu.Game.Screens.Multi.Match.Components return; } - bool hasEnoughTime = DateTimeOffset.UtcNow.AddSeconds(30).AddMilliseconds(gameBeatmap.Value.Track.Length) < endDate.Value; + bool hasEnoughTime = DateTimeOffset.UtcNow.AddSeconds(30).AddMilliseconds(musicController.TrackLength) < endDate.Value; Enabled.Value = hasBeatmap && hasEnoughTime; } diff --git a/osu.Game/Screens/Multi/Multiplayer.cs b/osu.Game/Screens/Multi/Multiplayer.cs index 4912df17b1..2d74434c76 100644 --- a/osu.Game/Screens/Multi/Multiplayer.cs +++ b/osu.Game/Screens/Multi/Multiplayer.cs @@ -52,7 +52,7 @@ namespace osu.Game.Screens.Multi private readonly Bindable currentFilter = new Bindable(new FilterCriteria()); [Resolved] - private MusicController music { get; set; } + private MusicController musicController { get; set; } [Cached(Type = typeof(IRoomManager))] private RoomManager roomManager; @@ -343,15 +343,9 @@ namespace osu.Game.Screens.Multi { if (screenStack.CurrentScreen is MatchSubScreen) { - var track = Beatmap.Value?.Track; - - if (track != null) - { - track.RestartPoint = Beatmap.Value.Metadata.PreviewTime; - track.Looping = true; - - music.EnsurePlayingSomething(); - } + musicController.RestartPoint = Beatmap.Value.Metadata.PreviewTime; + musicController.Looping = true; + musicController.EnsurePlayingSomething(); } else { @@ -361,13 +355,8 @@ namespace osu.Game.Screens.Multi private void cancelLooping() { - var track = Beatmap?.Value?.Track; - - if (track != null) - { - track.Looping = false; - track.RestartPoint = 0; - } + musicController.Looping = false; + musicController.RestartPoint = 0; } protected override void Dispose(bool isDisposing) diff --git a/osu.Game/Screens/Play/FailAnimation.cs b/osu.Game/Screens/Play/FailAnimation.cs index 54c644c999..0e0ef8c675 100644 --- a/osu.Game/Screens/Play/FailAnimation.cs +++ b/osu.Game/Screens/Play/FailAnimation.cs @@ -8,10 +8,10 @@ using System; using System.Collections.Generic; using osu.Framework.Allocation; using osu.Framework.Audio.Sample; -using osu.Framework.Audio.Track; using osu.Framework.Graphics; using osu.Framework.Utils; using osu.Game.Beatmaps; +using osu.Game.Overlays; using osu.Game.Rulesets.Objects.Drawables; using osuTK; using osuTK.Graphics; @@ -30,12 +30,13 @@ namespace osu.Game.Screens.Play private readonly BindableDouble trackFreq = new BindableDouble(1); - private Track track; - private const float duration = 2500; private SampleChannel failSample; + [Resolved] + private MusicController musicController { get; set; } + public FailAnimation(DrawableRuleset drawableRuleset) { this.drawableRuleset = drawableRuleset; @@ -44,7 +45,6 @@ namespace osu.Game.Screens.Play [BackgroundDependencyLoader] private void load(AudioManager audio, IBindable beatmap) { - track = beatmap.Value.Track; failSample = audio.Samples.Get(@"Gameplay/failsound"); } @@ -68,7 +68,7 @@ namespace osu.Game.Screens.Play Expire(); }); - track.AddAdjustment(AdjustableProperty.Frequency, trackFreq); + musicController.AddAdjustment(AdjustableProperty.Frequency, trackFreq); applyToPlayfield(drawableRuleset.Playfield); drawableRuleset.Playfield.HitObjectContainer.FlashColour(Color4.Red, 500); @@ -107,7 +107,7 @@ namespace osu.Game.Screens.Play protected override void Dispose(bool isDisposing) { base.Dispose(isDisposing); - track?.RemoveAdjustment(AdjustableProperty.Frequency, trackFreq); + musicController?.RemoveAdjustment(AdjustableProperty.Frequency, trackFreq); } } } diff --git a/osu.Game/Screens/Play/GameplayClockContainer.cs b/osu.Game/Screens/Play/GameplayClockContainer.cs index 0653373c91..cf4678ab29 100644 --- a/osu.Game/Screens/Play/GameplayClockContainer.cs +++ b/osu.Game/Screens/Play/GameplayClockContainer.cs @@ -8,13 +8,13 @@ using System.Threading.Tasks; using osu.Framework; using osu.Framework.Allocation; using osu.Framework.Audio; -using osu.Framework.Audio.Track; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Timing; using osu.Game.Beatmaps; using osu.Game.Configuration; +using osu.Game.Overlays; using osu.Game.Rulesets.Mods; namespace osu.Game.Screens.Play @@ -27,10 +27,8 @@ namespace osu.Game.Screens.Play private readonly WorkingBeatmap beatmap; private readonly IReadOnlyList mods; - /// - /// The 's track. - /// - private Track track; + [Resolved] + private MusicController musicController { get; set; } public readonly BindableBool IsPaused = new BindableBool(); @@ -72,8 +70,6 @@ namespace osu.Game.Screens.Play RelativeSizeAxes = Axes.Both; - track = beatmap.Track; - adjustableClock = new DecoupleableInterpolatingFramedClock { IsCoupled = false }; // Lazer's audio timings in general doesn't match stable. This is the result of user testing, albeit limited. @@ -125,15 +121,15 @@ namespace osu.Game.Screens.Play { // The Reset() call below causes speed adjustments to be reset in an async context, leading to deadlocks. // The deadlock can be prevented by resetting the track synchronously before entering the async context. - track.ResetSpeedAdjustments(); + musicController.Reset(); Task.Run(() => { - track.Reset(); + musicController.Reset(); Schedule(() => { - adjustableClock.ChangeSource(track); + adjustableClock.ChangeSource(musicController.GetTrackClock()); updateRate(); if (!IsPaused.Value) @@ -194,20 +190,6 @@ namespace osu.Game.Screens.Play IsPaused.Value = true; } - /// - /// Changes the backing clock to avoid using the originally provided beatmap's track. - /// - public void StopUsingBeatmapClock() - { - if (track != beatmap.Track) - return; - - removeSourceClockAdjustments(); - - track = new TrackVirtual(beatmap.Track.Length); - adjustableClock.ChangeSource(track); - } - protected override void Update() { if (!IsPaused.Value) @@ -220,31 +202,23 @@ namespace osu.Game.Screens.Play private void updateRate() { - if (track == null) return; - speedAdjustmentsApplied = true; - track.ResetSpeedAdjustments(); - - track.AddAdjustment(AdjustableProperty.Frequency, pauseFreqAdjust); - track.AddAdjustment(AdjustableProperty.Tempo, UserPlaybackRate); - - foreach (var mod in mods.OfType()) - mod.ApplyToTrack(track); + musicController.ResetTrackAdjustments(); + musicController.AddAdjustment(AdjustableProperty.Frequency, pauseFreqAdjust); + musicController.AddAdjustment(AdjustableProperty.Tempo, UserPlaybackRate); } protected override void Dispose(bool isDisposing) { base.Dispose(isDisposing); - removeSourceClockAdjustments(); - track = null; } private void removeSourceClockAdjustments() { if (speedAdjustmentsApplied) { - track.ResetSpeedAdjustments(); + musicController.ResetTrackAdjustments(); speedAdjustmentsApplied = false; } } diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 74a5ee8309..9ba2732920 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -4,7 +4,6 @@ using osu.Framework.Allocation; using osu.Framework.Audio; using osu.Framework.Audio.Sample; -using osu.Framework.Audio.Track; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -561,8 +560,11 @@ namespace osu.Game.Screens.Select BeatmapDetails.Refresh(); - Beatmap.Value.Track.Looping = true; - music?.ResetTrackAdjustments(); + if (music != null) + { + music.Looping = true; + music.ResetTrackAdjustments(); + } if (Beatmap != null && !Beatmap.Value.BeatmapSetInfo.DeletePending) { @@ -586,8 +588,8 @@ namespace osu.Game.Screens.Select BeatmapOptions.Hide(); - if (Beatmap.Value.Track != null) - Beatmap.Value.Track.Looping = false; + if (music != null) + music.Looping = false; this.ScaleTo(1.1f, 250, Easing.InSine); @@ -608,8 +610,8 @@ namespace osu.Game.Screens.Select FilterControl.Deactivate(); - if (Beatmap.Value.Track != null) - Beatmap.Value.Track.Looping = false; + if (music != null) + music.Looping = false; return false; } @@ -650,28 +652,18 @@ namespace osu.Game.Screens.Select BeatmapDetails.Beatmap = beatmap; - if (beatmap.Track != null) - beatmap.Track.Looping = true; + if (music != null) + music.Looping = false; } - private readonly WeakReference lastTrack = new WeakReference(null); - /// /// Ensures some music is playing for the current track. /// Will resume playback from a manual user pause if the track has changed. /// private void ensurePlayingSelected() { - Track track = Beatmap.Value.Track; - - bool isNewTrack = !lastTrack.TryGetTarget(out var last) || last != track; - - track.RestartPoint = Beatmap.Value.Metadata.PreviewTime; - - if (!track.IsRunning && (music?.IsUserPaused != true || isNewTrack)) - music?.Play(true); - - lastTrack.SetTarget(track); + music.RestartPoint = Beatmap.Value.Metadata.PreviewTime; + music.EnsurePlayingSomething(); } private void carouselBeatmapsLoaded() diff --git a/osu.Game/Tests/Beatmaps/TestWorkingBeatmap.cs b/osu.Game/Tests/Beatmaps/TestWorkingBeatmap.cs index cdf9170701..ee04142035 100644 --- a/osu.Game/Tests/Beatmaps/TestWorkingBeatmap.cs +++ b/osu.Game/Tests/Beatmaps/TestWorkingBeatmap.cs @@ -27,8 +27,6 @@ namespace osu.Game.Tests.Beatmaps this.storyboard = storyboard; } - public override bool TrackLoaded => true; - public override bool BeatmapLoaded => true; protected override IBeatmap GetBeatmap() => beatmap; diff --git a/osu.Game/Tests/Visual/EditorClockTestScene.cs b/osu.Game/Tests/Visual/EditorClockTestScene.cs index f0ec638fc9..5226a49def 100644 --- a/osu.Game/Tests/Visual/EditorClockTestScene.cs +++ b/osu.Game/Tests/Visual/EditorClockTestScene.cs @@ -44,7 +44,7 @@ namespace osu.Game.Tests.Visual private void beatmapChanged(ValueChangedEvent e) { Clock.ControlPointInfo = e.NewValue.Beatmap.ControlPointInfo; - Clock.ChangeSource((IAdjustableClock)e.NewValue.Track ?? new StopwatchClock()); + Clock.ChangeSource(MusicController.GetTrackClock() ?? new StopwatchClock()); Clock.ProcessFrame(); } diff --git a/osu.Game/Tests/Visual/OsuTestScene.cs b/osu.Game/Tests/Visual/OsuTestScene.cs index 866fc215d6..e968f7e675 100644 --- a/osu.Game/Tests/Visual/OsuTestScene.cs +++ b/osu.Game/Tests/Visual/OsuTestScene.cs @@ -20,6 +20,7 @@ using osu.Framework.Timing; using osu.Game.Beatmaps; using osu.Game.Database; using osu.Game.Online.API; +using osu.Game.Overlays; using osu.Game.Rulesets; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.UI; @@ -135,6 +136,9 @@ namespace osu.Game.Tests.Visual [Resolved] protected AudioManager Audio { get; private set; } + [Resolved] + protected MusicController MusicController { get; private set; } + /// /// Creates the ruleset to be used for this test scene. /// @@ -164,8 +168,8 @@ namespace osu.Game.Tests.Visual rulesetDependencies?.Dispose(); - if (Beatmap?.Value.TrackLoaded == true) - Beatmap.Value.Track.Stop(); + if (MusicController?.TrackLoaded == true) + MusicController.Stop(); if (contextFactory.IsValueCreated) contextFactory.Value.ResetDatabase(); diff --git a/osu.Game/Tests/Visual/RateAdjustedBeatmapTestScene.cs b/osu.Game/Tests/Visual/RateAdjustedBeatmapTestScene.cs index ad24ffc7b8..e7cb461d7b 100644 --- a/osu.Game/Tests/Visual/RateAdjustedBeatmapTestScene.cs +++ b/osu.Game/Tests/Visual/RateAdjustedBeatmapTestScene.cs @@ -13,7 +13,7 @@ namespace osu.Game.Tests.Visual base.Update(); // note that this will override any mod rate application - Beatmap.Value.Track.Tempo.Value = Clock.Rate; + MusicController.Tempo.Value = Clock.Rate; } } } From 5c05fe3988ad5ba9c92e908628f2d11def1c9376 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 5 Aug 2020 21:10:38 +0900 Subject: [PATCH 009/320] Expose track from MusicController --- .../TestSceneHoldNoteInput.cs | 2 +- .../TestSceneOutOfOrderHits.cs | 2 +- .../TestSceneSliderInput.cs | 2 +- .../Skins/TestSceneBeatmapSkinResources.cs | 2 +- .../Visual/Editing/TimelineTestScene.cs | 6 +- .../Visual/Gameplay/TestScenePause.cs | 2 +- .../Visual/Gameplay/TestScenePlayerLoader.cs | 6 +- .../Visual/Gameplay/TestSceneStoryboard.cs | 8 +- .../Visual/Menus/TestSceneIntroWelcome.cs | 2 +- .../Navigation/TestSceneScreenNavigation.cs | 13 +- .../TestSceneBeatSyncedContainer.cs | 3 +- .../TestSceneNowPlayingOverlay.cs | 4 +- .../Containers/BeatSyncedContainer.cs | 14 +- osu.Game/Overlays/MusicController.cs | 190 ++---------------- osu.Game/Overlays/NowPlayingOverlay.cs | 12 +- osu.Game/Rulesets/Mods/IApplicableToTrack.cs | 3 +- osu.Game/Rulesets/Mods/ModDaycore.cs | 7 +- osu.Game/Rulesets/Mods/ModNightcore.cs | 6 +- osu.Game/Rulesets/Mods/ModRateAdjust.cs | 4 +- osu.Game/Rulesets/Mods/ModTimeRamp.cs | 10 +- .../Edit/Components/PlaybackControl.cs | 4 +- .../Timelines/Summary/Parts/TimelinePart.cs | 4 +- .../Compose/Components/Timeline/Timeline.cs | 31 +-- .../Timeline/TimelineTickDisplay.cs | 3 +- osu.Game/Screens/Edit/Editor.cs | 2 +- osu.Game/Screens/Edit/EditorClock.cs | 2 +- osu.Game/Screens/Menu/IntroScreen.cs | 4 +- osu.Game/Screens/Menu/IntroTriangles.cs | 2 +- osu.Game/Screens/Menu/IntroWelcome.cs | 3 +- osu.Game/Screens/Menu/LogoVisualisation.cs | 5 +- osu.Game/Screens/Menu/MainMenu.cs | 10 +- osu.Game/Screens/Menu/OsuLogo.cs | 4 +- .../Multi/Match/Components/ReadyButton.cs | 2 +- osu.Game/Screens/Multi/Multiplayer.cs | 17 +- osu.Game/Screens/Play/FailAnimation.cs | 13 +- .../Screens/Play/GameplayClockContainer.cs | 44 +++- osu.Game/Screens/Select/SongSelect.cs | 33 ++- osu.Game/Tests/Visual/EditorClockTestScene.cs | 2 +- .../Visual/RateAdjustedBeatmapTestScene.cs | 4 +- 39 files changed, 204 insertions(+), 283 deletions(-) diff --git a/osu.Game.Rulesets.Mania.Tests/TestSceneHoldNoteInput.cs b/osu.Game.Rulesets.Mania.Tests/TestSceneHoldNoteInput.cs index c3e0c277a0..98669efb10 100644 --- a/osu.Game.Rulesets.Mania.Tests/TestSceneHoldNoteInput.cs +++ b/osu.Game.Rulesets.Mania.Tests/TestSceneHoldNoteInput.cs @@ -343,7 +343,7 @@ namespace osu.Game.Rulesets.Mania.Tests judgementResults = new List(); }); - AddUntilStep("Beatmap at 0", () => MusicController.CurrentTrackTime == 0); + AddUntilStep("Beatmap at 0", () => MusicController.CurrentTrack?.CurrentTime == 0); AddUntilStep("Wait until player is loaded", () => currentPlayer.IsCurrentScreen()); AddUntilStep("Wait for completion", () => currentPlayer.ScoreProcessor.HasCompleted.Value); } diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneOutOfOrderHits.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneOutOfOrderHits.cs index dc7e59b40d..e5be778527 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneOutOfOrderHits.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneOutOfOrderHits.cs @@ -385,7 +385,7 @@ namespace osu.Game.Rulesets.Osu.Tests judgementResults = new List(); }); - AddUntilStep("Beatmap at 0", () => MusicController.CurrentTrackTime == 0); + AddUntilStep("Beatmap at 0", () => MusicController.CurrentTrack?.CurrentTime == 0); AddUntilStep("Wait until player is loaded", () => currentPlayer.IsCurrentScreen()); AddUntilStep("Wait for completion", () => currentPlayer.ScoreProcessor.HasCompleted.Value); } diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs index 2dffcfeabb..c9d13d3976 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs @@ -366,7 +366,7 @@ namespace osu.Game.Rulesets.Osu.Tests judgementResults = new List(); }); - AddUntilStep("Beatmap at 0", () => MusicController.CurrentTrackTime == 0); + AddUntilStep("Beatmap at 0", () => MusicController.CurrentTrack?.CurrentTime == 0); AddUntilStep("Wait until player is loaded", () => currentPlayer.IsCurrentScreen()); AddUntilStep("Wait for completion", () => currentPlayer.ScoreProcessor.HasCompleted.Value); } diff --git a/osu.Game.Tests/Skins/TestSceneBeatmapSkinResources.cs b/osu.Game.Tests/Skins/TestSceneBeatmapSkinResources.cs index 1a19326ac4..08a4e27ff7 100644 --- a/osu.Game.Tests/Skins/TestSceneBeatmapSkinResources.cs +++ b/osu.Game.Tests/Skins/TestSceneBeatmapSkinResources.cs @@ -31,6 +31,6 @@ namespace osu.Game.Tests.Skins public void TestRetrieveOggSample() => AddAssert("sample is non-null", () => beatmap.Skin.GetSample(new SampleInfo("sample")) != null); [Test] - public void TestRetrieveOggTrack() => AddAssert("track is non-null", () => !MusicController.IsDummyDevice); + public void TestRetrieveOggTrack() => AddAssert("track is non-null", () => MusicController.CurrentTrack?.IsDummyDevice == false); } } diff --git a/osu.Game.Tests/Visual/Editing/TimelineTestScene.cs b/osu.Game.Tests/Visual/Editing/TimelineTestScene.cs index 5d6136d9fb..4113bdddf8 100644 --- a/osu.Game.Tests/Visual/Editing/TimelineTestScene.cs +++ b/osu.Game.Tests/Visual/Editing/TimelineTestScene.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.Diagnostics; using osu.Framework.Allocation; using osu.Framework.Audio; using osu.Framework.Graphics; @@ -94,7 +95,10 @@ namespace osu.Game.Tests.Visual.Editing base.Update(); if (musicController.TrackLoaded) - marker.X = (float)(editorClock.CurrentTime / musicController.TrackLength); + { + Debug.Assert(musicController.CurrentTrack != null); + marker.X = (float)(editorClock.CurrentTime / musicController.CurrentTrack.Length); + } } } diff --git a/osu.Game.Tests/Visual/Gameplay/TestScenePause.cs b/osu.Game.Tests/Visual/Gameplay/TestScenePause.cs index 8f14de1578..e500b451f0 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestScenePause.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestScenePause.cs @@ -288,7 +288,7 @@ namespace osu.Game.Tests.Visual.Gameplay private void confirmNoTrackAdjustments() { - AddAssert("track has no adjustments", () => MusicController.AggregateFrequency.Value == 1); + AddAssert("track has no adjustments", () => MusicController.CurrentTrack?.AggregateFrequency.Value == 1); } private void restart() => AddStep("restart", () => Player.Restart()); diff --git a/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs b/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs index 2f86db1b25..c72ab7d3d1 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs @@ -57,7 +57,7 @@ namespace osu.Game.Tests.Visual.Gameplay Beatmap.Value = CreateWorkingBeatmap(new OsuRuleset().RulesetInfo); foreach (var mod in SelectedMods.Value.OfType()) - mod.ApplyToTrack(MusicController); + mod.ApplyToTrack(MusicController.CurrentTrack); InputManager.Child = container = new TestPlayerLoaderContainer( loader = new TestPlayerLoader(() => @@ -77,12 +77,12 @@ namespace osu.Game.Tests.Visual.Gameplay { AddStep("load dummy beatmap", () => ResetPlayer(false, () => SelectedMods.Value = new[] { new OsuModNightcore() })); AddUntilStep("wait for current", () => loader.IsCurrentScreen()); - AddAssert("mod rate applied", () => MusicController.Rate != 1); + AddAssert("mod rate applied", () => MusicController.CurrentTrack?.Rate != 1); AddStep("exit loader", () => loader.Exit()); AddUntilStep("wait for not current", () => !loader.IsCurrentScreen()); AddAssert("player did not load", () => !player.IsLoaded); AddUntilStep("player disposed", () => loader.DisposalTask?.IsCompleted == true); - AddAssert("mod rate still applied", () => MusicController.Rate != 1); + AddAssert("mod rate still applied", () => MusicController.CurrentTrack?.Rate != 1); } [Test] diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboard.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboard.cs index a4b558fce2..c7a012a03f 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboard.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboard.cs @@ -87,9 +87,9 @@ namespace osu.Game.Tests.Visual.Gameplay private void restart() { - MusicController.Reset(); + MusicController.CurrentTrack?.Reset(); loadStoryboard(Beatmap.Value); - MusicController.Play(true); + MusicController.CurrentTrack?.Start(); } private void loadStoryboard(WorkingBeatmap working) @@ -104,7 +104,7 @@ namespace osu.Game.Tests.Visual.Gameplay storyboard.Passing = false; storyboardContainer.Add(storyboard); - decoupledClock.ChangeSource(musicController.GetTrackClock()); + decoupledClock.ChangeSource(musicController.CurrentTrack); } private void loadStoryboardNoVideo() @@ -127,7 +127,7 @@ namespace osu.Game.Tests.Visual.Gameplay storyboard = sb.CreateDrawable(Beatmap.Value); storyboardContainer.Add(storyboard); - decoupledClock.ChangeSource(musicController.GetTrackClock()); + decoupledClock.ChangeSource(musicController.CurrentTrack); } } } diff --git a/osu.Game.Tests/Visual/Menus/TestSceneIntroWelcome.cs b/osu.Game.Tests/Visual/Menus/TestSceneIntroWelcome.cs index 36f98b7a0c..a88704c831 100644 --- a/osu.Game.Tests/Visual/Menus/TestSceneIntroWelcome.cs +++ b/osu.Game.Tests/Visual/Menus/TestSceneIntroWelcome.cs @@ -16,7 +16,7 @@ namespace osu.Game.Tests.Visual.Menus { AddUntilStep("wait for load", () => MusicController.TrackLoaded); - AddAssert("check if menu music loops", () => MusicController.Looping); + AddAssert("check if menu music loops", () => MusicController.CurrentTrack?.Looping == true); } } } diff --git a/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs b/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs index 455b7e56e6..946bc2a175 100644 --- a/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs +++ b/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs @@ -4,6 +4,7 @@ using System.Linq; using NUnit.Framework; using osu.Framework.Allocation; +using osu.Framework.Extensions.ObjectExtensions; using osu.Framework.Graphics.Containers; using osu.Framework.Screens; using osu.Game.Beatmaps; @@ -61,12 +62,12 @@ namespace osu.Game.Tests.Visual.Navigation AddUntilStep("wait for fail", () => player.HasFailed); AddUntilStep("wait for track stop", () => !MusicController.IsPlaying); - AddAssert("Ensure time before preview point", () => MusicController.CurrentTrackTime < beatmap().Metadata.PreviewTime); + AddAssert("Ensure time before preview point", () => MusicController.CurrentTrack?.CurrentTime < beatmap().Metadata.PreviewTime); pushEscape(); AddUntilStep("wait for track playing", () => MusicController.IsPlaying); - AddAssert("Ensure time wasn't reset to preview point", () => MusicController.CurrentTrackTime < beatmap().Metadata.PreviewTime); + AddAssert("Ensure time wasn't reset to preview point", () => MusicController.CurrentTrack?.CurrentTime < beatmap().Metadata.PreviewTime); } [Test] @@ -76,11 +77,11 @@ namespace osu.Game.Tests.Visual.Navigation PushAndConfirm(() => songSelect = new TestSongSelect()); - AddUntilStep("wait for no track", () => MusicController.IsDummyDevice); + AddUntilStep("wait for no track", () => MusicController.CurrentTrack?.IsDummyDevice == true); AddStep("return to menu", () => songSelect.Exit()); - AddUntilStep("wait for track", () => !MusicController.IsDummyDevice && MusicController.IsPlaying); + AddUntilStep("wait for track", () => MusicController.CurrentTrack?.IsDummyDevice == false && MusicController.IsPlaying); } [Test] @@ -135,8 +136,8 @@ namespace osu.Game.Tests.Visual.Navigation AddUntilStep("Wait for music controller", () => Game.MusicController.IsLoaded); AddStep("Seek close to end", () => { - Game.MusicController.SeekTo(MusicController.TrackLength - 1000); - // MusicController.Completed += () => trackCompleted = true; + Game.MusicController.SeekTo(MusicController.CurrentTrack.AsNonNull().Length - 1000); + MusicController.CurrentTrack.AsNonNull().Completed += () => trackCompleted = true; }); AddUntilStep("Track was completed", () => trackCompleted); diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneBeatSyncedContainer.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneBeatSyncedContainer.cs index f3fef8c355..ac743d76df 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneBeatSyncedContainer.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneBeatSyncedContainer.cs @@ -8,6 +8,7 @@ using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Audio.Track; using osu.Framework.Extensions.Color4Extensions; +using osu.Framework.Extensions.ObjectExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; @@ -168,7 +169,7 @@ namespace osu.Game.Tests.Visual.UserInterface if (timingPoints.Count == 0) return 0; if (timingPoints[^1] == current) - return (int)Math.Ceiling((musicController.TrackLength - current.Time) / current.BeatLength); + return (int)Math.Ceiling((musicController.CurrentTrack.AsNonNull().Length - current.Time) / current.BeatLength); return (int)Math.Ceiling((getNextTimingPoint(current).Time - current.Time) / current.BeatLength); } diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneNowPlayingOverlay.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneNowPlayingOverlay.cs index 3ecd8ab550..0161ec0c56 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneNowPlayingOverlay.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneNowPlayingOverlay.cs @@ -80,12 +80,12 @@ namespace osu.Game.Tests.Visual.UserInterface AddStep("Store track", () => currentBeatmap = Beatmap.Value); AddStep(@"Seek track to 6 second", () => musicController.SeekTo(6000)); - AddUntilStep(@"Wait for current time to update", () => musicController.CurrentTrackTime > 5000); + AddUntilStep(@"Wait for current time to update", () => musicController.CurrentTrack?.CurrentTime > 5000); AddStep(@"Set previous", () => musicController.PreviousTrack()); AddAssert(@"Check beatmap didn't change", () => currentBeatmap == Beatmap.Value); - AddUntilStep("Wait for current time to update", () => musicController.CurrentTrackTime < 5000); + AddUntilStep("Wait for current time to update", () => musicController.CurrentTrack?.CurrentTime < 5000); AddStep(@"Set previous", () => musicController.PreviousTrack()); AddAssert(@"Check beatmap did change", () => currentBeatmap != Beatmap.Value); diff --git a/osu.Game/Graphics/Containers/BeatSyncedContainer.cs b/osu.Game/Graphics/Containers/BeatSyncedContainer.cs index 2dd28a01dc..92a9ed0566 100644 --- a/osu.Game/Graphics/Containers/BeatSyncedContainer.cs +++ b/osu.Game/Graphics/Containers/BeatSyncedContainer.cs @@ -51,6 +51,7 @@ namespace osu.Game.Graphics.Containers protected override void Update() { + ITrack track = null; IBeatmap beatmap = null; double currentTrackTime = 0; @@ -58,11 +59,14 @@ namespace osu.Game.Graphics.Containers EffectControlPoint effectPoint = null; if (musicController.TrackLoaded && Beatmap.Value.BeatmapLoaded) - beatmap = Beatmap.Value.Beatmap; - - if (beatmap != null && musicController.IsPlaying && musicController.TrackLength > 0) { - currentTrackTime = musicController.CurrentTrackTime + EarlyActivationMilliseconds; + track = musicController.CurrentTrack; + beatmap = Beatmap.Value.Beatmap; + } + + if (track != null && beatmap != null && musicController.IsPlaying && track.Length > 0) + { + currentTrackTime = track.CurrentTime + EarlyActivationMilliseconds; timingPoint = beatmap.ControlPointInfo.TimingPointAt(currentTrackTime); effectPoint = beatmap.ControlPointInfo.EffectPointAt(currentTrackTime); @@ -98,7 +102,7 @@ namespace osu.Game.Graphics.Containers return; using (BeginDelayedSequence(-TimeSinceLastBeat, true)) - OnNewBeat(beatIndex, timingPoint, effectPoint, musicController.CurrentAmplitudes); + OnNewBeat(beatIndex, timingPoint, effectPoint, track?.CurrentAmplitudes ?? ChannelAmplitudes.Empty); lastBeat = beatIndex; lastTimingPoint = timingPoint; diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index f5ca5a3a49..c22849b7d6 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -6,7 +6,6 @@ using System.Collections.Generic; using System.Linq; using JetBrains.Annotations; using osu.Framework.Allocation; -using osu.Framework.Audio; using osu.Framework.Audio.Track; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -15,7 +14,6 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Input.Bindings; using osu.Framework.Utils; using osu.Framework.Threading; -using osu.Framework.Timing; using osu.Game.Beatmaps; using osu.Game.Input.Bindings; using osu.Game.Overlays.OSD; @@ -26,7 +24,7 @@ namespace osu.Game.Overlays /// /// Handles playback of the global music track. /// - public class MusicController : CompositeDrawable, IKeyBindingHandler, ITrack + public class MusicController : CompositeDrawable, IKeyBindingHandler { [Resolved] private BeatmapManager beatmaps { get; set; } @@ -70,10 +68,7 @@ namespace osu.Game.Overlays private readonly TrackContainer trackContainer; [CanBeNull] - private DrawableTrack drawableTrack; - - [CanBeNull] - private Track track; + public DrawableTrack CurrentTrack { get; private set; } private IBindable> managerUpdated; private IBindable> managerRemoved; @@ -116,33 +111,12 @@ namespace osu.Game.Overlays /// /// Returns whether the beatmap track is playing. /// - public bool IsPlaying => drawableTrack?.IsRunning ?? false; + public bool IsPlaying => CurrentTrack?.IsRunning ?? false; /// /// Returns whether the beatmap track is loaded. /// - public bool TrackLoaded => drawableTrack?.IsLoaded == true; - - /// - /// Returns the current time of the beatmap track. - /// - public double CurrentTrackTime => drawableTrack?.CurrentTime ?? 0; - - /// - /// Returns the length of the beatmap track. - /// - public double TrackLength => drawableTrack?.Length ?? 0; - - public void AddAdjustment(AdjustableProperty type, BindableNumber adjustBindable) - => trackContainer.AddAdjustment(type, adjustBindable); - - public void RemoveAdjustment(AdjustableProperty type, BindableNumber adjustBindable) - => trackContainer.RemoveAdjustment(type, adjustBindable); - - public void Reset() => drawableTrack?.Reset(); - - [CanBeNull] - public IAdjustableClock GetTrackClock() => track; + public bool TrackLoaded => CurrentTrack?.IsLoaded == true; private void beatmapUpdated(ValueChangedEvent> weakSet) { @@ -175,7 +149,7 @@ namespace osu.Game.Overlays seekDelegate = Schedule(() => { if (!beatmap.Disabled) - drawableTrack?.Seek(position); + CurrentTrack?.Seek(position); }); } @@ -187,7 +161,7 @@ namespace osu.Game.Overlays { if (IsUserPaused) return; - if (drawableTrack == null || drawableTrack.IsDummyDevice) + if (CurrentTrack == null || CurrentTrack.IsDummyDevice) { if (beatmap.Disabled) return; @@ -208,13 +182,13 @@ namespace osu.Game.Overlays { IsUserPaused = false; - if (drawableTrack == null) + if (CurrentTrack == null) return false; if (restart) - drawableTrack.Restart(); + CurrentTrack.Restart(); else if (!IsPlaying) - drawableTrack.Start(); + CurrentTrack.Start(); return true; } @@ -225,8 +199,8 @@ namespace osu.Game.Overlays public void Stop() { IsUserPaused = true; - if (drawableTrack?.IsRunning == true) - drawableTrack.Stop(); + if (CurrentTrack?.IsRunning == true) + CurrentTrack.Stop(); } /// @@ -235,7 +209,7 @@ namespace osu.Game.Overlays /// Whether the operation was successful. public bool TogglePause() { - if (drawableTrack?.IsRunning == true) + if (CurrentTrack?.IsRunning == true) Stop(); else Play(); @@ -257,7 +231,7 @@ namespace osu.Game.Overlays if (beatmap.Disabled) return PreviousTrackResult.None; - var currentTrackPosition = drawableTrack?.CurrentTime; + var currentTrackPosition = CurrentTrack?.CurrentTime; if (currentTrackPosition >= restart_cutoff_point) { @@ -311,7 +285,7 @@ namespace osu.Game.Overlays { // if not scheduled, the previously track will be stopped one frame later (see ScheduleAfterChildren logic in GameBase). // we probably want to move this to a central method for switching to a new working beatmap in the future. - Schedule(() => drawableTrack?.Restart()); + Schedule(() => CurrentTrack?.Restart()); } private WorkingBeatmap current; @@ -345,12 +319,11 @@ namespace osu.Game.Overlays current = beatmap.NewValue; - drawableTrack?.Expire(); - drawableTrack = null; - track = null; + CurrentTrack?.Expire(); + CurrentTrack = null; if (current != null) - trackContainer.Add(drawableTrack = new DrawableTrack(track = current.GetRealTrack())); + trackContainer.Add(CurrentTrack = new DrawableTrack(current.GetRealTrack())); TrackChanged?.Invoke(current, direction); @@ -379,15 +352,15 @@ namespace osu.Game.Overlays public void ResetTrackAdjustments() { - if (drawableTrack == null) + if (CurrentTrack == null) return; - drawableTrack.ResetSpeedAdjustments(); + CurrentTrack.ResetSpeedAdjustments(); if (allowRateAdjustments) { foreach (var mod in mods.Value.OfType()) - mod.ApplyToTrack(drawableTrack); + mod.ApplyToTrack(CurrentTrack); } } @@ -442,129 +415,6 @@ namespace osu.Game.Overlays private class TrackContainer : AudioContainer { } - - #region ITrack - - /// - /// The volume of this component. - /// - public BindableNumber Volume => drawableTrack?.Volume; // Todo: Bad - - /// - /// The playback balance of this sample (-1 .. 1 where 0 is centered) - /// - public BindableNumber Balance => drawableTrack?.Balance; // Todo: Bad - - /// - /// Rate at which the component is played back (affects pitch). 1 is 100% playback speed, or default frequency. - /// - public BindableNumber Frequency => drawableTrack?.Frequency; // Todo: Bad - - /// - /// Rate at which the component is played back (does not affect pitch). 1 is 100% playback speed. - /// - public BindableNumber Tempo => drawableTrack?.Tempo; // Todo: Bad - - public IBindable AggregateVolume => drawableTrack?.AggregateVolume; // Todo: Bad - - public IBindable AggregateBalance => drawableTrack?.AggregateBalance; // Todo: Bad - - public IBindable AggregateFrequency => drawableTrack?.AggregateFrequency; // Todo: Bad - - public IBindable AggregateTempo => drawableTrack?.AggregateTempo; // Todo: Bad - - /// - /// Overall playback rate (1 is 100%, -1 is reversed at 100%). - /// - public double Rate => AggregateFrequency.Value * AggregateTempo.Value; - - event Action ITrack.Completed - { - add - { - if (drawableTrack != null) - drawableTrack.Completed += value; - } - remove - { - if (drawableTrack != null) - drawableTrack.Completed -= value; - } - } - - event Action ITrack.Failed - { - add - { - if (drawableTrack != null) - drawableTrack.Failed += value; - } - remove - { - if (drawableTrack != null) - drawableTrack.Failed -= value; - } - } - - public bool Looping - { - get => drawableTrack?.Looping ?? false; - set - { - if (drawableTrack != null) - drawableTrack.Looping = value; - } - } - - public bool IsDummyDevice => drawableTrack?.IsDummyDevice ?? true; - - public double RestartPoint - { - get => drawableTrack?.RestartPoint ?? 0; - set - { - if (drawableTrack != null) - drawableTrack.RestartPoint = value; - } - } - - double ITrack.CurrentTime => CurrentTrackTime; - - double ITrack.Length - { - get => TrackLength; - set - { - if (drawableTrack != null) - drawableTrack.Length = value; - } - } - - public int? Bitrate => drawableTrack?.Bitrate; - - bool ITrack.IsRunning => IsPlaying; - - public bool IsReversed => drawableTrack?.IsReversed ?? false; - - public bool HasCompleted => drawableTrack?.HasCompleted ?? false; - - void ITrack.Reset() => drawableTrack?.Reset(); - - void ITrack.Restart() => Play(true); - - void ITrack.ResetSpeedAdjustments() => ResetTrackAdjustments(); - - bool ITrack.Seek(double seek) - { - SeekTo(seek); - return true; - } - - void ITrack.Start() => Play(); - - public ChannelAmplitudes CurrentAmplitudes => drawableTrack?.CurrentAmplitudes ?? ChannelAmplitudes.Empty; - - #endregion } public enum TrackChangeDirection diff --git a/osu.Game/Overlays/NowPlayingOverlay.cs b/osu.Game/Overlays/NowPlayingOverlay.cs index fde6a52fee..15b189ead6 100644 --- a/osu.Game/Overlays/NowPlayingOverlay.cs +++ b/osu.Game/Overlays/NowPlayingOverlay.cs @@ -234,12 +234,14 @@ namespace osu.Game.Overlays pendingBeatmapSwitch = null; } - if (musicController.IsDummyDevice == false) - { - progressBar.EndTime = musicController.TrackLength; - progressBar.CurrentTime = musicController.CurrentTrackTime; + var track = musicController.TrackLoaded ? musicController.CurrentTrack : null; - playButton.Icon = musicController.IsPlaying ? FontAwesome.Regular.PauseCircle : FontAwesome.Regular.PlayCircle; + if (track?.IsDummyDevice == false) + { + progressBar.EndTime = track.Length; + progressBar.CurrentTime = track.CurrentTime; + + playButton.Icon = track.IsRunning ? FontAwesome.Regular.PauseCircle : FontAwesome.Regular.PlayCircle; } else { diff --git a/osu.Game/Rulesets/Mods/IApplicableToTrack.cs b/osu.Game/Rulesets/Mods/IApplicableToTrack.cs index 9b840cea08..5ae41fe09c 100644 --- a/osu.Game/Rulesets/Mods/IApplicableToTrack.cs +++ b/osu.Game/Rulesets/Mods/IApplicableToTrack.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 osu.Framework.Audio; using osu.Framework.Audio.Track; namespace osu.Game.Rulesets.Mods @@ -10,6 +11,6 @@ namespace osu.Game.Rulesets.Mods /// public interface IApplicableToTrack : IApplicableMod { - void ApplyToTrack(ITrack track); + void ApplyToTrack(T track) where T : ITrack, IAdjustableAudioComponent; } } diff --git a/osu.Game/Rulesets/Mods/ModDaycore.cs b/osu.Game/Rulesets/Mods/ModDaycore.cs index 9cefeb3340..989978eb35 100644 --- a/osu.Game/Rulesets/Mods/ModDaycore.cs +++ b/osu.Game/Rulesets/Mods/ModDaycore.cs @@ -2,7 +2,6 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Audio; -using osu.Framework.Audio.Track; using osu.Framework.Bindables; using osu.Framework.Graphics.Sprites; @@ -27,11 +26,11 @@ namespace osu.Game.Rulesets.Mods }, true); } - public override void ApplyToTrack(ITrack track) + public override void ApplyToTrack(T track) { // base.ApplyToTrack() intentionally not called (different tempo adjustment is applied) - (track as Track)?.AddAdjustment(AdjustableProperty.Frequency, freqAdjust); - (track as Track)?.AddAdjustment(AdjustableProperty.Tempo, tempoAdjust); + track.AddAdjustment(AdjustableProperty.Frequency, freqAdjust); + track.AddAdjustment(AdjustableProperty.Tempo, tempoAdjust); } } } diff --git a/osu.Game/Rulesets/Mods/ModNightcore.cs b/osu.Game/Rulesets/Mods/ModNightcore.cs index b34affa77f..70cdaa6345 100644 --- a/osu.Game/Rulesets/Mods/ModNightcore.cs +++ b/osu.Game/Rulesets/Mods/ModNightcore.cs @@ -38,11 +38,11 @@ namespace osu.Game.Rulesets.Mods }, true); } - public override void ApplyToTrack(ITrack track) + public override void ApplyToTrack(T track) { // base.ApplyToTrack() intentionally not called (different tempo adjustment is applied) - (track as Track)?.AddAdjustment(AdjustableProperty.Frequency, freqAdjust); - (track as Track)?.AddAdjustment(AdjustableProperty.Tempo, tempoAdjust); + track.AddAdjustment(AdjustableProperty.Frequency, freqAdjust); + track.AddAdjustment(AdjustableProperty.Tempo, tempoAdjust); } public void ApplyToDrawableRuleset(DrawableRuleset drawableRuleset) diff --git a/osu.Game/Rulesets/Mods/ModRateAdjust.cs b/osu.Game/Rulesets/Mods/ModRateAdjust.cs index ee1280da39..e2c8ac64d9 100644 --- a/osu.Game/Rulesets/Mods/ModRateAdjust.cs +++ b/osu.Game/Rulesets/Mods/ModRateAdjust.cs @@ -12,9 +12,9 @@ namespace osu.Game.Rulesets.Mods { public abstract BindableNumber SpeedChange { get; } - public virtual void ApplyToTrack(ITrack track) + public virtual void ApplyToTrack(T track) where T : ITrack, IAdjustableAudioComponent { - (track as Track)?.AddAdjustment(AdjustableProperty.Tempo, SpeedChange); + track.AddAdjustment(AdjustableProperty.Tempo, SpeedChange); } public virtual void ApplyToSample(SampleChannel sample) diff --git a/osu.Game/Rulesets/Mods/ModTimeRamp.cs b/osu.Game/Rulesets/Mods/ModTimeRamp.cs index 0257e241b8..b6cbe72971 100644 --- a/osu.Game/Rulesets/Mods/ModTimeRamp.cs +++ b/osu.Game/Rulesets/Mods/ModTimeRamp.cs @@ -42,7 +42,7 @@ namespace osu.Game.Rulesets.Mods Precision = 0.01, }; - private Track track; + private ITrack track; protected ModTimeRamp() { @@ -51,9 +51,9 @@ namespace osu.Game.Rulesets.Mods AdjustPitch.BindValueChanged(applyPitchAdjustment); } - public void ApplyToTrack(ITrack track) + public void ApplyToTrack(T track) where T : ITrack, IAdjustableAudioComponent { - this.track = track as Track; + this.track = track; FinalRate.TriggerChange(); AdjustPitch.TriggerChange(); @@ -89,9 +89,9 @@ namespace osu.Game.Rulesets.Mods private void applyPitchAdjustment(ValueChangedEvent adjustPitchSetting) { // remove existing old adjustment - track?.RemoveAdjustment(adjustmentForPitchSetting(adjustPitchSetting.OldValue), SpeedChange); + (track as IAdjustableAudioComponent)?.RemoveAdjustment(adjustmentForPitchSetting(adjustPitchSetting.OldValue), SpeedChange); - track?.AddAdjustment(adjustmentForPitchSetting(adjustPitchSetting.NewValue), SpeedChange); + (track as IAdjustableAudioComponent)?.AddAdjustment(adjustmentForPitchSetting(adjustPitchSetting.NewValue), SpeedChange); } private AdjustableProperty adjustmentForPitchSetting(bool adjustPitchSettingValue) diff --git a/osu.Game/Screens/Edit/Components/PlaybackControl.cs b/osu.Game/Screens/Edit/Components/PlaybackControl.cs index 0a9b4f06a7..412efe266c 100644 --- a/osu.Game/Screens/Edit/Components/PlaybackControl.cs +++ b/osu.Game/Screens/Edit/Components/PlaybackControl.cs @@ -66,12 +66,12 @@ namespace osu.Game.Screens.Edit.Components } }; - musicController.AddAdjustment(AdjustableProperty.Tempo, tempo); + musicController.CurrentTrack?.AddAdjustment(AdjustableProperty.Tempo, tempo); } protected override void Dispose(bool isDisposing) { - musicController?.RemoveAdjustment(AdjustableProperty.Tempo, tempo); + musicController?.CurrentTrack?.RemoveAdjustment(AdjustableProperty.Tempo, tempo); base.Dispose(isDisposing); } diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs index 446f7fdf88..24fb855009 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System; +using System.Diagnostics; using osu.Framework.Allocation; using osu.Framework.Bindables; using osuTK; @@ -57,7 +58,8 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts return; } - content.RelativeChildSize = new Vector2((float)Math.Max(1, musicController.TrackLength), 1); + Debug.Assert(musicController.CurrentTrack != null); + content.RelativeChildSize = new Vector2((float)Math.Max(1, musicController.CurrentTrack.Length), 1); } protected virtual void LoadBeatmap(WorkingBeatmap beatmap) diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs index f35e5defd8..d556d948f6 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs @@ -2,7 +2,9 @@ // See the LICENCE file in the repository root for full licence text. using System; +using System.Diagnostics; using osu.Framework.Allocation; +using osu.Framework.Audio.Track; using osu.Framework.Bindables; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; @@ -60,21 +62,20 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline Beatmap.BindValueChanged(b => { waveform.Waveform = b.NewValue.Waveform; + track = musicController.CurrentTrack; - // Todo: Wrong. - Schedule(() => + Debug.Assert(track != null); + + if (track.Length > 0) { - if (musicController.TrackLength > 0) - { - MaxZoom = getZoomLevelForVisibleMilliseconds(500); - MinZoom = getZoomLevelForVisibleMilliseconds(10000); - Zoom = getZoomLevelForVisibleMilliseconds(2000); - } - }); + MaxZoom = getZoomLevelForVisibleMilliseconds(500); + MinZoom = getZoomLevelForVisibleMilliseconds(10000); + Zoom = getZoomLevelForVisibleMilliseconds(2000); + } }, true); } - private float getZoomLevelForVisibleMilliseconds(double milliseconds) => (float)(musicController.TrackLength / milliseconds); + private float getZoomLevelForVisibleMilliseconds(double milliseconds) => (float)(track.Length / milliseconds); /// /// The timeline's scroll position in the last frame. @@ -96,6 +97,8 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline /// private bool trackWasPlaying; + private ITrack track; + protected override void Update() { base.Update(); @@ -136,15 +139,15 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline if (!musicController.TrackLoaded) return; - editorClock.Seek(Current / Content.DrawWidth * musicController.TrackLength); + editorClock.Seek(Current / Content.DrawWidth * track.Length); } private void scrollToTrackTime() { - if (!musicController.TrackLoaded || musicController.TrackLength == 0) + if (!musicController.TrackLoaded || track.Length == 0) return; - ScrollTo((float)(editorClock.CurrentTime / musicController.TrackLength) * Content.DrawWidth, false); + ScrollTo((float)(editorClock.CurrentTime / track.Length) * Content.DrawWidth, false); } protected override bool OnMouseDown(MouseDownEvent e) @@ -188,7 +191,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline new SnapResult(screenSpacePosition, beatSnapProvider.SnapTime(getTimeFromPosition(Content.ToLocalSpace(screenSpacePosition)))); private double getTimeFromPosition(Vector2 localPosition) => - (localPosition.X / Content.DrawWidth) * musicController.TrackLength; + (localPosition.X / Content.DrawWidth) * track.Length; public float GetBeatSnapDistanceAt(double referenceTime) => throw new NotImplementedException(); diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineTickDisplay.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineTickDisplay.cs index a833b354ed..ceb0275a13 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineTickDisplay.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineTickDisplay.cs @@ -3,6 +3,7 @@ using System.Linq; using osu.Framework.Allocation; +using osu.Framework.Extensions.ObjectExtensions; using osu.Framework.Graphics; using osu.Game.Graphics; using osu.Game.Overlays; @@ -43,7 +44,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline for (var i = 0; i < beatmap.ControlPointInfo.TimingPoints.Count; i++) { var point = beatmap.ControlPointInfo.TimingPoints[i]; - var until = i + 1 < beatmap.ControlPointInfo.TimingPoints.Count ? beatmap.ControlPointInfo.TimingPoints[i + 1].Time : musicController.TrackLength; + var until = i + 1 < beatmap.ControlPointInfo.TimingPoints.Count ? beatmap.ControlPointInfo.TimingPoints[i + 1].Time : musicController.CurrentTrack.AsNonNull().Length; int beat = 0; diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index 756b03d049..b02aabc24d 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -83,7 +83,7 @@ namespace osu.Game.Screens.Edit beatDivisor.BindValueChanged(divisor => Beatmap.Value.BeatmapInfo.BeatDivisor = divisor.NewValue); // Todo: should probably be done at a DrawableRuleset level to share logic with Player. - var sourceClock = musicController.GetTrackClock() ?? new StopwatchClock(); + var sourceClock = (IAdjustableClock)musicController.CurrentTrack ?? new StopwatchClock(); clock = new EditorClock(Beatmap.Value, beatDivisor) { IsCoupled = false }; clock.ChangeSource(sourceClock); diff --git a/osu.Game/Screens/Edit/EditorClock.cs b/osu.Game/Screens/Edit/EditorClock.cs index 4cb24f90a6..4e589aeeef 100644 --- a/osu.Game/Screens/Edit/EditorClock.cs +++ b/osu.Game/Screens/Edit/EditorClock.cs @@ -55,7 +55,7 @@ namespace osu.Game.Screens.Edit private void load() { // Todo: What. - TrackLength ??= musicController.TrackLength; + TrackLength ??= musicController.CurrentTrack?.Length ?? 0; } /// diff --git a/osu.Game/Screens/Menu/IntroScreen.cs b/osu.Game/Screens/Menu/IntroScreen.cs index 7da5df2723..030923c228 100644 --- a/osu.Game/Screens/Menu/IntroScreen.cs +++ b/osu.Game/Screens/Menu/IntroScreen.cs @@ -113,7 +113,9 @@ namespace osu.Game.Screens.Menu if (setInfo != null) { initialBeatmap = beatmaps.GetWorkingBeatmap(setInfo.Beatmaps[0]); - UsingThemedIntro = !MusicController.IsDummyDevice; + + // Todo: Wrong. + UsingThemedIntro = MusicController.CurrentTrack?.IsDummyDevice == false; } return UsingThemedIntro; diff --git a/osu.Game/Screens/Menu/IntroTriangles.cs b/osu.Game/Screens/Menu/IntroTriangles.cs index 86a6fa3802..e29ea6e743 100644 --- a/osu.Game/Screens/Menu/IntroTriangles.cs +++ b/osu.Game/Screens/Menu/IntroTriangles.cs @@ -59,7 +59,7 @@ namespace osu.Game.Screens.Menu LoadComponentAsync(new TrianglesIntroSequence(logo, background) { RelativeSizeAxes = Axes.Both, - Clock = new FramedClock(UsingThemedIntro ? MusicController.GetTrackClock() : null), + Clock = new FramedClock(UsingThemedIntro ? MusicController.CurrentTrack : null), LoadMenu = LoadMenu }, t => { diff --git a/osu.Game/Screens/Menu/IntroWelcome.cs b/osu.Game/Screens/Menu/IntroWelcome.cs index 62cada577d..85f11eb244 100644 --- a/osu.Game/Screens/Menu/IntroWelcome.cs +++ b/osu.Game/Screens/Menu/IntroWelcome.cs @@ -44,7 +44,8 @@ namespace osu.Game.Screens.Menu pianoReverb = audio.Samples.Get(@"Intro/Welcome/welcome_piano"); - musicController.Looping = true; + if (musicController.CurrentTrack != null) + musicController.CurrentTrack.Looping = true; } protected override void LogoArriving(OsuLogo logo, bool resuming) diff --git a/osu.Game/Screens/Menu/LogoVisualisation.cs b/osu.Game/Screens/Menu/LogoVisualisation.cs index 349654165f..7a1ff4fa06 100644 --- a/osu.Game/Screens/Menu/LogoVisualisation.cs +++ b/osu.Game/Screens/Menu/LogoVisualisation.cs @@ -19,6 +19,7 @@ using osu.Framework.Allocation; using osu.Framework.Audio; using osu.Framework.Audio.Track; using osu.Framework.Bindables; +using osu.Framework.Extensions.ObjectExtensions; using osu.Framework.Utils; using osu.Game.Overlays; @@ -108,14 +109,14 @@ namespace osu.Game.Screens.Menu private void updateAmplitudes() { var effect = beatmap.Value.BeatmapLoaded && musicController.TrackLoaded - ? beatmap.Value.Beatmap?.ControlPointInfo.EffectPointAt(musicController.CurrentTrackTime) + ? beatmap.Value.Beatmap?.ControlPointInfo.EffectPointAt(musicController.CurrentTrack.AsNonNull().CurrentTime) : null; for (int i = 0; i < temporalAmplitudes.Length; i++) temporalAmplitudes[i] = 0; if (musicController.TrackLoaded) - addAmplitudesFromSource(musicController); + addAmplitudesFromSource(musicController.CurrentTrack.AsNonNull()); foreach (var source in amplitudeSources) addAmplitudesFromSource(source); diff --git a/osu.Game/Screens/Menu/MainMenu.cs b/osu.Game/Screens/Menu/MainMenu.cs index c422f57332..ce48777ce1 100644 --- a/osu.Game/Screens/Menu/MainMenu.cs +++ b/osu.Game/Screens/Menu/MainMenu.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.Diagnostics; using System.Linq; using osuTK; using osuTK.Graphics; @@ -181,11 +182,12 @@ namespace osu.Game.Screens.Menu if (last is IntroScreen && musicController.TrackLoaded) { - // Todo: Wrong. - if (!musicController.IsPlaying) + Debug.Assert(musicController.CurrentTrack != null); + + if (!musicController.CurrentTrack.IsRunning) { - musicController.SeekTo(metadata.PreviewTime != -1 ? metadata.PreviewTime : 0.4f * musicController.TrackLength); - musicController.Play(); + musicController.CurrentTrack.Seek(metadata.PreviewTime != -1 ? metadata.PreviewTime : 0.4f * musicController.CurrentTrack.Length); + musicController.CurrentTrack.Start(); } } diff --git a/osu.Game/Screens/Menu/OsuLogo.cs b/osu.Game/Screens/Menu/OsuLogo.cs index 1feb2481c3..f028f9b229 100644 --- a/osu.Game/Screens/Menu/OsuLogo.cs +++ b/osu.Game/Screens/Menu/OsuLogo.cs @@ -330,9 +330,9 @@ namespace osu.Game.Screens.Menu const float velocity_adjust_cutoff = 0.98f; const float paused_velocity = 0.5f; - if (musicController.IsPlaying) + if (musicController.CurrentTrack?.IsRunning == true) { - var maxAmplitude = lastBeatIndex >= 0 ? musicController.CurrentAmplitudes.Maximum : 0; + var maxAmplitude = lastBeatIndex >= 0 ? musicController.CurrentTrack.CurrentAmplitudes.Maximum : 0; logoAmplitudeContainer.Scale = new Vector2((float)Interpolation.Damp(logoAmplitudeContainer.Scale.X, 1 - Math.Max(0, maxAmplitude - scale_adjust_cutoff) * 0.04f, 0.9f, Time.Elapsed)); if (maxAmplitude > velocity_adjust_cutoff) diff --git a/osu.Game/Screens/Multi/Match/Components/ReadyButton.cs b/osu.Game/Screens/Multi/Match/Components/ReadyButton.cs index 032c8d5ca9..c7dc20ff23 100644 --- a/osu.Game/Screens/Multi/Match/Components/ReadyButton.cs +++ b/osu.Game/Screens/Multi/Match/Components/ReadyButton.cs @@ -104,7 +104,7 @@ namespace osu.Game.Screens.Multi.Match.Components return; } - bool hasEnoughTime = DateTimeOffset.UtcNow.AddSeconds(30).AddMilliseconds(musicController.TrackLength) < endDate.Value; + bool hasEnoughTime = musicController.CurrentTrack != null && DateTimeOffset.UtcNow.AddSeconds(30).AddMilliseconds(musicController.CurrentTrack.Length) < endDate.Value; Enabled.Value = hasBeatmap && hasEnoughTime; } diff --git a/osu.Game/Screens/Multi/Multiplayer.cs b/osu.Game/Screens/Multi/Multiplayer.cs index 2d74434c76..e068899c7b 100644 --- a/osu.Game/Screens/Multi/Multiplayer.cs +++ b/osu.Game/Screens/Multi/Multiplayer.cs @@ -343,9 +343,13 @@ namespace osu.Game.Screens.Multi { if (screenStack.CurrentScreen is MatchSubScreen) { - musicController.RestartPoint = Beatmap.Value.Metadata.PreviewTime; - musicController.Looping = true; - musicController.EnsurePlayingSomething(); + if (musicController.CurrentTrack != null) + { + musicController.CurrentTrack.RestartPoint = Beatmap.Value.Metadata.PreviewTime; + musicController.CurrentTrack.Looping = true; + + musicController.EnsurePlayingSomething(); + } } else { @@ -355,8 +359,11 @@ namespace osu.Game.Screens.Multi private void cancelLooping() { - musicController.Looping = false; - musicController.RestartPoint = 0; + if (musicController.CurrentTrack != null) + { + musicController.CurrentTrack.Looping = false; + musicController.CurrentTrack.RestartPoint = 0; + } } protected override void Dispose(bool isDisposing) diff --git a/osu.Game/Screens/Play/FailAnimation.cs b/osu.Game/Screens/Play/FailAnimation.cs index 0e0ef8c675..1171d8c3b0 100644 --- a/osu.Game/Screens/Play/FailAnimation.cs +++ b/osu.Game/Screens/Play/FailAnimation.cs @@ -9,6 +9,7 @@ using System.Collections.Generic; using osu.Framework.Allocation; using osu.Framework.Audio.Sample; using osu.Framework.Graphics; +using osu.Framework.Graphics.Audio; using osu.Framework.Utils; using osu.Game.Beatmaps; using osu.Game.Overlays; @@ -30,21 +31,21 @@ namespace osu.Game.Screens.Play private readonly BindableDouble trackFreq = new BindableDouble(1); + private DrawableTrack track; + private const float duration = 2500; private SampleChannel failSample; - [Resolved] - private MusicController musicController { get; set; } - public FailAnimation(DrawableRuleset drawableRuleset) { this.drawableRuleset = drawableRuleset; } [BackgroundDependencyLoader] - private void load(AudioManager audio, IBindable beatmap) + private void load(AudioManager audio, IBindable beatmap, MusicController musicController) { + track = musicController.CurrentTrack; failSample = audio.Samples.Get(@"Gameplay/failsound"); } @@ -68,7 +69,7 @@ namespace osu.Game.Screens.Play Expire(); }); - musicController.AddAdjustment(AdjustableProperty.Frequency, trackFreq); + track.AddAdjustment(AdjustableProperty.Frequency, trackFreq); applyToPlayfield(drawableRuleset.Playfield); drawableRuleset.Playfield.HitObjectContainer.FlashColour(Color4.Red, 500); @@ -107,7 +108,7 @@ namespace osu.Game.Screens.Play protected override void Dispose(bool isDisposing) { base.Dispose(isDisposing); - musicController?.RemoveAdjustment(AdjustableProperty.Frequency, trackFreq); + track?.RemoveAdjustment(AdjustableProperty.Frequency, trackFreq); } } } diff --git a/osu.Game/Screens/Play/GameplayClockContainer.cs b/osu.Game/Screens/Play/GameplayClockContainer.cs index cf4678ab29..61272f56ad 100644 --- a/osu.Game/Screens/Play/GameplayClockContainer.cs +++ b/osu.Game/Screens/Play/GameplayClockContainer.cs @@ -8,8 +8,10 @@ using System.Threading.Tasks; using osu.Framework; using osu.Framework.Allocation; using osu.Framework.Audio; +using osu.Framework.Audio.Track; using osu.Framework.Bindables; using osu.Framework.Graphics; +using osu.Framework.Graphics.Audio; using osu.Framework.Graphics.Containers; using osu.Framework.Timing; using osu.Game.Beatmaps; @@ -27,8 +29,7 @@ namespace osu.Game.Screens.Play private readonly WorkingBeatmap beatmap; private readonly IReadOnlyList mods; - [Resolved] - private MusicController musicController { get; set; } + private DrawableTrack track; public readonly BindableBool IsPaused = new BindableBool(); @@ -95,8 +96,10 @@ namespace osu.Game.Screens.Play private readonly BindableDouble pauseFreqAdjust = new BindableDouble(1); [BackgroundDependencyLoader] - private void load(OsuConfigManager config) + private void load(OsuConfigManager config, MusicController musicController) { + track = musicController.CurrentTrack; + userAudioOffset = config.GetBindable(OsuSetting.AudioOffset); userAudioOffset.BindValueChanged(offset => userOffsetClock.Offset = offset.NewValue, true); @@ -121,15 +124,15 @@ namespace osu.Game.Screens.Play { // The Reset() call below causes speed adjustments to be reset in an async context, leading to deadlocks. // The deadlock can be prevented by resetting the track synchronously before entering the async context. - musicController.Reset(); + track.ResetSpeedAdjustments(); Task.Run(() => { - musicController.Reset(); + track.Reset(); Schedule(() => { - adjustableClock.ChangeSource(musicController.GetTrackClock()); + adjustableClock.ChangeSource(track); updateRate(); if (!IsPaused.Value) @@ -190,6 +193,20 @@ namespace osu.Game.Screens.Play IsPaused.Value = true; } + /// + /// Changes the backing clock to avoid using the originally provided track. + /// + public void StopUsingBeatmapClock() + { + if (track == null) + return; + + removeSourceClockAdjustments(); + + track = new DrawableTrack(new TrackVirtual(track.Length)); + adjustableClock.ChangeSource(track); + } + protected override void Update() { if (!IsPaused.Value) @@ -202,23 +219,30 @@ namespace osu.Game.Screens.Play private void updateRate() { + if (track == null) return; + speedAdjustmentsApplied = true; - musicController.ResetTrackAdjustments(); - musicController.AddAdjustment(AdjustableProperty.Frequency, pauseFreqAdjust); - musicController.AddAdjustment(AdjustableProperty.Tempo, UserPlaybackRate); + track.ResetSpeedAdjustments(); + + track.AddAdjustment(AdjustableProperty.Frequency, pauseFreqAdjust); + track.AddAdjustment(AdjustableProperty.Tempo, UserPlaybackRate); + + foreach (var mod in mods.OfType()) + mod.ApplyToTrack(track); } protected override void Dispose(bool isDisposing) { base.Dispose(isDisposing); removeSourceClockAdjustments(); + track = null; } private void removeSourceClockAdjustments() { if (speedAdjustmentsApplied) { - musicController.ResetTrackAdjustments(); + track.ResetSpeedAdjustments(); speedAdjustmentsApplied = false; } } diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 9ba2732920..ea04d82e67 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -31,6 +31,7 @@ using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using osu.Framework.Audio.Track; using osu.Framework.Graphics.Sprites; using osu.Framework.Input.Bindings; using osu.Game.Graphics.UserInterface; @@ -560,9 +561,9 @@ namespace osu.Game.Screens.Select BeatmapDetails.Refresh(); - if (music != null) + if (music?.CurrentTrack != null) { - music.Looping = true; + music.CurrentTrack.Looping = true; music.ResetTrackAdjustments(); } @@ -588,8 +589,8 @@ namespace osu.Game.Screens.Select BeatmapOptions.Hide(); - if (music != null) - music.Looping = false; + if (music?.CurrentTrack != null) + music.CurrentTrack.Looping = false; this.ScaleTo(1.1f, 250, Easing.InSine); @@ -610,8 +611,8 @@ namespace osu.Game.Screens.Select FilterControl.Deactivate(); - if (music != null) - music.Looping = false; + if (music?.CurrentTrack != null) + music.CurrentTrack.Looping = false; return false; } @@ -652,18 +653,30 @@ namespace osu.Game.Screens.Select BeatmapDetails.Beatmap = beatmap; - if (music != null) - music.Looping = false; + if (music?.CurrentTrack != null) + music.CurrentTrack.Looping = false; } + private readonly WeakReference lastTrack = new WeakReference(null); + /// /// Ensures some music is playing for the current track. /// Will resume playback from a manual user pause if the track has changed. /// private void ensurePlayingSelected() { - music.RestartPoint = Beatmap.Value.Metadata.PreviewTime; - music.EnsurePlayingSomething(); + ITrack track = music?.CurrentTrack; + if (track == null) + return; + + bool isNewTrack = !lastTrack.TryGetTarget(out var last) || last != track; + + track.RestartPoint = Beatmap.Value.Metadata.PreviewTime; + + if (!track.IsRunning && (music?.IsUserPaused != true || isNewTrack)) + music?.Play(true); + + lastTrack.SetTarget(track); } private void carouselBeatmapsLoaded() diff --git a/osu.Game/Tests/Visual/EditorClockTestScene.cs b/osu.Game/Tests/Visual/EditorClockTestScene.cs index 5226a49def..780b4f1b3a 100644 --- a/osu.Game/Tests/Visual/EditorClockTestScene.cs +++ b/osu.Game/Tests/Visual/EditorClockTestScene.cs @@ -44,7 +44,7 @@ namespace osu.Game.Tests.Visual private void beatmapChanged(ValueChangedEvent e) { Clock.ControlPointInfo = e.NewValue.Beatmap.ControlPointInfo; - Clock.ChangeSource(MusicController.GetTrackClock() ?? new StopwatchClock()); + Clock.ChangeSource((IAdjustableClock)MusicController.CurrentTrack ?? new StopwatchClock()); Clock.ProcessFrame(); } diff --git a/osu.Game/Tests/Visual/RateAdjustedBeatmapTestScene.cs b/osu.Game/Tests/Visual/RateAdjustedBeatmapTestScene.cs index e7cb461d7b..ae4b0ef84a 100644 --- a/osu.Game/Tests/Visual/RateAdjustedBeatmapTestScene.cs +++ b/osu.Game/Tests/Visual/RateAdjustedBeatmapTestScene.cs @@ -1,6 +1,8 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using osu.Framework.Extensions.ObjectExtensions; + namespace osu.Game.Tests.Visual { /// @@ -13,7 +15,7 @@ namespace osu.Game.Tests.Visual base.Update(); // note that this will override any mod rate application - MusicController.Tempo.Value = Clock.Rate; + MusicController.CurrentTrack.AsNonNull().Tempo.Value = Clock.Rate; } } } From 58660c70a3c9cad61e78ef854d238e8f569ee08e Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 5 Aug 2020 21:20:41 +0900 Subject: [PATCH 010/320] Cache before idle tracker --- osu.Game/OsuGame.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 929254e8ad..3e41be2028 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -554,8 +554,8 @@ namespace osu.Game Container logoContainer; BackButton.Receptor receptor; - dependencies.CacheAs(idleTracker = new GameIdleTracker(6000)); dependencies.CacheAs(MusicController = new MusicController()); + dependencies.CacheAs(idleTracker = new GameIdleTracker(6000)); AddRange(new Drawable[] { From e9fc783b1d75f31ec8291fa8a11f254f28cb1860 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 5 Aug 2020 21:21:08 +0900 Subject: [PATCH 011/320] Add back loop-on-completion --- osu.Game/OsuGame.cs | 18 +----------------- osu.Game/Overlays/MusicController.cs | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 3e41be2028..a41c7b28a5 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -427,23 +427,7 @@ namespace osu.Game updateModDefaults(); - var newBeatmap = beatmap.NewValue; - - if (newBeatmap != null) - { - // MusicController.Completed += () => Scheduler.AddOnce(() => trackCompleted(newBeatmap)); - newBeatmap.BeginAsyncLoad(); - } - - // void trackCompleted(WorkingBeatmap b) - // { - // // the source of track completion is the audio thread, so the beatmap may have changed before firing. - // if (Beatmap.Value != b) - // return; - // - // if (!MusicController.Looping && !Beatmap.Disabled) - // MusicController.NextTrack(); - // } + beatmap.NewValue?.BeginAsyncLoad(); } private void modsChanged(ValueChangedEvent> mods) diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index c22849b7d6..50ad97be7c 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; using JetBrains.Annotations; using osu.Framework.Allocation; @@ -323,7 +324,10 @@ namespace osu.Game.Overlays CurrentTrack = null; if (current != null) + { trackContainer.Add(CurrentTrack = new DrawableTrack(current.GetRealTrack())); + CurrentTrack.Completed += () => onTrackCompleted(current); + } TrackChanged?.Invoke(current, direction); @@ -332,6 +336,18 @@ namespace osu.Game.Overlays queuedDirection = null; } + private void onTrackCompleted(WorkingBeatmap workingBeatmap) + { + // the source of track completion is the audio thread, so the beatmap may have changed before firing. + if (current != workingBeatmap) + return; + + Debug.Assert(CurrentTrack != null); + + if (!CurrentTrack.Looping && !beatmap.Disabled) + NextTrack(); + } + private bool allowRateAdjustments; /// From 11a6c9bdccc65e89575a0e138512ccc379b1a15f Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 5 Aug 2020 21:21:14 +0900 Subject: [PATCH 012/320] Revert unnecessary change --- osu.Game/Graphics/Containers/BeatSyncedContainer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Graphics/Containers/BeatSyncedContainer.cs b/osu.Game/Graphics/Containers/BeatSyncedContainer.cs index 92a9ed0566..69021e1634 100644 --- a/osu.Game/Graphics/Containers/BeatSyncedContainer.cs +++ b/osu.Game/Graphics/Containers/BeatSyncedContainer.cs @@ -64,7 +64,7 @@ namespace osu.Game.Graphics.Containers beatmap = Beatmap.Value.Beatmap; } - if (track != null && beatmap != null && musicController.IsPlaying && track.Length > 0) + if (track != null && beatmap != null && track.IsRunning && track.Length > 0) { currentTrackTime = track.CurrentTime + EarlyActivationMilliseconds; From f058f5e977bbfb532b2711e0101c76868022b808 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 5 Aug 2020 21:29:53 +0900 Subject: [PATCH 013/320] Fix incorrect value being set --- osu.Game/Screens/Select/SongSelect.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index ea04d82e67..80ed894233 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -654,7 +654,7 @@ namespace osu.Game.Screens.Select BeatmapDetails.Beatmap = beatmap; if (music?.CurrentTrack != null) - music.CurrentTrack.Looping = false; + music.CurrentTrack.Looping = true; } private readonly WeakReference lastTrack = new WeakReference(null); From 0edd50939783f86909c3e024d47100259417c42e Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 5 Aug 2020 21:30:11 +0900 Subject: [PATCH 014/320] Only change track when audio doesn't equal --- osu.Game/Overlays/MusicController.cs | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index 50ad97be7c..47d1bef177 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -320,6 +320,18 @@ namespace osu.Game.Overlays current = beatmap.NewValue; + if (!beatmap.OldValue.BeatmapInfo.AudioEquals(current?.BeatmapInfo)) + changeTrack(); + + TrackChanged?.Invoke(current, direction); + + ResetTrackAdjustments(); + + queuedDirection = null; + } + + private void changeTrack() + { CurrentTrack?.Expire(); CurrentTrack = null; @@ -328,12 +340,6 @@ namespace osu.Game.Overlays trackContainer.Add(CurrentTrack = new DrawableTrack(current.GetRealTrack())); CurrentTrack.Completed += () => onTrackCompleted(current); } - - TrackChanged?.Invoke(current, direction); - - ResetTrackAdjustments(); - - queuedDirection = null; } private void onTrackCompleted(WorkingBeatmap workingBeatmap) From 86ae61c6b79aec0febbe8220781cc7ad3aefb9de Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 5 Aug 2020 22:09:47 +0900 Subject: [PATCH 015/320] Re-implement store transferral in BeatmapManager --- osu.Game/Beatmaps/BeatmapManager.cs | 19 +++++++++++-------- .../Beatmaps/BeatmapManager_WorkingBeatmap.cs | 17 +++++++++-------- 2 files changed, 20 insertions(+), 16 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index b2329f58ad..6a7d0b053f 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -218,7 +218,7 @@ namespace osu.Game.Beatmaps removeWorkingCache(info); } - private readonly WeakList workingCache = new WeakList(); + private readonly WeakList workingCache = new WeakList(); /// /// Retrieve a instance for the provided @@ -246,16 +246,19 @@ namespace osu.Game.Beatmaps lock (workingCache) { var working = workingCache.FirstOrDefault(w => w.BeatmapInfo?.ID == beatmapInfo.ID); + if (working != null) + return working; - if (working == null) - { - beatmapInfo.Metadata ??= beatmapInfo.BeatmapSet.Metadata; + beatmapInfo.Metadata ??= beatmapInfo.BeatmapSet.Metadata; - workingCache.Add(working = new BeatmapManagerWorkingBeatmap(Files.Store, - new LargeTextureStore(host?.CreateTextureLoaderStore(Files.Store)), beatmapInfo, audioManager)); - } + ITrackStore trackStore = workingCache.FirstOrDefault(b => b.BeatmapInfo.AudioEquals(beatmapInfo))?.TrackStore; + TextureStore textureStore = workingCache.FirstOrDefault(b => b.BeatmapInfo.BackgroundEquals(beatmapInfo))?.TextureStore; + + textureStore ??= new LargeTextureStore(host?.CreateTextureLoaderStore(Files.Store)); + trackStore ??= audioManager.GetTrackStore(Files.Store); + + workingCache.Add(working = new BeatmapManagerWorkingBeatmap(Files.Store, textureStore, trackStore, beatmapInfo, audioManager)); - // previous?.TransferTo(working); return working; } } diff --git a/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs b/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs index 33945a9eb1..ceefef5d7e 100644 --- a/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs @@ -19,13 +19,18 @@ namespace osu.Game.Beatmaps { protected class BeatmapManagerWorkingBeatmap : WorkingBeatmap { + public readonly TextureStore TextureStore; + public readonly ITrackStore TrackStore; + private readonly IResourceStore store; - public BeatmapManagerWorkingBeatmap(IResourceStore store, TextureStore textureStore, BeatmapInfo beatmapInfo, AudioManager audioManager) + public BeatmapManagerWorkingBeatmap(IResourceStore store, TextureStore textureStore, ITrackStore trackStore, BeatmapInfo beatmapInfo, AudioManager audioManager) : base(beatmapInfo, audioManager) { this.store = store; - this.textureStore = textureStore; + + TextureStore = textureStore; + TrackStore = trackStore; } protected override IBeatmap GetBeatmap() @@ -44,10 +49,6 @@ namespace osu.Game.Beatmaps private string getPathForFile(string filename) => BeatmapSetInfo.Files.SingleOrDefault(f => string.Equals(f.Filename, filename, StringComparison.OrdinalIgnoreCase))?.FileInfo.StoragePath; - private TextureStore textureStore; - - private ITrackStore trackStore; - protected override bool BackgroundStillValid(Texture b) => false; // bypass lazy logic. we want to return a new background each time for refcounting purposes. protected override Texture GetBackground() @@ -57,7 +58,7 @@ namespace osu.Game.Beatmaps try { - return textureStore.Get(getPathForFile(Metadata.BackgroundFile)); + return TextureStore.Get(getPathForFile(Metadata.BackgroundFile)); } catch (Exception e) { @@ -70,7 +71,7 @@ namespace osu.Game.Beatmaps { try { - return (trackStore ??= AudioManager.GetTrackStore(store)).Get(getPathForFile(Metadata.AudioFile)); + return TrackStore.Get(getPathForFile(Metadata.AudioFile)); } catch (Exception e) { From 0f7fde5d2cd5db7eb8e621bfe221ea28cc252da8 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 5 Aug 2020 22:32:44 +0900 Subject: [PATCH 016/320] Revert unnecessary change --- osu.Game/Overlays/Music/PlaylistOverlay.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Music/PlaylistOverlay.cs b/osu.Game/Overlays/Music/PlaylistOverlay.cs index c089158c01..b9a58c37cb 100644 --- a/osu.Game/Overlays/Music/PlaylistOverlay.cs +++ b/osu.Game/Overlays/Music/PlaylistOverlay.cs @@ -83,7 +83,10 @@ namespace osu.Game.Overlays.Music BeatmapInfo toSelect = list.FirstVisibleSet?.Beatmaps?.FirstOrDefault(); if (toSelect != null) + { beatmap.Value = beatmaps.GetWorkingBeatmap(toSelect); + musicController.CurrentTrack?.Restart(); + } }; } @@ -116,12 +119,12 @@ namespace osu.Game.Overlays.Music { if (set.ID == (beatmap.Value?.BeatmapSetInfo?.ID ?? -1)) { - musicController.SeekTo(0); + musicController.CurrentTrack?.Seek(0); return; } beatmap.Value = beatmaps.GetWorkingBeatmap(set.Beatmaps.First()); - musicController.Play(true); + musicController.CurrentTrack?.Restart(); } } From fe8c462498ad18a842544202bc4e6a14d3e217ed Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 6 Aug 2020 17:00:17 +0900 Subject: [PATCH 017/320] Remove intermediate container --- osu.Game/Overlays/MusicController.cs | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index 47d1bef177..6adfa1817e 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -65,20 +65,12 @@ namespace osu.Game.Overlays [Resolved(canBeNull: true)] private OnScreenDisplay onScreenDisplay { get; set; } - [NotNull] - private readonly TrackContainer trackContainer; - [CanBeNull] public DrawableTrack CurrentTrack { get; private set; } private IBindable> managerUpdated; private IBindable> managerRemoved; - public MusicController() - { - InternalChild = trackContainer = new TrackContainer { RelativeSizeAxes = Axes.Both }; - } - [BackgroundDependencyLoader] private void load() { @@ -337,8 +329,10 @@ namespace osu.Game.Overlays if (current != null) { - trackContainer.Add(CurrentTrack = new DrawableTrack(current.GetRealTrack())); + CurrentTrack = new DrawableTrack(current.GetRealTrack()); CurrentTrack.Completed += () => onTrackCompleted(current); + + AddInternal(CurrentTrack); } } @@ -433,10 +427,6 @@ namespace osu.Game.Overlays { } } - - private class TrackContainer : AudioContainer - { - } } public enum TrackChangeDirection From e8ab3cff3c38c5dad046b0c69f0f34b7478a08ce Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 6 Aug 2020 17:02:42 +0900 Subject: [PATCH 018/320] Add class constraint --- osu.Game/Rulesets/Mods/IApplicableToTrack.cs | 2 +- osu.Game/Rulesets/Mods/ModRateAdjust.cs | 3 ++- osu.Game/Rulesets/Mods/ModTimeRamp.cs | 3 ++- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/osu.Game/Rulesets/Mods/IApplicableToTrack.cs b/osu.Game/Rulesets/Mods/IApplicableToTrack.cs index 5ae41fe09c..b29ba55942 100644 --- a/osu.Game/Rulesets/Mods/IApplicableToTrack.cs +++ b/osu.Game/Rulesets/Mods/IApplicableToTrack.cs @@ -11,6 +11,6 @@ namespace osu.Game.Rulesets.Mods /// public interface IApplicableToTrack : IApplicableMod { - void ApplyToTrack(T track) where T : ITrack, IAdjustableAudioComponent; + void ApplyToTrack(T track) where T : class, ITrack, IAdjustableAudioComponent; } } diff --git a/osu.Game/Rulesets/Mods/ModRateAdjust.cs b/osu.Game/Rulesets/Mods/ModRateAdjust.cs index e2c8ac64d9..4aee5affe9 100644 --- a/osu.Game/Rulesets/Mods/ModRateAdjust.cs +++ b/osu.Game/Rulesets/Mods/ModRateAdjust.cs @@ -12,7 +12,8 @@ namespace osu.Game.Rulesets.Mods { public abstract BindableNumber SpeedChange { get; } - public virtual void ApplyToTrack(T track) where T : ITrack, IAdjustableAudioComponent + public virtual void ApplyToTrack(T track) + where T : class, ITrack, IAdjustableAudioComponent { track.AddAdjustment(AdjustableProperty.Tempo, SpeedChange); } diff --git a/osu.Game/Rulesets/Mods/ModTimeRamp.cs b/osu.Game/Rulesets/Mods/ModTimeRamp.cs index b6cbe72971..4b5241488f 100644 --- a/osu.Game/Rulesets/Mods/ModTimeRamp.cs +++ b/osu.Game/Rulesets/Mods/ModTimeRamp.cs @@ -51,7 +51,8 @@ namespace osu.Game.Rulesets.Mods AdjustPitch.BindValueChanged(applyPitchAdjustment); } - public void ApplyToTrack(T track) where T : ITrack, IAdjustableAudioComponent + public void ApplyToTrack(T track) + where T : class, ITrack, IAdjustableAudioComponent { this.track = track; From c72ab9047e3ea00dbc6eb176a797d20dfd5c95d3 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 6 Aug 2020 17:15:33 +0900 Subject: [PATCH 019/320] Cleanup test scene disposal --- osu.Game/Tests/Visual/OsuTestScene.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/osu.Game/Tests/Visual/OsuTestScene.cs b/osu.Game/Tests/Visual/OsuTestScene.cs index e968f7e675..f2b9388fdc 100644 --- a/osu.Game/Tests/Visual/OsuTestScene.cs +++ b/osu.Game/Tests/Visual/OsuTestScene.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.IO; using System.Linq; using System.Threading.Tasks; @@ -169,7 +170,10 @@ namespace osu.Game.Tests.Visual rulesetDependencies?.Dispose(); if (MusicController?.TrackLoaded == true) - MusicController.Stop(); + { + Debug.Assert(MusicController.CurrentTrack != null); + MusicController.CurrentTrack.Stop(); + } if (contextFactory.IsValueCreated) contextFactory.Value.ResetDatabase(); From f53672193eb6ccd1d14c7900603aa5269e7468c9 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 6 Aug 2020 17:48:07 +0900 Subject: [PATCH 020/320] Fix track stores being kept alive --- osu.Game/Beatmaps/BeatmapManager.cs | 16 +++++++++++++++- .../Beatmaps/BeatmapManager_WorkingBeatmap.cs | 10 +++++++++- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index 6a7d0b053f..f22f41531a 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -219,6 +219,7 @@ namespace osu.Game.Beatmaps } private readonly WeakList workingCache = new WeakList(); + private readonly Dictionary referencedTrackStores = new Dictionary(); /// /// Retrieve a instance for the provided @@ -257,12 +258,25 @@ namespace osu.Game.Beatmaps textureStore ??= new LargeTextureStore(host?.CreateTextureLoaderStore(Files.Store)); trackStore ??= audioManager.GetTrackStore(Files.Store); - workingCache.Add(working = new BeatmapManagerWorkingBeatmap(Files.Store, textureStore, trackStore, beatmapInfo, audioManager)); + workingCache.Add(working = new BeatmapManagerWorkingBeatmap(Files.Store, textureStore, trackStore, beatmapInfo, audioManager, dereferenceTrackStore)); + referencedTrackStores[trackStore] = referencedTrackStores.GetOrDefault(trackStore) + 1; return working; } } + private void dereferenceTrackStore(ITrackStore trackStore) + { + lock (workingCache) + { + if (--referencedTrackStores[trackStore] == 0) + { + referencedTrackStores.Remove(trackStore); + trackStore.Dispose(); + } + } + } + /// /// Perform a lookup query on available s. /// diff --git a/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs b/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs index ceefef5d7e..a54d46c1b1 100644 --- a/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs @@ -23,11 +23,14 @@ namespace osu.Game.Beatmaps public readonly ITrackStore TrackStore; private readonly IResourceStore store; + private readonly Action dereferenceAction; - public BeatmapManagerWorkingBeatmap(IResourceStore store, TextureStore textureStore, ITrackStore trackStore, BeatmapInfo beatmapInfo, AudioManager audioManager) + public BeatmapManagerWorkingBeatmap(IResourceStore store, TextureStore textureStore, ITrackStore trackStore, BeatmapInfo beatmapInfo, AudioManager audioManager, + Action dereferenceAction) : base(beatmapInfo, audioManager) { this.store = store; + this.dereferenceAction = dereferenceAction; TextureStore = textureStore; TrackStore = trackStore; @@ -137,6 +140,11 @@ namespace osu.Game.Beatmaps return null; } } + + ~BeatmapManagerWorkingBeatmap() + { + dereferenceAction?.Invoke(TrackStore); + } } } } From c8ebbc8594b79423825614268feb88f2f20a32e6 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 6 Aug 2020 18:19:55 +0900 Subject: [PATCH 021/320] Remove MusicController from EditorClock --- .../Timelines/Summary/Parts/MarkerPart.cs | 5 +-- osu.Game/Screens/Edit/Editor.cs | 2 +- osu.Game/Screens/Edit/EditorClock.cs | 36 ++++++------------- 3 files changed, 13 insertions(+), 30 deletions(-) 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 a353f79ef4..9e9ac93d23 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/MarkerPart.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/MarkerPart.cs @@ -2,7 +2,6 @@ // See the LICENCE file in the repository root for full licence text. using System; -using System.Diagnostics; using osuTK; using osu.Framework.Allocation; using osu.Framework.Graphics; @@ -59,9 +58,7 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts return; float markerPos = Math.Clamp(ToLocalSpace(screenPosition).X, 0, DrawWidth); - - Debug.Assert(editorClock.TrackLength != null); - editorClock.SeekTo(markerPos / DrawWidth * editorClock.TrackLength.Value); + editorClock.SeekTo(markerPos / DrawWidth * editorClock.TrackLength); }); } diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index b02aabc24d..79b13a7eac 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -84,7 +84,7 @@ namespace osu.Game.Screens.Edit // Todo: should probably be done at a DrawableRuleset level to share logic with Player. var sourceClock = (IAdjustableClock)musicController.CurrentTrack ?? new StopwatchClock(); - clock = new EditorClock(Beatmap.Value, beatDivisor) { IsCoupled = false }; + clock = new EditorClock(Beatmap.Value, musicController.CurrentTrack?.Length ?? 0, beatDivisor) { IsCoupled = false }; clock.ChangeSource(sourceClock); dependencies.CacheAs(clock); diff --git a/osu.Game/Screens/Edit/EditorClock.cs b/osu.Game/Screens/Edit/EditorClock.cs index 4e589aeeef..fbfa397795 100644 --- a/osu.Game/Screens/Edit/EditorClock.cs +++ b/osu.Game/Screens/Edit/EditorClock.cs @@ -2,16 +2,13 @@ // See the LICENCE file in the repository root for full licence text. using System; -using System.Diagnostics; using System.Linq; -using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Transforms; using osu.Framework.Utils; using osu.Framework.Timing; using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; -using osu.Game.Overlays; namespace osu.Game.Screens.Edit { @@ -20,7 +17,7 @@ namespace osu.Game.Screens.Edit /// public class EditorClock : Component, IFrameBasedClock, IAdjustableClock, ISourceChangeableClock { - public double? TrackLength { get; private set; } + public readonly double TrackLength; public ControlPointInfo ControlPointInfo; @@ -28,34 +25,24 @@ namespace osu.Game.Screens.Edit private readonly DecoupleableInterpolatingFramedClock underlyingClock; - [Resolved] - private MusicController musicController { get; set; } - - public EditorClock(WorkingBeatmap beatmap, BindableBeatDivisor beatDivisor) - : this(beatmap.Beatmap.ControlPointInfo, null, beatDivisor) + public EditorClock(WorkingBeatmap beatmap, double trackLength, BindableBeatDivisor beatDivisor) + : this(beatmap.Beatmap.ControlPointInfo, trackLength, beatDivisor) { } - public EditorClock(ControlPointInfo controlPointInfo, double? trackLength, BindableBeatDivisor beatDivisor) - { - this.beatDivisor = beatDivisor; - - ControlPointInfo = controlPointInfo; - TrackLength = trackLength; - - underlyingClock = new DecoupleableInterpolatingFramedClock(); - } - public EditorClock() : this(new ControlPointInfo(), 1000, new BindableBeatDivisor()) { } - [BackgroundDependencyLoader] - private void load() + public EditorClock(ControlPointInfo controlPointInfo, double trackLength, BindableBeatDivisor beatDivisor) { - // Todo: What. - TrackLength ??= musicController.CurrentTrack?.Length ?? 0; + this.beatDivisor = beatDivisor; + + ControlPointInfo = controlPointInfo; + TrackLength = trackLength; + + underlyingClock = new DecoupleableInterpolatingFramedClock(); } /// @@ -148,8 +135,7 @@ namespace osu.Game.Screens.Edit seekTime = timingPoint.Time; // Ensure the sought point is within the boundaries - Debug.Assert(TrackLength != null); - seekTime = Math.Clamp(seekTime, 0, TrackLength.Value); + seekTime = Math.Clamp(seekTime, 0, TrackLength); SeekTo(seekTime); } From 7c3ae4ed4291eeb86f704344956dedfef75e8735 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 6 Aug 2020 18:25:34 +0900 Subject: [PATCH 022/320] Remove generics from IApplicableToTrack --- osu.Game/Rulesets/Mods/IApplicableToTrack.cs | 3 +-- osu.Game/Rulesets/Mods/ModDaycore.cs | 7 ++++--- osu.Game/Rulesets/Mods/ModNightcore.cs | 6 +++--- osu.Game/Rulesets/Mods/ModRateAdjust.cs | 5 ++--- osu.Game/Rulesets/Mods/ModTimeRamp.cs | 3 +-- 5 files changed, 11 insertions(+), 13 deletions(-) diff --git a/osu.Game/Rulesets/Mods/IApplicableToTrack.cs b/osu.Game/Rulesets/Mods/IApplicableToTrack.cs index b29ba55942..9b840cea08 100644 --- a/osu.Game/Rulesets/Mods/IApplicableToTrack.cs +++ b/osu.Game/Rulesets/Mods/IApplicableToTrack.cs @@ -1,7 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using osu.Framework.Audio; using osu.Framework.Audio.Track; namespace osu.Game.Rulesets.Mods @@ -11,6 +10,6 @@ namespace osu.Game.Rulesets.Mods /// public interface IApplicableToTrack : IApplicableMod { - void ApplyToTrack(T track) where T : class, ITrack, IAdjustableAudioComponent; + void ApplyToTrack(ITrack track); } } diff --git a/osu.Game/Rulesets/Mods/ModDaycore.cs b/osu.Game/Rulesets/Mods/ModDaycore.cs index 989978eb35..800312d047 100644 --- a/osu.Game/Rulesets/Mods/ModDaycore.cs +++ b/osu.Game/Rulesets/Mods/ModDaycore.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Audio; +using osu.Framework.Audio.Track; using osu.Framework.Bindables; using osu.Framework.Graphics.Sprites; @@ -26,11 +27,11 @@ namespace osu.Game.Rulesets.Mods }, true); } - public override void ApplyToTrack(T track) + public override void ApplyToTrack(ITrack track) { // base.ApplyToTrack() intentionally not called (different tempo adjustment is applied) - track.AddAdjustment(AdjustableProperty.Frequency, freqAdjust); - track.AddAdjustment(AdjustableProperty.Tempo, tempoAdjust); + (track as IAdjustableAudioComponent)?.AddAdjustment(AdjustableProperty.Frequency, freqAdjust); + (track as IAdjustableAudioComponent)?.AddAdjustment(AdjustableProperty.Tempo, tempoAdjust); } } } diff --git a/osu.Game/Rulesets/Mods/ModNightcore.cs b/osu.Game/Rulesets/Mods/ModNightcore.cs index 70cdaa6345..4932df08f1 100644 --- a/osu.Game/Rulesets/Mods/ModNightcore.cs +++ b/osu.Game/Rulesets/Mods/ModNightcore.cs @@ -38,11 +38,11 @@ namespace osu.Game.Rulesets.Mods }, true); } - public override void ApplyToTrack(T track) + public override void ApplyToTrack(ITrack track) { // base.ApplyToTrack() intentionally not called (different tempo adjustment is applied) - track.AddAdjustment(AdjustableProperty.Frequency, freqAdjust); - track.AddAdjustment(AdjustableProperty.Tempo, tempoAdjust); + (track as IAdjustableAudioComponent)?.AddAdjustment(AdjustableProperty.Frequency, freqAdjust); + (track as IAdjustableAudioComponent)?.AddAdjustment(AdjustableProperty.Tempo, tempoAdjust); } public void ApplyToDrawableRuleset(DrawableRuleset drawableRuleset) diff --git a/osu.Game/Rulesets/Mods/ModRateAdjust.cs b/osu.Game/Rulesets/Mods/ModRateAdjust.cs index 4aee5affe9..ae7077c67b 100644 --- a/osu.Game/Rulesets/Mods/ModRateAdjust.cs +++ b/osu.Game/Rulesets/Mods/ModRateAdjust.cs @@ -12,10 +12,9 @@ namespace osu.Game.Rulesets.Mods { public abstract BindableNumber SpeedChange { get; } - public virtual void ApplyToTrack(T track) - where T : class, ITrack, IAdjustableAudioComponent + public virtual void ApplyToTrack(ITrack track) { - track.AddAdjustment(AdjustableProperty.Tempo, SpeedChange); + (track as IAdjustableAudioComponent)?.AddAdjustment(AdjustableProperty.Tempo, SpeedChange); } public virtual void ApplyToSample(SampleChannel sample) diff --git a/osu.Game/Rulesets/Mods/ModTimeRamp.cs b/osu.Game/Rulesets/Mods/ModTimeRamp.cs index 4b5241488f..b904cf007b 100644 --- a/osu.Game/Rulesets/Mods/ModTimeRamp.cs +++ b/osu.Game/Rulesets/Mods/ModTimeRamp.cs @@ -51,8 +51,7 @@ namespace osu.Game.Rulesets.Mods AdjustPitch.BindValueChanged(applyPitchAdjustment); } - public void ApplyToTrack(T track) - where T : class, ITrack, IAdjustableAudioComponent + public void ApplyToTrack(ITrack track) { this.track = track; From 2e3ecf71c70c035db37621df04cc289a4b7d7489 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 6 Aug 2020 18:31:08 +0900 Subject: [PATCH 023/320] Pass track from Player to components --- .../TestSceneGameplayClockContainer.cs | 7 +++++- .../Gameplay/TestSceneStoryboardSamples.cs | 6 +++-- .../Visual/Gameplay/TestSceneSkipOverlay.cs | 4 +++- osu.Game/Screens/Play/FailAnimation.cs | 16 ++++++-------- .../Screens/Play/GameplayClockContainer.cs | 22 +++++++++---------- osu.Game/Screens/Play/Player.cs | 11 +++++----- 6 files changed, 36 insertions(+), 30 deletions(-) diff --git a/osu.Game.Tests/Gameplay/TestSceneGameplayClockContainer.cs b/osu.Game.Tests/Gameplay/TestSceneGameplayClockContainer.cs index cd3669f160..40f6cecd9a 100644 --- a/osu.Game.Tests/Gameplay/TestSceneGameplayClockContainer.cs +++ b/osu.Game.Tests/Gameplay/TestSceneGameplayClockContainer.cs @@ -19,7 +19,12 @@ namespace osu.Game.Tests.Gameplay { GameplayClockContainer gcc = null; - AddStep("create container", () => Add(gcc = new GameplayClockContainer(CreateWorkingBeatmap(new OsuRuleset().RulesetInfo), Array.Empty(), 0))); + AddStep("create container", () => + { + var working = CreateWorkingBeatmap(new OsuRuleset().RulesetInfo); + Add(gcc = new GameplayClockContainer(working.GetRealTrack(), working, Array.Empty(), 0)); + }); + AddStep("start track", () => gcc.Start()); AddUntilStep("elapsed greater than zero", () => gcc.GameplayClock.ElapsedFrameTime > 0); } diff --git a/osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs b/osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs index b30870d057..720436fae4 100644 --- a/osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs +++ b/osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs @@ -59,7 +59,9 @@ namespace osu.Game.Tests.Gameplay AddStep("create container", () => { - Add(gameplayContainer = new GameplayClockContainer(CreateWorkingBeatmap(new OsuRuleset().RulesetInfo), Array.Empty(), 0)); + var working = CreateWorkingBeatmap(new OsuRuleset().RulesetInfo); + + Add(gameplayContainer = new GameplayClockContainer(working.GetRealTrack(), working, Array.Empty(), 0)); gameplayContainer.Add(sample = new DrawableStoryboardSample(new StoryboardSampleInfo(string.Empty, 0, 1)) { @@ -103,7 +105,7 @@ namespace osu.Game.Tests.Gameplay Beatmap.Value = new TestCustomSkinWorkingBeatmap(new OsuRuleset().RulesetInfo, Audio); SelectedMods.Value = new[] { testedMod }; - Add(gameplayContainer = new GameplayClockContainer(Beatmap.Value, SelectedMods.Value, 0)); + Add(gameplayContainer = new GameplayClockContainer(MusicController.CurrentTrack, Beatmap.Value, SelectedMods.Value, 0)); gameplayContainer.Add(sample = new TestDrawableStoryboardSample(new StoryboardSampleInfo("test-sample", 1, 1)) { diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSkipOverlay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSkipOverlay.cs index 7ed7a116b4..68110d759c 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSkipOverlay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSkipOverlay.cs @@ -32,7 +32,9 @@ namespace osu.Game.Tests.Visual.Gameplay requestCount = 0; increment = skip_time; - Child = gameplayClockContainer = new GameplayClockContainer(CreateWorkingBeatmap(CreateBeatmap(new OsuRuleset().RulesetInfo)), Array.Empty(), 0) + var working = CreateWorkingBeatmap(CreateBeatmap(new OsuRuleset().RulesetInfo)); + + Child = gameplayClockContainer = new GameplayClockContainer(working.GetRealTrack(), working, Array.Empty(), 0) { RelativeSizeAxes = Axes.Both, Children = new Drawable[] diff --git a/osu.Game/Screens/Play/FailAnimation.cs b/osu.Game/Screens/Play/FailAnimation.cs index 1171d8c3b0..a7bfca612e 100644 --- a/osu.Game/Screens/Play/FailAnimation.cs +++ b/osu.Game/Screens/Play/FailAnimation.cs @@ -8,11 +8,10 @@ using System; using System.Collections.Generic; using osu.Framework.Allocation; using osu.Framework.Audio.Sample; +using osu.Framework.Audio.Track; using osu.Framework.Graphics; -using osu.Framework.Graphics.Audio; using osu.Framework.Utils; using osu.Game.Beatmaps; -using osu.Game.Overlays; using osu.Game.Rulesets.Objects.Drawables; using osuTK; using osuTK.Graphics; @@ -28,24 +27,23 @@ namespace osu.Game.Screens.Play public Action OnComplete; private readonly DrawableRuleset drawableRuleset; + private readonly ITrack track; private readonly BindableDouble trackFreq = new BindableDouble(1); - private DrawableTrack track; - private const float duration = 2500; private SampleChannel failSample; - public FailAnimation(DrawableRuleset drawableRuleset) + public FailAnimation(DrawableRuleset drawableRuleset, ITrack track) { this.drawableRuleset = drawableRuleset; + this.track = track; } [BackgroundDependencyLoader] - private void load(AudioManager audio, IBindable beatmap, MusicController musicController) + private void load(AudioManager audio, IBindable beatmap) { - track = musicController.CurrentTrack; failSample = audio.Samples.Get(@"Gameplay/failsound"); } @@ -69,7 +67,7 @@ namespace osu.Game.Screens.Play Expire(); }); - track.AddAdjustment(AdjustableProperty.Frequency, trackFreq); + (track as IAdjustableAudioComponent)?.AddAdjustment(AdjustableProperty.Frequency, trackFreq); applyToPlayfield(drawableRuleset.Playfield); drawableRuleset.Playfield.HitObjectContainer.FlashColour(Color4.Red, 500); @@ -108,7 +106,7 @@ namespace osu.Game.Screens.Play protected override void Dispose(bool isDisposing) { base.Dispose(isDisposing); - track?.RemoveAdjustment(AdjustableProperty.Frequency, trackFreq); + (track as IAdjustableAudioComponent)?.RemoveAdjustment(AdjustableProperty.Frequency, trackFreq); } } } diff --git a/osu.Game/Screens/Play/GameplayClockContainer.cs b/osu.Game/Screens/Play/GameplayClockContainer.cs index 61272f56ad..c4f368e1f5 100644 --- a/osu.Game/Screens/Play/GameplayClockContainer.cs +++ b/osu.Game/Screens/Play/GameplayClockContainer.cs @@ -11,12 +11,10 @@ using osu.Framework.Audio; using osu.Framework.Audio.Track; using osu.Framework.Bindables; using osu.Framework.Graphics; -using osu.Framework.Graphics.Audio; using osu.Framework.Graphics.Containers; using osu.Framework.Timing; using osu.Game.Beatmaps; using osu.Game.Configuration; -using osu.Game.Overlays; using osu.Game.Rulesets.Mods; namespace osu.Game.Screens.Play @@ -29,7 +27,7 @@ namespace osu.Game.Screens.Play private readonly WorkingBeatmap beatmap; private readonly IReadOnlyList mods; - private DrawableTrack track; + private ITrack track; public readonly BindableBool IsPaused = new BindableBool(); @@ -62,11 +60,13 @@ namespace osu.Game.Screens.Play private readonly FramedOffsetClock platformOffsetClock; - public GameplayClockContainer(WorkingBeatmap beatmap, IReadOnlyList mods, double gameplayStartTime) + public GameplayClockContainer(ITrack track, WorkingBeatmap beatmap, IReadOnlyList mods, double gameplayStartTime) { this.beatmap = beatmap; this.mods = mods; this.gameplayStartTime = gameplayStartTime; + this.track = track; + firstHitObjectTime = beatmap.Beatmap.HitObjects.First().StartTime; RelativeSizeAxes = Axes.Both; @@ -96,10 +96,8 @@ namespace osu.Game.Screens.Play private readonly BindableDouble pauseFreqAdjust = new BindableDouble(1); [BackgroundDependencyLoader] - private void load(OsuConfigManager config, MusicController musicController) + private void load(OsuConfigManager config) { - track = musicController.CurrentTrack; - userAudioOffset = config.GetBindable(OsuSetting.AudioOffset); userAudioOffset.BindValueChanged(offset => userOffsetClock.Offset = offset.NewValue, true); @@ -132,7 +130,7 @@ namespace osu.Game.Screens.Play Schedule(() => { - adjustableClock.ChangeSource(track); + adjustableClock.ChangeSource((IAdjustableClock)track); updateRate(); if (!IsPaused.Value) @@ -203,8 +201,8 @@ namespace osu.Game.Screens.Play removeSourceClockAdjustments(); - track = new DrawableTrack(new TrackVirtual(track.Length)); - adjustableClock.ChangeSource(track); + track = new TrackVirtual(track.Length); + adjustableClock.ChangeSource((IAdjustableClock)track); } protected override void Update() @@ -224,8 +222,8 @@ namespace osu.Game.Screens.Play speedAdjustmentsApplied = true; track.ResetSpeedAdjustments(); - track.AddAdjustment(AdjustableProperty.Frequency, pauseFreqAdjust); - track.AddAdjustment(AdjustableProperty.Tempo, UserPlaybackRate); + (track as IAdjustableAudioComponent)?.AddAdjustment(AdjustableProperty.Frequency, pauseFreqAdjust); + (track as IAdjustableAudioComponent)?.AddAdjustment(AdjustableProperty.Tempo, UserPlaybackRate); foreach (var mod in mods.OfType()) mod.ApplyToTrack(track); diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 541275cf55..e92164de7c 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -8,6 +8,7 @@ using System.Linq; using osu.Framework.Allocation; using osu.Framework.Audio; using osu.Framework.Audio.Sample; +using osu.Framework.Audio.Track; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -150,7 +151,7 @@ namespace osu.Game.Screens.Play } [BackgroundDependencyLoader] - private void load(AudioManager audio, OsuConfigManager config) + private void load(AudioManager audio, OsuConfigManager config, MusicController musicController) { Mods.Value = base.Mods.Value.Select(m => m.CreateCopy()).ToArray(); @@ -178,7 +179,7 @@ namespace osu.Game.Screens.Play if (!ScoreProcessor.Mode.Disabled) config.BindWith(OsuSetting.ScoreDisplayMode, ScoreProcessor.Mode); - InternalChild = GameplayClockContainer = new GameplayClockContainer(Beatmap.Value, Mods.Value, DrawableRuleset.GameplayStartTime); + InternalChild = GameplayClockContainer = new GameplayClockContainer(musicController.CurrentTrack, Beatmap.Value, Mods.Value, DrawableRuleset.GameplayStartTime); AddInternal(gameplayBeatmap = new GameplayBeatmap(playableBeatmap)); AddInternal(screenSuspension = new ScreenSuspensionHandler(GameplayClockContainer)); @@ -187,7 +188,7 @@ namespace osu.Game.Screens.Play addUnderlayComponents(GameplayClockContainer); addGameplayComponents(GameplayClockContainer, Beatmap.Value, playableBeatmap); - addOverlayComponents(GameplayClockContainer, Beatmap.Value); + addOverlayComponents(GameplayClockContainer, Beatmap.Value, musicController.CurrentTrack); if (!DrawableRuleset.AllowGameplayOverlays) { @@ -264,7 +265,7 @@ namespace osu.Game.Screens.Play }); } - private void addOverlayComponents(Container target, WorkingBeatmap working) + private void addOverlayComponents(Container target, WorkingBeatmap working, ITrack track) { target.AddRange(new[] { @@ -331,7 +332,7 @@ namespace osu.Game.Screens.Play performImmediateExit(); }, }, - failAnimation = new FailAnimation(DrawableRuleset) { OnComplete = onFailComplete, }, + failAnimation = new FailAnimation(DrawableRuleset, track) { OnComplete = onFailComplete, }, }); } From ef689d943aafc413dac909da50d96532816abd6c Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 6 Aug 2020 18:54:08 +0900 Subject: [PATCH 024/320] Fix intros playing incorrectly --- osu.Game/OsuGame.cs | 4 ++-- osu.Game/Screens/Menu/IntroScreen.cs | 13 +++++++------ osu.Game/Screens/Menu/IntroTriangles.cs | 2 +- osu.Game/Screens/Menu/IntroWelcome.cs | 9 ++------- 4 files changed, 12 insertions(+), 16 deletions(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index a41c7b28a5..0049e5a520 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -581,6 +581,8 @@ namespace osu.Game ScreenStack.ScreenPushed += screenPushed; ScreenStack.ScreenExited += screenExited; + loadComponentSingleFile(MusicController, Add); + loadComponentSingleFile(osuLogo, logo => { logoContainer.Add(logo); @@ -602,8 +604,6 @@ namespace osu.Game loadComponentSingleFile(new OnScreenDisplay(), Add, true); - loadComponentSingleFile(MusicController, Add); - loadComponentSingleFile(notifications.With(d => { d.GetToolbarHeight = () => ToolbarOffset; diff --git a/osu.Game/Screens/Menu/IntroScreen.cs b/osu.Game/Screens/Menu/IntroScreen.cs index 030923c228..7e327261ab 100644 --- a/osu.Game/Screens/Menu/IntroScreen.cs +++ b/osu.Game/Screens/Menu/IntroScreen.cs @@ -44,8 +44,7 @@ namespace osu.Game.Screens.Menu private WorkingBeatmap initialBeatmap; - [Resolved] - protected MusicController MusicController { get; private set; } + protected ITrack Track { get; private set; } private readonly BindableDouble exitingVolumeFade = new BindableDouble(1); @@ -62,6 +61,9 @@ namespace osu.Game.Screens.Menu [Resolved] private AudioManager audio { get; set; } + [Resolved] + private MusicController musicController { get; set; } + /// /// Whether the is provided by osu! resources, rather than a user beatmap. /// @@ -113,9 +115,7 @@ namespace osu.Game.Screens.Menu if (setInfo != null) { initialBeatmap = beatmaps.GetWorkingBeatmap(setInfo.Beatmaps[0]); - - // Todo: Wrong. - UsingThemedIntro = MusicController.CurrentTrack?.IsDummyDevice == false; + UsingThemedIntro = initialBeatmap.GetRealTrack().IsDummyDevice == false; } return UsingThemedIntro; @@ -154,7 +154,7 @@ namespace osu.Game.Screens.Menu { // Only start the current track if it is the menu music. A beatmap's track is started when entering the Main Menu. if (UsingThemedIntro) - MusicController.Play(true); + Track.Restart(); } protected override void LogoArriving(OsuLogo logo, bool resuming) @@ -168,6 +168,7 @@ namespace osu.Game.Screens.Menu if (!resuming) { beatmap.Value = initialBeatmap; + Track = musicController.CurrentTrack; logo.MoveTo(new Vector2(0.5f)); logo.ScaleTo(Vector2.One); diff --git a/osu.Game/Screens/Menu/IntroTriangles.cs b/osu.Game/Screens/Menu/IntroTriangles.cs index e29ea6e743..86f7dbdd6f 100644 --- a/osu.Game/Screens/Menu/IntroTriangles.cs +++ b/osu.Game/Screens/Menu/IntroTriangles.cs @@ -59,7 +59,7 @@ namespace osu.Game.Screens.Menu LoadComponentAsync(new TrianglesIntroSequence(logo, background) { RelativeSizeAxes = Axes.Both, - Clock = new FramedClock(UsingThemedIntro ? MusicController.CurrentTrack : null), + Clock = new FramedClock(UsingThemedIntro ? (IAdjustableClock)Track : null), LoadMenu = LoadMenu }, t => { diff --git a/osu.Game/Screens/Menu/IntroWelcome.cs b/osu.Game/Screens/Menu/IntroWelcome.cs index 85f11eb244..e81646456f 100644 --- a/osu.Game/Screens/Menu/IntroWelcome.cs +++ b/osu.Game/Screens/Menu/IntroWelcome.cs @@ -11,7 +11,6 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Textures; -using osu.Game.Overlays; using osu.Game.Screens.Backgrounds; using osuTK.Graphics; @@ -31,9 +30,6 @@ namespace osu.Game.Screens.Menu Alpha = 0, }; - [Resolved] - private MusicController musicController { get; set; } - private BackgroundScreenDefault background; [BackgroundDependencyLoader] @@ -43,9 +39,6 @@ namespace osu.Game.Screens.Menu welcome = audio.Samples.Get(@"Intro/Welcome/welcome"); pianoReverb = audio.Samples.Get(@"Intro/Welcome/welcome_piano"); - - if (musicController.CurrentTrack != null) - musicController.CurrentTrack.Looping = true; } protected override void LogoArriving(OsuLogo logo, bool resuming) @@ -54,6 +47,8 @@ namespace osu.Game.Screens.Menu if (!resuming) { + Track.Looping = true; + LoadComponentAsync(new WelcomeIntroSequence { RelativeSizeAxes = Axes.Both From f8279dab328d758f2a590924de44a8a8921ca595 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 6 Aug 2020 18:54:14 +0900 Subject: [PATCH 025/320] Refactor MainMenu --- osu.Game/Screens/Menu/MainMenu.cs | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/osu.Game/Screens/Menu/MainMenu.cs b/osu.Game/Screens/Menu/MainMenu.cs index ce48777ce1..ea4347a285 100644 --- a/osu.Game/Screens/Menu/MainMenu.cs +++ b/osu.Game/Screens/Menu/MainMenu.cs @@ -170,9 +170,6 @@ namespace osu.Game.Screens.Menu [Resolved] private Storage storage { get; set; } - [Resolved] - private MusicController musicController { get; set; } - public override void OnEntering(IScreen last) { base.OnEntering(last); @@ -180,14 +177,14 @@ namespace osu.Game.Screens.Menu var metadata = Beatmap.Value.Metadata; - if (last is IntroScreen && musicController.TrackLoaded) + if (last is IntroScreen && music.TrackLoaded) { - Debug.Assert(musicController.CurrentTrack != null); + Debug.Assert(music.CurrentTrack != null); - if (!musicController.CurrentTrack.IsRunning) + if (!music.CurrentTrack.IsRunning) { - musicController.CurrentTrack.Seek(metadata.PreviewTime != -1 ? metadata.PreviewTime : 0.4f * musicController.CurrentTrack.Length); - musicController.CurrentTrack.Start(); + music.CurrentTrack.Seek(metadata.PreviewTime != -1 ? metadata.PreviewTime : 0.4f * music.CurrentTrack.Length); + music.CurrentTrack.Start(); } } From adf4f56dce1871816e29bde01e51fe78a77397ab Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 6 Aug 2020 19:01:23 +0900 Subject: [PATCH 026/320] Move MusicController to OsuGameBase --- osu.Game/OsuGame.cs | 5 ----- osu.Game/OsuGameBase.cs | 6 ++++++ 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 0049e5a520..cf4610793c 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -538,7 +538,6 @@ namespace osu.Game Container logoContainer; BackButton.Receptor receptor; - dependencies.CacheAs(MusicController = new MusicController()); dependencies.CacheAs(idleTracker = new GameIdleTracker(6000)); AddRange(new Drawable[] @@ -581,8 +580,6 @@ namespace osu.Game ScreenStack.ScreenPushed += screenPushed; ScreenStack.ScreenExited += screenExited; - loadComponentSingleFile(MusicController, Add); - loadComponentSingleFile(osuLogo, logo => { logoContainer.Add(logo); @@ -925,8 +922,6 @@ namespace osu.Game private ScalingContainer screenContainer; - protected MusicController MusicController { get; private set; } - protected override bool OnExiting() { if (ScreenStack.CurrentScreen is Loader) diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index 24c1f7849c..51b9b7278d 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -30,6 +30,7 @@ using osu.Game.Database; using osu.Game.Input; using osu.Game.Input.Bindings; using osu.Game.IO; +using osu.Game.Overlays; using osu.Game.Resources; using osu.Game.Rulesets; using osu.Game.Rulesets.Mods; @@ -73,6 +74,8 @@ namespace osu.Game protected MenuCursorContainer MenuCursorContainer; + protected MusicController MusicController; + private Container content; protected override Container Content => content; @@ -265,6 +268,9 @@ namespace osu.Game dependencies.Cache(previewTrackManager = new PreviewTrackManager()); Add(previewTrackManager); + AddInternal(MusicController = new MusicController()); + dependencies.CacheAs(MusicController); + Ruleset.BindValueChanged(onRulesetChanged); } From 4cfca71d080822734e7f29de27b5273f3304460a Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 6 Aug 2020 19:05:15 +0900 Subject: [PATCH 027/320] Fix a few test scenes --- osu.Game/Tests/Visual/RateAdjustedBeatmapTestScene.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/osu.Game/Tests/Visual/RateAdjustedBeatmapTestScene.cs b/osu.Game/Tests/Visual/RateAdjustedBeatmapTestScene.cs index ae4b0ef84a..a6266d210c 100644 --- a/osu.Game/Tests/Visual/RateAdjustedBeatmapTestScene.cs +++ b/osu.Game/Tests/Visual/RateAdjustedBeatmapTestScene.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.Diagnostics; using osu.Framework.Extensions.ObjectExtensions; namespace osu.Game.Tests.Visual @@ -15,7 +16,11 @@ namespace osu.Game.Tests.Visual base.Update(); // note that this will override any mod rate application - MusicController.CurrentTrack.AsNonNull().Tempo.Value = Clock.Rate; + if (MusicController.TrackLoaded) + { + Debug.Assert(MusicController.CurrentTrack != null); + MusicController.CurrentTrack.Tempo.Value = Clock.Rate; + } } } } From d1af1429b3dd8d79ba36bc5d41ac02a75ad86bac Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 6 Aug 2020 19:08:45 +0900 Subject: [PATCH 028/320] Fix inspection --- osu.Game/Tests/Visual/RateAdjustedBeatmapTestScene.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Tests/Visual/RateAdjustedBeatmapTestScene.cs b/osu.Game/Tests/Visual/RateAdjustedBeatmapTestScene.cs index a6266d210c..54458716b1 100644 --- a/osu.Game/Tests/Visual/RateAdjustedBeatmapTestScene.cs +++ b/osu.Game/Tests/Visual/RateAdjustedBeatmapTestScene.cs @@ -2,7 +2,6 @@ // See the LICENCE file in the repository root for full licence text. using System.Diagnostics; -using osu.Framework.Extensions.ObjectExtensions; namespace osu.Game.Tests.Visual { From f8ef53a62e0f4fecc26a614373749ccf08b14d43 Mon Sep 17 00:00:00 2001 From: Lucas A Date: Fri, 7 Aug 2020 10:17:11 +0200 Subject: [PATCH 029/320] Fix tests. --- .../Visual/Gameplay/TestSceneOverlayActivation.cs | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneOverlayActivation.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneOverlayActivation.cs index 9e93cf363d..03e1337125 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneOverlayActivation.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneOverlayActivation.cs @@ -2,7 +2,6 @@ // See the LICENCE file in the repository root for full licence text. using NUnit.Framework; -using osu.Framework.Allocation; using osu.Game.Configuration; using osu.Game.Overlays; using osu.Game.Rulesets; @@ -13,21 +12,25 @@ namespace osu.Game.Tests.Visual.Gameplay { private OverlayTestPlayer testPlayer; - [Resolved] - private OsuConfigManager config { get; set; } - public override void SetUpSteps() { - AddStep("disable overlay activation during gameplay", () => config.Set(OsuSetting.GameplayDisableOverlayActivation, true)); + AddStep("disable overlay activation during gameplay", () => LocalConfig.Set(OsuSetting.GameplayDisableOverlayActivation, true)); base.SetUpSteps(); } [Test] - public void TestGameplayOverlayActivationSetting() + public void TestGameplayOverlayActivation() { AddAssert("activation mode is disabled", () => testPlayer.OverlayActivationMode == OverlayActivation.Disabled); } + [Test] + public void TestGameplayOverlayActivationDisabled() + { + AddStep("enable overlay activation during gameplay", () => LocalConfig.Set(OsuSetting.GameplayDisableOverlayActivation, false)); + AddAssert("activation mode is user triggered", () => testPlayer.OverlayActivationMode == OverlayActivation.UserTriggered); + } + [Test] public void TestGameplayOverlayActivationPaused() { From 61b632516eb73c43918697a9e408b5d75d04ab4d Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 7 Aug 2020 19:43:16 +0900 Subject: [PATCH 030/320] Ensure CurrentTrack is never null --- osu.Game.Tests/Visual/Editing/TimelineTestScene.cs | 3 --- .../Visual/Navigation/TestSceneScreenNavigation.cs | 4 ++-- .../Visual/UserInterface/TestSceneBeatSyncedContainer.cs | 2 +- osu.Game/Overlays/MusicController.cs | 6 ++---- .../Edit/Components/Timelines/Summary/Parts/TimelinePart.cs | 1 - .../Edit/Compose/Components/Timeline/TimelineTickDisplay.cs | 2 +- osu.Game/Screens/Menu/LogoVisualisation.cs | 4 ++-- osu.Game/Screens/Menu/MainMenu.cs | 2 -- osu.Game/Tests/Visual/OsuTestScene.cs | 3 --- osu.Game/Tests/Visual/RateAdjustedBeatmapTestScene.cs | 3 --- 10 files changed, 8 insertions(+), 22 deletions(-) diff --git a/osu.Game.Tests/Visual/Editing/TimelineTestScene.cs b/osu.Game.Tests/Visual/Editing/TimelineTestScene.cs index 4113bdddf8..347b5757c8 100644 --- a/osu.Game.Tests/Visual/Editing/TimelineTestScene.cs +++ b/osu.Game.Tests/Visual/Editing/TimelineTestScene.cs @@ -95,10 +95,7 @@ namespace osu.Game.Tests.Visual.Editing base.Update(); if (musicController.TrackLoaded) - { - Debug.Assert(musicController.CurrentTrack != null); marker.X = (float)(editorClock.CurrentTime / musicController.CurrentTrack.Length); - } } } diff --git a/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs b/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs index 946bc2a175..e5d862cfc7 100644 --- a/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs +++ b/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs @@ -136,8 +136,8 @@ namespace osu.Game.Tests.Visual.Navigation AddUntilStep("Wait for music controller", () => Game.MusicController.IsLoaded); AddStep("Seek close to end", () => { - Game.MusicController.SeekTo(MusicController.CurrentTrack.AsNonNull().Length - 1000); - MusicController.CurrentTrack.AsNonNull().Completed += () => trackCompleted = true; + Game.MusicController.SeekTo(MusicController.CurrentTrack.Length - 1000); + MusicController.CurrentTrack.Completed += () => trackCompleted = true; }); AddUntilStep("Track was completed", () => trackCompleted); diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneBeatSyncedContainer.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneBeatSyncedContainer.cs index ac743d76df..3cccfa992e 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneBeatSyncedContainer.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneBeatSyncedContainer.cs @@ -169,7 +169,7 @@ namespace osu.Game.Tests.Visual.UserInterface if (timingPoints.Count == 0) return 0; if (timingPoints[^1] == current) - return (int)Math.Ceiling((musicController.CurrentTrack.AsNonNull().Length - current.Time) / current.BeatLength); + return (int)Math.Ceiling((musicController.CurrentTrack.Length - current.Time) / current.BeatLength); return (int)Math.Ceiling((getNextTimingPoint(current).Time - current.Time) / current.BeatLength); } diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index 6adfa1817e..7e3bb1ce89 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -5,7 +5,6 @@ using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; -using JetBrains.Annotations; using osu.Framework.Allocation; using osu.Framework.Audio.Track; using osu.Framework.Bindables; @@ -65,8 +64,7 @@ namespace osu.Game.Overlays [Resolved(canBeNull: true)] private OnScreenDisplay onScreenDisplay { get; set; } - [CanBeNull] - public DrawableTrack CurrentTrack { get; private set; } + public DrawableTrack CurrentTrack { get; private set; } = new DrawableTrack(new TrackVirtual(1000)); private IBindable> managerUpdated; private IBindable> managerRemoved; @@ -312,7 +310,7 @@ namespace osu.Game.Overlays current = beatmap.NewValue; - if (!beatmap.OldValue.BeatmapInfo.AudioEquals(current?.BeatmapInfo)) + if (CurrentTrack == null || !beatmap.OldValue.BeatmapInfo.AudioEquals(current?.BeatmapInfo)) changeTrack(); TrackChanged?.Invoke(current, direction); diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs index 24fb855009..7085c8b020 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs @@ -58,7 +58,6 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts return; } - Debug.Assert(musicController.CurrentTrack != null); content.RelativeChildSize = new Vector2((float)Math.Max(1, musicController.CurrentTrack.Length), 1); } diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineTickDisplay.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineTickDisplay.cs index ceb0275a13..1ce33f221a 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineTickDisplay.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineTickDisplay.cs @@ -44,7 +44,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline for (var i = 0; i < beatmap.ControlPointInfo.TimingPoints.Count; i++) { var point = beatmap.ControlPointInfo.TimingPoints[i]; - var until = i + 1 < beatmap.ControlPointInfo.TimingPoints.Count ? beatmap.ControlPointInfo.TimingPoints[i + 1].Time : musicController.CurrentTrack.AsNonNull().Length; + var until = i + 1 < beatmap.ControlPointInfo.TimingPoints.Count ? beatmap.ControlPointInfo.TimingPoints[i + 1].Time : musicController.CurrentTrack.Length; int beat = 0; diff --git a/osu.Game/Screens/Menu/LogoVisualisation.cs b/osu.Game/Screens/Menu/LogoVisualisation.cs index 7a1ff4fa06..974b704200 100644 --- a/osu.Game/Screens/Menu/LogoVisualisation.cs +++ b/osu.Game/Screens/Menu/LogoVisualisation.cs @@ -109,14 +109,14 @@ namespace osu.Game.Screens.Menu private void updateAmplitudes() { var effect = beatmap.Value.BeatmapLoaded && musicController.TrackLoaded - ? beatmap.Value.Beatmap?.ControlPointInfo.EffectPointAt(musicController.CurrentTrack.AsNonNull().CurrentTime) + ? beatmap.Value.Beatmap?.ControlPointInfo.EffectPointAt(musicController.CurrentTrack.CurrentTime) : null; for (int i = 0; i < temporalAmplitudes.Length; i++) temporalAmplitudes[i] = 0; if (musicController.TrackLoaded) - addAmplitudesFromSource(musicController.CurrentTrack.AsNonNull()); + addAmplitudesFromSource(musicController.CurrentTrack); foreach (var source in amplitudeSources) addAmplitudesFromSource(source); diff --git a/osu.Game/Screens/Menu/MainMenu.cs b/osu.Game/Screens/Menu/MainMenu.cs index ea4347a285..518277bce3 100644 --- a/osu.Game/Screens/Menu/MainMenu.cs +++ b/osu.Game/Screens/Menu/MainMenu.cs @@ -179,8 +179,6 @@ namespace osu.Game.Screens.Menu if (last is IntroScreen && music.TrackLoaded) { - Debug.Assert(music.CurrentTrack != null); - if (!music.CurrentTrack.IsRunning) { music.CurrentTrack.Seek(metadata.PreviewTime != -1 ? metadata.PreviewTime : 0.4f * music.CurrentTrack.Length); diff --git a/osu.Game/Tests/Visual/OsuTestScene.cs b/osu.Game/Tests/Visual/OsuTestScene.cs index f2b9388fdc..af7579aafb 100644 --- a/osu.Game/Tests/Visual/OsuTestScene.cs +++ b/osu.Game/Tests/Visual/OsuTestScene.cs @@ -170,10 +170,7 @@ namespace osu.Game.Tests.Visual rulesetDependencies?.Dispose(); if (MusicController?.TrackLoaded == true) - { - Debug.Assert(MusicController.CurrentTrack != null); MusicController.CurrentTrack.Stop(); - } if (contextFactory.IsValueCreated) contextFactory.Value.ResetDatabase(); diff --git a/osu.Game/Tests/Visual/RateAdjustedBeatmapTestScene.cs b/osu.Game/Tests/Visual/RateAdjustedBeatmapTestScene.cs index 54458716b1..027259d4f0 100644 --- a/osu.Game/Tests/Visual/RateAdjustedBeatmapTestScene.cs +++ b/osu.Game/Tests/Visual/RateAdjustedBeatmapTestScene.cs @@ -16,10 +16,7 @@ namespace osu.Game.Tests.Visual // note that this will override any mod rate application if (MusicController.TrackLoaded) - { - Debug.Assert(MusicController.CurrentTrack != null); MusicController.CurrentTrack.Tempo.Value = Clock.Rate; - } } } } From 5002d69f6973ab9753997dd28255c90a90de270a Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 7 Aug 2020 20:51:56 +0900 Subject: [PATCH 031/320] Update inspections --- .../TestSceneHoldNoteInput.cs | 2 +- .../TestSceneOutOfOrderHits.cs | 2 +- .../TestSceneSliderInput.cs | 2 +- .../Skins/TestSceneBeatmapSkinResources.cs | 2 +- .../Visual/Editing/TimelineTestScene.cs | 1 - .../Visual/Gameplay/TestScenePause.cs | 2 +- .../Visual/Gameplay/TestScenePlayerLoader.cs | 4 +-- .../Visual/Gameplay/TestSceneStoryboard.cs | 4 +-- .../Visual/Menus/TestSceneIntroWelcome.cs | 2 +- .../Navigation/TestSceneScreenNavigation.cs | 9 +++--- .../TestSceneBeatSyncedContainer.cs | 1 - .../TestSceneNowPlayingOverlay.cs | 4 +-- osu.Game/Audio/PreviewTrackManager.cs | 2 +- osu.Game/Overlays/Music/PlaylistOverlay.cs | 6 ++-- osu.Game/Overlays/MusicController.cs | 31 +++++++------------ .../Edit/Components/PlaybackControl.cs | 4 +-- .../Timelines/Summary/Parts/TimelinePart.cs | 1 - .../Timeline/TimelineTickDisplay.cs | 1 - osu.Game/Screens/Edit/Editor.cs | 2 +- osu.Game/Screens/Menu/LogoVisualisation.cs | 1 - osu.Game/Screens/Menu/MainMenu.cs | 1 - osu.Game/Screens/Menu/OsuLogo.cs | 2 +- .../Multi/Match/Components/ReadyButton.cs | 2 +- osu.Game/Screens/Multi/Multiplayer.cs | 16 +++------- osu.Game/Tests/Visual/OsuTestScene.cs | 1 - .../Visual/RateAdjustedBeatmapTestScene.cs | 2 -- 26 files changed, 42 insertions(+), 65 deletions(-) diff --git a/osu.Game.Rulesets.Mania.Tests/TestSceneHoldNoteInput.cs b/osu.Game.Rulesets.Mania.Tests/TestSceneHoldNoteInput.cs index 98669efb10..19b69bac6d 100644 --- a/osu.Game.Rulesets.Mania.Tests/TestSceneHoldNoteInput.cs +++ b/osu.Game.Rulesets.Mania.Tests/TestSceneHoldNoteInput.cs @@ -343,7 +343,7 @@ namespace osu.Game.Rulesets.Mania.Tests judgementResults = new List(); }); - AddUntilStep("Beatmap at 0", () => MusicController.CurrentTrack?.CurrentTime == 0); + AddUntilStep("Beatmap at 0", () => MusicController.CurrentTrack.CurrentTime == 0); AddUntilStep("Wait until player is loaded", () => currentPlayer.IsCurrentScreen()); AddUntilStep("Wait for completion", () => currentPlayer.ScoreProcessor.HasCompleted.Value); } diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneOutOfOrderHits.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneOutOfOrderHits.cs index e5be778527..744ad46c28 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneOutOfOrderHits.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneOutOfOrderHits.cs @@ -385,7 +385,7 @@ namespace osu.Game.Rulesets.Osu.Tests judgementResults = new List(); }); - AddUntilStep("Beatmap at 0", () => MusicController.CurrentTrack?.CurrentTime == 0); + AddUntilStep("Beatmap at 0", () => MusicController.CurrentTrack.CurrentTime == 0); AddUntilStep("Wait until player is loaded", () => currentPlayer.IsCurrentScreen()); AddUntilStep("Wait for completion", () => currentPlayer.ScoreProcessor.HasCompleted.Value); } diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs index c9d13d3976..1690f648f9 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs @@ -366,7 +366,7 @@ namespace osu.Game.Rulesets.Osu.Tests judgementResults = new List(); }); - AddUntilStep("Beatmap at 0", () => MusicController.CurrentTrack?.CurrentTime == 0); + AddUntilStep("Beatmap at 0", () => MusicController.CurrentTrack.CurrentTime == 0); AddUntilStep("Wait until player is loaded", () => currentPlayer.IsCurrentScreen()); AddUntilStep("Wait for completion", () => currentPlayer.ScoreProcessor.HasCompleted.Value); } diff --git a/osu.Game.Tests/Skins/TestSceneBeatmapSkinResources.cs b/osu.Game.Tests/Skins/TestSceneBeatmapSkinResources.cs index 08a4e27ff7..2866692be4 100644 --- a/osu.Game.Tests/Skins/TestSceneBeatmapSkinResources.cs +++ b/osu.Game.Tests/Skins/TestSceneBeatmapSkinResources.cs @@ -31,6 +31,6 @@ namespace osu.Game.Tests.Skins public void TestRetrieveOggSample() => AddAssert("sample is non-null", () => beatmap.Skin.GetSample(new SampleInfo("sample")) != null); [Test] - public void TestRetrieveOggTrack() => AddAssert("track is non-null", () => MusicController.CurrentTrack?.IsDummyDevice == false); + public void TestRetrieveOggTrack() => AddAssert("track is non-null", () => MusicController.CurrentTrack.IsDummyDevice == false); } } diff --git a/osu.Game.Tests/Visual/Editing/TimelineTestScene.cs b/osu.Game.Tests/Visual/Editing/TimelineTestScene.cs index 347b5757c8..4988a09650 100644 --- a/osu.Game.Tests/Visual/Editing/TimelineTestScene.cs +++ b/osu.Game.Tests/Visual/Editing/TimelineTestScene.cs @@ -1,7 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System.Diagnostics; using osu.Framework.Allocation; using osu.Framework.Audio; using osu.Framework.Graphics; diff --git a/osu.Game.Tests/Visual/Gameplay/TestScenePause.cs b/osu.Game.Tests/Visual/Gameplay/TestScenePause.cs index e500b451f0..e7dd586f4e 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestScenePause.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestScenePause.cs @@ -288,7 +288,7 @@ namespace osu.Game.Tests.Visual.Gameplay private void confirmNoTrackAdjustments() { - AddAssert("track has no adjustments", () => MusicController.CurrentTrack?.AggregateFrequency.Value == 1); + AddAssert("track has no adjustments", () => MusicController.CurrentTrack.AggregateFrequency.Value == 1); } private void restart() => AddStep("restart", () => Player.Restart()); diff --git a/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs b/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs index c72ab7d3d1..c4882046de 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs @@ -77,12 +77,12 @@ namespace osu.Game.Tests.Visual.Gameplay { AddStep("load dummy beatmap", () => ResetPlayer(false, () => SelectedMods.Value = new[] { new OsuModNightcore() })); AddUntilStep("wait for current", () => loader.IsCurrentScreen()); - AddAssert("mod rate applied", () => MusicController.CurrentTrack?.Rate != 1); + AddAssert("mod rate applied", () => MusicController.CurrentTrack.Rate != 1); AddStep("exit loader", () => loader.Exit()); AddUntilStep("wait for not current", () => !loader.IsCurrentScreen()); AddAssert("player did not load", () => !player.IsLoaded); AddUntilStep("player disposed", () => loader.DisposalTask?.IsCompleted == true); - AddAssert("mod rate still applied", () => MusicController.CurrentTrack?.Rate != 1); + AddAssert("mod rate still applied", () => MusicController.CurrentTrack.Rate != 1); } [Test] diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboard.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboard.cs index c7a012a03f..3d2dd8a0c5 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboard.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboard.cs @@ -87,9 +87,9 @@ namespace osu.Game.Tests.Visual.Gameplay private void restart() { - MusicController.CurrentTrack?.Reset(); + MusicController.CurrentTrack.Reset(); loadStoryboard(Beatmap.Value); - MusicController.CurrentTrack?.Start(); + MusicController.CurrentTrack.Start(); } private void loadStoryboard(WorkingBeatmap working) diff --git a/osu.Game.Tests/Visual/Menus/TestSceneIntroWelcome.cs b/osu.Game.Tests/Visual/Menus/TestSceneIntroWelcome.cs index a88704c831..29be250b12 100644 --- a/osu.Game.Tests/Visual/Menus/TestSceneIntroWelcome.cs +++ b/osu.Game.Tests/Visual/Menus/TestSceneIntroWelcome.cs @@ -16,7 +16,7 @@ namespace osu.Game.Tests.Visual.Menus { AddUntilStep("wait for load", () => MusicController.TrackLoaded); - AddAssert("check if menu music loops", () => MusicController.CurrentTrack?.Looping == true); + AddAssert("check if menu music loops", () => MusicController.CurrentTrack.Looping); } } } diff --git a/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs b/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs index e5d862cfc7..d2c71c1d17 100644 --- a/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs +++ b/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs @@ -4,7 +4,6 @@ using System.Linq; using NUnit.Framework; using osu.Framework.Allocation; -using osu.Framework.Extensions.ObjectExtensions; using osu.Framework.Graphics.Containers; using osu.Framework.Screens; using osu.Game.Beatmaps; @@ -62,12 +61,12 @@ namespace osu.Game.Tests.Visual.Navigation AddUntilStep("wait for fail", () => player.HasFailed); AddUntilStep("wait for track stop", () => !MusicController.IsPlaying); - AddAssert("Ensure time before preview point", () => MusicController.CurrentTrack?.CurrentTime < beatmap().Metadata.PreviewTime); + AddAssert("Ensure time before preview point", () => MusicController.CurrentTrack.CurrentTime < beatmap().Metadata.PreviewTime); pushEscape(); AddUntilStep("wait for track playing", () => MusicController.IsPlaying); - AddAssert("Ensure time wasn't reset to preview point", () => MusicController.CurrentTrack?.CurrentTime < beatmap().Metadata.PreviewTime); + AddAssert("Ensure time wasn't reset to preview point", () => MusicController.CurrentTrack.CurrentTime < beatmap().Metadata.PreviewTime); } [Test] @@ -77,11 +76,11 @@ namespace osu.Game.Tests.Visual.Navigation PushAndConfirm(() => songSelect = new TestSongSelect()); - AddUntilStep("wait for no track", () => MusicController.CurrentTrack?.IsDummyDevice == true); + AddUntilStep("wait for no track", () => MusicController.CurrentTrack.IsDummyDevice); AddStep("return to menu", () => songSelect.Exit()); - AddUntilStep("wait for track", () => MusicController.CurrentTrack?.IsDummyDevice == false && MusicController.IsPlaying); + AddUntilStep("wait for track", () => MusicController.CurrentTrack.IsDummyDevice == false && MusicController.IsPlaying); } [Test] diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneBeatSyncedContainer.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneBeatSyncedContainer.cs index 3cccfa992e..127915c6c6 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneBeatSyncedContainer.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneBeatSyncedContainer.cs @@ -8,7 +8,6 @@ using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Audio.Track; using osu.Framework.Extensions.Color4Extensions; -using osu.Framework.Extensions.ObjectExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneNowPlayingOverlay.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneNowPlayingOverlay.cs index 0161ec0c56..cadecbbef0 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneNowPlayingOverlay.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneNowPlayingOverlay.cs @@ -80,12 +80,12 @@ namespace osu.Game.Tests.Visual.UserInterface AddStep("Store track", () => currentBeatmap = Beatmap.Value); AddStep(@"Seek track to 6 second", () => musicController.SeekTo(6000)); - AddUntilStep(@"Wait for current time to update", () => musicController.CurrentTrack?.CurrentTime > 5000); + AddUntilStep(@"Wait for current time to update", () => musicController.CurrentTrack.CurrentTime > 5000); AddStep(@"Set previous", () => musicController.PreviousTrack()); AddAssert(@"Check beatmap didn't change", () => currentBeatmap == Beatmap.Value); - AddUntilStep("Wait for current time to update", () => musicController.CurrentTrack?.CurrentTime < 5000); + AddUntilStep("Wait for current time to update", () => musicController.CurrentTrack.CurrentTime < 5000); AddStep(@"Set previous", () => musicController.PreviousTrack()); AddAssert(@"Check beatmap did change", () => currentBeatmap != Beatmap.Value); diff --git a/osu.Game/Audio/PreviewTrackManager.cs b/osu.Game/Audio/PreviewTrackManager.cs index 862be41c1a..1c68ce71d4 100644 --- a/osu.Game/Audio/PreviewTrackManager.cs +++ b/osu.Game/Audio/PreviewTrackManager.cs @@ -48,7 +48,7 @@ namespace osu.Game.Audio track.Started += () => Schedule(() => { - CurrentTrack?.Stop(); + CurrentTrack.Stop(); CurrentTrack = track; audio.Tracks.AddAdjustment(AdjustableProperty.Volume, muteBindable); }); diff --git a/osu.Game/Overlays/Music/PlaylistOverlay.cs b/osu.Game/Overlays/Music/PlaylistOverlay.cs index b9a58c37cb..7471e31923 100644 --- a/osu.Game/Overlays/Music/PlaylistOverlay.cs +++ b/osu.Game/Overlays/Music/PlaylistOverlay.cs @@ -85,7 +85,7 @@ namespace osu.Game.Overlays.Music if (toSelect != null) { beatmap.Value = beatmaps.GetWorkingBeatmap(toSelect); - musicController.CurrentTrack?.Restart(); + musicController.CurrentTrack.Restart(); } }; } @@ -119,12 +119,12 @@ namespace osu.Game.Overlays.Music { if (set.ID == (beatmap.Value?.BeatmapSetInfo?.ID ?? -1)) { - musicController.CurrentTrack?.Seek(0); + musicController.CurrentTrack.Seek(0); return; } beatmap.Value = beatmaps.GetWorkingBeatmap(set.Beatmaps.First()); - musicController.CurrentTrack?.Restart(); + musicController.CurrentTrack.Restart(); } } diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index 7e3bb1ce89..3e93ae2ccd 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -3,8 +3,8 @@ using System; using System.Collections.Generic; -using System.Diagnostics; using System.Linq; +using JetBrains.Annotations; using osu.Framework.Allocation; using osu.Framework.Audio.Track; using osu.Framework.Bindables; @@ -64,6 +64,7 @@ namespace osu.Game.Overlays [Resolved(canBeNull: true)] private OnScreenDisplay onScreenDisplay { get; set; } + [NotNull] public DrawableTrack CurrentTrack { get; private set; } = new DrawableTrack(new TrackVirtual(1000)); private IBindable> managerUpdated; @@ -102,12 +103,12 @@ namespace osu.Game.Overlays /// /// Returns whether the beatmap track is playing. /// - public bool IsPlaying => CurrentTrack?.IsRunning ?? false; + public bool IsPlaying => CurrentTrack.IsRunning; /// /// Returns whether the beatmap track is loaded. /// - public bool TrackLoaded => CurrentTrack?.IsLoaded == true; + public bool TrackLoaded => CurrentTrack.IsLoaded; private void beatmapUpdated(ValueChangedEvent> weakSet) { @@ -140,7 +141,7 @@ namespace osu.Game.Overlays seekDelegate = Schedule(() => { if (!beatmap.Disabled) - CurrentTrack?.Seek(position); + CurrentTrack.Seek(position); }); } @@ -152,7 +153,7 @@ namespace osu.Game.Overlays { if (IsUserPaused) return; - if (CurrentTrack == null || CurrentTrack.IsDummyDevice) + if (CurrentTrack.IsDummyDevice) { if (beatmap.Disabled) return; @@ -173,9 +174,6 @@ namespace osu.Game.Overlays { IsUserPaused = false; - if (CurrentTrack == null) - return false; - if (restart) CurrentTrack.Restart(); else if (!IsPlaying) @@ -190,7 +188,7 @@ namespace osu.Game.Overlays public void Stop() { IsUserPaused = true; - if (CurrentTrack?.IsRunning == true) + if (CurrentTrack.IsRunning) CurrentTrack.Stop(); } @@ -200,7 +198,7 @@ namespace osu.Game.Overlays /// Whether the operation was successful. public bool TogglePause() { - if (CurrentTrack?.IsRunning == true) + if (CurrentTrack.IsRunning) Stop(); else Play(); @@ -222,7 +220,7 @@ namespace osu.Game.Overlays if (beatmap.Disabled) return PreviousTrackResult.None; - var currentTrackPosition = CurrentTrack?.CurrentTime; + var currentTrackPosition = CurrentTrack.CurrentTime; if (currentTrackPosition >= restart_cutoff_point) { @@ -276,7 +274,7 @@ namespace osu.Game.Overlays { // if not scheduled, the previously track will be stopped one frame later (see ScheduleAfterChildren logic in GameBase). // we probably want to move this to a central method for switching to a new working beatmap in the future. - Schedule(() => CurrentTrack?.Restart()); + Schedule(() => CurrentTrack.Restart()); } private WorkingBeatmap current; @@ -310,7 +308,7 @@ namespace osu.Game.Overlays current = beatmap.NewValue; - if (CurrentTrack == null || !beatmap.OldValue.BeatmapInfo.AudioEquals(current?.BeatmapInfo)) + if (CurrentTrack.IsDummyDevice || !beatmap.OldValue.BeatmapInfo.AudioEquals(current?.BeatmapInfo)) changeTrack(); TrackChanged?.Invoke(current, direction); @@ -322,7 +320,7 @@ namespace osu.Game.Overlays private void changeTrack() { - CurrentTrack?.Expire(); + CurrentTrack.Expire(); CurrentTrack = null; if (current != null) @@ -340,8 +338,6 @@ namespace osu.Game.Overlays if (current != workingBeatmap) return; - Debug.Assert(CurrentTrack != null); - if (!CurrentTrack.Looping && !beatmap.Disabled) NextTrack(); } @@ -366,9 +362,6 @@ namespace osu.Game.Overlays public void ResetTrackAdjustments() { - if (CurrentTrack == null) - return; - CurrentTrack.ResetSpeedAdjustments(); if (allowRateAdjustments) diff --git a/osu.Game/Screens/Edit/Components/PlaybackControl.cs b/osu.Game/Screens/Edit/Components/PlaybackControl.cs index 412efe266c..5bafc120af 100644 --- a/osu.Game/Screens/Edit/Components/PlaybackControl.cs +++ b/osu.Game/Screens/Edit/Components/PlaybackControl.cs @@ -66,12 +66,12 @@ namespace osu.Game.Screens.Edit.Components } }; - musicController.CurrentTrack?.AddAdjustment(AdjustableProperty.Tempo, tempo); + musicController.CurrentTrack.AddAdjustment(AdjustableProperty.Tempo, tempo); } protected override void Dispose(bool isDisposing) { - musicController?.CurrentTrack?.RemoveAdjustment(AdjustableProperty.Tempo, tempo); + musicController?.CurrentTrack.RemoveAdjustment(AdjustableProperty.Tempo, tempo); base.Dispose(isDisposing); } diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs index 7085c8b020..c8a470c58a 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs @@ -2,7 +2,6 @@ // See the LICENCE file in the repository root for full licence text. using System; -using System.Diagnostics; using osu.Framework.Allocation; using osu.Framework.Bindables; using osuTK; diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineTickDisplay.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineTickDisplay.cs index 1ce33f221a..cb122c590e 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineTickDisplay.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineTickDisplay.cs @@ -3,7 +3,6 @@ using System.Linq; using osu.Framework.Allocation; -using osu.Framework.Extensions.ObjectExtensions; using osu.Framework.Graphics; using osu.Game.Graphics; using osu.Game.Overlays; diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index 79b13a7eac..9f2009b415 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -84,7 +84,7 @@ namespace osu.Game.Screens.Edit // Todo: should probably be done at a DrawableRuleset level to share logic with Player. var sourceClock = (IAdjustableClock)musicController.CurrentTrack ?? new StopwatchClock(); - clock = new EditorClock(Beatmap.Value, musicController.CurrentTrack?.Length ?? 0, beatDivisor) { IsCoupled = false }; + clock = new EditorClock(Beatmap.Value, musicController.CurrentTrack.Length, beatDivisor) { IsCoupled = false }; clock.ChangeSource(sourceClock); dependencies.CacheAs(clock); diff --git a/osu.Game/Screens/Menu/LogoVisualisation.cs b/osu.Game/Screens/Menu/LogoVisualisation.cs index 974b704200..4d95ee9b7b 100644 --- a/osu.Game/Screens/Menu/LogoVisualisation.cs +++ b/osu.Game/Screens/Menu/LogoVisualisation.cs @@ -19,7 +19,6 @@ using osu.Framework.Allocation; using osu.Framework.Audio; using osu.Framework.Audio.Track; using osu.Framework.Bindables; -using osu.Framework.Extensions.ObjectExtensions; using osu.Framework.Utils; using osu.Game.Overlays; diff --git a/osu.Game/Screens/Menu/MainMenu.cs b/osu.Game/Screens/Menu/MainMenu.cs index 518277bce3..8837a49772 100644 --- a/osu.Game/Screens/Menu/MainMenu.cs +++ b/osu.Game/Screens/Menu/MainMenu.cs @@ -1,7 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System.Diagnostics; using System.Linq; using osuTK; using osuTK.Graphics; diff --git a/osu.Game/Screens/Menu/OsuLogo.cs b/osu.Game/Screens/Menu/OsuLogo.cs index f028f9b229..4515ee8ed0 100644 --- a/osu.Game/Screens/Menu/OsuLogo.cs +++ b/osu.Game/Screens/Menu/OsuLogo.cs @@ -330,7 +330,7 @@ namespace osu.Game.Screens.Menu const float velocity_adjust_cutoff = 0.98f; const float paused_velocity = 0.5f; - if (musicController.CurrentTrack?.IsRunning == true) + if (musicController.CurrentTrack.IsRunning) { var maxAmplitude = lastBeatIndex >= 0 ? musicController.CurrentTrack.CurrentAmplitudes.Maximum : 0; logoAmplitudeContainer.Scale = new Vector2((float)Interpolation.Damp(logoAmplitudeContainer.Scale.X, 1 - Math.Max(0, maxAmplitude - scale_adjust_cutoff) * 0.04f, 0.9f, Time.Elapsed)); diff --git a/osu.Game/Screens/Multi/Match/Components/ReadyButton.cs b/osu.Game/Screens/Multi/Match/Components/ReadyButton.cs index c7dc20ff23..384d3bd5a5 100644 --- a/osu.Game/Screens/Multi/Match/Components/ReadyButton.cs +++ b/osu.Game/Screens/Multi/Match/Components/ReadyButton.cs @@ -104,7 +104,7 @@ namespace osu.Game.Screens.Multi.Match.Components return; } - bool hasEnoughTime = musicController.CurrentTrack != null && DateTimeOffset.UtcNow.AddSeconds(30).AddMilliseconds(musicController.CurrentTrack.Length) < endDate.Value; + bool hasEnoughTime = DateTimeOffset.UtcNow.AddSeconds(30).AddMilliseconds(musicController.CurrentTrack.Length) < endDate.Value; Enabled.Value = hasBeatmap && hasEnoughTime; } diff --git a/osu.Game/Screens/Multi/Multiplayer.cs b/osu.Game/Screens/Multi/Multiplayer.cs index e068899c7b..1a39d80f8d 100644 --- a/osu.Game/Screens/Multi/Multiplayer.cs +++ b/osu.Game/Screens/Multi/Multiplayer.cs @@ -343,13 +343,10 @@ namespace osu.Game.Screens.Multi { if (screenStack.CurrentScreen is MatchSubScreen) { - if (musicController.CurrentTrack != null) - { - musicController.CurrentTrack.RestartPoint = Beatmap.Value.Metadata.PreviewTime; - musicController.CurrentTrack.Looping = true; + musicController.CurrentTrack.RestartPoint = Beatmap.Value.Metadata.PreviewTime; + musicController.CurrentTrack.Looping = true; - musicController.EnsurePlayingSomething(); - } + musicController.EnsurePlayingSomething(); } else { @@ -359,11 +356,8 @@ namespace osu.Game.Screens.Multi private void cancelLooping() { - if (musicController.CurrentTrack != null) - { - musicController.CurrentTrack.Looping = false; - musicController.CurrentTrack.RestartPoint = 0; - } + musicController.CurrentTrack.Looping = false; + musicController.CurrentTrack.RestartPoint = 0; } protected override void Dispose(bool isDisposing) diff --git a/osu.Game/Tests/Visual/OsuTestScene.cs b/osu.Game/Tests/Visual/OsuTestScene.cs index af7579aafb..b0d15bf442 100644 --- a/osu.Game/Tests/Visual/OsuTestScene.cs +++ b/osu.Game/Tests/Visual/OsuTestScene.cs @@ -3,7 +3,6 @@ using System; using System.Collections.Generic; -using System.Diagnostics; using System.IO; using System.Linq; using System.Threading.Tasks; diff --git a/osu.Game/Tests/Visual/RateAdjustedBeatmapTestScene.cs b/osu.Game/Tests/Visual/RateAdjustedBeatmapTestScene.cs index 027259d4f0..7651285970 100644 --- a/osu.Game/Tests/Visual/RateAdjustedBeatmapTestScene.cs +++ b/osu.Game/Tests/Visual/RateAdjustedBeatmapTestScene.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System.Diagnostics; - namespace osu.Game.Tests.Visual { /// From 028040344a9c2bfcc1cd25d3efad2e8dcf651207 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 7 Aug 2020 21:07:59 +0900 Subject: [PATCH 032/320] Fix test scene using local beatmap --- osu.Game.Tests/Skins/TestSceneBeatmapSkinResources.cs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/osu.Game.Tests/Skins/TestSceneBeatmapSkinResources.cs b/osu.Game.Tests/Skins/TestSceneBeatmapSkinResources.cs index 2866692be4..03faee9ad2 100644 --- a/osu.Game.Tests/Skins/TestSceneBeatmapSkinResources.cs +++ b/osu.Game.Tests/Skins/TestSceneBeatmapSkinResources.cs @@ -18,17 +18,15 @@ namespace osu.Game.Tests.Skins [Resolved] private BeatmapManager beatmaps { get; set; } - private WorkingBeatmap beatmap; - [BackgroundDependencyLoader] private void load() { var imported = beatmaps.Import(new ZipArchiveReader(TestResources.OpenResource("Archives/ogg-beatmap.osz"))).Result; - beatmap = beatmaps.GetWorkingBeatmap(imported.Beatmaps[0]); + Beatmap.Value = beatmaps.GetWorkingBeatmap(imported.Beatmaps[0]); } [Test] - public void TestRetrieveOggSample() => AddAssert("sample is non-null", () => beatmap.Skin.GetSample(new SampleInfo("sample")) != null); + public void TestRetrieveOggSample() => AddAssert("sample is non-null", () => Beatmap.Value.Skin.GetSample(new SampleInfo("sample")) != null); [Test] public void TestRetrieveOggTrack() => AddAssert("track is non-null", () => MusicController.CurrentTrack.IsDummyDevice == false); From 961c6dab541c379e30cd4afe837f5bbfb265096b Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 7 Aug 2020 21:08:03 +0900 Subject: [PATCH 033/320] Fix more inspections --- osu.Game/Screens/Edit/Editor.cs | 2 +- osu.Game/Tests/Visual/EditorClockTestScene.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index 9f2009b415..1a7d76ba8f 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -83,7 +83,7 @@ namespace osu.Game.Screens.Edit beatDivisor.BindValueChanged(divisor => Beatmap.Value.BeatmapInfo.BeatDivisor = divisor.NewValue); // Todo: should probably be done at a DrawableRuleset level to share logic with Player. - var sourceClock = (IAdjustableClock)musicController.CurrentTrack ?? new StopwatchClock(); + var sourceClock = (IAdjustableClock)musicController.CurrentTrack; clock = new EditorClock(Beatmap.Value, musicController.CurrentTrack.Length, beatDivisor) { IsCoupled = false }; clock.ChangeSource(sourceClock); diff --git a/osu.Game/Tests/Visual/EditorClockTestScene.cs b/osu.Game/Tests/Visual/EditorClockTestScene.cs index 780b4f1b3a..1009151ac4 100644 --- a/osu.Game/Tests/Visual/EditorClockTestScene.cs +++ b/osu.Game/Tests/Visual/EditorClockTestScene.cs @@ -44,7 +44,7 @@ namespace osu.Game.Tests.Visual private void beatmapChanged(ValueChangedEvent e) { Clock.ControlPointInfo = e.NewValue.Beatmap.ControlPointInfo; - Clock.ChangeSource((IAdjustableClock)MusicController.CurrentTrack ?? new StopwatchClock()); + Clock.ChangeSource((IAdjustableClock)MusicController.CurrentTrack); Clock.ProcessFrame(); } From b08ebe6f81f9d596920ba602e04a1df9cb90798a Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 7 Aug 2020 21:14:45 +0900 Subject: [PATCH 034/320] More inspections (rider is broken) --- osu.Game/Screens/Edit/Editor.cs | 4 +--- osu.Game/Tests/Visual/EditorClockTestScene.cs | 3 +-- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index 1a7d76ba8f..78fa6c74b0 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -14,7 +14,6 @@ using osu.Framework.Bindables; using osu.Framework.Graphics.UserInterface; using osu.Framework.Input.Events; using osu.Framework.Platform; -using osu.Framework.Timing; using osu.Game.Graphics.UserInterface; using osu.Game.Screens.Edit.Components; using osu.Game.Screens.Edit.Components.Menus; @@ -83,9 +82,8 @@ namespace osu.Game.Screens.Edit beatDivisor.BindValueChanged(divisor => Beatmap.Value.BeatmapInfo.BeatDivisor = divisor.NewValue); // Todo: should probably be done at a DrawableRuleset level to share logic with Player. - var sourceClock = (IAdjustableClock)musicController.CurrentTrack; clock = new EditorClock(Beatmap.Value, musicController.CurrentTrack.Length, beatDivisor) { IsCoupled = false }; - clock.ChangeSource(sourceClock); + clock.ChangeSource(musicController.CurrentTrack); dependencies.CacheAs(clock); AddInternal(clock); diff --git a/osu.Game/Tests/Visual/EditorClockTestScene.cs b/osu.Game/Tests/Visual/EditorClockTestScene.cs index 1009151ac4..59c9329d37 100644 --- a/osu.Game/Tests/Visual/EditorClockTestScene.cs +++ b/osu.Game/Tests/Visual/EditorClockTestScene.cs @@ -4,7 +4,6 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Input.Events; -using osu.Framework.Timing; using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Screens.Edit; @@ -44,7 +43,7 @@ namespace osu.Game.Tests.Visual private void beatmapChanged(ValueChangedEvent e) { Clock.ControlPointInfo = e.NewValue.Beatmap.ControlPointInfo; - Clock.ChangeSource((IAdjustableClock)MusicController.CurrentTrack); + Clock.ChangeSource(MusicController.CurrentTrack); Clock.ProcessFrame(); } From 08820c62ec6ab6121b60c59ad8e89f3dfbcef3f5 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 7 Aug 2020 21:36:02 +0900 Subject: [PATCH 035/320] Add back removed nullcheck --- osu.Game/Audio/PreviewTrackManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Audio/PreviewTrackManager.cs b/osu.Game/Audio/PreviewTrackManager.cs index 1c68ce71d4..862be41c1a 100644 --- a/osu.Game/Audio/PreviewTrackManager.cs +++ b/osu.Game/Audio/PreviewTrackManager.cs @@ -48,7 +48,7 @@ namespace osu.Game.Audio track.Started += () => Schedule(() => { - CurrentTrack.Stop(); + CurrentTrack?.Stop(); CurrentTrack = track; audio.Tracks.AddAdjustment(AdjustableProperty.Volume, muteBindable); }); From b6fb7a0d39e6a5667be3fa45d90a3f2a5072d5ed Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 7 Aug 2020 22:05:58 +0900 Subject: [PATCH 036/320] Fix possibly setting null track --- .../Visual/Online/TestSceneNowPlayingCommand.cs | 2 +- osu.Game/Beatmaps/DummyWorkingBeatmap.cs | 3 ++- osu.Game/Overlays/MusicController.cs | 8 +++----- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneNowPlayingCommand.cs b/osu.Game.Tests/Visual/Online/TestSceneNowPlayingCommand.cs index 103308d34d..9662bd65b4 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneNowPlayingCommand.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneNowPlayingCommand.cs @@ -59,7 +59,7 @@ namespace osu.Game.Tests.Visual.Online { AddStep("Set activity", () => API.Activity.Value = new UserActivity.InLobby()); - AddStep("Set beatmap", () => Beatmap.Value = new DummyWorkingBeatmap(null, null) + AddStep("Set beatmap", () => Beatmap.Value = new DummyWorkingBeatmap(Audio, null) { BeatmapInfo = { OnlineBeatmapID = hasOnlineId ? 1234 : (int?)null } }); diff --git a/osu.Game/Beatmaps/DummyWorkingBeatmap.cs b/osu.Game/Beatmaps/DummyWorkingBeatmap.cs index 8080e94075..ca801cf745 100644 --- a/osu.Game/Beatmaps/DummyWorkingBeatmap.cs +++ b/osu.Game/Beatmaps/DummyWorkingBeatmap.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using JetBrains.Annotations; using osu.Framework.Audio; using osu.Framework.Audio.Track; using osu.Framework.Extensions.IEnumerableExtensions; @@ -19,7 +20,7 @@ namespace osu.Game.Beatmaps { private readonly TextureStore textures; - public DummyWorkingBeatmap(AudioManager audio, TextureStore textures) + public DummyWorkingBeatmap([NotNull] AudioManager audio, TextureStore textures) : base(new BeatmapInfo { Metadata = new BeatmapMetadata diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index 3e93ae2ccd..2aed46a1d0 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -321,15 +321,13 @@ namespace osu.Game.Overlays private void changeTrack() { CurrentTrack.Expire(); - CurrentTrack = null; + CurrentTrack = new DrawableTrack(new TrackVirtual(1000)); if (current != null) - { CurrentTrack = new DrawableTrack(current.GetRealTrack()); - CurrentTrack.Completed += () => onTrackCompleted(current); - AddInternal(CurrentTrack); - } + CurrentTrack.Completed += () => onTrackCompleted(current); + AddInternal(CurrentTrack); } private void onTrackCompleted(WorkingBeatmap workingBeatmap) From d1765c8a45e3940974c35ec2c75366c14a96a4e1 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 7 Aug 2020 22:06:04 +0900 Subject: [PATCH 037/320] Fix using the wrong music controller instance --- .../Navigation/TestSceneScreenNavigation.cs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs b/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs index d2c71c1d17..0f06010a6a 100644 --- a/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs +++ b/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs @@ -60,13 +60,13 @@ namespace osu.Game.Tests.Visual.Navigation AddUntilStep("wait for player", () => (player = Game.ScreenStack.CurrentScreen as Player) != null); AddUntilStep("wait for fail", () => player.HasFailed); - AddUntilStep("wait for track stop", () => !MusicController.IsPlaying); - AddAssert("Ensure time before preview point", () => MusicController.CurrentTrack.CurrentTime < beatmap().Metadata.PreviewTime); + AddUntilStep("wait for track stop", () => !Game.MusicController.IsPlaying); + AddAssert("Ensure time before preview point", () => Game.MusicController.CurrentTrack.CurrentTime < beatmap().Metadata.PreviewTime); pushEscape(); - AddUntilStep("wait for track playing", () => MusicController.IsPlaying); - AddAssert("Ensure time wasn't reset to preview point", () => MusicController.CurrentTrack.CurrentTime < beatmap().Metadata.PreviewTime); + AddUntilStep("wait for track playing", () => Game.MusicController.IsPlaying); + AddAssert("Ensure time wasn't reset to preview point", () => Game.MusicController.CurrentTrack.CurrentTime < beatmap().Metadata.PreviewTime); } [Test] @@ -76,11 +76,11 @@ namespace osu.Game.Tests.Visual.Navigation PushAndConfirm(() => songSelect = new TestSongSelect()); - AddUntilStep("wait for no track", () => MusicController.CurrentTrack.IsDummyDevice); + AddUntilStep("wait for no track", () => Game.MusicController.CurrentTrack.IsDummyDevice); AddStep("return to menu", () => songSelect.Exit()); - AddUntilStep("wait for track", () => MusicController.CurrentTrack.IsDummyDevice == false && MusicController.IsPlaying); + AddUntilStep("wait for track", () => Game.MusicController.CurrentTrack.IsDummyDevice == false && Game.MusicController.IsPlaying); } [Test] @@ -135,12 +135,12 @@ namespace osu.Game.Tests.Visual.Navigation AddUntilStep("Wait for music controller", () => Game.MusicController.IsLoaded); AddStep("Seek close to end", () => { - Game.MusicController.SeekTo(MusicController.CurrentTrack.Length - 1000); - MusicController.CurrentTrack.Completed += () => trackCompleted = true; + Game.MusicController.SeekTo(Game.MusicController.CurrentTrack.Length - 1000); + Game.MusicController.CurrentTrack.Completed += () => trackCompleted = true; }); AddUntilStep("Track was completed", () => trackCompleted); - AddUntilStep("Track was restarted", () => MusicController.IsPlaying); + AddUntilStep("Track was restarted", () => Game.MusicController.IsPlaying); } private void pushEscape() => From e87f50f74f28ca8d5b5c6a0189b3ec2be21a1360 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 7 Aug 2020 22:31:41 +0900 Subject: [PATCH 038/320] Rename method --- osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs | 2 +- osu.Game.Tests/Gameplay/TestSceneGameplayClockContainer.cs | 2 +- osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs | 2 +- osu.Game.Tests/Visual/Gameplay/TestSceneSkipOverlay.cs | 2 +- osu.Game.Tests/WaveformTestBeatmap.cs | 2 +- osu.Game/Beatmaps/BeatmapManager.cs | 2 +- osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs | 2 +- osu.Game/Beatmaps/DummyWorkingBeatmap.cs | 2 +- osu.Game/Beatmaps/IWorkingBeatmap.cs | 5 +++++ osu.Game/Beatmaps/WorkingBeatmap.cs | 4 ++-- osu.Game/Overlays/MusicController.cs | 2 +- osu.Game/Screens/Edit/LegacyEditorBeatmapPatcher.cs | 2 +- osu.Game/Screens/Menu/IntroScreen.cs | 2 +- osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs | 2 +- osu.Game/Tests/Beatmaps/TestWorkingBeatmap.cs | 2 +- osu.Game/Tests/Visual/OsuTestScene.cs | 2 +- 16 files changed, 21 insertions(+), 16 deletions(-) diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs index 30331e98d2..4a11e1785b 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs @@ -106,7 +106,7 @@ namespace osu.Game.Tests.Beatmaps.Formats protected override Texture GetBackground() => throw new NotImplementedException(); - protected override Track GetTrack() => throw new NotImplementedException(); + protected override Track GetBeatmapTrack() => throw new NotImplementedException(); } } } diff --git a/osu.Game.Tests/Gameplay/TestSceneGameplayClockContainer.cs b/osu.Game.Tests/Gameplay/TestSceneGameplayClockContainer.cs index 40f6cecd9a..bb60ae73db 100644 --- a/osu.Game.Tests/Gameplay/TestSceneGameplayClockContainer.cs +++ b/osu.Game.Tests/Gameplay/TestSceneGameplayClockContainer.cs @@ -22,7 +22,7 @@ namespace osu.Game.Tests.Gameplay AddStep("create container", () => { var working = CreateWorkingBeatmap(new OsuRuleset().RulesetInfo); - Add(gcc = new GameplayClockContainer(working.GetRealTrack(), working, Array.Empty(), 0)); + Add(gcc = new GameplayClockContainer(working.GetTrack(), working, Array.Empty(), 0)); }); AddStep("start track", () => gcc.Start()); diff --git a/osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs b/osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs index 720436fae4..360e7eccdc 100644 --- a/osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs +++ b/osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs @@ -61,7 +61,7 @@ namespace osu.Game.Tests.Gameplay { var working = CreateWorkingBeatmap(new OsuRuleset().RulesetInfo); - Add(gameplayContainer = new GameplayClockContainer(working.GetRealTrack(), working, Array.Empty(), 0)); + Add(gameplayContainer = new GameplayClockContainer(working.GetTrack(), working, Array.Empty(), 0)); gameplayContainer.Add(sample = new DrawableStoryboardSample(new StoryboardSampleInfo(string.Empty, 0, 1)) { diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSkipOverlay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSkipOverlay.cs index 68110d759c..58fd760fc3 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSkipOverlay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSkipOverlay.cs @@ -34,7 +34,7 @@ namespace osu.Game.Tests.Visual.Gameplay var working = CreateWorkingBeatmap(CreateBeatmap(new OsuRuleset().RulesetInfo)); - Child = gameplayClockContainer = new GameplayClockContainer(working.GetRealTrack(), working, Array.Empty(), 0) + Child = gameplayClockContainer = new GameplayClockContainer(working.GetTrack(), working, Array.Empty(), 0) { RelativeSizeAxes = Axes.Both, Children = new Drawable[] diff --git a/osu.Game.Tests/WaveformTestBeatmap.cs b/osu.Game.Tests/WaveformTestBeatmap.cs index 90c91eb007..7dc5ce1d7f 100644 --- a/osu.Game.Tests/WaveformTestBeatmap.cs +++ b/osu.Game.Tests/WaveformTestBeatmap.cs @@ -52,7 +52,7 @@ namespace osu.Game.Tests protected override Waveform GetWaveform() => new Waveform(trackStore.GetStream(firstAudioFile)); - protected override Track GetTrack() => trackStore.Get(firstAudioFile); + protected override Track GetBeatmapTrack() => trackStore.Get(firstAudioFile); private string firstAudioFile { diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index f22f41531a..e001185da9 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -476,7 +476,7 @@ namespace osu.Game.Beatmaps protected override IBeatmap GetBeatmap() => beatmap; protected override Texture GetBackground() => null; - protected override Track GetTrack() => null; + protected override Track GetBeatmapTrack() => null; } } diff --git a/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs b/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs index a54d46c1b1..f1289cd3aa 100644 --- a/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs @@ -70,7 +70,7 @@ namespace osu.Game.Beatmaps } } - protected override Track GetTrack() + protected override Track GetBeatmapTrack() { try { diff --git a/osu.Game/Beatmaps/DummyWorkingBeatmap.cs b/osu.Game/Beatmaps/DummyWorkingBeatmap.cs index ca801cf745..af2a2ac250 100644 --- a/osu.Game/Beatmaps/DummyWorkingBeatmap.cs +++ b/osu.Game/Beatmaps/DummyWorkingBeatmap.cs @@ -45,7 +45,7 @@ namespace osu.Game.Beatmaps protected override Texture GetBackground() => textures?.Get(@"Backgrounds/bg4"); - protected override Track GetTrack() => GetVirtualTrack(); + protected override Track GetBeatmapTrack() => GetVirtualTrack(); private class DummyRulesetInfo : RulesetInfo { diff --git a/osu.Game/Beatmaps/IWorkingBeatmap.cs b/osu.Game/Beatmaps/IWorkingBeatmap.cs index 086b7502a2..e020625b99 100644 --- a/osu.Game/Beatmaps/IWorkingBeatmap.cs +++ b/osu.Game/Beatmaps/IWorkingBeatmap.cs @@ -54,5 +54,10 @@ namespace osu.Game.Beatmaps /// The converted . /// If could not be converted to . IBeatmap GetPlayableBeatmap(RulesetInfo ruleset, IReadOnlyList mods = null, TimeSpan? timeout = null); + + /// + /// Retrieves the which this provides. + /// + Track GetTrack(); } } diff --git a/osu.Game/Beatmaps/WorkingBeatmap.cs b/osu.Game/Beatmaps/WorkingBeatmap.cs index 171201ca68..af6a67ad3f 100644 --- a/osu.Game/Beatmaps/WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/WorkingBeatmap.cs @@ -249,9 +249,9 @@ namespace osu.Game.Beatmaps protected abstract Texture GetBackground(); private readonly RecyclableLazy background; - public Track GetRealTrack() => GetTrack() ?? GetVirtualTrack(1000); + public Track GetTrack() => GetBeatmapTrack() ?? GetVirtualTrack(1000); - protected abstract Track GetTrack(); + protected abstract Track GetBeatmapTrack(); public bool WaveformLoaded => waveform.IsResultAvailable; public Waveform Waveform => waveform.Value; diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index 2aed46a1d0..cf420c3b91 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -324,7 +324,7 @@ namespace osu.Game.Overlays CurrentTrack = new DrawableTrack(new TrackVirtual(1000)); if (current != null) - CurrentTrack = new DrawableTrack(current.GetRealTrack()); + CurrentTrack = new DrawableTrack(current.GetTrack()); CurrentTrack.Completed += () => onTrackCompleted(current); AddInternal(CurrentTrack); diff --git a/osu.Game/Screens/Edit/LegacyEditorBeatmapPatcher.cs b/osu.Game/Screens/Edit/LegacyEditorBeatmapPatcher.cs index fc3dd4c105..57b7ce6940 100644 --- a/osu.Game/Screens/Edit/LegacyEditorBeatmapPatcher.cs +++ b/osu.Game/Screens/Edit/LegacyEditorBeatmapPatcher.cs @@ -107,7 +107,7 @@ namespace osu.Game.Screens.Edit protected override Texture GetBackground() => throw new NotImplementedException(); - protected override Track GetTrack() => throw new NotImplementedException(); + protected override Track GetBeatmapTrack() => throw new NotImplementedException(); } } } diff --git a/osu.Game/Screens/Menu/IntroScreen.cs b/osu.Game/Screens/Menu/IntroScreen.cs index 7e327261ab..6e85abf7dc 100644 --- a/osu.Game/Screens/Menu/IntroScreen.cs +++ b/osu.Game/Screens/Menu/IntroScreen.cs @@ -115,7 +115,7 @@ namespace osu.Game.Screens.Menu if (setInfo != null) { initialBeatmap = beatmaps.GetWorkingBeatmap(setInfo.Beatmaps[0]); - UsingThemedIntro = initialBeatmap.GetRealTrack().IsDummyDevice == false; + UsingThemedIntro = initialBeatmap.GetTrack().IsDummyDevice == false; } return UsingThemedIntro; diff --git a/osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs b/osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs index 6ada632850..e492069c5e 100644 --- a/osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs +++ b/osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs @@ -208,7 +208,7 @@ namespace osu.Game.Tests.Beatmaps protected override Texture GetBackground() => throw new NotImplementedException(); - protected override Track GetTrack() => throw new NotImplementedException(); + protected override Track GetBeatmapTrack() => throw new NotImplementedException(); protected override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap, Ruleset ruleset) { diff --git a/osu.Game/Tests/Beatmaps/TestWorkingBeatmap.cs b/osu.Game/Tests/Beatmaps/TestWorkingBeatmap.cs index ee04142035..d091da3206 100644 --- a/osu.Game/Tests/Beatmaps/TestWorkingBeatmap.cs +++ b/osu.Game/Tests/Beatmaps/TestWorkingBeatmap.cs @@ -35,6 +35,6 @@ namespace osu.Game.Tests.Beatmaps protected override Texture GetBackground() => null; - protected override Track GetTrack() => null; + protected override Track GetBeatmapTrack() => null; } } diff --git a/osu.Game/Tests/Visual/OsuTestScene.cs b/osu.Game/Tests/Visual/OsuTestScene.cs index b0d15bf442..756074c0b3 100644 --- a/osu.Game/Tests/Visual/OsuTestScene.cs +++ b/osu.Game/Tests/Visual/OsuTestScene.cs @@ -223,7 +223,7 @@ namespace osu.Game.Tests.Visual store?.Dispose(); } - protected override Track GetTrack() => track; + protected override Track GetBeatmapTrack() => track; public class TrackVirtualStore : AudioCollectionManager, ITrackStore { From b8373e89b7e30e0370170f10bf16c1d7bb36b835 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 7 Aug 2020 23:05:59 +0900 Subject: [PATCH 039/320] Move beatmap bind to BDL load() --- osu.Game/Overlays/MusicController.cs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index cf420c3b91..26df48171e 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -79,12 +79,9 @@ namespace osu.Game.Overlays managerRemoved.BindValueChanged(beatmapRemoved); beatmapSets.AddRange(beatmaps.GetAllUsableBeatmapSets(IncludedDetails.Minimal, true).OrderBy(_ => RNG.Next())); - } - - protected override void LoadComplete() - { - base.LoadComplete(); + // Todo: These binds really shouldn't be here, but are unlikely to cause any issues for now. + // They are placed here for now since some tests rely on setting the beatmap _and_ their hierarchies inside their load(), which runs before the MusicController's load(). beatmap.BindValueChanged(beatmapChanged, true); mods.BindValueChanged(_ => ResetTrackAdjustments(), true); } From 2351701ade19e518b2d07f308af5237df2e7eedd Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 7 Aug 2020 23:08:51 +0900 Subject: [PATCH 040/320] Fix test not having a long enough track --- .../UserInterface/TestSceneNowPlayingOverlay.cs | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneNowPlayingOverlay.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneNowPlayingOverlay.cs index cadecbbef0..c14a1ddbf2 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneNowPlayingOverlay.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneNowPlayingOverlay.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System.Collections.Generic; +using System.Linq; using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Audio; @@ -11,6 +12,7 @@ using osu.Game.Beatmaps; using osu.Game.Overlays; using osu.Game.Rulesets; using osu.Game.Rulesets.Osu; +using osu.Game.Tests.Resources; namespace osu.Game.Tests.Visual.UserInterface { @@ -20,8 +22,6 @@ namespace osu.Game.Tests.Visual.UserInterface [Cached] private MusicController musicController = new MusicController(); - private WorkingBeatmap currentBeatmap; - private NowPlayingOverlay nowPlayingOverlay; private RulesetStore rulesets; @@ -76,8 +76,13 @@ namespace osu.Game.Tests.Visual.UserInterface } }).Wait(), 5); - AddStep(@"Next track", () => musicController.NextTrack()); - AddStep("Store track", () => currentBeatmap = Beatmap.Value); + WorkingBeatmap currentBeatmap = null; + + AddStep("import beatmap with track", () => + { + var setWithTrack = manager.Import(TestResources.GetTestBeatmapForImport()).Result; + Beatmap.Value = currentBeatmap = manager.GetWorkingBeatmap(setWithTrack.Beatmaps.First()); + }); AddStep(@"Seek track to 6 second", () => musicController.SeekTo(6000)); AddUntilStep(@"Wait for current time to update", () => musicController.CurrentTrack.CurrentTime > 5000); From 87ce1e3558d598388c38cd078840d7148c95f0fd Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Sat, 8 Aug 2020 00:58:04 +0900 Subject: [PATCH 041/320] Remove impossible null case (DummyWorkingBeatmap) --- osu.Game/Overlays/MusicController.cs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index 26df48171e..c5ba82288c 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -318,12 +318,9 @@ namespace osu.Game.Overlays private void changeTrack() { CurrentTrack.Expire(); - CurrentTrack = new DrawableTrack(new TrackVirtual(1000)); - - if (current != null) - CurrentTrack = new DrawableTrack(current.GetTrack()); - + CurrentTrack = new DrawableTrack(current.GetTrack()); CurrentTrack.Completed += () => onTrackCompleted(current); + AddInternal(CurrentTrack); } From 9a09f97478f063384a03c0d35d23f359cc9d1353 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 8 Aug 2020 21:21:30 +0200 Subject: [PATCH 042/320] Extract constant to avoid double initial value spec --- osu.Game/Screens/Play/Player.cs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 8f8128abfc..67283c843d 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -50,7 +50,13 @@ namespace osu.Game.Screens.Play public override bool HideOverlaysOnEnter => true; - public override OverlayActivation InitialOverlayActivationMode => OverlayActivation.UserTriggered; + private const OverlayActivation initial_overlay_activation_mode = OverlayActivation.UserTriggered; + public override OverlayActivation InitialOverlayActivationMode => initial_overlay_activation_mode; + + /// + /// The current activation mode for overlays. + /// + protected readonly Bindable OverlayActivationMode = new Bindable(initial_overlay_activation_mode); /// /// Whether gameplay should pause when the game window focus is lost. @@ -90,11 +96,6 @@ namespace osu.Game.Screens.Play private SkipOverlay skipOverlay; - /// - /// The current activation mode for overlays. - /// - protected readonly Bindable OverlayActivationMode = new Bindable(OverlayActivation.UserTriggered); - protected ScoreProcessor ScoreProcessor { get; private set; } protected HealthProcessor HealthProcessor { get; private set; } From 78692dc684e4efa337cdbfc12b02caa2eff6a821 Mon Sep 17 00:00:00 2001 From: Craftplacer Date: Mon, 10 Aug 2020 05:21:10 +0200 Subject: [PATCH 043/320] Initial commit --- osu.Game/Beatmaps/BeatmapManager.cs | 6 +++- .../Beatmaps/Formats/LegacyBeatmapEncoder.cs | 33 ++++++++++++++++++- 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index b4b341634c..06acd4e9f2 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -26,6 +26,7 @@ using osu.Game.Online.API; using osu.Game.Online.API.Requests; using osu.Game.Rulesets; using osu.Game.Rulesets.Objects; +using osu.Game.Skinning; using Decoder = osu.Game.Beatmaps.Formats.Decoder; namespace osu.Game.Beatmaps @@ -201,7 +202,10 @@ namespace osu.Game.Beatmaps using (var stream = new MemoryStream()) { using (var sw = new StreamWriter(stream, Encoding.UTF8, 1024, true)) - new LegacyBeatmapEncoder(beatmapContent).Encode(sw); + { + var skin = new LegacyBeatmapSkin(info, Files.Store, audioManager); + new LegacyBeatmapEncoder(beatmapContent, skin).Encode(sw); + } stream.Seek(0, SeekOrigin.Begin); diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs index 57555cce90..8c96e59f30 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs @@ -13,6 +13,7 @@ using osu.Game.Beatmaps.Legacy; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Legacy; using osu.Game.Rulesets.Objects.Types; +using osu.Game.Skinning; using osuTK; namespace osu.Game.Beatmaps.Formats @@ -22,10 +23,12 @@ namespace osu.Game.Beatmaps.Formats public const int LATEST_VERSION = 128; private readonly IBeatmap beatmap; + private readonly LegacyBeatmapSkin beatmapSkin; - public LegacyBeatmapEncoder(IBeatmap beatmap) + public LegacyBeatmapEncoder(IBeatmap beatmap, LegacyBeatmapSkin beatmapSkin = null) { this.beatmap = beatmap; + this.beatmapSkin = beatmapSkin; if (beatmap.BeatmapInfo.RulesetID < 0 || beatmap.BeatmapInfo.RulesetID > 3) throw new ArgumentException("Only beatmaps in the osu, taiko, catch, or mania rulesets can be encoded to the legacy beatmap format.", nameof(beatmap)); @@ -53,6 +56,9 @@ namespace osu.Game.Beatmaps.Formats writer.WriteLine(); handleControlPoints(writer); + writer.WriteLine(); + handleComboColours(writer); + writer.WriteLine(); handleHitObjects(writer); } @@ -196,6 +202,31 @@ namespace osu.Game.Beatmaps.Formats } } + private void handleComboColours(TextWriter writer) + { + if (beatmapSkin == null) + return; + + var colours = beatmapSkin.Configuration.ComboColours; + + if (colours.Count == 0) + return; + + writer.WriteLine("[Colours]"); + + for (var i = 0; i < colours.Count; i++) + { + var comboColour = colours[i]; + + var r = (byte)(comboColour.R * byte.MaxValue); + var g = (byte)(comboColour.G * byte.MaxValue); + var b = (byte)(comboColour.B * byte.MaxValue); + var a = (byte)(comboColour.A * byte.MaxValue); + + writer.WriteLine($"Combo{i}: {r},{g},{b},{a}"); + } + } + private void handleHitObjects(TextWriter writer) { if (beatmap.HitObjects.Count == 0) From 052bb06c910e3618b8cc83badeb41fa0b71c7f1f Mon Sep 17 00:00:00 2001 From: Lucas A Date: Mon, 10 Aug 2020 20:13:50 +0200 Subject: [PATCH 044/320] Add ability to open overlays during gameplay breaks. --- .../Visual/Gameplay/TestSceneOverlayActivation.cs | 11 +++++++++++ osu.Game/Screens/Play/Player.cs | 3 ++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneOverlayActivation.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneOverlayActivation.cs index 03e1337125..7fd5158515 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneOverlayActivation.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneOverlayActivation.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.Linq; using NUnit.Framework; using osu.Game.Configuration; using osu.Game.Overlays; @@ -47,6 +48,16 @@ namespace osu.Game.Tests.Visual.Gameplay AddAssert("activation mode is user triggered", () => testPlayer.OverlayActivationMode == OverlayActivation.UserTriggered); } + [Test] + public void TestGameplayOverlayActivationBreaks() + { + AddAssert("activation mode is disabled", () => testPlayer.OverlayActivationMode == OverlayActivation.Disabled); + AddStep("seek to break", () => testPlayer.GameplayClockContainer.Seek(Beatmap.Value.Beatmap.Breaks.First().StartTime)); + AddUntilStep("activation mode is user triggered", () => testPlayer.OverlayActivationMode == OverlayActivation.UserTriggered); + AddStep("seek to break end", () => testPlayer.GameplayClockContainer.Seek(Beatmap.Value.Beatmap.Breaks.First().EndTime)); + AddUntilStep("activation mode is disabled", () => testPlayer.OverlayActivationMode == OverlayActivation.Disabled); + } + protected override TestPlayer CreatePlayer(Ruleset ruleset) => testPlayer = new OverlayTestPlayer(); private class OverlayTestPlayer : TestPlayer diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 67283c843d..fba35af29e 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -215,6 +215,7 @@ namespace osu.Game.Screens.Play gameplayOverlaysDisabled.BindValueChanged(_ => updateOverlayActivationMode()); DrawableRuleset.IsPaused.BindValueChanged(_ => updateOverlayActivationMode()); DrawableRuleset.HasReplayLoaded.BindValueChanged(_ => updateOverlayActivationMode()); + breakTracker.IsBreakTime.BindValueChanged(_ => updateOverlayActivationMode()); DrawableRuleset.HasReplayLoaded.BindValueChanged(_ => updatePauseOnFocusLostState(), true); @@ -362,7 +363,7 @@ namespace osu.Game.Screens.Play private void updateOverlayActivationMode() { - bool canTriggerOverlays = DrawableRuleset.IsPaused.Value || !gameplayOverlaysDisabled.Value; + bool canTriggerOverlays = DrawableRuleset.IsPaused.Value || breakTracker.IsBreakTime.Value || !gameplayOverlaysDisabled.Value; if (DrawableRuleset.HasReplayLoaded.Value || canTriggerOverlays) OverlayActivationMode.Value = OverlayActivation.UserTriggered; From f74e162bbc90e5c32be17cc4231571a960fc482b Mon Sep 17 00:00:00 2001 From: Lucas A Date: Mon, 10 Aug 2020 20:27:42 +0200 Subject: [PATCH 045/320] Fix overlay activation mode being updated when player is not current screen. --- osu.Game/Screens/Play/Player.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index fba35af29e..2ecddf0f23 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -363,6 +363,9 @@ namespace osu.Game.Screens.Play private void updateOverlayActivationMode() { + if (!this.IsCurrentScreen()) + return; + bool canTriggerOverlays = DrawableRuleset.IsPaused.Value || breakTracker.IsBreakTime.Value || !gameplayOverlaysDisabled.Value; if (DrawableRuleset.HasReplayLoaded.Value || canTriggerOverlays) From 20197e276861128b96dec6fcf7f9fd148a763e8d Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 11 Aug 2020 12:27:32 +0900 Subject: [PATCH 046/320] Remove locally-cached music controller --- osu.Game.Tests/Visual/Gameplay/TestSceneStoryboard.cs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboard.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboard.cs index 3d2dd8a0c5..c11a47d62b 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboard.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboard.cs @@ -25,16 +25,12 @@ namespace osu.Game.Tests.Visual.Gameplay private readonly Container storyboardContainer; private DrawableStoryboard storyboard; - [Cached] - private MusicController musicController = new MusicController(); - public TestSceneStoryboard() { Clock = new FramedClock(); AddRange(new Drawable[] { - musicController, new Container { RelativeSizeAxes = Axes.Both, @@ -104,7 +100,7 @@ namespace osu.Game.Tests.Visual.Gameplay storyboard.Passing = false; storyboardContainer.Add(storyboard); - decoupledClock.ChangeSource(musicController.CurrentTrack); + decoupledClock.ChangeSource(MusicController.CurrentTrack); } private void loadStoryboardNoVideo() @@ -127,7 +123,7 @@ namespace osu.Game.Tests.Visual.Gameplay storyboard = sb.CreateDrawable(Beatmap.Value); storyboardContainer.Add(storyboard); - decoupledClock.ChangeSource(musicController.CurrentTrack); + decoupledClock.ChangeSource(MusicController.CurrentTrack); } } } From b64142dff9d04deb9295eeb9c5b3e52623c63cdf Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 11 Aug 2020 12:37:00 +0900 Subject: [PATCH 047/320] Fix incorrect load state being used --- osu.Game/Overlays/MusicController.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index c5ba82288c..813ad26ae4 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -105,7 +105,7 @@ namespace osu.Game.Overlays /// /// Returns whether the beatmap track is loaded. /// - public bool TrackLoaded => CurrentTrack.IsLoaded; + public bool TrackLoaded => CurrentTrack.TrackLoaded; private void beatmapUpdated(ValueChangedEvent> weakSet) { From c66a14e9c5d160def0fdcdabcf39772e72cdd0dc Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 11 Aug 2020 12:37:48 +0900 Subject: [PATCH 048/320] Remove beatmap from FailAnimation --- osu.Game/Screens/Play/FailAnimation.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/osu.Game/Screens/Play/FailAnimation.cs b/osu.Game/Screens/Play/FailAnimation.cs index a7bfca612e..122ae505ca 100644 --- a/osu.Game/Screens/Play/FailAnimation.cs +++ b/osu.Game/Screens/Play/FailAnimation.cs @@ -11,7 +11,6 @@ using osu.Framework.Audio.Sample; using osu.Framework.Audio.Track; using osu.Framework.Graphics; using osu.Framework.Utils; -using osu.Game.Beatmaps; using osu.Game.Rulesets.Objects.Drawables; using osuTK; using osuTK.Graphics; @@ -42,7 +41,7 @@ namespace osu.Game.Screens.Play } [BackgroundDependencyLoader] - private void load(AudioManager audio, IBindable beatmap) + private void load(AudioManager audio) { failSample = audio.Samples.Get(@"Gameplay/failsound"); } From 7d35893ecd2bf8b277c2e6ac9632592dbf313f6f Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 11 Aug 2020 12:40:58 +0900 Subject: [PATCH 049/320] Make MusicController non-nullable --- osu.Game/Screens/Menu/MainMenu.cs | 2 +- .../Screens/Multi/Lounge/LoungeSubScreen.cs | 2 +- osu.Game/Screens/Select/SongSelect.cs | 28 +++++++------------ 3 files changed, 12 insertions(+), 20 deletions(-) diff --git a/osu.Game/Screens/Menu/MainMenu.cs b/osu.Game/Screens/Menu/MainMenu.cs index 8837a49772..470e8ca9a6 100644 --- a/osu.Game/Screens/Menu/MainMenu.cs +++ b/osu.Game/Screens/Menu/MainMenu.cs @@ -45,7 +45,7 @@ namespace osu.Game.Screens.Menu [Resolved] private GameHost host { get; set; } - [Resolved(canBeNull: true)] + [Resolved] private MusicController music { get; set; } [Resolved(canBeNull: true)] diff --git a/osu.Game/Screens/Multi/Lounge/LoungeSubScreen.cs b/osu.Game/Screens/Multi/Lounge/LoungeSubScreen.cs index ff7d56a95b..f9c5fd13a4 100644 --- a/osu.Game/Screens/Multi/Lounge/LoungeSubScreen.cs +++ b/osu.Game/Screens/Multi/Lounge/LoungeSubScreen.cs @@ -32,7 +32,7 @@ namespace osu.Game.Screens.Multi.Lounge [Resolved] private Bindable selectedRoom { get; set; } - [Resolved(canBeNull: true)] + [Resolved] private MusicController music { get; set; } private bool joiningRoom; diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 80ed894233..ddbb021054 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -99,7 +99,7 @@ namespace osu.Game.Screens.Select private readonly Bindable decoupledRuleset = new Bindable(); - [Resolved(canBeNull: true)] + [Resolved] private MusicController music { get; set; } [BackgroundDependencyLoader(true)] @@ -561,18 +561,15 @@ namespace osu.Game.Screens.Select BeatmapDetails.Refresh(); - if (music?.CurrentTrack != null) - { - music.CurrentTrack.Looping = true; - music.ResetTrackAdjustments(); - } + music.CurrentTrack.Looping = true; + music.ResetTrackAdjustments(); if (Beatmap != null && !Beatmap.Value.BeatmapSetInfo.DeletePending) { updateComponentFromBeatmap(Beatmap.Value); // restart playback on returning to song select, regardless. - music?.Play(); + music.Play(); } this.FadeIn(250); @@ -589,8 +586,7 @@ namespace osu.Game.Screens.Select BeatmapOptions.Hide(); - if (music?.CurrentTrack != null) - music.CurrentTrack.Looping = false; + music.CurrentTrack.Looping = false; this.ScaleTo(1.1f, 250, Easing.InSine); @@ -611,8 +607,7 @@ namespace osu.Game.Screens.Select FilterControl.Deactivate(); - if (music?.CurrentTrack != null) - music.CurrentTrack.Looping = false; + music.CurrentTrack.Looping = false; return false; } @@ -653,8 +648,7 @@ namespace osu.Game.Screens.Select BeatmapDetails.Beatmap = beatmap; - if (music?.CurrentTrack != null) - music.CurrentTrack.Looping = true; + music.CurrentTrack.Looping = true; } private readonly WeakReference lastTrack = new WeakReference(null); @@ -665,16 +659,14 @@ namespace osu.Game.Screens.Select /// private void ensurePlayingSelected() { - ITrack track = music?.CurrentTrack; - if (track == null) - return; + ITrack track = music.CurrentTrack; bool isNewTrack = !lastTrack.TryGetTarget(out var last) || last != track; track.RestartPoint = Beatmap.Value.Metadata.PreviewTime; - if (!track.IsRunning && (music?.IsUserPaused != true || isNewTrack)) - music?.Play(true); + if (!track.IsRunning && (music.IsUserPaused != true || isNewTrack)) + music.Play(true); lastTrack.SetTarget(track); } From 322d08af1bfe25f45f90fcd8bc395219ce85c108 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 11 Aug 2020 13:11:59 +0900 Subject: [PATCH 050/320] Remove more local music controller caches --- osu.Game.Tests/Visual/Menus/TestSceneSongTicker.cs | 5 ----- .../Visual/UserInterface/TestSceneBeatSyncedContainer.cs | 4 ---- 2 files changed, 9 deletions(-) diff --git a/osu.Game.Tests/Visual/Menus/TestSceneSongTicker.cs b/osu.Game.Tests/Visual/Menus/TestSceneSongTicker.cs index d7f23f5cc0..4b22af38c5 100644 --- a/osu.Game.Tests/Visual/Menus/TestSceneSongTicker.cs +++ b/osu.Game.Tests/Visual/Menus/TestSceneSongTicker.cs @@ -1,7 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Overlays; @@ -11,14 +10,10 @@ namespace osu.Game.Tests.Visual.Menus { public class TestSceneSongTicker : OsuTestScene { - [Cached] - private MusicController musicController = new MusicController(); - public TestSceneSongTicker() { AddRange(new Drawable[] { - musicController, new SongTicker { Anchor = Anchor.Centre, diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneBeatSyncedContainer.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneBeatSyncedContainer.cs index 127915c6c6..82b7e65c4f 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneBeatSyncedContainer.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneBeatSyncedContainer.cs @@ -26,9 +26,6 @@ namespace osu.Game.Tests.Visual.UserInterface { private readonly NowPlayingOverlay np; - [Cached] - private MusicController musicController = new MusicController(); - public TestSceneBeatSyncedContainer() { Clock = new FramedClock(); @@ -36,7 +33,6 @@ namespace osu.Game.Tests.Visual.UserInterface AddRange(new Drawable[] { - musicController, new BeatContainer { Anchor = Anchor.BottomCentre, From 6aafb3d2710174fe4bf302300ecf2cd1edd52988 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 11 Aug 2020 13:14:20 +0900 Subject: [PATCH 051/320] Cleanup TestSceneScreenNavigation --- osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs b/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs index 0f06010a6a..73a833c15d 100644 --- a/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs +++ b/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs @@ -80,7 +80,7 @@ namespace osu.Game.Tests.Visual.Navigation AddStep("return to menu", () => songSelect.Exit()); - AddUntilStep("wait for track", () => Game.MusicController.CurrentTrack.IsDummyDevice == false && Game.MusicController.IsPlaying); + AddUntilStep("wait for track", () => !Game.MusicController.CurrentTrack.IsDummyDevice && Game.MusicController.IsPlaying); } [Test] From 338c01fa43657beb3f1476aab90db227605deed2 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 11 Aug 2020 13:16:06 +0900 Subject: [PATCH 052/320] Remove track store reference counting, use single instance stores --- osu.Game/Beatmaps/BeatmapManager.cs | 29 ++++--------------- .../Beatmaps/BeatmapManager_WorkingBeatmap.cs | 24 +++++---------- 2 files changed, 13 insertions(+), 40 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index e001185da9..6f01580998 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -63,8 +63,9 @@ namespace osu.Game.Beatmaps private readonly RulesetStore rulesets; private readonly BeatmapStore beatmaps; private readonly AudioManager audioManager; - private readonly GameHost host; private readonly BeatmapOnlineLookupQueue onlineLookupQueue; + private readonly TextureStore textureStore; + private readonly ITrackStore trackStore; public BeatmapManager(Storage storage, IDatabaseContextFactory contextFactory, RulesetStore rulesets, IAPIProvider api, AudioManager audioManager, GameHost host = null, WorkingBeatmap defaultBeatmap = null) @@ -72,7 +73,6 @@ namespace osu.Game.Beatmaps { this.rulesets = rulesets; this.audioManager = audioManager; - this.host = host; DefaultBeatmap = defaultBeatmap; @@ -83,6 +83,9 @@ namespace osu.Game.Beatmaps beatmaps.ItemUpdated += removeWorkingCache; onlineLookupQueue = new BeatmapOnlineLookupQueue(api, storage); + + textureStore = new LargeTextureStore(host?.CreateTextureLoaderStore(Files.Store)); + trackStore = audioManager.GetTrackStore(Files.Store); } protected override ArchiveDownloadRequest CreateDownloadRequest(BeatmapSetInfo set, bool minimiseDownloadSize) => @@ -219,7 +222,6 @@ namespace osu.Game.Beatmaps } private readonly WeakList workingCache = new WeakList(); - private readonly Dictionary referencedTrackStores = new Dictionary(); /// /// Retrieve a instance for the provided @@ -252,31 +254,12 @@ namespace osu.Game.Beatmaps beatmapInfo.Metadata ??= beatmapInfo.BeatmapSet.Metadata; - ITrackStore trackStore = workingCache.FirstOrDefault(b => b.BeatmapInfo.AudioEquals(beatmapInfo))?.TrackStore; - TextureStore textureStore = workingCache.FirstOrDefault(b => b.BeatmapInfo.BackgroundEquals(beatmapInfo))?.TextureStore; - - textureStore ??= new LargeTextureStore(host?.CreateTextureLoaderStore(Files.Store)); - trackStore ??= audioManager.GetTrackStore(Files.Store); - - workingCache.Add(working = new BeatmapManagerWorkingBeatmap(Files.Store, textureStore, trackStore, beatmapInfo, audioManager, dereferenceTrackStore)); - referencedTrackStores[trackStore] = referencedTrackStores.GetOrDefault(trackStore) + 1; + workingCache.Add(working = new BeatmapManagerWorkingBeatmap(Files.Store, textureStore, trackStore, beatmapInfo, audioManager)); return working; } } - private void dereferenceTrackStore(ITrackStore trackStore) - { - lock (workingCache) - { - if (--referencedTrackStores[trackStore] == 0) - { - referencedTrackStores.Remove(trackStore); - trackStore.Dispose(); - } - } - } - /// /// Perform a lookup query on available s. /// diff --git a/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs b/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs index f1289cd3aa..aa93833f33 100644 --- a/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs @@ -19,21 +19,16 @@ namespace osu.Game.Beatmaps { protected class BeatmapManagerWorkingBeatmap : WorkingBeatmap { - public readonly TextureStore TextureStore; - public readonly ITrackStore TrackStore; - private readonly IResourceStore store; - private readonly Action dereferenceAction; + private readonly TextureStore textureStore; + private readonly ITrackStore trackStore; - public BeatmapManagerWorkingBeatmap(IResourceStore store, TextureStore textureStore, ITrackStore trackStore, BeatmapInfo beatmapInfo, AudioManager audioManager, - Action dereferenceAction) + public BeatmapManagerWorkingBeatmap(IResourceStore store, TextureStore textureStore, ITrackStore trackStore, BeatmapInfo beatmapInfo, AudioManager audioManager) : base(beatmapInfo, audioManager) { this.store = store; - this.dereferenceAction = dereferenceAction; - - TextureStore = textureStore; - TrackStore = trackStore; + this.textureStore = textureStore; + this.trackStore = trackStore; } protected override IBeatmap GetBeatmap() @@ -61,7 +56,7 @@ namespace osu.Game.Beatmaps try { - return TextureStore.Get(getPathForFile(Metadata.BackgroundFile)); + return textureStore.Get(getPathForFile(Metadata.BackgroundFile)); } catch (Exception e) { @@ -74,7 +69,7 @@ namespace osu.Game.Beatmaps { try { - return TrackStore.Get(getPathForFile(Metadata.AudioFile)); + return trackStore.Get(getPathForFile(Metadata.AudioFile)); } catch (Exception e) { @@ -140,11 +135,6 @@ namespace osu.Game.Beatmaps return null; } } - - ~BeatmapManagerWorkingBeatmap() - { - dereferenceAction?.Invoke(TrackStore); - } } } } From faff0a70c49734841f6c1dd36c8df2775d1b867e Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 11 Aug 2020 13:48:57 +0900 Subject: [PATCH 053/320] Privatise BMWB --- osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs b/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs index aa93833f33..92199789ec 100644 --- a/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs @@ -17,7 +17,7 @@ namespace osu.Game.Beatmaps { public partial class BeatmapManager { - protected class BeatmapManagerWorkingBeatmap : WorkingBeatmap + private class BeatmapManagerWorkingBeatmap : WorkingBeatmap { private readonly IResourceStore store; private readonly TextureStore textureStore; From 031d29ac34bd6684340f51aab051b84db42c4644 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 11 Aug 2020 13:53:23 +0900 Subject: [PATCH 054/320] Inspect current track directly --- osu.Game/Overlays/NowPlayingOverlay.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/NowPlayingOverlay.cs b/osu.Game/Overlays/NowPlayingOverlay.cs index 15b189ead6..dc52300cdb 100644 --- a/osu.Game/Overlays/NowPlayingOverlay.cs +++ b/osu.Game/Overlays/NowPlayingOverlay.cs @@ -234,9 +234,9 @@ namespace osu.Game.Overlays pendingBeatmapSwitch = null; } - var track = musicController.TrackLoaded ? musicController.CurrentTrack : null; + var track = musicController.CurrentTrack; - if (track?.IsDummyDevice == false) + if (track.IsDummyDevice == false) { progressBar.EndTime = track.Length; progressBar.CurrentTime = track.CurrentTime; From 070d71ec27fa74eec6d27fa551dd5162ab628d4e Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 12 Aug 2020 00:48:38 +0900 Subject: [PATCH 055/320] More cleanups --- .../Skinning/TestSceneDrawableTaikoMascot.cs | 4 ++-- .../Skinning/TestSceneTaikoPlayfield.cs | 2 +- osu.Game.Tests/Skins/TestSceneBeatmapSkinResources.cs | 2 +- .../Visual/Gameplay/TestSceneNightcoreBeatContainer.cs | 4 ++-- osu.Game/Overlays/NowPlayingOverlay.cs | 2 +- osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs | 3 --- osu.Game/Screens/Edit/Editor.cs | 4 ++-- osu.Game/Screens/Edit/EditorClock.cs | 4 ++-- osu.Game/Screens/Menu/IntroScreen.cs | 2 +- 9 files changed, 12 insertions(+), 15 deletions(-) diff --git a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableTaikoMascot.cs b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableTaikoMascot.cs index ba5aef5968..6141bf062e 100644 --- a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableTaikoMascot.cs +++ b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableTaikoMascot.cs @@ -175,11 +175,11 @@ namespace osu.Game.Rulesets.Taiko.Tests.Skinning private void createDrawableRuleset() { - AddUntilStep("wait for beatmap to be loaded", () => MusicController.TrackLoaded); + AddUntilStep("wait for beatmap to be loaded", () => MusicController.CurrentTrack.TrackLoaded); AddStep("create drawable ruleset", () => { - MusicController.Play(true); + MusicController.CurrentTrack.Start(); SetContents(() => { diff --git a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneTaikoPlayfield.cs b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneTaikoPlayfield.cs index 5c54393fb8..a3d3bc81c4 100644 --- a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneTaikoPlayfield.cs +++ b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneTaikoPlayfield.cs @@ -34,7 +34,7 @@ namespace osu.Game.Rulesets.Taiko.Tests.Skinning beatmap.ControlPointInfo.Add(0, new TimingControlPoint { BeatLength = 1000 }); - MusicController.Play(true); + MusicController.CurrentTrack.Start(); }); AddStep("Load playfield", () => SetContents(() => new TaikoPlayfield(new ControlPointInfo()) diff --git a/osu.Game.Tests/Skins/TestSceneBeatmapSkinResources.cs b/osu.Game.Tests/Skins/TestSceneBeatmapSkinResources.cs index 03faee9ad2..49b40daf99 100644 --- a/osu.Game.Tests/Skins/TestSceneBeatmapSkinResources.cs +++ b/osu.Game.Tests/Skins/TestSceneBeatmapSkinResources.cs @@ -29,6 +29,6 @@ namespace osu.Game.Tests.Skins public void TestRetrieveOggSample() => AddAssert("sample is non-null", () => Beatmap.Value.Skin.GetSample(new SampleInfo("sample")) != null); [Test] - public void TestRetrieveOggTrack() => AddAssert("track is non-null", () => MusicController.CurrentTrack.IsDummyDevice == false); + public void TestRetrieveOggTrack() => AddAssert("track is non-null", () => !MusicController.CurrentTrack.IsDummyDevice); } } diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneNightcoreBeatContainer.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneNightcoreBeatContainer.cs index ce99d85e92..53e06a632e 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneNightcoreBeatContainer.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneNightcoreBeatContainer.cs @@ -19,8 +19,8 @@ namespace osu.Game.Tests.Visual.Gameplay Beatmap.Value = CreateWorkingBeatmap(new OsuRuleset().RulesetInfo); - MusicController.Play(true); - MusicController.SeekTo(Beatmap.Value.Beatmap.HitObjects.First().StartTime - 1000); + MusicController.CurrentTrack.Start(); + MusicController.CurrentTrack.Seek(Beatmap.Value.Beatmap.HitObjects.First().StartTime - 1000); Add(new ModNightcore.NightcoreBeatContainer()); diff --git a/osu.Game/Overlays/NowPlayingOverlay.cs b/osu.Game/Overlays/NowPlayingOverlay.cs index dc52300cdb..af692486b7 100644 --- a/osu.Game/Overlays/NowPlayingOverlay.cs +++ b/osu.Game/Overlays/NowPlayingOverlay.cs @@ -236,7 +236,7 @@ namespace osu.Game.Overlays var track = musicController.CurrentTrack; - if (track.IsDummyDevice == false) + if (!track.IsDummyDevice) { progressBar.EndTime = track.Length; progressBar.CurrentTime = track.CurrentTime; diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs index d556d948f6..e1702d3eff 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs @@ -2,7 +2,6 @@ // See the LICENCE file in the repository root for full licence text. using System; -using System.Diagnostics; using osu.Framework.Allocation; using osu.Framework.Audio.Track; using osu.Framework.Bindables; @@ -64,8 +63,6 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline waveform.Waveform = b.NewValue.Waveform; track = musicController.CurrentTrack; - Debug.Assert(track != null); - if (track.Length > 0) { MaxZoom = getZoomLevelForVisibleMilliseconds(500); diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index 78fa6c74b0..6722d9179c 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -82,7 +82,7 @@ namespace osu.Game.Screens.Edit beatDivisor.BindValueChanged(divisor => Beatmap.Value.BeatmapInfo.BeatDivisor = divisor.NewValue); // Todo: should probably be done at a DrawableRuleset level to share logic with Player. - clock = new EditorClock(Beatmap.Value, musicController.CurrentTrack.Length, beatDivisor) { IsCoupled = false }; + clock = new EditorClock(Beatmap.Value, beatDivisor) { IsCoupled = false }; clock.ChangeSource(musicController.CurrentTrack); dependencies.CacheAs(clock); @@ -348,7 +348,7 @@ namespace osu.Game.Screens.Edit private void resetTrack(bool seekToStart = false) { - musicController.Stop(); + musicController.CurrentTrack.Stop(); if (seekToStart) { diff --git a/osu.Game/Screens/Edit/EditorClock.cs b/osu.Game/Screens/Edit/EditorClock.cs index fbfa397795..d0e265adb0 100644 --- a/osu.Game/Screens/Edit/EditorClock.cs +++ b/osu.Game/Screens/Edit/EditorClock.cs @@ -25,8 +25,8 @@ namespace osu.Game.Screens.Edit private readonly DecoupleableInterpolatingFramedClock underlyingClock; - public EditorClock(WorkingBeatmap beatmap, double trackLength, BindableBeatDivisor beatDivisor) - : this(beatmap.Beatmap.ControlPointInfo, trackLength, beatDivisor) + public EditorClock(WorkingBeatmap beatmap, BindableBeatDivisor beatDivisor) + : this(beatmap.Beatmap.ControlPointInfo, beatmap.GetTrack().Length, beatDivisor) { } diff --git a/osu.Game/Screens/Menu/IntroScreen.cs b/osu.Game/Screens/Menu/IntroScreen.cs index 6e85abf7dc..389629445c 100644 --- a/osu.Game/Screens/Menu/IntroScreen.cs +++ b/osu.Game/Screens/Menu/IntroScreen.cs @@ -115,7 +115,7 @@ namespace osu.Game.Screens.Menu if (setInfo != null) { initialBeatmap = beatmaps.GetWorkingBeatmap(setInfo.Beatmaps[0]); - UsingThemedIntro = initialBeatmap.GetTrack().IsDummyDevice == false; + UsingThemedIntro = !initialBeatmap.GetTrack().IsDummyDevice; } return UsingThemedIntro; From b66f303e71cf9083c2f764964cf3424bb4433f64 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 12 Aug 2020 00:48:45 +0900 Subject: [PATCH 056/320] Add annotation --- osu.Game/Beatmaps/WorkingBeatmap.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Beatmaps/WorkingBeatmap.cs b/osu.Game/Beatmaps/WorkingBeatmap.cs index af6a67ad3f..bec2679103 100644 --- a/osu.Game/Beatmaps/WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/WorkingBeatmap.cs @@ -7,6 +7,7 @@ using System.Diagnostics; using System.Linq; using System.Threading; using System.Threading.Tasks; +using JetBrains.Annotations; using osu.Framework.Audio; using osu.Framework.Audio.Track; using osu.Framework.Graphics.Textures; @@ -249,6 +250,7 @@ namespace osu.Game.Beatmaps protected abstract Texture GetBackground(); private readonly RecyclableLazy background; + [NotNull] public Track GetTrack() => GetBeatmapTrack() ?? GetVirtualTrack(1000); protected abstract Track GetBeatmapTrack(); From eec94e1f535e1a5f9d3a17561bfd1ca6d2e5ccab Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 12 Aug 2020 00:50:56 +0900 Subject: [PATCH 057/320] Make track not-null in GameplayClockContainer/FailAnimation --- osu.Game/Screens/Play/FailAnimation.cs | 5 ++++- osu.Game/Screens/Play/GameplayClockContainer.cs | 10 +++------- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/osu.Game/Screens/Play/FailAnimation.cs b/osu.Game/Screens/Play/FailAnimation.cs index 122ae505ca..6ebee209e2 100644 --- a/osu.Game/Screens/Play/FailAnimation.cs +++ b/osu.Game/Screens/Play/FailAnimation.cs @@ -6,6 +6,7 @@ using osu.Framework.Bindables; using osu.Game.Rulesets.UI; using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using osu.Framework.Allocation; using osu.Framework.Audio.Sample; using osu.Framework.Audio.Track; @@ -26,6 +27,8 @@ namespace osu.Game.Screens.Play public Action OnComplete; private readonly DrawableRuleset drawableRuleset; + + [NotNull] private readonly ITrack track; private readonly BindableDouble trackFreq = new BindableDouble(1); @@ -34,7 +37,7 @@ namespace osu.Game.Screens.Play private SampleChannel failSample; - public FailAnimation(DrawableRuleset drawableRuleset, ITrack track) + public FailAnimation(DrawableRuleset drawableRuleset, [NotNull] ITrack track) { this.drawableRuleset = drawableRuleset; this.track = track; diff --git a/osu.Game/Screens/Play/GameplayClockContainer.cs b/osu.Game/Screens/Play/GameplayClockContainer.cs index c4f368e1f5..f3466a562e 100644 --- a/osu.Game/Screens/Play/GameplayClockContainer.cs +++ b/osu.Game/Screens/Play/GameplayClockContainer.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Threading.Tasks; using osu.Framework; @@ -27,6 +28,7 @@ namespace osu.Game.Screens.Play private readonly WorkingBeatmap beatmap; private readonly IReadOnlyList mods; + [NotNull] private ITrack track; public readonly BindableBool IsPaused = new BindableBool(); @@ -60,7 +62,7 @@ namespace osu.Game.Screens.Play private readonly FramedOffsetClock platformOffsetClock; - public GameplayClockContainer(ITrack track, WorkingBeatmap beatmap, IReadOnlyList mods, double gameplayStartTime) + public GameplayClockContainer([NotNull] ITrack track, WorkingBeatmap beatmap, IReadOnlyList mods, double gameplayStartTime) { this.beatmap = beatmap; this.mods = mods; @@ -196,9 +198,6 @@ namespace osu.Game.Screens.Play /// public void StopUsingBeatmapClock() { - if (track == null) - return; - removeSourceClockAdjustments(); track = new TrackVirtual(track.Length); @@ -217,8 +216,6 @@ namespace osu.Game.Screens.Play private void updateRate() { - if (track == null) return; - speedAdjustmentsApplied = true; track.ResetSpeedAdjustments(); @@ -233,7 +230,6 @@ namespace osu.Game.Screens.Play { base.Dispose(isDisposing); removeSourceClockAdjustments(); - track = null; } private void removeSourceClockAdjustments() From 688e4479506645bdacee7cdc7ae9ee9deaa5f1b4 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 12 Aug 2020 01:33:06 +0900 Subject: [PATCH 058/320] Fix potential hierarchy mutation from async context --- osu.Game/Overlays/MusicController.cs | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index 813ad26ae4..c18b564b4f 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -317,11 +317,28 @@ namespace osu.Game.Overlays private void changeTrack() { - CurrentTrack.Expire(); - CurrentTrack = new DrawableTrack(current.GetTrack()); - CurrentTrack.Completed += () => onTrackCompleted(current); + var lastTrack = CurrentTrack; - AddInternal(CurrentTrack); + var newTrack = new DrawableTrack(current.GetTrack()); + newTrack.Completed += () => onTrackCompleted(current); + + CurrentTrack = newTrack; + + // At this point we may potentially be in an async context from tests. This is extremely dangerous but we have to make do for now. + // CurrentTrack is immediately updated above for situations where a immediate knowledge about the new track is required, + // but the mutation of the hierarchy is scheduled to avoid exceptions. + Schedule(() => + { + lastTrack.Expire(); + + if (newTrack == CurrentTrack) + AddInternal(newTrack); + else + { + // If the track has changed via changeTrack() being called multiple times in a single update, force disposal on the old track. + newTrack.Dispose(); + } + }); } private void onTrackCompleted(WorkingBeatmap workingBeatmap) From e47a1eb313f86d9c0f635e58545644139d5cbf34 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 12 Aug 2020 01:41:21 +0900 Subject: [PATCH 059/320] Use adjustable ITrack --- osu.Game/Rulesets/Mods/ModDaycore.cs | 4 ++-- osu.Game/Rulesets/Mods/ModNightcore.cs | 4 ++-- osu.Game/Rulesets/Mods/ModRateAdjust.cs | 2 +- osu.Game/Rulesets/Mods/ModTimeRamp.cs | 4 ++-- osu.Game/Screens/Play/FailAnimation.cs | 4 ++-- osu.Game/Screens/Play/GameplayClockContainer.cs | 4 ++-- 6 files changed, 11 insertions(+), 11 deletions(-) diff --git a/osu.Game/Rulesets/Mods/ModDaycore.cs b/osu.Game/Rulesets/Mods/ModDaycore.cs index 800312d047..61ad7db706 100644 --- a/osu.Game/Rulesets/Mods/ModDaycore.cs +++ b/osu.Game/Rulesets/Mods/ModDaycore.cs @@ -30,8 +30,8 @@ namespace osu.Game.Rulesets.Mods public override void ApplyToTrack(ITrack track) { // base.ApplyToTrack() intentionally not called (different tempo adjustment is applied) - (track as IAdjustableAudioComponent)?.AddAdjustment(AdjustableProperty.Frequency, freqAdjust); - (track as IAdjustableAudioComponent)?.AddAdjustment(AdjustableProperty.Tempo, tempoAdjust); + track.AddAdjustment(AdjustableProperty.Frequency, freqAdjust); + track.AddAdjustment(AdjustableProperty.Tempo, tempoAdjust); } } } diff --git a/osu.Game/Rulesets/Mods/ModNightcore.cs b/osu.Game/Rulesets/Mods/ModNightcore.cs index 4932df08f1..4004953cd1 100644 --- a/osu.Game/Rulesets/Mods/ModNightcore.cs +++ b/osu.Game/Rulesets/Mods/ModNightcore.cs @@ -41,8 +41,8 @@ namespace osu.Game.Rulesets.Mods public override void ApplyToTrack(ITrack track) { // base.ApplyToTrack() intentionally not called (different tempo adjustment is applied) - (track as IAdjustableAudioComponent)?.AddAdjustment(AdjustableProperty.Frequency, freqAdjust); - (track as IAdjustableAudioComponent)?.AddAdjustment(AdjustableProperty.Tempo, tempoAdjust); + track.AddAdjustment(AdjustableProperty.Frequency, freqAdjust); + track.AddAdjustment(AdjustableProperty.Tempo, tempoAdjust); } public void ApplyToDrawableRuleset(DrawableRuleset drawableRuleset) diff --git a/osu.Game/Rulesets/Mods/ModRateAdjust.cs b/osu.Game/Rulesets/Mods/ModRateAdjust.cs index ae7077c67b..fec21764b0 100644 --- a/osu.Game/Rulesets/Mods/ModRateAdjust.cs +++ b/osu.Game/Rulesets/Mods/ModRateAdjust.cs @@ -14,7 +14,7 @@ namespace osu.Game.Rulesets.Mods public virtual void ApplyToTrack(ITrack track) { - (track as IAdjustableAudioComponent)?.AddAdjustment(AdjustableProperty.Tempo, SpeedChange); + track.AddAdjustment(AdjustableProperty.Tempo, SpeedChange); } public virtual void ApplyToSample(SampleChannel sample) diff --git a/osu.Game/Rulesets/Mods/ModTimeRamp.cs b/osu.Game/Rulesets/Mods/ModTimeRamp.cs index b904cf007b..20c8d0f3e7 100644 --- a/osu.Game/Rulesets/Mods/ModTimeRamp.cs +++ b/osu.Game/Rulesets/Mods/ModTimeRamp.cs @@ -89,9 +89,9 @@ namespace osu.Game.Rulesets.Mods private void applyPitchAdjustment(ValueChangedEvent adjustPitchSetting) { // remove existing old adjustment - (track as IAdjustableAudioComponent)?.RemoveAdjustment(adjustmentForPitchSetting(adjustPitchSetting.OldValue), SpeedChange); + track?.RemoveAdjustment(adjustmentForPitchSetting(adjustPitchSetting.OldValue), SpeedChange); - (track as IAdjustableAudioComponent)?.AddAdjustment(adjustmentForPitchSetting(adjustPitchSetting.NewValue), SpeedChange); + track?.AddAdjustment(adjustmentForPitchSetting(adjustPitchSetting.NewValue), SpeedChange); } private AdjustableProperty adjustmentForPitchSetting(bool adjustPitchSettingValue) diff --git a/osu.Game/Screens/Play/FailAnimation.cs b/osu.Game/Screens/Play/FailAnimation.cs index 6ebee209e2..dade904180 100644 --- a/osu.Game/Screens/Play/FailAnimation.cs +++ b/osu.Game/Screens/Play/FailAnimation.cs @@ -69,7 +69,7 @@ namespace osu.Game.Screens.Play Expire(); }); - (track as IAdjustableAudioComponent)?.AddAdjustment(AdjustableProperty.Frequency, trackFreq); + track.AddAdjustment(AdjustableProperty.Frequency, trackFreq); applyToPlayfield(drawableRuleset.Playfield); drawableRuleset.Playfield.HitObjectContainer.FlashColour(Color4.Red, 500); @@ -108,7 +108,7 @@ namespace osu.Game.Screens.Play protected override void Dispose(bool isDisposing) { base.Dispose(isDisposing); - (track as IAdjustableAudioComponent)?.RemoveAdjustment(AdjustableProperty.Frequency, trackFreq); + track?.RemoveAdjustment(AdjustableProperty.Frequency, trackFreq); } } } diff --git a/osu.Game/Screens/Play/GameplayClockContainer.cs b/osu.Game/Screens/Play/GameplayClockContainer.cs index f3466a562e..59e26cdf55 100644 --- a/osu.Game/Screens/Play/GameplayClockContainer.cs +++ b/osu.Game/Screens/Play/GameplayClockContainer.cs @@ -219,8 +219,8 @@ namespace osu.Game.Screens.Play speedAdjustmentsApplied = true; track.ResetSpeedAdjustments(); - (track as IAdjustableAudioComponent)?.AddAdjustment(AdjustableProperty.Frequency, pauseFreqAdjust); - (track as IAdjustableAudioComponent)?.AddAdjustment(AdjustableProperty.Tempo, UserPlaybackRate); + track.AddAdjustment(AdjustableProperty.Frequency, pauseFreqAdjust); + track.AddAdjustment(AdjustableProperty.Tempo, UserPlaybackRate); foreach (var mod in mods.OfType()) mod.ApplyToTrack(track); From c0031955c9ed6c0b74fd655366f988b33ba34ae6 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 12 Aug 2020 01:50:18 +0900 Subject: [PATCH 060/320] Update with further framework changes --- osu.Game/Screens/Menu/IntroTriangles.cs | 2 +- osu.Game/Screens/Play/GameplayClockContainer.cs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Menu/IntroTriangles.cs b/osu.Game/Screens/Menu/IntroTriangles.cs index 86f7dbdd6f..a9ef20436f 100644 --- a/osu.Game/Screens/Menu/IntroTriangles.cs +++ b/osu.Game/Screens/Menu/IntroTriangles.cs @@ -59,7 +59,7 @@ namespace osu.Game.Screens.Menu LoadComponentAsync(new TrianglesIntroSequence(logo, background) { RelativeSizeAxes = Axes.Both, - Clock = new FramedClock(UsingThemedIntro ? (IAdjustableClock)Track : null), + Clock = new FramedClock(UsingThemedIntro ? Track : null), LoadMenu = LoadMenu }, t => { diff --git a/osu.Game/Screens/Play/GameplayClockContainer.cs b/osu.Game/Screens/Play/GameplayClockContainer.cs index 59e26cdf55..f0bbcf957a 100644 --- a/osu.Game/Screens/Play/GameplayClockContainer.cs +++ b/osu.Game/Screens/Play/GameplayClockContainer.cs @@ -132,7 +132,7 @@ namespace osu.Game.Screens.Play Schedule(() => { - adjustableClock.ChangeSource((IAdjustableClock)track); + adjustableClock.ChangeSource(track); updateRate(); if (!IsPaused.Value) @@ -201,7 +201,7 @@ namespace osu.Game.Screens.Play removeSourceClockAdjustments(); track = new TrackVirtual(track.Length); - adjustableClock.ChangeSource((IAdjustableClock)track); + adjustableClock.ChangeSource(track); } protected override void Update() From 139c0c75f87e03ad4d86fd524e61c4dea79f0e81 Mon Sep 17 00:00:00 2001 From: Craftplacer Date: Wed, 12 Aug 2020 06:37:25 +0200 Subject: [PATCH 061/320] Add documentation for constructor --- osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs index 8c96e59f30..3e744056bb 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs @@ -7,6 +7,7 @@ using System.Globalization; using System.IO; using System.Linq; using System.Text; +using JetBrains.Annotations; using osu.Game.Audio; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Beatmaps.Legacy; @@ -25,7 +26,9 @@ namespace osu.Game.Beatmaps.Formats private readonly IBeatmap beatmap; private readonly LegacyBeatmapSkin beatmapSkin; - public LegacyBeatmapEncoder(IBeatmap beatmap, LegacyBeatmapSkin beatmapSkin = null) + /// The beatmap to encode + /// An optional beatmap skin, for encoding the beatmap's combo colours. + public LegacyBeatmapEncoder(IBeatmap beatmap, [CanBeNull] LegacyBeatmapSkin beatmapSkin) { this.beatmap = beatmap; this.beatmapSkin = beatmapSkin; From 8ffaa49839bdf3902e57c57b0ff429b8c91a2fb1 Mon Sep 17 00:00:00 2001 From: Craftplacer Date: Wed, 12 Aug 2020 06:37:33 +0200 Subject: [PATCH 062/320] Handle additional null case --- osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs index 3e744056bb..eb148794de 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs @@ -207,12 +207,9 @@ namespace osu.Game.Beatmaps.Formats private void handleComboColours(TextWriter writer) { - if (beatmapSkin == null) - return; + var colours = beatmapSkin?.Configuration.ComboColours; - var colours = beatmapSkin.Configuration.ComboColours; - - if (colours.Count == 0) + if (colours == null || colours.Count == 0) return; writer.WriteLine("[Colours]"); From 69590113d62c54ec56c86c8bc529a49b0c2e337a Mon Sep 17 00:00:00 2001 From: Craftplacer Date: Wed, 12 Aug 2020 06:38:05 +0200 Subject: [PATCH 063/320] Temporary changes --- .../Beatmaps/Formats/LegacyBeatmapEncoderTest.cs | 8 +++++++- osu.Game.Tests/Editing/LegacyEditorBeatmapPatcherTest.cs | 8 +++++++- osu.Game/Screens/Edit/EditorChangeHandler.cs | 8 +++++++- 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs index 30331e98d2..fba63f8539 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs @@ -10,6 +10,7 @@ using System.Text; using NUnit.Framework; using osu.Framework.Audio.Track; using osu.Framework.Graphics.Textures; +using osu.Framework.IO.Stores; using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Beatmaps.Formats; @@ -19,6 +20,7 @@ using osu.Game.Rulesets.Catch; using osu.Game.Rulesets.Mania; using osu.Game.Rulesets.Osu; using osu.Game.Rulesets.Taiko; +using osu.Game.Skinning; using osu.Game.Tests.Resources; namespace osu.Game.Tests.Beatmaps.Formats @@ -61,7 +63,11 @@ namespace osu.Game.Tests.Beatmaps.Formats var stream = new MemoryStream(); using (var writer = new StreamWriter(stream, Encoding.UTF8, 1024, true)) - new LegacyBeatmapEncoder(beatmap).Encode(writer); + using (var rs = new ResourceStore()) + { + var skin = new LegacyBeatmapSkin(beatmap.BeatmapInfo, rs, null); + new LegacyBeatmapEncoder(beatmap, skin).Encode(writer); + } stream.Position = 0; diff --git a/osu.Game.Tests/Editing/LegacyEditorBeatmapPatcherTest.cs b/osu.Game.Tests/Editing/LegacyEditorBeatmapPatcherTest.cs index ff17f23d50..74b6f66d85 100644 --- a/osu.Game.Tests/Editing/LegacyEditorBeatmapPatcherTest.cs +++ b/osu.Game.Tests/Editing/LegacyEditorBeatmapPatcherTest.cs @@ -4,6 +4,7 @@ using System.IO; using System.Text; using NUnit.Framework; +using osu.Framework.IO.Stores; using osu.Game.Audio; using osu.Game.Beatmaps; using osu.Game.Beatmaps.Formats; @@ -14,6 +15,7 @@ using osu.Game.Rulesets.Osu; using osu.Game.Rulesets.Osu.Beatmaps; using osu.Game.Rulesets.Osu.Objects; using osu.Game.Screens.Edit; +using osu.Game.Skinning; using osuTK; using Decoder = osu.Game.Beatmaps.Formats.Decoder; @@ -351,7 +353,11 @@ namespace osu.Game.Tests.Editing using (var encoded = new MemoryStream()) { using (var sw = new StreamWriter(encoded)) - new LegacyBeatmapEncoder(beatmap).Encode(sw); + using (var rs = new ResourceStore()) + { + var skin = new LegacyBeatmapSkin(beatmap.BeatmapInfo, rs, null); + new LegacyBeatmapEncoder(beatmap, skin).Encode(sw); + } return encoded.ToArray(); } diff --git a/osu.Game/Screens/Edit/EditorChangeHandler.cs b/osu.Game/Screens/Edit/EditorChangeHandler.cs index 1553c2d2ef..6393093c74 100644 --- a/osu.Game/Screens/Edit/EditorChangeHandler.cs +++ b/osu.Game/Screens/Edit/EditorChangeHandler.cs @@ -6,8 +6,10 @@ using System.Collections.Generic; using System.IO; using System.Text; using osu.Framework.Bindables; +using osu.Framework.IO.Stores; using osu.Game.Beatmaps.Formats; using osu.Game.Rulesets.Objects; +using osu.Game.Skinning; namespace osu.Game.Screens.Edit { @@ -85,7 +87,11 @@ namespace osu.Game.Screens.Edit using (var stream = new MemoryStream()) { using (var sw = new StreamWriter(stream, Encoding.UTF8, 1024, true)) - new LegacyBeatmapEncoder(editorBeatmap).Encode(sw); + using (var rs = new ResourceStore()) + { + var skin = new LegacyBeatmapSkin(editorBeatmap.BeatmapInfo, rs, null); + new LegacyBeatmapEncoder(editorBeatmap, skin).Encode(sw); + } savedStates.Add(stream.ToArray()); } From 45876bc55aca3d28034c8ba7d6b3ea5322708c23 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 12 Aug 2020 23:50:33 +0900 Subject: [PATCH 064/320] Fix reference to non-existent variable --- osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerRotation.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerRotation.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerRotation.cs index ab6cf60a79..3c559765d4 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerRotation.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerRotation.cs @@ -194,7 +194,7 @@ namespace osu.Game.Rulesets.Osu.Tests addSeekStep(0); - AddStep("adjust track rate", () => track.AddAdjustment(AdjustableProperty.Tempo, new BindableDouble(rate))); + AddStep("adjust track rate", () => MusicController.CurrentTrack.AddAdjustment(AdjustableProperty.Tempo, new BindableDouble(rate))); // autoplay replay frames use track time; // if a spin takes 1000ms in track time and we're playing with a 2x rate adjustment, the spin will take 500ms of *real* time. // therefore we need to apply the rate adjustment to the replay itself to change from track time to real time, From 91e28b849de0ed31402536b63069b8b2d5383f4b Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 13 Aug 2020 00:29:23 +0900 Subject: [PATCH 065/320] Fix incorrect BeatmapManager construction --- .../Visual/UserInterface/TestSceneDeleteLocalScore.cs | 3 ++- osu.Game/Beatmaps/BeatmapManager.cs | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneDeleteLocalScore.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneDeleteLocalScore.cs index eb4750a597..e54292f7cc 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneDeleteLocalScore.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneDeleteLocalScore.cs @@ -6,6 +6,7 @@ using System.Linq; using NUnit.Framework; using osu.Framework.Graphics; using osu.Framework.Allocation; +using osu.Framework.Audio; using osu.Framework.Graphics.Cursor; using osu.Framework.Platform; using osu.Framework.Testing; @@ -79,7 +80,7 @@ namespace osu.Game.Tests.Visual.UserInterface var dependencies = new DependencyContainer(base.CreateChildDependencies(parent)); dependencies.Cache(rulesetStore = new RulesetStore(ContextFactory)); - dependencies.Cache(beatmapManager = new BeatmapManager(LocalStorage, ContextFactory, rulesetStore, null, Audio, dependencies.Get(), Beatmap.Default)); + dependencies.Cache(beatmapManager = new BeatmapManager(LocalStorage, ContextFactory, rulesetStore, null, dependencies.Get(), dependencies.Get(), Beatmap.Default)); dependencies.Cache(scoreManager = new ScoreManager(rulesetStore, () => beatmapManager, LocalStorage, null, ContextFactory)); beatmap = beatmapManager.Import(TestResources.GetTestBeatmapForImport()).Result.Beatmaps[0]; diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index 6f01580998..0cadcf5947 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -9,6 +9,7 @@ using System.Linq.Expressions; using System.Text; using System.Threading; using System.Threading.Tasks; +using JetBrains.Annotations; using Microsoft.EntityFrameworkCore; using osu.Framework.Audio; using osu.Framework.Audio.Track; @@ -67,7 +68,7 @@ namespace osu.Game.Beatmaps private readonly TextureStore textureStore; private readonly ITrackStore trackStore; - public BeatmapManager(Storage storage, IDatabaseContextFactory contextFactory, RulesetStore rulesets, IAPIProvider api, AudioManager audioManager, GameHost host = null, + public BeatmapManager(Storage storage, IDatabaseContextFactory contextFactory, RulesetStore rulesets, IAPIProvider api, [NotNull] AudioManager audioManager, GameHost host = null, WorkingBeatmap defaultBeatmap = null) : base(storage, contextFactory, api, new BeatmapStore(contextFactory), host) { From 84cb36b6a8ee180552b41f48711b149d710cbaf6 Mon Sep 17 00:00:00 2001 From: Lucas A Date: Thu, 13 Aug 2020 10:57:18 +0200 Subject: [PATCH 066/320] Defer subscriptions for updateOverlayActivationMode() to OnEntering() --- osu.Game/Screens/Play/Player.cs | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 2ecddf0f23..6bb4be4096 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -212,11 +212,6 @@ namespace osu.Game.Screens.Play if (game != null) OverlayActivationMode.BindTo(game.OverlayActivationMode); - gameplayOverlaysDisabled.BindValueChanged(_ => updateOverlayActivationMode()); - DrawableRuleset.IsPaused.BindValueChanged(_ => updateOverlayActivationMode()); - DrawableRuleset.HasReplayLoaded.BindValueChanged(_ => updateOverlayActivationMode()); - breakTracker.IsBreakTime.BindValueChanged(_ => updateOverlayActivationMode()); - DrawableRuleset.HasReplayLoaded.BindValueChanged(_ => updatePauseOnFocusLostState(), true); // bind clock into components that require it @@ -363,9 +358,6 @@ namespace osu.Game.Screens.Play private void updateOverlayActivationMode() { - if (!this.IsCurrentScreen()) - return; - bool canTriggerOverlays = DrawableRuleset.IsPaused.Value || breakTracker.IsBreakTime.Value || !gameplayOverlaysDisabled.Value; if (DrawableRuleset.HasReplayLoaded.Value || canTriggerOverlays) @@ -661,7 +653,10 @@ namespace osu.Game.Screens.Play foreach (var mod in Mods.Value.OfType()) mod.ApplyToHUD(HUDOverlay); - updateOverlayActivationMode(); + DrawableRuleset.IsPaused.BindValueChanged(_ => updateOverlayActivationMode()); + DrawableRuleset.HasReplayLoaded.BindValueChanged(_ => updateOverlayActivationMode()); + breakTracker.IsBreakTime.BindValueChanged(_ => updateOverlayActivationMode()); + gameplayOverlaysDisabled.BindValueChanged(_ => updateOverlayActivationMode(), true); } public override void OnSuspending(IScreen next) From 74a8a4bca8dc7ee11a15e764e87c828bb9509668 Mon Sep 17 00:00:00 2001 From: Lucas A Date: Thu, 13 Aug 2020 21:53:17 +0200 Subject: [PATCH 067/320] Make testing code clearer to understand. --- .../Gameplay/TestSceneOverlayActivation.cs | 42 +++++++++---------- 1 file changed, 20 insertions(+), 22 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneOverlayActivation.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneOverlayActivation.cs index 7fd5158515..04c67433fa 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneOverlayActivation.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneOverlayActivation.cs @@ -11,56 +11,54 @@ namespace osu.Game.Tests.Visual.Gameplay { public class TestSceneOverlayActivation : OsuPlayerTestScene { - private OverlayTestPlayer testPlayer; - - public override void SetUpSteps() - { - AddStep("disable overlay activation during gameplay", () => LocalConfig.Set(OsuSetting.GameplayDisableOverlayActivation, true)); - base.SetUpSteps(); - } + protected new OverlayTestPlayer Player => base.Player as OverlayTestPlayer; [Test] public void TestGameplayOverlayActivation() { - AddAssert("activation mode is disabled", () => testPlayer.OverlayActivationMode == OverlayActivation.Disabled); + AddStep("disable overlay activation during gameplay", () => LocalConfig.Set(OsuSetting.GameplayDisableOverlayActivation, true)); + AddAssert("activation mode is disabled", () => Player.OverlayActivationMode == OverlayActivation.Disabled); } [Test] public void TestGameplayOverlayActivationDisabled() { AddStep("enable overlay activation during gameplay", () => LocalConfig.Set(OsuSetting.GameplayDisableOverlayActivation, false)); - AddAssert("activation mode is user triggered", () => testPlayer.OverlayActivationMode == OverlayActivation.UserTriggered); + AddAssert("activation mode is user triggered", () => Player.OverlayActivationMode == OverlayActivation.UserTriggered); } [Test] public void TestGameplayOverlayActivationPaused() { - AddUntilStep("activation mode is disabled", () => testPlayer.OverlayActivationMode == OverlayActivation.Disabled); - AddStep("pause gameplay", () => testPlayer.Pause()); - AddUntilStep("activation mode is user triggered", () => testPlayer.OverlayActivationMode == OverlayActivation.UserTriggered); + AddStep("disable overlay activation during gameplay", () => LocalConfig.Set(OsuSetting.GameplayDisableOverlayActivation, true)); + AddUntilStep("activation mode is disabled", () => Player.OverlayActivationMode == OverlayActivation.Disabled); + AddStep("pause gameplay", () => Player.Pause()); + AddUntilStep("activation mode is user triggered", () => Player.OverlayActivationMode == OverlayActivation.UserTriggered); } [Test] public void TestGameplayOverlayActivationReplayLoaded() { - AddAssert("activation mode is disabled", () => testPlayer.OverlayActivationMode == OverlayActivation.Disabled); - AddStep("load a replay", () => testPlayer.DrawableRuleset.HasReplayLoaded.Value = true); - AddAssert("activation mode is user triggered", () => testPlayer.OverlayActivationMode == OverlayActivation.UserTriggered); + AddStep("disable overlay activation during gameplay", () => LocalConfig.Set(OsuSetting.GameplayDisableOverlayActivation, true)); + AddAssert("activation mode is disabled", () => Player.OverlayActivationMode == OverlayActivation.Disabled); + AddStep("load a replay", () => Player.DrawableRuleset.HasReplayLoaded.Value = true); + AddAssert("activation mode is user triggered", () => Player.OverlayActivationMode == OverlayActivation.UserTriggered); } [Test] public void TestGameplayOverlayActivationBreaks() { - AddAssert("activation mode is disabled", () => testPlayer.OverlayActivationMode == OverlayActivation.Disabled); - AddStep("seek to break", () => testPlayer.GameplayClockContainer.Seek(Beatmap.Value.Beatmap.Breaks.First().StartTime)); - AddUntilStep("activation mode is user triggered", () => testPlayer.OverlayActivationMode == OverlayActivation.UserTriggered); - AddStep("seek to break end", () => testPlayer.GameplayClockContainer.Seek(Beatmap.Value.Beatmap.Breaks.First().EndTime)); - AddUntilStep("activation mode is disabled", () => testPlayer.OverlayActivationMode == OverlayActivation.Disabled); + AddStep("disable overlay activation during gameplay", () => LocalConfig.Set(OsuSetting.GameplayDisableOverlayActivation, true)); + AddAssert("activation mode is disabled", () => Player.OverlayActivationMode == OverlayActivation.Disabled); + AddStep("seek to break", () => Player.GameplayClockContainer.Seek(Beatmap.Value.Beatmap.Breaks.First().StartTime)); + AddUntilStep("activation mode is user triggered", () => Player.OverlayActivationMode == OverlayActivation.UserTriggered); + AddStep("seek to break end", () => Player.GameplayClockContainer.Seek(Beatmap.Value.Beatmap.Breaks.First().EndTime)); + AddUntilStep("activation mode is disabled", () => Player.OverlayActivationMode == OverlayActivation.Disabled); } - protected override TestPlayer CreatePlayer(Ruleset ruleset) => testPlayer = new OverlayTestPlayer(); + protected override TestPlayer CreatePlayer(Ruleset ruleset) => new OverlayTestPlayer(); - private class OverlayTestPlayer : TestPlayer + protected class OverlayTestPlayer : TestPlayer { public new OverlayActivation OverlayActivationMode => base.OverlayActivationMode.Value; } From c4a7fac760efde4622956f1fa3c581e469c8e508 Mon Sep 17 00:00:00 2001 From: Craftplacer Date: Sat, 15 Aug 2020 22:03:24 +0200 Subject: [PATCH 068/320] Add required parameters and other various changes --- .../Formats/LegacyBeatmapEncoderTest.cs | 30 ++++++++++++++----- .../Beatmaps/IO/ImportBeatmapTest.cs | 5 ++-- .../Editing/EditorChangeHandlerTest.cs | 6 ++-- .../Editing/LegacyEditorBeatmapPatcherTest.cs | 8 +---- osu.Game/Beatmaps/BeatmapManager.cs | 4 +-- .../Beatmaps/Formats/LegacyBeatmapEncoder.cs | 13 ++++---- osu.Game/Screens/Edit/Editor.cs | 7 +++-- osu.Game/Screens/Edit/EditorChangeHandler.cs | 11 +++---- 8 files changed, 51 insertions(+), 33 deletions(-) diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs index fba63f8539..38f730995e 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs @@ -28,13 +28,25 @@ namespace osu.Game.Tests.Beatmaps.Formats [TestFixture] public class LegacyBeatmapEncoderTest { - private static IEnumerable allBeatmaps => TestResources.GetStore().GetAvailableResources().Where(res => res.EndsWith(".osu")); + private static readonly DllResourceStore resource_store = TestResources.GetStore(); + + private static IEnumerable allBeatmaps = resource_store.GetAvailableResources().Where(res => res.EndsWith(".osu")); + + private static Stream beatmapSkinStream = resource_store.GetStream("skin.ini"); + + private ISkin skin; + + [SetUp] + public void Init() + { + skin = decodeSkinFromLegacy(beatmapSkinStream); + } [TestCaseSource(nameof(allBeatmaps))] public void TestEncodeDecodeStability(string name) { - var decoded = decodeFromLegacy(TestResources.GetStore().GetStream(name)); - var decodedAfterEncode = decodeFromLegacy(encodeToLegacy(decoded)); + var decoded = decodeBeatmapFromLegacy(TestResources.GetStore().GetStream(name)); + var decodedAfterEncode = decodeBeatmapFromLegacy(encodeToLegacy(decoded, skin)); sort(decoded); sort(decodedAfterEncode); @@ -52,20 +64,24 @@ namespace osu.Game.Tests.Beatmaps.Formats } } - private IBeatmap decodeFromLegacy(Stream stream) + private IBeatmap decodeBeatmapFromLegacy(Stream stream) { using (var reader = new LineBufferedReader(stream)) return convert(new LegacyBeatmapDecoder { ApplyOffsets = false }.Decode(reader)); } - private Stream encodeToLegacy(IBeatmap beatmap) + private ISkin decodeSkinFromLegacy(Stream stream) + { + using (var reader = new LineBufferedReader(stream)) + return new LegacySkin(SkinInfo.Default, resource_store, null); + } + + private Stream encodeToLegacy(IBeatmap beatmap, ISkin skin) { var stream = new MemoryStream(); using (var writer = new StreamWriter(stream, Encoding.UTF8, 1024, true)) - using (var rs = new ResourceStore()) { - var skin = new LegacyBeatmapSkin(beatmap.BeatmapInfo, rs, null); new LegacyBeatmapEncoder(beatmap, skin).Encode(writer); } diff --git a/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs b/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs index 0151678db3..17271184c0 100644 --- a/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs +++ b/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs @@ -730,7 +730,8 @@ namespace osu.Game.Tests.Beatmaps.IO BeatmapSetInfo setToUpdate = manager.GetAllUsableBeatmapSets()[0]; var beatmapInfo = setToUpdate.Beatmaps.First(b => b.RulesetID == 0); - Beatmap beatmapToUpdate = (Beatmap)manager.GetWorkingBeatmap(setToUpdate.Beatmaps.First(b => b.RulesetID == 0)).Beatmap; + var workingBeatmap = manager.GetWorkingBeatmap(setToUpdate.Beatmaps.First(b => b.RulesetID == 0)); + Beatmap beatmapToUpdate = (Beatmap)workingBeatmap.Beatmap; BeatmapSetFileInfo fileToUpdate = setToUpdate.Files.First(f => beatmapToUpdate.BeatmapInfo.Path.Contains(f.Filename)); string oldMd5Hash = beatmapToUpdate.BeatmapInfo.MD5Hash; @@ -738,7 +739,7 @@ namespace osu.Game.Tests.Beatmaps.IO beatmapToUpdate.HitObjects.Clear(); beatmapToUpdate.HitObjects.Add(new HitCircle { StartTime = 5000 }); - manager.Save(beatmapInfo, beatmapToUpdate); + manager.Save(beatmapInfo, beatmapToUpdate, workingBeatmap.Skin); // Check that the old file reference has been removed Assert.That(manager.QueryBeatmapSet(s => s.ID == setToUpdate.ID).Files.All(f => f.ID != fileToUpdate.ID)); diff --git a/osu.Game.Tests/Editing/EditorChangeHandlerTest.cs b/osu.Game.Tests/Editing/EditorChangeHandlerTest.cs index feda1ae0e9..6d708ce838 100644 --- a/osu.Game.Tests/Editing/EditorChangeHandlerTest.cs +++ b/osu.Game.Tests/Editing/EditorChangeHandlerTest.cs @@ -13,7 +13,7 @@ namespace osu.Game.Tests.Editing [Test] public void TestSaveRestoreState() { - var handler = new EditorChangeHandler(new EditorBeatmap(new Beatmap())); + var handler = new EditorChangeHandler(new EditorBeatmap(new Beatmap()), null); Assert.That(handler.CanUndo.Value, Is.False); Assert.That(handler.CanRedo.Value, Is.False); @@ -32,7 +32,7 @@ namespace osu.Game.Tests.Editing [Test] public void TestMaxStatesSaved() { - var handler = new EditorChangeHandler(new EditorBeatmap(new Beatmap())); + var handler = new EditorChangeHandler(new EditorBeatmap(new Beatmap()), null); Assert.That(handler.CanUndo.Value, Is.False); @@ -53,7 +53,7 @@ namespace osu.Game.Tests.Editing [Test] public void TestMaxStatesExceeded() { - var handler = new EditorChangeHandler(new EditorBeatmap(new Beatmap())); + var handler = new EditorChangeHandler(new EditorBeatmap(new Beatmap()), null); Assert.That(handler.CanUndo.Value, Is.False); diff --git a/osu.Game.Tests/Editing/LegacyEditorBeatmapPatcherTest.cs b/osu.Game.Tests/Editing/LegacyEditorBeatmapPatcherTest.cs index 74b6f66d85..b491157627 100644 --- a/osu.Game.Tests/Editing/LegacyEditorBeatmapPatcherTest.cs +++ b/osu.Game.Tests/Editing/LegacyEditorBeatmapPatcherTest.cs @@ -4,7 +4,6 @@ using System.IO; using System.Text; using NUnit.Framework; -using osu.Framework.IO.Stores; using osu.Game.Audio; using osu.Game.Beatmaps; using osu.Game.Beatmaps.Formats; @@ -15,7 +14,6 @@ using osu.Game.Rulesets.Osu; using osu.Game.Rulesets.Osu.Beatmaps; using osu.Game.Rulesets.Osu.Objects; using osu.Game.Screens.Edit; -using osu.Game.Skinning; using osuTK; using Decoder = osu.Game.Beatmaps.Formats.Decoder; @@ -353,11 +351,7 @@ namespace osu.Game.Tests.Editing using (var encoded = new MemoryStream()) { using (var sw = new StreamWriter(encoded)) - using (var rs = new ResourceStore()) - { - var skin = new LegacyBeatmapSkin(beatmap.BeatmapInfo, rs, null); - new LegacyBeatmapEncoder(beatmap, skin).Encode(sw); - } + new LegacyBeatmapEncoder(beatmap, null).Encode(sw); return encoded.ToArray(); } diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index 06acd4e9f2..bd757d30ca 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -195,7 +195,8 @@ namespace osu.Game.Beatmaps /// /// The to save the content against. The file referenced by will be replaced. /// The content to write. - public void Save(BeatmapInfo info, IBeatmap beatmapContent) + /// Optional beatmap skin for inline skin configuration in beatmap files. + public void Save(BeatmapInfo info, IBeatmap beatmapContent, ISkin skin) { var setInfo = QueryBeatmapSet(s => s.Beatmaps.Any(b => b.ID == info.ID)); @@ -203,7 +204,6 @@ namespace osu.Game.Beatmaps { using (var sw = new StreamWriter(stream, Encoding.UTF8, 1024, true)) { - var skin = new LegacyBeatmapSkin(info, Files.Store, audioManager); new LegacyBeatmapEncoder(beatmapContent, skin).Encode(sw); } diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs index eb148794de..716f1bc814 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs @@ -24,14 +24,14 @@ namespace osu.Game.Beatmaps.Formats public const int LATEST_VERSION = 128; private readonly IBeatmap beatmap; - private readonly LegacyBeatmapSkin beatmapSkin; + private readonly ISkin skin; /// The beatmap to encode - /// An optional beatmap skin, for encoding the beatmap's combo colours. - public LegacyBeatmapEncoder(IBeatmap beatmap, [CanBeNull] LegacyBeatmapSkin beatmapSkin) + /// An optional skin, for encoding the beatmap's combo colours. This will only work if the parameter is a type of . + public LegacyBeatmapEncoder(IBeatmap beatmap, [CanBeNull] ISkin skin) { this.beatmap = beatmap; - this.beatmapSkin = beatmapSkin; + this.skin = skin; if (beatmap.BeatmapInfo.RulesetID < 0 || beatmap.BeatmapInfo.RulesetID > 3) throw new ArgumentException("Only beatmaps in the osu, taiko, catch, or mania rulesets can be encoded to the legacy beatmap format.", nameof(beatmap)); @@ -207,7 +207,10 @@ namespace osu.Game.Beatmaps.Formats private void handleComboColours(TextWriter writer) { - var colours = beatmapSkin?.Configuration.ComboColours; + if (!(skin is LegacyBeatmapSkin legacySkin)) + return; + + var colours = legacySkin?.Configuration.ComboColours; if (colours == null || colours.Count == 0) return; diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index d92f3922c3..d52d832bf3 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -33,6 +33,7 @@ using osu.Game.Screens.Edit.Compose; using osu.Game.Screens.Edit.Setup; using osu.Game.Screens.Edit.Timing; using osu.Game.Screens.Play; +using osu.Game.Skinning; using osu.Game.Users; namespace osu.Game.Screens.Edit @@ -64,6 +65,7 @@ namespace osu.Game.Screens.Edit private IBeatmap playableBeatmap; private EditorBeatmap editorBeatmap; private EditorChangeHandler changeHandler; + private ISkin beatmapSkin; private DependencyContainer dependencies; @@ -92,6 +94,7 @@ namespace osu.Game.Screens.Edit try { playableBeatmap = Beatmap.Value.GetPlayableBeatmap(Beatmap.Value.BeatmapInfo.Ruleset); + beatmapSkin = Beatmap.Value.Skin; } catch (Exception e) { @@ -104,7 +107,7 @@ namespace osu.Game.Screens.Edit AddInternal(editorBeatmap = new EditorBeatmap(playableBeatmap)); dependencies.CacheAs(editorBeatmap); - changeHandler = new EditorChangeHandler(editorBeatmap); + changeHandler = new EditorChangeHandler(editorBeatmap, beatmapSkin); dependencies.CacheAs(changeHandler); EditorMenuBar menuBar; @@ -399,7 +402,7 @@ namespace osu.Game.Screens.Edit clock.SeekForward(!clock.IsRunning, amount); } - private void saveBeatmap() => beatmapManager.Save(playableBeatmap.BeatmapInfo, editorBeatmap); + private void saveBeatmap() => beatmapManager.Save(playableBeatmap.BeatmapInfo, editorBeatmap, Beatmap.Value.Skin); private void exportBeatmap() { diff --git a/osu.Game/Screens/Edit/EditorChangeHandler.cs b/osu.Game/Screens/Edit/EditorChangeHandler.cs index 6393093c74..f305d2a15d 100644 --- a/osu.Game/Screens/Edit/EditorChangeHandler.cs +++ b/osu.Game/Screens/Edit/EditorChangeHandler.cs @@ -6,7 +6,6 @@ using System.Collections.Generic; using System.IO; using System.Text; using osu.Framework.Bindables; -using osu.Framework.IO.Stores; using osu.Game.Beatmaps.Formats; using osu.Game.Rulesets.Objects; using osu.Game.Skinning; @@ -27,6 +26,7 @@ namespace osu.Game.Screens.Edit private int currentState = -1; private readonly EditorBeatmap editorBeatmap; + private readonly ISkin beatmapSkin; private int bulkChangesStarted; private bool isRestoring; @@ -36,7 +36,8 @@ namespace osu.Game.Screens.Edit /// Creates a new . /// /// The to track the s of. - public EditorChangeHandler(EditorBeatmap editorBeatmap) + /// The skin to track the inline skin configuration of. + public EditorChangeHandler(EditorBeatmap editorBeatmap, ISkin beatmapSkin) { this.editorBeatmap = editorBeatmap; @@ -46,6 +47,8 @@ namespace osu.Game.Screens.Edit patcher = new LegacyEditorBeatmapPatcher(editorBeatmap); + this.beatmapSkin = beatmapSkin; + // Initial state. SaveState(); } @@ -87,10 +90,8 @@ namespace osu.Game.Screens.Edit using (var stream = new MemoryStream()) { using (var sw = new StreamWriter(stream, Encoding.UTF8, 1024, true)) - using (var rs = new ResourceStore()) { - var skin = new LegacyBeatmapSkin(editorBeatmap.BeatmapInfo, rs, null); - new LegacyBeatmapEncoder(editorBeatmap, skin).Encode(sw); + new LegacyBeatmapEncoder(editorBeatmap, beatmapSkin).Encode(sw); } savedStates.Add(stream.ToArray()); From 0e8411f76c156110fb7e693292d5649dd2d17265 Mon Sep 17 00:00:00 2001 From: Craftplacer Date: Sat, 15 Aug 2020 22:06:26 +0200 Subject: [PATCH 069/320] Rename fields and make readonly --- .../Beatmaps/Formats/LegacyBeatmapEncoderTest.cs | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs index 38f730995e..63fdf2a8ae 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs @@ -32,14 +32,13 @@ namespace osu.Game.Tests.Beatmaps.Formats private static IEnumerable allBeatmaps = resource_store.GetAvailableResources().Where(res => res.EndsWith(".osu")); - private static Stream beatmapSkinStream = resource_store.GetStream("skin.ini"); - + private static readonly Stream beatmap_skin_stream = resource_store.GetStream("skin.ini"); private ISkin skin; [SetUp] public void Init() { - skin = decodeSkinFromLegacy(beatmapSkinStream); + skin = decodeSkinFromLegacy(beatmap_skin_stream); } [TestCaseSource(nameof(allBeatmaps))] @@ -76,14 +75,12 @@ namespace osu.Game.Tests.Beatmaps.Formats return new LegacySkin(SkinInfo.Default, resource_store, null); } - private Stream encodeToLegacy(IBeatmap beatmap, ISkin skin) + private Stream encodeToLegacy(IBeatmap beatmap, ISkin beatmapSkin) { var stream = new MemoryStream(); using (var writer = new StreamWriter(stream, Encoding.UTF8, 1024, true)) - { - new LegacyBeatmapEncoder(beatmap, skin).Encode(writer); - } + new LegacyBeatmapEncoder(beatmap, beatmapSkin).Encode(writer); stream.Position = 0; From 3a6e378a08ce5fde5b23ee302f48ba4afdf4f113 Mon Sep 17 00:00:00 2001 From: Craftplacer Date: Sat, 15 Aug 2020 23:41:53 +0200 Subject: [PATCH 070/320] Change skin testing --- .../Formats/LegacyBeatmapEncoderTest.cs | 48 ++++++++++--------- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs index 63fdf2a8ae..6ede30d7d8 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs @@ -32,25 +32,28 @@ namespace osu.Game.Tests.Beatmaps.Formats private static IEnumerable allBeatmaps = resource_store.GetAvailableResources().Where(res => res.EndsWith(".osu")); - private static readonly Stream beatmap_skin_stream = resource_store.GetStream("skin.ini"); - private ISkin skin; - - [SetUp] - public void Init() - { - skin = decodeSkinFromLegacy(beatmap_skin_stream); - } - [TestCaseSource(nameof(allBeatmaps))] public void TestEncodeDecodeStability(string name) { - var decoded = decodeBeatmapFromLegacy(TestResources.GetStore().GetStream(name)); - var decodedAfterEncode = decodeBeatmapFromLegacy(encodeToLegacy(decoded, skin)); + var decoded = decodeFromLegacy(TestResources.GetStore().GetStream(name)); + var decodedAfterEncode = decodeFromLegacy(encodeToLegacy(decoded)); - sort(decoded); - sort(decodedAfterEncode); + sort(decoded.beatmap); + sort(decodedAfterEncode.beatmap); - Assert.That(decodedAfterEncode.Serialize(), Is.EqualTo(decoded.Serialize())); + Assert.That(decodedAfterEncode.beatmap.Serialize(), Is.EqualTo(decoded.beatmap.Serialize())); + + areSkinsEqual(decoded.beatmapSkin, decodedAfterEncode.beatmapSkin); + } + + private void areSkinsEqual(LegacySkin expected, LegacySkin actual) + { + var expectedColours = expected.Configuration.ComboColours; + var actualColours = actual.Configuration.ComboColours; + + Assert.AreEqual(expectedColours.Count, actualColours.Count); + for (int i = 0; i < expectedColours.Count; i++) + Assert.AreEqual(expectedColours[i], actualColours[i]); } private void sort(IBeatmap beatmap) @@ -63,20 +66,19 @@ namespace osu.Game.Tests.Beatmaps.Formats } } - private IBeatmap decodeBeatmapFromLegacy(Stream stream) + private (IBeatmap beatmap, LegacyBeatmapSkin beatmapSkin) decodeFromLegacy(Stream stream) { using (var reader = new LineBufferedReader(stream)) - return convert(new LegacyBeatmapDecoder { ApplyOffsets = false }.Decode(reader)); + { + var beatmap = new LegacyBeatmapDecoder { ApplyOffsets = false }.Decode(reader); + var beatmapSkin = new LegacyBeatmapSkin(beatmap.BeatmapInfo, resource_store, null); + return (convert(beatmap), beatmapSkin); + } } - private ISkin decodeSkinFromLegacy(Stream stream) - { - using (var reader = new LineBufferedReader(stream)) - return new LegacySkin(SkinInfo.Default, resource_store, null); - } - - private Stream encodeToLegacy(IBeatmap beatmap, ISkin beatmapSkin) + private Stream encodeToLegacy((IBeatmap beatmap, LegacyBeatmapSkin beatmapSkin) fullBeatmap) { + var (beatmap, beatmapSkin) = fullBeatmap; var stream = new MemoryStream(); using (var writer = new StreamWriter(stream, Encoding.UTF8, 1024, true)) From 48bdbb0cfbd9f94b8d9b4182290a1dec66c7c256 Mon Sep 17 00:00:00 2001 From: Craftplacer Date: Sat, 15 Aug 2020 23:46:10 +0200 Subject: [PATCH 071/320] Use existing field in Editor --- osu.Game/Screens/Edit/Editor.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index d52d832bf3..a585db1ee9 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -402,7 +402,7 @@ namespace osu.Game.Screens.Edit clock.SeekForward(!clock.IsRunning, amount); } - private void saveBeatmap() => beatmapManager.Save(playableBeatmap.BeatmapInfo, editorBeatmap, Beatmap.Value.Skin); + private void saveBeatmap() => beatmapManager.Save(playableBeatmap.BeatmapInfo, editorBeatmap, beatmapSkin); private void exportBeatmap() { From 434354c44c2ab3f0bde6d0d04ade551b0a4d00ac Mon Sep 17 00:00:00 2001 From: Craftplacer Date: Sun, 16 Aug 2020 00:21:26 +0200 Subject: [PATCH 072/320] Properly implement SkinConfiguration equality --- .../Beatmaps/Formats/LegacyBeatmapEncoderTest.cs | 13 +------------ osu.Game/Skinning/SkinConfiguration.cs | 12 +++++++++++- 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs index 6ede30d7d8..66b39648e5 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs @@ -42,18 +42,7 @@ namespace osu.Game.Tests.Beatmaps.Formats sort(decodedAfterEncode.beatmap); Assert.That(decodedAfterEncode.beatmap.Serialize(), Is.EqualTo(decoded.beatmap.Serialize())); - - areSkinsEqual(decoded.beatmapSkin, decodedAfterEncode.beatmapSkin); - } - - private void areSkinsEqual(LegacySkin expected, LegacySkin actual) - { - var expectedColours = expected.Configuration.ComboColours; - var actualColours = actual.Configuration.ComboColours; - - Assert.AreEqual(expectedColours.Count, actualColours.Count); - for (int i = 0; i < expectedColours.Count; i++) - Assert.AreEqual(expectedColours[i], actualColours[i]); + Assert.IsTrue(decoded.beatmapSkin.Configuration.Equals(decodedAfterEncode.beatmapSkin.Configuration)); } private void sort(IBeatmap beatmap) diff --git a/osu.Game/Skinning/SkinConfiguration.cs b/osu.Game/Skinning/SkinConfiguration.cs index a55870aa6d..4b29111504 100644 --- a/osu.Game/Skinning/SkinConfiguration.cs +++ b/osu.Game/Skinning/SkinConfiguration.cs @@ -1,7 +1,9 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System; using System.Collections.Generic; +using System.Linq; using osu.Game.Beatmaps.Formats; using osuTK.Graphics; @@ -10,7 +12,7 @@ namespace osu.Game.Skinning /// /// An empty skin configuration. /// - public class SkinConfiguration : IHasComboColours, IHasCustomColours + public class SkinConfiguration : IHasComboColours, IHasCustomColours, IEquatable { public readonly SkinInfo SkinInfo = new SkinInfo(); @@ -48,5 +50,13 @@ namespace osu.Game.Skinning public Dictionary CustomColours { get; set; } = new Dictionary(); public readonly Dictionary ConfigDictionary = new Dictionary(); + + public bool Equals(SkinConfiguration other) + { + return other != null && + ConfigDictionary.SequenceEqual(other.ConfigDictionary) && + ComboColours.SequenceEqual(other.ComboColours) && + CustomColours.SequenceEqual(other.CustomColours); + } } } From cfd82104dbe5f23b9a92f2129441f8a328bc80a1 Mon Sep 17 00:00:00 2001 From: Craftplacer Date: Sun, 16 Aug 2020 01:00:28 +0200 Subject: [PATCH 073/320] Minor changes and improvements --- osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs | 4 ++-- osu.Game/Screens/Edit/EditorChangeHandler.cs | 2 -- osu.Game/Skinning/SkinConfiguration.cs | 2 +- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs index 66b39648e5..db18f9b444 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs @@ -55,7 +55,7 @@ namespace osu.Game.Tests.Beatmaps.Formats } } - private (IBeatmap beatmap, LegacyBeatmapSkin beatmapSkin) decodeFromLegacy(Stream stream) + private (IBeatmap beatmap, LegacySkin beatmapSkin) decodeFromLegacy(Stream stream) { using (var reader = new LineBufferedReader(stream)) { @@ -65,7 +65,7 @@ namespace osu.Game.Tests.Beatmaps.Formats } } - private Stream encodeToLegacy((IBeatmap beatmap, LegacyBeatmapSkin beatmapSkin) fullBeatmap) + private Stream encodeToLegacy((IBeatmap beatmap, LegacySkin beatmapSkin) fullBeatmap) { var (beatmap, beatmapSkin) = fullBeatmap; var stream = new MemoryStream(); diff --git a/osu.Game/Screens/Edit/EditorChangeHandler.cs b/osu.Game/Screens/Edit/EditorChangeHandler.cs index f305d2a15d..0489236d45 100644 --- a/osu.Game/Screens/Edit/EditorChangeHandler.cs +++ b/osu.Game/Screens/Edit/EditorChangeHandler.cs @@ -90,9 +90,7 @@ namespace osu.Game.Screens.Edit using (var stream = new MemoryStream()) { using (var sw = new StreamWriter(stream, Encoding.UTF8, 1024, true)) - { new LegacyBeatmapEncoder(editorBeatmap, beatmapSkin).Encode(sw); - } savedStates.Add(stream.ToArray()); } diff --git a/osu.Game/Skinning/SkinConfiguration.cs b/osu.Game/Skinning/SkinConfiguration.cs index 4b29111504..a48d713771 100644 --- a/osu.Game/Skinning/SkinConfiguration.cs +++ b/osu.Game/Skinning/SkinConfiguration.cs @@ -56,7 +56,7 @@ namespace osu.Game.Skinning return other != null && ConfigDictionary.SequenceEqual(other.ConfigDictionary) && ComboColours.SequenceEqual(other.ComboColours) && - CustomColours.SequenceEqual(other.CustomColours); + CustomColours?.SequenceEqual(other.CustomColours) == true; } } } From a6708c4286d3973c8ed68be43176228da1137237 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 16 Aug 2020 23:04:49 +0900 Subject: [PATCH 074/320] Rename resolved variable in MainMenu --- osu.Game/Screens/Menu/MainMenu.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/osu.Game/Screens/Menu/MainMenu.cs b/osu.Game/Screens/Menu/MainMenu.cs index 470e8ca9a6..fac9e9eb49 100644 --- a/osu.Game/Screens/Menu/MainMenu.cs +++ b/osu.Game/Screens/Menu/MainMenu.cs @@ -46,7 +46,7 @@ namespace osu.Game.Screens.Menu private GameHost host { get; set; } [Resolved] - private MusicController music { get; set; } + private MusicController musicController { get; set; } [Resolved(canBeNull: true)] private LoginOverlay login { get; set; } @@ -176,12 +176,12 @@ namespace osu.Game.Screens.Menu var metadata = Beatmap.Value.Metadata; - if (last is IntroScreen && music.TrackLoaded) + if (last is IntroScreen && musicController.TrackLoaded) { - if (!music.CurrentTrack.IsRunning) + if (!musicController.CurrentTrack.IsRunning) { - music.CurrentTrack.Seek(metadata.PreviewTime != -1 ? metadata.PreviewTime : 0.4f * music.CurrentTrack.Length); - music.CurrentTrack.Start(); + musicController.CurrentTrack.Seek(metadata.PreviewTime != -1 ? metadata.PreviewTime : 0.4f * musicController.CurrentTrack.Length); + musicController.CurrentTrack.Start(); } } @@ -256,7 +256,7 @@ namespace osu.Game.Screens.Menu // we may have consumed our preloaded instance, so let's make another. preloadSongSelect(); - music.EnsurePlayingSomething(); + musicController.EnsurePlayingSomething(); } public override bool OnExiting(IScreen next) From 589d4eeb5297a046b7001cb7c55a2e9b5c3ea824 Mon Sep 17 00:00:00 2001 From: Lucas A Date: Sun, 16 Aug 2020 17:18:40 +0200 Subject: [PATCH 075/320] Remove setting. --- .../Visual/Gameplay/TestSceneOverlayActivation.cs | 12 ------------ osu.Game/Configuration/OsuConfigManager.cs | 2 -- .../Settings/Sections/Gameplay/GeneralSettings.cs | 5 ----- osu.Game/Screens/Play/Player.cs | 14 ++++++-------- 4 files changed, 6 insertions(+), 27 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneOverlayActivation.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneOverlayActivation.cs index 04c67433fa..3ee0f4e720 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneOverlayActivation.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneOverlayActivation.cs @@ -3,7 +3,6 @@ using System.Linq; using NUnit.Framework; -using osu.Game.Configuration; using osu.Game.Overlays; using osu.Game.Rulesets; @@ -16,21 +15,12 @@ namespace osu.Game.Tests.Visual.Gameplay [Test] public void TestGameplayOverlayActivation() { - AddStep("disable overlay activation during gameplay", () => LocalConfig.Set(OsuSetting.GameplayDisableOverlayActivation, true)); AddAssert("activation mode is disabled", () => Player.OverlayActivationMode == OverlayActivation.Disabled); } - [Test] - public void TestGameplayOverlayActivationDisabled() - { - AddStep("enable overlay activation during gameplay", () => LocalConfig.Set(OsuSetting.GameplayDisableOverlayActivation, false)); - AddAssert("activation mode is user triggered", () => Player.OverlayActivationMode == OverlayActivation.UserTriggered); - } - [Test] public void TestGameplayOverlayActivationPaused() { - AddStep("disable overlay activation during gameplay", () => LocalConfig.Set(OsuSetting.GameplayDisableOverlayActivation, true)); AddUntilStep("activation mode is disabled", () => Player.OverlayActivationMode == OverlayActivation.Disabled); AddStep("pause gameplay", () => Player.Pause()); AddUntilStep("activation mode is user triggered", () => Player.OverlayActivationMode == OverlayActivation.UserTriggered); @@ -39,7 +29,6 @@ namespace osu.Game.Tests.Visual.Gameplay [Test] public void TestGameplayOverlayActivationReplayLoaded() { - AddStep("disable overlay activation during gameplay", () => LocalConfig.Set(OsuSetting.GameplayDisableOverlayActivation, true)); AddAssert("activation mode is disabled", () => Player.OverlayActivationMode == OverlayActivation.Disabled); AddStep("load a replay", () => Player.DrawableRuleset.HasReplayLoaded.Value = true); AddAssert("activation mode is user triggered", () => Player.OverlayActivationMode == OverlayActivation.UserTriggered); @@ -48,7 +37,6 @@ namespace osu.Game.Tests.Visual.Gameplay [Test] public void TestGameplayOverlayActivationBreaks() { - AddStep("disable overlay activation during gameplay", () => LocalConfig.Set(OsuSetting.GameplayDisableOverlayActivation, true)); AddAssert("activation mode is disabled", () => Player.OverlayActivationMode == OverlayActivation.Disabled); AddStep("seek to break", () => Player.GameplayClockContainer.Seek(Beatmap.Value.Beatmap.Breaks.First().StartTime)); AddUntilStep("activation mode is user triggered", () => Player.OverlayActivationMode == OverlayActivation.UserTriggered); diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs index 44c0fbde82..d49c78183e 100644 --- a/osu.Game/Configuration/OsuConfigManager.cs +++ b/osu.Game/Configuration/OsuConfigManager.cs @@ -100,7 +100,6 @@ namespace osu.Game.Configuration Set(OsuSetting.IncreaseFirstObjectVisibility, true); Set(OsuSetting.GameplayDisableWinKey, true); - Set(OsuSetting.GameplayDisableOverlayActivation, true); // Update Set(OsuSetting.ReleaseStream, ReleaseStream.Lazer); @@ -233,6 +232,5 @@ namespace osu.Game.Configuration HitLighting, MenuBackgroundSource, GameplayDisableWinKey, - GameplayDisableOverlayActivation } } diff --git a/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs b/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs index c2e668fe68..0149e6c3a6 100644 --- a/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs @@ -77,11 +77,6 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay { LabelText = "Score display mode", Bindable = config.GetBindable(OsuSetting.ScoreDisplayMode) - }, - new SettingsCheckbox - { - LabelText = "Disable overlays during gameplay", - Bindable = config.GetBindable(OsuSetting.GameplayDisableOverlayActivation) } }; diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 6bb4be4096..17838e0502 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -69,8 +69,6 @@ namespace osu.Game.Screens.Play private Bindable mouseWheelDisabled; - private Bindable gameplayOverlaysDisabled; - private readonly Bindable storyboardReplacesBackground = new Bindable(); public int RestartCount; @@ -176,7 +174,6 @@ namespace osu.Game.Screens.Play sampleRestart = audio.Samples.Get(@"Gameplay/restart"); mouseWheelDisabled = config.GetBindable(OsuSetting.MouseDisableWheel); - gameplayOverlaysDisabled = config.GetBindable(OsuSetting.GameplayDisableOverlayActivation); DrawableRuleset = ruleset.CreateDrawableRulesetWith(playableBeatmap, Mods.Value); @@ -212,6 +209,10 @@ namespace osu.Game.Screens.Play if (game != null) OverlayActivationMode.BindTo(game.OverlayActivationMode); + DrawableRuleset.IsPaused.BindValueChanged(_ => updateOverlayActivationMode()); + DrawableRuleset.HasReplayLoaded.BindValueChanged(_ => updateOverlayActivationMode()); + breakTracker.IsBreakTime.BindValueChanged(_ => updateOverlayActivationMode()); + DrawableRuleset.HasReplayLoaded.BindValueChanged(_ => updatePauseOnFocusLostState(), true); // bind clock into components that require it @@ -358,7 +359,7 @@ namespace osu.Game.Screens.Play private void updateOverlayActivationMode() { - bool canTriggerOverlays = DrawableRuleset.IsPaused.Value || breakTracker.IsBreakTime.Value || !gameplayOverlaysDisabled.Value; + bool canTriggerOverlays = DrawableRuleset.IsPaused.Value || breakTracker.IsBreakTime.Value; if (DrawableRuleset.HasReplayLoaded.Value || canTriggerOverlays) OverlayActivationMode.Value = OverlayActivation.UserTriggered; @@ -653,10 +654,7 @@ namespace osu.Game.Screens.Play foreach (var mod in Mods.Value.OfType()) mod.ApplyToHUD(HUDOverlay); - DrawableRuleset.IsPaused.BindValueChanged(_ => updateOverlayActivationMode()); - DrawableRuleset.HasReplayLoaded.BindValueChanged(_ => updateOverlayActivationMode()); - breakTracker.IsBreakTime.BindValueChanged(_ => updateOverlayActivationMode()); - gameplayOverlaysDisabled.BindValueChanged(_ => updateOverlayActivationMode(), true); + updateOverlayActivationMode(); } public override void OnSuspending(IScreen next) From d9debef1568a393f0da721759d09206ffe5c3701 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 17 Aug 2020 15:38:16 +0900 Subject: [PATCH 076/320] Add explicit LoadTrack method --- .../TestSceneGameplayClockContainer.cs | 4 +++- .../Gameplay/TestSceneStoryboardSamples.cs | 5 ++-- .../Visual/Gameplay/TestSceneSkipOverlay.cs | 3 ++- osu.Game/Beatmaps/IWorkingBeatmap.cs | 2 +- osu.Game/Beatmaps/WorkingBeatmap.cs | 23 ++++++++++++++++++- osu.Game/Overlays/MusicController.cs | 2 +- osu.Game/Screens/Edit/EditorClock.cs | 2 +- osu.Game/Screens/Menu/IntroScreen.cs | 2 +- .../Screens/Play/GameplayClockContainer.cs | 4 ++-- osu.Game/Screens/Play/Player.cs | 2 +- 10 files changed, 37 insertions(+), 12 deletions(-) diff --git a/osu.Game.Tests/Gameplay/TestSceneGameplayClockContainer.cs b/osu.Game.Tests/Gameplay/TestSceneGameplayClockContainer.cs index bb60ae73db..dc9f540907 100644 --- a/osu.Game.Tests/Gameplay/TestSceneGameplayClockContainer.cs +++ b/osu.Game.Tests/Gameplay/TestSceneGameplayClockContainer.cs @@ -22,7 +22,9 @@ namespace osu.Game.Tests.Gameplay AddStep("create container", () => { var working = CreateWorkingBeatmap(new OsuRuleset().RulesetInfo); - Add(gcc = new GameplayClockContainer(working.GetTrack(), working, Array.Empty(), 0)); + working.LoadTrack(); + + Add(gcc = new GameplayClockContainer(working, Array.Empty(), 0)); }); AddStep("start track", () => gcc.Start()); diff --git a/osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs b/osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs index 360e7eccdc..6f788a070e 100644 --- a/osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs +++ b/osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs @@ -60,8 +60,9 @@ namespace osu.Game.Tests.Gameplay AddStep("create container", () => { var working = CreateWorkingBeatmap(new OsuRuleset().RulesetInfo); + working.LoadTrack(); - Add(gameplayContainer = new GameplayClockContainer(working.GetTrack(), working, Array.Empty(), 0)); + Add(gameplayContainer = new GameplayClockContainer(working, Array.Empty(), 0)); gameplayContainer.Add(sample = new DrawableStoryboardSample(new StoryboardSampleInfo(string.Empty, 0, 1)) { @@ -105,7 +106,7 @@ namespace osu.Game.Tests.Gameplay Beatmap.Value = new TestCustomSkinWorkingBeatmap(new OsuRuleset().RulesetInfo, Audio); SelectedMods.Value = new[] { testedMod }; - Add(gameplayContainer = new GameplayClockContainer(MusicController.CurrentTrack, Beatmap.Value, SelectedMods.Value, 0)); + Add(gameplayContainer = new GameplayClockContainer(Beatmap.Value, SelectedMods.Value, 0)); gameplayContainer.Add(sample = new TestDrawableStoryboardSample(new StoryboardSampleInfo("test-sample", 1, 1)) { diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSkipOverlay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSkipOverlay.cs index 58fd760fc3..c7e5e2a7ec 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSkipOverlay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSkipOverlay.cs @@ -33,8 +33,9 @@ namespace osu.Game.Tests.Visual.Gameplay increment = skip_time; var working = CreateWorkingBeatmap(CreateBeatmap(new OsuRuleset().RulesetInfo)); + working.LoadTrack(); - Child = gameplayClockContainer = new GameplayClockContainer(working.GetTrack(), working, Array.Empty(), 0) + Child = gameplayClockContainer = new GameplayClockContainer(working, Array.Empty(), 0) { RelativeSizeAxes = Axes.Both, Children = new Drawable[] diff --git a/osu.Game/Beatmaps/IWorkingBeatmap.cs b/osu.Game/Beatmaps/IWorkingBeatmap.cs index e020625b99..88d73fd7c4 100644 --- a/osu.Game/Beatmaps/IWorkingBeatmap.cs +++ b/osu.Game/Beatmaps/IWorkingBeatmap.cs @@ -58,6 +58,6 @@ namespace osu.Game.Beatmaps /// /// Retrieves the which this provides. /// - Track GetTrack(); + Track LoadTrack(); } } diff --git a/osu.Game/Beatmaps/WorkingBeatmap.cs b/osu.Game/Beatmaps/WorkingBeatmap.cs index bec2679103..b4046a4e95 100644 --- a/osu.Game/Beatmaps/WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/WorkingBeatmap.cs @@ -250,8 +250,29 @@ namespace osu.Game.Beatmaps protected abstract Texture GetBackground(); private readonly RecyclableLazy background; + private Track loadedTrack; + + /// + /// Load a new audio track instance for this beatmap. + /// + /// A fresh track instance, which will also be available via . [NotNull] - public Track GetTrack() => GetBeatmapTrack() ?? GetVirtualTrack(1000); + public Track LoadTrack() => loadedTrack = GetBeatmapTrack() ?? GetVirtualTrack(1000); + + /// + /// Get the loaded audio track instance. must have first been called. + /// This generally happens via MusicController when changing the global beatmap. + /// + public Track Track + { + get + { + if (loadedTrack == null) + throw new InvalidOperationException($"Cannot access {nameof(Track)} without first calling {nameof(LoadTrack)}."); + + return loadedTrack; + } + } protected abstract Track GetBeatmapTrack(); diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index c18b564b4f..8bbae33811 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -319,7 +319,7 @@ namespace osu.Game.Overlays { var lastTrack = CurrentTrack; - var newTrack = new DrawableTrack(current.GetTrack()); + var newTrack = new DrawableTrack(current.LoadTrack()); newTrack.Completed += () => onTrackCompleted(current); CurrentTrack = newTrack; diff --git a/osu.Game/Screens/Edit/EditorClock.cs b/osu.Game/Screens/Edit/EditorClock.cs index d0e265adb0..634a6f7e25 100644 --- a/osu.Game/Screens/Edit/EditorClock.cs +++ b/osu.Game/Screens/Edit/EditorClock.cs @@ -26,7 +26,7 @@ namespace osu.Game.Screens.Edit private readonly DecoupleableInterpolatingFramedClock underlyingClock; public EditorClock(WorkingBeatmap beatmap, BindableBeatDivisor beatDivisor) - : this(beatmap.Beatmap.ControlPointInfo, beatmap.GetTrack().Length, beatDivisor) + : this(beatmap.Beatmap.ControlPointInfo, beatmap.Track.Length, beatDivisor) { } diff --git a/osu.Game/Screens/Menu/IntroScreen.cs b/osu.Game/Screens/Menu/IntroScreen.cs index 389629445c..3e4320ae44 100644 --- a/osu.Game/Screens/Menu/IntroScreen.cs +++ b/osu.Game/Screens/Menu/IntroScreen.cs @@ -115,7 +115,7 @@ namespace osu.Game.Screens.Menu if (setInfo != null) { initialBeatmap = beatmaps.GetWorkingBeatmap(setInfo.Beatmaps[0]); - UsingThemedIntro = !initialBeatmap.GetTrack().IsDummyDevice; + UsingThemedIntro = !initialBeatmap.LoadTrack().IsDummyDevice; } return UsingThemedIntro; diff --git a/osu.Game/Screens/Play/GameplayClockContainer.cs b/osu.Game/Screens/Play/GameplayClockContainer.cs index f0bbcf957a..50a7331e4f 100644 --- a/osu.Game/Screens/Play/GameplayClockContainer.cs +++ b/osu.Game/Screens/Play/GameplayClockContainer.cs @@ -62,12 +62,12 @@ namespace osu.Game.Screens.Play private readonly FramedOffsetClock platformOffsetClock; - public GameplayClockContainer([NotNull] ITrack track, WorkingBeatmap beatmap, IReadOnlyList mods, double gameplayStartTime) + public GameplayClockContainer(WorkingBeatmap beatmap, IReadOnlyList mods, double gameplayStartTime) { this.beatmap = beatmap; this.mods = mods; this.gameplayStartTime = gameplayStartTime; - this.track = track; + track = beatmap.Track; firstHitObjectTime = beatmap.Beatmap.HitObjects.First().StartTime; diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index e92164de7c..ccdd4ea8a4 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -179,7 +179,7 @@ namespace osu.Game.Screens.Play if (!ScoreProcessor.Mode.Disabled) config.BindWith(OsuSetting.ScoreDisplayMode, ScoreProcessor.Mode); - InternalChild = GameplayClockContainer = new GameplayClockContainer(musicController.CurrentTrack, Beatmap.Value, Mods.Value, DrawableRuleset.GameplayStartTime); + InternalChild = GameplayClockContainer = new GameplayClockContainer(Beatmap.Value, Mods.Value, DrawableRuleset.GameplayStartTime); AddInternal(gameplayBeatmap = new GameplayBeatmap(playableBeatmap)); AddInternal(screenSuspension = new ScreenSuspensionHandler(GameplayClockContainer)); From 93a8bc3d5aa330cb6ef008ac8858ae4d005434aa Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 17 Aug 2020 22:36:03 +0900 Subject: [PATCH 077/320] Remove local reset method in GameplayClockContainer --- .../TestSceneGameplayClockContainer.cs | 4 +-- .../Gameplay/TestSceneStoryboardSamples.cs | 4 +-- .../Visual/Gameplay/TestSceneSkipOverlay.cs | 4 +-- .../Screens/Play/GameplayClockContainer.cs | 31 +++++++------------ osu.Game/Screens/Play/Player.cs | 2 +- osu.Game/Tests/Visual/PlayerTestScene.cs | 2 ++ 6 files changed, 19 insertions(+), 28 deletions(-) diff --git a/osu.Game.Tests/Gameplay/TestSceneGameplayClockContainer.cs b/osu.Game.Tests/Gameplay/TestSceneGameplayClockContainer.cs index dc9f540907..891537c4ad 100644 --- a/osu.Game.Tests/Gameplay/TestSceneGameplayClockContainer.cs +++ b/osu.Game.Tests/Gameplay/TestSceneGameplayClockContainer.cs @@ -1,10 +1,8 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System; using NUnit.Framework; using osu.Framework.Testing; -using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Osu; using osu.Game.Screens.Play; using osu.Game.Tests.Visual; @@ -24,7 +22,7 @@ namespace osu.Game.Tests.Gameplay var working = CreateWorkingBeatmap(new OsuRuleset().RulesetInfo); working.LoadTrack(); - Add(gcc = new GameplayClockContainer(working, Array.Empty(), 0)); + Add(gcc = new GameplayClockContainer(working, 0)); }); AddStep("start track", () => gcc.Start()); diff --git a/osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs b/osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs index 6f788a070e..a690eb3b59 100644 --- a/osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs +++ b/osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs @@ -62,7 +62,7 @@ namespace osu.Game.Tests.Gameplay var working = CreateWorkingBeatmap(new OsuRuleset().RulesetInfo); working.LoadTrack(); - Add(gameplayContainer = new GameplayClockContainer(working, Array.Empty(), 0)); + Add(gameplayContainer = new GameplayClockContainer(working, 0)); gameplayContainer.Add(sample = new DrawableStoryboardSample(new StoryboardSampleInfo(string.Empty, 0, 1)) { @@ -106,7 +106,7 @@ namespace osu.Game.Tests.Gameplay Beatmap.Value = new TestCustomSkinWorkingBeatmap(new OsuRuleset().RulesetInfo, Audio); SelectedMods.Value = new[] { testedMod }; - Add(gameplayContainer = new GameplayClockContainer(Beatmap.Value, SelectedMods.Value, 0)); + Add(gameplayContainer = new GameplayClockContainer(Beatmap.Value, 0)); gameplayContainer.Add(sample = new TestDrawableStoryboardSample(new StoryboardSampleInfo("test-sample", 1, 1)) { diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSkipOverlay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSkipOverlay.cs index c7e5e2a7ec..841722a8f1 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSkipOverlay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSkipOverlay.cs @@ -1,11 +1,9 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System; using NUnit.Framework; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Osu; using osu.Game.Screens.Play; using osuTK; @@ -35,7 +33,7 @@ namespace osu.Game.Tests.Visual.Gameplay var working = CreateWorkingBeatmap(CreateBeatmap(new OsuRuleset().RulesetInfo)); working.LoadTrack(); - Child = gameplayClockContainer = new GameplayClockContainer(working, Array.Empty(), 0) + Child = gameplayClockContainer = new GameplayClockContainer(working, 0) { RelativeSizeAxes = Axes.Both, Children = new Drawable[] diff --git a/osu.Game/Screens/Play/GameplayClockContainer.cs b/osu.Game/Screens/Play/GameplayClockContainer.cs index 50a7331e4f..7a9cb3dddd 100644 --- a/osu.Game/Screens/Play/GameplayClockContainer.cs +++ b/osu.Game/Screens/Play/GameplayClockContainer.cs @@ -2,7 +2,6 @@ // See the LICENCE file in the repository root for full licence text. using System; -using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Threading.Tasks; @@ -16,7 +15,6 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Timing; using osu.Game.Beatmaps; using osu.Game.Configuration; -using osu.Game.Rulesets.Mods; namespace osu.Game.Screens.Play { @@ -26,7 +24,6 @@ namespace osu.Game.Screens.Play public class GameplayClockContainer : Container { private readonly WorkingBeatmap beatmap; - private readonly IReadOnlyList mods; [NotNull] private ITrack track; @@ -62,10 +59,9 @@ namespace osu.Game.Screens.Play private readonly FramedOffsetClock platformOffsetClock; - public GameplayClockContainer(WorkingBeatmap beatmap, IReadOnlyList mods, double gameplayStartTime) + public GameplayClockContainer(WorkingBeatmap beatmap, double gameplayStartTime) { this.beatmap = beatmap; - this.mods = mods; this.gameplayStartTime = gameplayStartTime; track = beatmap.Track; @@ -122,13 +118,10 @@ namespace osu.Game.Screens.Play public void Restart() { - // The Reset() call below causes speed adjustments to be reset in an async context, leading to deadlocks. - // The deadlock can be prevented by resetting the track synchronously before entering the async context. - track.ResetSpeedAdjustments(); - Task.Run(() => { - track.Reset(); + track.Seek(0); + track.Stop(); Schedule(() => { @@ -216,14 +209,13 @@ namespace osu.Game.Screens.Play private void updateRate() { - speedAdjustmentsApplied = true; - track.ResetSpeedAdjustments(); + if (speedAdjustmentsApplied) + return; track.AddAdjustment(AdjustableProperty.Frequency, pauseFreqAdjust); track.AddAdjustment(AdjustableProperty.Tempo, UserPlaybackRate); - foreach (var mod in mods.OfType()) - mod.ApplyToTrack(track); + speedAdjustmentsApplied = true; } protected override void Dispose(bool isDisposing) @@ -234,11 +226,12 @@ namespace osu.Game.Screens.Play private void removeSourceClockAdjustments() { - if (speedAdjustmentsApplied) - { - track.ResetSpeedAdjustments(); - speedAdjustmentsApplied = false; - } + if (!speedAdjustmentsApplied) return; + + track.RemoveAdjustment(AdjustableProperty.Frequency, pauseFreqAdjust); + track.RemoveAdjustment(AdjustableProperty.Tempo, UserPlaybackRate); + + speedAdjustmentsApplied = false; } private class HardwareCorrectionOffsetClock : FramedOffsetClock diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index ccdd4ea8a4..cc70995b26 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -179,7 +179,7 @@ namespace osu.Game.Screens.Play if (!ScoreProcessor.Mode.Disabled) config.BindWith(OsuSetting.ScoreDisplayMode, ScoreProcessor.Mode); - InternalChild = GameplayClockContainer = new GameplayClockContainer(Beatmap.Value, Mods.Value, DrawableRuleset.GameplayStartTime); + InternalChild = GameplayClockContainer = new GameplayClockContainer(Beatmap.Value, DrawableRuleset.GameplayStartTime); AddInternal(gameplayBeatmap = new GameplayBeatmap(playableBeatmap)); AddInternal(screenSuspension = new ScreenSuspensionHandler(GameplayClockContainer)); diff --git a/osu.Game/Tests/Visual/PlayerTestScene.cs b/osu.Game/Tests/Visual/PlayerTestScene.cs index 2c46e7f6d3..7d06c99133 100644 --- a/osu.Game/Tests/Visual/PlayerTestScene.cs +++ b/osu.Game/Tests/Visual/PlayerTestScene.cs @@ -29,6 +29,8 @@ namespace osu.Game.Tests.Visual { Dependencies.Cache(LocalConfig = new OsuConfigManager(LocalStorage)); LocalConfig.GetBindable(OsuSetting.DimLevel).Value = 1.0; + + MusicController.AllowRateAdjustments = true; } [SetUpSteps] From 083bcde3cf260147304b110d4a0956285690e4ba Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 18 Aug 2020 13:01:35 +0900 Subject: [PATCH 078/320] Fix beatmap transfer not working --- osu.Game/Beatmaps/WorkingBeatmap.cs | 7 +++++++ osu.Game/Overlays/MusicController.cs | 13 ++++++++++--- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/osu.Game/Beatmaps/WorkingBeatmap.cs b/osu.Game/Beatmaps/WorkingBeatmap.cs index b4046a4e95..c9a60d7948 100644 --- a/osu.Game/Beatmaps/WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/WorkingBeatmap.cs @@ -259,6 +259,13 @@ namespace osu.Game.Beatmaps [NotNull] public Track LoadTrack() => loadedTrack = GetBeatmapTrack() ?? GetVirtualTrack(1000); + /// + /// Transfer a valid audio track into this working beatmap. Used as an optimisation to avoid reload / track swap + /// across difficulties in the same beatmap set. + /// + /// The track to transfer. + public void TransferTrack([NotNull] Track track) => loadedTrack = track ?? throw new ArgumentNullException(nameof(track)); + /// /// Get the loaded audio track instance. must have first been called. /// This generally happens via MusicController when changing the global beatmap. diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index 8bbae33811..c1116ff651 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -282,10 +282,10 @@ namespace osu.Game.Overlays { TrackChangeDirection direction = TrackChangeDirection.None; + bool audioEquals = beatmap.NewValue?.BeatmapInfo?.AudioEquals(current?.BeatmapInfo) ?? false; + if (current != null) { - bool audioEquals = beatmap.NewValue?.BeatmapInfo?.AudioEquals(current.BeatmapInfo) ?? false; - if (audioEquals) direction = TrackChangeDirection.None; else if (queuedDirection.HasValue) @@ -305,8 +305,15 @@ namespace osu.Game.Overlays current = beatmap.NewValue; - if (CurrentTrack.IsDummyDevice || !beatmap.OldValue.BeatmapInfo.AudioEquals(current?.BeatmapInfo)) + if (!audioEquals || CurrentTrack.IsDummyDevice) + { changeTrack(); + } + else + { + // transfer still valid track to new working beatmap + current.TransferTrack(beatmap.OldValue.Track); + } TrackChanged?.Invoke(current, direction); From 526f06be4c714410061a732dfb041c84c3c45f0d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 21 Aug 2020 13:53:12 +0900 Subject: [PATCH 079/320] Add back track loaded bool in WorkingBeatmap --- osu.Game/Beatmaps/WorkingBeatmap.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/WorkingBeatmap.cs b/osu.Game/Beatmaps/WorkingBeatmap.cs index 051d66af7b..8d5543cadb 100644 --- a/osu.Game/Beatmaps/WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/WorkingBeatmap.cs @@ -275,6 +275,11 @@ namespace osu.Game.Beatmaps /// The track to transfer. public void TransferTrack([NotNull] Track track) => loadedTrack = track ?? throw new ArgumentNullException(nameof(track)); + /// + /// Whether this beatmap's track has been loaded via . + /// + public bool TrackLoaded => loadedTrack != null; + /// /// Get the loaded audio track instance. must have first been called. /// This generally happens via MusicController when changing the global beatmap. @@ -283,7 +288,7 @@ namespace osu.Game.Beatmaps { get { - if (loadedTrack == null) + if (!TrackLoaded) throw new InvalidOperationException($"Cannot access {nameof(Track)} without first calling {nameof(LoadTrack)}."); return loadedTrack; From 0b0ff626477a611a161ece951ffb9f0682dd8a44 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 21 Aug 2020 14:46:23 +0900 Subject: [PATCH 080/320] Switch timeline to use track directly from beatmap again --- .../Compose/Components/Timeline/Timeline.cs | 49 ++++++++++--------- 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs index e1702d3eff..96c48c0ddc 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs @@ -30,6 +30,28 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline [Resolved] private MusicController musicController { get; set; } + /// + /// The timeline's scroll position in the last frame. + /// + private float lastScrollPosition; + + /// + /// The track time in the last frame. + /// + private double lastTrackTime; + + /// + /// Whether the user is currently dragging the timeline. + /// + private bool handlingDragInput; + + /// + /// Whether the track was playing before a user drag event. + /// + private bool trackWasPlaying; + + private ITrack track; + public Timeline() { ZoomDuration = 200; @@ -61,9 +83,10 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline Beatmap.BindValueChanged(b => { waveform.Waveform = b.NewValue.Waveform; - track = musicController.CurrentTrack; + track = b.NewValue.Track; - if (track.Length > 0) + // todo: i don't think this is safe, the track may not be loaded yet. + if (b.NewValue.Track.Length > 0) { MaxZoom = getZoomLevelForVisibleMilliseconds(500); MinZoom = getZoomLevelForVisibleMilliseconds(10000); @@ -74,28 +97,6 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline private float getZoomLevelForVisibleMilliseconds(double milliseconds) => (float)(track.Length / milliseconds); - /// - /// The timeline's scroll position in the last frame. - /// - private float lastScrollPosition; - - /// - /// The track time in the last frame. - /// - private double lastTrackTime; - - /// - /// Whether the user is currently dragging the timeline. - /// - private bool handlingDragInput; - - /// - /// Whether the track was playing before a user drag event. - /// - private bool trackWasPlaying; - - private ITrack track; - protected override void Update() { base.Update(); From d2c2e8bbe89536f5fed2a35ea35aa514029ac28d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 21 Aug 2020 15:05:56 +0900 Subject: [PATCH 081/320] Revert some more usage of MusicController back to WorkingBeatmap --- .../TestSceneHoldNoteInput.cs | 2 +- osu.Game.Rulesets.Osu.Tests/TestSceneOutOfOrderHits.cs | 2 +- osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs | 2 +- .../Skinning/TestSceneDrawableTaikoMascot.cs | 4 ++-- .../Skinning/TestSceneTaikoPlayfield.cs | 2 +- osu.Game.Tests/Skins/TestSceneBeatmapSkinResources.cs | 10 +++++++--- osu.Game/Beatmaps/WorkingBeatmap.cs | 2 +- osu.Game/Tests/Beatmaps/TestWorkingBeatmap.cs | 2 ++ osu.Game/Tests/Visual/RateAdjustedBeatmapTestScene.cs | 3 +-- 9 files changed, 17 insertions(+), 12 deletions(-) diff --git a/osu.Game.Rulesets.Mania.Tests/TestSceneHoldNoteInput.cs b/osu.Game.Rulesets.Mania.Tests/TestSceneHoldNoteInput.cs index 19b69bac6d..95072cf4f8 100644 --- a/osu.Game.Rulesets.Mania.Tests/TestSceneHoldNoteInput.cs +++ b/osu.Game.Rulesets.Mania.Tests/TestSceneHoldNoteInput.cs @@ -343,7 +343,7 @@ namespace osu.Game.Rulesets.Mania.Tests judgementResults = new List(); }); - AddUntilStep("Beatmap at 0", () => MusicController.CurrentTrack.CurrentTime == 0); + AddUntilStep("Beatmap at 0", () => Beatmap.Value.Track.CurrentTime == 0); AddUntilStep("Wait until player is loaded", () => currentPlayer.IsCurrentScreen()); AddUntilStep("Wait for completion", () => currentPlayer.ScoreProcessor.HasCompleted.Value); } diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneOutOfOrderHits.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneOutOfOrderHits.cs index 744ad46c28..854626d362 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneOutOfOrderHits.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneOutOfOrderHits.cs @@ -385,7 +385,7 @@ namespace osu.Game.Rulesets.Osu.Tests judgementResults = new List(); }); - AddUntilStep("Beatmap at 0", () => MusicController.CurrentTrack.CurrentTime == 0); + AddUntilStep("Beatmap at 0", () => Beatmap.Value.Track.CurrentTime == 0); AddUntilStep("Wait until player is loaded", () => currentPlayer.IsCurrentScreen()); AddUntilStep("Wait for completion", () => currentPlayer.ScoreProcessor.HasCompleted.Value); } diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs index 1690f648f9..b543b6fa94 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs @@ -366,7 +366,7 @@ namespace osu.Game.Rulesets.Osu.Tests judgementResults = new List(); }); - AddUntilStep("Beatmap at 0", () => MusicController.CurrentTrack.CurrentTime == 0); + AddUntilStep("Beatmap at 0", () => Beatmap.Value.Track.CurrentTime == 0); AddUntilStep("Wait until player is loaded", () => currentPlayer.IsCurrentScreen()); AddUntilStep("Wait for completion", () => currentPlayer.ScoreProcessor.HasCompleted.Value); } diff --git a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableTaikoMascot.cs b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableTaikoMascot.cs index 6141bf062e..47d8a5c012 100644 --- a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableTaikoMascot.cs +++ b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableTaikoMascot.cs @@ -175,11 +175,11 @@ namespace osu.Game.Rulesets.Taiko.Tests.Skinning private void createDrawableRuleset() { - AddUntilStep("wait for beatmap to be loaded", () => MusicController.CurrentTrack.TrackLoaded); + AddUntilStep("wait for beatmap to be loaded", () => Beatmap.Value.Track.IsLoaded); AddStep("create drawable ruleset", () => { - MusicController.CurrentTrack.Start(); + Beatmap.Value.Track.Start(); SetContents(() => { diff --git a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneTaikoPlayfield.cs b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneTaikoPlayfield.cs index a3d3bc81c4..7b7e2c43d1 100644 --- a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneTaikoPlayfield.cs +++ b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneTaikoPlayfield.cs @@ -34,7 +34,7 @@ namespace osu.Game.Rulesets.Taiko.Tests.Skinning beatmap.ControlPointInfo.Add(0, new TimingControlPoint { BeatLength = 1000 }); - MusicController.CurrentTrack.Start(); + Beatmap.Value.Track.Start(); }); AddStep("Load playfield", () => SetContents(() => new TaikoPlayfield(new ControlPointInfo()) diff --git a/osu.Game.Tests/Skins/TestSceneBeatmapSkinResources.cs b/osu.Game.Tests/Skins/TestSceneBeatmapSkinResources.cs index 49b40daf99..eff430ac25 100644 --- a/osu.Game.Tests/Skins/TestSceneBeatmapSkinResources.cs +++ b/osu.Game.Tests/Skins/TestSceneBeatmapSkinResources.cs @@ -3,6 +3,7 @@ using NUnit.Framework; using osu.Framework.Allocation; +using osu.Framework.Audio.Track; using osu.Framework.Testing; using osu.Game.Audio; using osu.Game.Beatmaps; @@ -18,17 +19,20 @@ namespace osu.Game.Tests.Skins [Resolved] private BeatmapManager beatmaps { get; set; } + private WorkingBeatmap beatmap; + [BackgroundDependencyLoader] private void load() { var imported = beatmaps.Import(new ZipArchiveReader(TestResources.OpenResource("Archives/ogg-beatmap.osz"))).Result; - Beatmap.Value = beatmaps.GetWorkingBeatmap(imported.Beatmaps[0]); + beatmap = beatmaps.GetWorkingBeatmap(imported.Beatmaps[0]); + beatmap.LoadTrack(); } [Test] - public void TestRetrieveOggSample() => AddAssert("sample is non-null", () => Beatmap.Value.Skin.GetSample(new SampleInfo("sample")) != null); + public void TestRetrieveOggSample() => AddAssert("sample is non-null", () => beatmap.Skin.GetSample(new SampleInfo("sample")) != null); [Test] - public void TestRetrieveOggTrack() => AddAssert("track is non-null", () => !MusicController.CurrentTrack.IsDummyDevice); + public void TestRetrieveOggTrack() => AddAssert("track is non-null", () => !(beatmap.Track is TrackVirtual)); } } diff --git a/osu.Game/Beatmaps/WorkingBeatmap.cs b/osu.Game/Beatmaps/WorkingBeatmap.cs index 8d5543cadb..6a89739e6f 100644 --- a/osu.Game/Beatmaps/WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/WorkingBeatmap.cs @@ -278,7 +278,7 @@ namespace osu.Game.Beatmaps /// /// Whether this beatmap's track has been loaded via . /// - public bool TrackLoaded => loadedTrack != null; + public virtual bool TrackLoaded => loadedTrack != null; /// /// Get the loaded audio track instance. must have first been called. diff --git a/osu.Game/Tests/Beatmaps/TestWorkingBeatmap.cs b/osu.Game/Tests/Beatmaps/TestWorkingBeatmap.cs index d091da3206..bfcb2403c1 100644 --- a/osu.Game/Tests/Beatmaps/TestWorkingBeatmap.cs +++ b/osu.Game/Tests/Beatmaps/TestWorkingBeatmap.cs @@ -27,6 +27,8 @@ namespace osu.Game.Tests.Beatmaps this.storyboard = storyboard; } + public override bool TrackLoaded => true; + public override bool BeatmapLoaded => true; protected override IBeatmap GetBeatmap() => beatmap; diff --git a/osu.Game/Tests/Visual/RateAdjustedBeatmapTestScene.cs b/osu.Game/Tests/Visual/RateAdjustedBeatmapTestScene.cs index 7651285970..ad24ffc7b8 100644 --- a/osu.Game/Tests/Visual/RateAdjustedBeatmapTestScene.cs +++ b/osu.Game/Tests/Visual/RateAdjustedBeatmapTestScene.cs @@ -13,8 +13,7 @@ namespace osu.Game.Tests.Visual base.Update(); // note that this will override any mod rate application - if (MusicController.TrackLoaded) - MusicController.CurrentTrack.Tempo.Value = Clock.Rate; + Beatmap.Value.Track.Tempo.Value = Clock.Rate; } } } From f7e4feee3449630475a11a2291803997fb23e029 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 21 Aug 2020 15:25:57 +0900 Subject: [PATCH 082/320] Update remaining Player components to use WorkingBeatmap again --- osu.Game/Screens/Play/FailAnimation.cs | 13 ++++++------- osu.Game/Screens/Play/Player.cs | 8 ++++---- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/osu.Game/Screens/Play/FailAnimation.cs b/osu.Game/Screens/Play/FailAnimation.cs index dade904180..54c644c999 100644 --- a/osu.Game/Screens/Play/FailAnimation.cs +++ b/osu.Game/Screens/Play/FailAnimation.cs @@ -6,12 +6,12 @@ using osu.Framework.Bindables; using osu.Game.Rulesets.UI; using System; using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; using osu.Framework.Allocation; using osu.Framework.Audio.Sample; using osu.Framework.Audio.Track; using osu.Framework.Graphics; using osu.Framework.Utils; +using osu.Game.Beatmaps; using osu.Game.Rulesets.Objects.Drawables; using osuTK; using osuTK.Graphics; @@ -28,24 +28,23 @@ namespace osu.Game.Screens.Play private readonly DrawableRuleset drawableRuleset; - [NotNull] - private readonly ITrack track; - private readonly BindableDouble trackFreq = new BindableDouble(1); + private Track track; + private const float duration = 2500; private SampleChannel failSample; - public FailAnimation(DrawableRuleset drawableRuleset, [NotNull] ITrack track) + public FailAnimation(DrawableRuleset drawableRuleset) { this.drawableRuleset = drawableRuleset; - this.track = track; } [BackgroundDependencyLoader] - private void load(AudioManager audio) + private void load(AudioManager audio, IBindable beatmap) { + track = beatmap.Value.Track; failSample = audio.Samples.Get(@"Gameplay/failsound"); } diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index cc70995b26..a8fda10604 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -151,7 +151,7 @@ namespace osu.Game.Screens.Play } [BackgroundDependencyLoader] - private void load(AudioManager audio, OsuConfigManager config, MusicController musicController) + private void load(AudioManager audio, OsuConfigManager config) { Mods.Value = base.Mods.Value.Select(m => m.CreateCopy()).ToArray(); @@ -188,7 +188,7 @@ namespace osu.Game.Screens.Play addUnderlayComponents(GameplayClockContainer); addGameplayComponents(GameplayClockContainer, Beatmap.Value, playableBeatmap); - addOverlayComponents(GameplayClockContainer, Beatmap.Value, musicController.CurrentTrack); + addOverlayComponents(GameplayClockContainer, Beatmap.Value); if (!DrawableRuleset.AllowGameplayOverlays) { @@ -265,7 +265,7 @@ namespace osu.Game.Screens.Play }); } - private void addOverlayComponents(Container target, WorkingBeatmap working, ITrack track) + private void addOverlayComponents(Container target, WorkingBeatmap working) { target.AddRange(new[] { @@ -332,7 +332,7 @@ namespace osu.Game.Screens.Play performImmediateExit(); }, }, - failAnimation = new FailAnimation(DrawableRuleset, track) { OnComplete = onFailComplete, }, + failAnimation = new FailAnimation(DrawableRuleset) { OnComplete = onFailComplete, }, }); } From 0ae460fb8f4e7b9c235ce0cb27ae933157d162c6 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 21 Aug 2020 15:50:14 +0900 Subject: [PATCH 083/320] Avoid beatmap load call in IntroScreen --- osu.Game.Tests/Visual/Menus/TestSceneIntroWelcome.cs | 3 ++- osu.Game/Screens/Menu/IntroScreen.cs | 3 ++- osu.Game/Screens/Menu/IntroTriangles.cs | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/osu.Game.Tests/Visual/Menus/TestSceneIntroWelcome.cs b/osu.Game.Tests/Visual/Menus/TestSceneIntroWelcome.cs index 29be250b12..5f135febf4 100644 --- a/osu.Game.Tests/Visual/Menus/TestSceneIntroWelcome.cs +++ b/osu.Game.Tests/Visual/Menus/TestSceneIntroWelcome.cs @@ -3,6 +3,7 @@ using NUnit.Framework; using osu.Framework.Screens; +using osu.Framework.Utils; using osu.Game.Screens.Menu; namespace osu.Game.Tests.Visual.Menus @@ -15,7 +16,7 @@ namespace osu.Game.Tests.Visual.Menus public TestSceneIntroWelcome() { AddUntilStep("wait for load", () => MusicController.TrackLoaded); - + AddAssert("correct track", () => Precision.AlmostEquals(MusicController.CurrentTrack.Length, 48000, 1)); AddAssert("check if menu music loops", () => MusicController.CurrentTrack.Looping); } } diff --git a/osu.Game/Screens/Menu/IntroScreen.cs b/osu.Game/Screens/Menu/IntroScreen.cs index 3e4320ae44..363933694d 100644 --- a/osu.Game/Screens/Menu/IntroScreen.cs +++ b/osu.Game/Screens/Menu/IntroScreen.cs @@ -66,6 +66,7 @@ namespace osu.Game.Screens.Menu /// /// Whether the is provided by osu! resources, rather than a user beatmap. + /// Only valid during or after . /// protected bool UsingThemedIntro { get; private set; } @@ -115,7 +116,6 @@ namespace osu.Game.Screens.Menu if (setInfo != null) { initialBeatmap = beatmaps.GetWorkingBeatmap(setInfo.Beatmaps[0]); - UsingThemedIntro = !initialBeatmap.LoadTrack().IsDummyDevice; } return UsingThemedIntro; @@ -169,6 +169,7 @@ namespace osu.Game.Screens.Menu { beatmap.Value = initialBeatmap; Track = musicController.CurrentTrack; + UsingThemedIntro = !initialBeatmap.LoadTrack().IsDummyDevice; logo.MoveTo(new Vector2(0.5f)); logo.ScaleTo(Vector2.One); diff --git a/osu.Game/Screens/Menu/IntroTriangles.cs b/osu.Game/Screens/Menu/IntroTriangles.cs index a9ef20436f..52281967ee 100644 --- a/osu.Game/Screens/Menu/IntroTriangles.cs +++ b/osu.Game/Screens/Menu/IntroTriangles.cs @@ -44,7 +44,7 @@ namespace osu.Game.Screens.Menu [BackgroundDependencyLoader] private void load() { - if (MenuVoice.Value && !UsingThemedIntro) + if (MenuVoice.Value) welcome = audio.Samples.Get(@"Intro/welcome"); } From 3b03116179c3e0ec88b815dd2bcfc32961058510 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 21 Aug 2020 16:45:59 +0900 Subject: [PATCH 084/320] Remove unnecessary using statement --- osu.Game/Screens/Play/Player.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index a8fda10604..9be4fd6a65 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -8,7 +8,6 @@ using System.Linq; using osu.Framework.Allocation; using osu.Framework.Audio; using osu.Framework.Audio.Sample; -using osu.Framework.Audio.Track; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; From 70697cf1a0e36e57b3533613a5795bdb8722a746 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 21 Aug 2020 16:58:45 +0900 Subject: [PATCH 085/320] Restore remaining editor components to use Beatmap.Track --- osu.Game.Tests/Visual/Editing/TimelineTestScene.cs | 11 ++++++----- .../Screens/Edit/Components/BottomBarContainer.cs | 2 ++ osu.Game/Screens/Edit/Components/PlaybackControl.cs | 8 ++------ .../Timelines/Summary/Parts/TimelinePart.cs | 8 ++------ .../Edit/Compose/Components/Timeline/Timeline.cs | 6 +++--- .../Components/Timeline/TimelineTickDisplay.cs | 7 ++++--- osu.Game/Screens/Edit/Editor.cs | 10 ++++------ osu.Game/Screens/Edit/EditorClock.cs | 10 +++++----- osu.Game/Tests/Visual/EditorClockTestScene.cs | 3 ++- 9 files changed, 30 insertions(+), 35 deletions(-) diff --git a/osu.Game.Tests/Visual/Editing/TimelineTestScene.cs b/osu.Game.Tests/Visual/Editing/TimelineTestScene.cs index 4988a09650..fdb8781563 100644 --- a/osu.Game.Tests/Visual/Editing/TimelineTestScene.cs +++ b/osu.Game.Tests/Visual/Editing/TimelineTestScene.cs @@ -3,11 +3,12 @@ using osu.Framework.Allocation; using osu.Framework.Audio; +using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; +using osu.Game.Beatmaps; using osu.Game.Graphics.UserInterface; -using osu.Game.Overlays; using osu.Game.Rulesets.Edit; using osu.Game.Screens.Edit; using osu.Game.Screens.Edit.Compose.Components.Timeline; @@ -64,10 +65,10 @@ namespace osu.Game.Tests.Visual.Editing private readonly Drawable marker; [Resolved] - private EditorClock editorClock { get; set; } + private IBindable beatmap { get; set; } [Resolved] - private MusicController musicController { get; set; } + private EditorClock editorClock { get; set; } public AudioVisualiser() { @@ -93,8 +94,8 @@ namespace osu.Game.Tests.Visual.Editing { base.Update(); - if (musicController.TrackLoaded) - marker.X = (float)(editorClock.CurrentTime / musicController.CurrentTrack.Length); + if (beatmap.Value.Track.IsLoaded) + marker.X = (float)(editorClock.CurrentTime / beatmap.Value.Track.Length); } } diff --git a/osu.Game/Screens/Edit/Components/BottomBarContainer.cs b/osu.Game/Screens/Edit/Components/BottomBarContainer.cs index 8d8c59b2ee..cb5078a479 100644 --- a/osu.Game/Screens/Edit/Components/BottomBarContainer.cs +++ b/osu.Game/Screens/Edit/Components/BottomBarContainer.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Allocation; +using osu.Framework.Audio.Track; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -17,6 +18,7 @@ namespace osu.Game.Screens.Edit.Components private const float contents_padding = 15; protected readonly IBindable Beatmap = new Bindable(); + protected Track Track => Beatmap.Value.Track; private readonly Drawable background; private readonly Container content; diff --git a/osu.Game/Screens/Edit/Components/PlaybackControl.cs b/osu.Game/Screens/Edit/Components/PlaybackControl.cs index 5bafc120af..59b3d1c565 100644 --- a/osu.Game/Screens/Edit/Components/PlaybackControl.cs +++ b/osu.Game/Screens/Edit/Components/PlaybackControl.cs @@ -16,7 +16,6 @@ using osu.Framework.Input.Events; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; -using osu.Game.Overlays; using osuTK.Input; namespace osu.Game.Screens.Edit.Components @@ -28,9 +27,6 @@ namespace osu.Game.Screens.Edit.Components [Resolved] private EditorClock editorClock { get; set; } - [Resolved] - private MusicController musicController { get; set; } - private readonly BindableNumber tempo = new BindableDouble(1); [BackgroundDependencyLoader] @@ -66,12 +62,12 @@ namespace osu.Game.Screens.Edit.Components } }; - musicController.CurrentTrack.AddAdjustment(AdjustableProperty.Tempo, tempo); + Track?.AddAdjustment(AdjustableProperty.Tempo, tempo); } protected override void Dispose(bool isDisposing) { - musicController?.CurrentTrack.RemoveAdjustment(AdjustableProperty.Tempo, tempo); + Track?.RemoveAdjustment(AdjustableProperty.Tempo, tempo); base.Dispose(isDisposing); } diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs index c8a470c58a..4a7c3f26bc 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs @@ -8,7 +8,6 @@ using osuTK; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Beatmaps; -using osu.Game.Overlays; namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts { @@ -27,9 +26,6 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts protected override Container Content => content; - [Resolved] - private MusicController musicController { get; set; } - public TimelinePart(Container content = null) { AddInternal(this.content = content ?? new Container { RelativeSizeAxes = Axes.Both }); @@ -50,14 +46,14 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts private void updateRelativeChildSize() { // the track may not be loaded completely (only has a length once it is). - if (!musicController.TrackLoaded) + if (!Beatmap.Value.Track.IsLoaded) { content.RelativeChildSize = Vector2.One; Schedule(updateRelativeChildSize); return; } - content.RelativeChildSize = new Vector2((float)Math.Max(1, musicController.CurrentTrack.Length), 1); + content.RelativeChildSize = new Vector2((float)Math.Max(1, Beatmap.Value.Track.Length), 1); } protected virtual void LoadBeatmap(WorkingBeatmap beatmap) diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs index 96c48c0ddc..c6bfdda698 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs @@ -50,7 +50,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline /// private bool trackWasPlaying; - private ITrack track; + private Track track; public Timeline() { @@ -134,7 +134,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline private void seekTrackToCurrent() { - if (!musicController.TrackLoaded) + if (!track.IsLoaded) return; editorClock.Seek(Current / Content.DrawWidth * track.Length); @@ -142,7 +142,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline private void scrollToTrackTime() { - if (!musicController.TrackLoaded || track.Length == 0) + if (!track.IsLoaded || track.Length == 0) return; ScrollTo((float)(editorClock.CurrentTime / track.Length) * Content.DrawWidth, false); diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineTickDisplay.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineTickDisplay.cs index cb122c590e..36ee976bf7 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineTickDisplay.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineTickDisplay.cs @@ -3,9 +3,10 @@ using System.Linq; using osu.Framework.Allocation; +using osu.Framework.Bindables; using osu.Framework.Graphics; +using osu.Game.Beatmaps; using osu.Game.Graphics; -using osu.Game.Overlays; using osu.Game.Screens.Edit.Components.Timelines.Summary.Parts; using osu.Game.Screens.Edit.Components.Timelines.Summary.Visualisations; @@ -17,7 +18,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline private EditorBeatmap beatmap { get; set; } [Resolved] - private MusicController musicController { get; set; } + private Bindable working { get; set; } [Resolved] private BindableBeatDivisor beatDivisor { get; set; } @@ -43,7 +44,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline for (var i = 0; i < beatmap.ControlPointInfo.TimingPoints.Count; i++) { var point = beatmap.ControlPointInfo.TimingPoints[i]; - var until = i + 1 < beatmap.ControlPointInfo.TimingPoints.Count ? beatmap.ControlPointInfo.TimingPoints[i + 1].Time : musicController.CurrentTrack.Length; + var until = i + 1 < beatmap.ControlPointInfo.TimingPoints.Count ? beatmap.ControlPointInfo.TimingPoints[i + 1].Time : working.Value.Track.Length; int beat = 0; diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index 6722d9179c..d92f3922c3 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -14,6 +14,7 @@ using osu.Framework.Bindables; using osu.Framework.Graphics.UserInterface; using osu.Framework.Input.Events; using osu.Framework.Platform; +using osu.Framework.Timing; using osu.Game.Graphics.UserInterface; using osu.Game.Screens.Edit.Components; using osu.Game.Screens.Edit.Components.Menus; @@ -27,7 +28,6 @@ using osu.Framework.Logging; using osu.Game.Beatmaps; using osu.Game.Graphics.Cursor; using osu.Game.Input.Bindings; -using osu.Game.Overlays; using osu.Game.Rulesets.Edit; using osu.Game.Screens.Edit.Compose; using osu.Game.Screens.Edit.Setup; @@ -53,9 +53,6 @@ namespace osu.Game.Screens.Edit [Resolved] private BeatmapManager beatmapManager { get; set; } - [Resolved] - private MusicController musicController { get; set; } - private Box bottomBackground; private Container screenContainer; @@ -82,8 +79,9 @@ namespace osu.Game.Screens.Edit beatDivisor.BindValueChanged(divisor => Beatmap.Value.BeatmapInfo.BeatDivisor = divisor.NewValue); // Todo: should probably be done at a DrawableRuleset level to share logic with Player. + var sourceClock = (IAdjustableClock)Beatmap.Value.Track ?? new StopwatchClock(); clock = new EditorClock(Beatmap.Value, beatDivisor) { IsCoupled = false }; - clock.ChangeSource(musicController.CurrentTrack); + clock.ChangeSource(sourceClock); dependencies.CacheAs(clock); AddInternal(clock); @@ -348,7 +346,7 @@ namespace osu.Game.Screens.Edit private void resetTrack(bool seekToStart = false) { - musicController.CurrentTrack.Stop(); + Beatmap.Value.Track?.Stop(); if (seekToStart) { diff --git a/osu.Game/Screens/Edit/EditorClock.cs b/osu.Game/Screens/Edit/EditorClock.cs index 634a6f7e25..d4d0feb813 100644 --- a/osu.Game/Screens/Edit/EditorClock.cs +++ b/osu.Game/Screens/Edit/EditorClock.cs @@ -30,11 +30,6 @@ namespace osu.Game.Screens.Edit { } - public EditorClock() - : this(new ControlPointInfo(), 1000, new BindableBeatDivisor()) - { - } - public EditorClock(ControlPointInfo controlPointInfo, double trackLength, BindableBeatDivisor beatDivisor) { this.beatDivisor = beatDivisor; @@ -45,6 +40,11 @@ namespace osu.Game.Screens.Edit underlyingClock = new DecoupleableInterpolatingFramedClock(); } + public EditorClock() + : this(new ControlPointInfo(), 1000, new BindableBeatDivisor()) + { + } + /// /// Seek to the closest snappable beat from a time. /// diff --git a/osu.Game/Tests/Visual/EditorClockTestScene.cs b/osu.Game/Tests/Visual/EditorClockTestScene.cs index 59c9329d37..f0ec638fc9 100644 --- a/osu.Game/Tests/Visual/EditorClockTestScene.cs +++ b/osu.Game/Tests/Visual/EditorClockTestScene.cs @@ -4,6 +4,7 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Input.Events; +using osu.Framework.Timing; using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Screens.Edit; @@ -43,7 +44,7 @@ namespace osu.Game.Tests.Visual private void beatmapChanged(ValueChangedEvent e) { Clock.ControlPointInfo = e.NewValue.Beatmap.ControlPointInfo; - Clock.ChangeSource(MusicController.CurrentTrack); + Clock.ChangeSource((IAdjustableClock)e.NewValue.Track ?? new StopwatchClock()); Clock.ProcessFrame(); } From a47b8222b53a00daab14556988952824e59ec1ac Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 21 Aug 2020 16:59:11 +0900 Subject: [PATCH 086/320] Restore multiplayer to use beatmap track --- osu.Game/Screens/Multi/Multiplayer.cs | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/osu.Game/Screens/Multi/Multiplayer.cs b/osu.Game/Screens/Multi/Multiplayer.cs index 1a39d80f8d..4912df17b1 100644 --- a/osu.Game/Screens/Multi/Multiplayer.cs +++ b/osu.Game/Screens/Multi/Multiplayer.cs @@ -52,7 +52,7 @@ namespace osu.Game.Screens.Multi private readonly Bindable currentFilter = new Bindable(new FilterCriteria()); [Resolved] - private MusicController musicController { get; set; } + private MusicController music { get; set; } [Cached(Type = typeof(IRoomManager))] private RoomManager roomManager; @@ -343,10 +343,15 @@ namespace osu.Game.Screens.Multi { if (screenStack.CurrentScreen is MatchSubScreen) { - musicController.CurrentTrack.RestartPoint = Beatmap.Value.Metadata.PreviewTime; - musicController.CurrentTrack.Looping = true; + var track = Beatmap.Value?.Track; - musicController.EnsurePlayingSomething(); + if (track != null) + { + track.RestartPoint = Beatmap.Value.Metadata.PreviewTime; + track.Looping = true; + + music.EnsurePlayingSomething(); + } } else { @@ -356,8 +361,13 @@ namespace osu.Game.Screens.Multi private void cancelLooping() { - musicController.CurrentTrack.Looping = false; - musicController.CurrentTrack.RestartPoint = 0; + var track = Beatmap?.Value?.Track; + + if (track != null) + { + track.Looping = false; + track.RestartPoint = 0; + } } protected override void Dispose(bool isDisposing) From d5cbb589c2ff6fa2a8cfac96ef881d3406149ca9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 21 Aug 2020 17:21:08 +0900 Subject: [PATCH 087/320] Revert some test scene changes to use Beatmap.Track where relevant --- .../Gameplay/TestSceneCompletionCancellation.cs | 6 +++--- .../Visual/Gameplay/TestSceneGameplayRewinding.cs | 12 ++++-------- .../Gameplay/TestSceneNightcoreBeatContainer.cs | 4 ++-- osu.Game.Tests/Visual/Gameplay/TestScenePause.cs | 2 +- .../Visual/Gameplay/TestScenePlayerLoader.cs | 8 ++++---- .../Visual/Gameplay/TestSceneStoryboard.cs | 14 ++++++++++---- 6 files changed, 24 insertions(+), 22 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneCompletionCancellation.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneCompletionCancellation.cs index b39cfc3699..6fd5511e5a 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneCompletionCancellation.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneCompletionCancellation.cs @@ -31,7 +31,7 @@ namespace osu.Game.Tests.Visual.Gameplay base.SetUpSteps(); // Ensure track has actually running before attempting to seek - AddUntilStep("wait for track to start running", () => MusicController.IsPlaying); + AddUntilStep("wait for track to start running", () => Beatmap.Value.Track.IsRunning); } [Test] @@ -70,13 +70,13 @@ namespace osu.Game.Tests.Visual.Gameplay private void complete() { - AddStep("seek to completion", () => MusicController.SeekTo(5000)); + AddStep("seek to completion", () => Beatmap.Value.Track.Seek(5000)); AddUntilStep("completion set by processor", () => Player.ScoreProcessor.HasCompleted.Value); } private void cancel() { - AddStep("rewind to cancel", () => MusicController.SeekTo(4000)); + AddStep("rewind to cancel", () => Beatmap.Value.Track.Seek(4000)); AddUntilStep("completion cleared by processor", () => !Player.ScoreProcessor.HasCompleted.Value); } diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneGameplayRewinding.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneGameplayRewinding.cs index 6bdc65078a..73c6970482 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneGameplayRewinding.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneGameplayRewinding.cs @@ -8,7 +8,6 @@ using osu.Framework.Audio; using osu.Framework.Utils; using osu.Framework.Timing; using osu.Game.Beatmaps; -using osu.Game.Overlays; using osu.Game.Rulesets; using osu.Game.Rulesets.Osu.Objects; using osu.Game.Storyboards; @@ -21,16 +20,13 @@ namespace osu.Game.Tests.Visual.Gameplay [Resolved] private AudioManager audioManager { get; set; } - [Resolved] - private MusicController musicController { get; set; } - - protected override WorkingBeatmap CreateWorkingBeatmap(IBeatmap beatmap, Storyboard storyboard = null) - => new ClockBackedTestWorkingBeatmap(beatmap, storyboard, new FramedClock(new ManualClock { Rate = 1 }), audioManager); + protected override WorkingBeatmap CreateWorkingBeatmap(IBeatmap beatmap, Storyboard storyboard = null) => + new ClockBackedTestWorkingBeatmap(beatmap, storyboard, new FramedClock(new ManualClock { Rate = 1 }), audioManager); [Test] public void TestNoJudgementsOnRewind() { - AddUntilStep("wait for track to start running", () => MusicController.IsPlaying); + AddUntilStep("wait for track to start running", () => Beatmap.Value.Track.IsRunning); addSeekStep(3000); AddAssert("all judged", () => Player.DrawableRuleset.Playfield.AllHitObjects.All(h => h.Judged)); AddUntilStep("key counter counted keys", () => Player.HUDOverlay.KeyCounter.Children.All(kc => kc.CountPresses >= 7)); @@ -43,7 +39,7 @@ namespace osu.Game.Tests.Visual.Gameplay private void addSeekStep(double time) { - AddStep($"seek to {time}", () => MusicController.SeekTo(time)); + AddStep($"seek to {time}", () => Beatmap.Value.Track.Seek(time)); // Allow a few frames of lenience AddUntilStep("wait for seek to finish", () => Precision.AlmostEquals(time, Player.DrawableRuleset.FrameStableClock.CurrentTime, 100)); diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneNightcoreBeatContainer.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneNightcoreBeatContainer.cs index 53e06a632e..951ee1489d 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneNightcoreBeatContainer.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneNightcoreBeatContainer.cs @@ -19,8 +19,8 @@ namespace osu.Game.Tests.Visual.Gameplay Beatmap.Value = CreateWorkingBeatmap(new OsuRuleset().RulesetInfo); - MusicController.CurrentTrack.Start(); - MusicController.CurrentTrack.Seek(Beatmap.Value.Beatmap.HitObjects.First().StartTime - 1000); + Beatmap.Value.Track.Start(); + Beatmap.Value.Track.Seek(Beatmap.Value.Beatmap.HitObjects.First().StartTime - 1000); Add(new ModNightcore.NightcoreBeatContainer()); diff --git a/osu.Game.Tests/Visual/Gameplay/TestScenePause.cs b/osu.Game.Tests/Visual/Gameplay/TestScenePause.cs index e7dd586f4e..420bf29429 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestScenePause.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestScenePause.cs @@ -288,7 +288,7 @@ namespace osu.Game.Tests.Visual.Gameplay private void confirmNoTrackAdjustments() { - AddAssert("track has no adjustments", () => MusicController.CurrentTrack.AggregateFrequency.Value == 1); + AddAssert("track has no adjustments", () => Beatmap.Value.Track.AggregateFrequency.Value == 1); } private void restart() => AddStep("restart", () => Player.Restart()); diff --git a/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs b/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs index c3be6aee2b..4fac7bb45f 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs @@ -61,7 +61,7 @@ namespace osu.Game.Tests.Visual.Gameplay Beatmap.Value = CreateWorkingBeatmap(new OsuRuleset().RulesetInfo); foreach (var mod in SelectedMods.Value.OfType()) - mod.ApplyToTrack(MusicController.CurrentTrack); + mod.ApplyToTrack(Beatmap.Value.Track); InputManager.Child = container; } @@ -75,7 +75,7 @@ namespace osu.Game.Tests.Visual.Gameplay AddUntilStep("wait for not current", () => !loader.IsCurrentScreen()); AddAssert("player did not load", () => player == null); AddUntilStep("player disposed", () => loader.DisposalTask == null); - AddAssert("mod rate still applied", () => MusicController.CurrentTrack.Rate != 1); + AddAssert("mod rate still applied", () => Beatmap.Value.Track.Rate != 1); } /// @@ -88,13 +88,13 @@ namespace osu.Game.Tests.Visual.Gameplay { AddStep("load dummy beatmap", () => ResetPlayer(false, () => SelectedMods.Value = new[] { new OsuModNightcore() })); AddUntilStep("wait for current", () => loader.IsCurrentScreen()); - AddAssert("mod rate applied", () => MusicController.CurrentTrack.Rate != 1); + AddAssert("mod rate applied", () => Beatmap.Value.Track.Rate != 1); AddUntilStep("wait for non-null player", () => player != null); AddStep("exit loader", () => loader.Exit()); AddUntilStep("wait for not current", () => !loader.IsCurrentScreen()); AddAssert("player did not load", () => !player.IsLoaded); AddUntilStep("player disposed", () => loader.DisposalTask?.IsCompleted == true); - AddAssert("mod rate still applied", () => MusicController.CurrentTrack.Rate != 1); + AddAssert("mod rate still applied", () => Beatmap.Value.Track.Rate != 1); } [Test] diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboard.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboard.cs index c11a47d62b..9f1492a25f 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboard.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboard.cs @@ -25,12 +25,16 @@ namespace osu.Game.Tests.Visual.Gameplay private readonly Container storyboardContainer; private DrawableStoryboard storyboard; + [Cached] + private MusicController musicController = new MusicController(); + public TestSceneStoryboard() { Clock = new FramedClock(); AddRange(new Drawable[] { + musicController, new Container { RelativeSizeAxes = Axes.Both, @@ -83,9 +87,11 @@ namespace osu.Game.Tests.Visual.Gameplay private void restart() { - MusicController.CurrentTrack.Reset(); + var track = Beatmap.Value.Track; + + track.Reset(); loadStoryboard(Beatmap.Value); - MusicController.CurrentTrack.Start(); + track.Start(); } private void loadStoryboard(WorkingBeatmap working) @@ -100,7 +106,7 @@ namespace osu.Game.Tests.Visual.Gameplay storyboard.Passing = false; storyboardContainer.Add(storyboard); - decoupledClock.ChangeSource(MusicController.CurrentTrack); + decoupledClock.ChangeSource(working.Track); } private void loadStoryboardNoVideo() @@ -123,7 +129,7 @@ namespace osu.Game.Tests.Visual.Gameplay storyboard = sb.CreateDrawable(Beatmap.Value); storyboardContainer.Add(storyboard); - decoupledClock.ChangeSource(MusicController.CurrentTrack); + decoupledClock.ChangeSource(Beatmap.Value.Track); } } } From 1edafc39bac27e54ebb32dfb44124382ec3b55b5 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 21 Aug 2020 18:33:24 +0900 Subject: [PATCH 088/320] Fix intro welcome playing double due to missing conditional --- osu.Game/Screens/Menu/IntroTriangles.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Menu/IntroTriangles.cs b/osu.Game/Screens/Menu/IntroTriangles.cs index 52281967ee..a96fddb5ad 100644 --- a/osu.Game/Screens/Menu/IntroTriangles.cs +++ b/osu.Game/Screens/Menu/IntroTriangles.cs @@ -64,7 +64,8 @@ namespace osu.Game.Screens.Menu }, t => { AddInternal(t); - welcome?.Play(); + if (!UsingThemedIntro) + welcome?.Play(); StartTrack(); }); From 308d9f59679033e0585cd96b4d5e550c9d2b31d0 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 21 Aug 2020 18:43:58 +0900 Subject: [PATCH 089/320] Ensure locally executed methods are always loaded before propagation --- osu.Game/Overlays/MusicController.cs | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index c1116ff651..112026d9e2 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -231,9 +231,7 @@ namespace osu.Game.Overlays if (playable != null) { - if (beatmap is Bindable working) - working.Value = beatmaps.GetWorkingBeatmap(playable.Beatmaps.First(), beatmap.Value); - + changeBeatmap(beatmaps.GetWorkingBeatmap(playable.Beatmaps.First(), beatmap.Value)); restartTrack(); return PreviousTrackResult.Previous; } @@ -257,9 +255,7 @@ namespace osu.Game.Overlays if (playable != null) { - if (beatmap is Bindable working) - working.Value = beatmaps.GetWorkingBeatmap(playable.Beatmaps.First(), beatmap.Value); - + changeBeatmap(beatmaps.GetWorkingBeatmap(playable.Beatmaps.First(), beatmap.Value)); restartTrack(); return true; } @@ -278,11 +274,15 @@ namespace osu.Game.Overlays private TrackChangeDirection? queuedDirection; - private void beatmapChanged(ValueChangedEvent beatmap) + private void beatmapChanged(ValueChangedEvent beatmap) => changeBeatmap(beatmap.NewValue); + + private void changeBeatmap(WorkingBeatmap newWorking) { + var lastWorking = current; + TrackChangeDirection direction = TrackChangeDirection.None; - bool audioEquals = beatmap.NewValue?.BeatmapInfo?.AudioEquals(current?.BeatmapInfo) ?? false; + bool audioEquals = newWorking?.BeatmapInfo?.AudioEquals(current?.BeatmapInfo) ?? false; if (current != null) { @@ -297,13 +297,13 @@ namespace osu.Game.Overlays { // figure out the best direction based on order in playlist. var last = BeatmapSets.TakeWhile(b => b.ID != current.BeatmapSetInfo?.ID).Count(); - var next = beatmap.NewValue == null ? -1 : BeatmapSets.TakeWhile(b => b.ID != beatmap.NewValue.BeatmapSetInfo?.ID).Count(); + var next = newWorking == null ? -1 : BeatmapSets.TakeWhile(b => b.ID != newWorking.BeatmapSetInfo?.ID).Count(); direction = last > next ? TrackChangeDirection.Prev : TrackChangeDirection.Next; } } - current = beatmap.NewValue; + current = newWorking; if (!audioEquals || CurrentTrack.IsDummyDevice) { @@ -312,7 +312,7 @@ namespace osu.Game.Overlays else { // transfer still valid track to new working beatmap - current.TransferTrack(beatmap.OldValue.Track); + current.TransferTrack(lastWorking.Track); } TrackChanged?.Invoke(current, direction); @@ -320,6 +320,11 @@ namespace osu.Game.Overlays ResetTrackAdjustments(); queuedDirection = null; + + // this will be a noop if coming from the beatmapChanged event. + // the exception is local operations like next/prev, where we want to complete loading the track before sending out a change. + if (beatmap.Value != current && beatmap is Bindable working) + working.Value = current; } private void changeTrack() From 4239e9f684e7e1594fc652be1640a940d9092cd0 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 21 Aug 2020 18:44:14 +0900 Subject: [PATCH 090/320] Fix storyboard test not actually working due to incorrect track referencing --- .../Visual/Gameplay/TestSceneStoryboard.cs | 50 ++++++++----------- 1 file changed, 21 insertions(+), 29 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboard.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboard.cs index 9f1492a25f..5a2b8d22fd 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboard.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboard.cs @@ -22,19 +22,32 @@ namespace osu.Game.Tests.Visual.Gameplay [TestFixture] public class TestSceneStoryboard : OsuTestScene { - private readonly Container storyboardContainer; + private Container storyboardContainer; private DrawableStoryboard storyboard; - [Cached] - private MusicController musicController = new MusicController(); + [Test] + public void TestStoryboard() + { + AddStep("Restart", restart); + AddToggleStep("Passing", passing => + { + if (storyboard != null) storyboard.Passing = passing; + }); + } - public TestSceneStoryboard() + [Test] + public void TestStoryboardMissingVideo() + { + AddStep("Load storyboard with missing video", loadStoryboardNoVideo); + } + + [BackgroundDependencyLoader] + private void load() { Clock = new FramedClock(); AddRange(new Drawable[] { - musicController, new Container { RelativeSizeAxes = Axes.Both, @@ -58,32 +71,11 @@ namespace osu.Game.Tests.Visual.Gameplay State = { Value = Visibility.Visible }, } }); + + Beatmap.BindValueChanged(beatmapChanged, true); } - [Test] - public void TestStoryboard() - { - AddStep("Restart", restart); - AddToggleStep("Passing", passing => - { - if (storyboard != null) storyboard.Passing = passing; - }); - } - - [Test] - public void TestStoryboardMissingVideo() - { - AddStep("Load storyboard with missing video", loadStoryboardNoVideo); - } - - [BackgroundDependencyLoader] - private void load() - { - Beatmap.ValueChanged += beatmapChanged; - } - - private void beatmapChanged(ValueChangedEvent e) - => loadStoryboard(e.NewValue); + private void beatmapChanged(ValueChangedEvent e) => loadStoryboard(e.NewValue); private void restart() { From f63d1ba612df01640d3abe79a1db5217a947f54a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 21 Aug 2020 18:52:53 +0900 Subject: [PATCH 091/320] Remove stray call to LoadTrack that was forgotten --- osu.Game/Screens/Menu/IntroScreen.cs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/osu.Game/Screens/Menu/IntroScreen.cs b/osu.Game/Screens/Menu/IntroScreen.cs index 363933694d..884cbfe107 100644 --- a/osu.Game/Screens/Menu/IntroScreen.cs +++ b/osu.Game/Screens/Menu/IntroScreen.cs @@ -12,7 +12,6 @@ using osu.Framework.Screens; using osu.Game.Beatmaps; using osu.Game.Configuration; using osu.Game.IO.Archives; -using osu.Game.Overlays; using osu.Game.Screens.Backgrounds; using osu.Game.Skinning; using osuTK; @@ -61,9 +60,6 @@ namespace osu.Game.Screens.Menu [Resolved] private AudioManager audio { get; set; } - [Resolved] - private MusicController musicController { get; set; } - /// /// Whether the is provided by osu! resources, rather than a user beatmap. /// Only valid during or after . @@ -168,8 +164,8 @@ namespace osu.Game.Screens.Menu if (!resuming) { beatmap.Value = initialBeatmap; - Track = musicController.CurrentTrack; - UsingThemedIntro = !initialBeatmap.LoadTrack().IsDummyDevice; + Track = initialBeatmap.Track; + UsingThemedIntro = !initialBeatmap.Track.IsDummyDevice; logo.MoveTo(new Vector2(0.5f)); logo.ScaleTo(Vector2.One); From 88d50b6c4751e7fc87580b8e5bed753052017fa3 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Sat, 22 Aug 2020 00:15:37 +0900 Subject: [PATCH 092/320] Remove alpha mangling from LegacyDecoder --- osu.Game/Beatmaps/Formats/LegacyDecoder.cs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/osu.Game/Beatmaps/Formats/LegacyDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyDecoder.cs index 44ef9bcacc..c15240a4f6 100644 --- a/osu.Game/Beatmaps/Formats/LegacyDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyDecoder.cs @@ -104,10 +104,6 @@ namespace osu.Game.Beatmaps.Formats try { byte alpha = split.Length == 4 ? byte.Parse(split[3]) : (byte)255; - - if (alpha == 0) - alpha = 255; - colour = new Color4(byte.Parse(split[0]), byte.Parse(split[1]), byte.Parse(split[2]), alpha); } catch From 2424fa08027ebe105e1102997e8379ec31528c0a Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Sat, 22 Aug 2020 00:15:58 +0900 Subject: [PATCH 093/320] Add helper methods --- osu.Game/Skinning/LegacySkinExtensions.cs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/osu.Game/Skinning/LegacySkinExtensions.cs b/osu.Game/Skinning/LegacySkinExtensions.cs index bb46dc8b9f..088eae4bce 100644 --- a/osu.Game/Skinning/LegacySkinExtensions.cs +++ b/osu.Game/Skinning/LegacySkinExtensions.cs @@ -9,6 +9,7 @@ using osu.Framework.Graphics.Animations; using osu.Framework.Graphics.OpenGL.Textures; using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Textures; +using osuTK.Graphics; using static osu.Game.Skinning.LegacySkinConfiguration; namespace osu.Game.Skinning @@ -62,6 +63,21 @@ namespace osu.Game.Skinning } } + public static Color4 ToLegacyColour(this Color4 colour) + { + if (colour.A == 0) + colour.A = 1; + return colour; + } + + public static T WithInitialColour(this T drawable, Color4 colour) + where T : Drawable + { + drawable.Alpha = colour.A; + drawable.Colour = ToLegacyColour(colour); + return drawable; + } + public class SkinnableTextureAnimation : TextureAnimation { [Resolved(canBeNull: true)] From eaba32335327dc0a4f987f8b8f35bb89a01d51cb Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Sat, 22 Aug 2020 00:17:35 +0900 Subject: [PATCH 094/320] Update catch with legacy colour setters --- .../Skinning/CatchLegacySkinTransformer.cs | 8 +++++++- osu.Game.Rulesets.Catch/Skinning/LegacyFruitPiece.cs | 3 +-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Skinning/CatchLegacySkinTransformer.cs b/osu.Game.Rulesets.Catch/Skinning/CatchLegacySkinTransformer.cs index d929da1a29..5abd87d6f4 100644 --- a/osu.Game.Rulesets.Catch/Skinning/CatchLegacySkinTransformer.cs +++ b/osu.Game.Rulesets.Catch/Skinning/CatchLegacySkinTransformer.cs @@ -6,6 +6,7 @@ using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Game.Skinning; using osuTK; +using osuTK.Graphics; namespace osu.Game.Rulesets.Catch.Skinning { @@ -61,7 +62,12 @@ namespace osu.Game.Rulesets.Catch.Skinning switch (lookup) { case CatchSkinColour colour: - return Source.GetConfig(new SkinCustomColourLookup(colour)); + var result = (Bindable)Source.GetConfig(new SkinCustomColourLookup(colour)); + if (result == null) + return null; + + result.Value = result.Value.ToLegacyColour(); + return (IBindable)result; } return Source.GetConfig(lookup); diff --git a/osu.Game.Rulesets.Catch/Skinning/LegacyFruitPiece.cs b/osu.Game.Rulesets.Catch/Skinning/LegacyFruitPiece.cs index 5be54d3882..c9dd1d1f3e 100644 --- a/osu.Game.Rulesets.Catch/Skinning/LegacyFruitPiece.cs +++ b/osu.Game.Rulesets.Catch/Skinning/LegacyFruitPiece.cs @@ -40,7 +40,6 @@ namespace osu.Game.Rulesets.Catch.Skinning colouredSprite = new Sprite { Texture = skin.GetTexture(lookupName), - Colour = drawableObject.AccentColour.Value, Anchor = Anchor.Centre, Origin = Anchor.Centre, }, @@ -76,7 +75,7 @@ namespace osu.Game.Rulesets.Catch.Skinning { base.LoadComplete(); - accentColour.BindValueChanged(colour => colouredSprite.Colour = colour.NewValue, true); + accentColour.BindValueChanged(colour => colouredSprite.Colour = colour.NewValue.ToLegacyColour(), true); } } } From 454564b18928a17525e12596ca38446844cb0600 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Sat, 22 Aug 2020 00:19:15 +0900 Subject: [PATCH 095/320] Update mania with legacy colour setters --- .../Skinning/LegacyColumnBackground.cs | 20 ++++++++----------- .../Skinning/LegacyHitTarget.cs | 2 +- 2 files changed, 9 insertions(+), 13 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Skinning/LegacyColumnBackground.cs b/osu.Game.Rulesets.Mania/Skinning/LegacyColumnBackground.cs index 64a7641421..b97547bbc6 100644 --- a/osu.Game.Rulesets.Mania/Skinning/LegacyColumnBackground.cs +++ b/osu.Game.Rulesets.Mania/Skinning/LegacyColumnBackground.cs @@ -58,28 +58,24 @@ namespace osu.Game.Rulesets.Mania.Skinning InternalChildren = new Drawable[] { - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = backgroundColour - }, - new Box + new Box { RelativeSizeAxes = Axes.Both }.WithInitialColour(backgroundColour), + new Container { RelativeSizeAxes = Axes.Y, Width = leftLineWidth, Scale = new Vector2(0.740f, 1), - Colour = lineColour, - Alpha = hasLeftLine ? 1 : 0 + Alpha = hasLeftLine ? 1 : 0, + Child = new Box { RelativeSizeAxes = Axes.Both }.WithInitialColour(lineColour) }, - new Box + new Container { Anchor = Anchor.TopRight, Origin = Anchor.TopRight, RelativeSizeAxes = Axes.Y, Width = rightLineWidth, Scale = new Vector2(0.740f, 1), - Colour = lineColour, - Alpha = hasRightLine ? 1 : 0 + Alpha = hasRightLine ? 1 : 0, + Child = new Box { RelativeSizeAxes = Axes.Both }.WithInitialColour(lineColour) }, lightContainer = new Container { @@ -90,7 +86,7 @@ namespace osu.Game.Rulesets.Mania.Skinning { Anchor = Anchor.BottomCentre, Origin = Anchor.BottomCentre, - Colour = lightColour, + Colour = lightColour.ToLegacyColour(), Texture = skin.GetTexture(lightImage), RelativeSizeAxes = Axes.X, Width = 1, diff --git a/osu.Game.Rulesets.Mania/Skinning/LegacyHitTarget.cs b/osu.Game.Rulesets.Mania/Skinning/LegacyHitTarget.cs index d055ef3480..2177eaa5e6 100644 --- a/osu.Game.Rulesets.Mania/Skinning/LegacyHitTarget.cs +++ b/osu.Game.Rulesets.Mania/Skinning/LegacyHitTarget.cs @@ -56,7 +56,7 @@ namespace osu.Game.Rulesets.Mania.Skinning Anchor = Anchor.CentreLeft, RelativeSizeAxes = Axes.X, Height = 1, - Colour = lineColour, + Colour = lineColour.ToLegacyColour(), Alpha = showJudgementLine ? 0.9f : 0 } } From 16a2ab9dea4fd58e56eb00c017e61fce002b7ed2 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Sat, 22 Aug 2020 00:20:33 +0900 Subject: [PATCH 096/320] Update osu with legacy colour setters --- osu.Game.Rulesets.Osu/Skinning/LegacyMainCirclePiece.cs | 3 +-- osu.Game.Rulesets.Osu/Skinning/LegacySliderBall.cs | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Skinning/LegacyMainCirclePiece.cs b/osu.Game.Rulesets.Osu/Skinning/LegacyMainCirclePiece.cs index 0ab3e8825b..8a6beddb51 100644 --- a/osu.Game.Rulesets.Osu/Skinning/LegacyMainCirclePiece.cs +++ b/osu.Game.Rulesets.Osu/Skinning/LegacyMainCirclePiece.cs @@ -59,7 +59,6 @@ namespace osu.Game.Rulesets.Osu.Skinning hitCircleSprite = new Sprite { Texture = getTextureWithFallback(string.Empty), - Colour = drawableObject.AccentColour.Value, Anchor = Anchor.Centre, Origin = Anchor.Centre, }, @@ -107,7 +106,7 @@ namespace osu.Game.Rulesets.Osu.Skinning base.LoadComplete(); state.BindValueChanged(updateState, true); - accentColour.BindValueChanged(colour => hitCircleSprite.Colour = colour.NewValue, true); + accentColour.BindValueChanged(colour => hitCircleSprite.Colour = colour.NewValue.ToLegacyColour(), true); indexInCurrentCombo.BindValueChanged(index => hitCircleText.Text = (index.NewValue + 1).ToString(), true); } diff --git a/osu.Game.Rulesets.Osu/Skinning/LegacySliderBall.cs b/osu.Game.Rulesets.Osu/Skinning/LegacySliderBall.cs index 0f586034d5..3b75fcc8a0 100644 --- a/osu.Game.Rulesets.Osu/Skinning/LegacySliderBall.cs +++ b/osu.Game.Rulesets.Osu/Skinning/LegacySliderBall.cs @@ -28,7 +28,7 @@ namespace osu.Game.Rulesets.Osu.Skinning [BackgroundDependencyLoader] private void load(ISkinSource skin, DrawableHitObject drawableObject) { - animationContent.Colour = skin.GetConfig(OsuSkinColour.SliderBall)?.Value ?? Color4.White; + var ballColour = skin.GetConfig(OsuSkinColour.SliderBall)?.Value ?? Color4.White; InternalChildren = new[] { @@ -39,7 +39,7 @@ namespace osu.Game.Rulesets.Osu.Skinning Texture = skin.GetTexture("sliderb-nd"), Colour = new Color4(5, 5, 5, 255), }, - animationContent.With(d => + animationContent.WithInitialColour(ballColour).With(d => { d.Anchor = Anchor.Centre; d.Origin = Anchor.Centre; From 9fbc5f3aeb546fc27572a4c511793d6dd91088ea Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Sat, 22 Aug 2020 00:23:08 +0900 Subject: [PATCH 097/320] Update taiko with legacy colour setters --- osu.Game.Rulesets.Taiko/Skinning/LegacyCirclePiece.cs | 2 +- osu.Game.Rulesets.Taiko/Skinning/LegacyDrumRoll.cs | 6 +++--- osu.Game.Rulesets.Taiko/Skinning/LegacyHit.cs | 5 +++-- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Skinning/LegacyCirclePiece.cs b/osu.Game.Rulesets.Taiko/Skinning/LegacyCirclePiece.cs index bfcf268c3d..ed69b529ed 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/LegacyCirclePiece.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/LegacyCirclePiece.cs @@ -90,7 +90,7 @@ namespace osu.Game.Rulesets.Taiko.Skinning private void updateAccentColour() { - backgroundLayer.Colour = accentColour; + backgroundLayer.Colour = accentColour.ToLegacyColour(); } } } diff --git a/osu.Game.Rulesets.Taiko/Skinning/LegacyDrumRoll.cs b/osu.Game.Rulesets.Taiko/Skinning/LegacyDrumRoll.cs index 8223e3bc01..6bb8f9433e 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/LegacyDrumRoll.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/LegacyDrumRoll.cs @@ -76,9 +76,9 @@ namespace osu.Game.Rulesets.Taiko.Skinning private void updateAccentColour() { - headCircle.AccentColour = accentColour; - body.Colour = accentColour; - end.Colour = accentColour; + headCircle.AccentColour = accentColour.ToLegacyColour(); + body.Colour = accentColour.ToLegacyColour(); + end.Colour = accentColour.ToLegacyColour(); } } } diff --git a/osu.Game.Rulesets.Taiko/Skinning/LegacyHit.cs b/osu.Game.Rulesets.Taiko/Skinning/LegacyHit.cs index 656728f6e4..f36aae205a 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/LegacyHit.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/LegacyHit.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Allocation; +using osu.Game.Skinning; using osuTK.Graphics; namespace osu.Game.Rulesets.Taiko.Skinning @@ -18,9 +19,9 @@ namespace osu.Game.Rulesets.Taiko.Skinning [BackgroundDependencyLoader] private void load() { - AccentColour = component == TaikoSkinComponents.CentreHit + AccentColour = (component == TaikoSkinComponents.CentreHit ? new Color4(235, 69, 44, 255) - : new Color4(67, 142, 172, 255); + : new Color4(67, 142, 172, 255)).ToLegacyColour(); } } } From f89b6f44653112a86cc5df93be0d6e11ad0ad8d3 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Sat, 22 Aug 2020 00:52:53 +0900 Subject: [PATCH 098/320] Add xmldocs --- osu.Game/Skinning/LegacySkinExtensions.cs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/osu.Game/Skinning/LegacySkinExtensions.cs b/osu.Game/Skinning/LegacySkinExtensions.cs index 088eae4bce..ee7d74d7ec 100644 --- a/osu.Game/Skinning/LegacySkinExtensions.cs +++ b/osu.Game/Skinning/LegacySkinExtensions.cs @@ -63,6 +63,11 @@ namespace osu.Game.Skinning } } + /// + /// The resultant colour after setting a post-constructor colour in osu!stable. + /// + /// The to convert. + /// The converted . public static Color4 ToLegacyColour(this Color4 colour) { if (colour.A == 0) @@ -70,6 +75,16 @@ namespace osu.Game.Skinning return colour; } + /// + /// Equivalent of setting a colour in the constructor in osu!stable. + /// Doubles the alpha channel into and uses to set . + /// + /// + /// Beware: Any existing value in is overwritten. + /// + /// The to set the "InitialColour" of. + /// The to set. + /// The given . public static T WithInitialColour(this T drawable, Color4 colour) where T : Drawable { From 356c67f00d778e1f6d2535eb534a864d6b04caa4 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Sat, 22 Aug 2020 00:55:03 +0900 Subject: [PATCH 099/320] Remove outdated/wrong test --- osu.Game.Tests/Resources/skin-zero-alpha-colour.ini | 5 ----- osu.Game.Tests/Skins/LegacySkinDecoderTest.cs | 10 ---------- 2 files changed, 15 deletions(-) delete mode 100644 osu.Game.Tests/Resources/skin-zero-alpha-colour.ini diff --git a/osu.Game.Tests/Resources/skin-zero-alpha-colour.ini b/osu.Game.Tests/Resources/skin-zero-alpha-colour.ini deleted file mode 100644 index 3c0dae6b13..0000000000 --- a/osu.Game.Tests/Resources/skin-zero-alpha-colour.ini +++ /dev/null @@ -1,5 +0,0 @@ -[General] -Version: latest - -[Colours] -Combo1: 255,255,255,0 \ No newline at end of file diff --git a/osu.Game.Tests/Skins/LegacySkinDecoderTest.cs b/osu.Game.Tests/Skins/LegacySkinDecoderTest.cs index c408d2f182..aedf26ee75 100644 --- a/osu.Game.Tests/Skins/LegacySkinDecoderTest.cs +++ b/osu.Game.Tests/Skins/LegacySkinDecoderTest.cs @@ -108,15 +108,5 @@ namespace osu.Game.Tests.Skins using (var stream = new LineBufferedReader(resStream)) Assert.That(decoder.Decode(stream).LegacyVersion, Is.EqualTo(1.0m)); } - - [Test] - public void TestDecodeColourWithZeroAlpha() - { - var decoder = new LegacySkinDecoder(); - - using (var resStream = TestResources.OpenResource("skin-zero-alpha-colour.ini")) - using (var stream = new LineBufferedReader(resStream)) - Assert.That(decoder.Decode(stream).ComboColours[0].A, Is.EqualTo(1.0f)); - } } } From 08078b9513895806f9df2a08922fc7c4bf826fd9 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Sat, 22 Aug 2020 00:56:29 +0900 Subject: [PATCH 100/320] Rename method to remove "InitialColour" namings --- osu.Game.Rulesets.Mania/Skinning/LegacyColumnBackground.cs | 6 +++--- osu.Game.Rulesets.Osu/Skinning/LegacySliderBall.cs | 2 +- osu.Game/Skinning/LegacySkinExtensions.cs | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Skinning/LegacyColumnBackground.cs b/osu.Game.Rulesets.Mania/Skinning/LegacyColumnBackground.cs index b97547bbc6..54a16b840f 100644 --- a/osu.Game.Rulesets.Mania/Skinning/LegacyColumnBackground.cs +++ b/osu.Game.Rulesets.Mania/Skinning/LegacyColumnBackground.cs @@ -58,14 +58,14 @@ namespace osu.Game.Rulesets.Mania.Skinning InternalChildren = new Drawable[] { - new Box { RelativeSizeAxes = Axes.Both }.WithInitialColour(backgroundColour), + new Box { RelativeSizeAxes = Axes.Both }.WithLegacyColour(backgroundColour), new Container { RelativeSizeAxes = Axes.Y, Width = leftLineWidth, Scale = new Vector2(0.740f, 1), Alpha = hasLeftLine ? 1 : 0, - Child = new Box { RelativeSizeAxes = Axes.Both }.WithInitialColour(lineColour) + Child = new Box { RelativeSizeAxes = Axes.Both }.WithLegacyColour(lineColour) }, new Container { @@ -75,7 +75,7 @@ namespace osu.Game.Rulesets.Mania.Skinning Width = rightLineWidth, Scale = new Vector2(0.740f, 1), Alpha = hasRightLine ? 1 : 0, - Child = new Box { RelativeSizeAxes = Axes.Both }.WithInitialColour(lineColour) + Child = new Box { RelativeSizeAxes = Axes.Both }.WithLegacyColour(lineColour) }, lightContainer = new Container { diff --git a/osu.Game.Rulesets.Osu/Skinning/LegacySliderBall.cs b/osu.Game.Rulesets.Osu/Skinning/LegacySliderBall.cs index 3b75fcc8a0..27dec1b691 100644 --- a/osu.Game.Rulesets.Osu/Skinning/LegacySliderBall.cs +++ b/osu.Game.Rulesets.Osu/Skinning/LegacySliderBall.cs @@ -39,7 +39,7 @@ namespace osu.Game.Rulesets.Osu.Skinning Texture = skin.GetTexture("sliderb-nd"), Colour = new Color4(5, 5, 5, 255), }, - animationContent.WithInitialColour(ballColour).With(d => + animationContent.WithLegacyColour(ballColour).With(d => { d.Anchor = Anchor.Centre; d.Origin = Anchor.Centre; diff --git a/osu.Game/Skinning/LegacySkinExtensions.cs b/osu.Game/Skinning/LegacySkinExtensions.cs index ee7d74d7ec..7420f82f04 100644 --- a/osu.Game/Skinning/LegacySkinExtensions.cs +++ b/osu.Game/Skinning/LegacySkinExtensions.cs @@ -82,10 +82,10 @@ namespace osu.Game.Skinning /// /// Beware: Any existing value in is overwritten. /// - /// The to set the "InitialColour" of. + /// The to set the colour of. /// The to set. /// The given . - public static T WithInitialColour(this T drawable, Color4 colour) + public static T WithLegacyColour(this T drawable, Color4 colour) where T : Drawable { drawable.Alpha = colour.A; From b72f06fef68a219b599671cefe3ce2e2b252d3e9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 22 Aug 2020 19:42:34 +0900 Subject: [PATCH 101/320] Centralise and clarify LoadTrack documentation --- osu.Game/Beatmaps/IWorkingBeatmap.cs | 10 +++++++++- osu.Game/Beatmaps/WorkingBeatmap.cs | 4 ---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/osu.Game/Beatmaps/IWorkingBeatmap.cs b/osu.Game/Beatmaps/IWorkingBeatmap.cs index 88d73fd7c4..bcd94d76fd 100644 --- a/osu.Game/Beatmaps/IWorkingBeatmap.cs +++ b/osu.Game/Beatmaps/IWorkingBeatmap.cs @@ -56,8 +56,16 @@ namespace osu.Game.Beatmaps IBeatmap GetPlayableBeatmap(RulesetInfo ruleset, IReadOnlyList mods = null, TimeSpan? timeout = null); /// - /// Retrieves the which this provides. + /// Load a new audio track instance for this beatmap. This should be called once before accessing . + /// The caller of this method is responsible for the lifetime of the track. /// + /// + /// In a standard game context, the loading of the track is managed solely by MusicController, which will + /// automatically load the track of the current global IBindable WorkingBeatmap. + /// As such, this method should only be called in very special scenarios, such as external tests or apps which are + /// outside of the game context. + /// + /// A fresh track instance, which will also be available via . Track LoadTrack(); } } diff --git a/osu.Game/Beatmaps/WorkingBeatmap.cs b/osu.Game/Beatmaps/WorkingBeatmap.cs index 6a89739e6f..6a161e6e04 100644 --- a/osu.Game/Beatmaps/WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/WorkingBeatmap.cs @@ -261,10 +261,6 @@ namespace osu.Game.Beatmaps private Track loadedTrack; - /// - /// Load a new audio track instance for this beatmap. - /// - /// A fresh track instance, which will also be available via . [NotNull] public Track LoadTrack() => loadedTrack = GetBeatmapTrack() ?? GetVirtualTrack(1000); From db5226042747b7e5078903cdb14d3a36f9e4af73 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 22 Aug 2020 19:44:54 +0900 Subject: [PATCH 102/320] Rename and clarify comment regarding "previous" track disposal --- osu.Game/Overlays/MusicController.cs | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index 112026d9e2..6d5b5d43cd 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -331,10 +331,10 @@ namespace osu.Game.Overlays { var lastTrack = CurrentTrack; - var newTrack = new DrawableTrack(current.LoadTrack()); - newTrack.Completed += () => onTrackCompleted(current); + var queuedTrack = new DrawableTrack(current.LoadTrack()); + queuedTrack.Completed += () => onTrackCompleted(current); - CurrentTrack = newTrack; + CurrentTrack = queuedTrack; // At this point we may potentially be in an async context from tests. This is extremely dangerous but we have to make do for now. // CurrentTrack is immediately updated above for situations where a immediate knowledge about the new track is required, @@ -343,12 +343,13 @@ namespace osu.Game.Overlays { lastTrack.Expire(); - if (newTrack == CurrentTrack) - AddInternal(newTrack); + if (queuedTrack == CurrentTrack) + AddInternal(queuedTrack); else { - // If the track has changed via changeTrack() being called multiple times in a single update, force disposal on the old track. - newTrack.Dispose(); + // If the track has changed since the call to changeTrack, it is safe to dispose the + // queued track rather than consume it. + queuedTrack.Dispose(); } }); } From 122265ff0e233a72a48a329370e8f6f8c1fde6e3 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 22 Aug 2020 19:47:05 +0900 Subject: [PATCH 103/320] Revert non-track usage --- osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs index c6bfdda698..c617950c64 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs @@ -86,7 +86,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline track = b.NewValue.Track; // todo: i don't think this is safe, the track may not be loaded yet. - if (b.NewValue.Track.Length > 0) + if (track.Length > 0) { MaxZoom = getZoomLevelForVisibleMilliseconds(500); MinZoom = getZoomLevelForVisibleMilliseconds(10000); From e6646b9877883560187415b1781e3a726da1ca43 Mon Sep 17 00:00:00 2001 From: Craftplacer Date: Sun, 23 Aug 2020 15:08:02 +0200 Subject: [PATCH 104/320] Resolve review comments --- .../Formats/LegacyBeatmapEncoderTest.cs | 31 +++++++++++++------ .../Beatmaps/IO/ImportBeatmapTest.cs | 5 ++- osu.Game/Beatmaps/BeatmapManager.cs | 12 +++++-- .../Beatmaps/Formats/IHasCustomColours.cs | 2 +- .../Beatmaps/Formats/LegacyBeatmapEncoder.cs | 25 ++++++++------- osu.Game/Screens/Edit/Editor.cs | 4 +-- osu.Game/Screens/Edit/EditorChangeHandler.cs | 4 +-- .../Skinning/LegacyManiaSkinConfiguration.cs | 2 +- osu.Game/Skinning/SkinConfiguration.cs | 16 +++++----- 9 files changed, 59 insertions(+), 42 deletions(-) diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs index db18f9b444..4e9e6743c9 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs @@ -28,25 +28,27 @@ namespace osu.Game.Tests.Beatmaps.Formats [TestFixture] public class LegacyBeatmapEncoderTest { - private static readonly DllResourceStore resource_store = TestResources.GetStore(); + private static readonly DllResourceStore beatmaps_resource_store = TestResources.GetStore(); - private static IEnumerable allBeatmaps = resource_store.GetAvailableResources().Where(res => res.EndsWith(".osu")); + private static IEnumerable allBeatmaps = beatmaps_resource_store.GetAvailableResources().Where(res => res.EndsWith(".osu")); [TestCaseSource(nameof(allBeatmaps))] public void TestEncodeDecodeStability(string name) { - var decoded = decodeFromLegacy(TestResources.GetStore().GetStream(name)); - var decodedAfterEncode = decodeFromLegacy(encodeToLegacy(decoded)); + var decoded = decodeFromLegacy(TestResources.GetStore().GetStream(name), name); + var decodedAfterEncode = decodeFromLegacy(encodeToLegacy(decoded), name); - sort(decoded.beatmap); - sort(decodedAfterEncode.beatmap); + sort(decoded); + sort(decodedAfterEncode); Assert.That(decodedAfterEncode.beatmap.Serialize(), Is.EqualTo(decoded.beatmap.Serialize())); Assert.IsTrue(decoded.beatmapSkin.Configuration.Equals(decodedAfterEncode.beatmapSkin.Configuration)); } - private void sort(IBeatmap beatmap) + private void sort((IBeatmap, LegacyBeatmapSkin) bs) { + var (beatmap, beatmapSkin) = bs; + // Sort control points to ensure a sane ordering, as they may be parsed in different orders. This works because each group contains only uniquely-typed control points. foreach (var g in beatmap.ControlPointInfo.Groups) { @@ -55,17 +57,26 @@ namespace osu.Game.Tests.Beatmaps.Formats } } - private (IBeatmap beatmap, LegacySkin beatmapSkin) decodeFromLegacy(Stream stream) + private (IBeatmap beatmap, LegacyBeatmapSkin beatmapSkin) decodeFromLegacy(Stream stream, string name) { using (var reader = new LineBufferedReader(stream)) { var beatmap = new LegacyBeatmapDecoder { ApplyOffsets = false }.Decode(reader); - var beatmapSkin = new LegacyBeatmapSkin(beatmap.BeatmapInfo, resource_store, null); + beatmap.BeatmapInfo.BeatmapSet.Files = new List + { + new BeatmapSetFileInfo + { + Filename = name, + FileInfo = new osu.Game.IO.FileInfo() { Hash = name } + } + }; + + var beatmapSkin = new LegacyBeatmapSkin(beatmap.BeatmapInfo, beatmaps_resource_store, null); return (convert(beatmap), beatmapSkin); } } - private Stream encodeToLegacy((IBeatmap beatmap, LegacySkin beatmapSkin) fullBeatmap) + private Stream encodeToLegacy((IBeatmap beatmap, LegacyBeatmapSkin beatmapSkin) fullBeatmap) { var (beatmap, beatmapSkin) = fullBeatmap; var stream = new MemoryStream(); diff --git a/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs b/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs index 17271184c0..0151678db3 100644 --- a/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs +++ b/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs @@ -730,8 +730,7 @@ namespace osu.Game.Tests.Beatmaps.IO BeatmapSetInfo setToUpdate = manager.GetAllUsableBeatmapSets()[0]; var beatmapInfo = setToUpdate.Beatmaps.First(b => b.RulesetID == 0); - var workingBeatmap = manager.GetWorkingBeatmap(setToUpdate.Beatmaps.First(b => b.RulesetID == 0)); - Beatmap beatmapToUpdate = (Beatmap)workingBeatmap.Beatmap; + Beatmap beatmapToUpdate = (Beatmap)manager.GetWorkingBeatmap(setToUpdate.Beatmaps.First(b => b.RulesetID == 0)).Beatmap; BeatmapSetFileInfo fileToUpdate = setToUpdate.Files.First(f => beatmapToUpdate.BeatmapInfo.Path.Contains(f.Filename)); string oldMd5Hash = beatmapToUpdate.BeatmapInfo.MD5Hash; @@ -739,7 +738,7 @@ namespace osu.Game.Tests.Beatmaps.IO beatmapToUpdate.HitObjects.Clear(); beatmapToUpdate.HitObjects.Add(new HitCircle { StartTime = 5000 }); - manager.Save(beatmapInfo, beatmapToUpdate, workingBeatmap.Skin); + manager.Save(beatmapInfo, beatmapToUpdate); // Check that the old file reference has been removed Assert.That(manager.QueryBeatmapSet(s => s.ID == setToUpdate.ID).Files.All(f => f.ID != fileToUpdate.ID)); diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index bd757d30ca..86d35749ac 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -195,8 +195,8 @@ namespace osu.Game.Beatmaps /// /// The to save the content against. The file referenced by will be replaced. /// The content to write. - /// Optional beatmap skin for inline skin configuration in beatmap files. - public void Save(BeatmapInfo info, IBeatmap beatmapContent, ISkin skin) + /// The beatmap content to write, or null if not to be changed. + public void Save(BeatmapInfo info, IBeatmap beatmapContent, LegacyBeatmapSkin beatmapSkin = null) { var setInfo = QueryBeatmapSet(s => s.Beatmaps.Any(b => b.ID == info.ID)); @@ -204,7 +204,13 @@ namespace osu.Game.Beatmaps { using (var sw = new StreamWriter(stream, Encoding.UTF8, 1024, true)) { - new LegacyBeatmapEncoder(beatmapContent, skin).Encode(sw); + if (beatmapSkin == null) + { + var workingBeatmap = GetWorkingBeatmap(info); + beatmapSkin = (workingBeatmap.Skin is LegacyBeatmapSkin legacy) ? legacy : null; + } + + new LegacyBeatmapEncoder(beatmapContent, beatmapSkin).Encode(sw); } stream.Seek(0, SeekOrigin.Begin); diff --git a/osu.Game/Beatmaps/Formats/IHasCustomColours.cs b/osu.Game/Beatmaps/Formats/IHasCustomColours.cs index 8f6c7dc328..1ac5ca83cb 100644 --- a/osu.Game/Beatmaps/Formats/IHasCustomColours.cs +++ b/osu.Game/Beatmaps/Formats/IHasCustomColours.cs @@ -8,6 +8,6 @@ namespace osu.Game.Beatmaps.Formats { public interface IHasCustomColours { - Dictionary CustomColours { get; set; } + IDictionary CustomColours { get; } } } diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs index 716f1bc814..497c3c88d0 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs @@ -16,6 +16,7 @@ using osu.Game.Rulesets.Objects.Legacy; using osu.Game.Rulesets.Objects.Types; using osu.Game.Skinning; using osuTK; +using osuTK.Graphics; namespace osu.Game.Beatmaps.Formats { @@ -24,11 +25,14 @@ namespace osu.Game.Beatmaps.Formats public const int LATEST_VERSION = 128; private readonly IBeatmap beatmap; - private readonly ISkin skin; + private readonly LegacyBeatmapSkin skin; - /// The beatmap to encode - /// An optional skin, for encoding the beatmap's combo colours. This will only work if the parameter is a type of . - public LegacyBeatmapEncoder(IBeatmap beatmap, [CanBeNull] ISkin skin) + /// + /// Creates a new . + /// + /// The beatmap to encode. + /// An optional skin, for encoding the beatmap's combo colours. + public LegacyBeatmapEncoder(IBeatmap beatmap, [CanBeNull] LegacyBeatmapSkin skin) { this.beatmap = beatmap; this.skin = skin; @@ -210,7 +214,7 @@ namespace osu.Game.Beatmaps.Formats if (!(skin is LegacyBeatmapSkin legacySkin)) return; - var colours = legacySkin?.Configuration.ComboColours; + var colours = legacySkin.GetConfig>(GlobalSkinColours.ComboColours)?.Value; if (colours == null || colours.Count == 0) return; @@ -221,12 +225,11 @@ namespace osu.Game.Beatmaps.Formats { var comboColour = colours[i]; - var r = (byte)(comboColour.R * byte.MaxValue); - var g = (byte)(comboColour.G * byte.MaxValue); - var b = (byte)(comboColour.B * byte.MaxValue); - var a = (byte)(comboColour.A * byte.MaxValue); - - writer.WriteLine($"Combo{i}: {r},{g},{b},{a}"); + writer.Write(FormattableString.Invariant($"Combo{i}: ")); + writer.Write(FormattableString.Invariant($"{(byte)(comboColour.R * byte.MaxValue)},")); + writer.Write(FormattableString.Invariant($"{(byte)(comboColour.G * byte.MaxValue)},")); + writer.Write(FormattableString.Invariant($"{(byte)(comboColour.B * byte.MaxValue)},")); + writer.WriteLine(FormattableString.Invariant($"{(byte)(comboColour.A * byte.MaxValue)}")); } } diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index a585db1ee9..7bd6529897 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -65,7 +65,7 @@ namespace osu.Game.Screens.Edit private IBeatmap playableBeatmap; private EditorBeatmap editorBeatmap; private EditorChangeHandler changeHandler; - private ISkin beatmapSkin; + private LegacyBeatmapSkin beatmapSkin; private DependencyContainer dependencies; @@ -94,7 +94,6 @@ namespace osu.Game.Screens.Edit try { playableBeatmap = Beatmap.Value.GetPlayableBeatmap(Beatmap.Value.BeatmapInfo.Ruleset); - beatmapSkin = Beatmap.Value.Skin; } catch (Exception e) { @@ -107,6 +106,7 @@ namespace osu.Game.Screens.Edit AddInternal(editorBeatmap = new EditorBeatmap(playableBeatmap)); dependencies.CacheAs(editorBeatmap); + beatmapSkin = (Beatmap.Value.Skin is LegacyBeatmapSkin legacy) ? legacy : null; changeHandler = new EditorChangeHandler(editorBeatmap, beatmapSkin); dependencies.CacheAs(changeHandler); diff --git a/osu.Game/Screens/Edit/EditorChangeHandler.cs b/osu.Game/Screens/Edit/EditorChangeHandler.cs index 0489236d45..1d10eaf5cb 100644 --- a/osu.Game/Screens/Edit/EditorChangeHandler.cs +++ b/osu.Game/Screens/Edit/EditorChangeHandler.cs @@ -26,7 +26,7 @@ namespace osu.Game.Screens.Edit private int currentState = -1; private readonly EditorBeatmap editorBeatmap; - private readonly ISkin beatmapSkin; + private readonly LegacyBeatmapSkin beatmapSkin; private int bulkChangesStarted; private bool isRestoring; @@ -37,7 +37,7 @@ namespace osu.Game.Screens.Edit /// /// The to track the s of. /// The skin to track the inline skin configuration of. - public EditorChangeHandler(EditorBeatmap editorBeatmap, ISkin beatmapSkin) + public EditorChangeHandler(EditorBeatmap editorBeatmap, LegacyBeatmapSkin beatmapSkin) { this.editorBeatmap = editorBeatmap; diff --git a/osu.Game/Skinning/LegacyManiaSkinConfiguration.cs b/osu.Game/Skinning/LegacyManiaSkinConfiguration.cs index af7d6007f3..f92da0b446 100644 --- a/osu.Game/Skinning/LegacyManiaSkinConfiguration.cs +++ b/osu.Game/Skinning/LegacyManiaSkinConfiguration.cs @@ -23,7 +23,7 @@ namespace osu.Game.Skinning public readonly int Keys; - public Dictionary CustomColours { get; set; } = new Dictionary(); + public IDictionary CustomColours { get; set; } = new SortedDictionary(); public Dictionary ImageLookups = new Dictionary(); diff --git a/osu.Game/Skinning/SkinConfiguration.cs b/osu.Game/Skinning/SkinConfiguration.cs index a48d713771..9565eee827 100644 --- a/osu.Game/Skinning/SkinConfiguration.cs +++ b/osu.Game/Skinning/SkinConfiguration.cs @@ -12,7 +12,7 @@ namespace osu.Game.Skinning /// /// An empty skin configuration. /// - public class SkinConfiguration : IHasComboColours, IHasCustomColours, IEquatable + public class SkinConfiguration : IEquatable, IHasComboColours, IHasCustomColours { public readonly SkinInfo SkinInfo = new SkinInfo(); @@ -47,16 +47,14 @@ namespace osu.Game.Skinning public void AddComboColours(params Color4[] colours) => comboColours.AddRange(colours); - public Dictionary CustomColours { get; set; } = new Dictionary(); + public IDictionary CustomColours { get; set; } = new SortedDictionary(); - public readonly Dictionary ConfigDictionary = new Dictionary(); + public readonly SortedDictionary ConfigDictionary = new SortedDictionary(); public bool Equals(SkinConfiguration other) - { - return other != null && - ConfigDictionary.SequenceEqual(other.ConfigDictionary) && - ComboColours.SequenceEqual(other.ComboColours) && - CustomColours?.SequenceEqual(other.CustomColours) == true; - } + => other != null + && ConfigDictionary.SequenceEqual(other.ConfigDictionary) + && ComboColours.SequenceEqual(other.ComboColours) + && CustomColours?.SequenceEqual(other.CustomColours) == true; } } From 492be0e0169248794305cda313b187b1ca0c3894 Mon Sep 17 00:00:00 2001 From: Craftplacer Date: Sun, 23 Aug 2020 15:23:10 +0200 Subject: [PATCH 105/320] Fix formatting --- .../Beatmaps/Formats/LegacyBeatmapEncoderTest.cs | 8 +++----- osu.Game/Skinning/LegacyManiaSkinConfiguration.cs | 2 +- osu.Game/Skinning/SkinConfiguration.cs | 11 +++++------ 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs index 4e9e6743c9..f093180085 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs @@ -45,12 +45,10 @@ namespace osu.Game.Tests.Beatmaps.Formats Assert.IsTrue(decoded.beatmapSkin.Configuration.Equals(decodedAfterEncode.beatmapSkin.Configuration)); } - private void sort((IBeatmap, LegacyBeatmapSkin) bs) + private void sort((IBeatmap beatmap, LegacyBeatmapSkin beatmapSkin) tuple) { - var (beatmap, beatmapSkin) = bs; - // Sort control points to ensure a sane ordering, as they may be parsed in different orders. This works because each group contains only uniquely-typed control points. - foreach (var g in beatmap.ControlPointInfo.Groups) + foreach (var g in tuple.beatmap.ControlPointInfo.Groups) { ArrayList.Adapter((IList)g.ControlPoints).Sort( Comparer.Create((c1, c2) => string.Compare(c1.GetType().ToString(), c2.GetType().ToString(), StringComparison.Ordinal))); @@ -67,7 +65,7 @@ namespace osu.Game.Tests.Beatmaps.Formats new BeatmapSetFileInfo { Filename = name, - FileInfo = new osu.Game.IO.FileInfo() { Hash = name } + FileInfo = new osu.Game.IO.FileInfo { Hash = name } } }; diff --git a/osu.Game/Skinning/LegacyManiaSkinConfiguration.cs b/osu.Game/Skinning/LegacyManiaSkinConfiguration.cs index f92da0b446..baa7fa817c 100644 --- a/osu.Game/Skinning/LegacyManiaSkinConfiguration.cs +++ b/osu.Game/Skinning/LegacyManiaSkinConfiguration.cs @@ -23,7 +23,7 @@ namespace osu.Game.Skinning public readonly int Keys; - public IDictionary CustomColours { get; set; } = new SortedDictionary(); + public IDictionary CustomColours { get; } = new SortedDictionary(); public Dictionary ImageLookups = new Dictionary(); diff --git a/osu.Game/Skinning/SkinConfiguration.cs b/osu.Game/Skinning/SkinConfiguration.cs index 9565eee827..27589577e6 100644 --- a/osu.Game/Skinning/SkinConfiguration.cs +++ b/osu.Game/Skinning/SkinConfiguration.cs @@ -47,14 +47,13 @@ namespace osu.Game.Skinning public void AddComboColours(params Color4[] colours) => comboColours.AddRange(colours); - public IDictionary CustomColours { get; set; } = new SortedDictionary(); + public IDictionary CustomColours { get; } = new SortedDictionary(); public readonly SortedDictionary ConfigDictionary = new SortedDictionary(); - public bool Equals(SkinConfiguration other) - => other != null - && ConfigDictionary.SequenceEqual(other.ConfigDictionary) - && ComboColours.SequenceEqual(other.ComboColours) - && CustomColours?.SequenceEqual(other.CustomColours) == true; + public bool Equals(SkinConfiguration other) => other != null + && ConfigDictionary.SequenceEqual(other.ConfigDictionary) + && ComboColours.SequenceEqual(other.ComboColours) + && CustomColours?.SequenceEqual(other.CustomColours) == true; } } From 8f9e090f4c02549c8ed613e8c70785eed38d17be Mon Sep 17 00:00:00 2001 From: Craftplacer Date: Sun, 23 Aug 2020 15:39:48 +0200 Subject: [PATCH 106/320] Remove Indent --- osu.Game/Skinning/SkinConfiguration.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/osu.Game/Skinning/SkinConfiguration.cs b/osu.Game/Skinning/SkinConfiguration.cs index 27589577e6..2ac4dfa0c8 100644 --- a/osu.Game/Skinning/SkinConfiguration.cs +++ b/osu.Game/Skinning/SkinConfiguration.cs @@ -51,9 +51,6 @@ namespace osu.Game.Skinning public readonly SortedDictionary ConfigDictionary = new SortedDictionary(); - public bool Equals(SkinConfiguration other) => other != null - && ConfigDictionary.SequenceEqual(other.ConfigDictionary) - && ComboColours.SequenceEqual(other.ComboColours) - && CustomColours?.SequenceEqual(other.CustomColours) == true; + public bool Equals(SkinConfiguration other) => other != null && ConfigDictionary.SequenceEqual(other.ConfigDictionary) && ComboColours.SequenceEqual(other.ComboColours) && CustomColours?.SequenceEqual(other.CustomColours) == true; } } From dca307e93379e258c15b5423130014afb9f8f03a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 24 Aug 2020 13:02:39 +0900 Subject: [PATCH 107/320] Use beatmap directly in ReadyButton --- osu.Game/Screens/Multi/Match/Components/ReadyButton.cs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/osu.Game/Screens/Multi/Match/Components/ReadyButton.cs b/osu.Game/Screens/Multi/Match/Components/ReadyButton.cs index 384d3bd5a5..a64f24dd7e 100644 --- a/osu.Game/Screens/Multi/Match/Components/ReadyButton.cs +++ b/osu.Game/Screens/Multi/Match/Components/ReadyButton.cs @@ -10,7 +10,6 @@ using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Graphics.UserInterface; using osu.Game.Online.Multiplayer; -using osu.Game.Overlays; namespace osu.Game.Screens.Multi.Match.Components { @@ -27,9 +26,6 @@ namespace osu.Game.Screens.Multi.Match.Components [Resolved] private BeatmapManager beatmaps { get; set; } - [Resolved] - private MusicController musicController { get; set; } - private bool hasBeatmap; public ReadyButton() @@ -104,7 +100,7 @@ namespace osu.Game.Screens.Multi.Match.Components return; } - bool hasEnoughTime = DateTimeOffset.UtcNow.AddSeconds(30).AddMilliseconds(musicController.CurrentTrack.Length) < endDate.Value; + bool hasEnoughTime = DateTimeOffset.UtcNow.AddSeconds(30).AddMilliseconds(gameBeatmap.Value.Track.Length) < endDate.Value; Enabled.Value = hasBeatmap && hasEnoughTime; } From ab8d9be095e4925d67cb1c06be49a2e92f24195f Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 25 Aug 2020 15:16:41 +0900 Subject: [PATCH 108/320] Move out into a separate method --- .../Skinning/CatchLegacySkinTransformer.cs | 2 +- .../Skinning/LegacyFruitPiece.cs | 2 +- .../Skinning/LegacyColumnBackground.cs | 17 +++++-- .../Skinning/LegacyHitTarget.cs | 2 +- .../Skinning/LegacyMainCirclePiece.cs | 2 +- .../Skinning/LegacySliderBall.cs | 4 +- .../Skinning/LegacyCirclePiece.cs | 2 +- .../Skinning/LegacyDrumRoll.cs | 6 +-- osu.Game.Rulesets.Taiko/Skinning/LegacyHit.cs | 7 +-- .../Skinning/LegacyColourCompatibility.cs | 46 +++++++++++++++++++ osu.Game/Skinning/LegacySkinExtensions.cs | 31 ------------- 11 files changed, 73 insertions(+), 48 deletions(-) create mode 100644 osu.Game/Skinning/LegacyColourCompatibility.cs diff --git a/osu.Game.Rulesets.Catch/Skinning/CatchLegacySkinTransformer.cs b/osu.Game.Rulesets.Catch/Skinning/CatchLegacySkinTransformer.cs index 5abd87d6f4..ea2f031d65 100644 --- a/osu.Game.Rulesets.Catch/Skinning/CatchLegacySkinTransformer.cs +++ b/osu.Game.Rulesets.Catch/Skinning/CatchLegacySkinTransformer.cs @@ -66,7 +66,7 @@ namespace osu.Game.Rulesets.Catch.Skinning if (result == null) return null; - result.Value = result.Value.ToLegacyColour(); + result.Value = LegacyColourCompatibility.DisallowZeroAlpha(result.Value); return (IBindable)result; } diff --git a/osu.Game.Rulesets.Catch/Skinning/LegacyFruitPiece.cs b/osu.Game.Rulesets.Catch/Skinning/LegacyFruitPiece.cs index c9dd1d1f3e..381d066750 100644 --- a/osu.Game.Rulesets.Catch/Skinning/LegacyFruitPiece.cs +++ b/osu.Game.Rulesets.Catch/Skinning/LegacyFruitPiece.cs @@ -75,7 +75,7 @@ namespace osu.Game.Rulesets.Catch.Skinning { base.LoadComplete(); - accentColour.BindValueChanged(colour => colouredSprite.Colour = colour.NewValue.ToLegacyColour(), true); + accentColour.BindValueChanged(colour => colouredSprite.Colour = LegacyColourCompatibility.DisallowZeroAlpha(colour.NewValue), true); } } } diff --git a/osu.Game.Rulesets.Mania/Skinning/LegacyColumnBackground.cs b/osu.Game.Rulesets.Mania/Skinning/LegacyColumnBackground.cs index 54a16b840f..da6075248a 100644 --- a/osu.Game.Rulesets.Mania/Skinning/LegacyColumnBackground.cs +++ b/osu.Game.Rulesets.Mania/Skinning/LegacyColumnBackground.cs @@ -58,14 +58,20 @@ namespace osu.Game.Rulesets.Mania.Skinning InternalChildren = new Drawable[] { - new Box { RelativeSizeAxes = Axes.Both }.WithLegacyColour(backgroundColour), + LegacyColourCompatibility.ApplyWithDoubledAlpha(new Box + { + RelativeSizeAxes = Axes.Both + }, backgroundColour), new Container { RelativeSizeAxes = Axes.Y, Width = leftLineWidth, Scale = new Vector2(0.740f, 1), Alpha = hasLeftLine ? 1 : 0, - Child = new Box { RelativeSizeAxes = Axes.Both }.WithLegacyColour(lineColour) + Child = LegacyColourCompatibility.ApplyWithDoubledAlpha(new Box + { + RelativeSizeAxes = Axes.Both + }, lineColour) }, new Container { @@ -75,7 +81,10 @@ namespace osu.Game.Rulesets.Mania.Skinning Width = rightLineWidth, Scale = new Vector2(0.740f, 1), Alpha = hasRightLine ? 1 : 0, - Child = new Box { RelativeSizeAxes = Axes.Both }.WithLegacyColour(lineColour) + Child = LegacyColourCompatibility.ApplyWithDoubledAlpha(new Box + { + RelativeSizeAxes = Axes.Both + }, lineColour) }, lightContainer = new Container { @@ -86,7 +95,7 @@ namespace osu.Game.Rulesets.Mania.Skinning { Anchor = Anchor.BottomCentre, Origin = Anchor.BottomCentre, - Colour = lightColour.ToLegacyColour(), + Colour = LegacyColourCompatibility.DisallowZeroAlpha(lightColour), Texture = skin.GetTexture(lightImage), RelativeSizeAxes = Axes.X, Width = 1, diff --git a/osu.Game.Rulesets.Mania/Skinning/LegacyHitTarget.cs b/osu.Game.Rulesets.Mania/Skinning/LegacyHitTarget.cs index 2177eaa5e6..48504e6548 100644 --- a/osu.Game.Rulesets.Mania/Skinning/LegacyHitTarget.cs +++ b/osu.Game.Rulesets.Mania/Skinning/LegacyHitTarget.cs @@ -56,7 +56,7 @@ namespace osu.Game.Rulesets.Mania.Skinning Anchor = Anchor.CentreLeft, RelativeSizeAxes = Axes.X, Height = 1, - Colour = lineColour.ToLegacyColour(), + Colour = LegacyColourCompatibility.DisallowZeroAlpha(lineColour), Alpha = showJudgementLine ? 0.9f : 0 } } diff --git a/osu.Game.Rulesets.Osu/Skinning/LegacyMainCirclePiece.cs b/osu.Game.Rulesets.Osu/Skinning/LegacyMainCirclePiece.cs index 8a6beddb51..d15a0a3203 100644 --- a/osu.Game.Rulesets.Osu/Skinning/LegacyMainCirclePiece.cs +++ b/osu.Game.Rulesets.Osu/Skinning/LegacyMainCirclePiece.cs @@ -106,7 +106,7 @@ namespace osu.Game.Rulesets.Osu.Skinning base.LoadComplete(); state.BindValueChanged(updateState, true); - accentColour.BindValueChanged(colour => hitCircleSprite.Colour = colour.NewValue.ToLegacyColour(), true); + accentColour.BindValueChanged(colour => hitCircleSprite.Colour = LegacyColourCompatibility.DisallowZeroAlpha(colour.NewValue), true); indexInCurrentCombo.BindValueChanged(index => hitCircleText.Text = (index.NewValue + 1).ToString(), true); } diff --git a/osu.Game.Rulesets.Osu/Skinning/LegacySliderBall.cs b/osu.Game.Rulesets.Osu/Skinning/LegacySliderBall.cs index 27dec1b691..25ab96445a 100644 --- a/osu.Game.Rulesets.Osu/Skinning/LegacySliderBall.cs +++ b/osu.Game.Rulesets.Osu/Skinning/LegacySliderBall.cs @@ -39,11 +39,11 @@ namespace osu.Game.Rulesets.Osu.Skinning Texture = skin.GetTexture("sliderb-nd"), Colour = new Color4(5, 5, 5, 255), }, - animationContent.WithLegacyColour(ballColour).With(d => + LegacyColourCompatibility.ApplyWithDoubledAlpha(animationContent.With(d => { d.Anchor = Anchor.Centre; d.Origin = Anchor.Centre; - }), + }), ballColour), layerSpec = new Sprite { Anchor = Anchor.Centre, diff --git a/osu.Game.Rulesets.Taiko/Skinning/LegacyCirclePiece.cs b/osu.Game.Rulesets.Taiko/Skinning/LegacyCirclePiece.cs index ed69b529ed..9b73ccd248 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/LegacyCirclePiece.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/LegacyCirclePiece.cs @@ -90,7 +90,7 @@ namespace osu.Game.Rulesets.Taiko.Skinning private void updateAccentColour() { - backgroundLayer.Colour = accentColour.ToLegacyColour(); + backgroundLayer.Colour = LegacyColourCompatibility.DisallowZeroAlpha(accentColour); } } } diff --git a/osu.Game.Rulesets.Taiko/Skinning/LegacyDrumRoll.cs b/osu.Game.Rulesets.Taiko/Skinning/LegacyDrumRoll.cs index 6bb8f9433e..025eff53d5 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/LegacyDrumRoll.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/LegacyDrumRoll.cs @@ -76,9 +76,9 @@ namespace osu.Game.Rulesets.Taiko.Skinning private void updateAccentColour() { - headCircle.AccentColour = accentColour.ToLegacyColour(); - body.Colour = accentColour.ToLegacyColour(); - end.Colour = accentColour.ToLegacyColour(); + headCircle.AccentColour = LegacyColourCompatibility.DisallowZeroAlpha(accentColour); + body.Colour = LegacyColourCompatibility.DisallowZeroAlpha(accentColour); + end.Colour = LegacyColourCompatibility.DisallowZeroAlpha(accentColour); } } } diff --git a/osu.Game.Rulesets.Taiko/Skinning/LegacyHit.cs b/osu.Game.Rulesets.Taiko/Skinning/LegacyHit.cs index f36aae205a..b11b64c22c 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/LegacyHit.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/LegacyHit.cs @@ -19,9 +19,10 @@ namespace osu.Game.Rulesets.Taiko.Skinning [BackgroundDependencyLoader] private void load() { - AccentColour = (component == TaikoSkinComponents.CentreHit - ? new Color4(235, 69, 44, 255) - : new Color4(67, 142, 172, 255)).ToLegacyColour(); + AccentColour = LegacyColourCompatibility.DisallowZeroAlpha( + component == TaikoSkinComponents.CentreHit + ? new Color4(235, 69, 44, 255) + : new Color4(67, 142, 172, 255)); } } } diff --git a/osu.Game/Skinning/LegacyColourCompatibility.cs b/osu.Game/Skinning/LegacyColourCompatibility.cs new file mode 100644 index 0000000000..b842b50426 --- /dev/null +++ b/osu.Game/Skinning/LegacyColourCompatibility.cs @@ -0,0 +1,46 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Graphics; +using osuTK.Graphics; + +namespace osu.Game.Skinning +{ + /// + /// Compatibility methods to convert osu!stable colours to osu!lazer-compatible ones. Should be used for legacy skins only. + /// + public static class LegacyColourCompatibility + { + /// + /// Forces an alpha of 1 if a given is fully transparent. + /// + /// + /// This is equivalent to setting colour post-constructor in osu!stable. + /// + /// The to disallow zero alpha on. + /// The resultant . + public static Color4 DisallowZeroAlpha(Color4 colour) + { + if (colour.A == 0) + colour.A = 1; + return colour; + } + + /// + /// Applies a to a , doubling the alpha value into the property. + /// + /// + /// This is equivalent to setting colour in the constructor in osu!stable. + /// + /// The to apply the colour to. + /// The to apply. + /// The given . + public static T ApplyWithDoubledAlpha(T drawable, Color4 colour) + where T : Drawable + { + drawable.Alpha = colour.A; + drawable.Colour = DisallowZeroAlpha(colour); + return drawable; + } + } +} diff --git a/osu.Game/Skinning/LegacySkinExtensions.cs b/osu.Game/Skinning/LegacySkinExtensions.cs index 7420f82f04..bb46dc8b9f 100644 --- a/osu.Game/Skinning/LegacySkinExtensions.cs +++ b/osu.Game/Skinning/LegacySkinExtensions.cs @@ -9,7 +9,6 @@ using osu.Framework.Graphics.Animations; using osu.Framework.Graphics.OpenGL.Textures; using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Textures; -using osuTK.Graphics; using static osu.Game.Skinning.LegacySkinConfiguration; namespace osu.Game.Skinning @@ -63,36 +62,6 @@ namespace osu.Game.Skinning } } - /// - /// The resultant colour after setting a post-constructor colour in osu!stable. - /// - /// The to convert. - /// The converted . - public static Color4 ToLegacyColour(this Color4 colour) - { - if (colour.A == 0) - colour.A = 1; - return colour; - } - - /// - /// Equivalent of setting a colour in the constructor in osu!stable. - /// Doubles the alpha channel into and uses to set . - /// - /// - /// Beware: Any existing value in is overwritten. - /// - /// The to set the colour of. - /// The to set. - /// The given . - public static T WithLegacyColour(this T drawable, Color4 colour) - where T : Drawable - { - drawable.Alpha = colour.A; - drawable.Colour = ToLegacyColour(colour); - return drawable; - } - public class SkinnableTextureAnimation : TextureAnimation { [Resolved(canBeNull: true)] From c09cef4fca2d5264d96958cc388534012aa7ede0 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 25 Aug 2020 19:39:03 +0900 Subject: [PATCH 109/320] Apply post-merge fixes to LegacyStageBackground --- .../Skinning/LegacyStageBackground.cs | 29 ++++++++++--------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Skinning/LegacyStageBackground.cs b/osu.Game.Rulesets.Mania/Skinning/LegacyStageBackground.cs index 19ec86b1ed..16a6123724 100644 --- a/osu.Game.Rulesets.Mania/Skinning/LegacyStageBackground.cs +++ b/osu.Game.Rulesets.Mania/Skinning/LegacyStageBackground.cs @@ -108,37 +108,38 @@ namespace osu.Game.Rulesets.Mania.Skinning InternalChildren = new Drawable[] { - new Container + LegacyColourCompatibility.ApplyWithDoubledAlpha(new Box { - RelativeSizeAxes = Axes.Both, - Child = new Box - { - RelativeSizeAxes = Axes.Both, - Colour = backgroundColour - }, - }, + RelativeSizeAxes = Axes.Both + }, backgroundColour), new HitTargetInsetContainer { RelativeSizeAxes = Axes.Both, Children = new[] { - new Box + new Container { RelativeSizeAxes = Axes.Y, Width = leftLineWidth, Scale = new Vector2(0.740f, 1), - Colour = lineColour, - Alpha = hasLeftLine ? 1 : 0 + Alpha = hasLeftLine ? 1 : 0, + Child = LegacyColourCompatibility.ApplyWithDoubledAlpha(new Box + { + RelativeSizeAxes = Axes.Both + }, lineColour) }, - new Box + new Container { Anchor = Anchor.TopRight, Origin = Anchor.TopRight, RelativeSizeAxes = Axes.Y, Width = rightLineWidth, Scale = new Vector2(0.740f, 1), - Colour = lineColour, - Alpha = hasRightLine ? 1 : 0 + Alpha = hasRightLine ? 1 : 0, + Child = LegacyColourCompatibility.ApplyWithDoubledAlpha(new Box + { + RelativeSizeAxes = Axes.Both + }, lineColour) }, } } From 2cf2ba8fc5cb0e1648756774d99e81b1f045c70b Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 26 Aug 2020 14:24:04 +0900 Subject: [PATCH 110/320] Store computed accent colour to local --- osu.Game.Rulesets.Taiko/Skinning/LegacyDrumRoll.cs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Skinning/LegacyDrumRoll.cs b/osu.Game.Rulesets.Taiko/Skinning/LegacyDrumRoll.cs index 025eff53d5..5ab8e3a8c8 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/LegacyDrumRoll.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/LegacyDrumRoll.cs @@ -76,9 +76,11 @@ namespace osu.Game.Rulesets.Taiko.Skinning private void updateAccentColour() { - headCircle.AccentColour = LegacyColourCompatibility.DisallowZeroAlpha(accentColour); - body.Colour = LegacyColourCompatibility.DisallowZeroAlpha(accentColour); - end.Colour = LegacyColourCompatibility.DisallowZeroAlpha(accentColour); + var colour = LegacyColourCompatibility.DisallowZeroAlpha(accentColour); + + headCircle.AccentColour = colour; + body.Colour = colour; + end.Colour = colour; } } } From d057f5f4bce9297c9dc65d8eafc85cc585f604d6 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 26 Aug 2020 15:37:16 +0900 Subject: [PATCH 111/320] Implement mania "KeysUnderNotes" skin config --- osu.Game.Rulesets.Mania/Skinning/LegacyKeyArea.cs | 3 +++ osu.Game/Skinning/LegacyManiaSkinConfiguration.cs | 1 + osu.Game/Skinning/LegacyManiaSkinConfigurationLookup.cs | 1 + osu.Game/Skinning/LegacyManiaSkinDecoder.cs | 4 ++++ osu.Game/Skinning/LegacySkin.cs | 3 +++ 5 files changed, 12 insertions(+) diff --git a/osu.Game.Rulesets.Mania/Skinning/LegacyKeyArea.cs b/osu.Game.Rulesets.Mania/Skinning/LegacyKeyArea.cs index 44f3e7d7b3..b269ea25d4 100644 --- a/osu.Game.Rulesets.Mania/Skinning/LegacyKeyArea.cs +++ b/osu.Game.Rulesets.Mania/Skinning/LegacyKeyArea.cs @@ -65,6 +65,9 @@ namespace osu.Game.Rulesets.Mania.Skinning direction.BindTo(scrollingInfo.Direction); direction.BindValueChanged(onDirectionChanged, true); + + if (GetColumnSkinConfig(skin, LegacyManiaSkinConfigurationLookups.KeysUnderNotes)?.Value ?? false) + Column.UnderlayElements.Add(CreateProxy()); } private void onDirectionChanged(ValueChangedEvent direction) diff --git a/osu.Game/Skinning/LegacyManiaSkinConfiguration.cs b/osu.Game/Skinning/LegacyManiaSkinConfiguration.cs index af7d6007f3..a5cc899b53 100644 --- a/osu.Game/Skinning/LegacyManiaSkinConfiguration.cs +++ b/osu.Game/Skinning/LegacyManiaSkinConfiguration.cs @@ -35,6 +35,7 @@ namespace osu.Game.Skinning public float HitPosition = (480 - 402) * POSITION_SCALE_FACTOR; public float LightPosition = (480 - 413) * POSITION_SCALE_FACTOR; public bool ShowJudgementLine = true; + public bool KeysUnderNotes; public LegacyManiaSkinConfiguration(int keys) { diff --git a/osu.Game/Skinning/LegacyManiaSkinConfigurationLookup.cs b/osu.Game/Skinning/LegacyManiaSkinConfigurationLookup.cs index 4990ca8e60..890a0cc4ff 100644 --- a/osu.Game/Skinning/LegacyManiaSkinConfigurationLookup.cs +++ b/osu.Game/Skinning/LegacyManiaSkinConfigurationLookup.cs @@ -50,5 +50,6 @@ namespace osu.Game.Skinning Hit100, Hit50, Hit0, + KeysUnderNotes, } } diff --git a/osu.Game/Skinning/LegacyManiaSkinDecoder.cs b/osu.Game/Skinning/LegacyManiaSkinDecoder.cs index aebc229f7c..1ea120e8a4 100644 --- a/osu.Game/Skinning/LegacyManiaSkinDecoder.cs +++ b/osu.Game/Skinning/LegacyManiaSkinDecoder.cs @@ -97,6 +97,10 @@ namespace osu.Game.Skinning currentConfig.ShowJudgementLine = pair.Value == "1"; break; + case "KeysUnderNotes": + currentConfig.KeysUnderNotes = pair.Value == "1"; + break; + case "LightingNWidth": parseArrayValue(pair.Value, currentConfig.ExplosionWidth); break; diff --git a/osu.Game/Skinning/LegacySkin.cs b/osu.Game/Skinning/LegacySkin.cs index 02d07eee45..13a43c8aae 100644 --- a/osu.Game/Skinning/LegacySkin.cs +++ b/osu.Game/Skinning/LegacySkin.cs @@ -255,6 +255,9 @@ namespace osu.Game.Skinning case LegacyManiaSkinConfigurationLookups.Hit300: case LegacyManiaSkinConfigurationLookups.Hit300g: return SkinUtils.As(getManiaImage(existing, maniaLookup.Lookup.ToString())); + + case LegacyManiaSkinConfigurationLookups.KeysUnderNotes: + return SkinUtils.As(new Bindable(existing.KeysUnderNotes)); } return null; From c50e495e035bad956cf1883f510a41c2eb3e867a Mon Sep 17 00:00:00 2001 From: Poliwrath Date: Wed, 26 Aug 2020 02:49:55 -0400 Subject: [PATCH 112/320] fix lingering small ring in circles! intro --- osu.Game/Screens/Menu/IntroSequence.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Screens/Menu/IntroSequence.cs b/osu.Game/Screens/Menu/IntroSequence.cs index 6731fef6f7..98da31b93e 100644 --- a/osu.Game/Screens/Menu/IntroSequence.cs +++ b/osu.Game/Screens/Menu/IntroSequence.cs @@ -205,6 +205,7 @@ namespace osu.Game.Screens.Menu const int line_end_offset = 120; smallRing.Foreground.ResizeTo(1, line_duration, Easing.OutQuint); + smallRing.Delay(400).FadeOut(); lineTopLeft.MoveTo(new Vector2(-line_end_offset, -line_end_offset), line_duration, Easing.OutQuint); lineTopRight.MoveTo(new Vector2(line_end_offset, -line_end_offset), line_duration, Easing.OutQuint); From 97637bc747aaba00507f28f1c582e181fa7a7694 Mon Sep 17 00:00:00 2001 From: Poliwrath Date: Wed, 26 Aug 2020 01:59:53 -0400 Subject: [PATCH 113/320] remove new.ppy.sh from MessageFormatter --- osu.Game/Online/Chat/MessageFormatter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Online/Chat/MessageFormatter.cs b/osu.Game/Online/Chat/MessageFormatter.cs index 6af2561c89..648e4a762b 100644 --- a/osu.Game/Online/Chat/MessageFormatter.cs +++ b/osu.Game/Online/Chat/MessageFormatter.cs @@ -119,7 +119,7 @@ namespace osu.Game.Online.Chat case "http": case "https": // length > 3 since all these links need another argument to work - if (args.Length > 3 && (args[1] == "osu.ppy.sh" || args[1] == "new.ppy.sh")) + if (args.Length > 3 && args[1] == "osu.ppy.sh") { switch (args[2]) { From e6116890afbdcf93c7d032844b1670f9172a24ca Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 26 Aug 2020 20:00:38 +0900 Subject: [PATCH 114/320] Make hitobject tests display the column --- .../Skinning/ColumnTestContainer.cs | 24 +++++++++++-------- .../Skinning/ManiaHitObjectTestScene.cs | 4 ++-- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/osu.Game.Rulesets.Mania.Tests/Skinning/ColumnTestContainer.cs b/osu.Game.Rulesets.Mania.Tests/Skinning/ColumnTestContainer.cs index ff4865c71d..8ba58e3af3 100644 --- a/osu.Game.Rulesets.Mania.Tests/Skinning/ColumnTestContainer.cs +++ b/osu.Game.Rulesets.Mania.Tests/Skinning/ColumnTestContainer.cs @@ -22,18 +22,22 @@ namespace osu.Game.Rulesets.Mania.Tests.Skinning [Cached] private readonly Column column; - public ColumnTestContainer(int column, ManiaAction action) + public ColumnTestContainer(int column, ManiaAction action, bool showColumn = false) { - this.column = new Column(column) + InternalChildren = new[] { - Action = { Value = action }, - AccentColour = Color4.Orange, - ColumnType = column % 2 == 0 ? ColumnType.Even : ColumnType.Odd - }; - - InternalChild = content = new ManiaInputManager(new ManiaRuleset().RulesetInfo, 4) - { - RelativeSizeAxes = Axes.Both + this.column = new Column(column) + { + Action = { Value = action }, + AccentColour = Color4.Orange, + ColumnType = column % 2 == 0 ? ColumnType.Even : ColumnType.Odd, + Alpha = showColumn ? 1 : 0 + }, + content = new ManiaInputManager(new ManiaRuleset().RulesetInfo, 4) + { + RelativeSizeAxes = Axes.Both + }, + this.column.TopLevelContainer.CreateProxy() }; } } diff --git a/osu.Game.Rulesets.Mania.Tests/Skinning/ManiaHitObjectTestScene.cs b/osu.Game.Rulesets.Mania.Tests/Skinning/ManiaHitObjectTestScene.cs index 18eebada00..d24c81dac6 100644 --- a/osu.Game.Rulesets.Mania.Tests/Skinning/ManiaHitObjectTestScene.cs +++ b/osu.Game.Rulesets.Mania.Tests/Skinning/ManiaHitObjectTestScene.cs @@ -27,7 +27,7 @@ namespace osu.Game.Rulesets.Mania.Tests.Skinning Direction = FillDirection.Horizontal, Children = new Drawable[] { - new ColumnTestContainer(0, ManiaAction.Key1) + new ColumnTestContainer(0, ManiaAction.Key1, true) { Anchor = Anchor.Centre, Origin = Anchor.Centre, @@ -45,7 +45,7 @@ namespace osu.Game.Rulesets.Mania.Tests.Skinning })); }) }, - new ColumnTestContainer(1, ManiaAction.Key2) + new ColumnTestContainer(1, ManiaAction.Key2, true) { Anchor = Anchor.Centre, Origin = Anchor.Centre, From c0c67c11b12d0df3b318c763f196f383f91f2f8c Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 26 Aug 2020 20:21:41 +0900 Subject: [PATCH 115/320] Add parsing for hold note light/scale --- osu.Game/Skinning/LegacyManiaSkinConfiguration.cs | 2 ++ .../Skinning/LegacyManiaSkinConfigurationLookup.cs | 2 ++ osu.Game/Skinning/LegacyManiaSkinDecoder.cs | 4 ++++ osu.Game/Skinning/LegacySkin.cs | 14 ++++++++++++++ 4 files changed, 22 insertions(+) diff --git a/osu.Game/Skinning/LegacyManiaSkinConfiguration.cs b/osu.Game/Skinning/LegacyManiaSkinConfiguration.cs index af7d6007f3..18ae6acb38 100644 --- a/osu.Game/Skinning/LegacyManiaSkinConfiguration.cs +++ b/osu.Game/Skinning/LegacyManiaSkinConfiguration.cs @@ -31,6 +31,7 @@ namespace osu.Game.Skinning public readonly float[] ColumnSpacing; public readonly float[] ColumnWidth; public readonly float[] ExplosionWidth; + public readonly float[] HoldNoteLightWidth; public float HitPosition = (480 - 402) * POSITION_SCALE_FACTOR; public float LightPosition = (480 - 413) * POSITION_SCALE_FACTOR; @@ -44,6 +45,7 @@ namespace osu.Game.Skinning ColumnSpacing = new float[keys - 1]; ColumnWidth = new float[keys]; ExplosionWidth = new float[keys]; + HoldNoteLightWidth = new float[keys]; ColumnLineWidth.AsSpan().Fill(2); ColumnWidth.AsSpan().Fill(DEFAULT_COLUMN_SIZE); diff --git a/osu.Game/Skinning/LegacyManiaSkinConfigurationLookup.cs b/osu.Game/Skinning/LegacyManiaSkinConfigurationLookup.cs index 4990ca8e60..131c3fde34 100644 --- a/osu.Game/Skinning/LegacyManiaSkinConfigurationLookup.cs +++ b/osu.Game/Skinning/LegacyManiaSkinConfigurationLookup.cs @@ -34,6 +34,8 @@ namespace osu.Game.Skinning HoldNoteHeadImage, HoldNoteTailImage, HoldNoteBodyImage, + HoldNoteLightImage, + HoldNoteLightScale, ExplosionImage, ExplosionScale, ColumnLineColour, diff --git a/osu.Game/Skinning/LegacyManiaSkinDecoder.cs b/osu.Game/Skinning/LegacyManiaSkinDecoder.cs index 1e6102eaa4..ca492b5a21 100644 --- a/osu.Game/Skinning/LegacyManiaSkinDecoder.cs +++ b/osu.Game/Skinning/LegacyManiaSkinDecoder.cs @@ -101,6 +101,10 @@ namespace osu.Game.Skinning parseArrayValue(pair.Value, currentConfig.ExplosionWidth); break; + case "LightingLWidth": + parseArrayValue(pair.Value, currentConfig.HoldNoteLightWidth); + break; + case "WidthForNoteHeightScale": float minWidth = float.Parse(pair.Value, CultureInfo.InvariantCulture) * LegacyManiaSkinConfiguration.POSITION_SCALE_FACTOR; if (minWidth > 0) diff --git a/osu.Game/Skinning/LegacySkin.cs b/osu.Game/Skinning/LegacySkin.cs index 10fb476728..628169584a 100644 --- a/osu.Game/Skinning/LegacySkin.cs +++ b/osu.Game/Skinning/LegacySkin.cs @@ -220,6 +220,20 @@ namespace osu.Game.Skinning Debug.Assert(maniaLookup.TargetColumn != null); return SkinUtils.As(getManiaImage(existing, $"NoteImage{maniaLookup.TargetColumn}L")); + case LegacyManiaSkinConfigurationLookups.HoldNoteLightImage: + return SkinUtils.As(getManiaImage(existing, "LightingL")); + + case LegacyManiaSkinConfigurationLookups.HoldNoteLightScale: + Debug.Assert(maniaLookup.TargetColumn != null); + + if (GetConfig(LegacySkinConfiguration.LegacySetting.Version)?.Value < 2.5m) + return SkinUtils.As(new Bindable(1)); + + if (existing.HoldNoteLightWidth[maniaLookup.TargetColumn.Value] != 0) + return SkinUtils.As(new Bindable(existing.HoldNoteLightWidth[maniaLookup.TargetColumn.Value] / LegacyManiaSkinConfiguration.DEFAULT_COLUMN_SIZE)); + + return SkinUtils.As(new Bindable(existing.ColumnWidth[maniaLookup.TargetColumn.Value] / LegacyManiaSkinConfiguration.DEFAULT_COLUMN_SIZE)); + case LegacyManiaSkinConfigurationLookups.KeyImage: Debug.Assert(maniaLookup.TargetColumn != null); return SkinUtils.As(getManiaImage(existing, $"KeyImage{maniaLookup.TargetColumn}")); From 9372c6eef6e90ff35d5bdd81d332dbded910416b Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 26 Aug 2020 20:21:56 +0900 Subject: [PATCH 116/320] Implement hold note lighting --- .../Objects/Drawables/DrawableHoldNote.cs | 3 + .../Skinning/LegacyBodyPiece.cs | 124 +++++++++++++++--- 2 files changed, 112 insertions(+), 15 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs index a44f8a8886..4f29e0417e 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs @@ -159,7 +159,10 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables protected override void CheckForResult(bool userTriggered, double timeOffset) { if (Tail.AllJudged) + { ApplyResult(r => r.Type = HitResult.Perfect); + endHold(); + } if (Tail.Result.Type == HitResult.Miss) HasBroken = true; diff --git a/osu.Game.Rulesets.Mania/Skinning/LegacyBodyPiece.cs b/osu.Game.Rulesets.Mania/Skinning/LegacyBodyPiece.cs index 9f716428c0..d922934532 100644 --- a/osu.Game.Rulesets.Mania/Skinning/LegacyBodyPiece.cs +++ b/osu.Game.Rulesets.Mania/Skinning/LegacyBodyPiece.cs @@ -1,12 +1,15 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Animations; +using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.OpenGL.Textures; using osu.Game.Rulesets.Mania.Objects.Drawables; +using osu.Game.Rulesets.Mania.UI; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.UI.Scrolling; using osu.Game.Skinning; @@ -19,7 +22,9 @@ namespace osu.Game.Rulesets.Mania.Skinning private readonly IBindable direction = new Bindable(); private readonly IBindable isHitting = new Bindable(); - private Drawable sprite; + private Drawable bodySprite; + private Drawable lightContainer; + private Drawable light; public LegacyBodyPiece() { @@ -32,7 +37,33 @@ namespace osu.Game.Rulesets.Mania.Skinning string imageName = GetColumnSkinConfig(skin, LegacyManiaSkinConfigurationLookups.HoldNoteBodyImage)?.Value ?? $"mania-note{FallbackColumnIndex}L"; - sprite = skin.GetAnimation(imageName, WrapMode.ClampToEdge, WrapMode.ClampToEdge, true, true).With(d => + string lightImage = GetColumnSkinConfig(skin, LegacyManiaSkinConfigurationLookups.HoldNoteLightImage)?.Value + ?? "lightingL"; + + float lightScale = GetColumnSkinConfig(skin, LegacyManiaSkinConfigurationLookups.HoldNoteLightScale)?.Value + ?? 1; + + // Create a temporary animation to retrieve the number of frames, in an effort to calculate the intended frame length. + // This animation is discarded and re-queried with the appropriate frame length afterwards. + var tmp = skin.GetAnimation(lightImage, true, false); + double frameLength = 0; + if (tmp is IFramedAnimation tmpAnimation && tmpAnimation.FrameCount > 0) + frameLength = Math.Max(1000 / 60.0, 170.0 / tmpAnimation.FrameCount); + + light = skin.GetAnimation(lightImage, true, true, frameLength: frameLength).With(d => + { + if (d == null) + return; + + d.Origin = Anchor.Centre; + d.Blending = BlendingParameters.Additive; + d.Scale = new Vector2(lightScale); + }); + + if (light != null) + lightContainer = new HitTargetInsetContainer { Child = light }; + + bodySprite = skin.GetAnimation(imageName, WrapMode.ClampToEdge, WrapMode.ClampToEdge, true, true).With(d => { if (d == null) return; @@ -47,8 +78,8 @@ namespace osu.Game.Rulesets.Mania.Skinning // Todo: Wrap }); - if (sprite != null) - InternalChild = sprite; + if (bodySprite != null) + InternalChild = bodySprite; direction.BindTo(scrollingInfo.Direction); direction.BindValueChanged(onDirectionChanged, true); @@ -60,27 +91,90 @@ namespace osu.Game.Rulesets.Mania.Skinning private void onIsHittingChanged(ValueChangedEvent isHitting) { - if (!(sprite is TextureAnimation animation)) - return; + if (bodySprite is TextureAnimation bodyAnimation) + { + bodyAnimation.GotoFrame(0); + bodyAnimation.IsPlaying = isHitting.NewValue; + } - animation.GotoFrame(0); - animation.IsPlaying = isHitting.NewValue; + if (lightContainer != null) + { + if (isHitting.NewValue) + { + Column.TopLevelContainer.Add(lightContainer); + + // The light must be seeked only after being loaded, otherwise a nullref happens (https://github.com/ppy/osu-framework/issues/3847). + if (light is TextureAnimation lightAnimation) + lightAnimation.GotoFrame(0); + } + else + Column.TopLevelContainer.Remove(lightContainer); + } } private void onDirectionChanged(ValueChangedEvent direction) { - if (sprite == null) - return; - if (direction.NewValue == ScrollingDirection.Up) { - sprite.Origin = Anchor.BottomCentre; - sprite.Scale = new Vector2(1, -1); + if (bodySprite != null) + { + bodySprite.Origin = Anchor.BottomCentre; + bodySprite.Scale = new Vector2(1, -1); + } + + if (light != null) + light.Anchor = Anchor.TopCentre; } else { - sprite.Origin = Anchor.TopCentre; - sprite.Scale = Vector2.One; + if (bodySprite != null) + { + bodySprite.Origin = Anchor.TopCentre; + bodySprite.Scale = Vector2.One; + } + + if (light != null) + light.Anchor = Anchor.BottomCentre; + } + } + + protected override void Dispose(bool isDisposing) + { + base.Dispose(isDisposing); + + lightContainer?.Expire(); + } + + private class HitTargetInsetContainer : Container + { + private readonly IBindable direction = new Bindable(); + + protected override Container Content => content; + private readonly Container content; + + private float hitPosition; + + public HitTargetInsetContainer() + { + RelativeSizeAxes = Axes.Both; + + InternalChild = content = new Container { RelativeSizeAxes = Axes.Both }; + } + + [BackgroundDependencyLoader] + private void load(ISkinSource skin, IScrollingInfo scrollingInfo) + { + hitPosition = skin.GetManiaSkinConfig(LegacyManiaSkinConfigurationLookups.HitPosition)?.Value ?? Stage.HIT_TARGET_POSITION; + + direction.BindTo(scrollingInfo.Direction); + direction.BindValueChanged(onDirectionChanged, true); + } + + private void onDirectionChanged(ValueChangedEvent direction) + { + content.Padding = direction.NewValue == ScrollingDirection.Up + ? new MarginPadding { Top = hitPosition } + : new MarginPadding { Bottom = hitPosition }; } } } From 6fe1279e9deb3b3bea1ec7c53b2695fd47d6eb30 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 26 Aug 2020 20:23:01 +0900 Subject: [PATCH 117/320] Re-use existing inset container --- .../Skinning/HitTargetInsetContainer.cs | 46 +++++++++++++++++++ .../Skinning/LegacyBodyPiece.cs | 35 -------------- .../Skinning/LegacyStageBackground.cs | 35 -------------- 3 files changed, 46 insertions(+), 70 deletions(-) create mode 100644 osu.Game.Rulesets.Mania/Skinning/HitTargetInsetContainer.cs diff --git a/osu.Game.Rulesets.Mania/Skinning/HitTargetInsetContainer.cs b/osu.Game.Rulesets.Mania/Skinning/HitTargetInsetContainer.cs new file mode 100644 index 0000000000..c8b05ed2f8 --- /dev/null +++ b/osu.Game.Rulesets.Mania/Skinning/HitTargetInsetContainer.cs @@ -0,0 +1,46 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Allocation; +using osu.Framework.Bindables; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Game.Rulesets.Mania.UI; +using osu.Game.Rulesets.UI.Scrolling; +using osu.Game.Skinning; + +namespace osu.Game.Rulesets.Mania.Skinning +{ + public class HitTargetInsetContainer : Container + { + private readonly IBindable direction = new Bindable(); + + protected override Container Content => content; + private readonly Container content; + + private float hitPosition; + + public HitTargetInsetContainer() + { + RelativeSizeAxes = Axes.Both; + + InternalChild = content = new Container { RelativeSizeAxes = Axes.Both }; + } + + [BackgroundDependencyLoader] + private void load(ISkinSource skin, IScrollingInfo scrollingInfo) + { + hitPosition = skin.GetManiaSkinConfig(LegacyManiaSkinConfigurationLookups.HitPosition)?.Value ?? Stage.HIT_TARGET_POSITION; + + direction.BindTo(scrollingInfo.Direction); + direction.BindValueChanged(onDirectionChanged, true); + } + + private void onDirectionChanged(ValueChangedEvent direction) + { + content.Padding = direction.NewValue == ScrollingDirection.Up + ? new MarginPadding { Top = hitPosition } + : new MarginPadding { Bottom = hitPosition }; + } + } +} diff --git a/osu.Game.Rulesets.Mania/Skinning/LegacyBodyPiece.cs b/osu.Game.Rulesets.Mania/Skinning/LegacyBodyPiece.cs index d922934532..338dd5bb1d 100644 --- a/osu.Game.Rulesets.Mania/Skinning/LegacyBodyPiece.cs +++ b/osu.Game.Rulesets.Mania/Skinning/LegacyBodyPiece.cs @@ -6,10 +6,8 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Animations; -using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.OpenGL.Textures; using osu.Game.Rulesets.Mania.Objects.Drawables; -using osu.Game.Rulesets.Mania.UI; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.UI.Scrolling; using osu.Game.Skinning; @@ -144,38 +142,5 @@ namespace osu.Game.Rulesets.Mania.Skinning lightContainer?.Expire(); } - - private class HitTargetInsetContainer : Container - { - private readonly IBindable direction = new Bindable(); - - protected override Container Content => content; - private readonly Container content; - - private float hitPosition; - - public HitTargetInsetContainer() - { - RelativeSizeAxes = Axes.Both; - - InternalChild = content = new Container { RelativeSizeAxes = Axes.Both }; - } - - [BackgroundDependencyLoader] - private void load(ISkinSource skin, IScrollingInfo scrollingInfo) - { - hitPosition = skin.GetManiaSkinConfig(LegacyManiaSkinConfigurationLookups.HitPosition)?.Value ?? Stage.HIT_TARGET_POSITION; - - direction.BindTo(scrollingInfo.Direction); - direction.BindValueChanged(onDirectionChanged, true); - } - - private void onDirectionChanged(ValueChangedEvent direction) - { - content.Padding = direction.NewValue == ScrollingDirection.Up - ? new MarginPadding { Top = hitPosition } - : new MarginPadding { Bottom = hitPosition }; - } - } } } diff --git a/osu.Game.Rulesets.Mania/Skinning/LegacyStageBackground.cs b/osu.Game.Rulesets.Mania/Skinning/LegacyStageBackground.cs index 19ec86b1ed..ead51d91d7 100644 --- a/osu.Game.Rulesets.Mania/Skinning/LegacyStageBackground.cs +++ b/osu.Game.Rulesets.Mania/Skinning/LegacyStageBackground.cs @@ -2,14 +2,12 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Allocation; -using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Sprites; using osu.Game.Rulesets.Mania.Beatmaps; using osu.Game.Rulesets.Mania.UI; -using osu.Game.Rulesets.UI.Scrolling; using osu.Game.Skinning; using osuTK; using osuTK.Graphics; @@ -145,38 +143,5 @@ namespace osu.Game.Rulesets.Mania.Skinning }; } } - - private class HitTargetInsetContainer : Container - { - private readonly IBindable direction = new Bindable(); - - protected override Container Content => content; - private readonly Container content; - - private float hitPosition; - - public HitTargetInsetContainer() - { - RelativeSizeAxes = Axes.Both; - - InternalChild = content = new Container { RelativeSizeAxes = Axes.Both }; - } - - [BackgroundDependencyLoader] - private void load(ISkinSource skin, IScrollingInfo scrollingInfo) - { - hitPosition = skin.GetManiaSkinConfig(LegacyManiaSkinConfigurationLookups.HitPosition)?.Value ?? Stage.HIT_TARGET_POSITION; - - direction.BindTo(scrollingInfo.Direction); - direction.BindValueChanged(onDirectionChanged, true); - } - - private void onDirectionChanged(ValueChangedEvent direction) - { - content.Padding = direction.NewValue == ScrollingDirection.Up - ? new MarginPadding { Top = hitPosition } - : new MarginPadding { Bottom = hitPosition }; - } - } } } From 157e1d89651a4866b1e413ee1f953eea5058e948 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 26 Aug 2020 20:46:12 +0900 Subject: [PATCH 118/320] Add fades --- .../Skinning/LegacyBodyPiece.cs | 24 +++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Skinning/LegacyBodyPiece.cs b/osu.Game.Rulesets.Mania/Skinning/LegacyBodyPiece.cs index 338dd5bb1d..a1c2559386 100644 --- a/osu.Game.Rulesets.Mania/Skinning/LegacyBodyPiece.cs +++ b/osu.Game.Rulesets.Mania/Skinning/LegacyBodyPiece.cs @@ -59,7 +59,13 @@ namespace osu.Game.Rulesets.Mania.Skinning }); if (light != null) - lightContainer = new HitTargetInsetContainer { Child = light }; + { + lightContainer = new HitTargetInsetContainer + { + Alpha = 0, + Child = light + }; + } bodySprite = skin.GetAnimation(imageName, WrapMode.ClampToEdge, WrapMode.ClampToEdge, true, true).With(d => { @@ -99,14 +105,24 @@ namespace osu.Game.Rulesets.Mania.Skinning { if (isHitting.NewValue) { - Column.TopLevelContainer.Add(lightContainer); + // Clear the fade out and, more importantly, the removal. + lightContainer.ClearTransforms(); - // The light must be seeked only after being loaded, otherwise a nullref happens (https://github.com/ppy/osu-framework/issues/3847). + // Only add the container if the removal has taken place. + if (lightContainer.Parent == null) + Column.TopLevelContainer.Add(lightContainer); + + // The light must be seeked only after being loaded, otherwise a nullref occurs (https://github.com/ppy/osu-framework/issues/3847). if (light is TextureAnimation lightAnimation) lightAnimation.GotoFrame(0); + + lightContainer.FadeIn(80); } else - Column.TopLevelContainer.Remove(lightContainer); + { + lightContainer.FadeOut(120) + .OnComplete(d => Column.TopLevelContainer.Remove(d)); + } } } From f65991f31fbe30fcfd55a30e921b890b0709715d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 26 Aug 2020 23:28:58 +0900 Subject: [PATCH 119/320] Revert some usages based on review feedback --- osu.Game/Graphics/Containers/BeatSyncedContainer.cs | 8 ++------ osu.Game/Overlays/Music/PlaylistOverlay.cs | 9 +++------ .../Edit/Compose/Components/Timeline/Timeline.cs | 4 ---- osu.Game/Screens/Menu/LogoVisualisation.cs | 12 ++++-------- 4 files changed, 9 insertions(+), 24 deletions(-) diff --git a/osu.Game/Graphics/Containers/BeatSyncedContainer.cs b/osu.Game/Graphics/Containers/BeatSyncedContainer.cs index 69021e1634..1c9cdc174a 100644 --- a/osu.Game/Graphics/Containers/BeatSyncedContainer.cs +++ b/osu.Game/Graphics/Containers/BeatSyncedContainer.cs @@ -7,7 +7,6 @@ using osu.Framework.Bindables; using osu.Framework.Graphics.Containers; using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; -using osu.Game.Overlays; namespace osu.Game.Graphics.Containers { @@ -15,9 +14,6 @@ namespace osu.Game.Graphics.Containers { protected readonly IBindable Beatmap = new Bindable(); - [Resolved] - private MusicController musicController { get; set; } - private int lastBeat; private TimingControlPoint lastTimingPoint; @@ -58,9 +54,9 @@ namespace osu.Game.Graphics.Containers TimingControlPoint timingPoint = null; EffectControlPoint effectPoint = null; - if (musicController.TrackLoaded && Beatmap.Value.BeatmapLoaded) + if (Beatmap.Value.TrackLoaded && Beatmap.Value.BeatmapLoaded) { - track = musicController.CurrentTrack; + track = Beatmap.Value.Track; beatmap = Beatmap.Value.Beatmap; } diff --git a/osu.Game/Overlays/Music/PlaylistOverlay.cs b/osu.Game/Overlays/Music/PlaylistOverlay.cs index 7471e31923..b45d84049f 100644 --- a/osu.Game/Overlays/Music/PlaylistOverlay.cs +++ b/osu.Game/Overlays/Music/PlaylistOverlay.cs @@ -30,9 +30,6 @@ namespace osu.Game.Overlays.Music [Resolved] private BeatmapManager beatmaps { get; set; } - [Resolved] - private MusicController musicController { get; set; } - private FilterControl filter; private Playlist list; @@ -85,7 +82,7 @@ namespace osu.Game.Overlays.Music if (toSelect != null) { beatmap.Value = beatmaps.GetWorkingBeatmap(toSelect); - musicController.CurrentTrack.Restart(); + beatmap.Value.Track.Restart(); } }; } @@ -119,12 +116,12 @@ namespace osu.Game.Overlays.Music { if (set.ID == (beatmap.Value?.BeatmapSetInfo?.ID ?? -1)) { - musicController.CurrentTrack.Seek(0); + beatmap.Value?.Track.Seek(0); return; } beatmap.Value = beatmaps.GetWorkingBeatmap(set.Beatmaps.First()); - musicController.CurrentTrack.Restart(); + beatmap.Value.Track.Restart(); } } diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs index c617950c64..8c0e35b80e 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs @@ -11,7 +11,6 @@ using osu.Framework.Graphics.Audio; using osu.Framework.Input.Events; using osu.Game.Beatmaps; using osu.Game.Graphics; -using osu.Game.Overlays; using osu.Game.Rulesets.Edit; using osuTK; @@ -27,9 +26,6 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline [Resolved] private EditorClock editorClock { get; set; } - [Resolved] - private MusicController musicController { get; set; } - /// /// The timeline's scroll position in the last frame. /// diff --git a/osu.Game/Screens/Menu/LogoVisualisation.cs b/osu.Game/Screens/Menu/LogoVisualisation.cs index 4d95ee9b7b..ebbb19636c 100644 --- a/osu.Game/Screens/Menu/LogoVisualisation.cs +++ b/osu.Game/Screens/Menu/LogoVisualisation.cs @@ -20,7 +20,6 @@ using osu.Framework.Audio; using osu.Framework.Audio.Track; using osu.Framework.Bindables; using osu.Framework.Utils; -using osu.Game.Overlays; namespace osu.Game.Screens.Menu { @@ -75,9 +74,6 @@ namespace osu.Game.Screens.Menu /// public float Magnitude { get; set; } = 1; - [Resolved] - private MusicController musicController { get; set; } - private readonly float[] frequencyAmplitudes = new float[256]; private IShader shader; @@ -107,15 +103,15 @@ namespace osu.Game.Screens.Menu private void updateAmplitudes() { - var effect = beatmap.Value.BeatmapLoaded && musicController.TrackLoaded - ? beatmap.Value.Beatmap?.ControlPointInfo.EffectPointAt(musicController.CurrentTrack.CurrentTime) + var effect = beatmap.Value.BeatmapLoaded && beatmap.Value.TrackLoaded + ? beatmap.Value.Beatmap?.ControlPointInfo.EffectPointAt(beatmap.Value.Track.CurrentTime) : null; for (int i = 0; i < temporalAmplitudes.Length; i++) temporalAmplitudes[i] = 0; - if (musicController.TrackLoaded) - addAmplitudesFromSource(musicController.CurrentTrack); + if (beatmap.Value.TrackLoaded) + addAmplitudesFromSource(beatmap.Value.Track); foreach (var source in amplitudeSources) addAmplitudesFromSource(source); From fcf703864288ea6b974f21f8bf049cd254ab4036 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 27 Aug 2020 00:21:50 +0900 Subject: [PATCH 120/320] Fix a couple of missed cases --- osu.Game.Rulesets.Osu.Tests/TestSceneSliderSnaking.cs | 4 ++-- osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerRotation.cs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderSnaking.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderSnaking.cs index cd46e8c545..3d100e4b1c 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderSnaking.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderSnaking.cs @@ -65,7 +65,7 @@ namespace osu.Game.Rulesets.Osu.Tests { AddStep("enable autoplay", () => autoplay = true); base.SetUpSteps(); - AddUntilStep("wait for track to start running", () => MusicController.IsPlaying); + AddUntilStep("wait for track to start running", () => Beatmap.Value.Track.IsRunning); double startTime = hitObjects[sliderIndex].StartTime; retrieveDrawableSlider(sliderIndex); @@ -90,7 +90,7 @@ namespace osu.Game.Rulesets.Osu.Tests { AddStep("have autoplay", () => autoplay = true); base.SetUpSteps(); - AddUntilStep("wait for track to start running", () => MusicController.IsPlaying); + AddUntilStep("wait for track to start running", () => Beatmap.Value.Track.IsRunning); double startTime = hitObjects[sliderIndex].StartTime; retrieveDrawableSlider(sliderIndex); diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerRotation.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerRotation.cs index 3c559765d4..f7909071ea 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerRotation.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerRotation.cs @@ -48,7 +48,7 @@ namespace osu.Game.Rulesets.Osu.Tests { base.SetUpSteps(); - AddUntilStep("wait for track to start running", () => MusicController.IsPlaying); + AddUntilStep("wait for track to start running", () => Beatmap.Value.Track.IsRunning); AddStep("retrieve spinner", () => drawableSpinner = (DrawableSpinner)Player.DrawableRuleset.Playfield.AllHitObjects.First()); } From edc15c965cf6a29321cf84c1dcd1d7bb0fcdd17a Mon Sep 17 00:00:00 2001 From: Poliwrath Date: Wed, 26 Aug 2020 12:52:39 -0400 Subject: [PATCH 121/320] Update osu.Game/Screens/Menu/IntroSequence.cs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bartłomiej Dach --- osu.Game/Screens/Menu/IntroSequence.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Menu/IntroSequence.cs b/osu.Game/Screens/Menu/IntroSequence.cs index 98da31b93e..d92d38da45 100644 --- a/osu.Game/Screens/Menu/IntroSequence.cs +++ b/osu.Game/Screens/Menu/IntroSequence.cs @@ -205,7 +205,7 @@ namespace osu.Game.Screens.Menu const int line_end_offset = 120; smallRing.Foreground.ResizeTo(1, line_duration, Easing.OutQuint); - smallRing.Delay(400).FadeOut(); + smallRing.Delay(400).FadeColour(Color4.Black, 300); lineTopLeft.MoveTo(new Vector2(-line_end_offset, -line_end_offset), line_duration, Easing.OutQuint); lineTopRight.MoveTo(new Vector2(line_end_offset, -line_end_offset), line_duration, Easing.OutQuint); From 927a2a3d2df98bb3c93e9c4b8d7af6f35e71636e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Wed, 26 Aug 2020 19:19:42 +0200 Subject: [PATCH 122/320] Introduce IStatisticRow interface --- .../Ranking/Statistics/IStatisticRow.cs | 18 +++++++++++++ .../Ranking/Statistics/StatisticRow.cs | 26 +++++++++++++++++-- .../Ranking/Statistics/StatisticsPanel.cs | 24 +++-------------- 3 files changed, 45 insertions(+), 23 deletions(-) create mode 100644 osu.Game/Screens/Ranking/Statistics/IStatisticRow.cs diff --git a/osu.Game/Screens/Ranking/Statistics/IStatisticRow.cs b/osu.Game/Screens/Ranking/Statistics/IStatisticRow.cs new file mode 100644 index 0000000000..67224041d5 --- /dev/null +++ b/osu.Game/Screens/Ranking/Statistics/IStatisticRow.cs @@ -0,0 +1,18 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Graphics; + +namespace osu.Game.Screens.Ranking.Statistics +{ + /// + /// A row of statistics to be displayed on the results screen. + /// + public interface IStatisticRow + { + /// + /// Creates the visual representation of this row. + /// + Drawable CreateDrawableStatisticRow(); + } +} diff --git a/osu.Game/Screens/Ranking/Statistics/StatisticRow.cs b/osu.Game/Screens/Ranking/Statistics/StatisticRow.cs index e1ca9799a3..fff60cdcad 100644 --- a/osu.Game/Screens/Ranking/Statistics/StatisticRow.cs +++ b/osu.Game/Screens/Ranking/Statistics/StatisticRow.cs @@ -1,19 +1,41 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System.Linq; using JetBrains.Annotations; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; namespace osu.Game.Screens.Ranking.Statistics { /// - /// A row of statistics to be displayed in the results screen. + /// A row of graphically detailed s to be displayed in the results screen. /// - public class StatisticRow + public class StatisticRow : IStatisticRow { /// /// The columns of this . /// [ItemNotNull] public StatisticItem[] Columns; + + public Drawable CreateDrawableStatisticRow() => new GridContainer + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Content = new[] + { + Columns?.Select(c => new StatisticContainer(c) + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + }).Cast().ToArray() + }, + ColumnDimensions = Enumerable.Range(0, Columns?.Length ?? 0) + .Select(i => Columns[i].Dimension ?? new Dimension()).ToArray(), + RowDimensions = new[] { new Dimension(GridSizeMode.AutoSize) } + }; } } diff --git a/osu.Game/Screens/Ranking/Statistics/StatisticsPanel.cs b/osu.Game/Screens/Ranking/Statistics/StatisticsPanel.cs index 7f406331cd..fd62c9e7d9 100644 --- a/osu.Game/Screens/Ranking/Statistics/StatisticsPanel.cs +++ b/osu.Game/Screens/Ranking/Statistics/StatisticsPanel.cs @@ -96,27 +96,9 @@ namespace osu.Game.Screens.Ranking.Statistics Spacing = new Vector2(30, 15), }; - foreach (var row in newScore.Ruleset.CreateInstance().CreateStatisticsForScore(newScore, playableBeatmap)) - { - rows.Add(new GridContainer - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Content = new[] - { - row.Columns?.Select(c => new StatisticContainer(c) - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - }).Cast().ToArray() - }, - ColumnDimensions = Enumerable.Range(0, row.Columns?.Length ?? 0) - .Select(i => row.Columns[i].Dimension ?? new Dimension()).ToArray(), - RowDimensions = new[] { new Dimension(GridSizeMode.AutoSize) } - }); - } + rows.AddRange(newScore.Ruleset.CreateInstance() + .CreateStatisticsForScore(newScore, playableBeatmap) + .Select(row => row.CreateDrawableStatisticRow())); LoadComponentAsync(rows, d => { From bbb3d7522e3e606c94d3564b28b9ec21c3865a51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Wed, 26 Aug 2020 19:24:12 +0200 Subject: [PATCH 123/320] Scope up return type to IStatisticRow --- osu.Game.Rulesets.Mania/ManiaRuleset.cs | 2 +- osu.Game.Rulesets.Osu/OsuRuleset.cs | 2 +- osu.Game.Rulesets.Taiko/TaikoRuleset.cs | 2 +- osu.Game/Rulesets/Ruleset.cs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Mania/ManiaRuleset.cs b/osu.Game.Rulesets.Mania/ManiaRuleset.cs index 2795868c97..8cc635c316 100644 --- a/osu.Game.Rulesets.Mania/ManiaRuleset.cs +++ b/osu.Game.Rulesets.Mania/ManiaRuleset.cs @@ -314,7 +314,7 @@ namespace osu.Game.Rulesets.Mania return (PlayfieldType)Enum.GetValues(typeof(PlayfieldType)).Cast().OrderByDescending(i => i).First(v => variant >= v); } - public override StatisticRow[] CreateStatisticsForScore(ScoreInfo score, IBeatmap playableBeatmap) => new[] + public override IStatisticRow[] CreateStatisticsForScore(ScoreInfo score, IBeatmap playableBeatmap) => new IStatisticRow[] { new StatisticRow { diff --git a/osu.Game.Rulesets.Osu/OsuRuleset.cs b/osu.Game.Rulesets.Osu/OsuRuleset.cs index eaa5d8937a..298f1aec91 100644 --- a/osu.Game.Rulesets.Osu/OsuRuleset.cs +++ b/osu.Game.Rulesets.Osu/OsuRuleset.cs @@ -193,7 +193,7 @@ namespace osu.Game.Rulesets.Osu public override IRulesetConfigManager CreateConfig(SettingsStore settings) => new OsuRulesetConfigManager(settings, RulesetInfo); - public override StatisticRow[] CreateStatisticsForScore(ScoreInfo score, IBeatmap playableBeatmap) => new[] + public override IStatisticRow[] CreateStatisticsForScore(ScoreInfo score, IBeatmap playableBeatmap) => new IStatisticRow[] { new StatisticRow { diff --git a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs index 2011842591..0125e0a3ad 100644 --- a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs +++ b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs @@ -161,7 +161,7 @@ namespace osu.Game.Rulesets.Taiko public override IConvertibleReplayFrame CreateConvertibleReplayFrame() => new TaikoReplayFrame(); - public override StatisticRow[] CreateStatisticsForScore(ScoreInfo score, IBeatmap playableBeatmap) => new[] + public override IStatisticRow[] CreateStatisticsForScore(ScoreInfo score, IBeatmap playableBeatmap) => new IStatisticRow[] { new StatisticRow { diff --git a/osu.Game/Rulesets/Ruleset.cs b/osu.Game/Rulesets/Ruleset.cs index 3a7f433a37..f82ecd842a 100644 --- a/osu.Game/Rulesets/Ruleset.cs +++ b/osu.Game/Rulesets/Ruleset.cs @@ -217,6 +217,6 @@ namespace osu.Game.Rulesets /// The , converted for this with all relevant s applied. /// The s to display. Each may contain 0 or more . [NotNull] - public virtual StatisticRow[] CreateStatisticsForScore(ScoreInfo score, IBeatmap playableBeatmap) => Array.Empty(); + public virtual IStatisticRow[] CreateStatisticsForScore(ScoreInfo score, IBeatmap playableBeatmap) => Array.Empty(); } } From f5e52c80b4db250bcb18df027a06095f35347508 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Wed, 26 Aug 2020 19:25:59 +0200 Subject: [PATCH 124/320] Rename {-> Drawable}SimpleStatisticRow --- ...atisticRow.cs => TestSceneDrawableSimpleStatisticRow.cs} | 6 +++--- ...{SimpleStatisticRow.cs => DrawableSimpleStatisticRow.cs} | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) rename osu.Game.Tests/Visual/Ranking/{TestSceneSimpleStatisticRow.cs => TestSceneDrawableSimpleStatisticRow.cs} (88%) rename osu.Game/Screens/Ranking/Statistics/{SimpleStatisticRow.cs => DrawableSimpleStatisticRow.cs} (96%) diff --git a/osu.Game.Tests/Visual/Ranking/TestSceneSimpleStatisticRow.cs b/osu.Game.Tests/Visual/Ranking/TestSceneDrawableSimpleStatisticRow.cs similarity index 88% rename from osu.Game.Tests/Visual/Ranking/TestSceneSimpleStatisticRow.cs rename to osu.Game.Tests/Visual/Ranking/TestSceneDrawableSimpleStatisticRow.cs index aa569e47b1..2b0ba30357 100644 --- a/osu.Game.Tests/Visual/Ranking/TestSceneSimpleStatisticRow.cs +++ b/osu.Game.Tests/Visual/Ranking/TestSceneDrawableSimpleStatisticRow.cs @@ -13,7 +13,7 @@ using osu.Game.Screens.Ranking.Statistics; namespace osu.Game.Tests.Visual.Ranking { - public class TestSceneSimpleStatisticRow : OsuTestScene + public class TestSceneDrawableSimpleStatisticRow : OsuTestScene { private Container container; @@ -45,7 +45,7 @@ namespace osu.Game.Tests.Visual.Ranking public void TestEmpty() { AddStep("create with no items", - () => container.Add(new SimpleStatisticRow(2, Enumerable.Empty()))); + () => container.Add(new DrawableSimpleStatisticRow(2, Enumerable.Empty()))); } [Test] @@ -61,7 +61,7 @@ namespace osu.Game.Tests.Visual.Ranking Value = RNG.Next(100) }); - container.Add(new SimpleStatisticRow(columnCount, items)); + container.Add(new DrawableSimpleStatisticRow(columnCount, items)); }); } } diff --git a/osu.Game/Screens/Ranking/Statistics/SimpleStatisticRow.cs b/osu.Game/Screens/Ranking/Statistics/DrawableSimpleStatisticRow.cs similarity index 96% rename from osu.Game/Screens/Ranking/Statistics/SimpleStatisticRow.cs rename to osu.Game/Screens/Ranking/Statistics/DrawableSimpleStatisticRow.cs index 16501aae54..a592724bc3 100644 --- a/osu.Game/Screens/Ranking/Statistics/SimpleStatisticRow.cs +++ b/osu.Game/Screens/Ranking/Statistics/DrawableSimpleStatisticRow.cs @@ -16,7 +16,7 @@ namespace osu.Game.Screens.Ranking.Statistics /// Represents a statistic row with simple statistics (ones that only need textual display). /// Richer visualisations should be done with s and s. /// - public class SimpleStatisticRow : CompositeDrawable + public class DrawableSimpleStatisticRow : CompositeDrawable { private readonly SimpleStatisticItem[] items; private readonly int columnCount; @@ -28,7 +28,7 @@ namespace osu.Game.Screens.Ranking.Statistics /// /// The number of columns to layout the into. /// The s to display in this row. - public SimpleStatisticRow(int columnCount, IEnumerable items) + public DrawableSimpleStatisticRow(int columnCount, IEnumerable items) { if (columnCount < 1) throw new ArgumentOutOfRangeException(nameof(columnCount)); From 7c3368ecbe1ed8c6af1bd684f5af13027049b548 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Wed, 26 Aug 2020 19:30:49 +0200 Subject: [PATCH 125/320] Reintroduce SimpleStatisticRow as a data class --- .../Statistics/DrawableSimpleStatisticRow.cs | 3 +- .../Ranking/Statistics/SimpleStatisticRow.cs | 34 +++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 osu.Game/Screens/Ranking/Statistics/SimpleStatisticRow.cs diff --git a/osu.Game/Screens/Ranking/Statistics/DrawableSimpleStatisticRow.cs b/osu.Game/Screens/Ranking/Statistics/DrawableSimpleStatisticRow.cs index a592724bc3..7f69b323d8 100644 --- a/osu.Game/Screens/Ranking/Statistics/DrawableSimpleStatisticRow.cs +++ b/osu.Game/Screens/Ranking/Statistics/DrawableSimpleStatisticRow.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Linq; +using JetBrains.Annotations; using osu.Framework.Allocation; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; @@ -28,7 +29,7 @@ namespace osu.Game.Screens.Ranking.Statistics /// /// The number of columns to layout the into. /// The s to display in this row. - public DrawableSimpleStatisticRow(int columnCount, IEnumerable items) + public DrawableSimpleStatisticRow(int columnCount, [ItemNotNull] IEnumerable items) { if (columnCount < 1) throw new ArgumentOutOfRangeException(nameof(columnCount)); diff --git a/osu.Game/Screens/Ranking/Statistics/SimpleStatisticRow.cs b/osu.Game/Screens/Ranking/Statistics/SimpleStatisticRow.cs new file mode 100644 index 0000000000..cd6afeb3a5 --- /dev/null +++ b/osu.Game/Screens/Ranking/Statistics/SimpleStatisticRow.cs @@ -0,0 +1,34 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using JetBrains.Annotations; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; + +namespace osu.Game.Screens.Ranking.Statistics +{ + /// + /// Contains textual statistic data to display in a . + /// + public class SimpleStatisticRow : IStatisticRow + { + /// + /// The number of columns to layout the in. + /// + public int Columns { get; set; } + + /// + /// The s that this row should contain. + /// + [ItemNotNull] + public SimpleStatisticItem[] Items { get; set; } + + public Drawable CreateDrawableStatisticRow() => new Container + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Padding = new MarginPadding(20), + Child = new DrawableSimpleStatisticRow(Columns, Items) + }; + } +} From 5973e2ce4e6d595a6f910b55250ed174a97db92d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Wed, 26 Aug 2020 21:20:43 +0200 Subject: [PATCH 126/320] Add component for unstable rate statistic --- .../Ranking/Statistics/UnstableRate.cs | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 osu.Game/Screens/Ranking/Statistics/UnstableRate.cs diff --git a/osu.Game/Screens/Ranking/Statistics/UnstableRate.cs b/osu.Game/Screens/Ranking/Statistics/UnstableRate.cs new file mode 100644 index 0000000000..5b368c3e8d --- /dev/null +++ b/osu.Game/Screens/Ranking/Statistics/UnstableRate.cs @@ -0,0 +1,39 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System; +using System.Collections.Generic; +using System.Linq; +using osu.Game.Rulesets.Scoring; + +namespace osu.Game.Screens.Ranking.Statistics +{ + /// + /// Displays the unstable rate statistic for a given play. + /// + public class UnstableRate : SimpleStatisticItem + { + /// + /// Creates and computes an statistic. + /// + /// Sequence of s to calculate the unstable rate based on. + public UnstableRate(IEnumerable hitEvents) + : base("Unstable Rate") + { + var timeOffsets = hitEvents.Select(ev => ev.TimeOffset).ToArray(); + Value = 10 * standardDeviation(timeOffsets); + } + + private static double standardDeviation(double[] timeOffsets) + { + if (timeOffsets.Length == 0) + return double.NaN; + + var mean = timeOffsets.Average(); + var squares = timeOffsets.Select(offset => Math.Pow(offset - mean, 2)).Sum(); + return Math.Sqrt(squares / timeOffsets.Length); + } + + protected override string DisplayValue(double value) => double.IsNaN(value) ? "(not available)" : value.ToString("N2"); + } +} From 05e725d59fd5b7710e18f2fb414eb51e02d99e6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Wed, 26 Aug 2020 21:28:41 +0200 Subject: [PATCH 127/320] Add unstable rate statistic to rulesets in which it makes sense --- osu.Game.Rulesets.Mania/ManiaRuleset.cs | 8 ++++ osu.Game.Rulesets.Osu/OsuRuleset.cs | 50 ++++++++++++++++--------- osu.Game.Rulesets.Taiko/TaikoRuleset.cs | 31 ++++++++++----- 3 files changed, 62 insertions(+), 27 deletions(-) diff --git a/osu.Game.Rulesets.Mania/ManiaRuleset.cs b/osu.Game.Rulesets.Mania/ManiaRuleset.cs index 8cc635c316..490223b7a5 100644 --- a/osu.Game.Rulesets.Mania/ManiaRuleset.cs +++ b/osu.Game.Rulesets.Mania/ManiaRuleset.cs @@ -326,6 +326,14 @@ namespace osu.Game.Rulesets.Mania Height = 250 }), } + }, + new SimpleStatisticRow + { + Columns = 3, + Items = new SimpleStatisticItem[] + { + new UnstableRate(score.HitEvents) + } } }; } diff --git a/osu.Game.Rulesets.Osu/OsuRuleset.cs b/osu.Game.Rulesets.Osu/OsuRuleset.cs index 298f1aec91..dd950c60ec 100644 --- a/osu.Game.Rulesets.Osu/OsuRuleset.cs +++ b/osu.Game.Rulesets.Osu/OsuRuleset.cs @@ -193,30 +193,44 @@ namespace osu.Game.Rulesets.Osu public override IRulesetConfigManager CreateConfig(SettingsStore settings) => new OsuRulesetConfigManager(settings, RulesetInfo); - public override IStatisticRow[] CreateStatisticsForScore(ScoreInfo score, IBeatmap playableBeatmap) => new IStatisticRow[] + public override IStatisticRow[] CreateStatisticsForScore(ScoreInfo score, IBeatmap playableBeatmap) { - new StatisticRow + var timedHitEvents = score.HitEvents.Where(e => e.HitObject is HitCircle && !(e.HitObject is SliderTailCircle)).ToList(); + + return new IStatisticRow[] { - Columns = new[] + new StatisticRow { - new StatisticItem("Timing Distribution", new HitEventTimingDistributionGraph(score.HitEvents.Where(e => e.HitObject is HitCircle && !(e.HitObject is SliderTailCircle)).ToList()) + Columns = new[] { - RelativeSizeAxes = Axes.X, - Height = 250 - }), - } - }, - new StatisticRow - { - Columns = new[] + new StatisticItem("Timing Distribution", + new HitEventTimingDistributionGraph(timedHitEvents) + { + RelativeSizeAxes = Axes.X, + Height = 250 + }), + } + }, + new StatisticRow { - new StatisticItem("Accuracy Heatmap", new AccuracyHeatmap(score, playableBeatmap) + Columns = new[] { - RelativeSizeAxes = Axes.X, - Height = 250 - }), + new StatisticItem("Accuracy Heatmap", new AccuracyHeatmap(score, playableBeatmap) + { + RelativeSizeAxes = Axes.X, + Height = 250 + }), + } + }, + new SimpleStatisticRow + { + Columns = 3, + Items = new SimpleStatisticItem[] + { + new UnstableRate(timedHitEvents) + } } - } - }; + }; + } } } diff --git a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs index 0125e0a3ad..938c038413 100644 --- a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs +++ b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs @@ -161,19 +161,32 @@ namespace osu.Game.Rulesets.Taiko public override IConvertibleReplayFrame CreateConvertibleReplayFrame() => new TaikoReplayFrame(); - public override IStatisticRow[] CreateStatisticsForScore(ScoreInfo score, IBeatmap playableBeatmap) => new IStatisticRow[] + public override IStatisticRow[] CreateStatisticsForScore(ScoreInfo score, IBeatmap playableBeatmap) { - new StatisticRow + var timedHitEvents = score.HitEvents.Where(e => e.HitObject is Hit).ToList(); + + return new IStatisticRow[] { - Columns = new[] + new StatisticRow { - new StatisticItem("Timing Distribution", new HitEventTimingDistributionGraph(score.HitEvents.Where(e => e.HitObject is Hit).ToList()) + Columns = new[] { - RelativeSizeAxes = Axes.X, - Height = 250 - }), + new StatisticItem("Timing Distribution", new HitEventTimingDistributionGraph(timedHitEvents) + { + RelativeSizeAxes = Axes.X, + Height = 250 + }), + } + }, + new SimpleStatisticRow + { + Columns = 3, + Items = new SimpleStatisticItem[] + { + new UnstableRate(timedHitEvents) + } } - } - }; + }; + } } } From d81d538b7e202362c8208f403c449bdc018cf443 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Wed, 26 Aug 2020 21:29:01 +0200 Subject: [PATCH 128/320] Move out row anchor/origin set to one central place --- osu.Game/Screens/Ranking/Statistics/StatisticRow.cs | 2 -- osu.Game/Screens/Ranking/Statistics/StatisticsPanel.cs | 6 +++++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Ranking/Statistics/StatisticRow.cs b/osu.Game/Screens/Ranking/Statistics/StatisticRow.cs index fff60cdcad..d5324e14f0 100644 --- a/osu.Game/Screens/Ranking/Statistics/StatisticRow.cs +++ b/osu.Game/Screens/Ranking/Statistics/StatisticRow.cs @@ -21,8 +21,6 @@ namespace osu.Game.Screens.Ranking.Statistics public Drawable CreateDrawableStatisticRow() => new GridContainer { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, Content = new[] diff --git a/osu.Game/Screens/Ranking/Statistics/StatisticsPanel.cs b/osu.Game/Screens/Ranking/Statistics/StatisticsPanel.cs index fd62c9e7d9..2f3304e810 100644 --- a/osu.Game/Screens/Ranking/Statistics/StatisticsPanel.cs +++ b/osu.Game/Screens/Ranking/Statistics/StatisticsPanel.cs @@ -98,7 +98,11 @@ namespace osu.Game.Screens.Ranking.Statistics rows.AddRange(newScore.Ruleset.CreateInstance() .CreateStatisticsForScore(newScore, playableBeatmap) - .Select(row => row.CreateDrawableStatisticRow())); + .Select(row => row.CreateDrawableStatisticRow().With(r => + { + r.Anchor = Anchor.TopCentre; + r.Origin = Anchor.TopCentre; + }))); LoadComponentAsync(rows, d => { From c3197da3dac494617364c88899eef62b5d7f9bcd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Wed, 26 Aug 2020 21:43:33 +0200 Subject: [PATCH 129/320] Adjust simple statistic item font sizes --- osu.Game/Screens/Ranking/Statistics/SimpleStatisticItem.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Ranking/Statistics/SimpleStatisticItem.cs b/osu.Game/Screens/Ranking/Statistics/SimpleStatisticItem.cs index e6c4ab1c4e..3d9ba2f225 100644 --- a/osu.Game/Screens/Ranking/Statistics/SimpleStatisticItem.cs +++ b/osu.Game/Screens/Ranking/Statistics/SimpleStatisticItem.cs @@ -41,13 +41,14 @@ namespace osu.Game.Screens.Ranking.Statistics { Text = Name, Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft + Origin = Anchor.CentreLeft, + Font = OsuFont.GetFont(size: 14) }, value = new OsuSpriteText { Anchor = Anchor.CentreRight, Origin = Anchor.CentreRight, - Font = OsuFont.Torus.With(weight: FontWeight.Bold) + Font = OsuFont.GetFont(size: 14, weight: FontWeight.Bold) } }); } From f8042e6fd311b4f6713e75c310de746d4ea5daf7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Wed, 26 Aug 2020 22:34:02 +0200 Subject: [PATCH 130/320] Add fade to prevent jarring transitions --- osu.Game/Screens/Ranking/Statistics/StatisticsPanel.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Screens/Ranking/Statistics/StatisticsPanel.cs b/osu.Game/Screens/Ranking/Statistics/StatisticsPanel.cs index 2f3304e810..3b8f980070 100644 --- a/osu.Game/Screens/Ranking/Statistics/StatisticsPanel.cs +++ b/osu.Game/Screens/Ranking/Statistics/StatisticsPanel.cs @@ -94,6 +94,7 @@ namespace osu.Game.Screens.Ranking.Statistics RelativeSizeAxes = Axes.Both, Direction = FillDirection.Vertical, Spacing = new Vector2(30, 15), + Alpha = 0 }; rows.AddRange(newScore.Ruleset.CreateInstance() @@ -111,6 +112,7 @@ namespace osu.Game.Screens.Ranking.Statistics spinner.Hide(); content.Add(d); + d.FadeIn(250, Easing.OutQuint); }, localCancellationSource.Token); }), localCancellationSource.Token); } From deb172bb6ccab9cc46f015957eb45bb06ce1c04f Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 27 Aug 2020 20:24:08 +0900 Subject: [PATCH 131/320] Implement basic mania hit order policy --- .../TestSceneOutOfOrderHits.cs | 124 ++++++++++++++++++ .../Objects/Drawables/DrawableHoldNote.cs | 3 + .../Drawables/DrawableManiaHitObject.cs | 9 ++ .../Objects/Drawables/DrawableNote.cs | 3 + osu.Game.Rulesets.Mania/UI/Column.cs | 10 ++ .../UI/OrderedHitPolicy.cs | 66 ++++++++++ 6 files changed, 215 insertions(+) create mode 100644 osu.Game.Rulesets.Mania.Tests/TestSceneOutOfOrderHits.cs create mode 100644 osu.Game.Rulesets.Mania/UI/OrderedHitPolicy.cs diff --git a/osu.Game.Rulesets.Mania.Tests/TestSceneOutOfOrderHits.cs b/osu.Game.Rulesets.Mania.Tests/TestSceneOutOfOrderHits.cs new file mode 100644 index 0000000000..ed187e65bf --- /dev/null +++ b/osu.Game.Rulesets.Mania.Tests/TestSceneOutOfOrderHits.cs @@ -0,0 +1,124 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System; +using System.Collections.Generic; +using System.Linq; +using NUnit.Framework; +using osu.Framework.Extensions.TypeExtensions; +using osu.Framework.Screens; +using osu.Framework.Utils; +using osu.Game.Beatmaps.ControlPoints; +using osu.Game.Replays; +using osu.Game.Rulesets.Judgements; +using osu.Game.Rulesets.Mania.Beatmaps; +using osu.Game.Rulesets.Mania.Objects; +using osu.Game.Rulesets.Mania.Replays; +using osu.Game.Rulesets.Replays; +using osu.Game.Rulesets.Scoring; +using osu.Game.Scoring; +using osu.Game.Screens.Play; +using osu.Game.Tests.Visual; + +namespace osu.Game.Rulesets.Mania.Tests +{ + public class TestSceneOutOfOrderHits : RateAdjustedBeatmapTestScene + { + [Test] + public void TestPreviousHitWindowDoesNotExtendPastNextObject() + { + var objects = new List(); + var frames = new List(); + + for (int i = 0; i < 7; i++) + { + double time = 1000 + i * 100; + + objects.Add(new Note { StartTime = time }); + + if (i > 0) + { + frames.Add(new ManiaReplayFrame(time + 10, ManiaAction.Key1)); + frames.Add(new ManiaReplayFrame(time + 11)); + } + } + + performTest(objects, frames); + + addJudgementAssert(objects[0], HitResult.Miss); + + for (int i = 1; i < 7; i++) + { + addJudgementAssert(objects[i], HitResult.Perfect); + addJudgementOffsetAssert(objects[i], 10); + } + } + + private void addJudgementAssert(ManiaHitObject hitObject, HitResult result) + { + AddAssert($"({hitObject.GetType().ReadableName()} @ {hitObject.StartTime}) judgement is {result}", + () => judgementResults.Single(r => r.HitObject == hitObject).Type == result); + } + + private void addJudgementAssert(string name, Func hitObject, HitResult result) + { + AddAssert($"{name} judgement is {result}", + () => judgementResults.Single(r => r.HitObject == hitObject()).Type == result); + } + + private void addJudgementOffsetAssert(ManiaHitObject hitObject, double offset) + { + AddAssert($"({hitObject.GetType().ReadableName()} @ {hitObject.StartTime}) judged at {offset}", + () => Precision.AlmostEquals(judgementResults.Single(r => r.HitObject == hitObject).TimeOffset, offset, 100)); + } + + private ScoreAccessibleReplayPlayer currentPlayer; + private List judgementResults; + + private void performTest(List hitObjects, List frames) + { + AddStep("load player", () => + { + Beatmap.Value = CreateWorkingBeatmap(new ManiaBeatmap(new StageDefinition { Columns = 4 }) + { + HitObjects = hitObjects, + BeatmapInfo = + { + Ruleset = new ManiaRuleset().RulesetInfo + }, + }); + + Beatmap.Value.Beatmap.ControlPointInfo.Add(0, new DifficultyControlPoint { SpeedMultiplier = 0.1f }); + + var p = new ScoreAccessibleReplayPlayer(new Score { Replay = new Replay { Frames = frames } }); + + p.OnLoadComplete += _ => + { + p.ScoreProcessor.NewJudgement += result => + { + if (currentPlayer == p) judgementResults.Add(result); + }; + }; + + LoadScreen(currentPlayer = p); + judgementResults = new List(); + }); + + AddUntilStep("Beatmap at 0", () => Beatmap.Value.Track.CurrentTime == 0); + AddUntilStep("Wait until player is loaded", () => currentPlayer.IsCurrentScreen()); + AddUntilStep("Wait for completion", () => currentPlayer.ScoreProcessor.HasCompleted.Value); + } + + private class ScoreAccessibleReplayPlayer : ReplayPlayer + { + public new ScoreProcessor ScoreProcessor => base.ScoreProcessor; + + protected override bool PauseOnFocusLost => false; + + public ScoreAccessibleReplayPlayer(Score score) + : base(score, false, false) + { + } + } + } +} diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs index 0712026ca6..a04e5bc2f9 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs @@ -252,6 +252,9 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables if (action != Action.Value) return false; + if (CheckHittable?.Invoke(this, Time.Current) == false) + return false; + // The tail has a lenience applied to it which is factored into the miss window (i.e. the miss judgement will be delayed). // But the hold cannot ever be started within the late-lenience window, so we should skip trying to begin the hold during that time. // Note: Unlike below, we use the tail's start time to determine the time offset. diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs index ab76a5b8f8..0594d1e143 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.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; using JetBrains.Annotations; using osu.Framework.Allocation; using osu.Framework.Bindables; @@ -8,6 +9,7 @@ using osu.Framework.Graphics; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.UI.Scrolling; using osu.Game.Rulesets.Mania.UI; +using osu.Game.Rulesets.Scoring; namespace osu.Game.Rulesets.Mania.Objects.Drawables { @@ -34,6 +36,8 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables } } + public Func CheckHittable; + protected DrawableManiaHitObject(ManiaHitObject hitObject) : base(hitObject) { @@ -124,6 +128,11 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables break; } } + + /// + /// Causes this to get missed, disregarding all conditions in implementations of . + /// + public void MissForcefully() => ApplyResult(r => r.Type = HitResult.Miss); } public abstract class DrawableManiaHitObject : DrawableManiaHitObject diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs index 9451bc4430..973dc06e05 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs @@ -64,6 +64,9 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables if (action != Action.Value) return false; + if (CheckHittable?.Invoke(this, Time.Current) == false) + return false; + return UpdateResult(true); } diff --git a/osu.Game.Rulesets.Mania/UI/Column.cs b/osu.Game.Rulesets.Mania/UI/Column.cs index de4648e4fa..9aabcc6699 100644 --- a/osu.Game.Rulesets.Mania/UI/Column.cs +++ b/osu.Game.Rulesets.Mania/UI/Column.cs @@ -17,6 +17,7 @@ using osu.Game.Rulesets.UI.Scrolling; using osu.Game.Skinning; using osuTK; using osu.Game.Rulesets.Mania.Beatmaps; +using osu.Game.Rulesets.Mania.Objects.Drawables; namespace osu.Game.Rulesets.Mania.UI { @@ -36,6 +37,7 @@ namespace osu.Game.Rulesets.Mania.UI public readonly ColumnHitObjectArea HitObjectArea; internal readonly Container TopLevelContainer; private readonly DrawablePool hitExplosionPool; + private readonly OrderedHitPolicy hitPolicy; public Container UnderlayElements => HitObjectArea.UnderlayElements; @@ -65,6 +67,8 @@ namespace osu.Game.Rulesets.Mania.UI TopLevelContainer = new Container { RelativeSizeAxes = Axes.Both } }; + hitPolicy = new OrderedHitPolicy(HitObjectContainer); + TopLevelContainer.Add(HitObjectArea.Explosions.CreateProxy()); } @@ -90,6 +94,9 @@ namespace osu.Game.Rulesets.Mania.UI hitObject.AccentColour.Value = AccentColour; hitObject.OnNewResult += OnNewResult; + DrawableManiaHitObject maniaObject = (DrawableManiaHitObject)hitObject; + maniaObject.CheckHittable = hitPolicy.IsHittable; + HitObjectContainer.Add(hitObject); } @@ -104,6 +111,9 @@ namespace osu.Game.Rulesets.Mania.UI internal void OnNewResult(DrawableHitObject judgedObject, JudgementResult result) { + if (result.IsHit) + hitPolicy.HandleHit(judgedObject); + if (!result.IsHit || !judgedObject.DisplayResult || !DisplayJudgements.Value) return; diff --git a/osu.Game.Rulesets.Mania/UI/OrderedHitPolicy.cs b/osu.Game.Rulesets.Mania/UI/OrderedHitPolicy.cs new file mode 100644 index 0000000000..68183be89f --- /dev/null +++ b/osu.Game.Rulesets.Mania/UI/OrderedHitPolicy.cs @@ -0,0 +1,66 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System; +using System.Collections.Generic; +using osu.Framework.Extensions.IEnumerableExtensions; +using osu.Game.Rulesets.Mania.Objects.Drawables; +using osu.Game.Rulesets.Objects; +using osu.Game.Rulesets.Objects.Drawables; +using osu.Game.Rulesets.UI; + +namespace osu.Game.Rulesets.Mania.UI +{ + public class OrderedHitPolicy + { + private readonly HitObjectContainer hitObjectContainer; + + public OrderedHitPolicy(HitObjectContainer hitObjectContainer) + { + this.hitObjectContainer = hitObjectContainer; + } + + public bool IsHittable(DrawableHitObject hitObject, double time) + { + var nextObject = hitObjectContainer.AliveObjects.GetNext(hitObject); + return nextObject == null || time < nextObject.HitObject.StartTime; + } + + /// + /// Handles a being hit to potentially miss all earlier s. + /// + /// The that was hit. + public void HandleHit(DrawableHitObject hitObject) + { + if (!IsHittable(hitObject, hitObject.HitObject.StartTime + hitObject.Result.TimeOffset)) + throw new InvalidOperationException($"A {hitObject} was hit before it became hittable!"); + + foreach (var obj in enumerateHitObjectsUpTo(hitObject.HitObject.StartTime)) + { + if (obj.Judged) + continue; + + ((DrawableManiaHitObject)obj).MissForcefully(); + } + } + + private IEnumerable enumerateHitObjectsUpTo(double targetTime) + { + foreach (var obj in hitObjectContainer.AliveObjects) + { + if (obj.HitObject.StartTime >= targetTime) + yield break; + + yield return obj; + + foreach (var nestedObj in obj.NestedHitObjects) + { + if (nestedObj.HitObject.StartTime >= targetTime) + break; + + yield return nestedObj; + } + } + } + } +} From 6f93df0b9dbd1317b072c61b124fb50b30017b41 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 27 Aug 2020 21:05:12 +0900 Subject: [PATCH 132/320] Fix ticks causing hold note misses --- osu.Game.Rulesets.Mania/UI/OrderedHitPolicy.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Mania/UI/OrderedHitPolicy.cs b/osu.Game.Rulesets.Mania/UI/OrderedHitPolicy.cs index 68183be89f..dfd5136e3e 100644 --- a/osu.Game.Rulesets.Mania/UI/OrderedHitPolicy.cs +++ b/osu.Game.Rulesets.Mania/UI/OrderedHitPolicy.cs @@ -48,14 +48,14 @@ namespace osu.Game.Rulesets.Mania.UI { foreach (var obj in hitObjectContainer.AliveObjects) { - if (obj.HitObject.StartTime >= targetTime) + if (obj.HitObject.GetEndTime() >= targetTime) yield break; yield return obj; foreach (var nestedObj in obj.NestedHitObjects) { - if (nestedObj.HitObject.StartTime >= targetTime) + if (nestedObj.HitObject.GetEndTime() >= targetTime) break; yield return nestedObj; From 7a5292936e57096e3521a1781d33d777fdc386d4 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 27 Aug 2020 21:15:05 +0900 Subject: [PATCH 133/320] Add some xmldocs --- osu.Game.Rulesets.Mania/UI/OrderedHitPolicy.cs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/osu.Game.Rulesets.Mania/UI/OrderedHitPolicy.cs b/osu.Game.Rulesets.Mania/UI/OrderedHitPolicy.cs index dfd5136e3e..0f9cd48dd8 100644 --- a/osu.Game.Rulesets.Mania/UI/OrderedHitPolicy.cs +++ b/osu.Game.Rulesets.Mania/UI/OrderedHitPolicy.cs @@ -11,6 +11,9 @@ using osu.Game.Rulesets.UI; namespace osu.Game.Rulesets.Mania.UI { + /// + /// Ensures that only the most recent is hittable, affectionately known as "note lock". + /// public class OrderedHitPolicy { private readonly HitObjectContainer hitObjectContainer; @@ -20,6 +23,15 @@ namespace osu.Game.Rulesets.Mania.UI this.hitObjectContainer = hitObjectContainer; } + /// + /// Determines whether a can be hit at a point in time. + /// + /// + /// Only the most recent can be hit, a previous hitobject's window cannot extend past the next one. + /// + /// The to check. + /// The time to check. + /// Whether can be hit at the given . public bool IsHittable(DrawableHitObject hitObject, double time) { var nextObject = hitObjectContainer.AliveObjects.GetNext(hitObject); From 29b29cde8e69330a1fdb62aec6ea802288242ec3 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 27 Aug 2020 23:09:54 +0900 Subject: [PATCH 134/320] Flip condition to reduce nesting --- .../Skinning/LegacyBodyPiece.cs | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Skinning/LegacyBodyPiece.cs b/osu.Game.Rulesets.Mania/Skinning/LegacyBodyPiece.cs index a1c2559386..f2e92a7258 100644 --- a/osu.Game.Rulesets.Mania/Skinning/LegacyBodyPiece.cs +++ b/osu.Game.Rulesets.Mania/Skinning/LegacyBodyPiece.cs @@ -101,28 +101,28 @@ namespace osu.Game.Rulesets.Mania.Skinning bodyAnimation.IsPlaying = isHitting.NewValue; } - if (lightContainer != null) + if (lightContainer == null) + return; + + if (isHitting.NewValue) { - if (isHitting.NewValue) - { - // Clear the fade out and, more importantly, the removal. - lightContainer.ClearTransforms(); + // Clear the fade out and, more importantly, the removal. + lightContainer.ClearTransforms(); - // Only add the container if the removal has taken place. - if (lightContainer.Parent == null) - Column.TopLevelContainer.Add(lightContainer); + // Only add the container if the removal has taken place. + if (lightContainer.Parent == null) + Column.TopLevelContainer.Add(lightContainer); - // The light must be seeked only after being loaded, otherwise a nullref occurs (https://github.com/ppy/osu-framework/issues/3847). - if (light is TextureAnimation lightAnimation) - lightAnimation.GotoFrame(0); + // The light must be seeked only after being loaded, otherwise a nullref occurs (https://github.com/ppy/osu-framework/issues/3847). + if (light is TextureAnimation lightAnimation) + lightAnimation.GotoFrame(0); - lightContainer.FadeIn(80); - } - else - { - lightContainer.FadeOut(120) - .OnComplete(d => Column.TopLevelContainer.Remove(d)); - } + lightContainer.FadeIn(80); + } + else + { + lightContainer.FadeOut(120) + .OnComplete(d => Column.TopLevelContainer.Remove(d)); } } From 700219316519201aa90ec2327091244553b6e250 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 27 Aug 2020 23:16:54 +0900 Subject: [PATCH 135/320] Mark nullable members --- osu.Game.Rulesets.Mania/Skinning/LegacyBodyPiece.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/osu.Game.Rulesets.Mania/Skinning/LegacyBodyPiece.cs b/osu.Game.Rulesets.Mania/Skinning/LegacyBodyPiece.cs index f2e92a7258..c0f0fcb4af 100644 --- a/osu.Game.Rulesets.Mania/Skinning/LegacyBodyPiece.cs +++ b/osu.Game.Rulesets.Mania/Skinning/LegacyBodyPiece.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System; +using JetBrains.Annotations; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -20,8 +21,13 @@ namespace osu.Game.Rulesets.Mania.Skinning private readonly IBindable direction = new Bindable(); private readonly IBindable isHitting = new Bindable(); + [CanBeNull] private Drawable bodySprite; + + [CanBeNull] private Drawable lightContainer; + + [CanBeNull] private Drawable light; public LegacyBodyPiece() From 9d70b4af0922a20a1877df82bd745896d8b72132 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Thu, 27 Aug 2020 17:35:42 +0200 Subject: [PATCH 136/320] Add failing test case --- .../Formats/LegacyScoreDecoderTest.cs | 66 ++++++++++++++++++ .../Resources/Replays/mania-replay.osr | Bin 0 -> 1012 bytes 2 files changed, 66 insertions(+) create mode 100644 osu.Game.Tests/Beatmaps/Formats/LegacyScoreDecoderTest.cs create mode 100644 osu.Game.Tests/Resources/Replays/mania-replay.osr diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyScoreDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyScoreDecoderTest.cs new file mode 100644 index 0000000000..31c367aad1 --- /dev/null +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyScoreDecoderTest.cs @@ -0,0 +1,66 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Collections.Generic; +using System.Linq; +using NUnit.Framework; +using osu.Game.Beatmaps; +using osu.Game.Rulesets; +using osu.Game.Rulesets.Catch; +using osu.Game.Rulesets.Mania; +using osu.Game.Rulesets.Osu; +using osu.Game.Rulesets.Scoring; +using osu.Game.Rulesets.Taiko; +using osu.Game.Scoring.Legacy; +using osu.Game.Tests.Resources; + +namespace osu.Game.Tests.Beatmaps.Formats +{ + [TestFixture] + public class LegacyScoreDecoderTest + { + [Test] + public void TestDecodeManiaReplay() + { + var decoder = new TestLegacyScoreDecoder(); + + using (var resourceStream = TestResources.OpenResource("Replays/mania-replay.osr")) + { + var score = decoder.Parse(resourceStream); + + Assert.AreEqual(3, score.ScoreInfo.Ruleset.ID); + + Assert.AreEqual(2, score.ScoreInfo.Statistics[HitResult.Great]); + Assert.AreEqual(1, score.ScoreInfo.Statistics[HitResult.Good]); + + Assert.AreEqual(829_931, score.ScoreInfo.TotalScore); + Assert.AreEqual(3, score.ScoreInfo.MaxCombo); + + Assert.That(score.Replay.Frames, Is.Not.Empty); + } + } + + private class TestLegacyScoreDecoder : LegacyScoreDecoder + { + private static readonly Dictionary rulesets = new Ruleset[] + { + new OsuRuleset(), + new TaikoRuleset(), + new CatchRuleset(), + new ManiaRuleset() + }.ToDictionary(ruleset => ((ILegacyRuleset)ruleset).LegacyID); + + protected override Ruleset GetRuleset(int rulesetId) => rulesets[rulesetId]; + + protected override WorkingBeatmap GetBeatmap(string md5Hash) => new TestWorkingBeatmap(new Beatmap + { + BeatmapInfo = new BeatmapInfo + { + MD5Hash = md5Hash, + Ruleset = new OsuRuleset().RulesetInfo, + BaseDifficulty = new BeatmapDifficulty() + } + }); + } + } +} diff --git a/osu.Game.Tests/Resources/Replays/mania-replay.osr b/osu.Game.Tests/Resources/Replays/mania-replay.osr new file mode 100644 index 0000000000000000000000000000000000000000..da1a7bdd28e5b89eddd9742bce2b27bc8e75e6f5 GIT binary patch literal 1012 zcmV2Fk>_^VL323Gh;F`G&3?}Wi$c+0000000031008T$3;+WF00000 z01FT?FgZ6ed@(FBI50Uld@(FxP`z80O4tZ&0{{SB001BWz5CvGFroXr>*+lrR^_@@;>&b?uOx<^mMIMT(+z#h{kY?X9fc(g(Lwebtx# z7Q6Lh=|qk7uqqmlbl#mwF~34O;`FY?03m(j9XrY3L)0)1?Fw}$4J_CNJKO;4?X$~q z;+wGa#wD!!0q2PlCzFrV3*3>Lz{D|fez@9JR^@L#NXJJJ;9{+KP~}bh@_eim%+NSk zzegnGWya)SS7pW`<9yI$g`b0t!?MZslqBX+4bVy#tZV0pDNGmeSXKuOXGQ|f3zg8y zGrMu+gxo2?L-AA5RBaNH&*&Dv9Dc!%ufdTEO? zp@}%SBej)D4N{g#xwHF)8|Ks=@OJ2^BGnjH?@$dDOeELCl()%CSSocJ#J0 zrMz`0akC4=AW51K>p71-r!saF*3AP)S9{~98w6pYSsUr1=*o_Q#S)6A-dHA@d9~(^0+ax|D@!;n;Z|| zFvVlqvtKZJf2x8EVoS#`3YPzS-*vaun`i1N*BG`MvK_+XgTPh^GgHpdy!e==KZIaT z3!YC}(8nGj*i;imyixwy9zyF`AooHY90sBzR$Obzb-Vi~&7$v#i3~s7*O{}|SLmeL zoMGZCnRwCc_XbwVIh5g#M@wt{FGra$aqhxs9vn18+0v`>fSkg3XKs=0k_AUDZ~8>a zDG78!sD4dHOSBcg!q83SKA#^J)eG3=oY`jU3QIF2QVgemNl8@7S4(W%aYN@e0jDu% zmqiUorSh0*IbBRsW~4cH;@gJJOutPU2TVP<=OEnHm=mZ{2D~6Z=U*j5r!6K@YHyj* zwhC8cbzc~TkcHU?&2W;Km_To^u4o{p7%^`#txPglTyDDFl%vh Date: Thu, 27 Aug 2020 17:40:22 +0200 Subject: [PATCH 137/320] Fix some legacy mania replays crashing on import --- osu.Game/Scoring/Legacy/LegacyScoreDecoder.cs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/osu.Game/Scoring/Legacy/LegacyScoreDecoder.cs b/osu.Game/Scoring/Legacy/LegacyScoreDecoder.cs index a4a560c8e4..a3469f0965 100644 --- a/osu.Game/Scoring/Legacy/LegacyScoreDecoder.cs +++ b/osu.Game/Scoring/Legacy/LegacyScoreDecoder.cs @@ -241,12 +241,15 @@ namespace osu.Game.Scoring.Legacy } var diff = Parsing.ParseFloat(split[0]); + var mouseX = Parsing.ParseFloat(split[1], Parsing.MAX_COORDINATE_VALUE); + var mouseY = Parsing.ParseFloat(split[2], Parsing.MAX_COORDINATE_VALUE); lastTime += diff; - if (i == 0 && diff == 0) - // osu-stable adds a zero-time frame before potentially valid negative user frames. - // we need to ignore this. + if (i < 2 && mouseX == 256 && mouseY == -500) + // at the start of the replay, stable places two replay frames, at time 0 and SkipBoundary - 1, respectively. + // both frames use a position of (256, -500). + // ignore these frames as they serve no real purpose (and can even mislead ruleset-specific handlers - see mania) continue; // Todo: At some point we probably want to rewind and play back the negative-time frames @@ -255,8 +258,8 @@ namespace osu.Game.Scoring.Legacy continue; currentFrame = convertFrame(new LegacyReplayFrame(lastTime, - Parsing.ParseFloat(split[1], Parsing.MAX_COORDINATE_VALUE), - Parsing.ParseFloat(split[2], Parsing.MAX_COORDINATE_VALUE), + mouseX, + mouseY, (ReplayButtonState)Parsing.ParseInt(split[3])), currentFrame); replay.Frames.Add(currentFrame); From 37387d774165340e14c1e1ea493e23bb3aea693a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Thu, 27 Aug 2020 17:57:55 +0200 Subject: [PATCH 138/320] Add assertions to existing test to cover bug --- osu.Game.Tests/Beatmaps/Formats/LegacyScoreDecoderTest.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyScoreDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyScoreDecoderTest.cs index 31c367aad1..9c71466489 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyScoreDecoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyScoreDecoderTest.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Linq; using NUnit.Framework; +using osu.Framework.Utils; using osu.Game.Beatmaps; using osu.Game.Rulesets; using osu.Game.Rulesets.Catch; @@ -11,6 +12,7 @@ using osu.Game.Rulesets.Mania; using osu.Game.Rulesets.Osu; using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.Taiko; +using osu.Game.Scoring; using osu.Game.Scoring.Legacy; using osu.Game.Tests.Resources; @@ -35,6 +37,8 @@ namespace osu.Game.Tests.Beatmaps.Formats Assert.AreEqual(829_931, score.ScoreInfo.TotalScore); Assert.AreEqual(3, score.ScoreInfo.MaxCombo); + Assert.IsTrue(Precision.AlmostEquals(0.8889, score.ScoreInfo.Accuracy, 0.0001)); + Assert.AreEqual(ScoreRank.B, score.ScoreInfo.Rank); Assert.That(score.Replay.Frames, Is.Not.Empty); } From af59e2c17954ce8fbf3df20ed2a0b6d3eeb74fa1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Thu, 27 Aug 2020 18:05:06 +0200 Subject: [PATCH 139/320] Use extension methods instead of reading directly --- osu.Game/Scoring/Legacy/LegacyScoreDecoder.cs | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/osu.Game/Scoring/Legacy/LegacyScoreDecoder.cs b/osu.Game/Scoring/Legacy/LegacyScoreDecoder.cs index a3469f0965..97cb5ca7ab 100644 --- a/osu.Game/Scoring/Legacy/LegacyScoreDecoder.cs +++ b/osu.Game/Scoring/Legacy/LegacyScoreDecoder.cs @@ -13,7 +13,6 @@ using osu.Game.Replays.Legacy; using osu.Game.Rulesets; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Replays; -using osu.Game.Rulesets.Scoring; using osu.Game.Users; using SharpCompress.Compressors.LZMA; @@ -123,12 +122,12 @@ namespace osu.Game.Scoring.Legacy protected void CalculateAccuracy(ScoreInfo score) { - score.Statistics.TryGetValue(HitResult.Miss, out int countMiss); - score.Statistics.TryGetValue(HitResult.Meh, out int count50); - score.Statistics.TryGetValue(HitResult.Good, out int count100); - score.Statistics.TryGetValue(HitResult.Great, out int count300); - score.Statistics.TryGetValue(HitResult.Perfect, out int countGeki); - score.Statistics.TryGetValue(HitResult.Ok, out int countKatu); + int countMiss = score.GetCountMiss() ?? 0; + int count50 = score.GetCount50() ?? 0; + int count100 = score.GetCount100() ?? 0; + int count300 = score.GetCount300() ?? 0; + int countGeki = score.GetCountGeki() ?? 0; + int countKatu = score.GetCountKatu() ?? 0; switch (score.Ruleset.ID) { From f152e1b924f23da565ce0a89fb19ca3f2f16ac50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Thu, 27 Aug 2020 20:07:30 +0200 Subject: [PATCH 140/320] Revert IStatisticRow changes --- osu.Game.Rulesets.Mania/ManiaRuleset.cs | 10 +------ osu.Game.Rulesets.Osu/OsuRuleset.cs | 12 ++------ osu.Game.Rulesets.Taiko/TaikoRuleset.cs | 12 ++------ osu.Game/Rulesets/Ruleset.cs | 2 +- .../Ranking/Statistics/IStatisticRow.cs | 18 ------------ .../Ranking/Statistics/SimpleStatisticRow.cs | 2 +- .../Ranking/Statistics/StatisticRow.cs | 24 ++-------------- .../Ranking/Statistics/StatisticsPanel.cs | 28 ++++++++++++++----- 8 files changed, 30 insertions(+), 78 deletions(-) delete mode 100644 osu.Game/Screens/Ranking/Statistics/IStatisticRow.cs diff --git a/osu.Game.Rulesets.Mania/ManiaRuleset.cs b/osu.Game.Rulesets.Mania/ManiaRuleset.cs index 490223b7a5..bbfc5739ec 100644 --- a/osu.Game.Rulesets.Mania/ManiaRuleset.cs +++ b/osu.Game.Rulesets.Mania/ManiaRuleset.cs @@ -314,7 +314,7 @@ namespace osu.Game.Rulesets.Mania return (PlayfieldType)Enum.GetValues(typeof(PlayfieldType)).Cast().OrderByDescending(i => i).First(v => variant >= v); } - public override IStatisticRow[] CreateStatisticsForScore(ScoreInfo score, IBeatmap playableBeatmap) => new IStatisticRow[] + public override StatisticRow[] CreateStatisticsForScore(ScoreInfo score, IBeatmap playableBeatmap) => new[] { new StatisticRow { @@ -327,14 +327,6 @@ namespace osu.Game.Rulesets.Mania }), } }, - new SimpleStatisticRow - { - Columns = 3, - Items = new SimpleStatisticItem[] - { - new UnstableRate(score.HitEvents) - } - } }; } diff --git a/osu.Game.Rulesets.Osu/OsuRuleset.cs b/osu.Game.Rulesets.Osu/OsuRuleset.cs index dd950c60ec..14e7b9e9a4 100644 --- a/osu.Game.Rulesets.Osu/OsuRuleset.cs +++ b/osu.Game.Rulesets.Osu/OsuRuleset.cs @@ -193,11 +193,11 @@ namespace osu.Game.Rulesets.Osu public override IRulesetConfigManager CreateConfig(SettingsStore settings) => new OsuRulesetConfigManager(settings, RulesetInfo); - public override IStatisticRow[] CreateStatisticsForScore(ScoreInfo score, IBeatmap playableBeatmap) + public override StatisticRow[] CreateStatisticsForScore(ScoreInfo score, IBeatmap playableBeatmap) { var timedHitEvents = score.HitEvents.Where(e => e.HitObject is HitCircle && !(e.HitObject is SliderTailCircle)).ToList(); - return new IStatisticRow[] + return new[] { new StatisticRow { @@ -222,14 +222,6 @@ namespace osu.Game.Rulesets.Osu }), } }, - new SimpleStatisticRow - { - Columns = 3, - Items = new SimpleStatisticItem[] - { - new UnstableRate(timedHitEvents) - } - } }; } } diff --git a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs index 938c038413..367d991677 100644 --- a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs +++ b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs @@ -161,11 +161,11 @@ namespace osu.Game.Rulesets.Taiko public override IConvertibleReplayFrame CreateConvertibleReplayFrame() => new TaikoReplayFrame(); - public override IStatisticRow[] CreateStatisticsForScore(ScoreInfo score, IBeatmap playableBeatmap) + public override StatisticRow[] CreateStatisticsForScore(ScoreInfo score, IBeatmap playableBeatmap) { var timedHitEvents = score.HitEvents.Where(e => e.HitObject is Hit).ToList(); - return new IStatisticRow[] + return new[] { new StatisticRow { @@ -178,14 +178,6 @@ namespace osu.Game.Rulesets.Taiko }), } }, - new SimpleStatisticRow - { - Columns = 3, - Items = new SimpleStatisticItem[] - { - new UnstableRate(timedHitEvents) - } - } }; } } diff --git a/osu.Game/Rulesets/Ruleset.cs b/osu.Game/Rulesets/Ruleset.cs index f82ecd842a..3a7f433a37 100644 --- a/osu.Game/Rulesets/Ruleset.cs +++ b/osu.Game/Rulesets/Ruleset.cs @@ -217,6 +217,6 @@ namespace osu.Game.Rulesets /// The , converted for this with all relevant s applied. /// The s to display. Each may contain 0 or more . [NotNull] - public virtual IStatisticRow[] CreateStatisticsForScore(ScoreInfo score, IBeatmap playableBeatmap) => Array.Empty(); + public virtual StatisticRow[] CreateStatisticsForScore(ScoreInfo score, IBeatmap playableBeatmap) => Array.Empty(); } } diff --git a/osu.Game/Screens/Ranking/Statistics/IStatisticRow.cs b/osu.Game/Screens/Ranking/Statistics/IStatisticRow.cs deleted file mode 100644 index 67224041d5..0000000000 --- a/osu.Game/Screens/Ranking/Statistics/IStatisticRow.cs +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using osu.Framework.Graphics; - -namespace osu.Game.Screens.Ranking.Statistics -{ - /// - /// A row of statistics to be displayed on the results screen. - /// - public interface IStatisticRow - { - /// - /// Creates the visual representation of this row. - /// - Drawable CreateDrawableStatisticRow(); - } -} diff --git a/osu.Game/Screens/Ranking/Statistics/SimpleStatisticRow.cs b/osu.Game/Screens/Ranking/Statistics/SimpleStatisticRow.cs index cd6afeb3a5..5c0cb5b116 100644 --- a/osu.Game/Screens/Ranking/Statistics/SimpleStatisticRow.cs +++ b/osu.Game/Screens/Ranking/Statistics/SimpleStatisticRow.cs @@ -10,7 +10,7 @@ namespace osu.Game.Screens.Ranking.Statistics /// /// Contains textual statistic data to display in a . /// - public class SimpleStatisticRow : IStatisticRow + public class SimpleStatisticRow { /// /// The number of columns to layout the in. diff --git a/osu.Game/Screens/Ranking/Statistics/StatisticRow.cs b/osu.Game/Screens/Ranking/Statistics/StatisticRow.cs index d5324e14f0..e1ca9799a3 100644 --- a/osu.Game/Screens/Ranking/Statistics/StatisticRow.cs +++ b/osu.Game/Screens/Ranking/Statistics/StatisticRow.cs @@ -1,39 +1,19 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System.Linq; using JetBrains.Annotations; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; namespace osu.Game.Screens.Ranking.Statistics { /// - /// A row of graphically detailed s to be displayed in the results screen. + /// A row of statistics to be displayed in the results screen. /// - public class StatisticRow : IStatisticRow + public class StatisticRow { /// /// The columns of this . /// [ItemNotNull] public StatisticItem[] Columns; - - public Drawable CreateDrawableStatisticRow() => new GridContainer - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Content = new[] - { - Columns?.Select(c => new StatisticContainer(c) - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - }).Cast().ToArray() - }, - ColumnDimensions = Enumerable.Range(0, Columns?.Length ?? 0) - .Select(i => Columns[i].Dimension ?? new Dimension()).ToArray(), - RowDimensions = new[] { new Dimension(GridSizeMode.AutoSize) } - }; } } diff --git a/osu.Game/Screens/Ranking/Statistics/StatisticsPanel.cs b/osu.Game/Screens/Ranking/Statistics/StatisticsPanel.cs index 3b8f980070..128c6674e8 100644 --- a/osu.Game/Screens/Ranking/Statistics/StatisticsPanel.cs +++ b/osu.Game/Screens/Ranking/Statistics/StatisticsPanel.cs @@ -97,13 +97,27 @@ namespace osu.Game.Screens.Ranking.Statistics Alpha = 0 }; - rows.AddRange(newScore.Ruleset.CreateInstance() - .CreateStatisticsForScore(newScore, playableBeatmap) - .Select(row => row.CreateDrawableStatisticRow().With(r => - { - r.Anchor = Anchor.TopCentre; - r.Origin = Anchor.TopCentre; - }))); + foreach (var row in newScore.Ruleset.CreateInstance().CreateStatisticsForScore(newScore, playableBeatmap)) + { + rows.Add(new GridContainer + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Content = new[] + { + row.Columns?.Select(c => new StatisticContainer(c) + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + }).Cast().ToArray() + }, + ColumnDimensions = Enumerable.Range(0, row.Columns?.Length ?? 0) + .Select(i => row.Columns[i].Dimension ?? new Dimension()).ToArray(), + RowDimensions = new[] { new Dimension(GridSizeMode.AutoSize) } + }); + } LoadComponentAsync(rows, d => { From ce013ac9b4fe80910f187b2856985b695b93cf88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Thu, 27 Aug 2020 20:18:53 +0200 Subject: [PATCH 141/320] Make statistic header optional --- .../Ranking/Statistics/StatisticContainer.cs | 60 +++++++++++-------- .../Ranking/Statistics/StatisticItem.cs | 2 +- 2 files changed, 35 insertions(+), 27 deletions(-) diff --git a/osu.Game/Screens/Ranking/Statistics/StatisticContainer.cs b/osu.Game/Screens/Ranking/Statistics/StatisticContainer.cs index ed98698411..485d24d024 100644 --- a/osu.Game/Screens/Ranking/Statistics/StatisticContainer.cs +++ b/osu.Game/Screens/Ranking/Statistics/StatisticContainer.cs @@ -32,33 +32,9 @@ namespace osu.Game.Screens.Ranking.Statistics AutoSizeAxes = Axes.Y, Content = new[] { - new Drawable[] + new[] { - new FillFlowContainer - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Direction = FillDirection.Horizontal, - Spacing = new Vector2(5, 0), - Children = new Drawable[] - { - new Circle - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - Height = 9, - Width = 4, - Colour = Color4Extensions.FromHex("#00FFAA") - }, - new OsuSpriteText - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - Text = item.Name, - Font = OsuFont.GetFont(size: 14, weight: FontWeight.SemiBold), - } - } - } + createHeader(item) }, new Drawable[] { @@ -78,5 +54,37 @@ namespace osu.Game.Screens.Ranking.Statistics } }; } + + private static Drawable createHeader(StatisticItem item) + { + if (string.IsNullOrEmpty(item.Name)) + return Empty(); + + return new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(5, 0), + Children = new Drawable[] + { + new Circle + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Height = 9, + Width = 4, + Colour = Color4Extensions.FromHex("#00FFAA") + }, + new OsuSpriteText + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Text = item.Name, + Font = OsuFont.GetFont(size: 14, weight: FontWeight.SemiBold), + } + } + }; + } } } diff --git a/osu.Game/Screens/Ranking/Statistics/StatisticItem.cs b/osu.Game/Screens/Ranking/Statistics/StatisticItem.cs index e959ed24fc..4903983759 100644 --- a/osu.Game/Screens/Ranking/Statistics/StatisticItem.cs +++ b/osu.Game/Screens/Ranking/Statistics/StatisticItem.cs @@ -30,7 +30,7 @@ namespace osu.Game.Screens.Ranking.Statistics /// /// Creates a new , to be displayed inside a in the results screen. /// - /// The name of the item. + /// The name of the item. Can be to hide the item header. /// The content to be displayed. /// The of this item. This can be thought of as the column dimension of an encompassing . public StatisticItem([NotNull] string name, [NotNull] Drawable content, [CanBeNull] Dimension dimension = null) From ea1f07e311add124437f0346fbb85300c88ab699 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Thu, 27 Aug 2020 20:30:57 +0200 Subject: [PATCH 142/320] Simplify/rename SimpleStatisticRow mess --- ...ow.cs => TestSceneSimpleStatisticTable.cs} | 6 ++-- .../Ranking/Statistics/SimpleStatisticRow.cs | 34 ------------------- ...tatisticRow.cs => SimpleStatisticTable.cs} | 6 ++-- 3 files changed, 6 insertions(+), 40 deletions(-) rename osu.Game.Tests/Visual/Ranking/{TestSceneDrawableSimpleStatisticRow.cs => TestSceneSimpleStatisticTable.cs} (88%) delete mode 100644 osu.Game/Screens/Ranking/Statistics/SimpleStatisticRow.cs rename osu.Game/Screens/Ranking/Statistics/{DrawableSimpleStatisticRow.cs => SimpleStatisticTable.cs} (93%) diff --git a/osu.Game.Tests/Visual/Ranking/TestSceneDrawableSimpleStatisticRow.cs b/osu.Game.Tests/Visual/Ranking/TestSceneSimpleStatisticTable.cs similarity index 88% rename from osu.Game.Tests/Visual/Ranking/TestSceneDrawableSimpleStatisticRow.cs rename to osu.Game.Tests/Visual/Ranking/TestSceneSimpleStatisticTable.cs index 2b0ba30357..07a0bcc8d8 100644 --- a/osu.Game.Tests/Visual/Ranking/TestSceneDrawableSimpleStatisticRow.cs +++ b/osu.Game.Tests/Visual/Ranking/TestSceneSimpleStatisticTable.cs @@ -13,7 +13,7 @@ using osu.Game.Screens.Ranking.Statistics; namespace osu.Game.Tests.Visual.Ranking { - public class TestSceneDrawableSimpleStatisticRow : OsuTestScene + public class TestSceneSimpleStatisticTable : OsuTestScene { private Container container; @@ -45,7 +45,7 @@ namespace osu.Game.Tests.Visual.Ranking public void TestEmpty() { AddStep("create with no items", - () => container.Add(new DrawableSimpleStatisticRow(2, Enumerable.Empty()))); + () => container.Add(new SimpleStatisticTable(2, Enumerable.Empty()))); } [Test] @@ -61,7 +61,7 @@ namespace osu.Game.Tests.Visual.Ranking Value = RNG.Next(100) }); - container.Add(new DrawableSimpleStatisticRow(columnCount, items)); + container.Add(new SimpleStatisticTable(columnCount, items)); }); } } diff --git a/osu.Game/Screens/Ranking/Statistics/SimpleStatisticRow.cs b/osu.Game/Screens/Ranking/Statistics/SimpleStatisticRow.cs deleted file mode 100644 index 5c0cb5b116..0000000000 --- a/osu.Game/Screens/Ranking/Statistics/SimpleStatisticRow.cs +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using JetBrains.Annotations; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; - -namespace osu.Game.Screens.Ranking.Statistics -{ - /// - /// Contains textual statistic data to display in a . - /// - public class SimpleStatisticRow - { - /// - /// The number of columns to layout the in. - /// - public int Columns { get; set; } - - /// - /// The s that this row should contain. - /// - [ItemNotNull] - public SimpleStatisticItem[] Items { get; set; } - - public Drawable CreateDrawableStatisticRow() => new Container - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Padding = new MarginPadding(20), - Child = new DrawableSimpleStatisticRow(Columns, Items) - }; - } -} diff --git a/osu.Game/Screens/Ranking/Statistics/DrawableSimpleStatisticRow.cs b/osu.Game/Screens/Ranking/Statistics/SimpleStatisticTable.cs similarity index 93% rename from osu.Game/Screens/Ranking/Statistics/DrawableSimpleStatisticRow.cs rename to osu.Game/Screens/Ranking/Statistics/SimpleStatisticTable.cs index 7f69b323d8..8b503cc04e 100644 --- a/osu.Game/Screens/Ranking/Statistics/DrawableSimpleStatisticRow.cs +++ b/osu.Game/Screens/Ranking/Statistics/SimpleStatisticTable.cs @@ -14,10 +14,10 @@ using osu.Framework.Graphics.Shapes; namespace osu.Game.Screens.Ranking.Statistics { /// - /// Represents a statistic row with simple statistics (ones that only need textual display). + /// Represents a table with simple statistics (ones that only need textual display). /// Richer visualisations should be done with s and s. /// - public class DrawableSimpleStatisticRow : CompositeDrawable + public class SimpleStatisticTable : CompositeDrawable { private readonly SimpleStatisticItem[] items; private readonly int columnCount; @@ -29,7 +29,7 @@ namespace osu.Game.Screens.Ranking.Statistics /// /// The number of columns to layout the into. /// The s to display in this row. - public DrawableSimpleStatisticRow(int columnCount, [ItemNotNull] IEnumerable items) + public SimpleStatisticTable(int columnCount, [ItemNotNull] IEnumerable items) { if (columnCount < 1) throw new ArgumentOutOfRangeException(nameof(columnCount)); From 43d6d2b2e8845d073f78fa491d4f9946217828c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Thu, 27 Aug 2020 20:46:49 +0200 Subject: [PATCH 143/320] Add back unstable rate display --- osu.Game.Rulesets.Mania/ManiaRuleset.cs | 10 ++++++++++ osu.Game.Rulesets.Osu/OsuRuleset.cs | 10 ++++++++++ osu.Game.Rulesets.Taiko/TaikoRuleset.cs | 10 ++++++++++ 3 files changed, 30 insertions(+) diff --git a/osu.Game.Rulesets.Mania/ManiaRuleset.cs b/osu.Game.Rulesets.Mania/ManiaRuleset.cs index bbfc5739ec..f7098faa5d 100644 --- a/osu.Game.Rulesets.Mania/ManiaRuleset.cs +++ b/osu.Game.Rulesets.Mania/ManiaRuleset.cs @@ -327,6 +327,16 @@ namespace osu.Game.Rulesets.Mania }), } }, + new StatisticRow + { + Columns = new[] + { + new StatisticItem(string.Empty, new SimpleStatisticTable(3, new SimpleStatisticItem[] + { + new UnstableRate(score.HitEvents) + })) + } + } }; } diff --git a/osu.Game.Rulesets.Osu/OsuRuleset.cs b/osu.Game.Rulesets.Osu/OsuRuleset.cs index 14e7b9e9a4..f527eb2312 100644 --- a/osu.Game.Rulesets.Osu/OsuRuleset.cs +++ b/osu.Game.Rulesets.Osu/OsuRuleset.cs @@ -222,6 +222,16 @@ namespace osu.Game.Rulesets.Osu }), } }, + new StatisticRow + { + Columns = new[] + { + new StatisticItem(string.Empty, new SimpleStatisticTable(3, new SimpleStatisticItem[] + { + new UnstableRate(timedHitEvents) + })) + } + } }; } } diff --git a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs index 367d991677..dbc32f2c3e 100644 --- a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs +++ b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs @@ -178,6 +178,16 @@ namespace osu.Game.Rulesets.Taiko }), } }, + new StatisticRow + { + Columns = new[] + { + new StatisticItem(string.Empty, new SimpleStatisticTable(3, new SimpleStatisticItem[] + { + new UnstableRate(timedHitEvents) + })) + } + } }; } } From 6846a245f42e60955ea20be79c7a2b43e334cbde Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Thu, 27 Aug 2020 20:51:28 +0200 Subject: [PATCH 144/320] Reapply lost anchoring fix --- osu.Game/Screens/Ranking/Statistics/StatisticsPanel.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Ranking/Statistics/StatisticsPanel.cs b/osu.Game/Screens/Ranking/Statistics/StatisticsPanel.cs index 128c6674e8..c2ace6a04e 100644 --- a/osu.Game/Screens/Ranking/Statistics/StatisticsPanel.cs +++ b/osu.Game/Screens/Ranking/Statistics/StatisticsPanel.cs @@ -101,8 +101,8 @@ namespace osu.Game.Screens.Ranking.Statistics { rows.Add(new GridContainer { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, Content = new[] From 43c61e58308e2f411971a72da430292088d03487 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 28 Aug 2020 22:08:28 +0900 Subject: [PATCH 145/320] Re-query beatmap difficulty before computing --- osu.Game/Beatmaps/BeatmapDifficultyManager.cs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapDifficultyManager.cs b/osu.Game/Beatmaps/BeatmapDifficultyManager.cs index b80b4e45ed..490f1ba67c 100644 --- a/osu.Game/Beatmaps/BeatmapDifficultyManager.cs +++ b/osu.Game/Beatmaps/BeatmapDifficultyManager.cs @@ -89,8 +89,14 @@ namespace osu.Game.Beatmaps if (tryGetExisting(beatmapInfo, rulesetInfo, mods, out var existing, out var key)) return existing; - return await Task.Factory.StartNew(() => computeDifficulty(key, beatmapInfo, rulesetInfo), cancellationToken, - TaskCreationOptions.HideScheduler | TaskCreationOptions.RunContinuationsAsynchronously, updateScheduler); + return await Task.Factory.StartNew(() => + { + // Computation may have finished in a previous task. + if (tryGetExisting(beatmapInfo, rulesetInfo, mods, out existing, out _)) + return existing; + + return computeDifficulty(key, beatmapInfo, rulesetInfo); + }, cancellationToken, TaskCreationOptions.HideScheduler | TaskCreationOptions.RunContinuationsAsynchronously, updateScheduler); } /// From 436dbafe57614261e9380825aea13b802c9a6dbb Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 28 Aug 2020 22:12:17 +0900 Subject: [PATCH 146/320] Fix incorrect comparison for mods of different instances --- .../Beatmaps/BeatmapDifficultyManagerTest.cs | 32 +++++++++++++++++++ osu.Game/Beatmaps/BeatmapDifficultyManager.cs | 4 +-- 2 files changed, 34 insertions(+), 2 deletions(-) create mode 100644 osu.Game.Tests/Beatmaps/BeatmapDifficultyManagerTest.cs diff --git a/osu.Game.Tests/Beatmaps/BeatmapDifficultyManagerTest.cs b/osu.Game.Tests/Beatmaps/BeatmapDifficultyManagerTest.cs new file mode 100644 index 0000000000..0f6d956b3c --- /dev/null +++ b/osu.Game.Tests/Beatmaps/BeatmapDifficultyManagerTest.cs @@ -0,0 +1,32 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using NUnit.Framework; +using osu.Game.Beatmaps; +using osu.Game.Rulesets.Mods; +using osu.Game.Rulesets.Osu.Mods; + +namespace osu.Game.Tests.Beatmaps +{ + [TestFixture] + public class BeatmapDifficultyManagerTest + { + [Test] + public void TestKeyEqualsWithDifferentModInstances() + { + var key1 = new BeatmapDifficultyManager.DifficultyCacheLookup(1234, 0, new Mod[] { new OsuModHardRock(), new OsuModHidden() }); + var key2 = new BeatmapDifficultyManager.DifficultyCacheLookup(1234, 0, new Mod[] { new OsuModHardRock(), new OsuModHidden() }); + + Assert.That(key1, Is.EqualTo(key2)); + } + + [Test] + public void TestKeyEqualsWithDifferentModOrder() + { + var key1 = new BeatmapDifficultyManager.DifficultyCacheLookup(1234, 0, new Mod[] { new OsuModHardRock(), new OsuModHidden() }); + var key2 = new BeatmapDifficultyManager.DifficultyCacheLookup(1234, 0, new Mod[] { new OsuModHidden(), new OsuModHardRock() }); + + Assert.That(key1, Is.EqualTo(key2)); + } + } +} diff --git a/osu.Game/Beatmaps/BeatmapDifficultyManager.cs b/osu.Game/Beatmaps/BeatmapDifficultyManager.cs index 490f1ba67c..0100c9b210 100644 --- a/osu.Game/Beatmaps/BeatmapDifficultyManager.cs +++ b/osu.Game/Beatmaps/BeatmapDifficultyManager.cs @@ -251,7 +251,7 @@ namespace osu.Game.Beatmaps updateScheduler?.Dispose(); } - private readonly struct DifficultyCacheLookup : IEquatable + public readonly struct DifficultyCacheLookup : IEquatable { public readonly int BeatmapId; public readonly int RulesetId; @@ -267,7 +267,7 @@ namespace osu.Game.Beatmaps public bool Equals(DifficultyCacheLookup other) => BeatmapId == other.BeatmapId && RulesetId == other.RulesetId - && Mods.SequenceEqual(other.Mods); + && Mods.Select(m => m.Acronym).SequenceEqual(other.Mods.Select(m => m.Acronym)); public override int GetHashCode() { From da5853e7eb2c7dd95c8d5ca22ca4a0d4488ae731 Mon Sep 17 00:00:00 2001 From: Craftplacer Date: Sat, 29 Aug 2020 10:25:43 +0200 Subject: [PATCH 147/320] Create a new BeatmapSetInfo when setting files --- .../Beatmaps/Formats/LegacyBeatmapEncoderTest.cs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs index f093180085..dee4626cd0 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs @@ -60,12 +60,15 @@ namespace osu.Game.Tests.Beatmaps.Formats using (var reader = new LineBufferedReader(stream)) { var beatmap = new LegacyBeatmapDecoder { ApplyOffsets = false }.Decode(reader); - beatmap.BeatmapInfo.BeatmapSet.Files = new List + beatmap.BeatmapInfo.BeatmapSet = new BeatmapSetInfo { - new BeatmapSetFileInfo + Files = new List { - Filename = name, - FileInfo = new osu.Game.IO.FileInfo { Hash = name } + new BeatmapSetFileInfo + { + Filename = name, + FileInfo = new osu.Game.IO.FileInfo { Hash = name } + } } }; From 4cb9e1d4438895b7176c72464fcd6c65e738ac71 Mon Sep 17 00:00:00 2001 From: Craftplacer Date: Sat, 29 Aug 2020 10:33:43 +0200 Subject: [PATCH 148/320] Initial commit --- .../TestSceneLegacyBeatmapSkin.cs | 2 +- osu.Game.Rulesets.Osu.Tests/TestSceneSkinFallbacks.cs | 9 ++++++--- osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs | 5 +++-- osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs | 2 +- osu.Game/Beatmaps/IWorkingBeatmap.cs | 2 +- osu.Game/Beatmaps/WorkingBeatmap.cs | 8 ++++---- osu.Game/Skinning/BeatmapSkinProvidingContainer.cs | 4 ++-- osu.Game/Skinning/DefaultBeatmapSkin.cs | 9 +++++++++ osu.Game/Skinning/IBeatmapSkin.cs | 9 +++++++++ osu.Game/Skinning/LegacyBeatmapSkin.cs | 2 +- osu.Game/Tests/Beatmaps/HitObjectSampleTest.cs | 2 +- 11 files changed, 38 insertions(+), 16 deletions(-) create mode 100644 osu.Game/Skinning/DefaultBeatmapSkin.cs create mode 100644 osu.Game/Skinning/IBeatmapSkin.cs diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneLegacyBeatmapSkin.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneLegacyBeatmapSkin.cs index 3ff37c4147..03d18cefef 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneLegacyBeatmapSkin.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneLegacyBeatmapSkin.cs @@ -110,7 +110,7 @@ namespace osu.Game.Rulesets.Osu.Tests this.hasColours = hasColours; } - protected override ISkin GetSkin() => new TestBeatmapSkin(BeatmapInfo, hasColours); + protected override IBeatmapSkin GetSkin() => new TestBeatmapSkin(BeatmapInfo, hasColours); } private class TestBeatmapSkin : LegacyBeatmapSkin diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSkinFallbacks.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSkinFallbacks.cs index 075bf314bc..c3c19de17c 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSkinFallbacks.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSkinFallbacks.cs @@ -80,15 +80,18 @@ namespace osu.Game.Rulesets.Osu.Tests public class CustomSkinWorkingBeatmap : ClockBackedTestWorkingBeatmap { - private readonly ISkinSource skin; + private readonly ISkinSource skinSource; public CustomSkinWorkingBeatmap(IBeatmap beatmap, Storyboard storyboard, IFrameBasedClock frameBasedClock, AudioManager audio, ISkinSource skin) : base(beatmap, storyboard, frameBasedClock, audio) { - this.skin = skin; + if (!(skinSource is IBeatmapSkin)) + throw new ArgumentException("The provided skin source must be of type IBeatmapSkin."); + + skinSource = skin; } - protected override ISkin GetSkin() => skin; + protected override IBeatmapSkin GetSkin() => (IBeatmapSkin)skinSource; } public class SkinProvidingPlayer : TestPlayer diff --git a/osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs b/osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs index b30870d057..996d495e17 100644 --- a/osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs +++ b/osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs @@ -116,7 +116,8 @@ namespace osu.Game.Tests.Gameplay AddAssert("sample playback rate matches mod rates", () => sample.Channel.AggregateFrequency.Value == expectedRate); } - private class TestSkin : LegacySkin + // TODO: adding IBeatmapSkin changes are as minimal as possible, but this shouldn't exist or should be reworked to work with LegacyBeatmapSkin + private class TestSkin : LegacySkin, IBeatmapSkin { public TestSkin(string resourceName, AudioManager audioManager) : base(DefaultLegacySkin.Info, new TestResourceStore(resourceName), audioManager, "skin.ini") @@ -156,7 +157,7 @@ namespace osu.Game.Tests.Gameplay this.audio = audio; } - protected override ISkin GetSkin() => new TestSkin("test-sample", audio); + protected override IBeatmapSkin GetSkin() => new TestSkin("test-sample", audio); } private class TestDrawableStoryboardSample : DrawableStoryboardSample diff --git a/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs b/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs index 39c5ccab27..44728cc251 100644 --- a/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs @@ -140,7 +140,7 @@ namespace osu.Game.Beatmaps return storyboard; } - protected override ISkin GetSkin() + protected override IBeatmapSkin GetSkin() { try { diff --git a/osu.Game/Beatmaps/IWorkingBeatmap.cs b/osu.Game/Beatmaps/IWorkingBeatmap.cs index 31975157a0..dac9389822 100644 --- a/osu.Game/Beatmaps/IWorkingBeatmap.cs +++ b/osu.Game/Beatmaps/IWorkingBeatmap.cs @@ -44,7 +44,7 @@ namespace osu.Game.Beatmaps /// /// Retrieves the which this provides. /// - ISkin Skin { get; } + IBeatmapSkin Skin { get; } /// /// Constructs a playable from using the applicable converters for a specific . diff --git a/osu.Game/Beatmaps/WorkingBeatmap.cs b/osu.Game/Beatmaps/WorkingBeatmap.cs index b4bcf285b9..163b62a55c 100644 --- a/osu.Game/Beatmaps/WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/WorkingBeatmap.cs @@ -44,7 +44,7 @@ namespace osu.Game.Beatmaps background = new RecyclableLazy(GetBackground, BackgroundStillValid); waveform = new RecyclableLazy(GetWaveform); storyboard = new RecyclableLazy(GetStoryboard); - skin = new RecyclableLazy(GetSkin); + skin = new RecyclableLazy(GetSkin); total_count.Value++; } @@ -275,10 +275,10 @@ namespace osu.Game.Beatmaps private readonly RecyclableLazy storyboard; public bool SkinLoaded => skin.IsResultAvailable; - public ISkin Skin => skin.Value; + public IBeatmapSkin Skin => skin.Value; - protected virtual ISkin GetSkin() => new DefaultSkin(); - private readonly RecyclableLazy skin; + protected virtual IBeatmapSkin GetSkin() => new DefaultBeatmapSkin(); + private readonly RecyclableLazy skin; /// /// Transfer pieces of a beatmap to a new one, where possible, to save on loading. diff --git a/osu.Game/Skinning/BeatmapSkinProvidingContainer.cs b/osu.Game/Skinning/BeatmapSkinProvidingContainer.cs index 40335db697..346bfe53b8 100644 --- a/osu.Game/Skinning/BeatmapSkinProvidingContainer.cs +++ b/osu.Game/Skinning/BeatmapSkinProvidingContainer.cs @@ -11,7 +11,7 @@ namespace osu.Game.Skinning /// /// A container which overrides existing skin options with beatmap-local values. /// - public class BeatmapSkinProvidingContainer : SkinProvidingContainer + public class BeatmapSkinProvidingContainer : SkinProvidingContainer, IBeatmapSkin { private readonly Bindable beatmapSkins = new Bindable(); private readonly Bindable beatmapHitsounds = new Bindable(); @@ -21,7 +21,7 @@ namespace osu.Game.Skinning protected override bool AllowTextureLookup(string componentName) => beatmapSkins.Value; protected override bool AllowSampleLookup(ISampleInfo componentName) => beatmapHitsounds.Value; - public BeatmapSkinProvidingContainer(ISkin skin) + public BeatmapSkinProvidingContainer(IBeatmapSkin skin) : base(skin) { } diff --git a/osu.Game/Skinning/DefaultBeatmapSkin.cs b/osu.Game/Skinning/DefaultBeatmapSkin.cs new file mode 100644 index 0000000000..7b5ccd45c3 --- /dev/null +++ b/osu.Game/Skinning/DefaultBeatmapSkin.cs @@ -0,0 +1,9 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +namespace osu.Game.Skinning +{ + public class DefaultBeatmapSkin : DefaultSkin, IBeatmapSkin + { + } +} diff --git a/osu.Game/Skinning/IBeatmapSkin.cs b/osu.Game/Skinning/IBeatmapSkin.cs new file mode 100644 index 0000000000..77c34b8ad7 --- /dev/null +++ b/osu.Game/Skinning/IBeatmapSkin.cs @@ -0,0 +1,9 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +namespace osu.Game.Skinning +{ + public interface IBeatmapSkin : ISkin + { + } +} diff --git a/osu.Game/Skinning/LegacyBeatmapSkin.cs b/osu.Game/Skinning/LegacyBeatmapSkin.cs index d647bc4a2d..d53349dd11 100644 --- a/osu.Game/Skinning/LegacyBeatmapSkin.cs +++ b/osu.Game/Skinning/LegacyBeatmapSkin.cs @@ -11,7 +11,7 @@ using osu.Game.Rulesets.Objects.Legacy; namespace osu.Game.Skinning { - public class LegacyBeatmapSkin : LegacySkin + public class LegacyBeatmapSkin : LegacySkin, IBeatmapSkin { protected override bool AllowManiaSkin => false; protected override bool UseCustomSampleBanks => true; diff --git a/osu.Game/Tests/Beatmaps/HitObjectSampleTest.cs b/osu.Game/Tests/Beatmaps/HitObjectSampleTest.cs index ab4fb38657..db080d889f 100644 --- a/osu.Game/Tests/Beatmaps/HitObjectSampleTest.cs +++ b/osu.Game/Tests/Beatmaps/HitObjectSampleTest.cs @@ -188,7 +188,7 @@ namespace osu.Game.Tests.Beatmaps this.resourceStore = resourceStore; } - protected override ISkin GetSkin() => new LegacyBeatmapSkin(skinBeatmapInfo, resourceStore, AudioManager); + protected override IBeatmapSkin GetSkin() => new LegacyBeatmapSkin(skinBeatmapInfo, resourceStore, AudioManager); } } } From 1b81415a16e82131bb170f5473202112a82182ab Mon Sep 17 00:00:00 2001 From: Craftplacer Date: Sat, 29 Aug 2020 10:50:25 +0200 Subject: [PATCH 149/320] Correct comment --- osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs b/osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs index 996d495e17..1e3755c186 100644 --- a/osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs +++ b/osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs @@ -116,7 +116,7 @@ namespace osu.Game.Tests.Gameplay AddAssert("sample playback rate matches mod rates", () => sample.Channel.AggregateFrequency.Value == expectedRate); } - // TODO: adding IBeatmapSkin changes are as minimal as possible, but this shouldn't exist or should be reworked to work with LegacyBeatmapSkin + // TODO: adding IBeatmapSkin to keep changes as minimal as possible, but this shouldn't exist or should be reworked to inherit LegacyBeatmapSkin private class TestSkin : LegacySkin, IBeatmapSkin { public TestSkin(string resourceName, AudioManager audioManager) From 08329aa382d7afd64e9ce5afe30a94d55d0557ec Mon Sep 17 00:00:00 2001 From: Craftplacer Date: Sat, 29 Aug 2020 11:05:10 +0200 Subject: [PATCH 150/320] Remove comment again --- osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs b/osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs index 1e3755c186..bc9528beb6 100644 --- a/osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs +++ b/osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs @@ -116,7 +116,6 @@ namespace osu.Game.Tests.Gameplay AddAssert("sample playback rate matches mod rates", () => sample.Channel.AggregateFrequency.Value == expectedRate); } - // TODO: adding IBeatmapSkin to keep changes as minimal as possible, but this shouldn't exist or should be reworked to inherit LegacyBeatmapSkin private class TestSkin : LegacySkin, IBeatmapSkin { public TestSkin(string resourceName, AudioManager audioManager) From 82acb3506cbc36a0546ff77fc76c20d8854bb2ed Mon Sep 17 00:00:00 2001 From: Craftplacer Date: Sat, 29 Aug 2020 11:07:28 +0200 Subject: [PATCH 151/320] Add and change xmldocs --- osu.Game/Beatmaps/IWorkingBeatmap.cs | 2 +- osu.Game/Skinning/IBeatmapSkin.cs | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/IWorkingBeatmap.cs b/osu.Game/Beatmaps/IWorkingBeatmap.cs index dac9389822..aac41725a9 100644 --- a/osu.Game/Beatmaps/IWorkingBeatmap.cs +++ b/osu.Game/Beatmaps/IWorkingBeatmap.cs @@ -42,7 +42,7 @@ namespace osu.Game.Beatmaps Storyboard Storyboard { get; } /// - /// Retrieves the which this provides. + /// Retrieves the which this provides. /// IBeatmapSkin Skin { get; } diff --git a/osu.Game/Skinning/IBeatmapSkin.cs b/osu.Game/Skinning/IBeatmapSkin.cs index 77c34b8ad7..91caaed557 100644 --- a/osu.Game/Skinning/IBeatmapSkin.cs +++ b/osu.Game/Skinning/IBeatmapSkin.cs @@ -3,6 +3,9 @@ namespace osu.Game.Skinning { + /// + /// Marker interface for skins that originate from beatmaps. + /// public interface IBeatmapSkin : ISkin { } From 658a1d159f03df2a55339c5eab7e11085c75ac43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 29 Aug 2020 11:45:59 +0200 Subject: [PATCH 152/320] Add legacy flag value for mirror mod --- osu.Game/Beatmaps/Legacy/LegacyMods.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Beatmaps/Legacy/LegacyMods.cs b/osu.Game/Beatmaps/Legacy/LegacyMods.cs index 583e950e49..0e517ea3df 100644 --- a/osu.Game/Beatmaps/Legacy/LegacyMods.cs +++ b/osu.Game/Beatmaps/Legacy/LegacyMods.cs @@ -38,5 +38,6 @@ namespace osu.Game.Beatmaps.Legacy Key1 = 1 << 26, Key3 = 1 << 27, Key2 = 1 << 28, + Mirror = 1 << 30, } } From 58742afd99f131baeb23f0bc85b8161da1559847 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 29 Aug 2020 11:47:31 +0200 Subject: [PATCH 153/320] Add failing test case --- osu.Game.Rulesets.Mania.Tests/ManiaLegacyModConversionTest.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game.Rulesets.Mania.Tests/ManiaLegacyModConversionTest.cs b/osu.Game.Rulesets.Mania.Tests/ManiaLegacyModConversionTest.cs index 957743c5f1..b22687a0a7 100644 --- a/osu.Game.Rulesets.Mania.Tests/ManiaLegacyModConversionTest.cs +++ b/osu.Game.Rulesets.Mania.Tests/ManiaLegacyModConversionTest.cs @@ -23,6 +23,7 @@ namespace osu.Game.Rulesets.Mania.Tests [TestCase(LegacyMods.Perfect | LegacyMods.SuddenDeath, new[] { typeof(ManiaModPerfect) })] [TestCase(LegacyMods.Perfect | LegacyMods.SuddenDeath | LegacyMods.DoubleTime, new[] { typeof(ManiaModDoubleTime), typeof(ManiaModPerfect) })] [TestCase(LegacyMods.Random | LegacyMods.SuddenDeath, new[] { typeof(ManiaModRandom), typeof(ManiaModSuddenDeath) })] + [TestCase(LegacyMods.Flashlight | LegacyMods.Mirror, new[] { typeof(ManiaModFlashlight), typeof(ManiaModMirror) })] public new void Test(LegacyMods legacyMods, Type[] expectedMods) => base.Test(legacyMods, expectedMods); protected override Ruleset CreateRuleset() => new ManiaRuleset(); From da82556f6b647dff1d17b384c4061d80665b0393 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 29 Aug 2020 11:49:17 +0200 Subject: [PATCH 154/320] Add two-way legacy conversions for mirror mod --- osu.Game.Rulesets.Mania/ManiaRuleset.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/osu.Game.Rulesets.Mania/ManiaRuleset.cs b/osu.Game.Rulesets.Mania/ManiaRuleset.cs index f7098faa5d..37b34d1721 100644 --- a/osu.Game.Rulesets.Mania/ManiaRuleset.cs +++ b/osu.Game.Rulesets.Mania/ManiaRuleset.cs @@ -126,6 +126,9 @@ namespace osu.Game.Rulesets.Mania if (mods.HasFlag(LegacyMods.Random)) yield return new ManiaModRandom(); + + if (mods.HasFlag(LegacyMods.Mirror)) + yield return new ManiaModMirror(); } public override LegacyMods ConvertToLegacyMods(Mod[] mods) @@ -175,6 +178,10 @@ namespace osu.Game.Rulesets.Mania case ManiaModFadeIn _: value |= LegacyMods.FadeIn; break; + + case ManiaModMirror _: + value |= LegacyMods.Mirror; + break; } } From 9ce9ba3a0d1906448611749a0dc391dcf3944e3d Mon Sep 17 00:00:00 2001 From: Craftplacer Date: Sat, 29 Aug 2020 13:50:29 +0200 Subject: [PATCH 155/320] Update TestSceneSkinFallbacks.cs --- .../TestSceneSkinFallbacks.cs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSkinFallbacks.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSkinFallbacks.cs index c3c19de17c..0fe8949360 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSkinFallbacks.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSkinFallbacks.cs @@ -34,7 +34,7 @@ namespace osu.Game.Rulesets.Osu.Tests public TestSceneSkinFallbacks() { testUserSkin = new TestSource("user"); - testBeatmapSkin = new TestSource("beatmap"); + testBeatmapSkin = new BeatmapTestSource(); } [Test] @@ -85,7 +85,7 @@ namespace osu.Game.Rulesets.Osu.Tests public CustomSkinWorkingBeatmap(IBeatmap beatmap, Storyboard storyboard, IFrameBasedClock frameBasedClock, AudioManager audio, ISkinSource skin) : base(beatmap, storyboard, frameBasedClock, audio) { - if (!(skinSource is IBeatmapSkin)) + if (!(skin is IBeatmapSkin)) throw new ArgumentException("The provided skin source must be of type IBeatmapSkin."); skinSource = skin; @@ -115,6 +115,14 @@ namespace osu.Game.Rulesets.Osu.Tests } } + public class BeatmapTestSource : TestSource, IBeatmapSkin + { + public BeatmapTestSource() + : base("beatmap") + { + } + } + public class TestSource : ISkinSource { private readonly string identifier; From 43e91877a71c3451f4b9617212dbd0c38f7bdb2f Mon Sep 17 00:00:00 2001 From: Craftplacer Date: Sat, 29 Aug 2020 14:47:26 +0200 Subject: [PATCH 156/320] Scope and limit parameter to IBeatmapSkin --- .../TestSceneSkinFallbacks.cs | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSkinFallbacks.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSkinFallbacks.cs index 0fe8949360..64da80a88e 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSkinFallbacks.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSkinFallbacks.cs @@ -29,7 +29,7 @@ namespace osu.Game.Rulesets.Osu.Tests public class TestSceneSkinFallbacks : TestSceneOsuPlayer { private readonly TestSource testUserSkin; - private readonly TestSource testBeatmapSkin; + private readonly BeatmapTestSource testBeatmapSkin; public TestSceneSkinFallbacks() { @@ -80,18 +80,15 @@ namespace osu.Game.Rulesets.Osu.Tests public class CustomSkinWorkingBeatmap : ClockBackedTestWorkingBeatmap { - private readonly ISkinSource skinSource; + private readonly IBeatmapSkin skin; - public CustomSkinWorkingBeatmap(IBeatmap beatmap, Storyboard storyboard, IFrameBasedClock frameBasedClock, AudioManager audio, ISkinSource skin) + public CustomSkinWorkingBeatmap(IBeatmap beatmap, Storyboard storyboard, IFrameBasedClock frameBasedClock, AudioManager audio, IBeatmapSkin skin) : base(beatmap, storyboard, frameBasedClock, audio) { - if (!(skin is IBeatmapSkin)) - throw new ArgumentException("The provided skin source must be of type IBeatmapSkin."); - - skinSource = skin; + this.skin = skin; } - protected override IBeatmapSkin GetSkin() => (IBeatmapSkin)skinSource; + protected override IBeatmapSkin GetSkin() => skin; } public class SkinProvidingPlayer : TestPlayer @@ -115,7 +112,7 @@ namespace osu.Game.Rulesets.Osu.Tests } } - public class BeatmapTestSource : TestSource, IBeatmapSkin + private class BeatmapTestSource : TestSource, IBeatmapSkin { public BeatmapTestSource() : base("beatmap") From 69fae0f4122ad64b9c25bdc83ccd4e9cb00c34ba Mon Sep 17 00:00:00 2001 From: Joehu Date: Sat, 29 Aug 2020 09:30:56 -0700 Subject: [PATCH 157/320] Add failing replay download button test --- .../Visual/Ranking/TestSceneResultsScreen.cs | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/osu.Game.Tests/Visual/Ranking/TestSceneResultsScreen.cs b/osu.Game.Tests/Visual/Ranking/TestSceneResultsScreen.cs index 74808bc2f5..a86fa05129 100644 --- a/osu.Game.Tests/Visual/Ranking/TestSceneResultsScreen.cs +++ b/osu.Game.Tests/Visual/Ranking/TestSceneResultsScreen.cs @@ -13,6 +13,7 @@ using osu.Framework.Screens; using osu.Framework.Testing; using osu.Framework.Utils; using osu.Game.Beatmaps; +using osu.Game.Graphics.UserInterface; using osu.Game.Online.API; using osu.Game.Rulesets.Osu; using osu.Game.Scoring; @@ -212,6 +213,25 @@ namespace osu.Game.Tests.Visual.Ranking AddAssert("expanded panel still on screen", () => this.ChildrenOfType().Single(p => p.State == PanelState.Expanded).ScreenSpaceDrawQuad.TopLeft.X > 0); } + [Test] + public void TestDownloadButtonInitallyDisabled() + { + TestResultsScreen screen = null; + + AddStep("load results", () => Child = new TestResultsContainer(screen = createResultsScreen())); + + AddAssert("download button is disabled", () => !screen.ChildrenOfType().First().Enabled.Value); + + AddStep("click contracted panel", () => + { + var contractedPanel = this.ChildrenOfType().First(p => p.State == PanelState.Contracted && p.ScreenSpaceDrawQuad.TopLeft.X > screen.ScreenSpaceDrawQuad.TopLeft.X); + InputManager.MoveMouseTo(contractedPanel); + InputManager.Click(MouseButton.Left); + }); + + AddAssert("download button is enabled", () => screen.ChildrenOfType().First().Enabled.Value); + } + private class TestResultsContainer : Container { [Cached(typeof(Player))] @@ -255,6 +275,7 @@ namespace osu.Game.Tests.Visual.Ranking { var score = new TestScoreInfo(new OsuRuleset().RulesetInfo); score.TotalScore += 10 - i; + score.Hash = $"test{i}"; scores.Add(score); } From 0a643fd5e5a4f8b6e5b92f0a27ffe6995fc26b2c Mon Sep 17 00:00:00 2001 From: Joehu Date: Sat, 29 Aug 2020 09:33:01 -0700 Subject: [PATCH 158/320] Fix replay download button always being disabled when initial score's replay is unavailable --- .../Screens/Ranking/ReplayDownloadButton.cs | 40 ++++++++++++------- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/osu.Game/Screens/Ranking/ReplayDownloadButton.cs b/osu.Game/Screens/Ranking/ReplayDownloadButton.cs index d0142e57fe..b76842f405 100644 --- a/osu.Game/Screens/Ranking/ReplayDownloadButton.cs +++ b/osu.Game/Screens/Ranking/ReplayDownloadButton.cs @@ -74,23 +74,33 @@ namespace osu.Game.Screens.Ranking { button.State.Value = state.NewValue; - switch (replayAvailability) - { - case ReplayAvailability.Local: - button.TooltipText = @"watch replay"; - break; - - case ReplayAvailability.Online: - button.TooltipText = @"download replay"; - break; - - default: - button.TooltipText = @"replay unavailable"; - break; - } + updateTooltip(); }, true); - button.Enabled.Value = replayAvailability != ReplayAvailability.NotAvailable; + Model.BindValueChanged(_ => + { + button.Enabled.Value = replayAvailability != ReplayAvailability.NotAvailable; + + updateTooltip(); + }, true); + } + + private void updateTooltip() + { + switch (replayAvailability) + { + case ReplayAvailability.Local: + button.TooltipText = @"watch replay"; + break; + + case ReplayAvailability.Online: + button.TooltipText = @"download replay"; + break; + + default: + button.TooltipText = @"replay unavailable"; + break; + } } private enum ReplayAvailability From 5949a281fc54e94b34843ec5d91d8b819b1851b4 Mon Sep 17 00:00:00 2001 From: Lucas A Date: Thu, 27 Aug 2020 19:29:18 +0200 Subject: [PATCH 159/320] Make Introduce bindable property OverlayActivationMode in OsuScreen --- osu.Game/OsuGame.cs | 5 ++++- osu.Game/Screens/IOsuScreen.cs | 4 ++-- osu.Game/Screens/OsuScreen.cs | 6 +++++- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 053eb01dcd..6a390942b7 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -972,9 +972,12 @@ namespace osu.Game break; } + if (current is IOsuScreen currentOsuScreen) + OverlayActivationMode.UnbindFrom(currentOsuScreen.OverlayActivationMode); + if (newScreen is IOsuScreen newOsuScreen) { - OverlayActivationMode.Value = newOsuScreen.InitialOverlayActivationMode; + OverlayActivationMode.BindTo(newOsuScreen.OverlayActivationMode); MusicController.AllowRateAdjustments = newOsuScreen.AllowRateAdjustments; diff --git a/osu.Game/Screens/IOsuScreen.cs b/osu.Game/Screens/IOsuScreen.cs index 761f842c22..c9dce310af 100644 --- a/osu.Game/Screens/IOsuScreen.cs +++ b/osu.Game/Screens/IOsuScreen.cs @@ -39,9 +39,9 @@ namespace osu.Game.Screens bool HideOverlaysOnEnter { get; } /// - /// Whether overlays should be able to be opened once this screen is entered or resumed. + /// Whether overlays should be able to be opened when this screen is current. /// - OverlayActivation InitialOverlayActivationMode { get; } + public Bindable OverlayActivationMode { get; } /// /// The amount of parallax to be applied while this screen is displayed. diff --git a/osu.Game/Screens/OsuScreen.cs b/osu.Game/Screens/OsuScreen.cs index 872a1cd39a..c687c34ce9 100644 --- a/osu.Game/Screens/OsuScreen.cs +++ b/osu.Game/Screens/OsuScreen.cs @@ -44,10 +44,12 @@ namespace osu.Game.Screens public virtual bool HideOverlaysOnEnter => false; /// - /// Whether overlays should be able to be opened once this screen is entered or resumed. + /// The initial initial overlay activation mode to use when this screen is entered for the first time. /// public virtual OverlayActivation InitialOverlayActivationMode => OverlayActivation.All; + public Bindable OverlayActivationMode { get; } + public virtual bool CursorVisible => true; protected new OsuGameBase Game => base.Game as OsuGameBase; @@ -138,6 +140,8 @@ namespace osu.Game.Screens { Anchor = Anchor.Centre; Origin = Anchor.Centre; + + OverlayActivationMode = new Bindable(InitialOverlayActivationMode); } [BackgroundDependencyLoader(true)] From ad223bc460ea0d1a6a4d07a86d17cfa3ad0b5b38 Mon Sep 17 00:00:00 2001 From: Lucas A Date: Thu, 27 Aug 2020 20:07:24 +0200 Subject: [PATCH 160/320] Make game bindable immutable. --- osu.Game.Tests/Visual/Menus/TestSceneToolbar.cs | 7 ++++++- osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs | 2 +- osu.Game/OsuGame.cs | 2 +- osu.Game/Overlays/Toolbar/Toolbar.cs | 2 +- osu.Game/Screens/Menu/ButtonSystem.cs | 3 --- 5 files changed, 9 insertions(+), 7 deletions(-) diff --git a/osu.Game.Tests/Visual/Menus/TestSceneToolbar.cs b/osu.Game.Tests/Visual/Menus/TestSceneToolbar.cs index f819ae4682..841860accb 100644 --- a/osu.Game.Tests/Visual/Menus/TestSceneToolbar.cs +++ b/osu.Game.Tests/Visual/Menus/TestSceneToolbar.cs @@ -91,7 +91,12 @@ namespace osu.Game.Tests.Visual.Menus public class TestToolbar : Toolbar { - public new Bindable OverlayActivationMode => base.OverlayActivationMode; + public TestToolbar() + { + base.OverlayActivationMode.BindTo(OverlayActivationMode); + } + + public new Bindable OverlayActivationMode { get; } = new Bindable(OverlayActivation.All); } } } diff --git a/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs b/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs index 93ac69bdbf..751ccc8f15 100644 --- a/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs +++ b/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs @@ -35,7 +35,7 @@ namespace osu.Game.Graphics.Containers [Resolved] private PreviewTrackManager previewTrackManager { get; set; } - protected readonly Bindable OverlayActivationMode = new Bindable(OverlayActivation.All); + protected readonly IBindable OverlayActivationMode = new Bindable(OverlayActivation.All); [BackgroundDependencyLoader(true)] private void load(AudioManager audio) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 6a390942b7..e6d96df927 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -88,7 +88,7 @@ namespace osu.Game private IdleTracker idleTracker; - public readonly Bindable OverlayActivationMode = new Bindable(); + public readonly IBindable OverlayActivationMode = new Bindable(); protected OsuScreenStack ScreenStack; diff --git a/osu.Game/Overlays/Toolbar/Toolbar.cs b/osu.Game/Overlays/Toolbar/Toolbar.cs index 3bf9e85428..393e349bd0 100644 --- a/osu.Game/Overlays/Toolbar/Toolbar.cs +++ b/osu.Game/Overlays/Toolbar/Toolbar.cs @@ -28,7 +28,7 @@ namespace osu.Game.Overlays.Toolbar private const double transition_time = 500; - protected readonly Bindable OverlayActivationMode = new Bindable(OverlayActivation.All); + protected readonly IBindable OverlayActivationMode = new Bindable(OverlayActivation.All); // Toolbar components like RulesetSelector should receive keyboard input events even when the toolbar is hidden. public override bool PropagateNonPositionalInputSubTree => true; diff --git a/osu.Game/Screens/Menu/ButtonSystem.cs b/osu.Game/Screens/Menu/ButtonSystem.cs index 5ba7a8ddc3..4becdd58cd 100644 --- a/osu.Game/Screens/Menu/ButtonSystem.cs +++ b/osu.Game/Screens/Menu/ButtonSystem.cs @@ -270,9 +270,6 @@ namespace osu.Game.Screens.Menu ButtonSystemState lastState = state; state = value; - if (game != null) - game.OverlayActivationMode.Value = state == ButtonSystemState.Exit ? OverlayActivation.Disabled : OverlayActivation.All; - updateLogoState(lastState); Logger.Log($"{nameof(ButtonSystem)}'s state changed from {lastState} to {state}"); From 8de7744b52e98d0e42a9b88ec08b10ac1a5c2f6f Mon Sep 17 00:00:00 2001 From: Lucas A Date: Fri, 28 Aug 2020 09:55:14 +0200 Subject: [PATCH 161/320] Add back disabling of overlays on exiting game. --- osu.Game/Screens/Menu/MainMenu.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Screens/Menu/MainMenu.cs b/osu.Game/Screens/Menu/MainMenu.cs index 57252d557e..859184834b 100644 --- a/osu.Game/Screens/Menu/MainMenu.cs +++ b/osu.Game/Screens/Menu/MainMenu.cs @@ -280,6 +280,7 @@ namespace osu.Game.Screens.Menu } buttons.State = ButtonSystemState.Exit; + OverlayActivationMode.Value = OverlayActivation.Disabled; songTicker.Hide(); From 03b7c8b88969ae337ac52bcddd56c0c5d034f111 Mon Sep 17 00:00:00 2001 From: Lucas A Date: Sat, 29 Aug 2020 19:39:50 +0200 Subject: [PATCH 162/320] Remove unneeded access modifier. --- osu.Game/Screens/IOsuScreen.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/IOsuScreen.cs b/osu.Game/Screens/IOsuScreen.cs index c9dce310af..ead8e4bc22 100644 --- a/osu.Game/Screens/IOsuScreen.cs +++ b/osu.Game/Screens/IOsuScreen.cs @@ -41,7 +41,7 @@ namespace osu.Game.Screens /// /// Whether overlays should be able to be opened when this screen is current. /// - public Bindable OverlayActivationMode { get; } + Bindable OverlayActivationMode { get; } /// /// The amount of parallax to be applied while this screen is displayed. From e0eece11b1cde8e12856b33c5050335605b8c3cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 29 Aug 2020 20:13:03 +0200 Subject: [PATCH 163/320] Fix typo in test name --- osu.Game.Tests/Visual/Ranking/TestSceneResultsScreen.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Ranking/TestSceneResultsScreen.cs b/osu.Game.Tests/Visual/Ranking/TestSceneResultsScreen.cs index a86fa05129..49fa581108 100644 --- a/osu.Game.Tests/Visual/Ranking/TestSceneResultsScreen.cs +++ b/osu.Game.Tests/Visual/Ranking/TestSceneResultsScreen.cs @@ -214,7 +214,7 @@ namespace osu.Game.Tests.Visual.Ranking } [Test] - public void TestDownloadButtonInitallyDisabled() + public void TestDownloadButtonInitiallyDisabled() { TestResultsScreen screen = null; From 13df0783fe091b3171cf37972df3aa5a62c0d267 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 29 Aug 2020 20:23:22 +0200 Subject: [PATCH 164/320] Use Single() instead of First() where applicable --- osu.Game.Tests/Visual/Ranking/TestSceneResultsScreen.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/Ranking/TestSceneResultsScreen.cs b/osu.Game.Tests/Visual/Ranking/TestSceneResultsScreen.cs index 49fa581108..03cb5fa3db 100644 --- a/osu.Game.Tests/Visual/Ranking/TestSceneResultsScreen.cs +++ b/osu.Game.Tests/Visual/Ranking/TestSceneResultsScreen.cs @@ -220,7 +220,7 @@ namespace osu.Game.Tests.Visual.Ranking AddStep("load results", () => Child = new TestResultsContainer(screen = createResultsScreen())); - AddAssert("download button is disabled", () => !screen.ChildrenOfType().First().Enabled.Value); + AddAssert("download button is disabled", () => !screen.ChildrenOfType().Single().Enabled.Value); AddStep("click contracted panel", () => { @@ -229,7 +229,7 @@ namespace osu.Game.Tests.Visual.Ranking InputManager.Click(MouseButton.Left); }); - AddAssert("download button is enabled", () => screen.ChildrenOfType().First().Enabled.Value); + AddAssert("download button is enabled", () => screen.ChildrenOfType().Single().Enabled.Value); } private class TestResultsContainer : Container From d22768a98cba3c9d312ba2408536905371840668 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 29 Aug 2020 23:20:59 +0200 Subject: [PATCH 165/320] Add scale specification to spinner scene for visibility --- osu.Game.Rulesets.Osu.Tests/TestSceneSpinner.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSpinner.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSpinner.cs index 47b3926ceb..94d1cb8864 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSpinner.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSpinner.cs @@ -9,6 +9,7 @@ using osu.Game.Beatmaps.ControlPoints; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Osu.Objects.Drawables; +using osuTK; namespace osu.Game.Rulesets.Osu.Tests { @@ -62,7 +63,8 @@ namespace osu.Game.Rulesets.Osu.Tests drawableSpinner = new TestDrawableSpinner(spinner, auto) { Anchor = Anchor.Centre, - Depth = depthIndex++ + Depth = depthIndex++, + Scale = new Vector2(0.75f) }; foreach (var mod in SelectedMods.Value.OfType()) From c9723e541a464c84b8e3e5c27e94af4f0c3fd32d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 29 Aug 2020 23:21:19 +0200 Subject: [PATCH 166/320] Add metrics skin resources for old style spinner --- .../metrics-skin/spinner-background@2x.png | Bin 0 -> 14515 bytes .../metrics-skin/spinner-circle@2x.png | Bin 0 -> 6561 bytes .../Resources/metrics-skin/spinner-metre@2x.png | Bin 0 -> 14516 bytes 3 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 osu.Game.Rulesets.Osu.Tests/Resources/metrics-skin/spinner-background@2x.png create mode 100644 osu.Game.Rulesets.Osu.Tests/Resources/metrics-skin/spinner-circle@2x.png create mode 100644 osu.Game.Rulesets.Osu.Tests/Resources/metrics-skin/spinner-metre@2x.png diff --git a/osu.Game.Rulesets.Osu.Tests/Resources/metrics-skin/spinner-background@2x.png b/osu.Game.Rulesets.Osu.Tests/Resources/metrics-skin/spinner-background@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..4f50f638c5de06d711fc7d09a3a4ee13618cd59e GIT binary patch literal 14515 zcmeHNO)G>^6n=(b#_-liY7o6PHa3!?BrnZ0Grp3Pln{j-@{v*u+4u)Seu8Xl*pOm; z6rvQ$EbPd_Mxi)&ym$V7L$?+uU=Wd(Lz2dzRbVf`+Hi1HcG}{2hQ>)Qk~# zrVQ0L^+z&f4m1b-G6G-M4V|wtW{riqCxGlc^>bi#-6t1ali}8Y>(O1DpIcjAr!JWY z`x`oEZlCY>4U~EhteVUD)7h#1p{D5F$;S4OL(M7D_0jU90B@C|nG~>iHlwyCK|~OdfT^9pPhdQo`P&4{QZSASqk2k3_0NLiL%>(1 zdI7}$^nOZtpB`5+FPR$i_ml!#WwMmsqIiqWMJ&;OLvBKDLT;kAIlmi$EhYbp;`HoJ zo9P1Wis-|8N#D2}cJ4(K)Z>z#XtK;n^k7z)_Dw!W^Jpj#6xtFXD6}aE3T+93g6YG? s0<$YQg$)J9N5)6n0;Ja(3XG2_6dx^P)VSK|ID1mw4+q-(n~nX8-{y?j8UO$Q literal 0 HcmV?d00001 diff --git a/osu.Game.Rulesets.Osu.Tests/Resources/metrics-skin/spinner-circle@2x.png b/osu.Game.Rulesets.Osu.Tests/Resources/metrics-skin/spinner-circle@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..daf28e09cbe6bbb7fc531b4773e4d381054e65cf GIT binary patch literal 6561 zcmai32UHVT+fF7SA(Vt}D24z5L;(S5(u{(VP&J|=H6lf-EK(xPWJO>BAp{XriekhK zA|N(Ez*$+Ast8g90fUW>QKT#g{NuN-{@*$OIsZ8`XYPIPo#!p{&O7%$^V@zWTX7Ku z5f}_6PNmq;U@$oQ+bN8KB+SRgozMm4V{dB%U16||-rX*rp(`ewa`Y4oCMx~ygu^Zu z;2|M8lIpk@{Z4qZEJieI!*CV`lh>u%>~>)c&5k5w5d3OeK7I6TE_G{<4&@Hf(gF{8 z+1*iCl``y;lEI$PA>6YCiSSs}-9Sp(fjuHc0#zgO5JiP9(j2=#j?bJ>kuwR}Vl+f+ zPp`AF3%s8n^@tpGu)A=+B?B$tHdJ^i;6u^hiJY}ZU8hEtydHb)FkfPlsGR@jm^4D# zU;T?Zff~hTphr;|9f@@;T|SX67ETn%(OnkjOJ~NrQ!E@@xwBME_9Q~EgMX8pWiso>+|vI%AKi(t;yB7r)h~bu&@)%POqUi#Dj#GO_c4U>isULqw%=qre8x5^3y?l_yTw zoNz$P!RA@lbtq~Uz_3ucN>y7#E9^k_HGLsd*<~4lmuSxkMb<}nj1;2>8t4w+bKI~> zVp(kReE9t?1Q^5YLq;EkkYXG7`RD>vyqqcct1v^d2I2bN`&1jOdsoUnlW+~ePWok` zZm$s3Vc_-Wozn8eS#0JYcoZBT5gqzCf_Ml#lyD8$DJF4${Ky%VaO~uZF`Abp=!iV* zE`qRmDt0~_+{D}qx`>uYeF02>4$RC0B~_Zu$Yp8$&RIN(pofi(r3@`FjmNAEvEh8Eq3(=g#b??+#;bIm7Tk zdcZTP@j=@=N!Cb4VQTuJOk{|Np=gd6v$>}n~?9F{6k-%Chg1cRx0m3sNVRp z9oAjcbX+A|T(8@QQduqTI>UR6O7)UgLL&w^jhOvCqql+ern3s-66yumcmzH`pPSH+ z_Mq^iAw%xzo7OR>Dc)+^0vU&aO%nJj85G6+$y;e|i-&VHo)+fLn#T->YMFI3Etx43 z27nlO0_~UvJjU;_djt^Z8}5K^#B@Hu(*pb98&33`8+zo+QiOn<#%)8tId6R}QI!fl zz4!$7o25k<^4Wa}TFY%>RjUD>sE=wfxziFjWuGaC#Ad2-fex6N5Qgl8T=CVM`4E6k6k zCpWW$P9nn1SS=7BEs9Y?Qsh{ffS3Udn7?@zj*jN*bc6a&tH8?FcJOkD!s$GSry)B2Y=Ynj=$uw+M z7=IP?NLMjBj0+cGB|@>3ktO8Z-6*Ud@S&W4DCtV3r$ZAzC%0sSXAlQb-9GhY#iU-Oc&V{5&W|gRceo;$Lxk&mdtRI=%ojgD_`;8A_tVh{&U2 zyag092lI6pN~l#S!V-W!Dn`9D&dd>$MEIT@(^stNYP0SkXk<$_6!RhOmsLjR z+4lkxK+LGC3E7K4umv{K&xEQ^E`*}3rizyph#L%wATj=#bx-58Q0B?irsP>H`wN4k z{8st{XYutuevPqmT+b+sireRr9^g(@Xe7|R+;Q}f`BidbFoV(_7}js^#w&z#8oQd* z2GwPc?e0G)#+FNJk&2hU!1XD7^_Pj_gJ}X~W&OCf^){Y%x^Ov^ADal8z^?E!_FD%Z zOVo710-YF2@UKev>CuZW)rH_4B*BFI2A7o$o(090?sKt&uuhe#M{VBK;wIfEcUX|3 zUS^ap8M@s?kj5hTE=$#1k%G$$SN{r{Q!h_C2RSd;lY7*J{ObbL`&v6S2r)h7_O6%!gh}lY^}gPn zNgo{4o?_TZliV|LmQO6V@=BAL@csHyZuC`!&8M>!7C_#7JmcSJh<%vA# zv6RJ?yK-gWiCfu62>3N{aAX(9ts)P6R6t&|w2)IIaFAecxuzLw#+s1zz;b#2@9c_(7rB`Xbfqb4J1buY*3m~g(!%@on;{@=G7TaW^?)>eEp z*#kvZ8VKiFTT);pR;{WT^Db96!ka>~Xs9MgQ=VMgpJkKF6?V`N+>@qE0ZV5|&3!v= z6_cf~sKhLjF7-ffarj4~Amo)Mdmi$C=;LUD*CS1KQZ|T<58uyO9DwN+fpZU>h~9dT zM%TJ(!q5=rPw5!-z~!x$yoYrd(y?n}D%4tsr?G(@0P@){v+7!-UT#kzw+F$q6^}@= zK3G;%=q2*Ahz517xuT)JF{EpX6W51_y4|{>ACdAiS!DQuR73kq;Yi<=A~veeOs<@+l(-(Z(Mn%U7>a!2Dj8j^DL#2J4^ zUEta&Inqy+OSiUF6q62>_7XgznFa4ws5C#j*+1TULTJJkZ=voDtV)&61I#<*fFoz? z5x4ESJIGca>Zr8$cGJy%UQc4-_}L+7R20j_I%nc3PfcoB;gh&i^6<|p15{4XO~I(g zK4$#$C=Pc>tKMW&9FBBN^yQ=(m8NrEU2p#Y#y4|Xje7ski7Z_+vVW}=$Ho2J;zS9; zxAb4}3Zd2MYKIY|LxHIGAQ4I=Nhr8|Zb$lW1gpI|9he2uG5Z!nrRq zCBQq%fHkM&0HsTJD;XPO`9o}3kwV&gon7SF>3!^U(r=_@E?dpBs~PiASCx!CwV9-4RvQ;12{#ywVsj_n&5i6uwvq;R zb4qd^#cYx!rqp0LGKIqp<{PJom^1KwwQ?Mp+}*&*iZFmW0liyVcGs&3UI&=qD^CP9 z?QjL5$b|ft`sM zHaYr_+At=C1E*1$_1!D>w0r--{fzp7K&e{i$lUg@j89s~Asvz={-%E6yT*4P`@K0O zxwlfr#o3R)V?o}m2mQC*1}FZz|2g0XcB|-5gz?)y4DI>}hWcs#+RwRG-x2=xWS85I z07kq1Xs*-$QOsD6xvcqB2>;%ULUTc3>TBCENcxp&BDK41>$X^|WDz zME!Wa)y+Sj@4=rLkT?#Zd`}GO_s5>H$7`SV8b8(Em)}5EDvbF zBe0>S)818@72shGO;bTWXf|STl^KP>n$+B*M-DSCC=z*bp1Y`J4m``68CY%0LJqh6 z!qC|caW?4BmmJv7F`LUSN86f1;P1cJR&z;Wu!k*ms-`FIZu}uB8{d{&ahKHm+Wl5OxsKInw;oCjDn;ULuRb1>rmP5^jA~Hl z={<}#vna!`dvz)vlA1>j-omg!v#TvedEDXH>Y^bIj5_kJ4k`u>_l6V)F^`2x>()7j z+6~CjLw&ofO5SWga~*n9ep!58rpboByH`6Bh}2a-7~Yv4W3I{mlD_?vGNmWc{jeXy zWfzNku=Nk{BX2$8GO5`|n1N;m-1;ifXEJ*aW>TX}3M?MkAI0cB4p48htywyA80wH_ z4#vWBA?5cLzw7rTMn$u^0}sowV+V>cq{2Pl77ix=Svd5*O>;~L^SCKgJKCT^jf+h1 zd~)4Onqqd&0rudHw=cD4mm;7c`O+&7=Tf<^Q0_y}(r=`O_P!{QtQAM%q>KTIp-}9U z$326GVbulkg;p+Wy0SNf>U!2xsT&{L>(1F)YO?b*B%P;nxoOVB=YxUMZ3EDv$K|yb zKFISyQZek*w|wKbf8(9$hr?kEM4TH+=~|KC_@nrQu`3jFzJy1j)K2pxGBriiTM7{5ncM7 zRRU)!-I=J5xME20z}IBU5X|-vV^~wfM)|_<3)) z3DJ=ljspJ)zDW(*L0G?wrr(Hjru})?zd^glSm|z(E?ru$En$n6fjeswiSk(k)Jk;E zxGm3*q;OOt6FbKw&oH?v5hhi=4O_HS?eC7to?Z=2OF~2IYS%=QBv$b--laRA8hf($&N)+!9{jE~)?NNhw?F+{oC{6-c5AH5S+_9hzvm>V z3sO(bt;E<#fnaRBcm)^Qaqhr`gbi&9{vbXcdF@%mYr8Vm-OG5wQ}O?}e558u{m?`j z-g$6j$@o}l5>g3tqJGyEwt&g6eJ|F<|^l-%kSW6YPVG^@poQBJ7mA4 z*8R~T^CHmpyj^6^Biueive_n5y5MOt?V!i#UwOM_Ux*mRW5xj!H(@Qe^r1xsHw4!U zGOL5mJ=~{*3?^E39J1O-?L2{jWw|llbE%%ftK(%Q*73r z?0!Uxq-hqY+i~Dw^o>~in$#~z-Z+1kD`G&NRD4)F#^$tYqLyCnmq>4(co@7?f#5{k z8m(|i)C1LdA0Kq}2T@i}+=*BYGQLE)GcDA(k8k{qJUg|!8ozAt+)rQT+7IHbFRAq( zj?UTszc{)CwgXHT)p$bR<@f-?TeE5e%8oK`wgXBRcynUn%- zf{nkup>ybX>X-XM1CorP2s|-uI|ci!G<#m)|H$k(@rvn1Nk;!S@h-|fz#AqvR=iQB z)Bv6bBY;ObDew~i12k_^Z$1LRBSPPGR3 zt{1<$_*hP!7u;W8xF9Ccte`Q%b#6E#ybRU9k_$fHiRrFD2u~VuLo^@J*_w%mIjrkU zHC7XA3HC8eaL)kt6}4<6Knn1J-?ty*z*S{8X}@J@f#$3xW*bQ2OVCyI%1VplC0?Q| z5FtVjV9xNzh$2!|Q*$m{^^l_82>6Qi34F!;WzadsxIqb-0mmXoIYQ62@Er%c6j>(q zGfQglb?jI1<>18~`D)ZUv% U!O2zVX9|qE*U6@05B=Bw0VYd*8vpn&Wa)oHgy>;=0`AK-hts z0}&;PqoOHpc;DH#+pbEUxAuGAw(tA4-aXIrzP~?fBf|s!+Ll@Xek&0l1w0Z~&wE_r zy03dr#kpn%2jb#^ugln2L3~XzF|i1E8}#MCR<=prbT3&${q84Eu+bY?Zgal?CaidD zY~}X(_P8FVFTZ>8*|QmWwK|?MZh zX6R2Yni(wxfWv8ro`4JX`D4^e>ZKrodP%($7*H?&f?n3|1m}RJ zE+s9Sv)L8Xd^#um3`mCYcj!;4TjT)N1 z&jru)%Y22s!_)CrId$nPpSSEZ^%J$DbkXThRX%yi3+<#ZJp@Gw3*?MV3MvJKw1frf pBlVH`Sj+&aKq`<5q=IJP-%q8CgOLB?u=&}m*|7SD Date: Sat, 29 Aug 2020 23:29:29 +0200 Subject: [PATCH 167/320] Change structure of old style spinner to be closer to stable --- .../Skinning/LegacyOldStyleSpinner.cs | 85 +++++++++++-------- 1 file changed, 51 insertions(+), 34 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Skinning/LegacyOldStyleSpinner.cs b/osu.Game.Rulesets.Osu/Skinning/LegacyOldStyleSpinner.cs index 81a0df5ea5..e157842fd1 100644 --- a/osu.Game.Rulesets.Osu/Skinning/LegacyOldStyleSpinner.cs +++ b/osu.Game.Rulesets.Osu/Skinning/LegacyOldStyleSpinner.cs @@ -22,11 +22,11 @@ namespace osu.Game.Rulesets.Osu.Skinning { private DrawableSpinner drawableSpinner; private Sprite disc; + private Sprite metreSprite; private Container metre; - private const float background_y_offset = 20; - private const float sprite_scale = 1 / 1.6f; + private const float final_metre_height = 692 * sprite_scale; [BackgroundDependencyLoader] private void load(ISkinSource source, DrawableHitObject drawableObject) @@ -35,50 +35,58 @@ namespace osu.Game.Rulesets.Osu.Skinning RelativeSizeAxes = Axes.Both; - InternalChildren = new Drawable[] + InternalChild = new Container { - new Sprite + // the old-style spinner relied heavily on absolute screen-space coordinate values. + // wrap everything in a container simulating absolute coords to preserve alignment + // as there are skins that depend on it. + Width = 640, + Height = 480, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Children = new Drawable[] { - Anchor = Anchor.BottomCentre, - Origin = Anchor.BottomCentre, - Texture = source.GetTexture("spinner-background"), - Y = background_y_offset, - Scale = new Vector2(sprite_scale) - }, - disc = new Sprite - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Texture = source.GetTexture("spinner-circle"), - Scale = new Vector2(sprite_scale) - }, - metre = new Container - { - Anchor = Anchor.BottomCentre, - Origin = Anchor.BottomCentre, - Y = background_y_offset, - Masking = true, - Child = new Sprite + new Sprite { - Texture = source.GetTexture("spinner-metre"), - Anchor = Anchor.BottomCentre, - Origin = Anchor.BottomCentre, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Texture = source.GetTexture("spinner-background"), + Scale = new Vector2(sprite_scale) }, - Scale = new Vector2(0.625f) + disc = new Sprite + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Texture = source.GetTexture("spinner-circle"), + Scale = new Vector2(sprite_scale) + }, + metre = new Container + { + AutoSizeAxes = Axes.Both, + // this anchor makes no sense, but that's what stable uses. + Anchor = Anchor.TopLeft, + Origin = Anchor.TopLeft, + // adjustment for stable (metre has additional offset) + Margin = new MarginPadding { Top = 20 }, + Masking = true, + Child = metreSprite = new Sprite + { + Texture = source.GetTexture("spinner-metre"), + Anchor = Anchor.TopLeft, + Origin = Anchor.TopLeft, + Scale = new Vector2(0.625f) + } + } } }; } - private Vector2 metreFinalSize; - protected override void LoadComplete() { base.LoadComplete(); this.FadeOut(); drawableSpinner.State.BindValueChanged(updateStateTransforms, true); - - metreFinalSize = metre.Size = metre.Child.Size; } private void updateStateTransforms(ValueChangedEvent state) @@ -93,7 +101,16 @@ namespace osu.Game.Rulesets.Osu.Skinning { base.Update(); disc.Rotation = drawableSpinner.RotationTracker.Rotation; - metre.Height = getMetreHeight(drawableSpinner.Progress); + + // careful: need to call this exactly once for all calculations in a frame + // as the function has a random factor in it + var metreHeight = getMetreHeight(drawableSpinner.Progress); + + // hack to make the metre blink up from below than down from above. + // move down the container to be able to apply masking for the metre, + // and then move the sprite back up the same amount to keep its position absolute. + metre.Y = final_metre_height - metreHeight; + metreSprite.Y = -metre.Y; } private const int total_bars = 10; @@ -108,7 +125,7 @@ namespace osu.Game.Rulesets.Osu.Skinning if (RNG.NextBool(((int)progress % 10) / 10f)) barCount++; - return (float)barCount / total_bars * metreFinalSize.Y; + return (float)barCount / total_bars * final_metre_height; } } } From e428144f736cdbbb818f9c001d31866fb975b1f2 Mon Sep 17 00:00:00 2001 From: Craftplacer Date: Sun, 30 Aug 2020 11:34:50 +0200 Subject: [PATCH 168/320] Use IBeatmapSkin --- .../Beatmaps/Formats/LegacyBeatmapEncoderTest.cs | 4 ++-- osu.Game/Beatmaps/BeatmapManager.cs | 10 +--------- osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs | 9 +++------ 3 files changed, 6 insertions(+), 17 deletions(-) diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs index dee4626cd0..8d5060e2fe 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs @@ -45,7 +45,7 @@ namespace osu.Game.Tests.Beatmaps.Formats Assert.IsTrue(decoded.beatmapSkin.Configuration.Equals(decodedAfterEncode.beatmapSkin.Configuration)); } - private void sort((IBeatmap beatmap, LegacyBeatmapSkin beatmapSkin) tuple) + private void sort((IBeatmap beatmap, IBeatmapSkin beatmapSkin) tuple) { // Sort control points to ensure a sane ordering, as they may be parsed in different orders. This works because each group contains only uniquely-typed control points. foreach (var g in tuple.beatmap.ControlPointInfo.Groups) @@ -77,7 +77,7 @@ namespace osu.Game.Tests.Beatmaps.Formats } } - private Stream encodeToLegacy((IBeatmap beatmap, LegacyBeatmapSkin beatmapSkin) fullBeatmap) + private Stream encodeToLegacy((IBeatmap beatmap, IBeatmapSkin beatmapSkin) fullBeatmap) { var (beatmap, beatmapSkin) = fullBeatmap; var stream = new MemoryStream(); diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index 86d35749ac..89a776dd31 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -196,22 +196,14 @@ namespace osu.Game.Beatmaps /// The to save the content against. The file referenced by will be replaced. /// The content to write. /// The beatmap content to write, or null if not to be changed. - public void Save(BeatmapInfo info, IBeatmap beatmapContent, LegacyBeatmapSkin beatmapSkin = null) + public void Save(BeatmapInfo info, IBeatmap beatmapContent, IBeatmapSkin beatmapSkin = null) { var setInfo = QueryBeatmapSet(s => s.Beatmaps.Any(b => b.ID == info.ID)); using (var stream = new MemoryStream()) { using (var sw = new StreamWriter(stream, Encoding.UTF8, 1024, true)) - { - if (beatmapSkin == null) - { - var workingBeatmap = GetWorkingBeatmap(info); - beatmapSkin = (workingBeatmap.Skin is LegacyBeatmapSkin legacy) ? legacy : null; - } - new LegacyBeatmapEncoder(beatmapContent, beatmapSkin).Encode(sw); - } stream.Seek(0, SeekOrigin.Begin); diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs index 497c3c88d0..543d960300 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs @@ -25,14 +25,14 @@ namespace osu.Game.Beatmaps.Formats public const int LATEST_VERSION = 128; private readonly IBeatmap beatmap; - private readonly LegacyBeatmapSkin skin; + private readonly IBeatmapSkin skin; /// /// Creates a new . /// /// The beatmap to encode. /// An optional skin, for encoding the beatmap's combo colours. - public LegacyBeatmapEncoder(IBeatmap beatmap, [CanBeNull] LegacyBeatmapSkin skin) + public LegacyBeatmapEncoder(IBeatmap beatmap, [CanBeNull] IBeatmapSkin skin) { this.beatmap = beatmap; this.skin = skin; @@ -211,10 +211,7 @@ namespace osu.Game.Beatmaps.Formats private void handleComboColours(TextWriter writer) { - if (!(skin is LegacyBeatmapSkin legacySkin)) - return; - - var colours = legacySkin.GetConfig>(GlobalSkinColours.ComboColours)?.Value; + var colours = skin.GetConfig>(GlobalSkinColours.ComboColours)?.Value; if (colours == null || colours.Count == 0) return; From 08321d8dec457381c1e52cab064dd304e309a1ac Mon Sep 17 00:00:00 2001 From: Craftplacer Date: Sun, 30 Aug 2020 11:37:43 +0200 Subject: [PATCH 169/320] Safe checking against ComboColours instead of CustomColours --- osu.Game/Skinning/SkinConfiguration.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Skinning/SkinConfiguration.cs b/osu.Game/Skinning/SkinConfiguration.cs index 2ac4dfa0c8..0f6162d6c4 100644 --- a/osu.Game/Skinning/SkinConfiguration.cs +++ b/osu.Game/Skinning/SkinConfiguration.cs @@ -51,6 +51,6 @@ namespace osu.Game.Skinning public readonly SortedDictionary ConfigDictionary = new SortedDictionary(); - public bool Equals(SkinConfiguration other) => other != null && ConfigDictionary.SequenceEqual(other.ConfigDictionary) && ComboColours.SequenceEqual(other.ComboColours) && CustomColours?.SequenceEqual(other.CustomColours) == true; + public bool Equals(SkinConfiguration other) => other != null && ConfigDictionary.SequenceEqual(other.ConfigDictionary) && ComboColours?.SequenceEqual(other.ComboColours) == true && CustomColours.SequenceEqual(other.CustomColours); } } From f5c82d41eb010912aebd758db6c4b3e9677ac01a Mon Sep 17 00:00:00 2001 From: Craftplacer Date: Sun, 30 Aug 2020 16:06:48 +0200 Subject: [PATCH 170/320] Remove if-cast --- osu.Game/Screens/Edit/Editor.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index 7bd6529897..273ae67ffd 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -65,7 +65,7 @@ namespace osu.Game.Screens.Edit private IBeatmap playableBeatmap; private EditorBeatmap editorBeatmap; private EditorChangeHandler changeHandler; - private LegacyBeatmapSkin beatmapSkin; + private IBeatmapSkin beatmapSkin; private DependencyContainer dependencies; @@ -106,7 +106,7 @@ namespace osu.Game.Screens.Edit AddInternal(editorBeatmap = new EditorBeatmap(playableBeatmap)); dependencies.CacheAs(editorBeatmap); - beatmapSkin = (Beatmap.Value.Skin is LegacyBeatmapSkin legacy) ? legacy : null; + beatmapSkin = Beatmap.Value.Skin; changeHandler = new EditorChangeHandler(editorBeatmap, beatmapSkin); dependencies.CacheAs(changeHandler); From b39ec74bb812f5c582936cb2ca9877700d786968 Mon Sep 17 00:00:00 2001 From: Craftplacer Date: Sun, 30 Aug 2020 16:07:06 +0200 Subject: [PATCH 171/320] Scope down to IBeatmapSkin in EditorChangeHandler --- osu.Game/Screens/Edit/EditorChangeHandler.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Edit/EditorChangeHandler.cs b/osu.Game/Screens/Edit/EditorChangeHandler.cs index 1d10eaf5cb..60d869ec82 100644 --- a/osu.Game/Screens/Edit/EditorChangeHandler.cs +++ b/osu.Game/Screens/Edit/EditorChangeHandler.cs @@ -26,7 +26,7 @@ namespace osu.Game.Screens.Edit private int currentState = -1; private readonly EditorBeatmap editorBeatmap; - private readonly LegacyBeatmapSkin beatmapSkin; + private readonly IBeatmapSkin beatmapSkin; private int bulkChangesStarted; private bool isRestoring; @@ -37,7 +37,7 @@ namespace osu.Game.Screens.Edit /// /// The to track the s of. /// The skin to track the inline skin configuration of. - public EditorChangeHandler(EditorBeatmap editorBeatmap, LegacyBeatmapSkin beatmapSkin) + public EditorChangeHandler(EditorBeatmap editorBeatmap, IBeatmapSkin beatmapSkin) { this.editorBeatmap = editorBeatmap; From 7e57af3ca437b5ae7a053051eb3b64cc1c0bc0e4 Mon Sep 17 00:00:00 2001 From: Craftplacer Date: Sun, 30 Aug 2020 16:07:46 +0200 Subject: [PATCH 172/320] Return true if both ComboColours are null --- osu.Game/Skinning/SkinConfiguration.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Skinning/SkinConfiguration.cs b/osu.Game/Skinning/SkinConfiguration.cs index 0f6162d6c4..18d970dd64 100644 --- a/osu.Game/Skinning/SkinConfiguration.cs +++ b/osu.Game/Skinning/SkinConfiguration.cs @@ -51,6 +51,6 @@ namespace osu.Game.Skinning public readonly SortedDictionary ConfigDictionary = new SortedDictionary(); - public bool Equals(SkinConfiguration other) => other != null && ConfigDictionary.SequenceEqual(other.ConfigDictionary) && ComboColours?.SequenceEqual(other.ComboColours) == true && CustomColours.SequenceEqual(other.CustomColours); + public bool Equals(SkinConfiguration other) => other != null && ConfigDictionary.SequenceEqual(other.ConfigDictionary) && ((ComboColours == null && other.ComboColours == null) || ComboColours.SequenceEqual(other.ComboColours)) && CustomColours.SequenceEqual(other.CustomColours); } } From 1fdf8e62004f59ec098a793c6d1a8591cf053b37 Mon Sep 17 00:00:00 2001 From: Craftplacer Date: Sun, 30 Aug 2020 16:07:58 +0200 Subject: [PATCH 173/320] Fix xmldoc in LegacyBeatmapEncoder --- osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs index 543d960300..8d7e509070 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs @@ -31,7 +31,7 @@ namespace osu.Game.Beatmaps.Formats /// Creates a new . /// /// The beatmap to encode. - /// An optional skin, for encoding the beatmap's combo colours. + /// The beatmap's skin, used for encoding combo colours. public LegacyBeatmapEncoder(IBeatmap beatmap, [CanBeNull] IBeatmapSkin skin) { this.beatmap = beatmap; From 919d7b77855435bc90df339ac3c939550145ca96 Mon Sep 17 00:00:00 2001 From: Craftplacer Date: Sun, 30 Aug 2020 16:08:13 +0200 Subject: [PATCH 174/320] Remove redundant call to TestResources --- osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs index 8d5060e2fe..b25f2f1fd3 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs @@ -35,7 +35,7 @@ namespace osu.Game.Tests.Beatmaps.Formats [TestCaseSource(nameof(allBeatmaps))] public void TestEncodeDecodeStability(string name) { - var decoded = decodeFromLegacy(TestResources.GetStore().GetStream(name), name); + var decoded = decodeFromLegacy(beatmaps_resource_store.GetStream(name), name); var decodedAfterEncode = decodeFromLegacy(encodeToLegacy(decoded), name); sort(decoded); From 337037ab3b0f33474c1d9cc829b25b169a49337d Mon Sep 17 00:00:00 2001 From: Craftplacer Date: Sun, 30 Aug 2020 16:08:52 +0200 Subject: [PATCH 175/320] Make test load actual beatmap's skin configuration --- .../Formats/LegacyBeatmapEncoderTest.cs | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs index b25f2f1fd3..bea21087c5 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs @@ -42,7 +42,7 @@ namespace osu.Game.Tests.Beatmaps.Formats sort(decodedAfterEncode); Assert.That(decodedAfterEncode.beatmap.Serialize(), Is.EqualTo(decoded.beatmap.Serialize())); - Assert.IsTrue(decoded.beatmapSkin.Configuration.Equals(decodedAfterEncode.beatmapSkin.Configuration)); + Assert.IsTrue(decodedAfterEncode.beatmapSkin.Configuration.Equals(decoded.beatmapSkin.Configuration)); } private void sort((IBeatmap beatmap, IBeatmapSkin beatmapSkin) tuple) @@ -55,11 +55,13 @@ namespace osu.Game.Tests.Beatmaps.Formats } } - private (IBeatmap beatmap, LegacyBeatmapSkin beatmapSkin) decodeFromLegacy(Stream stream, string name) + private (IBeatmap beatmap, TestLegacySkin beatmapSkin) decodeFromLegacy(Stream stream, string name) { using (var reader = new LineBufferedReader(stream)) { var beatmap = new LegacyBeatmapDecoder { ApplyOffsets = false }.Decode(reader); + + beatmap.BeatmapInfo.Path = name; beatmap.BeatmapInfo.BeatmapSet = new BeatmapSetInfo { Files = new List @@ -69,14 +71,22 @@ namespace osu.Game.Tests.Beatmaps.Formats Filename = name, FileInfo = new osu.Game.IO.FileInfo { Hash = name } } - } + }, }; - var beatmapSkin = new LegacyBeatmapSkin(beatmap.BeatmapInfo, beatmaps_resource_store, null); + var beatmapSkin = new TestLegacySkin(beatmap, beatmaps_resource_store, name); return (convert(beatmap), beatmapSkin); } } + private class TestLegacySkin : LegacySkin, IBeatmapSkin + { + public TestLegacySkin(Beatmap beatmap, IResourceStore storage, string fileName) + : base(new SkinInfo() { Name = "Test Skin", Creator = "Craftplacer" }, storage, null, fileName) + { + } + } + private Stream encodeToLegacy((IBeatmap beatmap, IBeatmapSkin beatmapSkin) fullBeatmap) { var (beatmap, beatmapSkin) = fullBeatmap; From 7e668fc31a619ca1d89dc6532898433bf40efe07 Mon Sep 17 00:00:00 2001 From: Craftplacer Date: Sun, 30 Aug 2020 16:11:49 +0200 Subject: [PATCH 176/320] Update osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs Co-authored-by: Salman Ahmed --- osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs index 8d7e509070..cae6a43cd4 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs @@ -226,7 +226,8 @@ namespace osu.Game.Beatmaps.Formats writer.Write(FormattableString.Invariant($"{(byte)(comboColour.R * byte.MaxValue)},")); writer.Write(FormattableString.Invariant($"{(byte)(comboColour.G * byte.MaxValue)},")); writer.Write(FormattableString.Invariant($"{(byte)(comboColour.B * byte.MaxValue)},")); - writer.WriteLine(FormattableString.Invariant($"{(byte)(comboColour.A * byte.MaxValue)}")); + writer.Write(FormattableString.Invariant($"{(byte)(comboColour.A * byte.MaxValue)}")); + writer.WriteLine(); } } From 43d144b7c00756a0cb0d94a7c88750614fcd97f6 Mon Sep 17 00:00:00 2001 From: Craftplacer Date: Sun, 30 Aug 2020 16:23:00 +0200 Subject: [PATCH 177/320] Remove empty argument list --- osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs index bea21087c5..dc91af72e8 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs @@ -82,7 +82,7 @@ namespace osu.Game.Tests.Beatmaps.Formats private class TestLegacySkin : LegacySkin, IBeatmapSkin { public TestLegacySkin(Beatmap beatmap, IResourceStore storage, string fileName) - : base(new SkinInfo() { Name = "Test Skin", Creator = "Craftplacer" }, storage, null, fileName) + : base(new SkinInfo { Name = "Test Skin", Creator = "Craftplacer" }, storage, null, fileName) { } } From db413686bbe7db6dadf72d71d54fe1def027427b Mon Sep 17 00:00:00 2001 From: Craftplacer Date: Sun, 30 Aug 2020 21:12:45 +0200 Subject: [PATCH 178/320] Add BeatmapSkin to EditorBeatmap --- osu.Game.Tests/Editing/EditorChangeHandlerTest.cs | 6 +++--- osu.Game/Screens/Edit/Editor.cs | 10 +++------- osu.Game/Screens/Edit/EditorBeatmap.cs | 6 +++++- osu.Game/Screens/Edit/EditorChangeHandler.cs | 9 ++------- 4 files changed, 13 insertions(+), 18 deletions(-) diff --git a/osu.Game.Tests/Editing/EditorChangeHandlerTest.cs b/osu.Game.Tests/Editing/EditorChangeHandlerTest.cs index 6d708ce838..feda1ae0e9 100644 --- a/osu.Game.Tests/Editing/EditorChangeHandlerTest.cs +++ b/osu.Game.Tests/Editing/EditorChangeHandlerTest.cs @@ -13,7 +13,7 @@ namespace osu.Game.Tests.Editing [Test] public void TestSaveRestoreState() { - var handler = new EditorChangeHandler(new EditorBeatmap(new Beatmap()), null); + var handler = new EditorChangeHandler(new EditorBeatmap(new Beatmap())); Assert.That(handler.CanUndo.Value, Is.False); Assert.That(handler.CanRedo.Value, Is.False); @@ -32,7 +32,7 @@ namespace osu.Game.Tests.Editing [Test] public void TestMaxStatesSaved() { - var handler = new EditorChangeHandler(new EditorBeatmap(new Beatmap()), null); + var handler = new EditorChangeHandler(new EditorBeatmap(new Beatmap())); Assert.That(handler.CanUndo.Value, Is.False); @@ -53,7 +53,7 @@ namespace osu.Game.Tests.Editing [Test] public void TestMaxStatesExceeded() { - var handler = new EditorChangeHandler(new EditorBeatmap(new Beatmap()), null); + var handler = new EditorChangeHandler(new EditorBeatmap(new Beatmap())); Assert.That(handler.CanUndo.Value, Is.False); diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index 273ae67ffd..b1f11d79f9 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -33,7 +33,6 @@ using osu.Game.Screens.Edit.Compose; using osu.Game.Screens.Edit.Setup; using osu.Game.Screens.Edit.Timing; using osu.Game.Screens.Play; -using osu.Game.Skinning; using osu.Game.Users; namespace osu.Game.Screens.Edit @@ -65,7 +64,6 @@ namespace osu.Game.Screens.Edit private IBeatmap playableBeatmap; private EditorBeatmap editorBeatmap; private EditorChangeHandler changeHandler; - private IBeatmapSkin beatmapSkin; private DependencyContainer dependencies; @@ -103,11 +101,9 @@ namespace osu.Game.Screens.Edit return; } - AddInternal(editorBeatmap = new EditorBeatmap(playableBeatmap)); + AddInternal(editorBeatmap = new EditorBeatmap(playableBeatmap, Beatmap.Value.Skin)); dependencies.CacheAs(editorBeatmap); - - beatmapSkin = Beatmap.Value.Skin; - changeHandler = new EditorChangeHandler(editorBeatmap, beatmapSkin); + changeHandler = new EditorChangeHandler(editorBeatmap); dependencies.CacheAs(changeHandler); EditorMenuBar menuBar; @@ -402,7 +398,7 @@ namespace osu.Game.Screens.Edit clock.SeekForward(!clock.IsRunning, amount); } - private void saveBeatmap() => beatmapManager.Save(playableBeatmap.BeatmapInfo, editorBeatmap, beatmapSkin); + private void saveBeatmap() => beatmapManager.Save(playableBeatmap.BeatmapInfo, editorBeatmap, editorBeatmap.BeatmapSkin); private void exportBeatmap() { diff --git a/osu.Game/Screens/Edit/EditorBeatmap.cs b/osu.Game/Screens/Edit/EditorBeatmap.cs index 23c8c9f605..a314d50e60 100644 --- a/osu.Game/Screens/Edit/EditorBeatmap.cs +++ b/osu.Game/Screens/Edit/EditorBeatmap.cs @@ -15,6 +15,7 @@ using osu.Game.Beatmaps.ControlPoints; using osu.Game.Beatmaps.Timing; using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Objects; +using osu.Game.Skinning; namespace osu.Game.Screens.Edit { @@ -47,6 +48,8 @@ namespace osu.Game.Screens.Edit public readonly IBeatmap PlayableBeatmap; + public readonly IBeatmapSkin BeatmapSkin; + [Resolved] private BindableBeatDivisor beatDivisor { get; set; } @@ -54,9 +57,10 @@ namespace osu.Game.Screens.Edit private readonly Dictionary> startTimeBindables = new Dictionary>(); - public EditorBeatmap(IBeatmap playableBeatmap) + public EditorBeatmap(IBeatmap playableBeatmap, IBeatmapSkin beatmapSkin = null) { PlayableBeatmap = playableBeatmap; + BeatmapSkin = beatmapSkin; beatmapProcessor = playableBeatmap.BeatmapInfo.Ruleset?.CreateInstance().CreateBeatmapProcessor(PlayableBeatmap); diff --git a/osu.Game/Screens/Edit/EditorChangeHandler.cs b/osu.Game/Screens/Edit/EditorChangeHandler.cs index 60d869ec82..927c823c64 100644 --- a/osu.Game/Screens/Edit/EditorChangeHandler.cs +++ b/osu.Game/Screens/Edit/EditorChangeHandler.cs @@ -8,7 +8,6 @@ using System.Text; using osu.Framework.Bindables; using osu.Game.Beatmaps.Formats; using osu.Game.Rulesets.Objects; -using osu.Game.Skinning; namespace osu.Game.Screens.Edit { @@ -26,7 +25,6 @@ namespace osu.Game.Screens.Edit private int currentState = -1; private readonly EditorBeatmap editorBeatmap; - private readonly IBeatmapSkin beatmapSkin; private int bulkChangesStarted; private bool isRestoring; @@ -36,8 +34,7 @@ namespace osu.Game.Screens.Edit /// Creates a new . /// /// The to track the s of. - /// The skin to track the inline skin configuration of. - public EditorChangeHandler(EditorBeatmap editorBeatmap, IBeatmapSkin beatmapSkin) + public EditorChangeHandler(EditorBeatmap editorBeatmap) { this.editorBeatmap = editorBeatmap; @@ -47,8 +44,6 @@ namespace osu.Game.Screens.Edit patcher = new LegacyEditorBeatmapPatcher(editorBeatmap); - this.beatmapSkin = beatmapSkin; - // Initial state. SaveState(); } @@ -90,7 +85,7 @@ namespace osu.Game.Screens.Edit using (var stream = new MemoryStream()) { using (var sw = new StreamWriter(stream, Encoding.UTF8, 1024, true)) - new LegacyBeatmapEncoder(editorBeatmap, beatmapSkin).Encode(sw); + new LegacyBeatmapEncoder(editorBeatmap, editorBeatmap.BeatmapSkin).Encode(sw); savedStates.Add(stream.ToArray()); } From 07f6a6817961c0426baacb14507df4d1e4937451 Mon Sep 17 00:00:00 2001 From: Craftplacer Date: Sun, 30 Aug 2020 21:13:06 +0200 Subject: [PATCH 179/320] Update LegacyBeatmapEncoderTest.cs --- .../Formats/LegacyBeatmapEncoderTest.cs | 65 +++++++++++++++---- 1 file changed, 51 insertions(+), 14 deletions(-) diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs index dc91af72e8..a8a3f266fc 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs @@ -7,8 +7,10 @@ using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; +using System.Threading.Tasks; using NUnit.Framework; using osu.Framework.Audio.Track; +using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Graphics.Textures; using osu.Framework.IO.Stores; using osu.Game.Beatmaps; @@ -61,24 +63,59 @@ namespace osu.Game.Tests.Beatmaps.Formats { var beatmap = new LegacyBeatmapDecoder { ApplyOffsets = false }.Decode(reader); - beatmap.BeatmapInfo.Path = name; - beatmap.BeatmapInfo.BeatmapSet = new BeatmapSetInfo + using (var rs = new MemoryBeatmapResourceStore(stream, name)) { - Files = new List - { - new BeatmapSetFileInfo - { - Filename = name, - FileInfo = new osu.Game.IO.FileInfo { Hash = name } - } - }, - }; - - var beatmapSkin = new TestLegacySkin(beatmap, beatmaps_resource_store, name); - return (convert(beatmap), beatmapSkin); + var beatmapSkin = new TestLegacySkin(beatmap, rs, name); + return (convert(beatmap), beatmapSkin); + } } } + private class MemoryBeatmapResourceStore : IResourceStore + { + private readonly Stream beatmapData; + private readonly string beatmapName; + + public MemoryBeatmapResourceStore(Stream beatmapData, string beatmapName) + { + this.beatmapData = beatmapData; + this.beatmapName = beatmapName; + } + + public void Dispose() => beatmapData.Dispose(); + + public byte[] Get(string name) + { + if (name != beatmapName) + return null; + + byte[] buffer = new byte[beatmapData.Length]; + beatmapData.Read(buffer, 0, buffer.Length); + return buffer; + } + + public async Task GetAsync(string name) + { + if (name != beatmapName) + return null; + + byte[] buffer = new byte[beatmapData.Length]; + await beatmapData.ReadAsync(buffer.AsMemory()); + return buffer; + } + + public Stream GetStream(string name) + { + if (name != beatmapName) + return null; + + beatmapData.Seek(0, SeekOrigin.Begin); + return beatmapData; + } + + public IEnumerable GetAvailableResources() => beatmapName.Yield(); + } + private class TestLegacySkin : LegacySkin, IBeatmapSkin { public TestLegacySkin(Beatmap beatmap, IResourceStore storage, string fileName) From 8151aa6ed8b761f4b51ceb7345c0c9bb855d7ad1 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 31 Aug 2020 13:31:55 +0900 Subject: [PATCH 180/320] Remove unused method --- osu.Game.Rulesets.Mania.Tests/TestSceneOutOfOrderHits.cs | 7 ------- 1 file changed, 7 deletions(-) diff --git a/osu.Game.Rulesets.Mania.Tests/TestSceneOutOfOrderHits.cs b/osu.Game.Rulesets.Mania.Tests/TestSceneOutOfOrderHits.cs index ed187e65bf..ab840e1c46 100644 --- a/osu.Game.Rulesets.Mania.Tests/TestSceneOutOfOrderHits.cs +++ b/osu.Game.Rulesets.Mania.Tests/TestSceneOutOfOrderHits.cs @@ -1,7 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System; using System.Collections.Generic; using System.Linq; using NUnit.Framework; @@ -60,12 +59,6 @@ namespace osu.Game.Rulesets.Mania.Tests () => judgementResults.Single(r => r.HitObject == hitObject).Type == result); } - private void addJudgementAssert(string name, Func hitObject, HitResult result) - { - AddAssert($"{name} judgement is {result}", - () => judgementResults.Single(r => r.HitObject == hitObject()).Type == result); - } - private void addJudgementOffsetAssert(ManiaHitObject hitObject, double offset) { AddAssert($"({hitObject.GetType().ReadableName()} @ {hitObject.StartTime}) judged at {offset}", From acbeb5406f320d5749e2301f3b471b14eb85b62c Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 31 Aug 2020 13:33:41 +0900 Subject: [PATCH 181/320] Add/improve xmldoc --- .../Objects/Drawables/DrawableManiaHitObject.cs | 4 ++++ .../Objects/Drawables/DrawableOsuHitObject.cs | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs index 0594d1e143..e16413bce7 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs @@ -36,6 +36,10 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables } } + /// + /// Whether this can be hit, given a time value. + /// If non-null, judgements will be ignored (resulting in a shake) whilst the function returns false. + /// public Func CheckHittable; protected DrawableManiaHitObject(ManiaHitObject hitObject) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs index 8308c0c576..2946331bc6 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs @@ -22,7 +22,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables protected override float SamplePlaybackPosition => HitObject.X / OsuPlayfield.BASE_SIZE.X; /// - /// Whether this can be hit. + /// Whether this can be hit, given a time value. /// If non-null, judgements will be ignored (resulting in a shake) whilst the function returns false. /// public Func CheckHittable; From abdb99192397e21964706822c9d9fa8948a54c8f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 31 Aug 2020 14:15:47 +0900 Subject: [PATCH 182/320] Hide misses from timing distribution graph --- .../TestSceneHitEventTimingDistributionGraph.cs | 12 ++++++++++++ .../Statistics/HitEventTimingDistributionGraph.cs | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Ranking/TestSceneHitEventTimingDistributionGraph.cs b/osu.Game.Tests/Visual/Ranking/TestSceneHitEventTimingDistributionGraph.cs index 7ca1fc842f..144f8da2fa 100644 --- a/osu.Game.Tests/Visual/Ranking/TestSceneHitEventTimingDistributionGraph.cs +++ b/osu.Game.Tests/Visual/Ranking/TestSceneHitEventTimingDistributionGraph.cs @@ -35,6 +35,18 @@ namespace osu.Game.Tests.Visual.Ranking createTest(new List()); } + [Test] + public void TestMissesDontShow() + { + createTest(Enumerable.Range(0, 100).Select(i => + { + if (i % 2 == 0) + return new HitEvent(0, HitResult.Perfect, new HitCircle(), new HitCircle(), null); + + return new HitEvent(30, HitResult.Miss, new HitCircle(), new HitCircle(), null); + }).ToList()); + } + private void createTest(List events) => AddStep("create test", () => { Children = new Drawable[] diff --git a/osu.Game/Screens/Ranking/Statistics/HitEventTimingDistributionGraph.cs b/osu.Game/Screens/Ranking/Statistics/HitEventTimingDistributionGraph.cs index 527da429ed..45fdc3ff33 100644 --- a/osu.Game/Screens/Ranking/Statistics/HitEventTimingDistributionGraph.cs +++ b/osu.Game/Screens/Ranking/Statistics/HitEventTimingDistributionGraph.cs @@ -48,7 +48,7 @@ namespace osu.Game.Screens.Ranking.Statistics /// The s to display the timing distribution of. public HitEventTimingDistributionGraph(IReadOnlyList hitEvents) { - this.hitEvents = hitEvents.Where(e => !(e.HitObject.HitWindows is HitWindows.EmptyHitWindows)).ToList(); + this.hitEvents = hitEvents.Where(e => !(e.HitObject.HitWindows is HitWindows.EmptyHitWindows) && e.Result != HitResult.Miss).ToList(); } [BackgroundDependencyLoader] From c3bfce6ccff2bd908a80e47614b1329d1f585e00 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 31 Aug 2020 15:03:41 +0900 Subject: [PATCH 183/320] Add star rating to beatmap wedge --- osu.Game/Screens/Select/BeatmapInfoWedge.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/osu.Game/Screens/Select/BeatmapInfoWedge.cs b/osu.Game/Screens/Select/BeatmapInfoWedge.cs index 27ce9e82dd..cb3a347af4 100644 --- a/osu.Game/Screens/Select/BeatmapInfoWedge.cs +++ b/osu.Game/Screens/Select/BeatmapInfoWedge.cs @@ -27,6 +27,7 @@ using osu.Framework.Logging; using osu.Game.Rulesets; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.UI; +using osu.Game.Screens.Ranking.Expanded; namespace osu.Game.Screens.Select { @@ -224,8 +225,15 @@ namespace osu.Game.Screens.Select AutoSizeAxes = Axes.Both, Children = new Drawable[] { + new StarRatingDisplay(beatmapInfo) + { + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight, + }, StatusPill = new BeatmapSetOnlineStatusPill { + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight, TextSize = 11, TextPadding = new MarginPadding { Horizontal = 8, Vertical = 2 }, Status = beatmapInfo.Status, From 4736845318acac3c4e4da894500389a933bc8c22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Mon, 31 Aug 2020 10:56:06 +0200 Subject: [PATCH 184/320] Add spacing between star rating and beatmap status --- osu.Game/Screens/Select/BeatmapInfoWedge.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Screens/Select/BeatmapInfoWedge.cs b/osu.Game/Screens/Select/BeatmapInfoWedge.cs index cb3a347af4..518ad33529 100644 --- a/osu.Game/Screens/Select/BeatmapInfoWedge.cs +++ b/osu.Game/Screens/Select/BeatmapInfoWedge.cs @@ -229,6 +229,7 @@ namespace osu.Game.Screens.Select { Anchor = Anchor.CentreRight, Origin = Anchor.CentreRight, + Margin = new MarginPadding { Bottom = 5 } }, StatusPill = new BeatmapSetOnlineStatusPill { From bee01bdd38cf13bfeddac343c68ad315daef570f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 31 Aug 2020 18:01:16 +0900 Subject: [PATCH 185/320] Fix first scroll wheel in editor incorrectly advancing twice --- osu.Game/Screens/Edit/Editor.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index d92f3922c3..e178459d5c 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -284,7 +284,7 @@ namespace osu.Game.Screens.Edit // this is a special case to handle the "pivot" scenario. // if we are precise scrolling in one direction then change our mind and scroll backwards, // the existing accumulation should be applied in the inverse direction to maintain responsiveness. - if (Math.Sign(scrollAccumulation) != scrollDirection) + if (scrollAccumulation != 0 && Math.Sign(scrollAccumulation) != scrollDirection) scrollAccumulation = scrollDirection * (precision - Math.Abs(scrollAccumulation)); scrollAccumulation += scrollComponent * (e.IsPrecise ? 0.1 : 1); From 7d273d631be6491d3ad6ae769770469ba0cb9214 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Mon, 31 Aug 2020 11:05:42 +0200 Subject: [PATCH 186/320] Do not show star difficulty on wedge if zero --- osu.Game/Screens/Select/BeatmapInfoWedge.cs | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/osu.Game/Screens/Select/BeatmapInfoWedge.cs b/osu.Game/Screens/Select/BeatmapInfoWedge.cs index 518ad33529..2b2c40411d 100644 --- a/osu.Game/Screens/Select/BeatmapInfoWedge.cs +++ b/osu.Game/Screens/Select/BeatmapInfoWedge.cs @@ -223,14 +223,13 @@ namespace osu.Game.Screens.Select Direction = FillDirection.Vertical, Padding = new MarginPadding { Top = 14, Right = shear_width / 2 }, AutoSizeAxes = Axes.Both, - Children = new Drawable[] + Children = new[] { - new StarRatingDisplay(beatmapInfo) + createStarRatingDisplay(beatmapInfo).With(display => { - Anchor = Anchor.CentreRight, - Origin = Anchor.CentreRight, - Margin = new MarginPadding { Bottom = 5 } - }, + display.Anchor = Anchor.CentreRight; + display.Origin = Anchor.CentreRight; + }), StatusPill = new BeatmapSetOnlineStatusPill { Anchor = Anchor.CentreRight, @@ -291,6 +290,13 @@ namespace osu.Game.Screens.Select StatusPill.Hide(); } + private static Drawable createStarRatingDisplay(BeatmapInfo beatmapInfo) => beatmapInfo.StarDifficulty > 0 + ? new StarRatingDisplay(beatmapInfo) + { + Margin = new MarginPadding { Bottom = 5 } + } + : Empty(); + private void setMetadata(string source) { ArtistLabel.Text = artistBinding.Value; From 8b7446c43f1a53bbf83804486289ee6e42c5ec8e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 31 Aug 2020 18:13:51 +0900 Subject: [PATCH 187/320] Fix RollingCounter not updating initial value if changed before loaded --- osu.Game/Graphics/UserInterface/RollingCounter.cs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/RollingCounter.cs b/osu.Game/Graphics/UserInterface/RollingCounter.cs index 6763198213..ceb388600e 100644 --- a/osu.Game/Graphics/UserInterface/RollingCounter.cs +++ b/osu.Game/Graphics/UserInterface/RollingCounter.cs @@ -65,12 +65,6 @@ namespace osu.Game.Graphics.UserInterface protected RollingCounter() { AutoSizeAxes = Axes.Both; - - Current.ValueChanged += val => - { - if (IsLoaded) - TransformCount(DisplayedCount, val.NewValue); - }; } [BackgroundDependencyLoader] @@ -81,6 +75,13 @@ namespace osu.Game.Graphics.UserInterface Child = displayedCountSpriteText; } + protected override void LoadComplete() + { + base.LoadComplete(); + + Current.BindValueChanged(val => TransformCount(DisplayedCount, val.NewValue), true); + } + /// /// Sets count value, bypassing rollover animation. /// From a171d0e292be37a8c85d1f5e40b933f9d07b7619 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 31 Aug 2020 18:14:22 +0900 Subject: [PATCH 188/320] Remove unused methods and classes --- .../UserInterface/PercentageCounter.cs | 5 --- .../Graphics/UserInterface/RollingCounter.cs | 2 -- .../Graphics/UserInterface/ScoreCounter.cs | 5 --- .../UserInterface/SimpleComboCounter.cs | 5 --- .../Screens/Play/HUD/ComboResultCounter.cs | 32 ------------------- .../Expanded/Statistics/AccuracyStatistic.cs | 3 -- .../Expanded/Statistics/CounterStatistic.cs | 3 -- .../Ranking/Expanded/TotalScoreCounter.cs | 3 -- 8 files changed, 58 deletions(-) delete mode 100644 osu.Game/Screens/Play/HUD/ComboResultCounter.cs diff --git a/osu.Game/Graphics/UserInterface/PercentageCounter.cs b/osu.Game/Graphics/UserInterface/PercentageCounter.cs index 3ea9c1053c..1ccf7798e5 100644 --- a/osu.Game/Graphics/UserInterface/PercentageCounter.cs +++ b/osu.Game/Graphics/UserInterface/PercentageCounter.cs @@ -40,10 +40,5 @@ namespace osu.Game.Graphics.UserInterface protected override OsuSpriteText CreateSpriteText() => base.CreateSpriteText().With(s => s.Font = s.Font.With(size: 20f, fixedWidth: true)); - - public override void Increment(double amount) - { - Current.Value += amount; - } } } diff --git a/osu.Game/Graphics/UserInterface/RollingCounter.cs b/osu.Game/Graphics/UserInterface/RollingCounter.cs index ceb388600e..ece1b8e22c 100644 --- a/osu.Game/Graphics/UserInterface/RollingCounter.cs +++ b/osu.Game/Graphics/UserInterface/RollingCounter.cs @@ -57,8 +57,6 @@ namespace osu.Game.Graphics.UserInterface } } - public abstract void Increment(T amount); - /// /// Skeleton of a numeric counter which value rolls over time. /// diff --git a/osu.Game/Graphics/UserInterface/ScoreCounter.cs b/osu.Game/Graphics/UserInterface/ScoreCounter.cs index faabe69f87..73bbe5f03e 100644 --- a/osu.Game/Graphics/UserInterface/ScoreCounter.cs +++ b/osu.Game/Graphics/UserInterface/ScoreCounter.cs @@ -51,10 +51,5 @@ namespace osu.Game.Graphics.UserInterface protected override OsuSpriteText CreateSpriteText() => base.CreateSpriteText().With(s => s.Font = s.Font.With(fixedWidth: true)); - - public override void Increment(double amount) - { - Current.Value += amount; - } } } diff --git a/osu.Game/Graphics/UserInterface/SimpleComboCounter.cs b/osu.Game/Graphics/UserInterface/SimpleComboCounter.cs index aac0166774..c9790aed46 100644 --- a/osu.Game/Graphics/UserInterface/SimpleComboCounter.cs +++ b/osu.Game/Graphics/UserInterface/SimpleComboCounter.cs @@ -33,11 +33,6 @@ namespace osu.Game.Graphics.UserInterface return Math.Abs(currentValue - newValue) * RollingDuration * 100.0f; } - public override void Increment(int amount) - { - Current.Value += amount; - } - protected override OsuSpriteText CreateSpriteText() => base.CreateSpriteText().With(s => s.Font = s.Font.With(size: 20f)); } diff --git a/osu.Game/Screens/Play/HUD/ComboResultCounter.cs b/osu.Game/Screens/Play/HUD/ComboResultCounter.cs deleted file mode 100644 index 7ae8bc0ddf..0000000000 --- a/osu.Game/Screens/Play/HUD/ComboResultCounter.cs +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using osu.Framework.Graphics; -using osu.Game.Graphics.UserInterface; - -namespace osu.Game.Screens.Play.HUD -{ - /// - /// Used to display combo with a roll-up animation in results screen. - /// - public class ComboResultCounter : RollingCounter - { - protected override double RollingDuration => 500; - protected override Easing RollingEasing => Easing.Out; - - protected override double GetProportionalDuration(long currentValue, long newValue) - { - return currentValue > newValue ? currentValue - newValue : newValue - currentValue; - } - - protected override string FormatCount(long count) - { - return $@"{count}x"; - } - - public override void Increment(long amount) - { - Current.Value += amount; - } - } -} diff --git a/osu.Game/Screens/Ranking/Expanded/Statistics/AccuracyStatistic.cs b/osu.Game/Screens/Ranking/Expanded/Statistics/AccuracyStatistic.cs index 6933456e7e..288a107874 100644 --- a/osu.Game/Screens/Ranking/Expanded/Statistics/AccuracyStatistic.cs +++ b/osu.Game/Screens/Ranking/Expanded/Statistics/AccuracyStatistic.cs @@ -46,9 +46,6 @@ namespace osu.Game.Screens.Ranking.Expanded.Statistics protected override string FormatCount(double count) => count.FormatAccuracy(); - public override void Increment(double amount) - => Current.Value += amount; - protected override OsuSpriteText CreateSpriteText() => base.CreateSpriteText().With(s => { s.Font = OsuFont.Torus.With(size: 20, fixedWidth: true); diff --git a/osu.Game/Screens/Ranking/Expanded/Statistics/CounterStatistic.cs b/osu.Game/Screens/Ranking/Expanded/Statistics/CounterStatistic.cs index 043a560d12..e820831809 100644 --- a/osu.Game/Screens/Ranking/Expanded/Statistics/CounterStatistic.cs +++ b/osu.Game/Screens/Ranking/Expanded/Statistics/CounterStatistic.cs @@ -49,9 +49,6 @@ namespace osu.Game.Screens.Ranking.Expanded.Statistics s.Font = OsuFont.Torus.With(size: 20, fixedWidth: true); s.Spacing = new Vector2(-2, 0); }); - - public override void Increment(int amount) - => Current.Value += amount; } } } diff --git a/osu.Game/Screens/Ranking/Expanded/TotalScoreCounter.cs b/osu.Game/Screens/Ranking/Expanded/TotalScoreCounter.cs index 7f6fd1eabe..65082d3fae 100644 --- a/osu.Game/Screens/Ranking/Expanded/TotalScoreCounter.cs +++ b/osu.Game/Screens/Ranking/Expanded/TotalScoreCounter.cs @@ -36,8 +36,5 @@ namespace osu.Game.Screens.Ranking.Expanded s.Font = OsuFont.Torus.With(size: 60, weight: FontWeight.Light, fixedWidth: true); s.Spacing = new Vector2(-5, 0); }); - - public override void Increment(long amount) - => Current.Value += amount; } } From dd093f44d8826af623ed5232e6a38d8f39b0ce20 Mon Sep 17 00:00:00 2001 From: Lucas A Date: Mon, 31 Aug 2020 11:16:13 +0200 Subject: [PATCH 189/320] Cast base immutable bindable to mutable for testing purposes and make InitialOverlayActivationMode property protected --- osu.Game.Tests/Visual/Menus/TestSceneToolbar.cs | 7 +------ osu.Game/Screens/OsuScreen.cs | 2 +- osu.Game/Screens/Play/Player.cs | 2 +- osu.Game/Screens/StartupScreen.cs | 2 +- 4 files changed, 4 insertions(+), 9 deletions(-) diff --git a/osu.Game.Tests/Visual/Menus/TestSceneToolbar.cs b/osu.Game.Tests/Visual/Menus/TestSceneToolbar.cs index 841860accb..2a4486812c 100644 --- a/osu.Game.Tests/Visual/Menus/TestSceneToolbar.cs +++ b/osu.Game.Tests/Visual/Menus/TestSceneToolbar.cs @@ -91,12 +91,7 @@ namespace osu.Game.Tests.Visual.Menus public class TestToolbar : Toolbar { - public TestToolbar() - { - base.OverlayActivationMode.BindTo(OverlayActivationMode); - } - - public new Bindable OverlayActivationMode { get; } = new Bindable(OverlayActivation.All); + public new Bindable OverlayActivationMode => base.OverlayActivationMode as Bindable; } } } diff --git a/osu.Game/Screens/OsuScreen.cs b/osu.Game/Screens/OsuScreen.cs index c687c34ce9..c10deaf1e5 100644 --- a/osu.Game/Screens/OsuScreen.cs +++ b/osu.Game/Screens/OsuScreen.cs @@ -46,7 +46,7 @@ namespace osu.Game.Screens /// /// The initial initial overlay activation mode to use when this screen is entered for the first time. /// - public virtual OverlayActivation InitialOverlayActivationMode => OverlayActivation.All; + protected virtual OverlayActivation InitialOverlayActivationMode => OverlayActivation.All; public Bindable OverlayActivationMode { get; } diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 541275cf55..0a5158c6dc 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -50,7 +50,7 @@ namespace osu.Game.Screens.Play public override bool HideOverlaysOnEnter => true; - public override OverlayActivation InitialOverlayActivationMode => OverlayActivation.UserTriggered; + protected override OverlayActivation InitialOverlayActivationMode => OverlayActivation.UserTriggered; /// /// Whether gameplay should pause when the game window focus is lost. diff --git a/osu.Game/Screens/StartupScreen.cs b/osu.Game/Screens/StartupScreen.cs index c3e36c8e9d..e5e134fd39 100644 --- a/osu.Game/Screens/StartupScreen.cs +++ b/osu.Game/Screens/StartupScreen.cs @@ -18,6 +18,6 @@ namespace osu.Game.Screens public override bool AllowRateAdjustments => false; - public override OverlayActivation InitialOverlayActivationMode => OverlayActivation.Disabled; + protected override OverlayActivation InitialOverlayActivationMode => OverlayActivation.Disabled; } } From d419fe4dbf5f54edddd67cfb4507150ae43c2f8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Mon, 31 Aug 2020 12:02:02 +0200 Subject: [PATCH 190/320] Remove note shaking mention that doesn't apply in mania --- .../Objects/Drawables/DrawableManiaHitObject.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs index e16413bce7..08c41b0d75 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs @@ -38,7 +38,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables /// /// Whether this can be hit, given a time value. - /// If non-null, judgements will be ignored (resulting in a shake) whilst the function returns false. + /// If non-null, judgements will be ignored whilst the function returns false. /// public Func CheckHittable; From ed74c39b5587e2084dd9fe957aef6d4e9f422644 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 31 Aug 2020 19:54:22 +0900 Subject: [PATCH 191/320] Move UserTopScoreContainer into base leaderboard --- .../SongSelect/TestSceneBeatmapLeaderboard.cs | 61 ++++++------- .../TestSceneUserTopScoreContainer.cs | 91 +++++++++---------- .../API/Requests/Responses/APILegacyScores.cs | 9 ++ osu.Game/Online/Leaderboards/Leaderboard.cs | 21 ++++- .../Leaderboards/UserTopScoreContainer.cs | 26 ++---- .../Match/Components/MatchLeaderboard.cs | 2 + .../Select/Leaderboards/BeatmapLeaderboard.cs | 30 ++---- 7 files changed, 114 insertions(+), 126 deletions(-) rename osu.Game/{Screens/Select => Online}/Leaderboards/UserTopScoreContainer.cs (77%) diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapLeaderboard.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapLeaderboard.cs index 48b718c04d..67cd720260 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapLeaderboard.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapLeaderboard.cs @@ -5,9 +5,9 @@ using System; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Game.Beatmaps; -using osu.Game.Online.API.Requests.Responses; using osu.Game.Online.Leaderboards; using osu.Game.Overlays; +using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Osu.Mods; using osu.Game.Scoring; using osu.Game.Screens.Select.Leaderboards; @@ -53,53 +53,46 @@ namespace osu.Game.Tests.Visual.SongSelect private void showPersonalBestWithNullPosition() { - leaderboard.TopScore = new APILegacyUserTopScoreInfo + leaderboard.TopScore = new ScoreInfo { - Position = null, - Score = new APILegacyScoreInfo + Rank = ScoreRank.XH, + Accuracy = 1, + MaxCombo = 244, + TotalScore = 1707827, + Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock() }, + User = new User { - Rank = ScoreRank.XH, - Accuracy = 1, - MaxCombo = 244, - TotalScore = 1707827, - Mods = new[] { new OsuModHidden().Acronym, new OsuModHardRock().Acronym, }, - User = new User + Id = 6602580, + Username = @"waaiiru", + Country = new Country { - Id = 6602580, - Username = @"waaiiru", - Country = new Country - { - FullName = @"Spain", - FlagName = @"ES", - }, + FullName = @"Spain", + FlagName = @"ES", }, - } + }, }; } private void showPersonalBest() { - leaderboard.TopScore = new APILegacyUserTopScoreInfo + leaderboard.TopScore = new ScoreInfo { Position = 999, - Score = new APILegacyScoreInfo + Rank = ScoreRank.XH, + Accuracy = 1, + MaxCombo = 244, + TotalScore = 1707827, + Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), }, + User = new User { - Rank = ScoreRank.XH, - Accuracy = 1, - MaxCombo = 244, - TotalScore = 1707827, - Mods = new[] { new OsuModHidden().Acronym, new OsuModHardRock().Acronym, }, - User = new User + Id = 6602580, + Username = @"waaiiru", + Country = new Country { - Id = 6602580, - Username = @"waaiiru", - Country = new Country - { - FullName = @"Spain", - FlagName = @"ES", - }, + FullName = @"Spain", + FlagName = @"ES", }, - } + }, }; } diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneUserTopScoreContainer.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneUserTopScoreContainer.cs index 0598324110..b8b8792b9b 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestSceneUserTopScoreContainer.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestSceneUserTopScoreContainer.cs @@ -6,11 +6,11 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osuTK.Graphics; -using osu.Game.Online.API.Requests.Responses; +using osu.Game.Online.Leaderboards; using osu.Game.Overlays; +using osu.Game.Rulesets.Mods; using osu.Game.Scoring; using osu.Game.Rulesets.Osu.Mods; -using osu.Game.Screens.Select.Leaderboards; using osu.Game.Users; namespace osu.Game.Tests.Visual.SongSelect @@ -22,7 +22,7 @@ namespace osu.Game.Tests.Visual.SongSelect public TestSceneUserTopScoreContainer() { - UserTopScoreContainer topScoreContainer; + UserTopScoreContainer topScoreContainer; Add(dialogOverlay = new DialogOverlay { @@ -42,7 +42,7 @@ namespace osu.Game.Tests.Visual.SongSelect RelativeSizeAxes = Axes.Both, Colour = Color4.DarkGreen, }, - topScoreContainer = new UserTopScoreContainer + topScoreContainer = new UserTopScoreContainer(s => new LeaderboardScore(s, s.Position, false)) { Origin = Anchor.BottomCentre, Anchor = Anchor.BottomCentre, @@ -52,69 +52,60 @@ namespace osu.Game.Tests.Visual.SongSelect var scores = new[] { - new APILegacyUserTopScoreInfo + new ScoreInfo { Position = 999, - Score = new APILegacyScoreInfo + Rank = ScoreRank.XH, + Accuracy = 1, + MaxCombo = 244, + TotalScore = 1707827, + Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), }, + User = new User { - Rank = ScoreRank.XH, - Accuracy = 1, - MaxCombo = 244, - TotalScore = 1707827, - Mods = new[] { new OsuModHidden().Acronym, new OsuModHardRock().Acronym, }, - User = new User + Id = 6602580, + Username = @"waaiiru", + Country = new Country { - Id = 6602580, - Username = @"waaiiru", - Country = new Country - { - FullName = @"Spain", - FlagName = @"ES", - }, + FullName = @"Spain", + FlagName = @"ES", }, - } + }, }, - new APILegacyUserTopScoreInfo + new ScoreInfo { Position = 110000, - Score = new APILegacyScoreInfo + Rank = ScoreRank.X, + Accuracy = 1, + MaxCombo = 244, + TotalScore = 1707827, + User = new User { - Rank = ScoreRank.X, - Accuracy = 1, - MaxCombo = 244, - TotalScore = 1707827, - User = new User + Id = 4608074, + Username = @"Skycries", + Country = new Country { - Id = 4608074, - Username = @"Skycries", - Country = new Country - { - FullName = @"Brazil", - FlagName = @"BR", - }, + FullName = @"Brazil", + FlagName = @"BR", }, - } + }, }, - new APILegacyUserTopScoreInfo + new ScoreInfo { Position = 22333, - Score = new APILegacyScoreInfo + Rank = ScoreRank.S, + Accuracy = 1, + MaxCombo = 244, + TotalScore = 1707827, + User = new User { - Rank = ScoreRank.S, - Accuracy = 1, - MaxCombo = 244, - TotalScore = 1707827, - User = new User + Id = 1541390, + Username = @"Toukai", + Country = new Country { - Id = 1541390, - Username = @"Toukai", - Country = new Country - { - FullName = @"Canada", - FlagName = @"CA", - }, + FullName = @"Canada", + FlagName = @"CA", }, - } + }, } }; diff --git a/osu.Game/Online/API/Requests/Responses/APILegacyScores.cs b/osu.Game/Online/API/Requests/Responses/APILegacyScores.cs index 75be9171b0..009639c1dc 100644 --- a/osu.Game/Online/API/Requests/Responses/APILegacyScores.cs +++ b/osu.Game/Online/API/Requests/Responses/APILegacyScores.cs @@ -3,6 +3,8 @@ using System.Collections.Generic; using Newtonsoft.Json; +using osu.Game.Rulesets; +using osu.Game.Scoring; namespace osu.Game.Online.API.Requests.Responses { @@ -22,5 +24,12 @@ namespace osu.Game.Online.API.Requests.Responses [JsonProperty(@"score")] public APILegacyScoreInfo Score; + + public ScoreInfo CreateScoreInfo(RulesetStore rulesets) + { + var score = Score.CreateScoreInfo(rulesets); + score.Position = Position; + return score; + } } } diff --git a/osu.Game/Online/Leaderboards/Leaderboard.cs b/osu.Game/Online/Leaderboards/Leaderboard.cs index 800029ceb9..003d90d400 100644 --- a/osu.Game/Online/Leaderboards/Leaderboard.cs +++ b/osu.Game/Online/Leaderboards/Leaderboard.cs @@ -27,6 +27,7 @@ namespace osu.Game.Online.Leaderboards private readonly OsuScrollContainer scrollContainer; private readonly Container placeholderContainer; + private readonly UserTopScoreContainer topScoreContainer; private FillFlowContainer scrollFlow; @@ -87,6 +88,21 @@ namespace osu.Game.Online.Leaderboards } } + public TScoreInfo TopScore + { + get => topScoreContainer.Score.Value; + set + { + if (value == null) + topScoreContainer.Hide(); + else + { + topScoreContainer.Show(); + topScoreContainer.Score.Value = value; + } + } + } + protected virtual FillFlowContainer CreateScoreFlow() => new FillFlowContainer { @@ -198,8 +214,9 @@ namespace osu.Game.Online.Leaderboards { AutoSizeAxes = Axes.Y, RelativeSizeAxes = Axes.X, + Child = topScoreContainer = new UserTopScoreContainer(CreateDrawableTopScore) }, - } + }, }, }, }, @@ -367,5 +384,7 @@ namespace osu.Game.Online.Leaderboards } protected abstract LeaderboardScore CreateDrawableScore(TScoreInfo model, int index); + + protected abstract LeaderboardScore CreateDrawableTopScore(TScoreInfo model); } } diff --git a/osu.Game/Screens/Select/Leaderboards/UserTopScoreContainer.cs b/osu.Game/Online/Leaderboards/UserTopScoreContainer.cs similarity index 77% rename from osu.Game/Screens/Select/Leaderboards/UserTopScoreContainer.cs rename to osu.Game/Online/Leaderboards/UserTopScoreContainer.cs index 8e10734454..ffa7fa2c0b 100644 --- a/osu.Game/Screens/Select/Leaderboards/UserTopScoreContainer.cs +++ b/osu.Game/Online/Leaderboards/UserTopScoreContainer.cs @@ -9,31 +9,28 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; -using osu.Game.Online.API.Requests.Responses; -using osu.Game.Online.Leaderboards; using osu.Game.Rulesets; -using osu.Game.Scoring; using osuTK; -namespace osu.Game.Screens.Select.Leaderboards +namespace osu.Game.Online.Leaderboards { - public class UserTopScoreContainer : VisibilityContainer + public class UserTopScoreContainer : VisibilityContainer { private const int duration = 500; + public Bindable Score = new Bindable(); + private readonly Container scoreContainer; - - public Bindable Score = new Bindable(); - - public Action ScoreSelected; + private readonly Func createScoreDelegate; protected override bool StartHidden => true; [Resolved] private RulesetStore rulesets { get; set; } - public UserTopScoreContainer() + public UserTopScoreContainer(Func createScoreDelegate) { + this.createScoreDelegate = createScoreDelegate; RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; @@ -72,7 +69,7 @@ namespace osu.Game.Screens.Select.Leaderboards private CancellationTokenSource loadScoreCancellation; - private void onScoreChanged(ValueChangedEvent score) + private void onScoreChanged(ValueChangedEvent score) { var newScore = score.NewValue; @@ -82,12 +79,7 @@ namespace osu.Game.Screens.Select.Leaderboards if (newScore == null) return; - var scoreInfo = newScore.Score.CreateScoreInfo(rulesets); - - LoadComponentAsync(new LeaderboardScore(scoreInfo, newScore.Position, false) - { - Action = () => ScoreSelected?.Invoke(scoreInfo) - }, drawableScore => + LoadComponentAsync(createScoreDelegate(newScore), drawableScore => { scoreContainer.Child = drawableScore; drawableScore.FadeInFromZero(duration, Easing.OutQuint); diff --git a/osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs b/osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs index 1afbf5c32a..01137dad43 100644 --- a/osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs +++ b/osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs @@ -51,6 +51,8 @@ namespace osu.Game.Screens.Multi.Match.Components } protected override LeaderboardScore CreateDrawableScore(APIUserScoreAggregate model, int index) => new MatchLeaderboardScore(model, index); + + protected override LeaderboardScore CreateDrawableTopScore(APIUserScoreAggregate model) => new MatchLeaderboardScore(model, 0); } public enum MatchLeaderboardScope diff --git a/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs b/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs index 8e85eb4eb2..a78d8e3be0 100644 --- a/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs +++ b/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs @@ -9,7 +9,6 @@ using osu.Framework.Bindables; using osu.Game.Beatmaps; using osu.Game.Online.API; using osu.Game.Online.API.Requests; -using osu.Game.Online.API.Requests.Responses; using osu.Game.Online.Leaderboards; using osu.Game.Rulesets; using osu.Game.Rulesets.Mods; @@ -41,25 +40,8 @@ namespace osu.Game.Screens.Select.Leaderboards } } - public APILegacyUserTopScoreInfo TopScore - { - get => topScoreContainer.Score.Value; - set - { - if (value == null) - topScoreContainer.Hide(); - else - { - topScoreContainer.Show(); - topScoreContainer.Score.Value = value; - } - } - } - private bool filterMods; - private UserTopScoreContainer topScoreContainer; - private IBindable> itemRemoved; /// @@ -101,11 +83,6 @@ namespace osu.Game.Screens.Select.Leaderboards UpdateScores(); }; - Content.Add(topScoreContainer = new UserTopScoreContainer - { - ScoreSelected = s => ScoreSelected?.Invoke(s) - }); - itemRemoved = scoreManager.ItemRemoved.GetBoundCopy(); itemRemoved.BindValueChanged(onScoreRemoved); } @@ -183,7 +160,7 @@ namespace osu.Game.Screens.Select.Leaderboards req.Success += r => { scoresCallback?.Invoke(r.Scores.Select(s => s.CreateScoreInfo(rulesets))); - TopScore = r.UserScore; + TopScore = r.UserScore.CreateScoreInfo(rulesets); }; return req; @@ -193,5 +170,10 @@ namespace osu.Game.Screens.Select.Leaderboards { Action = () => ScoreSelected?.Invoke(model) }; + + protected override LeaderboardScore CreateDrawableTopScore(ScoreInfo model) => new LeaderboardScore(model, model.Position, false) + { + Action = () => ScoreSelected?.Invoke(model) + }; } } From d1ceb81797a8bd19b931f3816c26502673b0d8be Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 31 Aug 2020 19:54:41 +0900 Subject: [PATCH 192/320] Rename request --- ...GetRoomScoresRequest.cs => GetRoomLeaderboardRequest.cs} | 6 ++---- osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) rename osu.Game/Online/Multiplayer/{GetRoomScoresRequest.cs => GetRoomLeaderboardRequest.cs} (65%) diff --git a/osu.Game/Online/Multiplayer/GetRoomScoresRequest.cs b/osu.Game/Online/Multiplayer/GetRoomLeaderboardRequest.cs similarity index 65% rename from osu.Game/Online/Multiplayer/GetRoomScoresRequest.cs rename to osu.Game/Online/Multiplayer/GetRoomLeaderboardRequest.cs index bc913030dd..37c21457bc 100644 --- a/osu.Game/Online/Multiplayer/GetRoomScoresRequest.cs +++ b/osu.Game/Online/Multiplayer/GetRoomLeaderboardRequest.cs @@ -1,17 +1,15 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System.Collections.Generic; using osu.Game.Online.API; -using osu.Game.Online.API.Requests.Responses; namespace osu.Game.Online.Multiplayer { - public class GetRoomScoresRequest : APIRequest> + public class GetRoomLeaderboardRequest : APIRequest { private readonly int roomId; - public GetRoomScoresRequest(int roomId) + public GetRoomLeaderboardRequest(int roomId) { this.roomId = roomId; } diff --git a/osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs b/osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs index 01137dad43..56381dccb6 100644 --- a/osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs +++ b/osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs @@ -39,7 +39,7 @@ namespace osu.Game.Screens.Multi.Match.Components if (roomId.Value == null) return null; - var req = new GetRoomScoresRequest(roomId.Value ?? 0); + var req = new GetRoomLeaderboardRequest(roomId.Value ?? 0); req.Success += r => { From 77698ec31e8cae2550c2dac2d68bae51ab2805a6 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 31 Aug 2020 19:54:57 +0900 Subject: [PATCH 193/320] Add support for showing own top score in timeshift --- osu.Game/Online/Multiplayer/APILeaderboard.cs | 18 ++++++++++++++++++ .../Multi/Match/Components/MatchLeaderboard.cs | 6 ++---- 2 files changed, 20 insertions(+), 4 deletions(-) create mode 100644 osu.Game/Online/Multiplayer/APILeaderboard.cs diff --git a/osu.Game/Online/Multiplayer/APILeaderboard.cs b/osu.Game/Online/Multiplayer/APILeaderboard.cs new file mode 100644 index 0000000000..96fe7cefb0 --- /dev/null +++ b/osu.Game/Online/Multiplayer/APILeaderboard.cs @@ -0,0 +1,18 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Collections.Generic; +using Newtonsoft.Json; +using osu.Game.Online.API.Requests.Responses; + +namespace osu.Game.Online.Multiplayer +{ + public class APILeaderboard + { + [JsonProperty("leaderboard")] + public List Leaderboard; + + [JsonProperty("own_score")] + public APIUserScoreAggregate OwnScore; + } +} diff --git a/osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs b/osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs index 56381dccb6..847f3a7b55 100644 --- a/osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs +++ b/osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs @@ -14,8 +14,6 @@ namespace osu.Game.Screens.Multi.Match.Components { public class MatchLeaderboard : Leaderboard { - public Action> ScoresLoaded; - [Resolved(typeof(Room), nameof(Room.RoomID))] private Bindable roomId { get; set; } @@ -43,8 +41,8 @@ namespace osu.Game.Screens.Multi.Match.Components req.Success += r => { - scoresCallback?.Invoke(r); - ScoresLoaded?.Invoke(r); + scoresCallback?.Invoke(r.Leaderboard); + TopScore = r.OwnScore; }; return req; From 6ed191786f978e3b6bb943bc8e33633ac17ff80e Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 31 Aug 2020 20:01:59 +0900 Subject: [PATCH 194/320] Add support for position --- .../Online/API/Requests/Responses/APIUserScoreAggregate.cs | 4 ++++ osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/osu.Game/Online/API/Requests/Responses/APIUserScoreAggregate.cs b/osu.Game/Online/API/Requests/Responses/APIUserScoreAggregate.cs index 0bba6a93bd..bcc8721400 100644 --- a/osu.Game/Online/API/Requests/Responses/APIUserScoreAggregate.cs +++ b/osu.Game/Online/API/Requests/Responses/APIUserScoreAggregate.cs @@ -33,6 +33,9 @@ namespace osu.Game.Online.API.Requests.Responses [JsonProperty("user")] public User User { get; set; } + [JsonProperty("position")] + public int? Position { get; set; } + public ScoreInfo CreateScoreInfo() => new ScoreInfo { @@ -40,6 +43,7 @@ namespace osu.Game.Online.API.Requests.Responses PP = PP, TotalScore = TotalScore, User = User, + Position = Position }; } } diff --git a/osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs b/osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs index 847f3a7b55..7d5968202c 100644 --- a/osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs +++ b/osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs @@ -50,7 +50,7 @@ namespace osu.Game.Screens.Multi.Match.Components protected override LeaderboardScore CreateDrawableScore(APIUserScoreAggregate model, int index) => new MatchLeaderboardScore(model, index); - protected override LeaderboardScore CreateDrawableTopScore(APIUserScoreAggregate model) => new MatchLeaderboardScore(model, 0); + protected override LeaderboardScore CreateDrawableTopScore(APIUserScoreAggregate model) => new MatchLeaderboardScore(model, model.Position ?? 0); } public enum MatchLeaderboardScope From d22de26afb354e82769fd2ffdd3a587ae1a32f04 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 31 Aug 2020 20:08:36 +0900 Subject: [PATCH 195/320] Add whitespace --- osu.Game/Online/Leaderboards/UserTopScoreContainer.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Online/Leaderboards/UserTopScoreContainer.cs b/osu.Game/Online/Leaderboards/UserTopScoreContainer.cs index ffa7fa2c0b..ab4210251e 100644 --- a/osu.Game/Online/Leaderboards/UserTopScoreContainer.cs +++ b/osu.Game/Online/Leaderboards/UserTopScoreContainer.cs @@ -31,6 +31,7 @@ namespace osu.Game.Online.Leaderboards public UserTopScoreContainer(Func createScoreDelegate) { this.createScoreDelegate = createScoreDelegate; + RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; From 8cf26979fb11ec81199cf87378b20134a809d816 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 31 Aug 2020 20:16:28 +0900 Subject: [PATCH 196/320] Allow null user score --- osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs b/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs index a78d8e3be0..8ddae67dba 100644 --- a/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs +++ b/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs @@ -160,7 +160,7 @@ namespace osu.Game.Screens.Select.Leaderboards req.Success += r => { scoresCallback?.Invoke(r.Scores.Select(s => s.CreateScoreInfo(rulesets))); - TopScore = r.UserScore.CreateScoreInfo(rulesets); + TopScore = r.UserScore?.CreateScoreInfo(rulesets); }; return req; From 61d580b6ba9841793e81600d0c228ea7848bff3e Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 31 Aug 2020 20:17:23 +0900 Subject: [PATCH 197/320] Don't highlight top score --- osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs | 2 +- .../Screens/Multi/Match/Components/MatchLeaderboardScore.cs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs b/osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs index 7d5968202c..50afbb39fe 100644 --- a/osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs +++ b/osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs @@ -50,7 +50,7 @@ namespace osu.Game.Screens.Multi.Match.Components protected override LeaderboardScore CreateDrawableScore(APIUserScoreAggregate model, int index) => new MatchLeaderboardScore(model, index); - protected override LeaderboardScore CreateDrawableTopScore(APIUserScoreAggregate model) => new MatchLeaderboardScore(model, model.Position ?? 0); + protected override LeaderboardScore CreateDrawableTopScore(APIUserScoreAggregate model) => new MatchLeaderboardScore(model, model.Position ?? 0, false); } public enum MatchLeaderboardScope diff --git a/osu.Game/Screens/Multi/Match/Components/MatchLeaderboardScore.cs b/osu.Game/Screens/Multi/Match/Components/MatchLeaderboardScore.cs index 73a40d9579..c4e2b332b3 100644 --- a/osu.Game/Screens/Multi/Match/Components/MatchLeaderboardScore.cs +++ b/osu.Game/Screens/Multi/Match/Components/MatchLeaderboardScore.cs @@ -14,8 +14,8 @@ namespace osu.Game.Screens.Multi.Match.Components { private readonly APIUserScoreAggregate score; - public MatchLeaderboardScore(APIUserScoreAggregate score, int rank) - : base(score.CreateScoreInfo(), rank) + public MatchLeaderboardScore(APIUserScoreAggregate score, int rank, bool allowHighlight = true) + : base(score.CreateScoreInfo(), rank, allowHighlight) { this.score = score; } From 5e77e8cfcf74e642c2076773799ab355097fa22b Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 31 Aug 2020 20:21:57 +0900 Subject: [PATCH 198/320] Reduce min size of chat --- osu.Game/Screens/Multi/Match/MatchSubScreen.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Multi/Match/MatchSubScreen.cs b/osu.Game/Screens/Multi/Match/MatchSubScreen.cs index 7c2d5cf85d..0d2adeb27c 100644 --- a/osu.Game/Screens/Multi/Match/MatchSubScreen.cs +++ b/osu.Game/Screens/Multi/Match/MatchSubScreen.cs @@ -172,7 +172,7 @@ namespace osu.Game.Screens.Multi.Match new Dimension(GridSizeMode.AutoSize), new Dimension(), new Dimension(GridSizeMode.AutoSize), - new Dimension(GridSizeMode.Relative, size: 0.4f, minSize: 240), + new Dimension(GridSizeMode.Relative, size: 0.4f, minSize: 120), } }, null From 3b22b891d13e9d53d0266d234363dfd2362436c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Mon, 31 Aug 2020 14:28:45 +0200 Subject: [PATCH 199/320] Add failing test cases --- .../NonVisual/Ranking/UnstableRateTest.cs | 43 +++++++++++++++++++ .../Ranking/Statistics/SimpleStatisticItem.cs | 9 +++- 2 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 osu.Game.Tests/NonVisual/Ranking/UnstableRateTest.cs diff --git a/osu.Game.Tests/NonVisual/Ranking/UnstableRateTest.cs b/osu.Game.Tests/NonVisual/Ranking/UnstableRateTest.cs new file mode 100644 index 0000000000..bf4145754a --- /dev/null +++ b/osu.Game.Tests/NonVisual/Ranking/UnstableRateTest.cs @@ -0,0 +1,43 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System; +using System.Linq; +using NUnit.Framework; +using osu.Framework.Utils; +using osu.Game.Rulesets.Objects; +using osu.Game.Rulesets.Scoring; +using osu.Game.Screens.Ranking.Statistics; + +namespace osu.Game.Tests.NonVisual.Ranking +{ + [TestFixture] + public class UnstableRateTest + { + [Test] + public void TestDistributedHits() + { + var events = Enumerable.Range(-5, 11) + .Select(t => new HitEvent(t - 5, HitResult.Great, new HitObject(), null, null)); + + var unstableRate = new UnstableRate(events); + + Assert.IsTrue(Precision.AlmostEquals(unstableRate.Value, 10 * Math.Sqrt(10))); + } + + [Test] + public void TestMissesAndEmptyWindows() + { + var events = new[] + { + new HitEvent(-100, HitResult.Miss, new HitObject(), null, null), + new HitEvent(0, HitResult.Great, new HitObject(), null, null), + new HitEvent(200, HitResult.Meh, new HitObject { HitWindows = HitWindows.Empty }, null, null), + }; + + var unstableRate = new UnstableRate(events); + + Assert.IsTrue(Precision.AlmostEquals(0, unstableRate.Value)); + } + } +} diff --git a/osu.Game/Screens/Ranking/Statistics/SimpleStatisticItem.cs b/osu.Game/Screens/Ranking/Statistics/SimpleStatisticItem.cs index 3d9ba2f225..6fe7e4eda8 100644 --- a/osu.Game/Screens/Ranking/Statistics/SimpleStatisticItem.cs +++ b/osu.Game/Screens/Ranking/Statistics/SimpleStatisticItem.cs @@ -59,12 +59,19 @@ namespace osu.Game.Screens.Ranking.Statistics /// public class SimpleStatisticItem : SimpleStatisticItem { + private TValue value; + /// /// The statistic's value to be displayed. /// public new TValue Value { - set => base.Value = DisplayValue(value); + get => value; + set + { + this.value = value; + base.Value = DisplayValue(value); + } } /// From 3ca2a7767a04d2911d8244bb1d2755747e099a45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Mon, 31 Aug 2020 14:29:01 +0200 Subject: [PATCH 200/320] Exclude misses and empty window hits from UR calculation --- osu.Game/Screens/Ranking/Statistics/UnstableRate.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Ranking/Statistics/UnstableRate.cs b/osu.Game/Screens/Ranking/Statistics/UnstableRate.cs index 5b368c3e8d..18a2238784 100644 --- a/osu.Game/Screens/Ranking/Statistics/UnstableRate.cs +++ b/osu.Game/Screens/Ranking/Statistics/UnstableRate.cs @@ -20,7 +20,8 @@ namespace osu.Game.Screens.Ranking.Statistics public UnstableRate(IEnumerable hitEvents) : base("Unstable Rate") { - var timeOffsets = hitEvents.Select(ev => ev.TimeOffset).ToArray(); + var timeOffsets = hitEvents.Where(e => !(e.HitObject.HitWindows is HitWindows.EmptyHitWindows) && e.Result != HitResult.Miss) + .Select(ev => ev.TimeOffset).ToArray(); Value = 10 * standardDeviation(timeOffsets); } From 0980f97ea2c8da99030f6f9d7b16425c35865ba5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Mon, 31 Aug 2020 16:06:24 +0200 Subject: [PATCH 201/320] Replace precision check with absolute equality assert --- osu.Game.Tests/NonVisual/Ranking/UnstableRateTest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Tests/NonVisual/Ranking/UnstableRateTest.cs b/osu.Game.Tests/NonVisual/Ranking/UnstableRateTest.cs index bf4145754a..ad6f01881b 100644 --- a/osu.Game.Tests/NonVisual/Ranking/UnstableRateTest.cs +++ b/osu.Game.Tests/NonVisual/Ranking/UnstableRateTest.cs @@ -37,7 +37,7 @@ namespace osu.Game.Tests.NonVisual.Ranking var unstableRate = new UnstableRate(events); - Assert.IsTrue(Precision.AlmostEquals(0, unstableRate.Value)); + Assert.AreEqual(0, unstableRate.Value); } } } From fde4b03dabe1f58d871f7785f431a6c68f5b5ee5 Mon Sep 17 00:00:00 2001 From: Pavle Aleksov Date: Mon, 31 Aug 2020 16:21:00 +0200 Subject: [PATCH 202/320] added spinner duration check - skip HitObjectReplay if duration is 0 --- osu.Game.Rulesets.Osu/Replays/OsuAutoGenerator.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/osu.Game.Rulesets.Osu/Replays/OsuAutoGenerator.cs b/osu.Game.Rulesets.Osu/Replays/OsuAutoGenerator.cs index 4cb2cd6539..5a439734c6 100644 --- a/osu.Game.Rulesets.Osu/Replays/OsuAutoGenerator.cs +++ b/osu.Game.Rulesets.Osu/Replays/OsuAutoGenerator.cs @@ -156,6 +156,9 @@ namespace osu.Game.Rulesets.Osu.Replays // TODO: Shouldn't the spinner always spin in the same direction? if (h is Spinner) { + if ((h as Spinner).Duration == 0) + return; + calcSpinnerStartPosAndDirection(((OsuReplayFrame)Frames[^1]).Position, out startPosition, out spinnerDirection); Vector2 spinCentreOffset = SPINNER_CENTRE - ((OsuReplayFrame)Frames[^1]).Position; From 0655fc14737c76def98ebb375329044c4ff0392b Mon Sep 17 00:00:00 2001 From: PajLe Date: Mon, 31 Aug 2020 16:50:31 +0200 Subject: [PATCH 203/320] changed comparing Duration to autoplay's reactionTime instead of 0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bartłomiej Dach --- osu.Game.Rulesets.Osu/Replays/OsuAutoGenerator.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Replays/OsuAutoGenerator.cs b/osu.Game.Rulesets.Osu/Replays/OsuAutoGenerator.cs index 5a439734c6..9ef2ff9ebb 100644 --- a/osu.Game.Rulesets.Osu/Replays/OsuAutoGenerator.cs +++ b/osu.Game.Rulesets.Osu/Replays/OsuAutoGenerator.cs @@ -154,9 +154,9 @@ namespace osu.Game.Rulesets.Osu.Replays // The startPosition for the slider should not be its .Position, but the point on the circle whose tangent crosses the current cursor position // We also modify spinnerDirection so it spins in the direction it enters the spin circle, to make a smooth transition. // TODO: Shouldn't the spinner always spin in the same direction? - if (h is Spinner) + if (h is Spinner spinner) { - if ((h as Spinner).Duration == 0) + if (spinner.Duration < reactionTime) return; calcSpinnerStartPosAndDirection(((OsuReplayFrame)Frames[^1]).Position, out startPosition, out spinnerDirection); From 69ec2a76ef1586f76bb26658fec7ab183cc7762e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Mon, 31 Aug 2020 17:20:45 +0200 Subject: [PATCH 204/320] Replace reaction time check with spins required check --- osu.Game.Rulesets.Osu/Replays/OsuAutoGenerator.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Replays/OsuAutoGenerator.cs b/osu.Game.Rulesets.Osu/Replays/OsuAutoGenerator.cs index 9ef2ff9ebb..76b2631894 100644 --- a/osu.Game.Rulesets.Osu/Replays/OsuAutoGenerator.cs +++ b/osu.Game.Rulesets.Osu/Replays/OsuAutoGenerator.cs @@ -156,7 +156,8 @@ namespace osu.Game.Rulesets.Osu.Replays // TODO: Shouldn't the spinner always spin in the same direction? if (h is Spinner spinner) { - if (spinner.Duration < reactionTime) + // spinners with 0 spins required will auto-complete - don't bother + if (spinner.SpinsRequired == 0) return; calcSpinnerStartPosAndDirection(((OsuReplayFrame)Frames[^1]).Position, out startPosition, out spinnerDirection); From eafa97af17a1ef203ccd4f25759401ccce169cc0 Mon Sep 17 00:00:00 2001 From: Craftplacer Date: Mon, 31 Aug 2020 17:23:42 +0200 Subject: [PATCH 205/320] Revert changes done to SkinConfiguration and IHasCustomColours --- osu.Game/Beatmaps/Formats/IHasCustomColours.cs | 2 +- osu.Game/Skinning/LegacyManiaSkinConfiguration.cs | 2 +- osu.Game/Skinning/SkinConfiguration.cs | 8 ++------ 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/osu.Game/Beatmaps/Formats/IHasCustomColours.cs b/osu.Game/Beatmaps/Formats/IHasCustomColours.cs index 1ac5ca83cb..dba3a37545 100644 --- a/osu.Game/Beatmaps/Formats/IHasCustomColours.cs +++ b/osu.Game/Beatmaps/Formats/IHasCustomColours.cs @@ -8,6 +8,6 @@ namespace osu.Game.Beatmaps.Formats { public interface IHasCustomColours { - IDictionary CustomColours { get; } + Dictionary CustomColours { get; } } } diff --git a/osu.Game/Skinning/LegacyManiaSkinConfiguration.cs b/osu.Game/Skinning/LegacyManiaSkinConfiguration.cs index 7972cc7d06..65d5851455 100644 --- a/osu.Game/Skinning/LegacyManiaSkinConfiguration.cs +++ b/osu.Game/Skinning/LegacyManiaSkinConfiguration.cs @@ -23,7 +23,7 @@ namespace osu.Game.Skinning public readonly int Keys; - public IDictionary CustomColours { get; } = new SortedDictionary(); + public Dictionary CustomColours { get; set; } = new Dictionary(); public Dictionary ImageLookups = new Dictionary(); diff --git a/osu.Game/Skinning/SkinConfiguration.cs b/osu.Game/Skinning/SkinConfiguration.cs index 18d970dd64..2857ad3824 100644 --- a/osu.Game/Skinning/SkinConfiguration.cs +++ b/osu.Game/Skinning/SkinConfiguration.cs @@ -1,9 +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; using System.Collections.Generic; -using System.Linq; using osu.Game.Beatmaps.Formats; using osuTK.Graphics; @@ -12,7 +10,7 @@ namespace osu.Game.Skinning /// /// An empty skin configuration. /// - public class SkinConfiguration : IEquatable, IHasComboColours, IHasCustomColours + public class SkinConfiguration : IHasComboColours, IHasCustomColours { public readonly SkinInfo SkinInfo = new SkinInfo(); @@ -47,10 +45,8 @@ namespace osu.Game.Skinning public void AddComboColours(params Color4[] colours) => comboColours.AddRange(colours); - public IDictionary CustomColours { get; } = new SortedDictionary(); + public Dictionary CustomColours { get; set; } = new Dictionary(); public readonly SortedDictionary ConfigDictionary = new SortedDictionary(); - - public bool Equals(SkinConfiguration other) => other != null && ConfigDictionary.SequenceEqual(other.ConfigDictionary) && ((ComboColours == null && other.ComboColours == null) || ComboColours.SequenceEqual(other.ComboColours)) && CustomColours.SequenceEqual(other.CustomColours); } } From 1484e78654743b8e68ead43811ed5735d681b13d Mon Sep 17 00:00:00 2001 From: Craftplacer Date: Mon, 31 Aug 2020 17:24:00 +0200 Subject: [PATCH 206/320] Update xmldoc --- osu.Game/Beatmaps/BeatmapManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index 89a776dd31..f725d55970 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -195,7 +195,7 @@ namespace osu.Game.Beatmaps /// /// The to save the content against. The file referenced by will be replaced. /// The content to write. - /// The beatmap content to write, or null if not to be changed. + /// The beatmap content to write, null if to be omitted. public void Save(BeatmapInfo info, IBeatmap beatmapContent, IBeatmapSkin beatmapSkin = null) { var setInfo = QueryBeatmapSet(s => s.Beatmaps.Any(b => b.ID == info.ID)); From fb37a14d577416754f17a569b9658989d7327c07 Mon Sep 17 00:00:00 2001 From: Craftplacer Date: Mon, 31 Aug 2020 17:24:03 +0200 Subject: [PATCH 207/320] Update LegacyBeatmapEncoder.cs --- osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs index cae6a43cd4..53ce1c831c 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs @@ -25,6 +25,8 @@ namespace osu.Game.Beatmaps.Formats public const int LATEST_VERSION = 128; private readonly IBeatmap beatmap; + + [CanBeNull] private readonly IBeatmapSkin skin; /// @@ -64,7 +66,7 @@ namespace osu.Game.Beatmaps.Formats handleControlPoints(writer); writer.WriteLine(); - handleComboColours(writer); + handleColours(writer); writer.WriteLine(); handleHitObjects(writer); @@ -209,9 +211,9 @@ namespace osu.Game.Beatmaps.Formats } } - private void handleComboColours(TextWriter writer) + private void handleColours(TextWriter writer) { - var colours = skin.GetConfig>(GlobalSkinColours.ComboColours)?.Value; + var colours = skin?.GetConfig>(GlobalSkinColours.ComboColours)?.Value; if (colours == null || colours.Count == 0) return; From a893aa8af86b5037dc1662adfe789112a61afea7 Mon Sep 17 00:00:00 2001 From: Craftplacer Date: Mon, 31 Aug 2020 17:24:24 +0200 Subject: [PATCH 208/320] Cut down changes done to LegacyBeatmapEncoderTest --- .../Formats/LegacyBeatmapEncoderTest.cs | 71 +++++-------------- 1 file changed, 16 insertions(+), 55 deletions(-) diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs index a8a3f266fc..bcc5970a27 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs @@ -7,10 +7,8 @@ using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; -using System.Threading.Tasks; using NUnit.Framework; using osu.Framework.Audio.Track; -using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Graphics.Textures; using osu.Framework.IO.Stores; using osu.Game.Beatmaps; @@ -44,7 +42,19 @@ namespace osu.Game.Tests.Beatmaps.Formats sort(decodedAfterEncode); Assert.That(decodedAfterEncode.beatmap.Serialize(), Is.EqualTo(decoded.beatmap.Serialize())); - Assert.IsTrue(decodedAfterEncode.beatmapSkin.Configuration.Equals(decoded.beatmapSkin.Configuration)); + Assert.IsTrue(areComboColoursEqual(decodedAfterEncode.beatmapSkin.Configuration, decoded.beatmapSkin.Configuration)); + } + + private bool areComboColoursEqual(IHasComboColours a, IHasComboColours b) + { + // equal to null, no need to SequenceEqual + if (a.ComboColours == null && b.ComboColours == null) + return true; + + if (a.ComboColours == null || b.ComboColours == null) + return false; + + return a.ComboColours.SequenceEqual(b.ComboColours); } private void sort((IBeatmap beatmap, IBeatmapSkin beatmapSkin) tuple) @@ -62,63 +72,14 @@ namespace osu.Game.Tests.Beatmaps.Formats using (var reader = new LineBufferedReader(stream)) { var beatmap = new LegacyBeatmapDecoder { ApplyOffsets = false }.Decode(reader); - - using (var rs = new MemoryBeatmapResourceStore(stream, name)) - { - var beatmapSkin = new TestLegacySkin(beatmap, rs, name); - return (convert(beatmap), beatmapSkin); - } + var beatmapSkin = new TestLegacySkin(beatmaps_resource_store, name); + return (convert(beatmap), beatmapSkin); } } - private class MemoryBeatmapResourceStore : IResourceStore - { - private readonly Stream beatmapData; - private readonly string beatmapName; - - public MemoryBeatmapResourceStore(Stream beatmapData, string beatmapName) - { - this.beatmapData = beatmapData; - this.beatmapName = beatmapName; - } - - public void Dispose() => beatmapData.Dispose(); - - public byte[] Get(string name) - { - if (name != beatmapName) - return null; - - byte[] buffer = new byte[beatmapData.Length]; - beatmapData.Read(buffer, 0, buffer.Length); - return buffer; - } - - public async Task GetAsync(string name) - { - if (name != beatmapName) - return null; - - byte[] buffer = new byte[beatmapData.Length]; - await beatmapData.ReadAsync(buffer.AsMemory()); - return buffer; - } - - public Stream GetStream(string name) - { - if (name != beatmapName) - return null; - - beatmapData.Seek(0, SeekOrigin.Begin); - return beatmapData; - } - - public IEnumerable GetAvailableResources() => beatmapName.Yield(); - } - private class TestLegacySkin : LegacySkin, IBeatmapSkin { - public TestLegacySkin(Beatmap beatmap, IResourceStore storage, string fileName) + public TestLegacySkin(IResourceStore storage, string fileName) : base(new SkinInfo { Name = "Test Skin", Creator = "Craftplacer" }, storage, null, fileName) { } From a290f7eeec4ecefb46dc4288eb98f94c909f492b Mon Sep 17 00:00:00 2001 From: Craftplacer Date: Mon, 31 Aug 2020 17:34:18 +0200 Subject: [PATCH 209/320] Revert left-over type change in SkinConfiguration --- osu.Game/Skinning/SkinConfiguration.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Skinning/SkinConfiguration.cs b/osu.Game/Skinning/SkinConfiguration.cs index 2857ad3824..a55870aa6d 100644 --- a/osu.Game/Skinning/SkinConfiguration.cs +++ b/osu.Game/Skinning/SkinConfiguration.cs @@ -47,6 +47,6 @@ namespace osu.Game.Skinning public Dictionary CustomColours { get; set; } = new Dictionary(); - public readonly SortedDictionary ConfigDictionary = new SortedDictionary(); + public readonly Dictionary ConfigDictionary = new Dictionary(); } } From 3cc169c933f2e4518fb9756d7905641d4fcf4167 Mon Sep 17 00:00:00 2001 From: Craftplacer Date: Mon, 31 Aug 2020 17:48:36 +0200 Subject: [PATCH 210/320] Remove set from properties in SkinConfiguration classes I don't get why this wasn't resolved in the first place when this file was originally written. *sigh* --- osu.Game/Skinning/LegacyManiaSkinConfiguration.cs | 2 +- osu.Game/Skinning/SkinConfiguration.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Skinning/LegacyManiaSkinConfiguration.cs b/osu.Game/Skinning/LegacyManiaSkinConfiguration.cs index 65d5851455..35a6140cbc 100644 --- a/osu.Game/Skinning/LegacyManiaSkinConfiguration.cs +++ b/osu.Game/Skinning/LegacyManiaSkinConfiguration.cs @@ -23,7 +23,7 @@ namespace osu.Game.Skinning public readonly int Keys; - public Dictionary CustomColours { get; set; } = new Dictionary(); + public Dictionary CustomColours { get; } = new Dictionary(); public Dictionary ImageLookups = new Dictionary(); diff --git a/osu.Game/Skinning/SkinConfiguration.cs b/osu.Game/Skinning/SkinConfiguration.cs index a55870aa6d..25a924c929 100644 --- a/osu.Game/Skinning/SkinConfiguration.cs +++ b/osu.Game/Skinning/SkinConfiguration.cs @@ -45,7 +45,7 @@ namespace osu.Game.Skinning public void AddComboColours(params Color4[] colours) => comboColours.AddRange(colours); - public Dictionary CustomColours { get; set; } = new Dictionary(); + public Dictionary CustomColours { get; } = new Dictionary(); public readonly Dictionary ConfigDictionary = new Dictionary(); } From 9b3a48ee5e3426c8474232518755b429d563ff5d Mon Sep 17 00:00:00 2001 From: Craftplacer Date: Mon, 31 Aug 2020 18:29:46 +0200 Subject: [PATCH 211/320] Revert "Add marker interface for beatmap skins" --- .../TestSceneLegacyBeatmapSkin.cs | 2 +- .../TestSceneSkinFallbacks.cs | 18 +++++------------- .../Gameplay/TestSceneStoryboardSamples.cs | 4 ++-- .../Beatmaps/BeatmapManager_WorkingBeatmap.cs | 2 +- osu.Game/Beatmaps/IWorkingBeatmap.cs | 4 ++-- osu.Game/Beatmaps/WorkingBeatmap.cs | 8 ++++---- .../Skinning/BeatmapSkinProvidingContainer.cs | 4 ++-- osu.Game/Skinning/DefaultBeatmapSkin.cs | 9 --------- osu.Game/Skinning/IBeatmapSkin.cs | 12 ------------ osu.Game/Skinning/LegacyBeatmapSkin.cs | 2 +- osu.Game/Tests/Beatmaps/HitObjectSampleTest.cs | 2 +- 11 files changed, 19 insertions(+), 48 deletions(-) delete mode 100644 osu.Game/Skinning/DefaultBeatmapSkin.cs delete mode 100644 osu.Game/Skinning/IBeatmapSkin.cs diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneLegacyBeatmapSkin.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneLegacyBeatmapSkin.cs index 03d18cefef..3ff37c4147 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneLegacyBeatmapSkin.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneLegacyBeatmapSkin.cs @@ -110,7 +110,7 @@ namespace osu.Game.Rulesets.Osu.Tests this.hasColours = hasColours; } - protected override IBeatmapSkin GetSkin() => new TestBeatmapSkin(BeatmapInfo, hasColours); + protected override ISkin GetSkin() => new TestBeatmapSkin(BeatmapInfo, hasColours); } private class TestBeatmapSkin : LegacyBeatmapSkin diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSkinFallbacks.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSkinFallbacks.cs index 64da80a88e..075bf314bc 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSkinFallbacks.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSkinFallbacks.cs @@ -29,12 +29,12 @@ namespace osu.Game.Rulesets.Osu.Tests public class TestSceneSkinFallbacks : TestSceneOsuPlayer { private readonly TestSource testUserSkin; - private readonly BeatmapTestSource testBeatmapSkin; + private readonly TestSource testBeatmapSkin; public TestSceneSkinFallbacks() { testUserSkin = new TestSource("user"); - testBeatmapSkin = new BeatmapTestSource(); + testBeatmapSkin = new TestSource("beatmap"); } [Test] @@ -80,15 +80,15 @@ namespace osu.Game.Rulesets.Osu.Tests public class CustomSkinWorkingBeatmap : ClockBackedTestWorkingBeatmap { - private readonly IBeatmapSkin skin; + private readonly ISkinSource skin; - public CustomSkinWorkingBeatmap(IBeatmap beatmap, Storyboard storyboard, IFrameBasedClock frameBasedClock, AudioManager audio, IBeatmapSkin skin) + public CustomSkinWorkingBeatmap(IBeatmap beatmap, Storyboard storyboard, IFrameBasedClock frameBasedClock, AudioManager audio, ISkinSource skin) : base(beatmap, storyboard, frameBasedClock, audio) { this.skin = skin; } - protected override IBeatmapSkin GetSkin() => skin; + protected override ISkin GetSkin() => skin; } public class SkinProvidingPlayer : TestPlayer @@ -112,14 +112,6 @@ namespace osu.Game.Rulesets.Osu.Tests } } - private class BeatmapTestSource : TestSource, IBeatmapSkin - { - public BeatmapTestSource() - : base("beatmap") - { - } - } - public class TestSource : ISkinSource { private readonly string identifier; diff --git a/osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs b/osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs index bc9528beb6..b30870d057 100644 --- a/osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs +++ b/osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs @@ -116,7 +116,7 @@ namespace osu.Game.Tests.Gameplay AddAssert("sample playback rate matches mod rates", () => sample.Channel.AggregateFrequency.Value == expectedRate); } - private class TestSkin : LegacySkin, IBeatmapSkin + private class TestSkin : LegacySkin { public TestSkin(string resourceName, AudioManager audioManager) : base(DefaultLegacySkin.Info, new TestResourceStore(resourceName), audioManager, "skin.ini") @@ -156,7 +156,7 @@ namespace osu.Game.Tests.Gameplay this.audio = audio; } - protected override IBeatmapSkin GetSkin() => new TestSkin("test-sample", audio); + protected override ISkin GetSkin() => new TestSkin("test-sample", audio); } private class TestDrawableStoryboardSample : DrawableStoryboardSample diff --git a/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs b/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs index 44728cc251..39c5ccab27 100644 --- a/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs @@ -140,7 +140,7 @@ namespace osu.Game.Beatmaps return storyboard; } - protected override IBeatmapSkin GetSkin() + protected override ISkin GetSkin() { try { diff --git a/osu.Game/Beatmaps/IWorkingBeatmap.cs b/osu.Game/Beatmaps/IWorkingBeatmap.cs index aac41725a9..31975157a0 100644 --- a/osu.Game/Beatmaps/IWorkingBeatmap.cs +++ b/osu.Game/Beatmaps/IWorkingBeatmap.cs @@ -42,9 +42,9 @@ namespace osu.Game.Beatmaps Storyboard Storyboard { get; } /// - /// Retrieves the which this provides. + /// Retrieves the which this provides. /// - IBeatmapSkin Skin { get; } + ISkin Skin { get; } /// /// Constructs a playable from using the applicable converters for a specific . diff --git a/osu.Game/Beatmaps/WorkingBeatmap.cs b/osu.Game/Beatmaps/WorkingBeatmap.cs index 163b62a55c..b4bcf285b9 100644 --- a/osu.Game/Beatmaps/WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/WorkingBeatmap.cs @@ -44,7 +44,7 @@ namespace osu.Game.Beatmaps background = new RecyclableLazy(GetBackground, BackgroundStillValid); waveform = new RecyclableLazy(GetWaveform); storyboard = new RecyclableLazy(GetStoryboard); - skin = new RecyclableLazy(GetSkin); + skin = new RecyclableLazy(GetSkin); total_count.Value++; } @@ -275,10 +275,10 @@ namespace osu.Game.Beatmaps private readonly RecyclableLazy storyboard; public bool SkinLoaded => skin.IsResultAvailable; - public IBeatmapSkin Skin => skin.Value; + public ISkin Skin => skin.Value; - protected virtual IBeatmapSkin GetSkin() => new DefaultBeatmapSkin(); - private readonly RecyclableLazy skin; + protected virtual ISkin GetSkin() => new DefaultSkin(); + private readonly RecyclableLazy skin; /// /// Transfer pieces of a beatmap to a new one, where possible, to save on loading. diff --git a/osu.Game/Skinning/BeatmapSkinProvidingContainer.cs b/osu.Game/Skinning/BeatmapSkinProvidingContainer.cs index 346bfe53b8..40335db697 100644 --- a/osu.Game/Skinning/BeatmapSkinProvidingContainer.cs +++ b/osu.Game/Skinning/BeatmapSkinProvidingContainer.cs @@ -11,7 +11,7 @@ namespace osu.Game.Skinning /// /// A container which overrides existing skin options with beatmap-local values. /// - public class BeatmapSkinProvidingContainer : SkinProvidingContainer, IBeatmapSkin + public class BeatmapSkinProvidingContainer : SkinProvidingContainer { private readonly Bindable beatmapSkins = new Bindable(); private readonly Bindable beatmapHitsounds = new Bindable(); @@ -21,7 +21,7 @@ namespace osu.Game.Skinning protected override bool AllowTextureLookup(string componentName) => beatmapSkins.Value; protected override bool AllowSampleLookup(ISampleInfo componentName) => beatmapHitsounds.Value; - public BeatmapSkinProvidingContainer(IBeatmapSkin skin) + public BeatmapSkinProvidingContainer(ISkin skin) : base(skin) { } diff --git a/osu.Game/Skinning/DefaultBeatmapSkin.cs b/osu.Game/Skinning/DefaultBeatmapSkin.cs deleted file mode 100644 index 7b5ccd45c3..0000000000 --- a/osu.Game/Skinning/DefaultBeatmapSkin.cs +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -namespace osu.Game.Skinning -{ - public class DefaultBeatmapSkin : DefaultSkin, IBeatmapSkin - { - } -} diff --git a/osu.Game/Skinning/IBeatmapSkin.cs b/osu.Game/Skinning/IBeatmapSkin.cs deleted file mode 100644 index 91caaed557..0000000000 --- a/osu.Game/Skinning/IBeatmapSkin.cs +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -namespace osu.Game.Skinning -{ - /// - /// Marker interface for skins that originate from beatmaps. - /// - public interface IBeatmapSkin : ISkin - { - } -} diff --git a/osu.Game/Skinning/LegacyBeatmapSkin.cs b/osu.Game/Skinning/LegacyBeatmapSkin.cs index d53349dd11..d647bc4a2d 100644 --- a/osu.Game/Skinning/LegacyBeatmapSkin.cs +++ b/osu.Game/Skinning/LegacyBeatmapSkin.cs @@ -11,7 +11,7 @@ using osu.Game.Rulesets.Objects.Legacy; namespace osu.Game.Skinning { - public class LegacyBeatmapSkin : LegacySkin, IBeatmapSkin + public class LegacyBeatmapSkin : LegacySkin { protected override bool AllowManiaSkin => false; protected override bool UseCustomSampleBanks => true; diff --git a/osu.Game/Tests/Beatmaps/HitObjectSampleTest.cs b/osu.Game/Tests/Beatmaps/HitObjectSampleTest.cs index db080d889f..ab4fb38657 100644 --- a/osu.Game/Tests/Beatmaps/HitObjectSampleTest.cs +++ b/osu.Game/Tests/Beatmaps/HitObjectSampleTest.cs @@ -188,7 +188,7 @@ namespace osu.Game.Tests.Beatmaps this.resourceStore = resourceStore; } - protected override IBeatmapSkin GetSkin() => new LegacyBeatmapSkin(skinBeatmapInfo, resourceStore, AudioManager); + protected override ISkin GetSkin() => new LegacyBeatmapSkin(skinBeatmapInfo, resourceStore, AudioManager); } } } From 2e2f26449d1304e6bcd0af00a7aa2e130bb9919d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Mon, 31 Aug 2020 19:23:19 +0200 Subject: [PATCH 212/320] Change anchoring to TopRight --- osu.Game/Screens/Select/BeatmapInfoWedge.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game/Screens/Select/BeatmapInfoWedge.cs b/osu.Game/Screens/Select/BeatmapInfoWedge.cs index 2b2c40411d..44d7d0f765 100644 --- a/osu.Game/Screens/Select/BeatmapInfoWedge.cs +++ b/osu.Game/Screens/Select/BeatmapInfoWedge.cs @@ -227,13 +227,13 @@ namespace osu.Game.Screens.Select { createStarRatingDisplay(beatmapInfo).With(display => { - display.Anchor = Anchor.CentreRight; - display.Origin = Anchor.CentreRight; + display.Anchor = Anchor.TopRight; + display.Origin = Anchor.TopRight; }), StatusPill = new BeatmapSetOnlineStatusPill { - Anchor = Anchor.CentreRight, - Origin = Anchor.CentreRight, + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, TextSize = 11, TextPadding = new MarginPadding { Horizontal = 8, Vertical = 2 }, Status = beatmapInfo.Status, From 876fd21230a401d0d75877a3d681d167c2f38a9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Mon, 31 Aug 2020 19:31:47 +0200 Subject: [PATCH 213/320] Apply shear to right-anchored items --- osu.Game/Screens/Select/BeatmapInfoWedge.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/osu.Game/Screens/Select/BeatmapInfoWedge.cs b/osu.Game/Screens/Select/BeatmapInfoWedge.cs index 44d7d0f765..ad977c70b5 100644 --- a/osu.Game/Screens/Select/BeatmapInfoWedge.cs +++ b/osu.Game/Screens/Select/BeatmapInfoWedge.cs @@ -223,17 +223,20 @@ namespace osu.Game.Screens.Select Direction = FillDirection.Vertical, Padding = new MarginPadding { Top = 14, Right = shear_width / 2 }, AutoSizeAxes = Axes.Both, + Shear = wedged_container_shear, Children = new[] { createStarRatingDisplay(beatmapInfo).With(display => { display.Anchor = Anchor.TopRight; display.Origin = Anchor.TopRight; + display.Shear = -wedged_container_shear; }), StatusPill = new BeatmapSetOnlineStatusPill { Anchor = Anchor.TopRight, Origin = Anchor.TopRight, + Shear = -wedged_container_shear, TextSize = 11, TextPadding = new MarginPadding { Horizontal = 8, Vertical = 2 }, Status = beatmapInfo.Status, From c8aa197e5b472f9b3389382106253d0eeea61cb0 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 1 Sep 2020 11:36:18 +0900 Subject: [PATCH 214/320] Update framework --- osu.Android.props | 2 +- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index 1a76a24496..d4a6d6759e 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -52,6 +52,6 @@ - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index d1e2033596..5cc2f61e86 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -24,7 +24,7 @@ - + diff --git a/osu.iOS.props b/osu.iOS.props index 9b25eaab41..e7addc1c2c 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -70,7 +70,7 @@ - + @@ -80,7 +80,7 @@ - + From d45a1521a1e6441ec47f391c2575c5ac79239fb8 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 1 Sep 2020 11:56:23 +0900 Subject: [PATCH 215/320] Update BindableList usages --- osu.Game/Overlays/ChatOverlay.cs | 63 ++++++++++--------- .../Sections/Graphics/LayoutSettings.cs | 3 +- .../Screens/Edit/Timing/ControlPointTable.cs | 3 +- osu.Game/Screens/Edit/Timing/TimingScreen.cs | 3 +- .../Multi/Lounge/Components/RoomsContainer.cs | 18 +++++- 5 files changed, 53 insertions(+), 37 deletions(-) diff --git a/osu.Game/Overlays/ChatOverlay.cs b/osu.Game/Overlays/ChatOverlay.cs index 5ba55f6d45..692175603c 100644 --- a/osu.Game/Overlays/ChatOverlay.cs +++ b/osu.Game/Overlays/ChatOverlay.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System.Collections.Generic; +using System.Collections.Specialized; using System.Linq; using osuTK; using osuTK.Graphics; @@ -218,14 +219,13 @@ namespace osu.Game.Overlays Schedule(() => { // TODO: consider scheduling bindable callbacks to not perform when overlay is not present. - channelManager.JoinedChannels.ItemsAdded += onChannelAddedToJoinedChannels; - channelManager.JoinedChannels.ItemsRemoved += onChannelRemovedFromJoinedChannels; + channelManager.JoinedChannels.CollectionChanged += joinedChannelsChanged; + foreach (Channel channel in channelManager.JoinedChannels) ChannelTabControl.AddChannel(channel); - channelManager.AvailableChannels.ItemsAdded += availableChannelsChanged; - channelManager.AvailableChannels.ItemsRemoved += availableChannelsChanged; - ChannelSelectionOverlay.UpdateAvailableChannels(channelManager.AvailableChannels); + channelManager.AvailableChannels.CollectionChanged += availableChannelsChanged; + availableChannelsChanged(null, null); currentChannel = channelManager.CurrentChannel.GetBoundCopy(); currentChannel.BindValueChanged(currentChannelChanged, true); @@ -384,34 +384,41 @@ namespace osu.Game.Overlays base.PopOut(); } - private void onChannelAddedToJoinedChannels(IEnumerable channels) + private void joinedChannelsChanged(object sender, NotifyCollectionChangedEventArgs args) { - foreach (Channel channel in channels) - ChannelTabControl.AddChannel(channel); - } - - private void onChannelRemovedFromJoinedChannels(IEnumerable channels) - { - foreach (Channel channel in channels) + switch (args.Action) { - ChannelTabControl.RemoveChannel(channel); + case NotifyCollectionChangedAction.Add: + foreach (Channel channel in args.NewItems.Cast()) + ChannelTabControl.AddChannel(channel); + break; - var loaded = loadedChannels.Find(c => c.Channel == channel); + case NotifyCollectionChangedAction.Remove: + foreach (Channel channel in args.OldItems.Cast()) + { + ChannelTabControl.RemoveChannel(channel); - if (loaded != null) - { - loadedChannels.Remove(loaded); + var loaded = loadedChannels.Find(c => c.Channel == channel); - // Because the container is only cleared in the async load callback of a new channel, it is forcefully cleared - // to ensure that the previous channel doesn't get updated after it's disposed - currentChannelContainer.Remove(loaded); - loaded.Dispose(); - } + if (loaded != null) + { + loadedChannels.Remove(loaded); + + // Because the container is only cleared in the async load callback of a new channel, it is forcefully cleared + // to ensure that the previous channel doesn't get updated after it's disposed + currentChannelContainer.Remove(loaded); + loaded.Dispose(); + } + } + + break; } } - private void availableChannelsChanged(IEnumerable channels) - => ChannelSelectionOverlay.UpdateAvailableChannels(channelManager.AvailableChannels); + private void availableChannelsChanged(object sender, NotifyCollectionChangedEventArgs args) + { + ChannelSelectionOverlay.UpdateAvailableChannels(channelManager.AvailableChannels); + } protected override void Dispose(bool isDisposing) { @@ -420,10 +427,8 @@ namespace osu.Game.Overlays if (channelManager != null) { channelManager.CurrentChannel.ValueChanged -= currentChannelChanged; - channelManager.JoinedChannels.ItemsAdded -= onChannelAddedToJoinedChannels; - channelManager.JoinedChannels.ItemsRemoved -= onChannelRemovedFromJoinedChannels; - channelManager.AvailableChannels.ItemsAdded -= availableChannelsChanged; - channelManager.AvailableChannels.ItemsRemoved -= availableChannelsChanged; + channelManager.JoinedChannels.CollectionChanged -= joinedChannelsChanged; + channelManager.AvailableChannels.CollectionChanged -= availableChannelsChanged; } } diff --git a/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs b/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs index 00b7643332..4312b319c0 100644 --- a/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs @@ -163,8 +163,7 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics scalingSettings.ForEach(s => s.TransferValueOnCommit = mode.NewValue == ScalingMode.Everything); }, true); - windowModes.ItemsAdded += _ => windowModesChanged(); - windowModes.ItemsRemoved += _ => windowModesChanged(); + windowModes.CollectionChanged += (sender, args) => windowModesChanged(); windowModesChanged(); } diff --git a/osu.Game/Screens/Edit/Timing/ControlPointTable.cs b/osu.Game/Screens/Edit/Timing/ControlPointTable.cs index 5c59cfbfe8..c0c0bcead2 100644 --- a/osu.Game/Screens/Edit/Timing/ControlPointTable.cs +++ b/osu.Game/Screens/Edit/Timing/ControlPointTable.cs @@ -112,8 +112,7 @@ namespace osu.Game.Screens.Edit.Timing }; controlPoints = group.ControlPoints.GetBoundCopy(); - controlPoints.ItemsAdded += _ => createChildren(); - controlPoints.ItemsRemoved += _ => createChildren(); + controlPoints.CollectionChanged += (_, __) => createChildren(); createChildren(); } diff --git a/osu.Game/Screens/Edit/Timing/TimingScreen.cs b/osu.Game/Screens/Edit/Timing/TimingScreen.cs index a08a660e7e..8c40c8e721 100644 --- a/osu.Game/Screens/Edit/Timing/TimingScreen.cs +++ b/osu.Game/Screens/Edit/Timing/TimingScreen.cs @@ -124,8 +124,7 @@ namespace osu.Game.Screens.Edit.Timing selectedGroup.BindValueChanged(selected => { deleteButton.Enabled.Value = selected.NewValue != null; }, true); controlGroups = Beatmap.Value.Beatmap.ControlPointInfo.Groups.GetBoundCopy(); - controlGroups.ItemsAdded += _ => createContent(); - controlGroups.ItemsRemoved += _ => createContent(); + controlGroups.CollectionChanged += (sender, args) => createContent(); createContent(); } diff --git a/osu.Game/Screens/Multi/Lounge/Components/RoomsContainer.cs b/osu.Game/Screens/Multi/Lounge/Components/RoomsContainer.cs index 447c99039a..321d7b0a19 100644 --- a/osu.Game/Screens/Multi/Lounge/Components/RoomsContainer.cs +++ b/osu.Game/Screens/Multi/Lounge/Components/RoomsContainer.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Collections.Specialized; using System.Linq; using osu.Framework.Allocation; using osu.Framework.Bindables; @@ -53,8 +54,7 @@ namespace osu.Game.Screens.Multi.Lounge.Components protected override void LoadComplete() { - rooms.ItemsAdded += addRooms; - rooms.ItemsRemoved += removeRooms; + rooms.CollectionChanged += roomsChanged; roomManager.RoomsUpdated += updateSorting; rooms.BindTo(roomManager.Rooms); @@ -82,6 +82,20 @@ namespace osu.Game.Screens.Multi.Lounge.Components }); } + private void roomsChanged(object sender, NotifyCollectionChangedEventArgs args) + { + switch (args.Action) + { + case NotifyCollectionChangedAction.Add: + addRooms(args.NewItems.Cast()); + break; + + case NotifyCollectionChangedAction.Remove: + removeRooms(args.OldItems.Cast()); + break; + } + } + private void addRooms(IEnumerable rooms) { foreach (var room in rooms) From d1f79a6a488a9b8f07f88e35d7b96ac71192a458 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 24 Aug 2020 20:00:24 +0900 Subject: [PATCH 216/320] Fix potentially incorrect zoom level getting set on very short audio track --- osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs index 717d60b4f3..ce2954f301 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs @@ -68,7 +68,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline }, true); } - private float getZoomLevelForVisibleMilliseconds(double milliseconds) => (float)(track.Length / milliseconds); + private float getZoomLevelForVisibleMilliseconds(double milliseconds) => Math.Max(1, (float)(track.Length / milliseconds)); /// /// The timeline's scroll position in the last frame. From 9e3b809cab6f61489f90379327928768778672fb Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 1 Sep 2020 15:42:47 +0900 Subject: [PATCH 217/320] Rename to user_score to match API --- osu.Game/Online/Multiplayer/APILeaderboard.cs | 4 ++-- osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Online/Multiplayer/APILeaderboard.cs b/osu.Game/Online/Multiplayer/APILeaderboard.cs index 96fe7cefb0..65863d6e0e 100644 --- a/osu.Game/Online/Multiplayer/APILeaderboard.cs +++ b/osu.Game/Online/Multiplayer/APILeaderboard.cs @@ -12,7 +12,7 @@ namespace osu.Game.Online.Multiplayer [JsonProperty("leaderboard")] public List Leaderboard; - [JsonProperty("own_score")] - public APIUserScoreAggregate OwnScore; + [JsonProperty("user_score")] + public APIUserScoreAggregate UserScore; } } diff --git a/osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs b/osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs index 50afbb39fe..5bf61eb4ee 100644 --- a/osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs +++ b/osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs @@ -42,7 +42,7 @@ namespace osu.Game.Screens.Multi.Match.Components req.Success += r => { scoresCallback?.Invoke(r.Leaderboard); - TopScore = r.OwnScore; + TopScore = r.UserScore; }; return req; From 26b4226b5538c9f95657fdc985b9a873c763b4f1 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 1 Sep 2020 16:55:10 +0900 Subject: [PATCH 218/320] Fix ModTimeRamp not working --- osu.Game/Screens/Play/Player.cs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 9be4fd6a65..07be482529 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -52,6 +52,9 @@ namespace osu.Game.Screens.Play public override OverlayActivation InitialOverlayActivationMode => OverlayActivation.UserTriggered; + // We are managing our own adjustments (see OnEntering/OnExiting). + public override bool AllowRateAdjustments => false; + /// /// Whether gameplay should pause when the game window focus is lost. /// @@ -627,6 +630,10 @@ namespace osu.Game.Screens.Play foreach (var mod in Mods.Value.OfType()) mod.ApplyToHUD(HUDOverlay); + + Beatmap.Value.Track.ResetSpeedAdjustments(); + foreach (var mod in Mods.Value.OfType()) + mod.ApplyToTrack(Beatmap.Value.Track); } public override void OnSuspending(IScreen next) @@ -660,6 +667,8 @@ namespace osu.Game.Screens.Play // as we are no longer the current screen, we cannot guarantee the track is still usable. GameplayClockContainer?.StopUsingBeatmapClock(); + Beatmap.Value.Track.ResetSpeedAdjustments(); + fadeOut(); return base.OnExiting(next); } From 7e1844ed773368a4b932ea0e2d7fc87fa0fc53b4 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 1 Sep 2020 18:07:19 +0900 Subject: [PATCH 219/320] Fix track adjusments being reset incorrectly --- osu.Game/Screens/Play/Player.cs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 07be482529..82c446f5e4 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -80,6 +80,9 @@ namespace osu.Game.Screens.Play [Resolved] private IAPIProvider api { get; set; } + [Resolved] + private MusicController musicController { get; set; } + private SampleChannel sampleRestart; public BreakOverlay BreakOverlay; @@ -631,9 +634,12 @@ namespace osu.Game.Screens.Play foreach (var mod in Mods.Value.OfType()) mod.ApplyToHUD(HUDOverlay); - Beatmap.Value.Track.ResetSpeedAdjustments(); + // Our mods are local copies of the global mods so they need to be re-applied to the track. + // This is done through the music controller (for now), because resetting speed adjustments on the beatmap track also removes adjustments provided by DrawableTrack. + // Todo: In the future, player will receive in a track and will probably not have to worry about this... + musicController.ResetTrackAdjustments(); foreach (var mod in Mods.Value.OfType()) - mod.ApplyToTrack(Beatmap.Value.Track); + mod.ApplyToTrack(musicController.CurrentTrack); } public override void OnSuspending(IScreen next) @@ -667,7 +673,7 @@ namespace osu.Game.Screens.Play // as we are no longer the current screen, we cannot guarantee the track is still usable. GameplayClockContainer?.StopUsingBeatmapClock(); - Beatmap.Value.Track.ResetSpeedAdjustments(); + musicController.ResetTrackAdjustments(); fadeOut(); return base.OnExiting(next); From c2ade44656c3ea7d397d39652c77a70056d8fe1c Mon Sep 17 00:00:00 2001 From: Craftplacer Date: Tue, 1 Sep 2020 17:58:06 +0200 Subject: [PATCH 220/320] Change types back --- osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs | 6 +++--- osu.Game/Beatmaps/BeatmapManager.cs | 2 +- osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs | 4 ++-- osu.Game/Screens/Edit/EditorBeatmap.cs | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs index bcc5970a27..613db79242 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs @@ -57,7 +57,7 @@ namespace osu.Game.Tests.Beatmaps.Formats return a.ComboColours.SequenceEqual(b.ComboColours); } - private void sort((IBeatmap beatmap, IBeatmapSkin beatmapSkin) tuple) + private void sort((IBeatmap beatmap, ISkin beatmapSkin) tuple) { // Sort control points to ensure a sane ordering, as they may be parsed in different orders. This works because each group contains only uniquely-typed control points. foreach (var g in tuple.beatmap.ControlPointInfo.Groups) @@ -77,7 +77,7 @@ namespace osu.Game.Tests.Beatmaps.Formats } } - private class TestLegacySkin : LegacySkin, IBeatmapSkin + private class TestLegacySkin : LegacySkin, ISkin { public TestLegacySkin(IResourceStore storage, string fileName) : base(new SkinInfo { Name = "Test Skin", Creator = "Craftplacer" }, storage, null, fileName) @@ -85,7 +85,7 @@ namespace osu.Game.Tests.Beatmaps.Formats } } - private Stream encodeToLegacy((IBeatmap beatmap, IBeatmapSkin beatmapSkin) fullBeatmap) + private Stream encodeToLegacy((IBeatmap beatmap, ISkin beatmapSkin) fullBeatmap) { var (beatmap, beatmapSkin) = fullBeatmap; var stream = new MemoryStream(); diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index f725d55970..a96af68714 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -196,7 +196,7 @@ namespace osu.Game.Beatmaps /// The to save the content against. The file referenced by will be replaced. /// The content to write. /// The beatmap content to write, null if to be omitted. - public void Save(BeatmapInfo info, IBeatmap beatmapContent, IBeatmapSkin beatmapSkin = null) + public void Save(BeatmapInfo info, IBeatmap beatmapContent, ISkin beatmapSkin = null) { var setInfo = QueryBeatmapSet(s => s.Beatmaps.Any(b => b.ID == info.ID)); diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs index 53ce1c831c..80a4d6dea4 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs @@ -27,14 +27,14 @@ namespace osu.Game.Beatmaps.Formats private readonly IBeatmap beatmap; [CanBeNull] - private readonly IBeatmapSkin skin; + private readonly ISkin skin; /// /// Creates a new . /// /// The beatmap to encode. /// The beatmap's skin, used for encoding combo colours. - public LegacyBeatmapEncoder(IBeatmap beatmap, [CanBeNull] IBeatmapSkin skin) + public LegacyBeatmapEncoder(IBeatmap beatmap, [CanBeNull] ISkin skin) { this.beatmap = beatmap; this.skin = skin; diff --git a/osu.Game/Screens/Edit/EditorBeatmap.cs b/osu.Game/Screens/Edit/EditorBeatmap.cs index a314d50e60..061009e519 100644 --- a/osu.Game/Screens/Edit/EditorBeatmap.cs +++ b/osu.Game/Screens/Edit/EditorBeatmap.cs @@ -48,7 +48,7 @@ namespace osu.Game.Screens.Edit public readonly IBeatmap PlayableBeatmap; - public readonly IBeatmapSkin BeatmapSkin; + public readonly ISkin BeatmapSkin; [Resolved] private BindableBeatDivisor beatDivisor { get; set; } @@ -57,7 +57,7 @@ namespace osu.Game.Screens.Edit private readonly Dictionary> startTimeBindables = new Dictionary>(); - public EditorBeatmap(IBeatmap playableBeatmap, IBeatmapSkin beatmapSkin = null) + public EditorBeatmap(IBeatmap playableBeatmap, ISkin beatmapSkin = null) { PlayableBeatmap = playableBeatmap; BeatmapSkin = beatmapSkin; From 2a7259f7aa76d1dac116af9b6d0f016ab15db2bb Mon Sep 17 00:00:00 2001 From: Craftplacer Date: Tue, 1 Sep 2020 18:15:46 +0200 Subject: [PATCH 221/320] Update LegacyBeatmapEncoderTest.cs --- osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs index 613db79242..6e103af3f0 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs @@ -77,7 +77,7 @@ namespace osu.Game.Tests.Beatmaps.Formats } } - private class TestLegacySkin : LegacySkin, ISkin + private class TestLegacySkin : LegacySkin { public TestLegacySkin(IResourceStore storage, string fileName) : base(new SkinInfo { Name = "Test Skin", Creator = "Craftplacer" }, storage, null, fileName) From 112ecf085d6a44b59be0c12f131d7fee2a20d4f1 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 1 Sep 2020 17:19:04 +0000 Subject: [PATCH 222/320] Bump Sentry from 2.1.5 to 2.1.6 Bumps [Sentry](https://github.com/getsentry/sentry-dotnet) from 2.1.5 to 2.1.6. - [Release notes](https://github.com/getsentry/sentry-dotnet/releases) - [Commits](https://github.com/getsentry/sentry-dotnet/compare/2.1.5...2.1.6) Signed-off-by: dependabot-preview[bot] --- osu.Game/osu.Game.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index d1e2033596..c021770d7b 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -26,7 +26,7 @@ - + From 846189659b935cf970a22fa17e23a63f1353604a Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 1 Sep 2020 17:19:29 +0000 Subject: [PATCH 223/320] Bump Microsoft.Build.Traversal from 2.0.52 to 2.1.1 Bumps [Microsoft.Build.Traversal](https://github.com/Microsoft/MSBuildSdks) from 2.0.52 to 2.1.1. - [Release notes](https://github.com/Microsoft/MSBuildSdks/releases) - [Changelog](https://github.com/microsoft/MSBuildSdks/blob/master/RELEASE.md) - [Commits](https://github.com/Microsoft/MSBuildSdks/compare/Microsoft.Build.Traversal.2.0.52...Microsoft.Build.Traversal.2.1.1) Signed-off-by: dependabot-preview[bot] --- global.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/global.json b/global.json index 233a040d18..a9a531f59c 100644 --- a/global.json +++ b/global.json @@ -5,6 +5,6 @@ "version": "3.1.100" }, "msbuild-sdks": { - "Microsoft.Build.Traversal": "2.0.52" + "Microsoft.Build.Traversal": "2.1.1" } } \ No newline at end of file From 66c0d12da619a86b43cbbb594987c59712a8acff Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 1 Sep 2020 17:19:46 +0000 Subject: [PATCH 224/320] Bump Microsoft.NET.Test.Sdk from 16.7.0 to 16.7.1 Bumps [Microsoft.NET.Test.Sdk](https://github.com/microsoft/vstest) from 16.7.0 to 16.7.1. - [Release notes](https://github.com/microsoft/vstest/releases) - [Commits](https://github.com/microsoft/vstest/compare/v16.7.0...v16.7.1) Signed-off-by: dependabot-preview[bot] --- .../osu.Game.Rulesets.Catch.Tests.csproj | 2 +- .../osu.Game.Rulesets.Mania.Tests.csproj | 2 +- osu.Game.Rulesets.Osu.Tests/osu.Game.Rulesets.Osu.Tests.csproj | 2 +- .../osu.Game.Rulesets.Taiko.Tests.csproj | 2 +- osu.Game.Tests/osu.Game.Tests.csproj | 2 +- osu.Game.Tournament.Tests/osu.Game.Tournament.Tests.csproj | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/osu.Game.Rulesets.Catch.Tests/osu.Game.Rulesets.Catch.Tests.csproj b/osu.Game.Rulesets.Catch.Tests/osu.Game.Rulesets.Catch.Tests.csproj index f9d56dfa78..dfe3bf8af4 100644 --- a/osu.Game.Rulesets.Catch.Tests/osu.Game.Rulesets.Catch.Tests.csproj +++ b/osu.Game.Rulesets.Catch.Tests/osu.Game.Rulesets.Catch.Tests.csproj @@ -2,7 +2,7 @@ - + diff --git a/osu.Game.Rulesets.Mania.Tests/osu.Game.Rulesets.Mania.Tests.csproj b/osu.Game.Rulesets.Mania.Tests/osu.Game.Rulesets.Mania.Tests.csproj index ed00ed0b4c..892f27d27f 100644 --- a/osu.Game.Rulesets.Mania.Tests/osu.Game.Rulesets.Mania.Tests.csproj +++ b/osu.Game.Rulesets.Mania.Tests/osu.Game.Rulesets.Mania.Tests.csproj @@ -2,7 +2,7 @@ - + diff --git a/osu.Game.Rulesets.Osu.Tests/osu.Game.Rulesets.Osu.Tests.csproj b/osu.Game.Rulesets.Osu.Tests/osu.Game.Rulesets.Osu.Tests.csproj index f3837ea6b1..3639c3616f 100644 --- a/osu.Game.Rulesets.Osu.Tests/osu.Game.Rulesets.Osu.Tests.csproj +++ b/osu.Game.Rulesets.Osu.Tests/osu.Game.Rulesets.Osu.Tests.csproj @@ -2,7 +2,7 @@ - + diff --git a/osu.Game.Rulesets.Taiko.Tests/osu.Game.Rulesets.Taiko.Tests.csproj b/osu.Game.Rulesets.Taiko.Tests/osu.Game.Rulesets.Taiko.Tests.csproj index e896606ee8..b59f3a4344 100644 --- a/osu.Game.Rulesets.Taiko.Tests/osu.Game.Rulesets.Taiko.Tests.csproj +++ b/osu.Game.Rulesets.Taiko.Tests/osu.Game.Rulesets.Taiko.Tests.csproj @@ -2,7 +2,7 @@ - + diff --git a/osu.Game.Tests/osu.Game.Tests.csproj b/osu.Game.Tests/osu.Game.Tests.csproj index d767973528..c692bcd5e4 100644 --- a/osu.Game.Tests/osu.Game.Tests.csproj +++ b/osu.Game.Tests/osu.Game.Tests.csproj @@ -3,7 +3,7 @@ - + diff --git a/osu.Game.Tournament.Tests/osu.Game.Tournament.Tests.csproj b/osu.Game.Tournament.Tests/osu.Game.Tournament.Tests.csproj index 95f5deb2cc..5d55196dcf 100644 --- a/osu.Game.Tournament.Tests/osu.Game.Tournament.Tests.csproj +++ b/osu.Game.Tournament.Tests/osu.Game.Tournament.Tests.csproj @@ -5,7 +5,7 @@ - + From 8bf679db8be69f18ac06aba4972a14bcf5e8f513 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 2 Sep 2020 13:17:17 +0900 Subject: [PATCH 225/320] Fix nullref in date text box --- osu.Game.Tournament/Components/DateTextBox.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game.Tournament/Components/DateTextBox.cs b/osu.Game.Tournament/Components/DateTextBox.cs index ee7e350970..aee5241e35 100644 --- a/osu.Game.Tournament/Components/DateTextBox.cs +++ b/osu.Game.Tournament/Components/DateTextBox.cs @@ -22,11 +22,12 @@ namespace osu.Game.Tournament.Components } // hold a reference to the provided bindable so we don't have to in every settings section. - private Bindable bindable; + private Bindable bindable = new Bindable(); public DateTextBox() { base.Bindable = new Bindable(); + ((OsuTextBox)Control).OnCommit = (sender, newText) => { try From 8f90cc182099075a3651d22d1c31b9303aabd6ed Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 2 Sep 2020 13:21:51 +0900 Subject: [PATCH 226/320] Add test --- .../Components/TestSceneDateTextBox.cs | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 osu.Game.Tournament.Tests/Components/TestSceneDateTextBox.cs diff --git a/osu.Game.Tournament.Tests/Components/TestSceneDateTextBox.cs b/osu.Game.Tournament.Tests/Components/TestSceneDateTextBox.cs new file mode 100644 index 0000000000..33165d385a --- /dev/null +++ b/osu.Game.Tournament.Tests/Components/TestSceneDateTextBox.cs @@ -0,0 +1,41 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using NUnit.Framework; +using osu.Game.Tests.Visual; +using osu.Game.Tournament.Components; +using osuTK; +using osuTK.Input; + +namespace osu.Game.Tournament.Tests.Components +{ + public class TestSceneDateTextBox : OsuManualInputManagerTestScene + { + private DateTextBox textBox; + + [SetUp] + public void Setup() => Schedule(() => + { + Child = textBox = new DateTextBox + { + Width = 0.3f + }; + }); + + [Test] + public void TestCommitWithoutSettingBindable() + { + AddStep("click textbox", () => + { + InputManager.MoveMouseTo(textBox); + InputManager.Click(MouseButton.Left); + }); + + AddStep("unfocus", () => + { + InputManager.MoveMouseTo(Vector2.Zero); + InputManager.Click(MouseButton.Left); + }); + } + } +} From f793bf66e5e34c94c374b4f19391c83ce08fd361 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 2 Sep 2020 14:25:24 +0900 Subject: [PATCH 227/320] Remove rate adjustment from player test scene --- osu.Game/Tests/Visual/PlayerTestScene.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.Game/Tests/Visual/PlayerTestScene.cs b/osu.Game/Tests/Visual/PlayerTestScene.cs index 7d06c99133..2c46e7f6d3 100644 --- a/osu.Game/Tests/Visual/PlayerTestScene.cs +++ b/osu.Game/Tests/Visual/PlayerTestScene.cs @@ -29,8 +29,6 @@ namespace osu.Game.Tests.Visual { Dependencies.Cache(LocalConfig = new OsuConfigManager(LocalStorage)); LocalConfig.GetBindable(OsuSetting.DimLevel).Value = 1.0; - - MusicController.AllowRateAdjustments = true; } [SetUpSteps] From 7a6e02c558cffb2eaa5f665611f6ce778359d035 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 2 Sep 2020 14:28:31 +0900 Subject: [PATCH 228/320] Allow null rank --- osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs | 2 +- .../Screens/Multi/Match/Components/MatchLeaderboardScore.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs b/osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs index 5bf61eb4ee..f2409d64e7 100644 --- a/osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs +++ b/osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs @@ -50,7 +50,7 @@ namespace osu.Game.Screens.Multi.Match.Components protected override LeaderboardScore CreateDrawableScore(APIUserScoreAggregate model, int index) => new MatchLeaderboardScore(model, index); - protected override LeaderboardScore CreateDrawableTopScore(APIUserScoreAggregate model) => new MatchLeaderboardScore(model, model.Position ?? 0, false); + protected override LeaderboardScore CreateDrawableTopScore(APIUserScoreAggregate model) => new MatchLeaderboardScore(model, model.Position, false); } public enum MatchLeaderboardScope diff --git a/osu.Game/Screens/Multi/Match/Components/MatchLeaderboardScore.cs b/osu.Game/Screens/Multi/Match/Components/MatchLeaderboardScore.cs index c4e2b332b3..1fabdbb86a 100644 --- a/osu.Game/Screens/Multi/Match/Components/MatchLeaderboardScore.cs +++ b/osu.Game/Screens/Multi/Match/Components/MatchLeaderboardScore.cs @@ -14,7 +14,7 @@ namespace osu.Game.Screens.Multi.Match.Components { private readonly APIUserScoreAggregate score; - public MatchLeaderboardScore(APIUserScoreAggregate score, int rank, bool allowHighlight = true) + public MatchLeaderboardScore(APIUserScoreAggregate score, int? rank, bool allowHighlight = true) : base(score.CreateScoreInfo(), rank, allowHighlight) { this.score = score; From bff652a26f4755e3b18546af495d8bab778ef67f Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 2 Sep 2020 14:29:46 +0900 Subject: [PATCH 229/320] Persist nulls to the top score bindable --- osu.Game/Online/Leaderboards/Leaderboard.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/osu.Game/Online/Leaderboards/Leaderboard.cs b/osu.Game/Online/Leaderboards/Leaderboard.cs index 003d90d400..db0f835c67 100644 --- a/osu.Game/Online/Leaderboards/Leaderboard.cs +++ b/osu.Game/Online/Leaderboards/Leaderboard.cs @@ -93,13 +93,12 @@ namespace osu.Game.Online.Leaderboards get => topScoreContainer.Score.Value; set { + topScoreContainer.Score.Value = value; + if (value == null) topScoreContainer.Hide(); else - { topScoreContainer.Show(); - topScoreContainer.Score.Value = value; - } } } From 5195da3ceb6abc93db51e711c94086a009bf197d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 2 Sep 2020 15:18:51 +0900 Subject: [PATCH 230/320] Add message box in bracket editor explaining how to get started --- .../Screens/Editors/LadderEditorScreen.cs | 12 ++++++ osu.Game.Tournament/TournamentGame.cs | 25 +----------- osu.Game.Tournament/WarningBox.cs | 40 +++++++++++++++++++ 3 files changed, 53 insertions(+), 24 deletions(-) create mode 100644 osu.Game.Tournament/WarningBox.cs diff --git a/osu.Game.Tournament/Screens/Editors/LadderEditorScreen.cs b/osu.Game.Tournament/Screens/Editors/LadderEditorScreen.cs index f3eecf8afe..efec4cffdd 100644 --- a/osu.Game.Tournament/Screens/Editors/LadderEditorScreen.cs +++ b/osu.Game.Tournament/Screens/Editors/LadderEditorScreen.cs @@ -26,6 +26,8 @@ namespace osu.Game.Tournament.Screens.Editors [Cached] private LadderEditorInfo editorInfo = new LadderEditorInfo(); + private WarningBox rightClickMessage; + protected override bool DrawLoserPaths => true; [BackgroundDependencyLoader] @@ -37,6 +39,16 @@ namespace osu.Game.Tournament.Screens.Editors Origin = Anchor.TopRight, Margin = new MarginPadding(5) }); + + AddInternal(rightClickMessage = new WarningBox("Right click to place and link matches")); + + LadderInfo.Matches.CollectionChanged += (_, __) => updateMessage(); + updateMessage(); + } + + private void updateMessage() + { + rightClickMessage.Alpha = LadderInfo.Matches.Count > 0 ? 0 : 1; } public void BeginJoin(TournamentMatch match, bool losers) diff --git a/osu.Game.Tournament/TournamentGame.cs b/osu.Game.Tournament/TournamentGame.cs index 307ee1c773..bbe4a53d8f 100644 --- a/osu.Game.Tournament/TournamentGame.cs +++ b/osu.Game.Tournament/TournamentGame.cs @@ -87,30 +87,7 @@ namespace osu.Game.Tournament }, } }, - heightWarning = new Container - { - Masking = true, - CornerRadius = 5, - Depth = float.MinValue, - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - AutoSizeAxes = Axes.Both, - Children = new Drawable[] - { - new Box - { - Colour = Color4.Red, - RelativeSizeAxes = Axes.Both, - }, - new TournamentSpriteText - { - Text = "Please make the window wider", - Font = OsuFont.Torus.With(weight: FontWeight.Bold), - Colour = Color4.White, - Padding = new MarginPadding(20) - } - } - }, + heightWarning = new WarningBox("Please make the window wider"), new OsuContextMenuContainer { RelativeSizeAxes = Axes.Both, diff --git a/osu.Game.Tournament/WarningBox.cs b/osu.Game.Tournament/WarningBox.cs new file mode 100644 index 0000000000..814482aea4 --- /dev/null +++ b/osu.Game.Tournament/WarningBox.cs @@ -0,0 +1,40 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Game.Graphics; +using osuTK.Graphics; + +namespace osu.Game.Tournament +{ + internal class WarningBox : Container + { + public WarningBox(string text) + { + Masking = true; + CornerRadius = 5; + Depth = float.MinValue; + Anchor = Anchor.Centre; + Origin = Anchor.Centre; + AutoSizeAxes = Axes.Both; + + Children = new Drawable[] + { + new Box + { + Colour = Color4.Red, + RelativeSizeAxes = Axes.Both, + }, + new TournamentSpriteText + { + Text = text, + Font = OsuFont.Torus.With(weight: FontWeight.Bold), + Colour = Color4.White, + Padding = new MarginPadding(20) + } + }; + } + } +} From 555b2196b734cbce88a2acd2a0832367bf1c33d4 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 2 Sep 2020 15:23:50 +0900 Subject: [PATCH 231/320] Add xmldoc to MusicController.ResetTrackAdjustments() --- osu.Game/Overlays/MusicController.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index 6d5b5d43cd..c831584248 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -382,6 +382,12 @@ namespace osu.Game.Overlays } } + /// + /// Resets the speed adjustments currently applied on and applies the mod adjustments if is true. + /// + /// + /// Does not reset speed adjustments applied directly to the beatmap track. + /// public void ResetTrackAdjustments() { CurrentTrack.ResetSpeedAdjustments(); From 6a765d2d765dd01f4bd145560d6b30542aae7813 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 2 Sep 2020 20:04:56 +0900 Subject: [PATCH 232/320] Add smooth fading between audio tracks on transition --- osu.Game/Overlays/MusicController.cs | 6 +++++- osu.Game/Screens/Menu/IntroScreen.cs | 7 +++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index c831584248..17877a69a5 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.Linq; using JetBrains.Annotations; using osu.Framework.Allocation; +using osu.Framework.Audio; using osu.Framework.Audio.Track; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -341,10 +342,13 @@ namespace osu.Game.Overlays // but the mutation of the hierarchy is scheduled to avoid exceptions. Schedule(() => { - lastTrack.Expire(); + lastTrack.VolumeTo(0, 500, Easing.Out).Expire(); if (queuedTrack == CurrentTrack) + { AddInternal(queuedTrack); + queuedTrack.VolumeTo(0).Then().VolumeTo(1, 300, Easing.Out); + } else { // If the track has changed since the call to changeTrack, it is safe to dispose the diff --git a/osu.Game/Screens/Menu/IntroScreen.cs b/osu.Game/Screens/Menu/IntroScreen.cs index 884cbfe107..473e6b0364 100644 --- a/osu.Game/Screens/Menu/IntroScreen.cs +++ b/osu.Game/Screens/Menu/IntroScreen.cs @@ -12,6 +12,7 @@ using osu.Framework.Screens; using osu.Game.Beatmaps; using osu.Game.Configuration; using osu.Game.IO.Archives; +using osu.Game.Overlays; using osu.Game.Screens.Backgrounds; using osu.Game.Skinning; using osuTK; @@ -60,6 +61,9 @@ namespace osu.Game.Screens.Menu [Resolved] private AudioManager audio { get; set; } + [Resolved] + private MusicController musicController { get; set; } + /// /// Whether the is provided by osu! resources, rather than a user beatmap. /// Only valid during or after . @@ -167,6 +171,9 @@ namespace osu.Game.Screens.Menu Track = initialBeatmap.Track; UsingThemedIntro = !initialBeatmap.Track.IsDummyDevice; + // ensure the track starts at maximum volume + musicController.CurrentTrack.FinishTransforms(); + logo.MoveTo(new Vector2(0.5f)); logo.ScaleTo(Vector2.One); logo.Hide(); From 3fc6a74fdfa1bfd30c05b4748b7712c97530a923 Mon Sep 17 00:00:00 2001 From: Lucas A Date: Wed, 2 Sep 2020 19:55:46 +0200 Subject: [PATCH 233/320] Expose an immutable bindable in interface. --- osu.Game/Screens/IOsuScreen.cs | 2 +- osu.Game/Screens/OsuScreen.cs | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/IOsuScreen.cs b/osu.Game/Screens/IOsuScreen.cs index ead8e4bc22..e19037c2c4 100644 --- a/osu.Game/Screens/IOsuScreen.cs +++ b/osu.Game/Screens/IOsuScreen.cs @@ -41,7 +41,7 @@ namespace osu.Game.Screens /// /// Whether overlays should be able to be opened when this screen is current. /// - Bindable OverlayActivationMode { get; } + IBindable OverlayActivationMode { get; } /// /// The amount of parallax to be applied while this screen is displayed. diff --git a/osu.Game/Screens/OsuScreen.cs b/osu.Game/Screens/OsuScreen.cs index c10deaf1e5..cb8f2d21fe 100644 --- a/osu.Game/Screens/OsuScreen.cs +++ b/osu.Game/Screens/OsuScreen.cs @@ -48,7 +48,9 @@ namespace osu.Game.Screens /// protected virtual OverlayActivation InitialOverlayActivationMode => OverlayActivation.All; - public Bindable OverlayActivationMode { get; } + protected readonly Bindable OverlayActivationMode; + + IBindable IOsuScreen.OverlayActivationMode => OverlayActivationMode; public virtual bool CursorVisible => true; From 754274a146522ce3a8e69bda0ff4541819b539a2 Mon Sep 17 00:00:00 2001 From: Lucas A Date: Wed, 2 Sep 2020 20:55:26 +0200 Subject: [PATCH 234/320] Fix and add XMLDoc --- osu.Game/OsuGame.cs | 3 +++ osu.Game/Screens/OsuScreen.cs | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index e6d96df927..31926a6845 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -88,6 +88,9 @@ namespace osu.Game private IdleTracker idleTracker; + /// + /// Whether overlays should be able to be opened game-wide. Value is sourced from the current active screen. + /// public readonly IBindable OverlayActivationMode = new Bindable(); protected OsuScreenStack ScreenStack; diff --git a/osu.Game/Screens/OsuScreen.cs b/osu.Game/Screens/OsuScreen.cs index cb8f2d21fe..a44d14fb5c 100644 --- a/osu.Game/Screens/OsuScreen.cs +++ b/osu.Game/Screens/OsuScreen.cs @@ -44,7 +44,7 @@ namespace osu.Game.Screens public virtual bool HideOverlaysOnEnter => false; /// - /// The initial initial overlay activation mode to use when this screen is entered for the first time. + /// The initial overlay activation mode to use when this screen is entered for the first time. /// protected virtual OverlayActivation InitialOverlayActivationMode => OverlayActivation.All; From e7eaaf8b02efd43448b6dbbb11b4e98e7062aca7 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Thu, 3 Sep 2020 04:42:05 +0300 Subject: [PATCH 235/320] Bring legacy slider border width closer to osu!stable --- osu.Game.Rulesets.Osu/Skinning/LegacySliderBody.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game.Rulesets.Osu/Skinning/LegacySliderBody.cs b/osu.Game.Rulesets.Osu/Skinning/LegacySliderBody.cs index 21df49d80b..28277ac443 100644 --- a/osu.Game.Rulesets.Osu/Skinning/LegacySliderBody.cs +++ b/osu.Game.Rulesets.Osu/Skinning/LegacySliderBody.cs @@ -18,6 +18,8 @@ namespace osu.Game.Rulesets.Osu.Skinning { private const float shadow_portion = 1 - (OsuLegacySkinTransformer.LEGACY_CIRCLE_RADIUS / OsuHitObject.OBJECT_RADIUS); + protected new float CalculatedBorderPortion => base.CalculatedBorderPortion * 0.77f; + public new Color4 AccentColour => new Color4(base.AccentColour.R, base.AccentColour.G, base.AccentColour.B, base.AccentColour.A * 0.70f); protected override Color4 ColourAt(float position) From 5180d71fd9fda153ac8c895b5fad8cc7c345d0f7 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Thu, 3 Sep 2020 06:09:52 +0300 Subject: [PATCH 236/320] Attach an inline comment explaining how the value was reached --- osu.Game.Rulesets.Osu/Skinning/LegacySliderBody.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Skinning/LegacySliderBody.cs b/osu.Game.Rulesets.Osu/Skinning/LegacySliderBody.cs index 28277ac443..aad8b189d9 100644 --- a/osu.Game.Rulesets.Osu/Skinning/LegacySliderBody.cs +++ b/osu.Game.Rulesets.Osu/Skinning/LegacySliderBody.cs @@ -18,7 +18,9 @@ namespace osu.Game.Rulesets.Osu.Skinning { private const float shadow_portion = 1 - (OsuLegacySkinTransformer.LEGACY_CIRCLE_RADIUS / OsuHitObject.OBJECT_RADIUS); - protected new float CalculatedBorderPortion => base.CalculatedBorderPortion * 0.77f; + protected new float CalculatedBorderPortion + // Roughly matches osu!stable's slider border portions. + => base.CalculatedBorderPortion * 0.77f; public new Color4 AccentColour => new Color4(base.AccentColour.R, base.AccentColour.G, base.AccentColour.B, base.AccentColour.A * 0.70f); From 547c8090e5a5ae5d3c232debdfe5cbb95ce2f8ca Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 3 Sep 2020 13:13:48 +0900 Subject: [PATCH 237/320] Improve game exit music fade --- osu.Game/Screens/Menu/IntroScreen.cs | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/osu.Game/Screens/Menu/IntroScreen.cs b/osu.Game/Screens/Menu/IntroScreen.cs index 473e6b0364..bed8dbcdcb 100644 --- a/osu.Game/Screens/Menu/IntroScreen.cs +++ b/osu.Game/Screens/Menu/IntroScreen.cs @@ -46,8 +46,6 @@ namespace osu.Game.Screens.Menu protected ITrack Track { get; private set; } - private readonly BindableDouble exitingVolumeFade = new BindableDouble(1); - private const int exit_delay = 3000; private SampleChannel seeya; @@ -127,17 +125,29 @@ namespace osu.Game.Screens.Menu this.FadeIn(300); double fadeOutTime = exit_delay; + // we also handle the exit transition. if (MenuVoice.Value) + { seeya.Play(); + + // if playing the outro voice, we have more time to have fun with the background track. + // initially fade to almost silent then ramp out over the remaining time. + const double initial_fade = 200; + musicController.CurrentTrack + .VolumeTo(0.03f, initial_fade).Then() + .VolumeTo(0, fadeOutTime - initial_fade, Easing.In); + } else + { fadeOutTime = 500; - audio.AddAdjustment(AdjustableProperty.Volume, exitingVolumeFade); - this.TransformBindableTo(exitingVolumeFade, 0, fadeOutTime).OnComplete(_ => this.Exit()); + // if outro voice is turned off, just do a simple fade out. + musicController.CurrentTrack.VolumeTo(0, fadeOutTime, Easing.Out); + } //don't want to fade out completely else we will stop running updates. - Game.FadeTo(0.01f, fadeOutTime); + Game.FadeTo(0.01f, fadeOutTime).OnComplete(_ => this.Exit()); base.OnResuming(last); } From 2f42c57f4b7cbe4a9ae4f2ab0ed5fb5d2e65a53d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 3 Sep 2020 13:15:16 +0900 Subject: [PATCH 238/320] Add safeties to ensure the current track doesn't loop or change --- osu.Game/Screens/Menu/IntroScreen.cs | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/osu.Game/Screens/Menu/IntroScreen.cs b/osu.Game/Screens/Menu/IntroScreen.cs index bed8dbcdcb..1df5c503d6 100644 --- a/osu.Game/Screens/Menu/IntroScreen.cs +++ b/osu.Game/Screens/Menu/IntroScreen.cs @@ -126,6 +126,12 @@ namespace osu.Game.Screens.Menu double fadeOutTime = exit_delay; + var track = musicController.CurrentTrack; + + // ensure the track doesn't change or loop as we are exiting. + track.Looping = false; + Beatmap.Disabled = true; + // we also handle the exit transition. if (MenuVoice.Value) { @@ -134,16 +140,16 @@ namespace osu.Game.Screens.Menu // if playing the outro voice, we have more time to have fun with the background track. // initially fade to almost silent then ramp out over the remaining time. const double initial_fade = 200; - musicController.CurrentTrack - .VolumeTo(0.03f, initial_fade).Then() - .VolumeTo(0, fadeOutTime - initial_fade, Easing.In); + track + .VolumeTo(0.03f, initial_fade).Then() + .VolumeTo(0, fadeOutTime - initial_fade, Easing.In); } else { fadeOutTime = 500; // if outro voice is turned off, just do a simple fade out. - musicController.CurrentTrack.VolumeTo(0, fadeOutTime, Easing.Out); + track.VolumeTo(0, fadeOutTime, Easing.Out); } //don't want to fade out completely else we will stop running updates. From e0328445709f5218befafe0eb091ab7d0e1e738a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 24 Aug 2020 19:38:05 +0900 Subject: [PATCH 239/320] Start with a fresh beatmap when entering editor from main menu --- osu.Game/Beatmaps/BeatmapManager.cs | 25 +++++++++++++++++++ .../Beatmaps/BeatmapManager_WorkingBeatmap.cs | 3 +++ .../Menus/ScreenSelectionTabControl.cs | 2 -- osu.Game/Screens/Edit/Editor.cs | 9 +++++++ osu.Game/Screens/Menu/MainMenu.cs | 6 ++++- 5 files changed, 42 insertions(+), 3 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index 0cadcf5947..9289ed29d9 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -27,6 +27,7 @@ using osu.Game.Online.API; using osu.Game.Online.API.Requests; using osu.Game.Rulesets; using osu.Game.Rulesets.Objects; +using osu.Game.Users; using Decoder = osu.Game.Beatmaps.Formats.Decoder; namespace osu.Game.Beatmaps @@ -94,6 +95,30 @@ namespace osu.Game.Beatmaps protected override bool ShouldDeleteArchive(string path) => Path.GetExtension(path)?.ToLowerInvariant() == ".osz"; + public WorkingBeatmap CreateNew(RulesetInfo ruleset) + { + var set = new BeatmapSetInfo + { + Metadata = new BeatmapMetadata + { + Artist = "unknown", + Title = "unknown", + Author = User.SYSTEM_USER, + }, + Beatmaps = new List + { + new BeatmapInfo + { + BaseDifficulty = new BeatmapDifficulty(), + Ruleset = ruleset + } + } + }; + + var working = Import(set).Result; + return GetWorkingBeatmap(working.Beatmaps.First()); + } + protected override async Task Populate(BeatmapSetInfo beatmapSet, ArchiveReader archive, CancellationToken cancellationToken = default) { if (archive != null) diff --git a/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs b/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs index 92199789ec..63b1647f33 100644 --- a/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs @@ -33,6 +33,9 @@ namespace osu.Game.Beatmaps protected override IBeatmap GetBeatmap() { + if (BeatmapInfo.Path == null) + return BeatmapInfo.Ruleset.CreateInstance().CreateBeatmapConverter(new Beatmap()).Beatmap; + try { using (var stream = new LineBufferedReader(store.GetStream(getPathForFile(BeatmapInfo.Path)))) diff --git a/osu.Game/Screens/Edit/Components/Menus/ScreenSelectionTabControl.cs b/osu.Game/Screens/Edit/Components/Menus/ScreenSelectionTabControl.cs index 089da4f222..b8bc5cdf36 100644 --- a/osu.Game/Screens/Edit/Components/Menus/ScreenSelectionTabControl.cs +++ b/osu.Game/Screens/Edit/Components/Menus/ScreenSelectionTabControl.cs @@ -32,8 +32,6 @@ namespace osu.Game.Screens.Edit.Components.Menus Height = 1, Colour = Color4.White.Opacity(0.2f), }); - - Current.Value = EditorScreenMode.Compose; } [BackgroundDependencyLoader] diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index e178459d5c..dfba5f457b 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -89,6 +89,14 @@ namespace osu.Game.Screens.Edit // todo: remove caching of this and consume via editorBeatmap? dependencies.Cache(beatDivisor); + bool isNewBeatmap = false; + + if (Beatmap.Value is DummyWorkingBeatmap) + { + isNewBeatmap = true; + Beatmap.Value = beatmapManager.CreateNew(Ruleset.Value); + } + try { playableBeatmap = Beatmap.Value.GetPlayableBeatmap(Beatmap.Value.BeatmapInfo.Ruleset); @@ -148,6 +156,7 @@ namespace osu.Game.Screens.Edit Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, RelativeSizeAxes = Axes.Both, + Mode = { Value = isNewBeatmap ? EditorScreenMode.SongSetup : EditorScreenMode.Compose }, Items = new[] { new MenuItem("File") diff --git a/osu.Game/Screens/Menu/MainMenu.cs b/osu.Game/Screens/Menu/MainMenu.cs index fac9e9eb49..e0ac19cbaf 100644 --- a/osu.Game/Screens/Menu/MainMenu.cs +++ b/osu.Game/Screens/Menu/MainMenu.cs @@ -98,7 +98,11 @@ namespace osu.Game.Screens.Menu { buttons = new ButtonSystem { - OnEdit = delegate { this.Push(new Editor()); }, + OnEdit = delegate + { + Beatmap.SetDefault(); + this.Push(new Editor()); + }, OnSolo = onSolo, OnMulti = delegate { this.Push(new Multiplayer()); }, OnExit = confirmAndExit, From faf9b0a52864b2d5f8beedb12ab02cefb6bdb15a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 1 Sep 2020 15:48:13 +0900 Subject: [PATCH 240/320] Fix hard crash when trying to retrieve a beatmap's track when no file is present --- osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs b/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs index 63b1647f33..9e4c29a8d4 100644 --- a/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs @@ -70,6 +70,9 @@ namespace osu.Game.Beatmaps protected override Track GetBeatmapTrack() { + if (Metadata?.AudioFile == null) + return null; + try { return trackStore.Get(getPathForFile(Metadata.AudioFile)); @@ -83,6 +86,9 @@ namespace osu.Game.Beatmaps protected override Waveform GetWaveform() { + if (Metadata?.AudioFile == null) + return null; + try { var trackData = store.GetStream(getPathForFile(Metadata.AudioFile)); From 218cc39a4c46ce467264d11600a15b1e169795de Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 1 Sep 2020 15:49:21 +0900 Subject: [PATCH 241/320] Avoid throwing exceptions when MutatePath is called with null path --- osu.Game/IO/WrappedStorage.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/IO/WrappedStorage.cs b/osu.Game/IO/WrappedStorage.cs index 1dd3afbfae..766e36ef14 100644 --- a/osu.Game/IO/WrappedStorage.cs +++ b/osu.Game/IO/WrappedStorage.cs @@ -25,7 +25,7 @@ namespace osu.Game.IO this.subPath = subPath; } - protected virtual string MutatePath(string path) => !string.IsNullOrEmpty(subPath) ? Path.Combine(subPath, path) : path; + protected virtual string MutatePath(string path) => !string.IsNullOrEmpty(subPath) && !string.IsNullOrEmpty(path) ? Path.Combine(subPath, path) : path; protected virtual void ChangeTargetStorage(Storage newStorage) { From e80ef341d2663ea07c272154b8ddb1e0bde13467 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 1 Sep 2020 15:50:08 +0900 Subject: [PATCH 242/320] Allow UpdateFile to be called when a previous file doesn't exist --- osu.Game/Database/ArchiveModelManager.cs | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/osu.Game/Database/ArchiveModelManager.cs b/osu.Game/Database/ArchiveModelManager.cs index 915d980d24..49d7edd56c 100644 --- a/osu.Game/Database/ArchiveModelManager.cs +++ b/osu.Game/Database/ArchiveModelManager.cs @@ -397,15 +397,24 @@ namespace osu.Game.Database } } + /// + /// Update an existing file, or create a new entry if not already part of the 's files. + /// + /// The item to operate on. + /// The file model to be updated or added. + /// The new file contents. public void UpdateFile(TModel model, TFileModel file, Stream contents) { using (var usage = ContextFactory.GetForWrite()) { // Dereference the existing file info, since the file model will be removed. - Files.Dereference(file.FileInfo); + if (file.FileInfo != null) + { + Files.Dereference(file.FileInfo); - // Remove the file model. - usage.Context.Set().Remove(file); + // Remove the file model. + usage.Context.Set().Remove(file); + } // Add the new file info and containing file model. model.Files.Remove(file); From e337e6b3b0d804c40aac0667471c52a205584a20 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 1 Sep 2020 18:55:49 +0900 Subject: [PATCH 243/320] Use a more correct filename when saving --- osu.Game/Beatmaps/BeatmapManager.cs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index 9289ed29d9..fee7a71df4 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -237,10 +237,20 @@ namespace osu.Game.Beatmaps using (ContextFactory.GetForWrite()) { var beatmapInfo = setInfo.Beatmaps.Single(b => b.ID == info.ID); + var metadata = beatmapInfo.Metadata ?? setInfo.Metadata; + + // metadata may have changed; update the path with the standard format. + beatmapInfo.Path = $"{metadata.Artist} - {metadata.Title} ({metadata.Author}) [{beatmapInfo.Version}]"; + beatmapInfo.MD5Hash = stream.ComputeMD5Hash(); + var fileInfo = setInfo.Files.SingleOrDefault(f => string.Equals(f.Filename, beatmapInfo.Path, StringComparison.OrdinalIgnoreCase)) ?? new BeatmapSetFileInfo + { + Filename = beatmapInfo.Path + }; + stream.Seek(0, SeekOrigin.Begin); - UpdateFile(setInfo, setInfo.Files.Single(f => string.Equals(f.Filename, info.Path, StringComparison.OrdinalIgnoreCase)), stream); + UpdateFile(setInfo, fileInfo, stream); } } From d849f7f2b5b83b76b1e2a1803aadcbb10f6e3d1a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 1 Sep 2020 18:56:49 +0900 Subject: [PATCH 244/320] Use the local user's username when saving a new beatmap --- osu.Game/Beatmaps/BeatmapManager.cs | 18 +++++++++++------- osu.Game/Screens/Edit/Editor.cs | 14 +++++++++++++- 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index fee7a71df4..325e6c6e98 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -97,20 +97,24 @@ namespace osu.Game.Beatmaps public WorkingBeatmap CreateNew(RulesetInfo ruleset) { + var metadata = new BeatmapMetadata + { + Artist = "artist", + Title = "title", + Author = User.SYSTEM_USER, + }; + var set = new BeatmapSetInfo { - Metadata = new BeatmapMetadata - { - Artist = "unknown", - Title = "unknown", - Author = User.SYSTEM_USER, - }, + Metadata = metadata, Beatmaps = new List { new BeatmapInfo { BaseDifficulty = new BeatmapDifficulty(), - Ruleset = ruleset + Ruleset = ruleset, + Metadata = metadata, + Version = "difficulty" } } }; diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index dfba5f457b..b8c1932186 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -28,6 +28,7 @@ using osu.Framework.Logging; using osu.Game.Beatmaps; using osu.Game.Graphics.Cursor; using osu.Game.Input.Bindings; +using osu.Game.Online.API; using osu.Game.Rulesets.Edit; using osu.Game.Screens.Edit.Compose; using osu.Game.Screens.Edit.Setup; @@ -72,6 +73,9 @@ namespace osu.Game.Screens.Edit protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) => dependencies = new DependencyContainer(base.CreateChildDependencies(parent)); + [Resolved] + private IAPIProvider api { get; set; } + [BackgroundDependencyLoader] private void load(OsuColour colours, GameHost host) { @@ -95,6 +99,7 @@ namespace osu.Game.Screens.Edit { isNewBeatmap = true; Beatmap.Value = beatmapManager.CreateNew(Ruleset.Value); + Beatmap.Value.BeatmapSetInfo.Metadata.Author = api.LocalUser.Value; } try @@ -408,7 +413,14 @@ namespace osu.Game.Screens.Edit clock.SeekForward(!clock.IsRunning, amount); } - private void saveBeatmap() => beatmapManager.Save(playableBeatmap.BeatmapInfo, editorBeatmap); + private void saveBeatmap() + { + // apply any set-level metadata changes. + beatmapManager.Update(playableBeatmap.BeatmapInfo.BeatmapSet); + + // save the loaded beatmap's data stream. + beatmapManager.Save(playableBeatmap.BeatmapInfo, editorBeatmap); + } private void exportBeatmap() { From 0530c4b8a740d63f6c4c06faab5dac23cf517c63 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 3 Sep 2020 14:58:22 +0900 Subject: [PATCH 245/320] Update framework --- osu.Android.props | 2 +- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index d4a6d6759e..2d3bfaf7ce 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -52,6 +52,6 @@ - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 2a592108b7..166910b165 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -24,7 +24,7 @@ - + diff --git a/osu.iOS.props b/osu.iOS.props index e7addc1c2c..51f8141bac 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -70,7 +70,7 @@ - + @@ -80,7 +80,7 @@ - + From dceae21bbf4083f912b61b5fcb9d4b3b9422ffb0 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 3 Sep 2020 15:46:56 +0900 Subject: [PATCH 246/320] Centralise fetching of overlay component titles and textures --- .../BeatmapListing/BeatmapListingHeader.cs | 3 ++- osu.Game/Overlays/BeatmapSetOverlay.cs | 4 +++- .../Overlays/Changelog/ChangelogHeader.cs | 1 + osu.Game/Overlays/ChangelogOverlay.cs | 9 ++++---- osu.Game/Overlays/ChatOverlay.cs | 6 ++++- .../Dashboard/DashboardOverlayHeader.cs | 3 ++- osu.Game/Overlays/DashboardOverlay.cs | 2 +- osu.Game/Overlays/FullscreenOverlay.cs | 8 ++++++- osu.Game/Overlays/INamedOverlayComponent.cs | 14 ++++++++++++ osu.Game/Overlays/News/NewsHeader.cs | 1 + osu.Game/Overlays/NewsOverlay.cs | 5 +++-- osu.Game/Overlays/NotificationOverlay.cs | 6 ++++- osu.Game/Overlays/NowPlayingOverlay.cs | 6 ++++- osu.Game/Overlays/OverlayHeader.cs | 4 +++- osu.Game/Overlays/OverlayTitle.cs | 22 +++++++++++++------ .../Rankings/RankingsOverlayHeader.cs | 1 + osu.Game/Overlays/RankingsOverlay.cs | 2 +- .../SearchableList/SearchableListOverlay.cs | 2 +- osu.Game/Overlays/SettingsOverlay.cs | 6 ++++- .../Toolbar/ToolbarBeatmapListingButton.cs | 5 ----- osu.Game/Overlays/Toolbar/ToolbarButton.cs | 11 ---------- .../Toolbar/ToolbarChangelogButton.cs | 8 ------- .../Overlays/Toolbar/ToolbarChatButton.cs | 5 ----- .../Overlays/Toolbar/ToolbarHomeButton.cs | 3 +-- .../Overlays/Toolbar/ToolbarMusicButton.cs | 5 ----- .../Overlays/Toolbar/ToolbarNewsButton.cs | 8 ------- .../Toolbar/ToolbarNotificationButton.cs | 5 ----- .../Toolbar/ToolbarOverlayToggleButton.cs | 16 ++++++++++++++ .../Overlays/Toolbar/ToolbarRankingsButton.cs | 8 ------- .../Overlays/Toolbar/ToolbarSettingsButton.cs | 5 ----- .../Overlays/Toolbar/ToolbarSocialButton.cs | 5 ----- osu.Game/Overlays/UserProfileOverlay.cs | 4 ++-- 32 files changed, 98 insertions(+), 95 deletions(-) create mode 100644 osu.Game/Overlays/INamedOverlayComponent.cs diff --git a/osu.Game/Overlays/BeatmapListing/BeatmapListingHeader.cs b/osu.Game/Overlays/BeatmapListing/BeatmapListingHeader.cs index 1bab200fec..1cf86b78cf 100644 --- a/osu.Game/Overlays/BeatmapListing/BeatmapListingHeader.cs +++ b/osu.Game/Overlays/BeatmapListing/BeatmapListingHeader.cs @@ -12,7 +12,8 @@ namespace osu.Game.Overlays.BeatmapListing public BeatmapListingTitle() { Title = "beatmap listing"; - IconTexture = "Icons/changelog"; + Description = "Browse for new beatmaps"; + IconTexture = "Icons/Hexacons/music"; } } } diff --git a/osu.Game/Overlays/BeatmapSetOverlay.cs b/osu.Game/Overlays/BeatmapSetOverlay.cs index 3e23442023..2dfd1fa20f 100644 --- a/osu.Game/Overlays/BeatmapSetOverlay.cs +++ b/osu.Game/Overlays/BeatmapSetOverlay.cs @@ -24,7 +24,9 @@ namespace osu.Game.Overlays public const float X_PADDING = 40; public const float Y_PADDING = 25; public const float RIGHT_WIDTH = 275; - protected readonly Header Header; + + //todo: should be an OverlayHeader? or maybe not? + protected new readonly Header Header; [Resolved] private RulesetStore rulesets { get; set; } diff --git a/osu.Game/Overlays/Changelog/ChangelogHeader.cs b/osu.Game/Overlays/Changelog/ChangelogHeader.cs index 050bdea03a..35a4fc7014 100644 --- a/osu.Game/Overlays/Changelog/ChangelogHeader.cs +++ b/osu.Game/Overlays/Changelog/ChangelogHeader.cs @@ -115,6 +115,7 @@ namespace osu.Game.Overlays.Changelog public ChangelogHeaderTitle() { Title = "changelog"; + Description = "Track recent dev updates in the osu! ecosystem"; IconTexture = "Icons/changelog"; } } diff --git a/osu.Game/Overlays/ChangelogOverlay.cs b/osu.Game/Overlays/ChangelogOverlay.cs index 726be9e194..e9520906ea 100644 --- a/osu.Game/Overlays/ChangelogOverlay.cs +++ b/osu.Game/Overlays/ChangelogOverlay.cs @@ -25,10 +25,10 @@ namespace osu.Game.Overlays { public readonly Bindable Current = new Bindable(); - protected ChangelogHeader Header; - private Container content; + protected new ChangelogHeader Header; + private SampleChannel sampleBack; private List builds; @@ -61,9 +61,10 @@ namespace osu.Game.Overlays Direction = FillDirection.Vertical, Children = new Drawable[] { - Header = new ChangelogHeader + base.Header = Header = new ChangelogHeader { ListingSelected = ShowListing, + Build = { BindTarget = Current } }, content = new Container { @@ -77,8 +78,6 @@ namespace osu.Game.Overlays sampleBack = audio.Samples.Get(@"UI/generic-select-soft"); - Header.Build.BindTo(Current); - Current.BindValueChanged(e => { if (e.NewValue != null) diff --git a/osu.Game/Overlays/ChatOverlay.cs b/osu.Game/Overlays/ChatOverlay.cs index 692175603c..8e34f5d2c0 100644 --- a/osu.Game/Overlays/ChatOverlay.cs +++ b/osu.Game/Overlays/ChatOverlay.cs @@ -26,8 +26,12 @@ using osu.Framework.Graphics.Sprites; namespace osu.Game.Overlays { - public class ChatOverlay : OsuFocusedOverlayContainer + public class ChatOverlay : OsuFocusedOverlayContainer, INamedOverlayComponent { + public string IconTexture => "Icons/chat"; + public string Title => "Chat"; + public string Description => "Join the real-time discussion"; + private const float textbox_height = 60; private const float channel_selection_min_height = 0.3f; diff --git a/osu.Game/Overlays/Dashboard/DashboardOverlayHeader.cs b/osu.Game/Overlays/Dashboard/DashboardOverlayHeader.cs index 9ee679a866..1330a44374 100644 --- a/osu.Game/Overlays/Dashboard/DashboardOverlayHeader.cs +++ b/osu.Game/Overlays/Dashboard/DashboardOverlayHeader.cs @@ -12,7 +12,8 @@ namespace osu.Game.Overlays.Dashboard public DashboardTitle() { Title = "dashboard"; - IconTexture = "Icons/changelog"; + Description = "View your friends and other top level information"; + IconTexture = "Icons/hexacons/dashboard"; } } } diff --git a/osu.Game/Overlays/DashboardOverlay.cs b/osu.Game/Overlays/DashboardOverlay.cs index e3a4b0e152..68eb35c7da 100644 --- a/osu.Game/Overlays/DashboardOverlay.cs +++ b/osu.Game/Overlays/DashboardOverlay.cs @@ -50,7 +50,7 @@ namespace osu.Game.Overlays Direction = FillDirection.Vertical, Children = new Drawable[] { - header = new DashboardOverlayHeader + Header = header = new DashboardOverlayHeader { Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, diff --git a/osu.Game/Overlays/FullscreenOverlay.cs b/osu.Game/Overlays/FullscreenOverlay.cs index 3464ce6086..6d0441ff46 100644 --- a/osu.Game/Overlays/FullscreenOverlay.cs +++ b/osu.Game/Overlays/FullscreenOverlay.cs @@ -12,8 +12,14 @@ using osuTK.Graphics; namespace osu.Game.Overlays { - public abstract class FullscreenOverlay : WaveOverlayContainer, IOnlineComponent + public abstract class FullscreenOverlay : WaveOverlayContainer, IOnlineComponent, INamedOverlayComponent { + public virtual string IconTexture => Header?.Title.IconTexture ?? string.Empty; + public virtual string Title => Header?.Title.Title ?? string.Empty; + public virtual string Description => Header?.Title.Description ?? string.Empty; + + public OverlayHeader Header { get; protected set; } + [Resolved] protected IAPIProvider API { get; private set; } diff --git a/osu.Game/Overlays/INamedOverlayComponent.cs b/osu.Game/Overlays/INamedOverlayComponent.cs new file mode 100644 index 0000000000..38fb8679a0 --- /dev/null +++ b/osu.Game/Overlays/INamedOverlayComponent.cs @@ -0,0 +1,14 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +namespace osu.Game.Overlays +{ + public interface INamedOverlayComponent + { + string IconTexture { get; } + + string Title { get; } + + string Description { get; } + } +} diff --git a/osu.Game/Overlays/News/NewsHeader.cs b/osu.Game/Overlays/News/NewsHeader.cs index ddada2bdaf..f85d765d46 100644 --- a/osu.Game/Overlays/News/NewsHeader.cs +++ b/osu.Game/Overlays/News/NewsHeader.cs @@ -57,6 +57,7 @@ namespace osu.Game.Overlays.News public NewsHeaderTitle() { Title = "news"; + Description = "Get up-to-date on community happenings"; IconTexture = "Icons/news"; } } diff --git a/osu.Game/Overlays/NewsOverlay.cs b/osu.Game/Overlays/NewsOverlay.cs index 09fb445b1f..bc3e080158 100644 --- a/osu.Game/Overlays/NewsOverlay.cs +++ b/osu.Game/Overlays/NewsOverlay.cs @@ -19,7 +19,6 @@ namespace osu.Game.Overlays private Container content; private LoadingLayer loading; - private NewsHeader header; private OverlayScrollContainer scrollFlow; public NewsOverlay() @@ -48,7 +47,7 @@ namespace osu.Game.Overlays Direction = FillDirection.Vertical, Children = new Drawable[] { - header = new NewsHeader + Header = new NewsHeader { ShowFrontPage = ShowFrontPage }, @@ -110,6 +109,8 @@ namespace osu.Game.Overlays cancellationToken?.Cancel(); loading.Show(); + var header = (NewsHeader)Header; + if (e.NewValue == null) { header.SetFrontPage(); diff --git a/osu.Game/Overlays/NotificationOverlay.cs b/osu.Game/Overlays/NotificationOverlay.cs index 41160d10ec..6bdacb9c5e 100644 --- a/osu.Game/Overlays/NotificationOverlay.cs +++ b/osu.Game/Overlays/NotificationOverlay.cs @@ -16,8 +16,12 @@ using osu.Framework.Threading; namespace osu.Game.Overlays { - public class NotificationOverlay : OsuFocusedOverlayContainer + public class NotificationOverlay : OsuFocusedOverlayContainer, INamedOverlayComponent { + public string IconTexture => "Icons/Hexacons/"; + public string Title => "Notifications"; + public string Description => "Waiting for 'ya"; + private const float width = 320; public const float TRANSITION_LENGTH = 600; diff --git a/osu.Game/Overlays/NowPlayingOverlay.cs b/osu.Game/Overlays/NowPlayingOverlay.cs index af692486b7..f19f7bbc61 100644 --- a/osu.Game/Overlays/NowPlayingOverlay.cs +++ b/osu.Game/Overlays/NowPlayingOverlay.cs @@ -25,8 +25,12 @@ using osuTK.Graphics; namespace osu.Game.Overlays { - public class NowPlayingOverlay : OsuFocusedOverlayContainer + public class NowPlayingOverlay : OsuFocusedOverlayContainer, INamedOverlayComponent { + public string IconTexture => "Icons/Hexacons/music"; + public string Title => "Now playing"; + public string Description => "Manage the currently playing track"; + private const float player_height = 130; private const float transition_length = 800; private const float progress_height = 10; diff --git a/osu.Game/Overlays/OverlayHeader.cs b/osu.Game/Overlays/OverlayHeader.cs index cc7f798c4a..fed1e57686 100644 --- a/osu.Game/Overlays/OverlayHeader.cs +++ b/osu.Game/Overlays/OverlayHeader.cs @@ -12,6 +12,8 @@ namespace osu.Game.Overlays { public abstract class OverlayHeader : Container { + public OverlayTitle Title { get; } + private float contentSidePadding; /// @@ -73,7 +75,7 @@ namespace osu.Game.Overlays AutoSizeAxes = Axes.Y, Children = new[] { - CreateTitle().With(title => + Title = CreateTitle().With(title => { title.Anchor = Anchor.CentreLeft; title.Origin = Anchor.CentreLeft; diff --git a/osu.Game/Overlays/OverlayTitle.cs b/osu.Game/Overlays/OverlayTitle.cs index 1c9567428c..17eeece1f8 100644 --- a/osu.Game/Overlays/OverlayTitle.cs +++ b/osu.Game/Overlays/OverlayTitle.cs @@ -12,19 +12,27 @@ using osuTK; namespace osu.Game.Overlays { - public abstract class OverlayTitle : CompositeDrawable + public abstract class OverlayTitle : CompositeDrawable, INamedOverlayComponent { - private readonly OsuSpriteText title; + private readonly OsuSpriteText titleText; private readonly Container icon; - protected string Title + private string title; + + public string Title { - set => title.Text = value; + get => title; + protected set => titleText.Text = title = value; } - protected string IconTexture + public string Description { get; protected set; } + + private string iconTexture; + + public string IconTexture { - set => icon.Child = new OverlayTitleIcon(value); + get => iconTexture; + protected set => icon.Child = new OverlayTitleIcon(iconTexture = value); } protected OverlayTitle() @@ -45,7 +53,7 @@ namespace osu.Game.Overlays Margin = new MarginPadding { Horizontal = 5 }, // compensates for osu-web sprites having around 5px of whitespace on each side Size = new Vector2(30) }, - title = new OsuSpriteText + titleText = new OsuSpriteText { Anchor = Anchor.Centre, Origin = Anchor.Centre, diff --git a/osu.Game/Overlays/Rankings/RankingsOverlayHeader.cs b/osu.Game/Overlays/Rankings/RankingsOverlayHeader.cs index e30c6f07a8..b12294c6c1 100644 --- a/osu.Game/Overlays/Rankings/RankingsOverlayHeader.cs +++ b/osu.Game/Overlays/Rankings/RankingsOverlayHeader.cs @@ -30,6 +30,7 @@ namespace osu.Game.Overlays.Rankings public RankingsTitle() { Title = "ranking"; + Description = "Find out who's the best right now"; IconTexture = "Icons/rankings"; } } diff --git a/osu.Game/Overlays/RankingsOverlay.cs b/osu.Game/Overlays/RankingsOverlay.cs index 7b200d4226..6e8a7d8554 100644 --- a/osu.Game/Overlays/RankingsOverlay.cs +++ b/osu.Game/Overlays/RankingsOverlay.cs @@ -55,7 +55,7 @@ namespace osu.Game.Overlays Direction = FillDirection.Vertical, Children = new Drawable[] { - header = new RankingsOverlayHeader + Header = header = new RankingsOverlayHeader { Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, diff --git a/osu.Game/Overlays/SearchableList/SearchableListOverlay.cs b/osu.Game/Overlays/SearchableList/SearchableListOverlay.cs index 4ab2de06b6..da2066e677 100644 --- a/osu.Game/Overlays/SearchableList/SearchableListOverlay.cs +++ b/osu.Game/Overlays/SearchableList/SearchableListOverlay.cs @@ -29,7 +29,7 @@ namespace osu.Game.Overlays.SearchableList { private readonly Container scrollContainer; - protected readonly SearchableListHeader Header; + protected new readonly SearchableListHeader Header; protected readonly SearchableListFilterControl Filter; protected readonly FillFlowContainer ScrollFlow; diff --git a/osu.Game/Overlays/SettingsOverlay.cs b/osu.Game/Overlays/SettingsOverlay.cs index bb84de5d3a..9a7937dfce 100644 --- a/osu.Game/Overlays/SettingsOverlay.cs +++ b/osu.Game/Overlays/SettingsOverlay.cs @@ -13,8 +13,12 @@ using osu.Framework.Bindables; namespace osu.Game.Overlays { - public class SettingsOverlay : SettingsPanel + public class SettingsOverlay : SettingsPanel, INamedOverlayComponent { + public string IconTexture => "Icons/Hexacons/settings"; + public string Title => "Settings"; + public string Description => "Change your settings"; + protected override IEnumerable CreateSections() => new SettingsSection[] { new GeneralSection(), diff --git a/osu.Game/Overlays/Toolbar/ToolbarBeatmapListingButton.cs b/osu.Game/Overlays/Toolbar/ToolbarBeatmapListingButton.cs index cde305fffd..0363873326 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarBeatmapListingButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarBeatmapListingButton.cs @@ -2,7 +2,6 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Allocation; -using osu.Game.Graphics; using osu.Game.Input.Bindings; namespace osu.Game.Overlays.Toolbar @@ -11,10 +10,6 @@ namespace osu.Game.Overlays.Toolbar { public ToolbarBeatmapListingButton() { - SetIcon(OsuIcon.ChevronDownCircle); - TooltipMain = "Beatmap listing"; - TooltipSub = "Browse for new beatmaps"; - Hotkey = GlobalAction.ToggleDirect; } diff --git a/osu.Game/Overlays/Toolbar/ToolbarButton.cs b/osu.Game/Overlays/Toolbar/ToolbarButton.cs index 0afc6642b2..5d402c9a23 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarButton.cs @@ -35,17 +35,6 @@ namespace osu.Game.Overlays.Toolbar IconContainer.Show(); } - public void SetIcon(IconUsage icon) => SetIcon(new SpriteIcon - { - Size = new Vector2(20), - Icon = icon - }); - - public IconUsage Icon - { - set => SetIcon(value); - } - public string Text { get => DrawableText.Text; diff --git a/osu.Game/Overlays/Toolbar/ToolbarChangelogButton.cs b/osu.Game/Overlays/Toolbar/ToolbarChangelogButton.cs index c88b418853..23f8b141b2 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarChangelogButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarChangelogButton.cs @@ -2,19 +2,11 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Allocation; -using osu.Framework.Graphics.Sprites; namespace osu.Game.Overlays.Toolbar { public class ToolbarChangelogButton : ToolbarOverlayToggleButton { - public ToolbarChangelogButton() - { - SetIcon(FontAwesome.Solid.Bullhorn); - TooltipMain = "Changelog"; - TooltipSub = "Track recent dev updates in the osu! ecosystem"; - } - [BackgroundDependencyLoader(true)] private void load(ChangelogOverlay changelog) { diff --git a/osu.Game/Overlays/Toolbar/ToolbarChatButton.cs b/osu.Game/Overlays/Toolbar/ToolbarChatButton.cs index dee4be0c1f..f9a66ae7bb 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarChatButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarChatButton.cs @@ -2,7 +2,6 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Allocation; -using osu.Framework.Graphics.Sprites; using osu.Game.Input.Bindings; namespace osu.Game.Overlays.Toolbar @@ -11,10 +10,6 @@ namespace osu.Game.Overlays.Toolbar { public ToolbarChatButton() { - SetIcon(FontAwesome.Solid.Comments); - TooltipMain = "Chat"; - TooltipSub = "Join the real-time discussion"; - Hotkey = GlobalAction.ToggleChat; } diff --git a/osu.Game/Overlays/Toolbar/ToolbarHomeButton.cs b/osu.Game/Overlays/Toolbar/ToolbarHomeButton.cs index 4845c9a99f..08ba65fc47 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarHomeButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarHomeButton.cs @@ -1,7 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using osu.Framework.Graphics.Sprites; using osu.Game.Input.Bindings; namespace osu.Game.Overlays.Toolbar @@ -10,7 +9,7 @@ namespace osu.Game.Overlays.Toolbar { public ToolbarHomeButton() { - Icon = FontAwesome.Solid.Home; + // todo: icon TooltipMain = "Home"; TooltipSub = "Return to the main menu"; diff --git a/osu.Game/Overlays/Toolbar/ToolbarMusicButton.cs b/osu.Game/Overlays/Toolbar/ToolbarMusicButton.cs index f9aa2de497..0f5e8e5456 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarMusicButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarMusicButton.cs @@ -3,7 +3,6 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; -using osu.Framework.Graphics.Sprites; using osu.Game.Input.Bindings; namespace osu.Game.Overlays.Toolbar @@ -14,10 +13,6 @@ namespace osu.Game.Overlays.Toolbar public ToolbarMusicButton() { - Icon = FontAwesome.Solid.Music; - TooltipMain = "Now playing"; - TooltipSub = "Manage the currently playing track"; - Hotkey = GlobalAction.ToggleNowPlaying; } diff --git a/osu.Game/Overlays/Toolbar/ToolbarNewsButton.cs b/osu.Game/Overlays/Toolbar/ToolbarNewsButton.cs index 106c67a041..0ba2935c80 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarNewsButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarNewsButton.cs @@ -2,19 +2,11 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Allocation; -using osu.Framework.Graphics.Sprites; namespace osu.Game.Overlays.Toolbar { public class ToolbarNewsButton : ToolbarOverlayToggleButton { - public ToolbarNewsButton() - { - Icon = FontAwesome.Solid.Newspaper; - TooltipMain = "News"; - TooltipSub = "Get up-to-date on community happenings"; - } - [BackgroundDependencyLoader(true)] private void load(NewsOverlay news) { diff --git a/osu.Game/Overlays/Toolbar/ToolbarNotificationButton.cs b/osu.Game/Overlays/Toolbar/ToolbarNotificationButton.cs index a699fd907f..79d0fc74c1 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarNotificationButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarNotificationButton.cs @@ -6,7 +6,6 @@ using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; -using osu.Framework.Graphics.Sprites; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Input.Bindings; @@ -25,10 +24,6 @@ namespace osu.Game.Overlays.Toolbar public ToolbarNotificationButton() { - Icon = FontAwesome.Solid.Bars; - TooltipMain = "Notifications"; - TooltipSub = "Waiting for 'ya"; - Hotkey = GlobalAction.ToggleNotifications; Add(countDisplay = new CountCircle diff --git a/osu.Game/Overlays/Toolbar/ToolbarOverlayToggleButton.cs b/osu.Game/Overlays/Toolbar/ToolbarOverlayToggleButton.cs index 36387bb00d..a76ca26a47 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarOverlayToggleButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarOverlayToggleButton.cs @@ -1,11 +1,14 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Graphics.Textures; using osu.Game.Graphics; namespace osu.Game.Overlays.Toolbar @@ -18,6 +21,9 @@ namespace osu.Game.Overlays.Toolbar private readonly Bindable overlayState = new Bindable(); + [Resolved] + private TextureStore textures { get; set; } + public OverlayContainer StateContainer { get => stateContainer; @@ -32,6 +38,16 @@ namespace osu.Game.Overlays.Toolbar Action = stateContainer.ToggleVisibility; overlayState.BindTo(stateContainer.State); } + + if (stateContainer is INamedOverlayComponent named) + { + TooltipMain = named.Title; + TooltipSub = named.Description; + SetIcon(new Sprite + { + Texture = textures.Get(named.IconTexture), + }); + } } } diff --git a/osu.Game/Overlays/Toolbar/ToolbarRankingsButton.cs b/osu.Game/Overlays/Toolbar/ToolbarRankingsButton.cs index c026ce99fe..22a01bcdb5 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarRankingsButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarRankingsButton.cs @@ -2,19 +2,11 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Allocation; -using osu.Framework.Graphics.Sprites; namespace osu.Game.Overlays.Toolbar { public class ToolbarRankingsButton : ToolbarOverlayToggleButton { - public ToolbarRankingsButton() - { - SetIcon(FontAwesome.Regular.ChartBar); - TooltipMain = "Ranking"; - TooltipSub = "Find out who's the best right now"; - } - [BackgroundDependencyLoader(true)] private void load(RankingsOverlay rankings) { diff --git a/osu.Game/Overlays/Toolbar/ToolbarSettingsButton.cs b/osu.Game/Overlays/Toolbar/ToolbarSettingsButton.cs index ed2a23ec2a..4051a2a194 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarSettingsButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarSettingsButton.cs @@ -2,7 +2,6 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Allocation; -using osu.Framework.Graphics.Sprites; using osu.Game.Input.Bindings; namespace osu.Game.Overlays.Toolbar @@ -11,10 +10,6 @@ namespace osu.Game.Overlays.Toolbar { public ToolbarSettingsButton() { - Icon = FontAwesome.Solid.Cog; - TooltipMain = "Settings"; - TooltipSub = "Change your settings"; - Hotkey = GlobalAction.ToggleSettings; } diff --git a/osu.Game/Overlays/Toolbar/ToolbarSocialButton.cs b/osu.Game/Overlays/Toolbar/ToolbarSocialButton.cs index 6faa58c559..e62c7bc807 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarSocialButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarSocialButton.cs @@ -2,7 +2,6 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Allocation; -using osu.Framework.Graphics.Sprites; using osu.Game.Input.Bindings; namespace osu.Game.Overlays.Toolbar @@ -11,10 +10,6 @@ namespace osu.Game.Overlays.Toolbar { public ToolbarSocialButton() { - Icon = FontAwesome.Solid.Users; - TooltipMain = "Friends"; - TooltipSub = "Interact with those close to you"; - Hotkey = GlobalAction.ToggleSocial; } diff --git a/osu.Game/Overlays/UserProfileOverlay.cs b/osu.Game/Overlays/UserProfileOverlay.cs index b4c8a2d3ca..625758614e 100644 --- a/osu.Game/Overlays/UserProfileOverlay.cs +++ b/osu.Game/Overlays/UserProfileOverlay.cs @@ -22,7 +22,7 @@ namespace osu.Game.Overlays private ProfileSection lastSection; private ProfileSection[] sections; private GetUserRequest userReq; - protected ProfileHeader Header; + protected new ProfileHeader Header; private ProfileSectionsContainer sectionsContainer; private ProfileSectionTabControl tabs; @@ -77,7 +77,7 @@ namespace osu.Game.Overlays Add(sectionsContainer = new ProfileSectionsContainer { - ExpandableHeader = Header = new ProfileHeader(), + ExpandableHeader = base.Header = Header = new ProfileHeader(), FixedHeader = tabs, HeaderBackground = new Box { From dbf44fbaf265b2bf7142e57370e5764d7f7269ca Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 3 Sep 2020 16:26:09 +0900 Subject: [PATCH 247/320] Update names and icons to match new designs --- osu.Game/Overlays/BeatmapSet/BeatmapSetHeader.cs | 2 +- osu.Game/Overlays/Changelog/ChangelogHeader.cs | 2 +- osu.Game/Overlays/ChatOverlay.cs | 4 ++-- osu.Game/Overlays/Dashboard/DashboardOverlayHeader.cs | 4 ++-- osu.Game/Overlays/News/NewsHeader.cs | 2 +- osu.Game/Overlays/NowPlayingOverlay.cs | 2 +- osu.Game/Overlays/Profile/ProfileHeader.cs | 2 +- osu.Game/Overlays/Rankings/RankingsOverlayHeader.cs | 2 +- 8 files changed, 10 insertions(+), 10 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/BeatmapSetHeader.cs b/osu.Game/Overlays/BeatmapSet/BeatmapSetHeader.cs index 4626589d81..329045c743 100644 --- a/osu.Game/Overlays/BeatmapSet/BeatmapSetHeader.cs +++ b/osu.Game/Overlays/BeatmapSet/BeatmapSetHeader.cs @@ -25,7 +25,7 @@ namespace osu.Game.Overlays.BeatmapSet public BeatmapHeaderTitle() { Title = "beatmap info"; - IconTexture = "Icons/changelog"; + IconTexture = "Icons/Hexacons/music"; } } } diff --git a/osu.Game/Overlays/Changelog/ChangelogHeader.cs b/osu.Game/Overlays/Changelog/ChangelogHeader.cs index 35a4fc7014..bdc59297bb 100644 --- a/osu.Game/Overlays/Changelog/ChangelogHeader.cs +++ b/osu.Game/Overlays/Changelog/ChangelogHeader.cs @@ -116,7 +116,7 @@ namespace osu.Game.Overlays.Changelog { Title = "changelog"; Description = "Track recent dev updates in the osu! ecosystem"; - IconTexture = "Icons/changelog"; + IconTexture = "Icons/Hexacons/devtools"; } } } diff --git a/osu.Game/Overlays/ChatOverlay.cs b/osu.Game/Overlays/ChatOverlay.cs index 8e34f5d2c0..bcc2227be8 100644 --- a/osu.Game/Overlays/ChatOverlay.cs +++ b/osu.Game/Overlays/ChatOverlay.cs @@ -28,8 +28,8 @@ namespace osu.Game.Overlays { public class ChatOverlay : OsuFocusedOverlayContainer, INamedOverlayComponent { - public string IconTexture => "Icons/chat"; - public string Title => "Chat"; + public string IconTexture => "Icons/Hexacons/messaging"; + public string Title => "chat"; public string Description => "Join the real-time discussion"; private const float textbox_height = 60; diff --git a/osu.Game/Overlays/Dashboard/DashboardOverlayHeader.cs b/osu.Game/Overlays/Dashboard/DashboardOverlayHeader.cs index 1330a44374..a964d84c4f 100644 --- a/osu.Game/Overlays/Dashboard/DashboardOverlayHeader.cs +++ b/osu.Game/Overlays/Dashboard/DashboardOverlayHeader.cs @@ -12,8 +12,8 @@ namespace osu.Game.Overlays.Dashboard public DashboardTitle() { Title = "dashboard"; - Description = "View your friends and other top level information"; - IconTexture = "Icons/hexacons/dashboard"; + Description = "View your friends and other information"; + IconTexture = "Icons/Hexacons/social"; } } } diff --git a/osu.Game/Overlays/News/NewsHeader.cs b/osu.Game/Overlays/News/NewsHeader.cs index f85d765d46..38ac519387 100644 --- a/osu.Game/Overlays/News/NewsHeader.cs +++ b/osu.Game/Overlays/News/NewsHeader.cs @@ -58,7 +58,7 @@ namespace osu.Game.Overlays.News { Title = "news"; Description = "Get up-to-date on community happenings"; - IconTexture = "Icons/news"; + IconTexture = "Icons/Hexacons/news"; } } } diff --git a/osu.Game/Overlays/NowPlayingOverlay.cs b/osu.Game/Overlays/NowPlayingOverlay.cs index f19f7bbc61..d1df1fa936 100644 --- a/osu.Game/Overlays/NowPlayingOverlay.cs +++ b/osu.Game/Overlays/NowPlayingOverlay.cs @@ -28,7 +28,7 @@ namespace osu.Game.Overlays public class NowPlayingOverlay : OsuFocusedOverlayContainer, INamedOverlayComponent { public string IconTexture => "Icons/Hexacons/music"; - public string Title => "Now playing"; + public string Title => "now playing"; public string Description => "Manage the currently playing track"; private const float player_height = 130; diff --git a/osu.Game/Overlays/Profile/ProfileHeader.cs b/osu.Game/Overlays/Profile/ProfileHeader.cs index 55474c9d3e..c947ef0781 100644 --- a/osu.Game/Overlays/Profile/ProfileHeader.cs +++ b/osu.Game/Overlays/Profile/ProfileHeader.cs @@ -97,7 +97,7 @@ namespace osu.Game.Overlays.Profile public ProfileHeaderTitle() { Title = "player info"; - IconTexture = "Icons/profile"; + IconTexture = "Icons/Hexacons/profile"; } } diff --git a/osu.Game/Overlays/Rankings/RankingsOverlayHeader.cs b/osu.Game/Overlays/Rankings/RankingsOverlayHeader.cs index b12294c6c1..7039ab8214 100644 --- a/osu.Game/Overlays/Rankings/RankingsOverlayHeader.cs +++ b/osu.Game/Overlays/Rankings/RankingsOverlayHeader.cs @@ -31,7 +31,7 @@ namespace osu.Game.Overlays.Rankings { Title = "ranking"; Description = "Find out who's the best right now"; - IconTexture = "Icons/rankings"; + IconTexture = "Icons/Hexacons/rankings"; } } } From 7bcbac6f45000482ed566b7be6b221eef639d05b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 3 Sep 2020 16:27:31 +0900 Subject: [PATCH 248/320] Move header setting to FullscreenOverlay --- .../Online/TestSceneFullscreenOverlay.cs | 6 ++--- osu.Game/Overlays/BeatmapListingOverlay.cs | 6 ++--- osu.Game/Overlays/BeatmapSetOverlay.cs | 4 ++-- osu.Game/Overlays/ChangelogOverlay.cs | 14 +++++------ osu.Game/Overlays/DashboardOverlay.cs | 23 +++++++++---------- osu.Game/Overlays/FullscreenOverlay.cs | 9 +++++--- osu.Game/Overlays/NewsOverlay.cs | 16 ++++++------- osu.Game/Overlays/OverlayScrollContainer.cs | 2 +- osu.Game/Overlays/OverlayView.cs | 2 +- osu.Game/Overlays/RankingsOverlay.cs | 23 +++++++++---------- osu.Game/Overlays/UserProfileOverlay.cs | 7 +++--- 11 files changed, 54 insertions(+), 58 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneFullscreenOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneFullscreenOverlay.cs index e60adcee34..8f20bcdcc1 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneFullscreenOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneFullscreenOverlay.cs @@ -12,7 +12,7 @@ namespace osu.Game.Tests.Visual.Online [TestFixture] public class TestSceneFullscreenOverlay : OsuTestScene { - private FullscreenOverlay overlay; + private FullscreenOverlay overlay; protected override void LoadComplete() { @@ -38,10 +38,10 @@ namespace osu.Game.Tests.Visual.Online AddAssert("fire count 3", () => fireCount == 3); } - private class TestFullscreenOverlay : FullscreenOverlay + private class TestFullscreenOverlay : FullscreenOverlay { public TestFullscreenOverlay() - : base(OverlayColourScheme.Pink) + : base(OverlayColourScheme.Pink, null) { Children = new Drawable[] { diff --git a/osu.Game/Overlays/BeatmapListingOverlay.cs b/osu.Game/Overlays/BeatmapListingOverlay.cs index 225a8a0578..144af91145 100644 --- a/osu.Game/Overlays/BeatmapListingOverlay.cs +++ b/osu.Game/Overlays/BeatmapListingOverlay.cs @@ -24,7 +24,7 @@ using osuTK; namespace osu.Game.Overlays { - public class BeatmapListingOverlay : FullscreenOverlay + public class BeatmapListingOverlay : FullscreenOverlay { [Resolved] private PreviewTrackManager previewTrackManager { get; set; } @@ -38,7 +38,7 @@ namespace osu.Game.Overlays private OverlayScrollContainer resultScrollContainer; public BeatmapListingOverlay() - : base(OverlayColourScheme.Blue) + : base(OverlayColourScheme.Blue, new BeatmapListingHeader()) { } @@ -65,7 +65,7 @@ namespace osu.Game.Overlays Direction = FillDirection.Vertical, Children = new Drawable[] { - new BeatmapListingHeader(), + Header, filterControl = new BeatmapListingFilterControl { SearchStarted = onSearchStarted, diff --git a/osu.Game/Overlays/BeatmapSetOverlay.cs b/osu.Game/Overlays/BeatmapSetOverlay.cs index 2dfd1fa20f..bbec62a85a 100644 --- a/osu.Game/Overlays/BeatmapSetOverlay.cs +++ b/osu.Game/Overlays/BeatmapSetOverlay.cs @@ -19,7 +19,7 @@ using osuTK; namespace osu.Game.Overlays { - public class BeatmapSetOverlay : FullscreenOverlay + public class BeatmapSetOverlay : FullscreenOverlay // we don't provide a standard header for now. { public const float X_PADDING = 40; public const float Y_PADDING = 25; @@ -39,7 +39,7 @@ namespace osu.Game.Overlays private readonly Box background; public BeatmapSetOverlay() - : base(OverlayColourScheme.Blue) + : base(OverlayColourScheme.Blue, null) { OverlayScrollContainer scroll; Info info; diff --git a/osu.Game/Overlays/ChangelogOverlay.cs b/osu.Game/Overlays/ChangelogOverlay.cs index e9520906ea..c7e9a86fa4 100644 --- a/osu.Game/Overlays/ChangelogOverlay.cs +++ b/osu.Game/Overlays/ChangelogOverlay.cs @@ -21,14 +21,12 @@ using osu.Game.Overlays.Changelog; namespace osu.Game.Overlays { - public class ChangelogOverlay : FullscreenOverlay + public class ChangelogOverlay : FullscreenOverlay { public readonly Bindable Current = new Bindable(); private Container content; - protected new ChangelogHeader Header; - private SampleChannel sampleBack; private List builds; @@ -36,7 +34,7 @@ namespace osu.Game.Overlays protected List Streams; public ChangelogOverlay() - : base(OverlayColourScheme.Purple) + : base(OverlayColourScheme.Purple, new ChangelogHeader()) { } @@ -61,11 +59,11 @@ namespace osu.Game.Overlays Direction = FillDirection.Vertical, Children = new Drawable[] { - base.Header = Header = new ChangelogHeader + Header.With(h => { - ListingSelected = ShowListing, - Build = { BindTarget = Current } - }, + h.ListingSelected = ShowListing; + h.Build.BindTarget = Current; + }), content = new Container { RelativeSizeAxes = Axes.X, diff --git a/osu.Game/Overlays/DashboardOverlay.cs b/osu.Game/Overlays/DashboardOverlay.cs index 68eb35c7da..8135b83a03 100644 --- a/osu.Game/Overlays/DashboardOverlay.cs +++ b/osu.Game/Overlays/DashboardOverlay.cs @@ -15,17 +15,21 @@ using osu.Game.Overlays.Dashboard.Friends; namespace osu.Game.Overlays { - public class DashboardOverlay : FullscreenOverlay + public class DashboardOverlay : FullscreenOverlay { private CancellationTokenSource cancellationToken; private Container content; - private DashboardOverlayHeader header; private LoadingLayer loading; private OverlayScrollContainer scrollFlow; public DashboardOverlay() - : base(OverlayColourScheme.Purple) + : base(OverlayColourScheme.Purple, new DashboardOverlayHeader + { + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + Depth = -float.MaxValue + }) { } @@ -50,12 +54,7 @@ namespace osu.Game.Overlays Direction = FillDirection.Vertical, Children = new Drawable[] { - Header = header = new DashboardOverlayHeader - { - Anchor = Anchor.TopCentre, - Origin = Anchor.TopCentre, - Depth = -float.MaxValue - }, + Header, content = new Container { RelativeSizeAxes = Axes.X, @@ -72,7 +71,7 @@ namespace osu.Game.Overlays { base.LoadComplete(); - header.Current.BindValueChanged(onTabChanged); + Header.Current.BindValueChanged(onTabChanged); } private bool displayUpdateRequired = true; @@ -84,7 +83,7 @@ namespace osu.Game.Overlays // We don't want to create a new display on every call, only when exiting from fully closed state. if (displayUpdateRequired) { - header.Current.TriggerChange(); + Header.Current.TriggerChange(); displayUpdateRequired = false; } } @@ -136,7 +135,7 @@ namespace osu.Game.Overlays if (State.Value == Visibility.Hidden) return; - header.Current.TriggerChange(); + Header.Current.TriggerChange(); } protected override void Dispose(bool isDisposing) diff --git a/osu.Game/Overlays/FullscreenOverlay.cs b/osu.Game/Overlays/FullscreenOverlay.cs index 6d0441ff46..bd6b07c65f 100644 --- a/osu.Game/Overlays/FullscreenOverlay.cs +++ b/osu.Game/Overlays/FullscreenOverlay.cs @@ -12,13 +12,14 @@ using osuTK.Graphics; namespace osu.Game.Overlays { - public abstract class FullscreenOverlay : WaveOverlayContainer, IOnlineComponent, INamedOverlayComponent + public abstract class FullscreenOverlay : WaveOverlayContainer, IOnlineComponent, INamedOverlayComponent + where T : OverlayHeader { public virtual string IconTexture => Header?.Title.IconTexture ?? string.Empty; public virtual string Title => Header?.Title.Title ?? string.Empty; public virtual string Description => Header?.Title.Description ?? string.Empty; - public OverlayHeader Header { get; protected set; } + public T Header { get; } [Resolved] protected IAPIProvider API { get; private set; } @@ -26,8 +27,10 @@ namespace osu.Game.Overlays [Cached] protected readonly OverlayColourProvider ColourProvider; - protected FullscreenOverlay(OverlayColourScheme colourScheme) + protected FullscreenOverlay(OverlayColourScheme colourScheme, T header) { + Header = header; + ColourProvider = new OverlayColourProvider(colourScheme); RelativeSizeAxes = Axes.Both; diff --git a/osu.Game/Overlays/NewsOverlay.cs b/osu.Game/Overlays/NewsOverlay.cs index bc3e080158..c8c1db012f 100644 --- a/osu.Game/Overlays/NewsOverlay.cs +++ b/osu.Game/Overlays/NewsOverlay.cs @@ -13,7 +13,7 @@ using osu.Game.Overlays.News.Displays; namespace osu.Game.Overlays { - public class NewsOverlay : FullscreenOverlay + public class NewsOverlay : FullscreenOverlay { private readonly Bindable article = new Bindable(null); @@ -22,7 +22,7 @@ namespace osu.Game.Overlays private OverlayScrollContainer scrollFlow; public NewsOverlay() - : base(OverlayColourScheme.Purple) + : base(OverlayColourScheme.Purple, new NewsHeader()) { } @@ -47,10 +47,10 @@ namespace osu.Game.Overlays Direction = FillDirection.Vertical, Children = new Drawable[] { - Header = new NewsHeader + Header.With(h => { - ShowFrontPage = ShowFrontPage - }, + h.ShowFrontPage = ShowFrontPage; + }), content = new Container { RelativeSizeAxes = Axes.X, @@ -109,16 +109,14 @@ namespace osu.Game.Overlays cancellationToken?.Cancel(); loading.Show(); - var header = (NewsHeader)Header; - if (e.NewValue == null) { - header.SetFrontPage(); + Header.SetFrontPage(); LoadDisplay(new FrontPageDisplay()); return; } - header.SetArticle(e.NewValue); + Header.SetArticle(e.NewValue); LoadDisplay(Empty()); } diff --git a/osu.Game/Overlays/OverlayScrollContainer.cs b/osu.Game/Overlays/OverlayScrollContainer.cs index e7415e6f74..b67d5db1a4 100644 --- a/osu.Game/Overlays/OverlayScrollContainer.cs +++ b/osu.Game/Overlays/OverlayScrollContainer.cs @@ -17,7 +17,7 @@ using osuTK.Graphics; namespace osu.Game.Overlays { /// - /// which provides . Mostly used in . + /// which provides . Mostly used in . /// public class OverlayScrollContainer : OsuScrollContainer { diff --git a/osu.Game/Overlays/OverlayView.cs b/osu.Game/Overlays/OverlayView.cs index 3e2c54c726..312271316a 100644 --- a/osu.Game/Overlays/OverlayView.cs +++ b/osu.Game/Overlays/OverlayView.cs @@ -9,7 +9,7 @@ using osu.Game.Online.API; namespace osu.Game.Overlays { /// - /// A subview containing online content, to be displayed inside a . + /// A subview containing online content, to be displayed inside a . /// /// /// Automatically performs a data fetch on load. diff --git a/osu.Game/Overlays/RankingsOverlay.cs b/osu.Game/Overlays/RankingsOverlay.cs index 6e8a7d8554..ae6d49960a 100644 --- a/osu.Game/Overlays/RankingsOverlay.cs +++ b/osu.Game/Overlays/RankingsOverlay.cs @@ -17,17 +17,16 @@ using osu.Game.Overlays.Rankings.Tables; namespace osu.Game.Overlays { - public class RankingsOverlay : FullscreenOverlay + public class RankingsOverlay : FullscreenOverlay { - protected Bindable Country => header.Country; + protected Bindable Country => Header.Country; - protected Bindable Scope => header.Current; + protected Bindable Scope => Header.Current; private readonly OverlayScrollContainer scrollFlow; private readonly Container contentContainer; private readonly LoadingLayer loading; private readonly Box background; - private readonly RankingsOverlayHeader header; private APIRequest lastRequest; private CancellationTokenSource cancellationToken; @@ -36,7 +35,12 @@ namespace osu.Game.Overlays private IAPIProvider api { get; set; } public RankingsOverlay() - : base(OverlayColourScheme.Green) + : base(OverlayColourScheme.Green, new RankingsOverlayHeader + { + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + Depth = -float.MaxValue + }) { Children = new Drawable[] { @@ -55,12 +59,7 @@ namespace osu.Game.Overlays Direction = FillDirection.Vertical, Children = new Drawable[] { - Header = header = new RankingsOverlayHeader - { - Anchor = Anchor.TopCentre, - Origin = Anchor.TopCentre, - Depth = -float.MaxValue - }, + Header, new Container { RelativeSizeAxes = Axes.X, @@ -97,7 +96,7 @@ namespace osu.Game.Overlays { base.LoadComplete(); - header.Ruleset.BindTo(ruleset); + Header.Ruleset.BindTo(ruleset); Country.BindValueChanged(_ => { diff --git a/osu.Game/Overlays/UserProfileOverlay.cs b/osu.Game/Overlays/UserProfileOverlay.cs index 625758614e..965ad790ed 100644 --- a/osu.Game/Overlays/UserProfileOverlay.cs +++ b/osu.Game/Overlays/UserProfileOverlay.cs @@ -17,19 +17,18 @@ using osuTK; namespace osu.Game.Overlays { - public class UserProfileOverlay : FullscreenOverlay + public class UserProfileOverlay : FullscreenOverlay { private ProfileSection lastSection; private ProfileSection[] sections; private GetUserRequest userReq; - protected new ProfileHeader Header; private ProfileSectionsContainer sectionsContainer; private ProfileSectionTabControl tabs; public const float CONTENT_X_MARGIN = 70; public UserProfileOverlay() - : base(OverlayColourScheme.Pink) + : base(OverlayColourScheme.Pink, new ProfileHeader()) { } @@ -77,7 +76,7 @@ namespace osu.Game.Overlays Add(sectionsContainer = new ProfileSectionsContainer { - ExpandableHeader = base.Header = Header = new ProfileHeader(), + ExpandableHeader = Header, FixedHeader = tabs, HeaderBackground = new Box { From 942276d88f10e83fb8eb1ddb4894583f94876a0f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 3 Sep 2020 16:28:14 +0900 Subject: [PATCH 249/320] Remove outdated SearchableList classes --- .../Chat/Selection/ChannelSelectionOverlay.cs | 2 +- .../SearchableListFilterControl.cs | 2 +- .../SearchableList/SearchableListHeader.cs | 82 ----------- .../SearchableList/SearchableListOverlay.cs | 128 ------------------ osu.Game/Overlays/WaveOverlayContainer.cs | 2 + osu.Game/Screens/Multi/Header.cs | 4 +- .../Screens/Multi/Lounge/LoungeSubScreen.cs | 5 +- .../Match/Components/MatchSettingsOverlay.cs | 4 +- 8 files changed, 10 insertions(+), 219 deletions(-) delete mode 100644 osu.Game/Overlays/SearchableList/SearchableListHeader.cs delete mode 100644 osu.Game/Overlays/SearchableList/SearchableListOverlay.cs diff --git a/osu.Game/Overlays/Chat/Selection/ChannelSelectionOverlay.cs b/osu.Game/Overlays/Chat/Selection/ChannelSelectionOverlay.cs index b46ca6b040..be9ecc6746 100644 --- a/osu.Game/Overlays/Chat/Selection/ChannelSelectionOverlay.cs +++ b/osu.Game/Overlays/Chat/Selection/ChannelSelectionOverlay.cs @@ -22,7 +22,7 @@ namespace osu.Game.Overlays.Chat.Selection { public class ChannelSelectionOverlay : WaveOverlayContainer { - public const float WIDTH_PADDING = 170; + public new const float WIDTH_PADDING = 170; private const float transition_duration = 500; diff --git a/osu.Game/Overlays/SearchableList/SearchableListFilterControl.cs b/osu.Game/Overlays/SearchableList/SearchableListFilterControl.cs index e0163b5b0c..1990674aa9 100644 --- a/osu.Game/Overlays/SearchableList/SearchableListFilterControl.cs +++ b/osu.Game/Overlays/SearchableList/SearchableListFilterControl.cs @@ -36,7 +36,7 @@ namespace osu.Game.Overlays.SearchableList /// /// The amount of padding added to content (does not affect background or tab control strip). /// - protected virtual float ContentHorizontalPadding => SearchableListOverlay.WIDTH_PADDING; + protected virtual float ContentHorizontalPadding => WaveOverlayContainer.WIDTH_PADDING; protected SearchableListFilterControl() { diff --git a/osu.Game/Overlays/SearchableList/SearchableListHeader.cs b/osu.Game/Overlays/SearchableList/SearchableListHeader.cs deleted file mode 100644 index 66fedf0a56..0000000000 --- a/osu.Game/Overlays/SearchableList/SearchableListHeader.cs +++ /dev/null @@ -1,82 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using System; -using osuTK; -using osuTK.Graphics; -using osu.Framework.Allocation; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Game.Graphics; -using osu.Framework.Graphics.Shapes; -using osu.Framework.Graphics.Sprites; - -namespace osu.Game.Overlays.SearchableList -{ - public abstract class SearchableListHeader : Container - where T : struct, Enum - { - public readonly HeaderTabControl Tabs; - - protected abstract Color4 BackgroundColour { get; } - protected abstract T DefaultTab { get; } - protected abstract Drawable CreateHeaderText(); - protected abstract IconUsage Icon { get; } - - protected SearchableListHeader() - { - RelativeSizeAxes = Axes.X; - Height = 90; - - Children = new Drawable[] - { - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = BackgroundColour, - }, - new Container - { - RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding { Left = SearchableListOverlay.WIDTH_PADDING, Right = SearchableListOverlay.WIDTH_PADDING }, - Children = new Drawable[] - { - new FillFlowContainer - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.BottomLeft, - Position = new Vector2(-35f, 5f), - AutoSizeAxes = Axes.Both, - Direction = FillDirection.Horizontal, - Spacing = new Vector2(10f, 0f), - Children = new[] - { - new SpriteIcon - { - Size = new Vector2(25), - Icon = Icon, - }, - CreateHeaderText(), - }, - }, - Tabs = new HeaderTabControl - { - Anchor = Anchor.BottomLeft, - Origin = Anchor.BottomLeft, - RelativeSizeAxes = Axes.X, - }, - }, - }, - }; - - Tabs.Current.Value = DefaultTab; - Tabs.Current.TriggerChange(); - } - - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { - Tabs.StripColour = colours.Green; - } - } -} diff --git a/osu.Game/Overlays/SearchableList/SearchableListOverlay.cs b/osu.Game/Overlays/SearchableList/SearchableListOverlay.cs deleted file mode 100644 index da2066e677..0000000000 --- a/osu.Game/Overlays/SearchableList/SearchableListOverlay.cs +++ /dev/null @@ -1,128 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using System; -using osuTK.Graphics; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Shapes; -using osu.Framework.Input.Events; -using osu.Game.Graphics.Backgrounds; -using osu.Game.Graphics.Cursor; - -namespace osu.Game.Overlays.SearchableList -{ - public abstract class SearchableListOverlay : FullscreenOverlay - { - public const float WIDTH_PADDING = 80; - - protected SearchableListOverlay(OverlayColourScheme colourScheme) - : base(colourScheme) - { - } - } - - public abstract class SearchableListOverlay : SearchableListOverlay - where THeader : struct, Enum - where TTab : struct, Enum - where TCategory : struct, Enum - { - private readonly Container scrollContainer; - - protected new readonly SearchableListHeader Header; - protected readonly SearchableListFilterControl Filter; - protected readonly FillFlowContainer ScrollFlow; - - protected abstract Color4 BackgroundColour { get; } - protected abstract Color4 TrianglesColourLight { get; } - protected abstract Color4 TrianglesColourDark { get; } - protected abstract SearchableListHeader CreateHeader(); - protected abstract SearchableListFilterControl CreateFilterControl(); - - protected SearchableListOverlay(OverlayColourScheme colourScheme) - : base(colourScheme) - { - Children = new Drawable[] - { - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = BackgroundColour, - }, - new Container - { - RelativeSizeAxes = Axes.Both, - Masking = true, - Children = new[] - { - new Triangles - { - RelativeSizeAxes = Axes.Both, - TriangleScale = 5, - ColourLight = TrianglesColourLight, - ColourDark = TrianglesColourDark, - }, - }, - }, - scrollContainer = new Container - { - RelativeSizeAxes = Axes.Both, - Child = new OsuContextMenuContainer - { - RelativeSizeAxes = Axes.Both, - Masking = true, - Child = new OverlayScrollContainer - { - RelativeSizeAxes = Axes.Both, - ScrollbarVisible = false, - Child = ScrollFlow = new FillFlowContainer - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Padding = new MarginPadding { Horizontal = 10, Bottom = 50 }, - Direction = FillDirection.Vertical, - }, - }, - }, - }, - new FillFlowContainer - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Direction = FillDirection.Vertical, - Children = new Drawable[] - { - Header = CreateHeader(), - Filter = CreateFilterControl(), - }, - }, - }; - } - - protected override void Update() - { - base.Update(); - - scrollContainer.Padding = new MarginPadding { Top = Header.Height + Filter.Height }; - } - - protected override void OnFocus(FocusEvent e) - { - Filter.Search.TakeFocus(); - } - - protected override void PopIn() - { - base.PopIn(); - - Filter.Search.HoldFocus = true; - } - - protected override void PopOut() - { - base.PopOut(); - - Filter.Search.HoldFocus = false; - } - } -} diff --git a/osu.Game/Overlays/WaveOverlayContainer.cs b/osu.Game/Overlays/WaveOverlayContainer.cs index 5c87096dd4..d0fa9987d5 100644 --- a/osu.Game/Overlays/WaveOverlayContainer.cs +++ b/osu.Game/Overlays/WaveOverlayContainer.cs @@ -14,6 +14,8 @@ namespace osu.Game.Overlays protected override bool BlockNonPositionalInput => true; protected override Container Content => Waves; + public const float WIDTH_PADDING = 80; + protected override bool StartHidden => true; protected WaveOverlayContainer() diff --git a/osu.Game/Screens/Multi/Header.cs b/osu.Game/Screens/Multi/Header.cs index 653cb3791a..cd8695286b 100644 --- a/osu.Game/Screens/Multi/Header.cs +++ b/osu.Game/Screens/Multi/Header.cs @@ -11,8 +11,8 @@ using osu.Framework.Graphics.UserInterface; using osu.Framework.Screens; using osu.Game.Graphics; using osu.Game.Graphics.UserInterface; -using osu.Game.Overlays.SearchableList; using osu.Game.Graphics.Sprites; +using osu.Game.Overlays; using osuTK; using osuTK.Graphics; @@ -42,7 +42,7 @@ namespace osu.Game.Screens.Multi Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding { Left = SearchableListOverlay.WIDTH_PADDING + OsuScreen.HORIZONTAL_OVERFLOW_PADDING }, + Padding = new MarginPadding { Left = WaveOverlayContainer.WIDTH_PADDING + OsuScreen.HORIZONTAL_OVERFLOW_PADDING }, Children = new Drawable[] { title = new MultiHeaderTitle diff --git a/osu.Game/Screens/Multi/Lounge/LoungeSubScreen.cs b/osu.Game/Screens/Multi/Lounge/LoungeSubScreen.cs index f9c5fd13a4..a1e99c83b2 100644 --- a/osu.Game/Screens/Multi/Lounge/LoungeSubScreen.cs +++ b/osu.Game/Screens/Multi/Lounge/LoungeSubScreen.cs @@ -12,7 +12,6 @@ using osu.Game.Graphics.Containers; using osu.Game.Graphics.UserInterface; using osu.Game.Online.Multiplayer; using osu.Game.Overlays; -using osu.Game.Overlays.SearchableList; using osu.Game.Screens.Multi.Lounge.Components; using osu.Game.Screens.Multi.Match; @@ -102,8 +101,8 @@ namespace osu.Game.Screens.Multi.Lounge content.Padding = new MarginPadding { Top = Filter.DrawHeight, - Left = SearchableListOverlay.WIDTH_PADDING - DrawableRoom.SELECTION_BORDER_WIDTH + HORIZONTAL_OVERFLOW_PADDING, - Right = SearchableListOverlay.WIDTH_PADDING + HORIZONTAL_OVERFLOW_PADDING, + Left = WaveOverlayContainer.WIDTH_PADDING - DrawableRoom.SELECTION_BORDER_WIDTH + HORIZONTAL_OVERFLOW_PADDING, + Right = WaveOverlayContainer.WIDTH_PADDING + HORIZONTAL_OVERFLOW_PADDING, }; } diff --git a/osu.Game/Screens/Multi/Match/Components/MatchSettingsOverlay.cs b/osu.Game/Screens/Multi/Match/Components/MatchSettingsOverlay.cs index 49a0fc434b..caefc194b1 100644 --- a/osu.Game/Screens/Multi/Match/Components/MatchSettingsOverlay.cs +++ b/osu.Game/Screens/Multi/Match/Components/MatchSettingsOverlay.cs @@ -14,7 +14,7 @@ using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; using osu.Game.Online.Multiplayer; -using osu.Game.Overlays.SearchableList; +using osu.Game.Overlays; using osuTK; using osuTK.Graphics; @@ -117,7 +117,7 @@ namespace osu.Game.Screens.Multi.Match.Components { new Container { - Padding = new MarginPadding { Horizontal = SearchableListOverlay.WIDTH_PADDING }, + Padding = new MarginPadding { Horizontal = WaveOverlayContainer.WIDTH_PADDING }, RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, Children = new Drawable[] From 98c5a04a09b715de91ed305c4313e6d2055db963 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 3 Sep 2020 16:28:53 +0900 Subject: [PATCH 250/320] Update home button --- osu.Game/Overlays/Toolbar/ToolbarButton.cs | 9 +++++++++ osu.Game/Overlays/Toolbar/ToolbarHomeButton.cs | 12 +++++++++--- .../Overlays/Toolbar/ToolbarOverlayToggleButton.cs | 11 +---------- 3 files changed, 19 insertions(+), 13 deletions(-) diff --git a/osu.Game/Overlays/Toolbar/ToolbarButton.cs b/osu.Game/Overlays/Toolbar/ToolbarButton.cs index 5d402c9a23..d0787664a0 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarButton.cs @@ -35,6 +35,15 @@ namespace osu.Game.Overlays.Toolbar IconContainer.Show(); } + [Resolved] + private TextureStore textures { get; set; } + + public void SetIcon(string texture) => + SetIcon(new Sprite + { + Texture = textures.Get(texture), + }); + public string Text { get => DrawableText.Text; diff --git a/osu.Game/Overlays/Toolbar/ToolbarHomeButton.cs b/osu.Game/Overlays/Toolbar/ToolbarHomeButton.cs index 08ba65fc47..6b2c24c0f3 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarHomeButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarHomeButton.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 osu.Framework.Allocation; using osu.Game.Input.Bindings; namespace osu.Game.Overlays.Toolbar @@ -9,11 +10,16 @@ namespace osu.Game.Overlays.Toolbar { public ToolbarHomeButton() { - // todo: icon + Width *= 1.4f; + Hotkey = GlobalAction.Home; + } + + [BackgroundDependencyLoader] + private void load() + { TooltipMain = "Home"; TooltipSub = "Return to the main menu"; - - Hotkey = GlobalAction.Home; + SetIcon("Icons/Hexacons/home"); } } } diff --git a/osu.Game/Overlays/Toolbar/ToolbarOverlayToggleButton.cs b/osu.Game/Overlays/Toolbar/ToolbarOverlayToggleButton.cs index a76ca26a47..0dea71cc08 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarOverlayToggleButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarOverlayToggleButton.cs @@ -1,14 +1,11 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; -using osu.Framework.Graphics.Sprites; -using osu.Framework.Graphics.Textures; using osu.Game.Graphics; namespace osu.Game.Overlays.Toolbar @@ -21,9 +18,6 @@ namespace osu.Game.Overlays.Toolbar private readonly Bindable overlayState = new Bindable(); - [Resolved] - private TextureStore textures { get; set; } - public OverlayContainer StateContainer { get => stateContainer; @@ -43,10 +37,7 @@ namespace osu.Game.Overlays.Toolbar { TooltipMain = named.Title; TooltipSub = named.Description; - SetIcon(new Sprite - { - Texture = textures.Get(named.IconTexture), - }); + SetIcon(named.IconTexture); } } } From 2fac0a180e0640362b8ce0294e261b3ac2134d5b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 3 Sep 2020 16:29:15 +0900 Subject: [PATCH 251/320] Adjust toolbar button sizing --- osu.Game/OsuGame.cs | 4 ++-- osu.Game/Overlays/Settings/Sidebar.cs | 7 +++---- osu.Game/Overlays/Toolbar/ToolbarButton.cs | 7 +++---- osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.cs | 2 +- osu.Game/Overlays/Toolbar/ToolbarRulesetTabButton.cs | 6 ------ osu.Game/Overlays/Toolbar/ToolbarSettingsButton.cs | 1 + 6 files changed, 10 insertions(+), 17 deletions(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 6b8e70e546..164a40c6a5 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -698,9 +698,9 @@ namespace osu.Game float offset = 0; if (Settings.State.Value == Visibility.Visible) - offset += ToolbarButton.WIDTH / 2; + offset += Toolbar.HEIGHT / 2; if (notifications.State.Value == Visibility.Visible) - offset -= ToolbarButton.WIDTH / 2; + offset -= Toolbar.HEIGHT / 2; screenContainer.MoveToX(offset, SettingsPanel.TRANSITION_LENGTH, Easing.OutQuint); } diff --git a/osu.Game/Overlays/Settings/Sidebar.cs b/osu.Game/Overlays/Settings/Sidebar.cs index 358f94b659..3783d15e5a 100644 --- a/osu.Game/Overlays/Settings/Sidebar.cs +++ b/osu.Game/Overlays/Settings/Sidebar.cs @@ -4,22 +4,21 @@ using System; using System.Linq; using osu.Framework; -using osuTK; -using osuTK.Graphics; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Framework.Input.Events; using osu.Framework.Threading; using osu.Game.Graphics.Containers; -using osu.Game.Overlays.Toolbar; +using osuTK; +using osuTK.Graphics; namespace osu.Game.Overlays.Settings { public class Sidebar : Container, IStateful { private readonly FillFlowContainer content; - public const float DEFAULT_WIDTH = ToolbarButton.WIDTH; + public const float DEFAULT_WIDTH = Toolbar.Toolbar.HEIGHT; public const int EXPANDED_WIDTH = 200; public event Action StateChanged; diff --git a/osu.Game/Overlays/Toolbar/ToolbarButton.cs b/osu.Game/Overlays/Toolbar/ToolbarButton.cs index d0787664a0..49b9c62d85 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarButton.cs @@ -9,6 +9,7 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Effects; using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Sprites; +using osu.Framework.Graphics.Textures; using osu.Framework.Input.Bindings; using osu.Framework.Input.Events; using osu.Game.Graphics; @@ -25,8 +26,6 @@ namespace osu.Game.Overlays.Toolbar { public abstract class ToolbarButton : OsuClickableContainer, IKeyBindingHandler { - public const float WIDTH = Toolbar.HEIGHT * 1.4f; - protected GlobalAction? Hotkey { get; set; } public void SetIcon(Drawable icon) @@ -80,7 +79,7 @@ namespace osu.Game.Overlays.Toolbar protected ToolbarButton() : base(HoverSampleSet.Loud) { - Width = WIDTH; + Width = Toolbar.HEIGHT; RelativeSizeAxes = Axes.Y; Children = new Drawable[] @@ -114,7 +113,7 @@ namespace osu.Game.Overlays.Toolbar { Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, - Size = new Vector2(20), + Size = new Vector2(26), Alpha = 0, }, DrawableText = new OsuSpriteText diff --git a/osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.cs b/osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.cs index 422bf00c6d..905d5b44c6 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.cs @@ -37,7 +37,7 @@ namespace osu.Game.Overlays.Toolbar }, ModeButtonLine = new Container { - Size = new Vector2(ToolbarButton.WIDTH, 3), + Size = new Vector2(Toolbar.HEIGHT, 3), Anchor = Anchor.BottomLeft, Origin = Anchor.TopLeft, Masking = true, diff --git a/osu.Game/Overlays/Toolbar/ToolbarRulesetTabButton.cs b/osu.Game/Overlays/Toolbar/ToolbarRulesetTabButton.cs index a5194ea752..754b679599 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarRulesetTabButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarRulesetTabButton.cs @@ -65,12 +65,6 @@ namespace osu.Game.Overlays.Toolbar Parent.Click(); return base.OnClick(e); } - - protected override void LoadComplete() - { - base.LoadComplete(); - IconContainer.Scale *= 1.4f; - } } } } diff --git a/osu.Game/Overlays/Toolbar/ToolbarSettingsButton.cs b/osu.Game/Overlays/Toolbar/ToolbarSettingsButton.cs index 4051a2a194..c53f4a55d9 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarSettingsButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarSettingsButton.cs @@ -10,6 +10,7 @@ namespace osu.Game.Overlays.Toolbar { public ToolbarSettingsButton() { + Width *= 1.4f; Hotkey = GlobalAction.ToggleSettings; } From 0d1674ca5e28fce53ab48fe478e44faa376b7caa Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 3 Sep 2020 16:32:43 +0900 Subject: [PATCH 252/320] Combine settings strings to read from same location --- osu.Game/Overlays/SettingsOverlay.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Overlays/SettingsOverlay.cs b/osu.Game/Overlays/SettingsOverlay.cs index 9a7937dfce..0532a031f3 100644 --- a/osu.Game/Overlays/SettingsOverlay.cs +++ b/osu.Game/Overlays/SettingsOverlay.cs @@ -16,8 +16,8 @@ namespace osu.Game.Overlays public class SettingsOverlay : SettingsPanel, INamedOverlayComponent { public string IconTexture => "Icons/Hexacons/settings"; - public string Title => "Settings"; - public string Description => "Change your settings"; + public string Title => "settings"; + public string Description => "Change the way osu! behaves"; protected override IEnumerable CreateSections() => new SettingsSection[] { @@ -34,7 +34,7 @@ namespace osu.Game.Overlays private readonly List subPanels = new List(); - protected override Drawable CreateHeader() => new SettingsHeader("settings", "Change the way osu! behaves"); + protected override Drawable CreateHeader() => new SettingsHeader(Title, Description); protected override Drawable CreateFooter() => new SettingsFooter(); public SettingsOverlay() From f5a73130e1aa32ca1001669f4118a15decfce8c4 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 3 Sep 2020 16:34:47 +0900 Subject: [PATCH 253/320] Fix regression in sidebar button sizing --- osu.Game/Overlays/Settings/Sidebar.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Settings/Sidebar.cs b/osu.Game/Overlays/Settings/Sidebar.cs index 3783d15e5a..031ecaae46 100644 --- a/osu.Game/Overlays/Settings/Sidebar.cs +++ b/osu.Game/Overlays/Settings/Sidebar.cs @@ -18,7 +18,7 @@ namespace osu.Game.Overlays.Settings public class Sidebar : Container, IStateful { private readonly FillFlowContainer content; - public const float DEFAULT_WIDTH = Toolbar.Toolbar.HEIGHT; + public const float DEFAULT_WIDTH = Toolbar.Toolbar.HEIGHT * 1.4f; public const int EXPANDED_WIDTH = 200; public event Action StateChanged; From 99e34d85621b283476376d72d8cb70c3f9a50eb8 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 3 Sep 2020 17:05:45 +0900 Subject: [PATCH 254/320] Update with missing icons --- osu.Game/Overlays/BeatmapListing/BeatmapListingHeader.cs | 2 +- osu.Game/Overlays/BeatmapSet/BeatmapSetHeader.cs | 2 +- osu.Game/Overlays/NotificationOverlay.cs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Overlays/BeatmapListing/BeatmapListingHeader.cs b/osu.Game/Overlays/BeatmapListing/BeatmapListingHeader.cs index 1cf86b78cf..b7f511271c 100644 --- a/osu.Game/Overlays/BeatmapListing/BeatmapListingHeader.cs +++ b/osu.Game/Overlays/BeatmapListing/BeatmapListingHeader.cs @@ -13,7 +13,7 @@ namespace osu.Game.Overlays.BeatmapListing { Title = "beatmap listing"; Description = "Browse for new beatmaps"; - IconTexture = "Icons/Hexacons/music"; + IconTexture = "Icons/Hexacons/beatmap"; } } } diff --git a/osu.Game/Overlays/BeatmapSet/BeatmapSetHeader.cs b/osu.Game/Overlays/BeatmapSet/BeatmapSetHeader.cs index 329045c743..6511b15fc8 100644 --- a/osu.Game/Overlays/BeatmapSet/BeatmapSetHeader.cs +++ b/osu.Game/Overlays/BeatmapSet/BeatmapSetHeader.cs @@ -25,7 +25,7 @@ namespace osu.Game.Overlays.BeatmapSet public BeatmapHeaderTitle() { Title = "beatmap info"; - IconTexture = "Icons/Hexacons/music"; + IconTexture = "Icons/Hexacons/beatmap"; } } } diff --git a/osu.Game/Overlays/NotificationOverlay.cs b/osu.Game/Overlays/NotificationOverlay.cs index 6bdacb9c5e..b7d916c48f 100644 --- a/osu.Game/Overlays/NotificationOverlay.cs +++ b/osu.Game/Overlays/NotificationOverlay.cs @@ -18,7 +18,7 @@ namespace osu.Game.Overlays { public class NotificationOverlay : OsuFocusedOverlayContainer, INamedOverlayComponent { - public string IconTexture => "Icons/Hexacons/"; + public string IconTexture => "Icons/Hexacons/notification"; public string Title => "Notifications"; public string Description => "Waiting for 'ya"; From d55c9c3cc2e6f951ff5bf8776c9cff638f3f5726 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 3 Sep 2020 17:11:34 +0900 Subject: [PATCH 255/320] Fix UserProfile weirdness --- osu.Game/Graphics/Containers/SectionsContainer.cs | 5 ++++- osu.Game/Overlays/UserProfileOverlay.cs | 3 +++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/osu.Game/Graphics/Containers/SectionsContainer.cs b/osu.Game/Graphics/Containers/SectionsContainer.cs index d739f56828..f32f8e0c67 100644 --- a/osu.Game/Graphics/Containers/SectionsContainer.cs +++ b/osu.Game/Graphics/Containers/SectionsContainer.cs @@ -26,8 +26,11 @@ namespace osu.Game.Graphics.Containers { if (value == expandableHeader) return; - expandableHeader?.Expire(); + if (expandableHeader != null) + RemoveInternal(expandableHeader); + expandableHeader = value; + if (value == null) return; AddInternal(expandableHeader); diff --git a/osu.Game/Overlays/UserProfileOverlay.cs b/osu.Game/Overlays/UserProfileOverlay.cs index 965ad790ed..2b316c0e34 100644 --- a/osu.Game/Overlays/UserProfileOverlay.cs +++ b/osu.Game/Overlays/UserProfileOverlay.cs @@ -44,6 +44,9 @@ namespace osu.Game.Overlays if (user.Id == Header?.User.Value?.Id) return; + if (sectionsContainer != null) + sectionsContainer.ExpandableHeader = null; + userReq?.Cancel(); Clear(); lastSection = null; From 72cb65c22f55c89677a4bf3a466e082788831a99 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 3 Sep 2020 17:51:54 +0900 Subject: [PATCH 256/320] Update and add missing beatmap statistic icons to info wedge --- .../Beatmaps/CatchBeatmap.cs | 7 +++--- .../Beatmaps/ManiaBeatmap.cs | 5 ++-- osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmap.cs | 7 +++--- .../Beatmaps/TaikoBeatmap.cs | 7 +++--- osu.Game/Beatmaps/BeatmapStatistic.cs | 18 ++++++++++++- osu.Game/Beatmaps/BeatmapStatisticSprite.cs | 25 +++++++++++++++++++ osu.Game/Screens/Select/BeatmapInfoWedge.cs | 16 +++++++++--- 7 files changed, 65 insertions(+), 20 deletions(-) create mode 100644 osu.Game/Beatmaps/BeatmapStatisticSprite.cs diff --git a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmap.cs b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmap.cs index 18cc300ff9..5dc19ce15b 100644 --- a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmap.cs +++ b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmap.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.Linq; -using osu.Framework.Graphics.Sprites; using osu.Game.Beatmaps; using osu.Game.Rulesets.Catch.Objects; @@ -23,19 +22,19 @@ namespace osu.Game.Rulesets.Catch.Beatmaps { Name = @"Fruit Count", Content = fruits.ToString(), - Icon = FontAwesome.Regular.Circle + CreateIcon = () => new BeatmapStatisticSprite("circles"), }, new BeatmapStatistic { Name = @"Juice Stream Count", Content = juiceStreams.ToString(), - Icon = FontAwesome.Regular.Circle + CreateIcon = () => new BeatmapStatisticSprite("sliders"), }, new BeatmapStatistic { Name = @"Banana Shower Count", Content = bananaShowers.ToString(), - Icon = FontAwesome.Regular.Circle + CreateIcon = () => new BeatmapStatisticSprite("spinners"), } }; } diff --git a/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmap.cs b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmap.cs index dc24a344e9..f6b460f269 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmap.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmap.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.Linq; -using osu.Framework.Graphics.Sprites; using osu.Game.Beatmaps; using osu.Game.Rulesets.Mania.Objects; using osu.Game.Rulesets.Mania.UI; @@ -41,14 +40,14 @@ namespace osu.Game.Rulesets.Mania.Beatmaps new BeatmapStatistic { Name = @"Note Count", + CreateIcon = () => new BeatmapStatisticSprite("circles"), Content = notes.ToString(), - Icon = FontAwesome.Regular.Circle }, new BeatmapStatistic { Name = @"Hold Note Count", + CreateIcon = () => new BeatmapStatisticSprite("sliders"), Content = holdnotes.ToString(), - Icon = FontAwesome.Regular.Circle }, }; } diff --git a/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmap.cs b/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmap.cs index 491d82b89e..513a9254ec 100644 --- a/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmap.cs +++ b/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmap.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.Linq; -using osu.Framework.Graphics.Sprites; using osu.Game.Beatmaps; using osu.Game.Rulesets.Osu.Objects; @@ -23,19 +22,19 @@ namespace osu.Game.Rulesets.Osu.Beatmaps { Name = @"Circle Count", Content = circles.ToString(), - Icon = FontAwesome.Regular.Circle + CreateIcon = () => new BeatmapStatisticSprite("circles"), }, new BeatmapStatistic { Name = @"Slider Count", Content = sliders.ToString(), - Icon = FontAwesome.Regular.Circle + CreateIcon = () => new BeatmapStatisticSprite("sliders"), }, new BeatmapStatistic { Name = @"Spinner Count", Content = spinners.ToString(), - Icon = FontAwesome.Regular.Circle + CreateIcon = () => new BeatmapStatisticSprite("spinners"), } }; } diff --git a/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmap.cs b/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmap.cs index b595f43fbb..c0f8af4fff 100644 --- a/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmap.cs +++ b/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmap.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.Linq; -using osu.Framework.Graphics.Sprites; using osu.Game.Beatmaps; using osu.Game.Rulesets.Taiko.Objects; @@ -22,20 +21,20 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps new BeatmapStatistic { Name = @"Hit Count", + CreateIcon = () => new BeatmapStatisticSprite("circles"), Content = hits.ToString(), - Icon = FontAwesome.Regular.Circle }, new BeatmapStatistic { Name = @"Drumroll Count", + CreateIcon = () => new BeatmapStatisticSprite("sliders"), Content = drumrolls.ToString(), - Icon = FontAwesome.Regular.Circle }, new BeatmapStatistic { Name = @"Swell Count", + CreateIcon = () => new BeatmapStatisticSprite("spinners"), Content = swells.ToString(), - Icon = FontAwesome.Regular.Circle } }; } diff --git a/osu.Game/Beatmaps/BeatmapStatistic.cs b/osu.Game/Beatmaps/BeatmapStatistic.cs index 0745ec5222..5a466c24be 100644 --- a/osu.Game/Beatmaps/BeatmapStatistic.cs +++ b/osu.Game/Beatmaps/BeatmapStatistic.cs @@ -1,14 +1,30 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System; +using osu.Framework.Graphics; using osu.Framework.Graphics.Sprites; namespace osu.Game.Beatmaps { public class BeatmapStatistic { - public IconUsage Icon; + [Obsolete("Use CreateIcon instead")] // can be removed 20210203 + public IconUsage Icon = FontAwesome.Regular.QuestionCircle; + + /// + /// A function to create the icon for display purposes. + /// + public Func CreateIcon; + public string Content; public string Name; + + public BeatmapStatistic() + { +#pragma warning disable 618 + CreateIcon = () => new SpriteIcon { Icon = Icon }; +#pragma warning restore 618 + } } } diff --git a/osu.Game/Beatmaps/BeatmapStatisticSprite.cs b/osu.Game/Beatmaps/BeatmapStatisticSprite.cs new file mode 100644 index 0000000000..1cb0bacf0f --- /dev/null +++ b/osu.Game/Beatmaps/BeatmapStatisticSprite.cs @@ -0,0 +1,25 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Allocation; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Graphics.Textures; + +namespace osu.Game.Beatmaps +{ + public class BeatmapStatisticSprite : Sprite + { + private readonly string iconName; + + public BeatmapStatisticSprite(string iconName) + { + this.iconName = iconName; + } + + [BackgroundDependencyLoader] + private void load(TextureStore textures) + { + Texture = textures.Get($"Icons/BeatmapDetails/{iconName}"); + } + } +} diff --git a/osu.Game/Screens/Select/BeatmapInfoWedge.cs b/osu.Game/Screens/Select/BeatmapInfoWedge.cs index ad977c70b5..4ef074b967 100644 --- a/osu.Game/Screens/Select/BeatmapInfoWedge.cs +++ b/osu.Game/Screens/Select/BeatmapInfoWedge.cs @@ -318,14 +318,14 @@ namespace osu.Game.Screens.Select labels.Add(new InfoLabel(new BeatmapStatistic { Name = "Length", - Icon = FontAwesome.Regular.Clock, + CreateIcon = () => new BeatmapStatisticSprite("length"), Content = TimeSpan.FromMilliseconds(b.BeatmapInfo.Length).ToString(@"m\:ss"), })); labels.Add(new InfoLabel(new BeatmapStatistic { Name = "BPM", - Icon = FontAwesome.Regular.Circle, + CreateIcon = () => new BeatmapStatisticSprite("bpm"), Content = getBPMRange(b), })); @@ -418,10 +418,18 @@ namespace osu.Game.Screens.Select Anchor = Anchor.Centre, Origin = Anchor.Centre, RelativeSizeAxes = Axes.Both, - Scale = new Vector2(0.8f), Colour = Color4Extensions.FromHex(@"f7dd55"), - Icon = statistic.Icon, + Icon = FontAwesome.Regular.Circle, + Scale = new Vector2(0.8f) }, + statistic.CreateIcon().With(i => + { + i.Anchor = Anchor.Centre; + i.Origin = Anchor.Centre; + i.RelativeSizeAxes = Axes.Both; + i.Size = new Vector2(1.2f); + i.Colour = Color4Extensions.FromHex(@"f7dd55"); + }), } }, new OsuSpriteText From 58e84760b959362ee49fd98d36b8222f30298f70 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 3 Sep 2020 19:17:07 +0900 Subject: [PATCH 257/320] Fix path empty string check causing regression in behaviour --- osu.Game/IO/WrappedStorage.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/osu.Game/IO/WrappedStorage.cs b/osu.Game/IO/WrappedStorage.cs index 766e36ef14..5b2549d2ee 100644 --- a/osu.Game/IO/WrappedStorage.cs +++ b/osu.Game/IO/WrappedStorage.cs @@ -25,7 +25,13 @@ namespace osu.Game.IO this.subPath = subPath; } - protected virtual string MutatePath(string path) => !string.IsNullOrEmpty(subPath) && !string.IsNullOrEmpty(path) ? Path.Combine(subPath, path) : path; + protected virtual string MutatePath(string path) + { + if (path == null) + return null; + + return !string.IsNullOrEmpty(subPath) ? Path.Combine(subPath, path) : path; + } protected virtual void ChangeTargetStorage(Storage newStorage) { From a555407f3772353b2b4f8b9b3a93179ec2212585 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 3 Sep 2020 19:20:42 +0900 Subject: [PATCH 258/320] Fix various test failures due to missing beatmap info in empty beatmap --- osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs | 2 +- osu.Game/Beatmaps/WorkingBeatmap.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs b/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs index 9e4c29a8d4..11b6ad8c29 100644 --- a/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs @@ -34,7 +34,7 @@ namespace osu.Game.Beatmaps protected override IBeatmap GetBeatmap() { if (BeatmapInfo.Path == null) - return BeatmapInfo.Ruleset.CreateInstance().CreateBeatmapConverter(new Beatmap()).Beatmap; + return BeatmapInfo?.Ruleset.CreateInstance().CreateBeatmapConverter(new Beatmap { BeatmapInfo = BeatmapInfo }).Beatmap; try { diff --git a/osu.Game/Beatmaps/WorkingBeatmap.cs b/osu.Game/Beatmaps/WorkingBeatmap.cs index 6a161e6e04..aefeb48453 100644 --- a/osu.Game/Beatmaps/WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/WorkingBeatmap.cs @@ -53,7 +53,7 @@ namespace osu.Game.Beatmaps { const double excess_length = 1000; - var lastObject = Beatmap.HitObjects.LastOrDefault(); + var lastObject = Beatmap?.HitObjects.LastOrDefault(); double length; From 1c1c583d3b9bf0ed2b306f7fef8ebae0bd11f1b7 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 3 Sep 2020 19:31:40 +0900 Subject: [PATCH 259/320] Fix regression in file update logic (filename set too early) --- osu.Game/Beatmaps/BeatmapManager.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index 325e6c6e98..1456e7487b 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -243,15 +243,15 @@ namespace osu.Game.Beatmaps var beatmapInfo = setInfo.Beatmaps.Single(b => b.ID == info.ID); var metadata = beatmapInfo.Metadata ?? setInfo.Metadata; + // grab the original file (or create a new one if not found). + var fileInfo = setInfo.Files.SingleOrDefault(f => string.Equals(f.Filename, beatmapInfo.Path, StringComparison.OrdinalIgnoreCase)) ?? new BeatmapSetFileInfo(); + // metadata may have changed; update the path with the standard format. beatmapInfo.Path = $"{metadata.Artist} - {metadata.Title} ({metadata.Author}) [{beatmapInfo.Version}]"; - beatmapInfo.MD5Hash = stream.ComputeMD5Hash(); - var fileInfo = setInfo.Files.SingleOrDefault(f => string.Equals(f.Filename, beatmapInfo.Path, StringComparison.OrdinalIgnoreCase)) ?? new BeatmapSetFileInfo - { - Filename = beatmapInfo.Path - }; + // update existing or populate new file's filename. + fileInfo.Filename = beatmapInfo.Path; stream.Seek(0, SeekOrigin.Begin); UpdateFile(setInfo, fileInfo, stream); From c9a73926a68cd4104eb719f8b365be601c67373c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 3 Sep 2020 19:38:01 +0900 Subject: [PATCH 260/320] Add basic test coverage --- .../Beatmaps/IO/ImportBeatmapTest.cs | 58 +++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs b/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs index 0151678db3..4547613b5a 100644 --- a/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs +++ b/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs @@ -15,6 +15,7 @@ using osu.Framework.Extensions; using osu.Framework.Logging; using osu.Game.Beatmaps; using osu.Game.IO; +using osu.Game.Rulesets.Osu; using osu.Game.Rulesets.Osu.Objects; using osu.Game.Tests.Resources; using SharpCompress.Archives; @@ -756,6 +757,63 @@ namespace osu.Game.Tests.Beatmaps.IO } } + [Test] + public void TestCreateNewEmptyBeatmap() + { + using (HeadlessGameHost host = new CleanRunHeadlessGameHost(nameof(TestUpdateBeatmapFile))) + { + try + { + var osu = loadOsu(host); + var manager = osu.Dependencies.Get(); + + var working = osu.Dependencies.Get().CreateNew(new OsuRuleset().RulesetInfo); + + manager.Save(working.BeatmapInfo, working.Beatmap); + + var retrievedSet = manager.GetAllUsableBeatmapSets()[0]; + + // Check that the new file is referenced correctly by attempting a retrieval + Beatmap updatedBeatmap = (Beatmap)manager.GetWorkingBeatmap(retrievedSet.Beatmaps[0]).Beatmap; + Assert.That(updatedBeatmap.HitObjects.Count, Is.EqualTo(0)); + } + finally + { + host.Exit(); + } + } + } + + [Test] + public void TestCreateNewBeatmapWithObject() + { + using (HeadlessGameHost host = new CleanRunHeadlessGameHost(nameof(TestUpdateBeatmapFile))) + { + try + { + var osu = loadOsu(host); + var manager = osu.Dependencies.Get(); + + var working = osu.Dependencies.Get().CreateNew(new OsuRuleset().RulesetInfo); + + ((Beatmap)working.Beatmap).HitObjects.Add(new HitCircle { StartTime = 5000 }); + + manager.Save(working.BeatmapInfo, working.Beatmap); + + var retrievedSet = manager.GetAllUsableBeatmapSets()[0]; + + // Check that the new file is referenced correctly by attempting a retrieval + Beatmap updatedBeatmap = (Beatmap)manager.GetWorkingBeatmap(retrievedSet.Beatmaps[0]).Beatmap; + Assert.That(updatedBeatmap.HitObjects.Count, Is.EqualTo(1)); + Assert.That(updatedBeatmap.HitObjects[0].StartTime, Is.EqualTo(5000)); + } + finally + { + host.Exit(); + } + } + } + public static async Task LoadOszIntoOsu(OsuGameBase osu, string path = null, bool virtualTrack = false) { var temp = path ?? TestResources.GetTestBeatmapForImport(virtualTrack); From d32b77f045a120ee21645baff1209f5c9215118c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 3 Sep 2020 21:33:25 +0900 Subject: [PATCH 261/320] Add missing extension to filename Co-authored-by: Dan Balasescu --- osu.Game/Beatmaps/BeatmapManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index 1456e7487b..12add76b46 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -247,7 +247,7 @@ namespace osu.Game.Beatmaps var fileInfo = setInfo.Files.SingleOrDefault(f => string.Equals(f.Filename, beatmapInfo.Path, StringComparison.OrdinalIgnoreCase)) ?? new BeatmapSetFileInfo(); // metadata may have changed; update the path with the standard format. - beatmapInfo.Path = $"{metadata.Artist} - {metadata.Title} ({metadata.Author}) [{beatmapInfo.Version}]"; + beatmapInfo.Path = $"{metadata.Artist} - {metadata.Title} ({metadata.Author}) [{beatmapInfo.Version}].osu"; beatmapInfo.MD5Hash = stream.ComputeMD5Hash(); // update existing or populate new file's filename. From ebed7d09e3412206660666a3231b406e4550206d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 3 Sep 2020 21:56:36 +0900 Subject: [PATCH 262/320] Update resources --- osu.Android.props | 2 +- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index 2d3bfaf7ce..a41c1a5864 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -51,7 +51,7 @@ - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 166910b165..d79806883e 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -25,7 +25,7 @@ - + diff --git a/osu.iOS.props b/osu.iOS.props index 51f8141bac..16a8a1acb7 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -71,7 +71,7 @@ - + From 18927304f10bd912fc9a09cb22aaed3dd38974d0 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Thu, 3 Sep 2020 16:29:25 +0300 Subject: [PATCH 263/320] Move adjustment to LegacySkinConfiguration as a default value --- osu.Game.Rulesets.Osu/Skinning/LegacySliderBody.cs | 4 ---- osu.Game/Skinning/LegacySkinConfiguration.cs | 9 +++++++++ 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Skinning/LegacySliderBody.cs b/osu.Game.Rulesets.Osu/Skinning/LegacySliderBody.cs index aad8b189d9..21df49d80b 100644 --- a/osu.Game.Rulesets.Osu/Skinning/LegacySliderBody.cs +++ b/osu.Game.Rulesets.Osu/Skinning/LegacySliderBody.cs @@ -18,10 +18,6 @@ namespace osu.Game.Rulesets.Osu.Skinning { private const float shadow_portion = 1 - (OsuLegacySkinTransformer.LEGACY_CIRCLE_RADIUS / OsuHitObject.OBJECT_RADIUS); - protected new float CalculatedBorderPortion - // Roughly matches osu!stable's slider border portions. - => base.CalculatedBorderPortion * 0.77f; - public new Color4 AccentColour => new Color4(base.AccentColour.R, base.AccentColour.G, base.AccentColour.B, base.AccentColour.A * 0.70f); protected override Color4 ColourAt(float position) diff --git a/osu.Game/Skinning/LegacySkinConfiguration.cs b/osu.Game/Skinning/LegacySkinConfiguration.cs index 41b7aea34b..b980d727ed 100644 --- a/osu.Game/Skinning/LegacySkinConfiguration.cs +++ b/osu.Game/Skinning/LegacySkinConfiguration.cs @@ -1,6 +1,8 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System.Globalization; + namespace osu.Game.Skinning { public class LegacySkinConfiguration : SkinConfiguration @@ -12,6 +14,13 @@ namespace osu.Game.Skinning /// public decimal? LegacyVersion { get; internal set; } + public LegacySkinConfiguration() + { + // Roughly matches osu!stable's slider border portions. + // Can't use nameof(SliderBorderSize) as the lookup enum is declared in the osu! ruleset. + ConfigDictionary["SliderBorderSize"] = 0.77f.ToString(CultureInfo.InvariantCulture); + } + public enum LegacySetting { Version, From d6b46936a0f7100617815b67130252f413ef03d9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 4 Sep 2020 12:55:28 +0900 Subject: [PATCH 264/320] Adjust sizing to match updated textures with less padding --- osu.Game/Screens/Select/BeatmapInfoWedge.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Select/BeatmapInfoWedge.cs b/osu.Game/Screens/Select/BeatmapInfoWedge.cs index 4ef074b967..b3bf306431 100644 --- a/osu.Game/Screens/Select/BeatmapInfoWedge.cs +++ b/osu.Game/Screens/Select/BeatmapInfoWedge.cs @@ -420,15 +420,15 @@ namespace osu.Game.Screens.Select RelativeSizeAxes = Axes.Both, Colour = Color4Extensions.FromHex(@"f7dd55"), Icon = FontAwesome.Regular.Circle, - Scale = new Vector2(0.8f) + Size = new Vector2(0.8f) }, statistic.CreateIcon().With(i => { i.Anchor = Anchor.Centre; i.Origin = Anchor.Centre; i.RelativeSizeAxes = Axes.Both; - i.Size = new Vector2(1.2f); i.Colour = Color4Extensions.FromHex(@"f7dd55"); + i.Size = new Vector2(0.8f); }), } }, From 9d2dff2cb871403637511e2d7545dfad89d59c68 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 4 Sep 2020 12:55:39 +0900 Subject: [PATCH 265/320] Add scale to allow legacy icons to display correctly sized --- osu.Game/Beatmaps/BeatmapStatistic.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/BeatmapStatistic.cs b/osu.Game/Beatmaps/BeatmapStatistic.cs index 5a466c24be..15036d1cd6 100644 --- a/osu.Game/Beatmaps/BeatmapStatistic.cs +++ b/osu.Game/Beatmaps/BeatmapStatistic.cs @@ -4,6 +4,7 @@ using System; using osu.Framework.Graphics; using osu.Framework.Graphics.Sprites; +using osuTK; namespace osu.Game.Beatmaps { @@ -23,7 +24,7 @@ namespace osu.Game.Beatmaps public BeatmapStatistic() { #pragma warning disable 618 - CreateIcon = () => new SpriteIcon { Icon = Icon }; + CreateIcon = () => new SpriteIcon { Icon = Icon, Scale = new Vector2(0.6f) }; #pragma warning restore 618 } } From cd253ab055e97b67cdc7b59a2fcea6bdeb971a39 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 4 Sep 2020 13:05:39 +0900 Subject: [PATCH 266/320] Further tweaks to get closer to design originals --- osu.Game/Beatmaps/BeatmapStatistic.cs | 2 +- osu.Game/Screens/Select/BeatmapInfoWedge.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapStatistic.cs b/osu.Game/Beatmaps/BeatmapStatistic.cs index 15036d1cd6..825bb08246 100644 --- a/osu.Game/Beatmaps/BeatmapStatistic.cs +++ b/osu.Game/Beatmaps/BeatmapStatistic.cs @@ -24,7 +24,7 @@ namespace osu.Game.Beatmaps public BeatmapStatistic() { #pragma warning disable 618 - CreateIcon = () => new SpriteIcon { Icon = Icon, Scale = new Vector2(0.6f) }; + CreateIcon = () => new SpriteIcon { Icon = Icon, Scale = new Vector2(0.7f) }; #pragma warning restore 618 } } diff --git a/osu.Game/Screens/Select/BeatmapInfoWedge.cs b/osu.Game/Screens/Select/BeatmapInfoWedge.cs index b3bf306431..400f3e3063 100644 --- a/osu.Game/Screens/Select/BeatmapInfoWedge.cs +++ b/osu.Game/Screens/Select/BeatmapInfoWedge.cs @@ -428,7 +428,7 @@ namespace osu.Game.Screens.Select i.Origin = Anchor.Centre; i.RelativeSizeAxes = Axes.Both; i.Colour = Color4Extensions.FromHex(@"f7dd55"); - i.Size = new Vector2(0.8f); + i.Size = new Vector2(0.64f); }), } }, From f14a82e3a927950e23631ed1c5eeb430c94c8957 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 4 Sep 2020 13:13:53 +0900 Subject: [PATCH 267/320] Remove unnecessary conversion --- osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs b/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs index 11b6ad8c29..362c99ea3f 100644 --- a/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs @@ -34,7 +34,7 @@ namespace osu.Game.Beatmaps protected override IBeatmap GetBeatmap() { if (BeatmapInfo.Path == null) - return BeatmapInfo?.Ruleset.CreateInstance().CreateBeatmapConverter(new Beatmap { BeatmapInfo = BeatmapInfo }).Beatmap; + return new Beatmap { BeatmapInfo = BeatmapInfo }; try { From d3fbc7cc53ea92a28e76ed07f11a6edc855c584e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 4 Sep 2020 13:16:35 +0900 Subject: [PATCH 268/320] Use more direct reference in tests --- osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs b/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs index 4547613b5a..6c60d7b467 100644 --- a/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs +++ b/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs @@ -767,7 +767,7 @@ namespace osu.Game.Tests.Beatmaps.IO var osu = loadOsu(host); var manager = osu.Dependencies.Get(); - var working = osu.Dependencies.Get().CreateNew(new OsuRuleset().RulesetInfo); + var working = manager.CreateNew(new OsuRuleset().RulesetInfo); manager.Save(working.BeatmapInfo, working.Beatmap); @@ -794,7 +794,7 @@ namespace osu.Game.Tests.Beatmaps.IO var osu = loadOsu(host); var manager = osu.Dependencies.Get(); - var working = osu.Dependencies.Get().CreateNew(new OsuRuleset().RulesetInfo); + var working = manager.CreateNew(new OsuRuleset().RulesetInfo); ((Beatmap)working.Beatmap).HitObjects.Add(new HitCircle { StartTime = 5000 }); From fba253f131e7f5d279a0f011d404ef7685ab2c1c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 4 Sep 2020 13:17:43 +0900 Subject: [PATCH 269/320] Take user argument in CreateNew method parameters --- osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs | 5 +++-- osu.Game/Beatmaps/BeatmapManager.cs | 4 ++-- osu.Game/Screens/Edit/Editor.cs | 3 +-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs b/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs index 6c60d7b467..cef8105490 100644 --- a/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs +++ b/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs @@ -18,6 +18,7 @@ using osu.Game.IO; using osu.Game.Rulesets.Osu; using osu.Game.Rulesets.Osu.Objects; using osu.Game.Tests.Resources; +using osu.Game.Users; using SharpCompress.Archives; using SharpCompress.Archives.Zip; using SharpCompress.Common; @@ -767,7 +768,7 @@ namespace osu.Game.Tests.Beatmaps.IO var osu = loadOsu(host); var manager = osu.Dependencies.Get(); - var working = manager.CreateNew(new OsuRuleset().RulesetInfo); + var working = manager.CreateNew(new OsuRuleset().RulesetInfo, User.SYSTEM_USER); manager.Save(working.BeatmapInfo, working.Beatmap); @@ -794,7 +795,7 @@ namespace osu.Game.Tests.Beatmaps.IO var osu = loadOsu(host); var manager = osu.Dependencies.Get(); - var working = manager.CreateNew(new OsuRuleset().RulesetInfo); + var working = manager.CreateNew(new OsuRuleset().RulesetInfo, User.SYSTEM_USER); ((Beatmap)working.Beatmap).HitObjects.Add(new HitCircle { StartTime = 5000 }); diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index 12add76b46..844af31a16 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -95,13 +95,13 @@ namespace osu.Game.Beatmaps protected override bool ShouldDeleteArchive(string path) => Path.GetExtension(path)?.ToLowerInvariant() == ".osz"; - public WorkingBeatmap CreateNew(RulesetInfo ruleset) + public WorkingBeatmap CreateNew(RulesetInfo ruleset, User user) { var metadata = new BeatmapMetadata { Artist = "artist", Title = "title", - Author = User.SYSTEM_USER, + Author = user, }; var set = new BeatmapSetInfo diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index b8c1932186..ef497e3246 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -98,8 +98,7 @@ namespace osu.Game.Screens.Edit if (Beatmap.Value is DummyWorkingBeatmap) { isNewBeatmap = true; - Beatmap.Value = beatmapManager.CreateNew(Ruleset.Value); - Beatmap.Value.BeatmapSetInfo.Metadata.Author = api.LocalUser.Value; + Beatmap.Value = beatmapManager.CreateNew(Ruleset.Value, api.LocalUser.Value); } try From 7c99f66cf518fe4696ac33c5a4e2ad1a01a7825f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 4 Sep 2020 14:13:42 +0900 Subject: [PATCH 270/320] Update resources --- osu.Android.props | 2 +- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index a41c1a5864..7dfda5babb 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -51,7 +51,7 @@ - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index d79806883e..cd7dcbb8db 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -25,7 +25,7 @@ - + diff --git a/osu.iOS.props b/osu.iOS.props index 16a8a1acb7..284b717a0f 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -71,7 +71,7 @@ - + From 25e142965d925ef6936b6424175b3736041dbcfd Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 4 Sep 2020 15:01:32 +0900 Subject: [PATCH 271/320] Strongly type and expose default beatmap information icon implementations for other rulesets --- .../Beatmaps/CatchBeatmap.cs | 6 +-- .../Beatmaps/ManiaBeatmap.cs | 4 +- osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmap.cs | 6 +-- .../Beatmaps/TaikoBeatmap.cs | 6 +-- osu.Game/Beatmaps/BeatmapStatistic.cs | 2 +- osu.Game/Beatmaps/BeatmapStatisticIcon.cs | 43 +++++++++++++++++++ osu.Game/Beatmaps/BeatmapStatisticSprite.cs | 25 ----------- osu.Game/Screens/Select/BeatmapInfoWedge.cs | 4 +- 8 files changed, 57 insertions(+), 39 deletions(-) create mode 100644 osu.Game/Beatmaps/BeatmapStatisticIcon.cs delete mode 100644 osu.Game/Beatmaps/BeatmapStatisticSprite.cs diff --git a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmap.cs b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmap.cs index 5dc19ce15b..f009c10a9c 100644 --- a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmap.cs +++ b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmap.cs @@ -22,19 +22,19 @@ namespace osu.Game.Rulesets.Catch.Beatmaps { Name = @"Fruit Count", Content = fruits.ToString(), - CreateIcon = () => new BeatmapStatisticSprite("circles"), + CreateIcon = () => new BeatmapStatisticIcon(BeatmapStatisticsIconType.Circles), }, new BeatmapStatistic { Name = @"Juice Stream Count", Content = juiceStreams.ToString(), - CreateIcon = () => new BeatmapStatisticSprite("sliders"), + CreateIcon = () => new BeatmapStatisticIcon(BeatmapStatisticsIconType.Sliders), }, new BeatmapStatistic { Name = @"Banana Shower Count", Content = bananaShowers.ToString(), - CreateIcon = () => new BeatmapStatisticSprite("spinners"), + CreateIcon = () => new BeatmapStatisticIcon(BeatmapStatisticsIconType.Spinners), } }; } diff --git a/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmap.cs b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmap.cs index f6b460f269..d1d5adea75 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmap.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmap.cs @@ -40,13 +40,13 @@ namespace osu.Game.Rulesets.Mania.Beatmaps new BeatmapStatistic { Name = @"Note Count", - CreateIcon = () => new BeatmapStatisticSprite("circles"), + CreateIcon = () => new BeatmapStatisticIcon(BeatmapStatisticsIconType.Circles), Content = notes.ToString(), }, new BeatmapStatistic { Name = @"Hold Note Count", - CreateIcon = () => new BeatmapStatisticSprite("sliders"), + CreateIcon = () => new BeatmapStatisticIcon(BeatmapStatisticsIconType.Sliders), Content = holdnotes.ToString(), }, }; diff --git a/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmap.cs b/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmap.cs index 513a9254ec..2d3cc3c103 100644 --- a/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmap.cs +++ b/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmap.cs @@ -22,19 +22,19 @@ namespace osu.Game.Rulesets.Osu.Beatmaps { Name = @"Circle Count", Content = circles.ToString(), - CreateIcon = () => new BeatmapStatisticSprite("circles"), + CreateIcon = () => new BeatmapStatisticIcon(BeatmapStatisticsIconType.Circles), }, new BeatmapStatistic { Name = @"Slider Count", Content = sliders.ToString(), - CreateIcon = () => new BeatmapStatisticSprite("sliders"), + CreateIcon = () => new BeatmapStatisticIcon(BeatmapStatisticsIconType.Sliders), }, new BeatmapStatistic { Name = @"Spinner Count", Content = spinners.ToString(), - CreateIcon = () => new BeatmapStatisticSprite("spinners"), + CreateIcon = () => new BeatmapStatisticIcon(BeatmapStatisticsIconType.Spinners), } }; } diff --git a/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmap.cs b/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmap.cs index c0f8af4fff..16a0726c8c 100644 --- a/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmap.cs +++ b/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmap.cs @@ -21,19 +21,19 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps new BeatmapStatistic { Name = @"Hit Count", - CreateIcon = () => new BeatmapStatisticSprite("circles"), + CreateIcon = () => new BeatmapStatisticIcon(BeatmapStatisticsIconType.Circles), Content = hits.ToString(), }, new BeatmapStatistic { Name = @"Drumroll Count", - CreateIcon = () => new BeatmapStatisticSprite("sliders"), + CreateIcon = () => new BeatmapStatisticIcon(BeatmapStatisticsIconType.Sliders), Content = drumrolls.ToString(), }, new BeatmapStatistic { Name = @"Swell Count", - CreateIcon = () => new BeatmapStatisticSprite("spinners"), + CreateIcon = () => new BeatmapStatisticIcon(BeatmapStatisticsIconType.Spinners), Content = swells.ToString(), } }; diff --git a/osu.Game/Beatmaps/BeatmapStatistic.cs b/osu.Game/Beatmaps/BeatmapStatistic.cs index 825bb08246..9d87a20d60 100644 --- a/osu.Game/Beatmaps/BeatmapStatistic.cs +++ b/osu.Game/Beatmaps/BeatmapStatistic.cs @@ -14,7 +14,7 @@ namespace osu.Game.Beatmaps public IconUsage Icon = FontAwesome.Regular.QuestionCircle; /// - /// A function to create the icon for display purposes. + /// A function to create the icon for display purposes. Use default icons available via whenever possible for conformity. /// public Func CreateIcon; diff --git a/osu.Game/Beatmaps/BeatmapStatisticIcon.cs b/osu.Game/Beatmaps/BeatmapStatisticIcon.cs new file mode 100644 index 0000000000..181fb540df --- /dev/null +++ b/osu.Game/Beatmaps/BeatmapStatisticIcon.cs @@ -0,0 +1,43 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using Humanizer; +using osu.Framework.Allocation; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Graphics.Textures; + +namespace osu.Game.Beatmaps +{ + /// + /// A default implementation of an icon used to represent beatmap statistics. + /// + public class BeatmapStatisticIcon : Sprite + { + private readonly BeatmapStatisticsIconType iconType; + + public BeatmapStatisticIcon(BeatmapStatisticsIconType iconType) + { + this.iconType = iconType; + } + + [BackgroundDependencyLoader] + private void load(TextureStore textures) + { + Texture = textures.Get($"Icons/BeatmapDetails/{iconType.ToString().Kebaberize()}"); + } + } + + public enum BeatmapStatisticsIconType + { + Accuracy, + ApproachRate, + Bpm, + Circles, + HpDrain, + Length, + OverallDifficulty, + Size, + Sliders, + Spinners, + } +} diff --git a/osu.Game/Beatmaps/BeatmapStatisticSprite.cs b/osu.Game/Beatmaps/BeatmapStatisticSprite.cs deleted file mode 100644 index 1cb0bacf0f..0000000000 --- a/osu.Game/Beatmaps/BeatmapStatisticSprite.cs +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using osu.Framework.Allocation; -using osu.Framework.Graphics.Sprites; -using osu.Framework.Graphics.Textures; - -namespace osu.Game.Beatmaps -{ - public class BeatmapStatisticSprite : Sprite - { - private readonly string iconName; - - public BeatmapStatisticSprite(string iconName) - { - this.iconName = iconName; - } - - [BackgroundDependencyLoader] - private void load(TextureStore textures) - { - Texture = textures.Get($"Icons/BeatmapDetails/{iconName}"); - } - } -} diff --git a/osu.Game/Screens/Select/BeatmapInfoWedge.cs b/osu.Game/Screens/Select/BeatmapInfoWedge.cs index 400f3e3063..2a3eb8c67a 100644 --- a/osu.Game/Screens/Select/BeatmapInfoWedge.cs +++ b/osu.Game/Screens/Select/BeatmapInfoWedge.cs @@ -318,14 +318,14 @@ namespace osu.Game.Screens.Select labels.Add(new InfoLabel(new BeatmapStatistic { Name = "Length", - CreateIcon = () => new BeatmapStatisticSprite("length"), + CreateIcon = () => new BeatmapStatisticIcon(BeatmapStatisticsIconType.Length), Content = TimeSpan.FromMilliseconds(b.BeatmapInfo.Length).ToString(@"m\:ss"), })); labels.Add(new InfoLabel(new BeatmapStatistic { Name = "BPM", - CreateIcon = () => new BeatmapStatisticSprite("bpm"), + CreateIcon = () => new BeatmapStatisticIcon(BeatmapStatisticsIconType.Bpm), Content = getBPMRange(b), })); From 4399f5976c2e380937311e925652c4a4be60accc Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 4 Sep 2020 15:20:55 +0900 Subject: [PATCH 272/320] Fix global mods being retained by rooms --- .../Multiplayer/TestSceneMatchSongSelect.cs | 22 +++++++++++++++++++ osu.Game/Screens/Select/MatchSongSelect.cs | 4 +--- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchSongSelect.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchSongSelect.cs index 3d225aa0a9..faea32f90f 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchSongSelect.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchSongSelect.cs @@ -162,6 +162,28 @@ namespace osu.Game.Tests.Visual.Multiplayer AddAssert("item 2 has rate 2", () => Precision.AlmostEquals(2, ((OsuModDoubleTime)Room.Playlist.Last().RequiredMods[0]).SpeedChange.Value)); } + /// + /// Tests that the global mod instances are not retained by the rooms, as global mod instances are retained and re-used by the mod select overlay. + /// + [Test] + public void TestGlobalModInstancesNotRetained() + { + OsuModDoubleTime mod = null; + + AddStep("set dt mod and store", () => + { + SelectedMods.Value = new[] { new OsuModDoubleTime() }; + + // Mod select overlay replaces our mod. + mod = (OsuModDoubleTime)SelectedMods.Value[0]; + }); + + AddStep("create item", () => songSelect.BeatmapDetails.CreateNewItem()); + + AddStep("change stored mod rate", () => mod.SpeedChange.Value = 2); + AddAssert("item has rate 1.5", () => Precision.AlmostEquals(1.5, ((OsuModDoubleTime)Room.Playlist.First().RequiredMods[0]).SpeedChange.Value)); + } + private class TestMatchSongSelect : MatchSongSelect { public new MatchBeatmapDetailArea BeatmapDetails => (MatchBeatmapDetailArea)base.BeatmapDetails; diff --git a/osu.Game/Screens/Select/MatchSongSelect.cs b/osu.Game/Screens/Select/MatchSongSelect.cs index 96a48fa3ac..8692833a21 100644 --- a/osu.Game/Screens/Select/MatchSongSelect.cs +++ b/osu.Game/Screens/Select/MatchSongSelect.cs @@ -76,9 +76,7 @@ namespace osu.Game.Screens.Select item.Ruleset.Value = Ruleset.Value; item.RequiredMods.Clear(); - item.RequiredMods.AddRange(Mods.Value); - - Mods.Value = Mods.Value.Select(m => m.CreateCopy()).ToArray(); + item.RequiredMods.AddRange(Mods.Value.Select(m => m.CreateCopy())); } } } From 0b3f2fe7df1d956d6cf3d53a263461957cb580ae Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 4 Sep 2020 15:21:48 +0900 Subject: [PATCH 273/320] Update framework --- osu.Android.props | 2 +- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index a41c1a5864..a096370a05 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -52,6 +52,6 @@ - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index d79806883e..cb8e30a084 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -24,7 +24,7 @@ - + diff --git a/osu.iOS.props b/osu.iOS.props index 16a8a1acb7..72b17d216d 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -70,7 +70,7 @@ - + @@ -80,7 +80,7 @@ - + From a15653c77cf79c1a6fc8628979d30c2dbb95492e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 4 Sep 2020 16:15:57 +0900 Subject: [PATCH 274/320] Fix potential hard crash if ruleset settings fail to construct --- .../Overlays/Settings/Sections/GameplaySection.cs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Settings/Sections/GameplaySection.cs b/osu.Game/Overlays/Settings/Sections/GameplaySection.cs index aca507f20a..c09e3a227d 100644 --- a/osu.Game/Overlays/Settings/Sections/GameplaySection.cs +++ b/osu.Game/Overlays/Settings/Sections/GameplaySection.cs @@ -1,12 +1,14 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Game.Overlays.Settings.Sections.Gameplay; using osu.Game.Rulesets; using System.Linq; using osu.Framework.Graphics.Sprites; +using osu.Framework.Logging; namespace osu.Game.Overlays.Settings.Sections { @@ -35,8 +37,18 @@ namespace osu.Game.Overlays.Settings.Sections foreach (Ruleset ruleset in rulesets.AvailableRulesets.Select(info => info.CreateInstance())) { SettingsSubsection section = ruleset.CreateSettings(); + if (section != null) - Add(section); + { + try + { + Add(section); + } + catch (Exception e) + { + Logger.Error(e, $"Failed to load ruleset settings"); + } + } } } } From 54013790fc9c4d86612c9bcce0609c76aeaada9d Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 4 Sep 2020 09:45:24 +0300 Subject: [PATCH 275/320] Fix MusicController raising TrackChanged event twice --- osu.Game/Overlays/MusicController.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index 17877a69a5..119aad5226 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -279,6 +279,10 @@ namespace osu.Game.Overlays private void changeBeatmap(WorkingBeatmap newWorking) { + // The provided beatmap is same as current, no need to do any changes. + if (newWorking == current) + return; + var lastWorking = current; TrackChangeDirection direction = TrackChangeDirection.None; From 42895e27b6f1188e6e623d5a921c99f4b4f0038f Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 4 Sep 2020 10:10:14 +0300 Subject: [PATCH 276/320] Expose track change results on the methods --- osu.Game/Overlays/MusicController.cs | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index 119aad5226..ea72ef0b84 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -207,7 +207,18 @@ namespace osu.Game.Overlays /// /// Play the previous track or restart the current track if it's current time below . /// - public void PreviousTrack() => Schedule(() => prev()); + /// + /// Invoked when the operation has been performed successfully. + /// The result isn't returned directly to the caller because + /// the operation is scheduled and isn't performed immediately. + /// + /// A of the operation. + public ScheduledDelegate PreviousTrack(Action onSuccess = null) => Schedule(() => + { + PreviousTrackResult res = prev(); + if (res != PreviousTrackResult.None) + onSuccess?.Invoke(res); + }); /// /// Play the previous track or restart the current track if it's current time below . @@ -243,7 +254,18 @@ namespace osu.Game.Overlays /// /// Play the next random or playlist track. /// - public void NextTrack() => Schedule(() => next()); + /// + /// Invoked when the operation has been performed successfully. + /// The result isn't returned directly to the caller because + /// the operation is scheduled and isn't performed immediately. + /// + /// A of the operation. + public ScheduledDelegate NextTrack(Action onSuccess = null) => Schedule(() => + { + bool res = next(); + if (res) + onSuccess?.Invoke(); + }); private bool next() { From 001509df55015a32b5b6f6d582c805f0a4f459f8 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 4 Sep 2020 10:22:37 +0300 Subject: [PATCH 277/320] Move music global action handling to an own component Due to requiring components that are added at an OsuGame-level --- osu.Game/OsuGame.cs | 2 + osu.Game/Overlays/Music/MusicActionHandler.cs | 82 +++++++++++++++++++ osu.Game/Overlays/MusicController.cs | 56 +------------ 3 files changed, 85 insertions(+), 55 deletions(-) create mode 100644 osu.Game/Overlays/Music/MusicActionHandler.cs diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 164a40c6a5..a73469d836 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -38,6 +38,7 @@ using osu.Game.Input; using osu.Game.Overlays.Notifications; using osu.Game.Input.Bindings; using osu.Game.Online.Chat; +using osu.Game.Overlays.Music; using osu.Game.Skinning; using osuTK.Graphics; using osu.Game.Overlays.Volume; @@ -647,6 +648,7 @@ namespace osu.Game chatOverlay.State.ValueChanged += state => channelManager.HighPollRate.Value = state.NewValue == Visibility.Visible; Add(externalLinkOpener = new ExternalLinkOpener()); + Add(new MusicActionHandler()); // side overlays which cancel each other. var singleDisplaySideOverlays = new OverlayContainer[] { Settings, notifications }; diff --git a/osu.Game/Overlays/Music/MusicActionHandler.cs b/osu.Game/Overlays/Music/MusicActionHandler.cs new file mode 100644 index 0000000000..17aa4c1d32 --- /dev/null +++ b/osu.Game/Overlays/Music/MusicActionHandler.cs @@ -0,0 +1,82 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Allocation; +using osu.Framework.Bindables; +using osu.Framework.Graphics; +using osu.Framework.Input.Bindings; +using osu.Game.Beatmaps; +using osu.Game.Input.Bindings; +using osu.Game.Overlays.OSD; + +namespace osu.Game.Overlays.Music +{ + /// + /// Handles relating to music playback, and displays a via the cached accordingly. + /// + public class MusicActionHandler : Component, IKeyBindingHandler + { + [Resolved] + private IBindable beatmap { get; set; } + + [Resolved] + private MusicController musicController { get; set; } + + [Resolved] + private OnScreenDisplay onScreenDisplay { get; set; } + + public bool OnPressed(GlobalAction action) + { + if (beatmap.Disabled) + return false; + + switch (action) + { + case GlobalAction.MusicPlay: + if (musicController.TogglePause()) + onScreenDisplay.Display(new MusicActionToast(musicController.IsPlaying ? "Play track" : "Pause track")); + + return true; + + case GlobalAction.MusicNext: + musicController.NextTrack(() => + { + onScreenDisplay.Display(new MusicActionToast("Next track")); + }).RunTask(); + + return true; + + case GlobalAction.MusicPrev: + musicController.PreviousTrack(res => + { + switch (res) + { + case PreviousTrackResult.Restart: + onScreenDisplay.Display(new MusicActionToast("Restart track")); + break; + + case PreviousTrackResult.Previous: + onScreenDisplay.Display(new MusicActionToast("Previous track")); + break; + } + }).RunTask(); + + return true; + } + + return false; + } + + public void OnReleased(GlobalAction action) + { + } + + private class MusicActionToast : Toast + { + public MusicActionToast(string action) + : base("Music Playback", action, string.Empty) + { + } + } + } +} diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index ea72ef0b84..69722a8c0c 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -12,12 +12,9 @@ using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Audio; using osu.Framework.Graphics.Containers; -using osu.Framework.Input.Bindings; using osu.Framework.Utils; using osu.Framework.Threading; using osu.Game.Beatmaps; -using osu.Game.Input.Bindings; -using osu.Game.Overlays.OSD; using osu.Game.Rulesets.Mods; namespace osu.Game.Overlays @@ -25,7 +22,7 @@ namespace osu.Game.Overlays /// /// Handles playback of the global music track. /// - public class MusicController : CompositeDrawable, IKeyBindingHandler + public class MusicController : CompositeDrawable { [Resolved] private BeatmapManager beatmaps { get; set; } @@ -62,9 +59,6 @@ namespace osu.Game.Overlays [Resolved] private IBindable> mods { get; set; } - [Resolved(canBeNull: true)] - private OnScreenDisplay onScreenDisplay { get; set; } - [NotNull] public DrawableTrack CurrentTrack { get; private set; } = new DrawableTrack(new TrackVirtual(1000)); @@ -428,54 +422,6 @@ namespace osu.Game.Overlays mod.ApplyToTrack(CurrentTrack); } } - - public bool OnPressed(GlobalAction action) - { - if (beatmap.Disabled) - return false; - - switch (action) - { - case GlobalAction.MusicPlay: - if (TogglePause()) - onScreenDisplay?.Display(new MusicControllerToast(IsPlaying ? "Play track" : "Pause track")); - return true; - - case GlobalAction.MusicNext: - if (next()) - onScreenDisplay?.Display(new MusicControllerToast("Next track")); - - return true; - - case GlobalAction.MusicPrev: - switch (prev()) - { - case PreviousTrackResult.Restart: - onScreenDisplay?.Display(new MusicControllerToast("Restart track")); - break; - - case PreviousTrackResult.Previous: - onScreenDisplay?.Display(new MusicControllerToast("Previous track")); - break; - } - - return true; - } - - return false; - } - - public void OnReleased(GlobalAction action) - { - } - - public class MusicControllerToast : Toast - { - public MusicControllerToast(string action) - : base("Music Playback", action, string.Empty) - { - } - } } public enum TrackChangeDirection From 4d9a06bde993bd416604e0b13e71a4fedf72873f Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 4 Sep 2020 10:23:06 +0300 Subject: [PATCH 278/320] Expose the global binding container to OsuGameTestScene --- osu.Game.Tests/Visual/Navigation/OsuGameTestScene.cs | 3 +++ osu.Game/OsuGameBase.cs | 10 +++++----- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/osu.Game.Tests/Visual/Navigation/OsuGameTestScene.cs b/osu.Game.Tests/Visual/Navigation/OsuGameTestScene.cs index c4acf4f7da..e29d23ba75 100644 --- a/osu.Game.Tests/Visual/Navigation/OsuGameTestScene.cs +++ b/osu.Game.Tests/Visual/Navigation/OsuGameTestScene.cs @@ -14,6 +14,7 @@ using osu.Framework.Testing; using osu.Game.Beatmaps; using osu.Game.Configuration; using osu.Game.Graphics.UserInterface; +using osu.Game.Input.Bindings; using osu.Game.Online.API; using osu.Game.Overlays; using osu.Game.Rulesets; @@ -109,6 +110,8 @@ namespace osu.Game.Tests.Visual.Navigation public new OsuConfigManager LocalConfig => base.LocalConfig; + public new GlobalActionContainer GlobalBinding => base.GlobalBinding; + public new Bindable Beatmap => base.Beatmap; public new Bindable Ruleset => base.Ruleset; diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index 51b9b7278d..8e01bda6ec 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -64,6 +64,8 @@ namespace osu.Game protected FileStore FileStore; + protected GlobalActionContainer GlobalBinding; + protected KeyBindingStore KeyBindingStore; protected SettingsStore SettingsStore; @@ -250,10 +252,8 @@ namespace osu.Game AddInternal(apiAccess); AddInternal(RulesetConfigCache); - GlobalActionContainer globalBinding; - MenuCursorContainer = new MenuCursorContainer { RelativeSizeAxes = Axes.Both }; - MenuCursorContainer.Child = globalBinding = new GlobalActionContainer(this) + MenuCursorContainer.Child = GlobalBinding = new GlobalActionContainer(this) { RelativeSizeAxes = Axes.Both, Child = content = new OsuTooltipContainer(MenuCursorContainer.Cursor) { RelativeSizeAxes = Axes.Both } @@ -261,8 +261,8 @@ namespace osu.Game base.Content.Add(CreateScalingContainer().WithChild(MenuCursorContainer)); - KeyBindingStore.Register(globalBinding); - dependencies.Cache(globalBinding); + KeyBindingStore.Register(GlobalBinding); + dependencies.Cache(GlobalBinding); PreviewTrackManager previewTrackManager; dependencies.Cache(previewTrackManager = new PreviewTrackManager()); From 314031d56d342f722d998d0897769ea2de4bde9c Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 4 Sep 2020 10:23:34 +0300 Subject: [PATCH 279/320] Add test cases ensuring music actions are handled from a game instance --- .../Menus/TestSceneMusicActionHandling.cs | 80 +++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 osu.Game.Tests/Visual/Menus/TestSceneMusicActionHandling.cs diff --git a/osu.Game.Tests/Visual/Menus/TestSceneMusicActionHandling.cs b/osu.Game.Tests/Visual/Menus/TestSceneMusicActionHandling.cs new file mode 100644 index 0000000000..9121309489 --- /dev/null +++ b/osu.Game.Tests/Visual/Menus/TestSceneMusicActionHandling.cs @@ -0,0 +1,80 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Collections.Generic; +using System.Linq; +using NUnit.Framework; +using osu.Game.Beatmaps; +using osu.Game.Input.Bindings; +using osu.Game.Overlays; +using osu.Game.Tests.Resources; +using osu.Game.Tests.Visual.Navigation; + +namespace osu.Game.Tests.Visual.Menus +{ + public class TestSceneMusicActionHandling : OsuGameTestScene + { + [Test] + public void TestMusicPlayAction() + { + AddStep("ensure playing something", () => Game.MusicController.EnsurePlayingSomething()); + AddStep("trigger music playback toggle action", () => Game.GlobalBinding.TriggerPressed(GlobalAction.MusicPlay)); + AddAssert("music paused", () => !Game.MusicController.IsPlaying && Game.MusicController.IsUserPaused); + AddStep("trigger music playback toggle action", () => Game.GlobalBinding.TriggerPressed(GlobalAction.MusicPlay)); + AddAssert("music resumed", () => Game.MusicController.IsPlaying && !Game.MusicController.IsUserPaused); + } + + [Test] + public void TestMusicNavigationActions() + { + int importId = 0; + Queue<(WorkingBeatmap working, TrackChangeDirection dir)> trackChangeQueue = null; + + // ensure we have at least two beatmaps available to identify the direction the music controller navigated to. + AddRepeatStep("import beatmap", () => Game.BeatmapManager.Import(new BeatmapSetInfo + { + Beatmaps = new List + { + new BeatmapInfo + { + BaseDifficulty = new BeatmapDifficulty(), + } + }, + Metadata = new BeatmapMetadata + { + Artist = $"a test map {importId++}", + Title = "title", + } + }).Wait(), 5); + + AddStep("import beatmap with track", () => + { + var setWithTrack = Game.BeatmapManager.Import(TestResources.GetTestBeatmapForImport()).Result; + Beatmap.Value = Game.BeatmapManager.GetWorkingBeatmap(setWithTrack.Beatmaps.First()); + }); + + AddStep("bind to track change", () => + { + trackChangeQueue = new Queue<(WorkingBeatmap working, TrackChangeDirection dir)>(); + Game.MusicController.TrackChanged += (working, dir) => trackChangeQueue.Enqueue((working, dir)); + }); + + AddStep("seek track to 6 second", () => Game.MusicController.SeekTo(6000)); + AddUntilStep("wait for current time to update", () => Game.MusicController.CurrentTrack.CurrentTime > 5000); + + AddStep("trigger music prev action", () => Game.GlobalBinding.TriggerPressed(GlobalAction.MusicPrev)); + AddAssert("no track change", () => trackChangeQueue.Count == 0); + AddUntilStep("track restarted", () => Game.MusicController.CurrentTrack.CurrentTime < 5000); + + AddStep("trigger music prev action", () => Game.GlobalBinding.TriggerPressed(GlobalAction.MusicPrev)); + AddAssert("track changed to previous", () => + trackChangeQueue.Count == 1 && + trackChangeQueue.Dequeue().dir == TrackChangeDirection.Prev); + + AddStep("trigger music next action", () => Game.GlobalBinding.TriggerPressed(GlobalAction.MusicNext)); + AddAssert("track changed to next", () => + trackChangeQueue.Count == 1 && + trackChangeQueue.Dequeue().dir == TrackChangeDirection.Next); + } + } +} From 0500f24a1dbdede80d403e1f9b03fea9cfabc901 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 4 Sep 2020 10:24:07 +0300 Subject: [PATCH 280/320] Remove now-redundant test case --- .../TestSceneNowPlayingOverlay.cs | 58 +------------------ 1 file changed, 1 insertion(+), 57 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneNowPlayingOverlay.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneNowPlayingOverlay.cs index c14a1ddbf2..475ab0c414 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneNowPlayingOverlay.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneNowPlayingOverlay.cs @@ -1,18 +1,11 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System.Collections.Generic; -using System.Linq; using NUnit.Framework; using osu.Framework.Allocation; -using osu.Framework.Audio; using osu.Framework.Graphics; -using osu.Framework.Platform; -using osu.Game.Beatmaps; using osu.Game.Overlays; -using osu.Game.Rulesets; using osu.Game.Rulesets.Osu; -using osu.Game.Tests.Resources; namespace osu.Game.Tests.Visual.UserInterface { @@ -24,14 +17,9 @@ namespace osu.Game.Tests.Visual.UserInterface private NowPlayingOverlay nowPlayingOverlay; - private RulesetStore rulesets; - [BackgroundDependencyLoader] - private void load(AudioManager audio, GameHost host) + private void load() { - Dependencies.Cache(rulesets = new RulesetStore(ContextFactory)); - Dependencies.Cache(manager = new BeatmapManager(LocalStorage, ContextFactory, rulesets, null, audio, host, Beatmap.Default)); - Beatmap.Value = CreateWorkingBeatmap(new OsuRuleset().RulesetInfo); nowPlayingOverlay = new NowPlayingOverlay @@ -51,49 +39,5 @@ namespace osu.Game.Tests.Visual.UserInterface AddToggleStep(@"toggle beatmap lock", state => Beatmap.Disabled = state); AddStep(@"hide", () => nowPlayingOverlay.Hide()); } - - private BeatmapManager manager { get; set; } - - private int importId; - - [Test] - public void TestPrevTrackBehavior() - { - // ensure we have at least two beatmaps available. - AddRepeatStep("import beatmap", () => manager.Import(new BeatmapSetInfo - { - Beatmaps = new List - { - new BeatmapInfo - { - BaseDifficulty = new BeatmapDifficulty(), - } - }, - Metadata = new BeatmapMetadata - { - Artist = $"a test map {importId++}", - Title = "title", - } - }).Wait(), 5); - - WorkingBeatmap currentBeatmap = null; - - AddStep("import beatmap with track", () => - { - var setWithTrack = manager.Import(TestResources.GetTestBeatmapForImport()).Result; - Beatmap.Value = currentBeatmap = manager.GetWorkingBeatmap(setWithTrack.Beatmaps.First()); - }); - - AddStep(@"Seek track to 6 second", () => musicController.SeekTo(6000)); - AddUntilStep(@"Wait for current time to update", () => musicController.CurrentTrack.CurrentTime > 5000); - - AddStep(@"Set previous", () => musicController.PreviousTrack()); - - AddAssert(@"Check beatmap didn't change", () => currentBeatmap == Beatmap.Value); - AddUntilStep("Wait for current time to update", () => musicController.CurrentTrack.CurrentTime < 5000); - - AddStep(@"Set previous", () => musicController.PreviousTrack()); - AddAssert(@"Check beatmap did change", () => currentBeatmap != Beatmap.Value); - } } } From 644f3375ac2210428cf7dfbd8afb58fb9e0dd0aa Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 4 Sep 2020 16:28:19 +0900 Subject: [PATCH 281/320] Also catch exceptions in the construction call --- .../Settings/Sections/GameplaySection.cs | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/osu.Game/Overlays/Settings/Sections/GameplaySection.cs b/osu.Game/Overlays/Settings/Sections/GameplaySection.cs index c09e3a227d..f76b8e085b 100644 --- a/osu.Game/Overlays/Settings/Sections/GameplaySection.cs +++ b/osu.Game/Overlays/Settings/Sections/GameplaySection.cs @@ -36,18 +36,16 @@ namespace osu.Game.Overlays.Settings.Sections { foreach (Ruleset ruleset in rulesets.AvailableRulesets.Select(info => info.CreateInstance())) { - SettingsSubsection section = ruleset.CreateSettings(); - - if (section != null) + try { - try - { + SettingsSubsection section = ruleset.CreateSettings(); + + if (section != null) Add(section); - } - catch (Exception e) - { - Logger.Error(e, $"Failed to load ruleset settings"); - } + } + catch (Exception e) + { + Logger.Error(e, $"Failed to load ruleset settings"); } } } From ab057e6c654886d961b5abd7b2bdd795a93ed28f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 4 Sep 2020 16:28:35 +0900 Subject: [PATCH 282/320] Remove unnecessary string interpolation --- osu.Game/Overlays/Settings/Sections/GameplaySection.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Settings/Sections/GameplaySection.cs b/osu.Game/Overlays/Settings/Sections/GameplaySection.cs index f76b8e085b..e5cebd28e2 100644 --- a/osu.Game/Overlays/Settings/Sections/GameplaySection.cs +++ b/osu.Game/Overlays/Settings/Sections/GameplaySection.cs @@ -45,7 +45,7 @@ namespace osu.Game.Overlays.Settings.Sections } catch (Exception e) { - Logger.Error(e, $"Failed to load ruleset settings"); + Logger.Error(e, "Failed to load ruleset settings"); } } } From 65d541456ab8a408095c1b028930f72dfc72f902 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 4 Sep 2020 11:11:07 +0300 Subject: [PATCH 283/320] Slight rewording --- osu.Game/Overlays/MusicController.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index 119aad5226..74a438a124 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -279,7 +279,7 @@ namespace osu.Game.Overlays private void changeBeatmap(WorkingBeatmap newWorking) { - // The provided beatmap is same as current, no need to do any changes. + // If the provided beatmap is same as current, then there is no need to do any changes. if (newWorking == current) return; From 4236e5fe71ceec15ffd6881532d8fda26dbd8f38 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 4 Sep 2020 11:31:54 +0300 Subject: [PATCH 284/320] Replace useless "matching-code" comment with explanation of how it could happen Co-authored-by: Dean Herbert --- osu.Game/Overlays/MusicController.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index 74a438a124..edef4d8589 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -279,7 +279,8 @@ namespace osu.Game.Overlays private void changeBeatmap(WorkingBeatmap newWorking) { - // If the provided beatmap is same as current, then there is no need to do any changes. + // This method can potentially be triggered multiple times as it is eagerly fired in next() / prev() to ensure correct execution order + // (changeBeatmap must be called before consumers receive the bindable changed event, which is not the case when called from the bindable itself). if (newWorking == current) return; From 3239576a239922e8dad80f61bff40a1b42205618 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 4 Sep 2020 11:50:49 +0300 Subject: [PATCH 285/320] Minor rewording of new comment Co-authored-by: Dean Herbert --- osu.Game/Overlays/MusicController.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index edef4d8589..31bd80d6f3 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -280,7 +280,7 @@ namespace osu.Game.Overlays private void changeBeatmap(WorkingBeatmap newWorking) { // This method can potentially be triggered multiple times as it is eagerly fired in next() / prev() to ensure correct execution order - // (changeBeatmap must be called before consumers receive the bindable changed event, which is not the case when called from the bindable itself). + // (changeBeatmap must be called before consumers receive the bindable changed event, which is not the case when the local beatmap bindable is updated directly). if (newWorking == current) return; From 569a56eccb85307cd3e4c080cb22492a116c2480 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 4 Sep 2020 13:33:23 +0300 Subject: [PATCH 286/320] Revert "Move adjustment to LegacySkinConfiguration as a default value" This reverts commit 18927304f10bd912fc9a09cb22aaed3dd38974d0. --- osu.Game.Rulesets.Osu/Skinning/LegacySliderBody.cs | 4 ++++ osu.Game/Skinning/LegacySkinConfiguration.cs | 9 --------- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Skinning/LegacySliderBody.cs b/osu.Game.Rulesets.Osu/Skinning/LegacySliderBody.cs index 21df49d80b..aad8b189d9 100644 --- a/osu.Game.Rulesets.Osu/Skinning/LegacySliderBody.cs +++ b/osu.Game.Rulesets.Osu/Skinning/LegacySliderBody.cs @@ -18,6 +18,10 @@ namespace osu.Game.Rulesets.Osu.Skinning { private const float shadow_portion = 1 - (OsuLegacySkinTransformer.LEGACY_CIRCLE_RADIUS / OsuHitObject.OBJECT_RADIUS); + protected new float CalculatedBorderPortion + // Roughly matches osu!stable's slider border portions. + => base.CalculatedBorderPortion * 0.77f; + public new Color4 AccentColour => new Color4(base.AccentColour.R, base.AccentColour.G, base.AccentColour.B, base.AccentColour.A * 0.70f); protected override Color4 ColourAt(float position) diff --git a/osu.Game/Skinning/LegacySkinConfiguration.cs b/osu.Game/Skinning/LegacySkinConfiguration.cs index b980d727ed..41b7aea34b 100644 --- a/osu.Game/Skinning/LegacySkinConfiguration.cs +++ b/osu.Game/Skinning/LegacySkinConfiguration.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System.Globalization; - namespace osu.Game.Skinning { public class LegacySkinConfiguration : SkinConfiguration @@ -14,13 +12,6 @@ namespace osu.Game.Skinning /// public decimal? LegacyVersion { get; internal set; } - public LegacySkinConfiguration() - { - // Roughly matches osu!stable's slider border portions. - // Can't use nameof(SliderBorderSize) as the lookup enum is declared in the osu! ruleset. - ConfigDictionary["SliderBorderSize"] = 0.77f.ToString(CultureInfo.InvariantCulture); - } - public enum LegacySetting { Version, From 1143d5d9928d58fb2dd058b2b1dca31f1b868281 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 4 Sep 2020 20:34:26 +0900 Subject: [PATCH 287/320] Update class exclusion for dynamic compilation --- osu.Game.Rulesets.Catch/CatchRuleset.cs | 2 -- osu.Game.Rulesets.Mania/ManiaRuleset.cs | 2 -- osu.Game.Rulesets.Osu/OsuRuleset.cs | 2 -- osu.Game.Rulesets.Taiko/TaikoRuleset.cs | 2 -- .../Navigation/TestScenePresentScore.cs | 1 + osu.Game/Beatmaps/BeatmapInfo.cs | 2 ++ osu.Game/Beatmaps/BeatmapMetadata.cs | 2 ++ osu.Game/Beatmaps/BeatmapSetInfo.cs | 2 ++ osu.Game/Beatmaps/WorkingBeatmap.cs | 2 ++ osu.Game/Configuration/OsuConfigManager.cs | 2 ++ osu.Game/Input/GameIdleTracker.cs | 25 +++++++++++++++++++ osu.Game/OsuGame.cs | 24 ------------------ osu.Game/Rulesets/Mods/Mod.cs | 2 ++ osu.Game/Rulesets/Ruleset.cs | 2 ++ osu.Game/Rulesets/RulesetInfo.cs | 2 ++ osu.Game/Screens/ScorePresentType.cs | 11 ++++++++ osu.Game/Tests/Visual/OsuTestScene.cs | 1 + 17 files changed, 54 insertions(+), 32 deletions(-) create mode 100644 osu.Game/Input/GameIdleTracker.cs create mode 100644 osu.Game/Screens/ScorePresentType.cs diff --git a/osu.Game.Rulesets.Catch/CatchRuleset.cs b/osu.Game.Rulesets.Catch/CatchRuleset.cs index 9437023c70..ca75a816f1 100644 --- a/osu.Game.Rulesets.Catch/CatchRuleset.cs +++ b/osu.Game.Rulesets.Catch/CatchRuleset.cs @@ -21,13 +21,11 @@ using osu.Game.Rulesets.Difficulty; using osu.Game.Rulesets.Scoring; using osu.Game.Scoring; using System; -using osu.Framework.Testing; using osu.Game.Rulesets.Catch.Skinning; using osu.Game.Skinning; namespace osu.Game.Rulesets.Catch { - [ExcludeFromDynamicCompile] public class CatchRuleset : Ruleset, ILegacyRuleset { public override DrawableRuleset CreateDrawableRulesetWith(IBeatmap beatmap, IReadOnlyList mods = null) => new DrawableCatchRuleset(this, beatmap, mods); diff --git a/osu.Game.Rulesets.Mania/ManiaRuleset.cs b/osu.Game.Rulesets.Mania/ManiaRuleset.cs index 37b34d1721..71ac85dd1b 100644 --- a/osu.Game.Rulesets.Mania/ManiaRuleset.cs +++ b/osu.Game.Rulesets.Mania/ManiaRuleset.cs @@ -12,7 +12,6 @@ using System.Linq; using osu.Framework.Graphics; using osu.Framework.Graphics.Sprites; using osu.Framework.Input.Bindings; -using osu.Framework.Testing; using osu.Game.Graphics; using osu.Game.Rulesets.Mania.Replays; using osu.Game.Rulesets.Replays.Types; @@ -35,7 +34,6 @@ using osu.Game.Screens.Ranking.Statistics; namespace osu.Game.Rulesets.Mania { - [ExcludeFromDynamicCompile] public class ManiaRuleset : Ruleset, ILegacyRuleset { /// diff --git a/osu.Game.Rulesets.Osu/OsuRuleset.cs b/osu.Game.Rulesets.Osu/OsuRuleset.cs index f527eb2312..7f4a0dcbbb 100644 --- a/osu.Game.Rulesets.Osu/OsuRuleset.cs +++ b/osu.Game.Rulesets.Osu/OsuRuleset.cs @@ -30,14 +30,12 @@ using osu.Game.Scoring; using osu.Game.Skinning; using System; using System.Linq; -using osu.Framework.Testing; using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Osu.Statistics; using osu.Game.Screens.Ranking.Statistics; namespace osu.Game.Rulesets.Osu { - [ExcludeFromDynamicCompile] public class OsuRuleset : Ruleset, ILegacyRuleset { public override DrawableRuleset CreateDrawableRulesetWith(IBeatmap beatmap, IReadOnlyList mods = null) => new DrawableOsuRuleset(this, beatmap, mods); diff --git a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs index dbc32f2c3e..9d485e3f20 100644 --- a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs +++ b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs @@ -22,7 +22,6 @@ using osu.Game.Rulesets.Taiko.Scoring; using osu.Game.Scoring; using System; using System.Linq; -using osu.Framework.Testing; using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Taiko.Edit; using osu.Game.Rulesets.Taiko.Objects; @@ -32,7 +31,6 @@ using osu.Game.Skinning; namespace osu.Game.Rulesets.Taiko { - [ExcludeFromDynamicCompile] public class TaikoRuleset : Ruleset, ILegacyRuleset { public override DrawableRuleset CreateDrawableRulesetWith(IBeatmap beatmap, IReadOnlyList mods = null) => new DrawableTaikoRuleset(this, beatmap, mods); diff --git a/osu.Game.Tests/Visual/Navigation/TestScenePresentScore.cs b/osu.Game.Tests/Visual/Navigation/TestScenePresentScore.cs index b2e18849c9..a899d072ac 100644 --- a/osu.Game.Tests/Visual/Navigation/TestScenePresentScore.cs +++ b/osu.Game.Tests/Visual/Navigation/TestScenePresentScore.cs @@ -12,6 +12,7 @@ using osu.Game.Rulesets; using osu.Game.Rulesets.Mania; using osu.Game.Rulesets.Osu; using osu.Game.Scoring; +using osu.Game.Screens; using osu.Game.Screens.Menu; using osu.Game.Screens.Play; using osu.Game.Screens.Ranking; diff --git a/osu.Game/Beatmaps/BeatmapInfo.cs b/osu.Game/Beatmaps/BeatmapInfo.cs index 3860f12baa..c5be5810e9 100644 --- a/osu.Game/Beatmaps/BeatmapInfo.cs +++ b/osu.Game/Beatmaps/BeatmapInfo.cs @@ -7,6 +7,7 @@ using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; using System.Linq; using Newtonsoft.Json; +using osu.Framework.Testing; using osu.Game.Database; using osu.Game.IO.Serialization; using osu.Game.Rulesets; @@ -14,6 +15,7 @@ using osu.Game.Scoring; namespace osu.Game.Beatmaps { + [ExcludeFromDynamicCompile] [Serializable] public class BeatmapInfo : IEquatable, IJsonSerializable, IHasPrimaryKey { diff --git a/osu.Game/Beatmaps/BeatmapMetadata.cs b/osu.Game/Beatmaps/BeatmapMetadata.cs index 775d78f1fb..39b3c23ddd 100644 --- a/osu.Game/Beatmaps/BeatmapMetadata.cs +++ b/osu.Game/Beatmaps/BeatmapMetadata.cs @@ -6,11 +6,13 @@ using System.Collections.Generic; using System.ComponentModel.DataAnnotations.Schema; using System.Linq; using Newtonsoft.Json; +using osu.Framework.Testing; using osu.Game.Database; using osu.Game.Users; namespace osu.Game.Beatmaps { + [ExcludeFromDynamicCompile] [Serializable] public class BeatmapMetadata : IEquatable, IHasPrimaryKey { diff --git a/osu.Game/Beatmaps/BeatmapSetInfo.cs b/osu.Game/Beatmaps/BeatmapSetInfo.cs index a8b83dca38..b76d780860 100644 --- a/osu.Game/Beatmaps/BeatmapSetInfo.cs +++ b/osu.Game/Beatmaps/BeatmapSetInfo.cs @@ -5,10 +5,12 @@ using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations.Schema; using System.Linq; +using osu.Framework.Testing; using osu.Game.Database; namespace osu.Game.Beatmaps { + [ExcludeFromDynamicCompile] public class BeatmapSetInfo : IHasPrimaryKey, IHasFiles, ISoftDelete, IEquatable { public int ID { get; set; } diff --git a/osu.Game/Beatmaps/WorkingBeatmap.cs b/osu.Game/Beatmaps/WorkingBeatmap.cs index 6a161e6e04..19b54e1783 100644 --- a/osu.Game/Beatmaps/WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/WorkingBeatmap.cs @@ -13,6 +13,7 @@ using osu.Framework.Audio.Track; using osu.Framework.Graphics.Textures; using osu.Framework.Logging; using osu.Framework.Statistics; +using osu.Framework.Testing; using osu.Game.Rulesets; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Objects.Types; @@ -22,6 +23,7 @@ using osu.Game.Storyboards; namespace osu.Game.Beatmaps { + [ExcludeFromDynamicCompile] public abstract class WorkingBeatmap : IWorkingBeatmap { public readonly BeatmapInfo BeatmapInfo; diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs index a8a8794320..e5432cb84e 100644 --- a/osu.Game/Configuration/OsuConfigManager.cs +++ b/osu.Game/Configuration/OsuConfigManager.cs @@ -6,6 +6,7 @@ using osu.Framework.Configuration; using osu.Framework.Configuration.Tracking; using osu.Framework.Extensions; using osu.Framework.Platform; +using osu.Framework.Testing; using osu.Game.Overlays; using osu.Game.Rulesets.Scoring; using osu.Game.Screens.Select; @@ -13,6 +14,7 @@ using osu.Game.Screens.Select.Filter; namespace osu.Game.Configuration { + [ExcludeFromDynamicCompile] public class OsuConfigManager : IniConfigManager { protected override void InitialiseDefaults() diff --git a/osu.Game/Input/GameIdleTracker.cs b/osu.Game/Input/GameIdleTracker.cs new file mode 100644 index 0000000000..260be7e5c9 --- /dev/null +++ b/osu.Game/Input/GameIdleTracker.cs @@ -0,0 +1,25 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Input; + +namespace osu.Game.Input +{ + public class GameIdleTracker : IdleTracker + { + private InputManager inputManager; + + public GameIdleTracker(int time) + : base(time) + { + } + + protected override void LoadComplete() + { + base.LoadComplete(); + inputManager = GetContainingInputManager(); + } + + protected override bool AllowIdle => inputManager.FocusedDrawable == null; + } +} diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 164a40c6a5..a8722d03ab 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -718,24 +718,6 @@ namespace osu.Game overlayContent.ChangeChildDepth(overlay, (float)-Clock.CurrentTime); } - public class GameIdleTracker : IdleTracker - { - private InputManager inputManager; - - public GameIdleTracker(int time) - : base(time) - { - } - - protected override void LoadComplete() - { - base.LoadComplete(); - inputManager = GetContainingInputManager(); - } - - protected override bool AllowIdle => inputManager.FocusedDrawable == null; - } - private void forwardLoggedErrorsToNotifications() { int recentLogCount = 0; @@ -991,10 +973,4 @@ namespace osu.Game Exit(); } } - - public enum ScorePresentType - { - Results, - Gameplay - } } diff --git a/osu.Game/Rulesets/Mods/Mod.cs b/osu.Game/Rulesets/Mods/Mod.cs index 52ffa0ad2a..b8dc7a2661 100644 --- a/osu.Game/Rulesets/Mods/Mod.cs +++ b/osu.Game/Rulesets/Mods/Mod.cs @@ -9,6 +9,7 @@ using System.Reflection; using Newtonsoft.Json; using osu.Framework.Bindables; using osu.Framework.Graphics.Sprites; +using osu.Framework.Testing; using osu.Game.Configuration; using osu.Game.IO.Serialization; using osu.Game.Rulesets.UI; @@ -18,6 +19,7 @@ namespace osu.Game.Rulesets.Mods /// /// The base class for gameplay modifiers. /// + [ExcludeFromDynamicCompile] public abstract class Mod : IMod, IJsonSerializable { /// diff --git a/osu.Game/Rulesets/Ruleset.cs b/osu.Game/Rulesets/Ruleset.cs index 3a7f433a37..915544d010 100644 --- a/osu.Game/Rulesets/Ruleset.cs +++ b/osu.Game/Rulesets/Ruleset.cs @@ -23,10 +23,12 @@ using osu.Game.Scoring; using osu.Game.Skinning; using osu.Game.Users; using JetBrains.Annotations; +using osu.Framework.Testing; using osu.Game.Screens.Ranking.Statistics; namespace osu.Game.Rulesets { + [ExcludeFromDynamicCompile] public abstract class Ruleset { public RulesetInfo RulesetInfo { get; internal set; } diff --git a/osu.Game/Rulesets/RulesetInfo.cs b/osu.Game/Rulesets/RulesetInfo.cs index 2e32b96084..d5aca8c650 100644 --- a/osu.Game/Rulesets/RulesetInfo.cs +++ b/osu.Game/Rulesets/RulesetInfo.cs @@ -5,9 +5,11 @@ using System; using System.Diagnostics.CodeAnalysis; using System.Linq; using Newtonsoft.Json; +using osu.Framework.Testing; namespace osu.Game.Rulesets { + [ExcludeFromDynamicCompile] public class RulesetInfo : IEquatable { public int? ID { get; set; } diff --git a/osu.Game/Screens/ScorePresentType.cs b/osu.Game/Screens/ScorePresentType.cs new file mode 100644 index 0000000000..3216f92091 --- /dev/null +++ b/osu.Game/Screens/ScorePresentType.cs @@ -0,0 +1,11 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +namespace osu.Game.Screens +{ + public enum ScorePresentType + { + Results, + Gameplay + } +} diff --git a/osu.Game/Tests/Visual/OsuTestScene.cs b/osu.Game/Tests/Visual/OsuTestScene.cs index 756074c0b3..4db5139813 100644 --- a/osu.Game/Tests/Visual/OsuTestScene.cs +++ b/osu.Game/Tests/Visual/OsuTestScene.cs @@ -30,6 +30,7 @@ using osu.Game.Tests.Beatmaps; namespace osu.Game.Tests.Visual { + [ExcludeFromDynamicCompile] public abstract class OsuTestScene : TestScene { protected Bindable Beatmap { get; private set; } From 33b76015d80df41618867a94227fbe2251bae200 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Sun, 6 Sep 2020 01:54:08 +0300 Subject: [PATCH 288/320] Fix MusicActionHandler unnecessarily depending on OnScreenDisplay's existance --- osu.Game/Overlays/Music/MusicActionHandler.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/osu.Game/Overlays/Music/MusicActionHandler.cs b/osu.Game/Overlays/Music/MusicActionHandler.cs index 17aa4c1d32..cd8548c1c0 100644 --- a/osu.Game/Overlays/Music/MusicActionHandler.cs +++ b/osu.Game/Overlays/Music/MusicActionHandler.cs @@ -22,7 +22,7 @@ namespace osu.Game.Overlays.Music [Resolved] private MusicController musicController { get; set; } - [Resolved] + [Resolved(canBeNull: true)] private OnScreenDisplay onScreenDisplay { get; set; } public bool OnPressed(GlobalAction action) @@ -34,14 +34,14 @@ namespace osu.Game.Overlays.Music { case GlobalAction.MusicPlay: if (musicController.TogglePause()) - onScreenDisplay.Display(new MusicActionToast(musicController.IsPlaying ? "Play track" : "Pause track")); + onScreenDisplay?.Display(new MusicActionToast(musicController.IsPlaying ? "Play track" : "Pause track")); return true; case GlobalAction.MusicNext: musicController.NextTrack(() => { - onScreenDisplay.Display(new MusicActionToast("Next track")); + onScreenDisplay?.Display(new MusicActionToast("Next track")); }).RunTask(); return true; @@ -52,11 +52,11 @@ namespace osu.Game.Overlays.Music switch (res) { case PreviousTrackResult.Restart: - onScreenDisplay.Display(new MusicActionToast("Restart track")); + onScreenDisplay?.Display(new MusicActionToast("Restart track")); break; case PreviousTrackResult.Previous: - onScreenDisplay.Display(new MusicActionToast("Previous track")); + onScreenDisplay?.Display(new MusicActionToast("Previous track")); break; } }).RunTask(); From e37a3a84fd2e232d6f1eeb0f71eec3c64417256d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 5 Sep 2020 15:40:26 +0200 Subject: [PATCH 289/320] Use legible tuple member name --- .../Visual/Menus/TestSceneMusicActionHandling.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/osu.Game.Tests/Visual/Menus/TestSceneMusicActionHandling.cs b/osu.Game.Tests/Visual/Menus/TestSceneMusicActionHandling.cs index 9121309489..9ee86eaf78 100644 --- a/osu.Game.Tests/Visual/Menus/TestSceneMusicActionHandling.cs +++ b/osu.Game.Tests/Visual/Menus/TestSceneMusicActionHandling.cs @@ -28,7 +28,7 @@ namespace osu.Game.Tests.Visual.Menus public void TestMusicNavigationActions() { int importId = 0; - Queue<(WorkingBeatmap working, TrackChangeDirection dir)> trackChangeQueue = null; + Queue<(WorkingBeatmap working, TrackChangeDirection changeDirection)> trackChangeQueue = null; // ensure we have at least two beatmaps available to identify the direction the music controller navigated to. AddRepeatStep("import beatmap", () => Game.BeatmapManager.Import(new BeatmapSetInfo @@ -55,8 +55,8 @@ namespace osu.Game.Tests.Visual.Menus AddStep("bind to track change", () => { - trackChangeQueue = new Queue<(WorkingBeatmap working, TrackChangeDirection dir)>(); - Game.MusicController.TrackChanged += (working, dir) => trackChangeQueue.Enqueue((working, dir)); + trackChangeQueue = new Queue<(WorkingBeatmap, TrackChangeDirection)>(); + Game.MusicController.TrackChanged += (working, changeDirection) => trackChangeQueue.Enqueue((working, changeDirection)); }); AddStep("seek track to 6 second", () => Game.MusicController.SeekTo(6000)); @@ -69,12 +69,12 @@ namespace osu.Game.Tests.Visual.Menus AddStep("trigger music prev action", () => Game.GlobalBinding.TriggerPressed(GlobalAction.MusicPrev)); AddAssert("track changed to previous", () => trackChangeQueue.Count == 1 && - trackChangeQueue.Dequeue().dir == TrackChangeDirection.Prev); + trackChangeQueue.Dequeue().changeDirection == TrackChangeDirection.Prev); AddStep("trigger music next action", () => Game.GlobalBinding.TriggerPressed(GlobalAction.MusicNext)); AddAssert("track changed to next", () => trackChangeQueue.Count == 1 && - trackChangeQueue.Dequeue().dir == TrackChangeDirection.Next); + trackChangeQueue.Dequeue().changeDirection == TrackChangeDirection.Next); } } } From 8b1151284c507b12cbb56811a90018f916645873 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 5 Sep 2020 15:43:16 +0200 Subject: [PATCH 290/320] Simplify overly verbose step names --- .../Visual/Menus/TestSceneMusicActionHandling.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/osu.Game.Tests/Visual/Menus/TestSceneMusicActionHandling.cs b/osu.Game.Tests/Visual/Menus/TestSceneMusicActionHandling.cs index 9ee86eaf78..9b8ba47992 100644 --- a/osu.Game.Tests/Visual/Menus/TestSceneMusicActionHandling.cs +++ b/osu.Game.Tests/Visual/Menus/TestSceneMusicActionHandling.cs @@ -18,9 +18,9 @@ namespace osu.Game.Tests.Visual.Menus public void TestMusicPlayAction() { AddStep("ensure playing something", () => Game.MusicController.EnsurePlayingSomething()); - AddStep("trigger music playback toggle action", () => Game.GlobalBinding.TriggerPressed(GlobalAction.MusicPlay)); + AddStep("toggle playback", () => Game.GlobalBinding.TriggerPressed(GlobalAction.MusicPlay)); AddAssert("music paused", () => !Game.MusicController.IsPlaying && Game.MusicController.IsUserPaused); - AddStep("trigger music playback toggle action", () => Game.GlobalBinding.TriggerPressed(GlobalAction.MusicPlay)); + AddStep("toggle playback", () => Game.GlobalBinding.TriggerPressed(GlobalAction.MusicPlay)); AddAssert("music resumed", () => Game.MusicController.IsPlaying && !Game.MusicController.IsUserPaused); } @@ -62,16 +62,16 @@ namespace osu.Game.Tests.Visual.Menus AddStep("seek track to 6 second", () => Game.MusicController.SeekTo(6000)); AddUntilStep("wait for current time to update", () => Game.MusicController.CurrentTrack.CurrentTime > 5000); - AddStep("trigger music prev action", () => Game.GlobalBinding.TriggerPressed(GlobalAction.MusicPrev)); + AddStep("press previous", () => Game.GlobalBinding.TriggerPressed(GlobalAction.MusicPrev)); AddAssert("no track change", () => trackChangeQueue.Count == 0); AddUntilStep("track restarted", () => Game.MusicController.CurrentTrack.CurrentTime < 5000); - AddStep("trigger music prev action", () => Game.GlobalBinding.TriggerPressed(GlobalAction.MusicPrev)); + AddStep("press previous", () => Game.GlobalBinding.TriggerPressed(GlobalAction.MusicPrev)); AddAssert("track changed to previous", () => trackChangeQueue.Count == 1 && trackChangeQueue.Dequeue().changeDirection == TrackChangeDirection.Prev); - AddStep("trigger music next action", () => Game.GlobalBinding.TriggerPressed(GlobalAction.MusicNext)); + AddStep("press next", () => Game.GlobalBinding.TriggerPressed(GlobalAction.MusicNext)); AddAssert("track changed to next", () => trackChangeQueue.Count == 1 && trackChangeQueue.Dequeue().changeDirection == TrackChangeDirection.Next); From 2b16e2535304263507f338bad1591e4d25cf70e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sun, 6 Sep 2020 18:44:41 +0200 Subject: [PATCH 291/320] Revert unnecessary passing down of tuple in test --- .../Beatmaps/Formats/LegacyBeatmapEncoderTest.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs index 6e103af3f0..17d910036f 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs @@ -38,8 +38,8 @@ namespace osu.Game.Tests.Beatmaps.Formats var decoded = decodeFromLegacy(beatmaps_resource_store.GetStream(name), name); var decodedAfterEncode = decodeFromLegacy(encodeToLegacy(decoded), name); - sort(decoded); - sort(decodedAfterEncode); + sort(decoded.beatmap); + sort(decodedAfterEncode.beatmap); Assert.That(decodedAfterEncode.beatmap.Serialize(), Is.EqualTo(decoded.beatmap.Serialize())); Assert.IsTrue(areComboColoursEqual(decodedAfterEncode.beatmapSkin.Configuration, decoded.beatmapSkin.Configuration)); @@ -57,10 +57,10 @@ namespace osu.Game.Tests.Beatmaps.Formats return a.ComboColours.SequenceEqual(b.ComboColours); } - private void sort((IBeatmap beatmap, ISkin beatmapSkin) tuple) + private void sort(IBeatmap beatmap) { // Sort control points to ensure a sane ordering, as they may be parsed in different orders. This works because each group contains only uniquely-typed control points. - foreach (var g in tuple.beatmap.ControlPointInfo.Groups) + foreach (var g in beatmap.ControlPointInfo.Groups) { ArrayList.Adapter((IList)g.ControlPoints).Sort( Comparer.Create((c1, c2) => string.Compare(c1.GetType().ToString(), c2.GetType().ToString(), StringComparison.Ordinal))); From b4b9c71f00eab44bb189a3d1936b71edc6219c03 Mon Sep 17 00:00:00 2001 From: Joehu Date: Sun, 6 Sep 2020 10:13:06 -0700 Subject: [PATCH 292/320] Make all toolbar tooltips lowercase --- osu.Game/Overlays/BeatmapListing/BeatmapListingHeader.cs | 2 +- osu.Game/Overlays/Changelog/ChangelogHeader.cs | 2 +- osu.Game/Overlays/Dashboard/DashboardOverlayHeader.cs | 2 +- osu.Game/Overlays/News/NewsHeader.cs | 2 +- osu.Game/Overlays/NotificationOverlay.cs | 4 ++-- osu.Game/Overlays/Rankings/RankingsOverlayHeader.cs | 2 +- osu.Game/Overlays/SettingsOverlay.cs | 2 +- osu.Game/Overlays/Toolbar/ToolbarHomeButton.cs | 4 ++-- osu.Game/Overlays/Toolbar/ToolbarRulesetTabButton.cs | 2 +- 9 files changed, 11 insertions(+), 11 deletions(-) diff --git a/osu.Game/Overlays/BeatmapListing/BeatmapListingHeader.cs b/osu.Game/Overlays/BeatmapListing/BeatmapListingHeader.cs index b7f511271c..6a9a71210a 100644 --- a/osu.Game/Overlays/BeatmapListing/BeatmapListingHeader.cs +++ b/osu.Game/Overlays/BeatmapListing/BeatmapListingHeader.cs @@ -12,7 +12,7 @@ namespace osu.Game.Overlays.BeatmapListing public BeatmapListingTitle() { Title = "beatmap listing"; - Description = "Browse for new beatmaps"; + Description = "browse for new beatmaps"; IconTexture = "Icons/Hexacons/beatmap"; } } diff --git a/osu.Game/Overlays/Changelog/ChangelogHeader.cs b/osu.Game/Overlays/Changelog/ChangelogHeader.cs index bdc59297bb..f4be4328e7 100644 --- a/osu.Game/Overlays/Changelog/ChangelogHeader.cs +++ b/osu.Game/Overlays/Changelog/ChangelogHeader.cs @@ -115,7 +115,7 @@ namespace osu.Game.Overlays.Changelog public ChangelogHeaderTitle() { Title = "changelog"; - Description = "Track recent dev updates in the osu! ecosystem"; + Description = "track recent dev updates in the osu! ecosystem"; IconTexture = "Icons/Hexacons/devtools"; } } diff --git a/osu.Game/Overlays/Dashboard/DashboardOverlayHeader.cs b/osu.Game/Overlays/Dashboard/DashboardOverlayHeader.cs index a964d84c4f..36bf589877 100644 --- a/osu.Game/Overlays/Dashboard/DashboardOverlayHeader.cs +++ b/osu.Game/Overlays/Dashboard/DashboardOverlayHeader.cs @@ -12,7 +12,7 @@ namespace osu.Game.Overlays.Dashboard public DashboardTitle() { Title = "dashboard"; - Description = "View your friends and other information"; + Description = "view your friends and other information"; IconTexture = "Icons/Hexacons/social"; } } diff --git a/osu.Game/Overlays/News/NewsHeader.cs b/osu.Game/Overlays/News/NewsHeader.cs index 38ac519387..63174128e7 100644 --- a/osu.Game/Overlays/News/NewsHeader.cs +++ b/osu.Game/Overlays/News/NewsHeader.cs @@ -57,7 +57,7 @@ namespace osu.Game.Overlays.News public NewsHeaderTitle() { Title = "news"; - Description = "Get up-to-date on community happenings"; + Description = "get up-to-date on community happenings"; IconTexture = "Icons/Hexacons/news"; } } diff --git a/osu.Game/Overlays/NotificationOverlay.cs b/osu.Game/Overlays/NotificationOverlay.cs index b7d916c48f..b5714fbcae 100644 --- a/osu.Game/Overlays/NotificationOverlay.cs +++ b/osu.Game/Overlays/NotificationOverlay.cs @@ -19,8 +19,8 @@ namespace osu.Game.Overlays public class NotificationOverlay : OsuFocusedOverlayContainer, INamedOverlayComponent { public string IconTexture => "Icons/Hexacons/notification"; - public string Title => "Notifications"; - public string Description => "Waiting for 'ya"; + public string Title => "notifications"; + public string Description => "waiting for 'ya"; private const float width = 320; diff --git a/osu.Game/Overlays/Rankings/RankingsOverlayHeader.cs b/osu.Game/Overlays/Rankings/RankingsOverlayHeader.cs index 7039ab8214..92e22f5873 100644 --- a/osu.Game/Overlays/Rankings/RankingsOverlayHeader.cs +++ b/osu.Game/Overlays/Rankings/RankingsOverlayHeader.cs @@ -30,7 +30,7 @@ namespace osu.Game.Overlays.Rankings public RankingsTitle() { Title = "ranking"; - Description = "Find out who's the best right now"; + Description = "find out who's the best right now"; IconTexture = "Icons/Hexacons/rankings"; } } diff --git a/osu.Game/Overlays/SettingsOverlay.cs b/osu.Game/Overlays/SettingsOverlay.cs index 0532a031f3..e1bcdbbaf0 100644 --- a/osu.Game/Overlays/SettingsOverlay.cs +++ b/osu.Game/Overlays/SettingsOverlay.cs @@ -17,7 +17,7 @@ namespace osu.Game.Overlays { public string IconTexture => "Icons/Hexacons/settings"; public string Title => "settings"; - public string Description => "Change the way osu! behaves"; + public string Description => "change the way osu! behaves"; protected override IEnumerable CreateSections() => new SettingsSection[] { diff --git a/osu.Game/Overlays/Toolbar/ToolbarHomeButton.cs b/osu.Game/Overlays/Toolbar/ToolbarHomeButton.cs index 6b2c24c0f3..76fbd40d66 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarHomeButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarHomeButton.cs @@ -17,8 +17,8 @@ namespace osu.Game.Overlays.Toolbar [BackgroundDependencyLoader] private void load() { - TooltipMain = "Home"; - TooltipSub = "Return to the main menu"; + TooltipMain = "home"; + TooltipSub = "return to the main menu"; SetIcon("Icons/Hexacons/home"); } } diff --git a/osu.Game/Overlays/Toolbar/ToolbarRulesetTabButton.cs b/osu.Game/Overlays/Toolbar/ToolbarRulesetTabButton.cs index 754b679599..564fd65719 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarRulesetTabButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarRulesetTabButton.cs @@ -27,7 +27,7 @@ namespace osu.Game.Overlays.Toolbar var rInstance = value.CreateInstance(); ruleset.TooltipMain = rInstance.Description; - ruleset.TooltipSub = $"Play some {rInstance.Description}"; + ruleset.TooltipSub = $"play some {rInstance.Description}"; ruleset.SetIcon(rInstance.CreateIcon()); } From 8f8f907fc7c3dda37646e8e6a8eca762ca47d32a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 7 Sep 2020 13:27:28 +0900 Subject: [PATCH 293/320] Fix missed string --- osu.Game/Overlays/NowPlayingOverlay.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/NowPlayingOverlay.cs b/osu.Game/Overlays/NowPlayingOverlay.cs index d1df1fa936..55adf02a45 100644 --- a/osu.Game/Overlays/NowPlayingOverlay.cs +++ b/osu.Game/Overlays/NowPlayingOverlay.cs @@ -29,7 +29,7 @@ namespace osu.Game.Overlays { public string IconTexture => "Icons/Hexacons/music"; public string Title => "now playing"; - public string Description => "Manage the currently playing track"; + public string Description => "manage the currently playing track"; private const float player_height = 130; private const float transition_length = 800; From daff060c9a0ff86c12c662583b641871d23c8a5e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 7 Sep 2020 15:18:15 +0900 Subject: [PATCH 294/320] Hide the game-wide cursor on touch input --- osu.Game/Graphics/Cursor/MenuCursorContainer.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/osu.Game/Graphics/Cursor/MenuCursorContainer.cs b/osu.Game/Graphics/Cursor/MenuCursorContainer.cs index 3015c44613..8da80f25ff 100644 --- a/osu.Game/Graphics/Cursor/MenuCursorContainer.cs +++ b/osu.Game/Graphics/Cursor/MenuCursorContainer.cs @@ -5,6 +5,7 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Cursor; using osu.Framework.Input; +using osu.Framework.Input.StateChanges; namespace osu.Game.Graphics.Cursor { @@ -47,7 +48,10 @@ namespace osu.Game.Graphics.Cursor { base.Update(); - if (!CanShowCursor) + var lastMouseSource = GetContainingInputManager().CurrentState.Mouse.LastSource; + bool hasValidInput = lastMouseSource != null && !(lastMouseSource is ISourcedFromTouch); + + if (!hasValidInput || !CanShowCursor) { currentTarget?.Cursor?.Hide(); currentTarget = null; From 1a55d92c719c0d2db2eb0d2c977be242fe2afda8 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 7 Sep 2020 15:31:05 +0900 Subject: [PATCH 295/320] Use local input manager --- osu.Game/Graphics/Cursor/MenuCursorContainer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Graphics/Cursor/MenuCursorContainer.cs b/osu.Game/Graphics/Cursor/MenuCursorContainer.cs index 8da80f25ff..4c7f7957e9 100644 --- a/osu.Game/Graphics/Cursor/MenuCursorContainer.cs +++ b/osu.Game/Graphics/Cursor/MenuCursorContainer.cs @@ -48,7 +48,7 @@ namespace osu.Game.Graphics.Cursor { base.Update(); - var lastMouseSource = GetContainingInputManager().CurrentState.Mouse.LastSource; + var lastMouseSource = inputManager.CurrentState.Mouse.LastSource; bool hasValidInput = lastMouseSource != null && !(lastMouseSource is ISourcedFromTouch); if (!hasValidInput || !CanShowCursor) From ecc9c2957ffa287c6eff47fcc49b7dd544f7d0f1 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 7 Sep 2020 16:30:05 +0900 Subject: [PATCH 296/320] Avoid float precision error in mania conversion --- .../Beatmaps/ManiaBeatmapConverter.cs | 5 ++-- .../Legacy/DistanceObjectPatternGenerator.cs | 23 +++++++++---------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs index b025ac7992..211905835c 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs @@ -5,7 +5,6 @@ using osu.Game.Rulesets.Mania.Objects; using System; using System.Linq; using System.Collections.Generic; -using osu.Framework.Utils; using osu.Game.Audio; using osu.Game.Beatmaps; using osu.Game.Rulesets.Objects; @@ -167,8 +166,10 @@ namespace osu.Game.Rulesets.Mania.Beatmaps var positionData = original as IHasPosition; - for (double time = original.StartTime; !Precision.DefinitelyBigger(time, generator.EndTime); time += generator.SegmentDuration) + for (int i = 0; i <= generator.SpanCount; i++) { + double time = original.StartTime + generator.SegmentDuration * i; + recordNote(time, positionData?.Position ?? Vector2.Zero); computeDensity(time); } diff --git a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs index d03eb0b3c9..fe146c5324 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs @@ -27,8 +27,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy public readonly double EndTime; public readonly double SegmentDuration; - - private readonly int spanCount; + public readonly int SpanCount; private PatternType convertType; @@ -42,20 +41,20 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy var distanceData = hitObject as IHasDistance; var repeatsData = hitObject as IHasRepeats; - spanCount = repeatsData?.SpanCount() ?? 1; + SpanCount = repeatsData?.SpanCount() ?? 1; TimingControlPoint timingPoint = beatmap.ControlPointInfo.TimingPointAt(hitObject.StartTime); DifficultyControlPoint difficultyPoint = beatmap.ControlPointInfo.DifficultyPointAt(hitObject.StartTime); // The true distance, accounting for any repeats - double distance = (distanceData?.Distance ?? 0) * spanCount; + double distance = (distanceData?.Distance ?? 0) * SpanCount; // The velocity of the osu! hit object - calculated as the velocity of a slider double osuVelocity = osu_base_scoring_distance * beatmap.BeatmapInfo.BaseDifficulty.SliderMultiplier * difficultyPoint.SpeedMultiplier / timingPoint.BeatLength; // The duration of the osu! hit object double osuDuration = distance / osuVelocity; EndTime = hitObject.StartTime + osuDuration; - SegmentDuration = (EndTime - HitObject.StartTime) / spanCount; + SegmentDuration = (EndTime - HitObject.StartTime) / SpanCount; } public override IEnumerable Generate() @@ -96,7 +95,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy return pattern; } - if (spanCount > 1) + if (SpanCount > 1) { if (SegmentDuration <= 90) return generateRandomHoldNotes(HitObject.StartTime, 1); @@ -104,7 +103,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy if (SegmentDuration <= 120) { convertType |= PatternType.ForceNotStack; - return generateRandomNotes(HitObject.StartTime, spanCount + 1); + return generateRandomNotes(HitObject.StartTime, SpanCount + 1); } if (SegmentDuration <= 160) @@ -117,7 +116,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy if (duration >= 4000) return generateNRandomNotes(HitObject.StartTime, 0.23, 0, 0); - if (SegmentDuration > 400 && spanCount < TotalColumns - 1 - RandomStart) + if (SegmentDuration > 400 && SpanCount < TotalColumns - 1 - RandomStart) return generateTiledHoldNotes(HitObject.StartTime); return generateHoldAndNormalNotes(HitObject.StartTime); @@ -251,7 +250,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy int column = GetColumn((HitObject as IHasXPosition)?.X ?? 0, true); bool increasing = Random.NextDouble() > 0.5; - for (int i = 0; i <= spanCount; i++) + for (int i = 0; i <= SpanCount; i++) { addToPattern(pattern, column, startTime, startTime); startTime += SegmentDuration; @@ -302,7 +301,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy int nextColumn = GetColumn((HitObject as IHasXPosition)?.X ?? 0, true); - for (int i = 0; i <= spanCount; i++) + for (int i = 0; i <= SpanCount; i++) { addToPattern(pattern, nextColumn, startTime, startTime); @@ -393,7 +392,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy var pattern = new Pattern(); - int columnRepeat = Math.Min(spanCount, TotalColumns); + int columnRepeat = Math.Min(SpanCount, TotalColumns); int nextColumn = GetColumn((HitObject as IHasXPosition)?.X ?? 0, true); if (convertType.HasFlag(PatternType.ForceNotStack) && PreviousPattern.ColumnWithObjects < TotalColumns) @@ -447,7 +446,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy var rowPattern = new Pattern(); - for (int i = 0; i <= spanCount; i++) + for (int i = 0; i <= SpanCount; i++) { if (!(ignoreHead && startTime == HitObject.StartTime)) { From c72a8d475552049d602b69a8867ff5f5b440e081 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 7 Sep 2020 17:18:40 +0900 Subject: [PATCH 297/320] Add zero-length slider test --- .../ManiaBeatmapConversionTest.cs | 1 + ...ero-length-slider-expected-conversion.json | 14 +++++++++++++ .../Testing/Beatmaps/zero-length-slider.osu | 20 +++++++++++++++++++ 3 files changed, 35 insertions(+) create mode 100644 osu.Game.Rulesets.Mania/Resources/Testing/Beatmaps/zero-length-slider-expected-conversion.json create mode 100644 osu.Game.Rulesets.Mania/Resources/Testing/Beatmaps/zero-length-slider.osu diff --git a/osu.Game.Rulesets.Mania.Tests/ManiaBeatmapConversionTest.cs b/osu.Game.Rulesets.Mania.Tests/ManiaBeatmapConversionTest.cs index d0ff1fab43..d1e1280c7f 100644 --- a/osu.Game.Rulesets.Mania.Tests/ManiaBeatmapConversionTest.cs +++ b/osu.Game.Rulesets.Mania.Tests/ManiaBeatmapConversionTest.cs @@ -19,6 +19,7 @@ namespace osu.Game.Rulesets.Mania.Tests protected override string ResourceAssembly => "osu.Game.Rulesets.Mania"; [TestCase("basic")] + [TestCase("zero-length-slider")] public void Test(string name) => base.Test(name); protected override IEnumerable CreateConvertValue(HitObject hitObject) diff --git a/osu.Game.Rulesets.Mania/Resources/Testing/Beatmaps/zero-length-slider-expected-conversion.json b/osu.Game.Rulesets.Mania/Resources/Testing/Beatmaps/zero-length-slider-expected-conversion.json new file mode 100644 index 0000000000..229760cd1c --- /dev/null +++ b/osu.Game.Rulesets.Mania/Resources/Testing/Beatmaps/zero-length-slider-expected-conversion.json @@ -0,0 +1,14 @@ +{ + "Mappings": [{ + "RandomW": 3083084786, + "RandomX": 273326509, + "RandomY": 273553282, + "RandomZ": 2659838971, + "StartTime": 4836, + "Objects": [{ + "StartTime": 4836, + "EndTime": 4836, + "Column": 0 + }] + }] +} \ No newline at end of file diff --git a/osu.Game.Rulesets.Mania/Resources/Testing/Beatmaps/zero-length-slider.osu b/osu.Game.Rulesets.Mania/Resources/Testing/Beatmaps/zero-length-slider.osu new file mode 100644 index 0000000000..9b8ac1f9db --- /dev/null +++ b/osu.Game.Rulesets.Mania/Resources/Testing/Beatmaps/zero-length-slider.osu @@ -0,0 +1,20 @@ +osu file format v14 + +[General] +StackLeniency: 0.7 +Mode: 0 + +[Difficulty] +HPDrainRate:1 +CircleSize:4 +OverallDifficulty:1 +ApproachRate:9 +SliderMultiplier:2.5 +SliderTickRate:0.5 + +[TimingPoints] +34,431.654676258993,4,1,0,50,1,0 +4782,-66.6666666666667,4,1,0,20,0,0 + +[HitObjects] +15,199,4836,22,0,L,1,46.8750017881394 \ No newline at end of file From 679dc34aa410ec3c6732c52b981537136f5ab0c7 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 7 Sep 2020 17:18:54 +0900 Subject: [PATCH 298/320] Add test timeouts --- osu.Game.Rulesets.Catch.Tests/CatchBeatmapConversionTest.cs | 1 + osu.Game.Rulesets.Mania.Tests/ManiaBeatmapConversionTest.cs | 1 + osu.Game.Rulesets.Osu.Tests/OsuBeatmapConversionTest.cs | 1 + osu.Game.Rulesets.Taiko.Tests/TaikoBeatmapConversionTest.cs | 1 + 4 files changed, 4 insertions(+) diff --git a/osu.Game.Rulesets.Catch.Tests/CatchBeatmapConversionTest.cs b/osu.Game.Rulesets.Catch.Tests/CatchBeatmapConversionTest.cs index 8c48158acd..466cbdaf8d 100644 --- a/osu.Game.Rulesets.Catch.Tests/CatchBeatmapConversionTest.cs +++ b/osu.Game.Rulesets.Catch.Tests/CatchBeatmapConversionTest.cs @@ -14,6 +14,7 @@ using osu.Game.Tests.Beatmaps; namespace osu.Game.Rulesets.Catch.Tests { [TestFixture] + [Timeout(10000)] public class CatchBeatmapConversionTest : BeatmapConversionTest { protected override string ResourceAssembly => "osu.Game.Rulesets.Catch"; diff --git a/osu.Game.Rulesets.Mania.Tests/ManiaBeatmapConversionTest.cs b/osu.Game.Rulesets.Mania.Tests/ManiaBeatmapConversionTest.cs index d1e1280c7f..0c57267970 100644 --- a/osu.Game.Rulesets.Mania.Tests/ManiaBeatmapConversionTest.cs +++ b/osu.Game.Rulesets.Mania.Tests/ManiaBeatmapConversionTest.cs @@ -14,6 +14,7 @@ using osu.Game.Tests.Beatmaps; namespace osu.Game.Rulesets.Mania.Tests { [TestFixture] + [Timeout(10000)] public class ManiaBeatmapConversionTest : BeatmapConversionTest { protected override string ResourceAssembly => "osu.Game.Rulesets.Mania"; diff --git a/osu.Game.Rulesets.Osu.Tests/OsuBeatmapConversionTest.cs b/osu.Game.Rulesets.Osu.Tests/OsuBeatmapConversionTest.cs index cd3daf18a9..7d32895083 100644 --- a/osu.Game.Rulesets.Osu.Tests/OsuBeatmapConversionTest.cs +++ b/osu.Game.Rulesets.Osu.Tests/OsuBeatmapConversionTest.cs @@ -12,6 +12,7 @@ using osu.Game.Tests.Beatmaps; namespace osu.Game.Rulesets.Osu.Tests { [TestFixture] + [Timeout(10000)] public class OsuBeatmapConversionTest : BeatmapConversionTest { protected override string ResourceAssembly => "osu.Game.Rulesets.Osu"; diff --git a/osu.Game.Rulesets.Taiko.Tests/TaikoBeatmapConversionTest.cs b/osu.Game.Rulesets.Taiko.Tests/TaikoBeatmapConversionTest.cs index d0c57b20c0..5e550a5d03 100644 --- a/osu.Game.Rulesets.Taiko.Tests/TaikoBeatmapConversionTest.cs +++ b/osu.Game.Rulesets.Taiko.Tests/TaikoBeatmapConversionTest.cs @@ -12,6 +12,7 @@ using osu.Game.Tests.Beatmaps; namespace osu.Game.Rulesets.Taiko.Tests { [TestFixture] + [Timeout(10000)] public class TaikoBeatmapConversionTest : BeatmapConversionTest { protected override string ResourceAssembly => "osu.Game.Rulesets.Taiko"; From a8a0bfb8aa26012fd6d4d3343eadf58bede72752 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 7 Sep 2020 18:01:56 +0900 Subject: [PATCH 299/320] Update framework --- osu.Android.props | 2 +- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index f62ba48953..62397ca028 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -52,6 +52,6 @@ - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 526dca421a..1de0633d1f 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -24,7 +24,7 @@ - + diff --git a/osu.iOS.props b/osu.iOS.props index 0cbbba70b9..7187b48907 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -70,7 +70,7 @@ - + @@ -80,7 +80,7 @@ - + From 6091714f158ff4675612d43de3bf1be99b1910f2 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 7 Sep 2020 17:34:30 +0900 Subject: [PATCH 300/320] Limit BPM entry via slider to a sane range --- osu.Game/Screens/Edit/Timing/TimingSection.cs | 39 ++++++++++++++----- 1 file changed, 30 insertions(+), 9 deletions(-) diff --git a/osu.Game/Screens/Edit/Timing/TimingSection.cs b/osu.Game/Screens/Edit/Timing/TimingSection.cs index 906644ce14..8e6ea90797 100644 --- a/osu.Game/Screens/Edit/Timing/TimingSection.cs +++ b/osu.Game/Screens/Edit/Timing/TimingSection.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; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -12,7 +13,7 @@ namespace osu.Game.Screens.Edit.Timing { internal class TimingSection : Section { - private SettingsSlider bpm; + private SettingsSlider bpmSlider; private SettingsEnumDropdown timeSignature; [BackgroundDependencyLoader] @@ -20,7 +21,7 @@ namespace osu.Game.Screens.Edit.Timing { Flow.AddRange(new Drawable[] { - bpm = new BPMSlider + bpmSlider = new BPMSlider { Bindable = new TimingControlPoint().BeatLengthBindable, LabelText = "BPM", @@ -36,7 +37,7 @@ namespace osu.Game.Screens.Edit.Timing { if (point.NewValue != null) { - bpm.Bindable = point.NewValue.BeatLengthBindable; + bpmSlider.Bindable = point.NewValue.BeatLengthBindable; timeSignature.Bindable = point.NewValue.TimeSignatureBindable; } } @@ -54,6 +55,9 @@ namespace osu.Game.Screens.Edit.Timing private class BPMSlider : SettingsSlider { + private const double sane_minimum = 60; + private const double sane_maximum = 200; + private readonly BindableDouble beatLengthBindable = new BindableDouble(); private BindableDouble bpmBindable; @@ -63,22 +67,39 @@ namespace osu.Game.Screens.Edit.Timing get => base.Bindable; set { - // incoming will be beatlength - + // incoming will be beat length, not bpm beatLengthBindable.UnbindBindings(); beatLengthBindable.BindTo(value); - base.Bindable = bpmBindable = new BindableDouble(beatLengthToBpm(beatLengthBindable.Value)) + double initial = beatLengthToBpm(beatLengthBindable.Value); + + bpmBindable = new BindableDouble(initial) { - MinValue = beatLengthToBpm(beatLengthBindable.MaxValue), - MaxValue = beatLengthToBpm(beatLengthBindable.MinValue), Default = beatLengthToBpm(beatLengthBindable.Default), }; - bpmBindable.BindValueChanged(bpm => beatLengthBindable.Value = beatLengthToBpm(bpm.NewValue)); + updateCurrent(initial); + + bpmBindable.BindValueChanged(bpm => + { + updateCurrent(bpm.NewValue); + beatLengthBindable.Value = beatLengthToBpm(bpm.NewValue); + }); + + base.Bindable = bpmBindable; } } + private void updateCurrent(double newValue) + { + // we use a more sane range for the slider display unless overridden by the user. + // if a value comes in outside our range, we should expand temporarily. + bpmBindable.MinValue = Math.Min(newValue, sane_minimum); + bpmBindable.MaxValue = Math.Max(newValue, sane_maximum); + + bpmBindable.Value = newValue; + } + private double beatLengthToBpm(double beatLength) => 60000 / beatLength; } } From 86512d6e8d4ad6ba2d20c14bcc76a6fd2708f372 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 7 Sep 2020 17:39:13 +0900 Subject: [PATCH 301/320] Add BPM entry textbox --- osu.Game/Screens/Edit/Timing/TimingSection.cs | 81 ++++++++++++++----- 1 file changed, 60 insertions(+), 21 deletions(-) diff --git a/osu.Game/Screens/Edit/Timing/TimingSection.cs b/osu.Game/Screens/Edit/Timing/TimingSection.cs index 8e6ea90797..6fed4589ce 100644 --- a/osu.Game/Screens/Edit/Timing/TimingSection.cs +++ b/osu.Game/Screens/Edit/Timing/TimingSection.cs @@ -7,6 +7,7 @@ using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Beatmaps.Timing; +using osu.Game.Graphics.UserInterfaceV2; using osu.Game.Overlays.Settings; namespace osu.Game.Screens.Edit.Timing @@ -15,16 +16,21 @@ namespace osu.Game.Screens.Edit.Timing { private SettingsSlider bpmSlider; private SettingsEnumDropdown timeSignature; + private BPMTextBox bpmTextEntry; [BackgroundDependencyLoader] private void load() { Flow.AddRange(new Drawable[] { + bpmTextEntry = new BPMTextBox + { + Bindable = new TimingControlPoint().BeatLengthBindable, + Label = "BPM", + }, bpmSlider = new BPMSlider { Bindable = new TimingControlPoint().BeatLengthBindable, - LabelText = "BPM", }, timeSignature = new SettingsEnumDropdown { @@ -38,6 +44,7 @@ namespace osu.Game.Screens.Edit.Timing if (point.NewValue != null) { bpmSlider.Bindable = point.NewValue.BeatLengthBindable; + bpmTextEntry.Bindable = point.NewValue.BeatLengthBindable; timeSignature.Bindable = point.NewValue.TimeSignatureBindable; } } @@ -53,14 +60,63 @@ namespace osu.Game.Screens.Edit.Timing }; } + private class BPMTextBox : LabelledTextBox + { + public BPMTextBox() + { + OnCommit += (val, isNew) => + { + if (!isNew) return; + + if (double.TryParse(Current.Value, out double doubleVal)) + { + try + { + beatLengthBindable.Value = beatLengthToBpm(doubleVal); + } + catch + { + // will restore the previous text value on failure. + beatLengthBindable.TriggerChange(); + } + } + }; + + beatLengthBindable.BindValueChanged(val => + { + Current.Value = beatLengthToBpm(val.NewValue).ToString(); + }); + } + + private readonly BindableDouble beatLengthBindable = new BindableDouble(); + + public Bindable Bindable + { + get => beatLengthBindable; + set + { + // incoming will be beat length, not bpm + beatLengthBindable.UnbindBindings(); + beatLengthBindable.BindTo(value); + } + } + } + private class BPMSlider : SettingsSlider { private const double sane_minimum = 60; private const double sane_maximum = 200; private readonly BindableDouble beatLengthBindable = new BindableDouble(); + private readonly BindableDouble bpmBindable = new BindableDouble(); - private BindableDouble bpmBindable; + public BPMSlider() + { + beatLengthBindable.BindValueChanged(beatLength => updateCurrent(beatLengthToBpm(beatLength.NewValue))); + bpmBindable.BindValueChanged(bpm => bpmBindable.Default = beatLengthBindable.Value = beatLengthToBpm(bpm.NewValue)); + + base.Bindable = bpmBindable; + } public override Bindable Bindable { @@ -70,23 +126,6 @@ namespace osu.Game.Screens.Edit.Timing // incoming will be beat length, not bpm beatLengthBindable.UnbindBindings(); beatLengthBindable.BindTo(value); - - double initial = beatLengthToBpm(beatLengthBindable.Value); - - bpmBindable = new BindableDouble(initial) - { - Default = beatLengthToBpm(beatLengthBindable.Default), - }; - - updateCurrent(initial); - - bpmBindable.BindValueChanged(bpm => - { - updateCurrent(bpm.NewValue); - beatLengthBindable.Value = beatLengthToBpm(bpm.NewValue); - }); - - base.Bindable = bpmBindable; } } @@ -99,8 +138,8 @@ namespace osu.Game.Screens.Edit.Timing bpmBindable.Value = newValue; } - - private double beatLengthToBpm(double beatLength) => 60000 / beatLength; } + + private static double beatLengthToBpm(double beatLength) => 60000 / beatLength; } } From 98676af7bb3b737aeb07f8fbb8f7a821e21372d8 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 7 Sep 2020 18:18:34 +0900 Subject: [PATCH 302/320] Move default declarations for readability --- osu.Game/Screens/Edit/Timing/TimingSection.cs | 25 ++++++++----------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/osu.Game/Screens/Edit/Timing/TimingSection.cs b/osu.Game/Screens/Edit/Timing/TimingSection.cs index 6fed4589ce..0112471522 100644 --- a/osu.Game/Screens/Edit/Timing/TimingSection.cs +++ b/osu.Game/Screens/Edit/Timing/TimingSection.cs @@ -23,15 +23,8 @@ namespace osu.Game.Screens.Edit.Timing { Flow.AddRange(new Drawable[] { - bpmTextEntry = new BPMTextBox - { - Bindable = new TimingControlPoint().BeatLengthBindable, - Label = "BPM", - }, - bpmSlider = new BPMSlider - { - Bindable = new TimingControlPoint().BeatLengthBindable, - }, + bpmTextEntry = new BPMTextBox(), + bpmSlider = new BPMSlider(), timeSignature = new SettingsEnumDropdown { LabelText = "Time Signature" @@ -62,8 +55,12 @@ namespace osu.Game.Screens.Edit.Timing private class BPMTextBox : LabelledTextBox { + private readonly BindableNumber beatLengthBindable = new TimingControlPoint().BeatLengthBindable; + public BPMTextBox() { + Label = "BPM"; + OnCommit += (val, isNew) => { if (!isNew) return; @@ -84,12 +81,10 @@ namespace osu.Game.Screens.Edit.Timing beatLengthBindable.BindValueChanged(val => { - Current.Value = beatLengthToBpm(val.NewValue).ToString(); - }); + Current.Value = beatLengthToBpm(val.NewValue).ToString("N2"); + }, true); } - private readonly BindableDouble beatLengthBindable = new BindableDouble(); - public Bindable Bindable { get => beatLengthBindable; @@ -107,12 +102,12 @@ namespace osu.Game.Screens.Edit.Timing private const double sane_minimum = 60; private const double sane_maximum = 200; - private readonly BindableDouble beatLengthBindable = new BindableDouble(); + private readonly BindableNumber beatLengthBindable = new TimingControlPoint().BeatLengthBindable; private readonly BindableDouble bpmBindable = new BindableDouble(); public BPMSlider() { - beatLengthBindable.BindValueChanged(beatLength => updateCurrent(beatLengthToBpm(beatLength.NewValue))); + beatLengthBindable.BindValueChanged(beatLength => updateCurrent(beatLengthToBpm(beatLength.NewValue)), true); bpmBindable.BindValueChanged(bpm => bpmBindable.Default = beatLengthBindable.Value = beatLengthToBpm(bpm.NewValue)); base.Bindable = bpmBindable; From 1468b9589fd7e843cc53c27dcfa6cddcb7bcf1a3 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 7 Sep 2020 18:20:47 +0900 Subject: [PATCH 303/320] Increase max sane BPM value --- osu.Game/Screens/Edit/Timing/TimingSection.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/Timing/TimingSection.cs b/osu.Game/Screens/Edit/Timing/TimingSection.cs index 0112471522..879363ba08 100644 --- a/osu.Game/Screens/Edit/Timing/TimingSection.cs +++ b/osu.Game/Screens/Edit/Timing/TimingSection.cs @@ -100,7 +100,7 @@ namespace osu.Game.Screens.Edit.Timing private class BPMSlider : SettingsSlider { private const double sane_minimum = 60; - private const double sane_maximum = 200; + private const double sane_maximum = 240; private readonly BindableNumber beatLengthBindable = new TimingControlPoint().BeatLengthBindable; private readonly BindableDouble bpmBindable = new BindableDouble(); From 01c0b61b203df181285cc052fb73509073ffefbb Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 8 Sep 2020 01:52:31 +0900 Subject: [PATCH 304/320] Fix incorrect test names --- osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs b/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs index cef8105490..0702b02bb1 100644 --- a/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs +++ b/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs @@ -761,7 +761,7 @@ namespace osu.Game.Tests.Beatmaps.IO [Test] public void TestCreateNewEmptyBeatmap() { - using (HeadlessGameHost host = new CleanRunHeadlessGameHost(nameof(TestUpdateBeatmapFile))) + using (HeadlessGameHost host = new CleanRunHeadlessGameHost(nameof(TestCreateNewEmptyBeatmap))) { try { @@ -788,7 +788,7 @@ namespace osu.Game.Tests.Beatmaps.IO [Test] public void TestCreateNewBeatmapWithObject() { - using (HeadlessGameHost host = new CleanRunHeadlessGameHost(nameof(TestUpdateBeatmapFile))) + using (HeadlessGameHost host = new CleanRunHeadlessGameHost(nameof(TestCreateNewBeatmapWithObject))) { try { From 2b62579488c76a5f3bc65455085178912081e459 Mon Sep 17 00:00:00 2001 From: Joehu Date: Mon, 7 Sep 2020 10:18:22 -0700 Subject: [PATCH 305/320] Lowercase one more toolbar tooltip --- osu.Game/Overlays/ChatOverlay.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/ChatOverlay.cs b/osu.Game/Overlays/ChatOverlay.cs index bcc2227be8..25a59e9b25 100644 --- a/osu.Game/Overlays/ChatOverlay.cs +++ b/osu.Game/Overlays/ChatOverlay.cs @@ -30,7 +30,7 @@ namespace osu.Game.Overlays { public string IconTexture => "Icons/Hexacons/messaging"; public string Title => "chat"; - public string Description => "Join the real-time discussion"; + public string Description => "join the real-time discussion"; private const float textbox_height = 60; private const float channel_selection_min_height = 0.3f; From 5268eee0fb7a51866d78eec067a4d5e2e069f264 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 8 Sep 2020 11:31:42 +0900 Subject: [PATCH 306/320] Avoid requiring sending the calling method for CleanRunHeadlessGameHost --- .../Beatmaps/IO/ImportBeatmapTest.cs | 38 +++++++++---------- osu.Game.Tests/Scores/IO/ImportScoreTest.cs | 10 ++--- osu.Game/Tests/CleanRunHeadlessGameHost.cs | 12 +++++- 3 files changed, 34 insertions(+), 26 deletions(-) diff --git a/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs b/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs index 0702b02bb1..dd3dba1274 100644 --- a/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs +++ b/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs @@ -34,7 +34,7 @@ namespace osu.Game.Tests.Beatmaps.IO public async Task TestImportWhenClosed() { // unfortunately for the time being we need to reference osu.Framework.Desktop for a game host here. - using (HeadlessGameHost host = new CleanRunHeadlessGameHost(nameof(TestImportWhenClosed))) + using (HeadlessGameHost host = new CleanRunHeadlessGameHost()) { try { @@ -51,7 +51,7 @@ namespace osu.Game.Tests.Beatmaps.IO public async Task TestImportThenDelete() { // unfortunately for the time being we need to reference osu.Framework.Desktop for a game host here. - using (HeadlessGameHost host = new CleanRunHeadlessGameHost(nameof(TestImportThenDelete))) + using (HeadlessGameHost host = new CleanRunHeadlessGameHost()) { try { @@ -72,7 +72,7 @@ namespace osu.Game.Tests.Beatmaps.IO public async Task TestImportThenImport() { // unfortunately for the time being we need to reference osu.Framework.Desktop for a game host here. - using (HeadlessGameHost host = new CleanRunHeadlessGameHost(nameof(TestImportThenImport))) + using (HeadlessGameHost host = new CleanRunHeadlessGameHost()) { try { @@ -98,7 +98,7 @@ namespace osu.Game.Tests.Beatmaps.IO [Test] public async Task TestImportThenImportWithReZip() { - using (HeadlessGameHost host = new CleanRunHeadlessGameHost(nameof(TestImportThenImportWithReZip))) + using (HeadlessGameHost host = new CleanRunHeadlessGameHost()) { try { @@ -156,7 +156,7 @@ namespace osu.Game.Tests.Beatmaps.IO [Test] public async Task TestImportThenImportWithChangedFile() { - using (HeadlessGameHost host = new CleanRunHeadlessGameHost(nameof(TestImportThenImportWithChangedFile))) + using (HeadlessGameHost host = new CleanRunHeadlessGameHost()) { try { @@ -207,7 +207,7 @@ namespace osu.Game.Tests.Beatmaps.IO [Test] public async Task TestImportThenImportWithDifferentFilename() { - using (HeadlessGameHost host = new CleanRunHeadlessGameHost(nameof(TestImportThenImportWithDifferentFilename))) + using (HeadlessGameHost host = new CleanRunHeadlessGameHost()) { try { @@ -259,7 +259,7 @@ namespace osu.Game.Tests.Beatmaps.IO public async Task TestImportCorruptThenImport() { // unfortunately for the time being we need to reference osu.Framework.Desktop for a game host here. - using (HeadlessGameHost host = new CleanRunHeadlessGameHost(nameof(TestImportCorruptThenImport))) + using (HeadlessGameHost host = new CleanRunHeadlessGameHost()) { try { @@ -301,7 +301,7 @@ namespace osu.Game.Tests.Beatmaps.IO public async Task TestRollbackOnFailure() { // unfortunately for the time being we need to reference osu.Framework.Desktop for a game host here. - using (HeadlessGameHost host = new CleanRunHeadlessGameHost(nameof(TestRollbackOnFailure))) + using (HeadlessGameHost host = new CleanRunHeadlessGameHost()) { try { @@ -378,7 +378,7 @@ namespace osu.Game.Tests.Beatmaps.IO public async Task TestImportThenDeleteThenImport() { // unfortunately for the time being we need to reference osu.Framework.Desktop for a game host here. - using (HeadlessGameHost host = new CleanRunHeadlessGameHost(nameof(TestImportThenDeleteThenImport))) + using (HeadlessGameHost host = new CleanRunHeadlessGameHost()) { try { @@ -406,7 +406,7 @@ namespace osu.Game.Tests.Beatmaps.IO public async Task TestImportThenDeleteThenImportWithOnlineIDMismatch(bool set) { // unfortunately for the time being we need to reference osu.Framework.Desktop for a game host here. - using (HeadlessGameHost host = new CleanRunHeadlessGameHost($"{nameof(TestImportThenDeleteThenImportWithOnlineIDMismatch)}-{set}")) + using (HeadlessGameHost host = new CleanRunHeadlessGameHost(set.ToString())) { try { @@ -440,7 +440,7 @@ namespace osu.Game.Tests.Beatmaps.IO public async Task TestImportWithDuplicateBeatmapIDs() { // unfortunately for the time being we need to reference osu.Framework.Desktop for a game host here. - using (HeadlessGameHost host = new CleanRunHeadlessGameHost(nameof(TestImportWithDuplicateBeatmapIDs))) + using (HeadlessGameHost host = new CleanRunHeadlessGameHost()) { try { @@ -526,7 +526,7 @@ namespace osu.Game.Tests.Beatmaps.IO [Test] public async Task TestImportWhenFileOpen() { - using (HeadlessGameHost host = new CleanRunHeadlessGameHost(nameof(TestImportWhenFileOpen))) + using (HeadlessGameHost host = new CleanRunHeadlessGameHost()) { try { @@ -548,7 +548,7 @@ namespace osu.Game.Tests.Beatmaps.IO [Test] public async Task TestImportWithDuplicateHashes() { - using (HeadlessGameHost host = new CleanRunHeadlessGameHost(nameof(TestImportWithDuplicateHashes))) + using (HeadlessGameHost host = new CleanRunHeadlessGameHost()) { try { @@ -590,7 +590,7 @@ namespace osu.Game.Tests.Beatmaps.IO [Test] public async Task TestImportNestedStructure() { - using (HeadlessGameHost host = new CleanRunHeadlessGameHost(nameof(TestImportNestedStructure))) + using (HeadlessGameHost host = new CleanRunHeadlessGameHost()) { try { @@ -635,7 +635,7 @@ namespace osu.Game.Tests.Beatmaps.IO [Test] public async Task TestImportWithIgnoredDirectoryInArchive() { - using (HeadlessGameHost host = new CleanRunHeadlessGameHost(nameof(TestImportWithIgnoredDirectoryInArchive))) + using (HeadlessGameHost host = new CleanRunHeadlessGameHost()) { try { @@ -689,7 +689,7 @@ namespace osu.Game.Tests.Beatmaps.IO [Test] public async Task TestUpdateBeatmapInfo() { - using (HeadlessGameHost host = new CleanRunHeadlessGameHost(nameof(TestUpdateBeatmapInfo))) + using (HeadlessGameHost host = new CleanRunHeadlessGameHost()) { try { @@ -719,7 +719,7 @@ namespace osu.Game.Tests.Beatmaps.IO [Test] public async Task TestUpdateBeatmapFile() { - using (HeadlessGameHost host = new CleanRunHeadlessGameHost(nameof(TestUpdateBeatmapFile))) + using (HeadlessGameHost host = new CleanRunHeadlessGameHost()) { try { @@ -761,7 +761,7 @@ namespace osu.Game.Tests.Beatmaps.IO [Test] public void TestCreateNewEmptyBeatmap() { - using (HeadlessGameHost host = new CleanRunHeadlessGameHost(nameof(TestCreateNewEmptyBeatmap))) + using (HeadlessGameHost host = new CleanRunHeadlessGameHost()) { try { @@ -788,7 +788,7 @@ namespace osu.Game.Tests.Beatmaps.IO [Test] public void TestCreateNewBeatmapWithObject() { - using (HeadlessGameHost host = new CleanRunHeadlessGameHost(nameof(TestCreateNewBeatmapWithObject))) + using (HeadlessGameHost host = new CleanRunHeadlessGameHost()) { try { diff --git a/osu.Game.Tests/Scores/IO/ImportScoreTest.cs b/osu.Game.Tests/Scores/IO/ImportScoreTest.cs index 57f0d7e957..a4d20714fa 100644 --- a/osu.Game.Tests/Scores/IO/ImportScoreTest.cs +++ b/osu.Game.Tests/Scores/IO/ImportScoreTest.cs @@ -27,7 +27,7 @@ namespace osu.Game.Tests.Scores.IO [Test] public async Task TestBasicImport() { - using (HeadlessGameHost host = new CleanRunHeadlessGameHost("TestBasicImport")) + using (HeadlessGameHost host = new CleanRunHeadlessGameHost()) { try { @@ -66,7 +66,7 @@ namespace osu.Game.Tests.Scores.IO [Test] public async Task TestImportMods() { - using (HeadlessGameHost host = new CleanRunHeadlessGameHost("TestImportMods")) + using (HeadlessGameHost host = new CleanRunHeadlessGameHost()) { try { @@ -92,7 +92,7 @@ namespace osu.Game.Tests.Scores.IO [Test] public async Task TestImportStatistics() { - using (HeadlessGameHost host = new CleanRunHeadlessGameHost("TestImportStatistics")) + using (HeadlessGameHost host = new CleanRunHeadlessGameHost()) { try { @@ -122,7 +122,7 @@ namespace osu.Game.Tests.Scores.IO [Test] public async Task TestImportWithDeletedBeatmapSet() { - using (HeadlessGameHost host = new CleanRunHeadlessGameHost("TestImportWithDeletedBeatmapSet")) + using (HeadlessGameHost host = new CleanRunHeadlessGameHost()) { try { @@ -159,7 +159,7 @@ namespace osu.Game.Tests.Scores.IO [Test] public async Task TestOnlineScoreIsAvailableLocally() { - using (HeadlessGameHost host = new CleanRunHeadlessGameHost("TestOnlineScoreIsAvailableLocally")) + using (HeadlessGameHost host = new CleanRunHeadlessGameHost()) { try { diff --git a/osu.Game/Tests/CleanRunHeadlessGameHost.cs b/osu.Game/Tests/CleanRunHeadlessGameHost.cs index bfbf7bb9da..baa7b27d28 100644 --- a/osu.Game/Tests/CleanRunHeadlessGameHost.cs +++ b/osu.Game/Tests/CleanRunHeadlessGameHost.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.Runtime.CompilerServices; using osu.Framework.Platform; namespace osu.Game.Tests @@ -10,8 +11,15 @@ namespace osu.Game.Tests /// public class CleanRunHeadlessGameHost : HeadlessGameHost { - public CleanRunHeadlessGameHost(string gameName = @"", bool bindIPC = false, bool realtime = true) - : base(gameName, bindIPC, realtime) + /// + /// Create a new instance. + /// + /// An optional suffix which will isolate this host from others called from the same method source. + /// Whether to bind IPC channels. + /// Whether the host should be forced to run in realtime, rather than accelerated test time. + /// The name of the calling method, used for test file isolation and clean-up. + public CleanRunHeadlessGameHost(string gameSuffix = @"", bool bindIPC = false, bool realtime = true, [CallerMemberName] string callingMethodName = @"") + : base(callingMethodName + gameSuffix, bindIPC, realtime) { } From c3123bf11712937fed58039477442717e7e8076b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 8 Sep 2020 17:22:59 +0900 Subject: [PATCH 307/320] Rename drag blueprint selection method for discoverability --- .../Screens/Edit/Compose/Components/BlueprintContainer.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs index fcff672045..865e225645 100644 --- a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs @@ -61,7 +61,7 @@ namespace osu.Game.Screens.Edit.Compose.Components AddRangeInternal(new[] { - DragBox = CreateDragBox(select), + DragBox = CreateDragBox(selectBlueprintsFromDragRectangle), selectionHandler, SelectionBlueprints = CreateSelectionBlueprintContainer(), selectionHandler.CreateProxy(), @@ -326,7 +326,7 @@ namespace osu.Game.Screens.Edit.Compose.Components /// Select all masks in a given rectangle selection area. /// /// The rectangle to perform a selection on in screen-space coordinates. - private void select(RectangleF rect) + private void selectBlueprintsFromDragRectangle(RectangleF rect) { foreach (var blueprint in SelectionBlueprints) { From b1110e5e3a1778a4cf5075728194e524c468f0c1 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 8 Sep 2020 18:10:14 +0900 Subject: [PATCH 308/320] Rename class to match derived class --- osu.Game/OsuGame.cs | 2 +- .../Music/{MusicActionHandler.cs => MusicKeyBindingHandler.cs} | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename osu.Game/Overlays/Music/{MusicActionHandler.cs => MusicKeyBindingHandler.cs} (96%) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index a73469d836..b4e671d0b0 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -648,7 +648,7 @@ namespace osu.Game chatOverlay.State.ValueChanged += state => channelManager.HighPollRate.Value = state.NewValue == Visibility.Visible; Add(externalLinkOpener = new ExternalLinkOpener()); - Add(new MusicActionHandler()); + Add(new MusicKeyBindingHandler()); // side overlays which cancel each other. var singleDisplaySideOverlays = new OverlayContainer[] { Settings, notifications }; diff --git a/osu.Game/Overlays/Music/MusicActionHandler.cs b/osu.Game/Overlays/Music/MusicKeyBindingHandler.cs similarity index 96% rename from osu.Game/Overlays/Music/MusicActionHandler.cs rename to osu.Game/Overlays/Music/MusicKeyBindingHandler.cs index cd8548c1c0..78e6ba1381 100644 --- a/osu.Game/Overlays/Music/MusicActionHandler.cs +++ b/osu.Game/Overlays/Music/MusicKeyBindingHandler.cs @@ -14,7 +14,7 @@ namespace osu.Game.Overlays.Music /// /// Handles relating to music playback, and displays a via the cached accordingly. /// - public class MusicActionHandler : Component, IKeyBindingHandler + public class MusicKeyBindingHandler : Component, IKeyBindingHandler { [Resolved] private IBindable beatmap { get; set; } From a46be45a71b9b70ca1b70b68d54d33a625070a4c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 8 Sep 2020 18:12:03 +0900 Subject: [PATCH 309/320] Fix OSD occasionally display incorrect play/pause state --- osu.Game/Overlays/Music/MusicKeyBindingHandler.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Music/MusicKeyBindingHandler.cs b/osu.Game/Overlays/Music/MusicKeyBindingHandler.cs index 78e6ba1381..277fb1a35d 100644 --- a/osu.Game/Overlays/Music/MusicKeyBindingHandler.cs +++ b/osu.Game/Overlays/Music/MusicKeyBindingHandler.cs @@ -33,9 +33,11 @@ namespace osu.Game.Overlays.Music switch (action) { case GlobalAction.MusicPlay: - if (musicController.TogglePause()) - onScreenDisplay?.Display(new MusicActionToast(musicController.IsPlaying ? "Play track" : "Pause track")); + // use previous state as TogglePause may not update the track's state immediately (state update is run on the audio thread see https://github.com/ppy/osu/issues/9880#issuecomment-674668842) + bool wasPlaying = musicController.IsPlaying; + if (musicController.TogglePause()) + onScreenDisplay?.Display(new MusicActionToast(wasPlaying ? "Pause track" : "Play track")); return true; case GlobalAction.MusicNext: From 14bf2ab936b38c16cccbac254293d28791002b33 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 8 Sep 2020 18:21:26 +0900 Subject: [PATCH 310/320] Fix grammar in xmldoc --- osu.Game/Overlays/Music/MusicKeyBindingHandler.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Music/MusicKeyBindingHandler.cs b/osu.Game/Overlays/Music/MusicKeyBindingHandler.cs index 78e6ba1381..02196348ae 100644 --- a/osu.Game/Overlays/Music/MusicKeyBindingHandler.cs +++ b/osu.Game/Overlays/Music/MusicKeyBindingHandler.cs @@ -12,7 +12,7 @@ using osu.Game.Overlays.OSD; namespace osu.Game.Overlays.Music { /// - /// Handles relating to music playback, and displays a via the cached accordingly. + /// Handles s related to music playback, and displays s via the global accordingly. /// public class MusicKeyBindingHandler : Component, IKeyBindingHandler { From ad5d6117c76856237d2215a89f8c2f7c2ab7524d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 8 Sep 2020 18:26:13 +0900 Subject: [PATCH 311/320] Remove unnecessary RunTask calls --- .../Overlays/Music/MusicKeyBindingHandler.cs | 7 ++----- osu.Game/Overlays/MusicController.cs | 17 ++++------------- 2 files changed, 6 insertions(+), 18 deletions(-) diff --git a/osu.Game/Overlays/Music/MusicKeyBindingHandler.cs b/osu.Game/Overlays/Music/MusicKeyBindingHandler.cs index 02196348ae..f5968614cd 100644 --- a/osu.Game/Overlays/Music/MusicKeyBindingHandler.cs +++ b/osu.Game/Overlays/Music/MusicKeyBindingHandler.cs @@ -39,10 +39,7 @@ namespace osu.Game.Overlays.Music return true; case GlobalAction.MusicNext: - musicController.NextTrack(() => - { - onScreenDisplay?.Display(new MusicActionToast("Next track")); - }).RunTask(); + musicController.NextTrack(() => onScreenDisplay?.Display(new MusicActionToast("Next track"))); return true; @@ -59,7 +56,7 @@ namespace osu.Game.Overlays.Music onScreenDisplay?.Display(new MusicActionToast("Previous track")); break; } - }).RunTask(); + }); return true; } diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index a405be1b74..b568e4d02b 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -201,13 +201,8 @@ namespace osu.Game.Overlays /// /// Play the previous track or restart the current track if it's current time below . /// - /// - /// Invoked when the operation has been performed successfully. - /// The result isn't returned directly to the caller because - /// the operation is scheduled and isn't performed immediately. - /// - /// A of the operation. - public ScheduledDelegate PreviousTrack(Action onSuccess = null) => Schedule(() => + /// Invoked when the operation has been performed successfully. + public void PreviousTrack(Action onSuccess = null) => Schedule(() => { PreviousTrackResult res = prev(); if (res != PreviousTrackResult.None) @@ -248,13 +243,9 @@ namespace osu.Game.Overlays /// /// Play the next random or playlist track. /// - /// - /// Invoked when the operation has been performed successfully. - /// The result isn't returned directly to the caller because - /// the operation is scheduled and isn't performed immediately. - /// + /// Invoked when the operation has been performed successfully. /// A of the operation. - public ScheduledDelegate NextTrack(Action onSuccess = null) => Schedule(() => + public void NextTrack(Action onSuccess = null) => Schedule(() => { bool res = next(); if (res) From e1053c4b6f9376884786084e0d48a26962f6edcf Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 8 Sep 2020 18:36:11 +0900 Subject: [PATCH 312/320] Revert exposure changes to GlobalActionContainer --- .../Visual/Menus/TestSceneMusicActionHandling.cs | 13 ++++++++----- .../Visual/Navigation/OsuGameTestScene.cs | 3 --- osu.Game/OsuGameBase.cs | 11 ++++++----- 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/osu.Game.Tests/Visual/Menus/TestSceneMusicActionHandling.cs b/osu.Game.Tests/Visual/Menus/TestSceneMusicActionHandling.cs index 9b8ba47992..4cad2b19d5 100644 --- a/osu.Game.Tests/Visual/Menus/TestSceneMusicActionHandling.cs +++ b/osu.Game.Tests/Visual/Menus/TestSceneMusicActionHandling.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Linq; using NUnit.Framework; +using osu.Framework.Testing; using osu.Game.Beatmaps; using osu.Game.Input.Bindings; using osu.Game.Overlays; @@ -14,13 +15,15 @@ namespace osu.Game.Tests.Visual.Menus { public class TestSceneMusicActionHandling : OsuGameTestScene { + private GlobalActionContainer globalActionContainer => Game.ChildrenOfType().First(); + [Test] public void TestMusicPlayAction() { AddStep("ensure playing something", () => Game.MusicController.EnsurePlayingSomething()); - AddStep("toggle playback", () => Game.GlobalBinding.TriggerPressed(GlobalAction.MusicPlay)); + AddStep("toggle playback", () => globalActionContainer.TriggerPressed(GlobalAction.MusicPlay)); AddAssert("music paused", () => !Game.MusicController.IsPlaying && Game.MusicController.IsUserPaused); - AddStep("toggle playback", () => Game.GlobalBinding.TriggerPressed(GlobalAction.MusicPlay)); + AddStep("toggle playback", () => globalActionContainer.TriggerPressed(GlobalAction.MusicPlay)); AddAssert("music resumed", () => Game.MusicController.IsPlaying && !Game.MusicController.IsUserPaused); } @@ -62,16 +65,16 @@ namespace osu.Game.Tests.Visual.Menus AddStep("seek track to 6 second", () => Game.MusicController.SeekTo(6000)); AddUntilStep("wait for current time to update", () => Game.MusicController.CurrentTrack.CurrentTime > 5000); - AddStep("press previous", () => Game.GlobalBinding.TriggerPressed(GlobalAction.MusicPrev)); + AddStep("press previous", () => globalActionContainer.TriggerPressed(GlobalAction.MusicPrev)); AddAssert("no track change", () => trackChangeQueue.Count == 0); AddUntilStep("track restarted", () => Game.MusicController.CurrentTrack.CurrentTime < 5000); - AddStep("press previous", () => Game.GlobalBinding.TriggerPressed(GlobalAction.MusicPrev)); + AddStep("press previous", () => globalActionContainer.TriggerPressed(GlobalAction.MusicPrev)); AddAssert("track changed to previous", () => trackChangeQueue.Count == 1 && trackChangeQueue.Dequeue().changeDirection == TrackChangeDirection.Prev); - AddStep("press next", () => Game.GlobalBinding.TriggerPressed(GlobalAction.MusicNext)); + AddStep("press next", () => globalActionContainer.TriggerPressed(GlobalAction.MusicNext)); AddAssert("track changed to next", () => trackChangeQueue.Count == 1 && trackChangeQueue.Dequeue().changeDirection == TrackChangeDirection.Next); diff --git a/osu.Game.Tests/Visual/Navigation/OsuGameTestScene.cs b/osu.Game.Tests/Visual/Navigation/OsuGameTestScene.cs index e29d23ba75..c4acf4f7da 100644 --- a/osu.Game.Tests/Visual/Navigation/OsuGameTestScene.cs +++ b/osu.Game.Tests/Visual/Navigation/OsuGameTestScene.cs @@ -14,7 +14,6 @@ using osu.Framework.Testing; using osu.Game.Beatmaps; using osu.Game.Configuration; using osu.Game.Graphics.UserInterface; -using osu.Game.Input.Bindings; using osu.Game.Online.API; using osu.Game.Overlays; using osu.Game.Rulesets; @@ -110,8 +109,6 @@ namespace osu.Game.Tests.Visual.Navigation public new OsuConfigManager LocalConfig => base.LocalConfig; - public new GlobalActionContainer GlobalBinding => base.GlobalBinding; - public new Bindable Beatmap => base.Beatmap; public new Bindable Ruleset => base.Ruleset; diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index 8e01bda6ec..4bc8f4c527 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -64,8 +64,6 @@ namespace osu.Game protected FileStore FileStore; - protected GlobalActionContainer GlobalBinding; - protected KeyBindingStore KeyBindingStore; protected SettingsStore SettingsStore; @@ -253,7 +251,10 @@ namespace osu.Game AddInternal(RulesetConfigCache); MenuCursorContainer = new MenuCursorContainer { RelativeSizeAxes = Axes.Both }; - MenuCursorContainer.Child = GlobalBinding = new GlobalActionContainer(this) + + GlobalActionContainer globalBindings; + + MenuCursorContainer.Child = globalBindings = new GlobalActionContainer(this) { RelativeSizeAxes = Axes.Both, Child = content = new OsuTooltipContainer(MenuCursorContainer.Cursor) { RelativeSizeAxes = Axes.Both } @@ -261,8 +262,8 @@ namespace osu.Game base.Content.Add(CreateScalingContainer().WithChild(MenuCursorContainer)); - KeyBindingStore.Register(GlobalBinding); - dependencies.Cache(GlobalBinding); + KeyBindingStore.Register(globalBindings); + dependencies.Cache(globalBindings); PreviewTrackManager previewTrackManager; dependencies.Cache(previewTrackManager = new PreviewTrackManager()); From 2b4e2d8ed63c4500aba1fb3236fb481469caab6e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 8 Sep 2020 19:04:46 +0900 Subject: [PATCH 313/320] Standardise corner radius of dropdowns --- osu.Game/Graphics/UserInterface/OsuDropdown.cs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/OsuDropdown.cs b/osu.Game/Graphics/UserInterface/OsuDropdown.cs index fc3a7229fa..cc76c12975 100644 --- a/osu.Game/Graphics/UserInterface/OsuDropdown.cs +++ b/osu.Game/Graphics/UserInterface/OsuDropdown.cs @@ -17,6 +17,8 @@ namespace osu.Game.Graphics.UserInterface { public class OsuDropdown : Dropdown, IHasAccentColour { + private const float corner_radius = 4; + private Color4 accentColour; public Color4 AccentColour @@ -57,9 +59,11 @@ namespace osu.Game.Graphics.UserInterface // todo: this uses the same styling as OsuMenu. hopefully we can just use OsuMenu in the future with some refactoring public OsuDropdownMenu() { - CornerRadius = 4; + CornerRadius = corner_radius; BackgroundColour = Color4.Black.Opacity(0.5f); + MaskingContainer.CornerRadius = corner_radius; + // todo: this uses the same styling as OsuMenu. hopefully we can just use OsuMenu in the future with some refactoring ItemsContainer.Padding = new MarginPadding(5); } @@ -138,7 +142,7 @@ namespace osu.Game.Graphics.UserInterface Foreground.Padding = new MarginPadding(2); Masking = true; - CornerRadius = 6; + CornerRadius = corner_radius; } [BackgroundDependencyLoader] @@ -237,7 +241,7 @@ namespace osu.Game.Graphics.UserInterface AutoSizeAxes = Axes.None; Margin = new MarginPadding { Bottom = 4 }; - CornerRadius = 4; + CornerRadius = corner_radius; Height = 40; Foreground.Children = new Drawable[] From a501df954b3337ef6782a07aeb565a0172c7c7b9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 8 Sep 2020 19:50:29 +0900 Subject: [PATCH 314/320] Avoid multiple editor screens potentially loading on top of each other --- osu.Game/Screens/Edit/Editor.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index 3ba3eb108a..ac1f61c4fd 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -398,7 +398,11 @@ namespace osu.Game.Screens.Edit break; } - LoadComponentAsync(currentScreen, screenContainer.Add); + LoadComponentAsync(currentScreen, newScreen => + { + if (newScreen == currentScreen) + screenContainer.Add(newScreen); + }); } private void seek(UIEvent e, int direction) From 379fdadbe54e34ea99e57a86106b94bdd9b8bcd9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 7 Sep 2020 18:47:14 +0900 Subject: [PATCH 315/320] Add test scene for setup screen --- .../Visual/Editing/TestSceneSetupScreen.cs | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 osu.Game.Tests/Visual/Editing/TestSceneSetupScreen.cs diff --git a/osu.Game.Tests/Visual/Editing/TestSceneSetupScreen.cs b/osu.Game.Tests/Visual/Editing/TestSceneSetupScreen.cs new file mode 100644 index 0000000000..62e12158ab --- /dev/null +++ b/osu.Game.Tests/Visual/Editing/TestSceneSetupScreen.cs @@ -0,0 +1,32 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using NUnit.Framework; +using osu.Framework.Allocation; +using osu.Game.Rulesets.Edit; +using osu.Game.Rulesets.Osu.Beatmaps; +using osu.Game.Screens.Edit; +using osu.Game.Screens.Edit.Setup; + +namespace osu.Game.Tests.Visual.Editing +{ + [TestFixture] + public class TestSceneSetupScreen : EditorClockTestScene + { + [Cached(typeof(EditorBeatmap))] + [Cached(typeof(IBeatSnapProvider))] + private readonly EditorBeatmap editorBeatmap; + + public TestSceneSetupScreen() + { + editorBeatmap = new EditorBeatmap(new OsuBeatmap()); + } + + [BackgroundDependencyLoader] + private void load() + { + Beatmap.Value = CreateWorkingBeatmap(editorBeatmap.PlayableBeatmap); + Child = new SetupScreen(); + } + } +} From f43f8cf6b95bebf5c18683acdb0e96a6ff731fb3 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 7 Sep 2020 19:21:35 +0900 Subject: [PATCH 316/320] Add basic setup for song select screen --- osu.Game/Screens/Edit/Setup/SetupScreen.cs | 74 +++++++++++++++++++++- 1 file changed, 72 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Edit/Setup/SetupScreen.cs b/osu.Game/Screens/Edit/Setup/SetupScreen.cs index 758dbc6e16..84e96a14e2 100644 --- a/osu.Game/Screens/Edit/Setup/SetupScreen.cs +++ b/osu.Game/Screens/Edit/Setup/SetupScreen.cs @@ -1,13 +1,83 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Game.Beatmaps.Drawables; +using osu.Game.Graphics; +using osu.Game.Graphics.Containers; +using osu.Game.Graphics.Sprites; +using osu.Game.Graphics.UserInterfaceV2; +using osuTK; + namespace osu.Game.Screens.Edit.Setup { public class SetupScreen : EditorScreen { - public SetupScreen() + [BackgroundDependencyLoader] + private void load(OsuColour colours) { - Child = new ScreenWhiteBox.UnderConstructionMessage("Setup mode"); + Children = new Drawable[] + { + new Box + { + Colour = colours.Gray0, + RelativeSizeAxes = Axes.Both, + }, + new OsuScrollContainer + { + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding(50), + Child = new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Spacing = new Vector2(20), + Direction = FillDirection.Vertical, + Children = new Drawable[] + { + new Container + { + RelativeSizeAxes = Axes.X, + Height = 250, + Masking = true, + CornerRadius = 50, + Child = new BeatmapBackgroundSprite(Beatmap.Value) + { + RelativeSizeAxes = Axes.Both, + FillMode = FillMode.Fill, + }, + }, + new OsuSpriteText + { + Text = "Beatmap metadata" + }, + new LabelledTextBox + { + Label = "Artist", + Current = { Value = Beatmap.Value.Metadata.Artist } + }, + new LabelledTextBox + { + Label = "Title", + Current = { Value = Beatmap.Value.Metadata.Title } + }, + new LabelledTextBox + { + Label = "Creator", + Current = { Value = Beatmap.Value.Metadata.AuthorString } + }, + new LabelledTextBox + { + Label = "Difficulty Name", + Current = { Value = Beatmap.Value.BeatmapInfo.Version } + }, + } + }, + }, + }; } } } From fe31edfa26a126c1a3d55a1cad2c51e60ce3aaa7 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 8 Sep 2020 19:28:20 +0900 Subject: [PATCH 317/320] Add rudimentary saving logic --- osu.Game/Screens/Edit/Setup/SetupScreen.cs | 34 ++++++++++++++++++---- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/osu.Game/Screens/Edit/Setup/SetupScreen.cs b/osu.Game/Screens/Edit/Setup/SetupScreen.cs index 84e96a14e2..7ea810c514 100644 --- a/osu.Game/Screens/Edit/Setup/SetupScreen.cs +++ b/osu.Game/Screens/Edit/Setup/SetupScreen.cs @@ -1,10 +1,12 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System.Linq; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; +using osu.Framework.Graphics.UserInterface; using osu.Game.Beatmaps.Drawables; using osu.Game.Graphics; using osu.Game.Graphics.Containers; @@ -16,6 +18,12 @@ namespace osu.Game.Screens.Edit.Setup { public class SetupScreen : EditorScreen { + private FillFlowContainer flow; + private LabelledTextBox artistTextBox; + private LabelledTextBox titleTextBox; + private LabelledTextBox creatorTextBox; + private LabelledTextBox difficultyTextBox; + [BackgroundDependencyLoader] private void load(OsuColour colours) { @@ -24,13 +32,14 @@ namespace osu.Game.Screens.Edit.Setup new Box { Colour = colours.Gray0, + Alpha = 0.4f, RelativeSizeAxes = Axes.Both, }, new OsuScrollContainer { RelativeSizeAxes = Axes.Both, Padding = new MarginPadding(50), - Child = new FillFlowContainer + Child = flow = new FillFlowContainer { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, @@ -54,22 +63,22 @@ namespace osu.Game.Screens.Edit.Setup { Text = "Beatmap metadata" }, - new LabelledTextBox + artistTextBox = new LabelledTextBox { Label = "Artist", Current = { Value = Beatmap.Value.Metadata.Artist } }, - new LabelledTextBox + titleTextBox = new LabelledTextBox { Label = "Title", Current = { Value = Beatmap.Value.Metadata.Title } }, - new LabelledTextBox + creatorTextBox = new LabelledTextBox { Label = "Creator", Current = { Value = Beatmap.Value.Metadata.AuthorString } }, - new LabelledTextBox + difficultyTextBox = new LabelledTextBox { Label = "Difficulty Name", Current = { Value = Beatmap.Value.BeatmapInfo.Version } @@ -78,6 +87,21 @@ namespace osu.Game.Screens.Edit.Setup }, }, }; + + foreach (var item in flow.OfType()) + item.OnCommit += onCommit; + } + + private void onCommit(TextBox sender, bool newText) + { + if (!newText) return; + + // for now, update these on commit rather than making BeatmapMetadata bindables. + // after switching database engines we can reconsider if switching to bindables is a good direction. + Beatmap.Value.Metadata.Artist = artistTextBox.Current.Value; + Beatmap.Value.Metadata.Title = titleTextBox.Current.Value; + Beatmap.Value.Metadata.AuthorString = creatorTextBox.Current.Value; + Beatmap.Value.BeatmapInfo.Version = difficultyTextBox.Current.Value; } } } From c8281b17bdee45478edfbb71ecfec3541d1e1e7b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 8 Sep 2020 19:49:26 +0900 Subject: [PATCH 318/320] Remove editor screen fade (looks bad) --- osu.Game/Screens/Edit/EditorScreen.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/EditorScreen.cs b/osu.Game/Screens/Edit/EditorScreen.cs index d42447ac4b..8b5f0aaa71 100644 --- a/osu.Game/Screens/Edit/EditorScreen.cs +++ b/osu.Game/Screens/Edit/EditorScreen.cs @@ -43,7 +43,7 @@ namespace osu.Game.Screens.Edit public void Exit() { - this.FadeOut(250).Expire(); + Expire(); } } } From b55b6e374699e06eed4c0178ad88eec195b4d972 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 8 Sep 2020 19:50:44 +0900 Subject: [PATCH 319/320] Bring design somewhat in line with collections dialog --- osu.Game/Screens/Edit/Setup/SetupScreen.cs | 112 ++++++++++++--------- 1 file changed, 62 insertions(+), 50 deletions(-) diff --git a/osu.Game/Screens/Edit/Setup/SetupScreen.cs b/osu.Game/Screens/Edit/Setup/SetupScreen.cs index 7ea810c514..da8eb3a3b3 100644 --- a/osu.Game/Screens/Edit/Setup/SetupScreen.cs +++ b/osu.Game/Screens/Edit/Setup/SetupScreen.cs @@ -27,65 +27,77 @@ namespace osu.Game.Screens.Edit.Setup [BackgroundDependencyLoader] private void load(OsuColour colours) { - Children = new Drawable[] + Child = new Container { - new Box - { - Colour = colours.Gray0, - Alpha = 0.4f, - RelativeSizeAxes = Axes.Both, - }, - new OsuScrollContainer + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding(50), + Child = new Container { RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding(50), - Child = flow = new FillFlowContainer + Masking = true, + CornerRadius = 10, + Children = new Drawable[] { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Spacing = new Vector2(20), - Direction = FillDirection.Vertical, - Children = new Drawable[] + new Box { - new Container + Colour = colours.GreySeafoamDark, + RelativeSizeAxes = Axes.Both, + }, + new OsuScrollContainer + { + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding(10), + Child = flow = new FillFlowContainer { RelativeSizeAxes = Axes.X, - Height = 250, - Masking = true, - CornerRadius = 50, - Child = new BeatmapBackgroundSprite(Beatmap.Value) + AutoSizeAxes = Axes.Y, + Spacing = new Vector2(20), + Direction = FillDirection.Vertical, + Children = new Drawable[] { - RelativeSizeAxes = Axes.Both, - FillMode = FillMode.Fill, - }, + new Container + { + RelativeSizeAxes = Axes.X, + Height = 250, + Masking = true, + CornerRadius = 10, + Child = new BeatmapBackgroundSprite(Beatmap.Value) + { + RelativeSizeAxes = Axes.Both, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + FillMode = FillMode.Fill, + }, + }, + new OsuSpriteText + { + Text = "Beatmap metadata" + }, + artistTextBox = new LabelledTextBox + { + Label = "Artist", + Current = { Value = Beatmap.Value.Metadata.Artist } + }, + titleTextBox = new LabelledTextBox + { + Label = "Title", + Current = { Value = Beatmap.Value.Metadata.Title } + }, + creatorTextBox = new LabelledTextBox + { + Label = "Creator", + Current = { Value = Beatmap.Value.Metadata.AuthorString } + }, + difficultyTextBox = new LabelledTextBox + { + Label = "Difficulty Name", + Current = { Value = Beatmap.Value.BeatmapInfo.Version } + }, + } }, - new OsuSpriteText - { - Text = "Beatmap metadata" - }, - artistTextBox = new LabelledTextBox - { - Label = "Artist", - Current = { Value = Beatmap.Value.Metadata.Artist } - }, - titleTextBox = new LabelledTextBox - { - Label = "Title", - Current = { Value = Beatmap.Value.Metadata.Title } - }, - creatorTextBox = new LabelledTextBox - { - Label = "Creator", - Current = { Value = Beatmap.Value.Metadata.AuthorString } - }, - difficultyTextBox = new LabelledTextBox - { - Label = "Difficulty Name", - Current = { Value = Beatmap.Value.BeatmapInfo.Version } - }, - } - }, - }, + }, + } + } }; foreach (var item in flow.OfType()) From c38e7d796a577c477fbb844376dc6902667aa015 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 8 Sep 2020 19:51:31 +0900 Subject: [PATCH 320/320] Fix tab key not working --- osu.Game/Graphics/UserInterfaceV2/LabelledTextBox.cs | 6 ++++++ osu.Game/Screens/Edit/Setup/SetupScreen.cs | 12 ++++++++---- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/osu.Game/Graphics/UserInterfaceV2/LabelledTextBox.cs b/osu.Game/Graphics/UserInterfaceV2/LabelledTextBox.cs index 2cbe095d0b..290aba3468 100644 --- a/osu.Game/Graphics/UserInterfaceV2/LabelledTextBox.cs +++ b/osu.Game/Graphics/UserInterfaceV2/LabelledTextBox.cs @@ -3,6 +3,7 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.UserInterface; using osu.Game.Graphics.UserInterface; @@ -32,6 +33,11 @@ namespace osu.Game.Graphics.UserInterfaceV2 set => Component.Text = value; } + public Container TabbableContentContainer + { + set => Component.TabbableContentContainer = value; + } + [BackgroundDependencyLoader] private void load(OsuColour colours) { diff --git a/osu.Game/Screens/Edit/Setup/SetupScreen.cs b/osu.Game/Screens/Edit/Setup/SetupScreen.cs index da8eb3a3b3..a2c8f19016 100644 --- a/osu.Game/Screens/Edit/Setup/SetupScreen.cs +++ b/osu.Game/Screens/Edit/Setup/SetupScreen.cs @@ -76,22 +76,26 @@ namespace osu.Game.Screens.Edit.Setup artistTextBox = new LabelledTextBox { Label = "Artist", - Current = { Value = Beatmap.Value.Metadata.Artist } + Current = { Value = Beatmap.Value.Metadata.Artist }, + TabbableContentContainer = this }, titleTextBox = new LabelledTextBox { Label = "Title", - Current = { Value = Beatmap.Value.Metadata.Title } + Current = { Value = Beatmap.Value.Metadata.Title }, + TabbableContentContainer = this }, creatorTextBox = new LabelledTextBox { Label = "Creator", - Current = { Value = Beatmap.Value.Metadata.AuthorString } + Current = { Value = Beatmap.Value.Metadata.AuthorString }, + TabbableContentContainer = this }, difficultyTextBox = new LabelledTextBox { Label = "Difficulty Name", - Current = { Value = Beatmap.Value.BeatmapInfo.Version } + Current = { Value = Beatmap.Value.BeatmapInfo.Version }, + TabbableContentContainer = this }, } },