From 792d3b82159c9adfde092def00ac583ae9c50dfd Mon Sep 17 00:00:00 2001 From: Aergwyn Date: Sat, 9 Jun 2018 09:14:52 +0200 Subject: [PATCH 01/30] allow "go back" keybind in play --- osu.Game/Screens/Play/FailOverlay.cs | 16 +++++++------ osu.Game/Screens/Play/PauseContainer.cs | 30 +++++++++++++------------ osu.Game/Screens/Play/Player.cs | 2 -- 3 files changed, 25 insertions(+), 23 deletions(-) diff --git a/osu.Game/Screens/Play/FailOverlay.cs b/osu.Game/Screens/Play/FailOverlay.cs index 7b555776f7..8c3ab8f235 100644 --- a/osu.Game/Screens/Play/FailOverlay.cs +++ b/osu.Game/Screens/Play/FailOverlay.cs @@ -1,16 +1,16 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using osu.Framework.Input; -using OpenTK.Input; using osu.Game.Graphics; using OpenTK.Graphics; using osu.Framework.Allocation; using System.Linq; +using osu.Framework.Input.Bindings; +using osu.Game.Input.Bindings; namespace osu.Game.Screens.Play { - public class FailOverlay : GameplayMenuOverlay + public class FailOverlay : GameplayMenuOverlay, IKeyBindingHandler { public override string Header => "failed"; public override string Description => "you're dead, try again?"; @@ -21,16 +21,18 @@ namespace osu.Game.Screens.Play AddButton("Retry", colours.YellowDark, () => OnRetry?.Invoke()); AddButton("Quit", new Color4(170, 27, 39, 255), () => OnQuit?.Invoke()); } - - protected override bool OnKeyDown(InputState state, KeyDownEventArgs args) + + public bool OnPressed(GlobalAction action) { - if (!args.Repeat && args.Key == Key.Escape) + if (action == GlobalAction.Back) { InternalButtons.Children.Last().TriggerOnClick(); return true; } - return base.OnKeyDown(state, args); + return false; } + + public bool OnReleased(GlobalAction action) => action == GlobalAction.Back; } } diff --git a/osu.Game/Screens/Play/PauseContainer.cs b/osu.Game/Screens/Play/PauseContainer.cs index 6262f71ddc..d814bb46a2 100644 --- a/osu.Game/Screens/Play/PauseContainer.cs +++ b/osu.Game/Screens/Play/PauseContainer.cs @@ -6,11 +6,11 @@ using System.Linq; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Framework.Input; +using osu.Framework.Input.Bindings; using osu.Framework.Timing; using osu.Game.Graphics; +using osu.Game.Input.Bindings; using OpenTK.Graphics; -using OpenTK.Input; namespace osu.Game.Screens.Play { @@ -131,24 +131,13 @@ namespace osu.Game.Screens.Play base.Update(); } - public class PauseOverlay : GameplayMenuOverlay + public class PauseOverlay : GameplayMenuOverlay, IKeyBindingHandler { public Action OnResume; public override string Header => "paused"; public override string Description => "you're not going to do what i think you're going to do, are ya?"; - protected override bool OnKeyDown(InputState state, KeyDownEventArgs args) - { - if (!args.Repeat && args.Key == Key.Escape) - { - InternalButtons.Children.First().TriggerOnClick(); - return true; - } - - return base.OnKeyDown(state, args); - } - [BackgroundDependencyLoader] private void load(OsuColour colours) { @@ -156,6 +145,19 @@ namespace osu.Game.Screens.Play AddButton("Retry", colours.YellowDark, () => OnRetry?.Invoke()); AddButton("Quit", new Color4(170, 27, 39, 255), () => OnQuit?.Invoke()); } + + public bool OnPressed(GlobalAction action) + { + if (action == GlobalAction.Back) + { + InternalButtons.Children.First().TriggerOnClick(); + return true; + } + + return false; + } + + public bool OnReleased(GlobalAction action) => action == GlobalAction.Back; } } } diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index fe77f85a50..739dcdf066 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -49,8 +49,6 @@ namespace osu.Game.Screens.Play public bool AllowLeadIn { get; set; } = true; public bool AllowResults { get; set; } = true; - protected override bool AllowBackButton => false; - private Bindable mouseWheelDisabled; private Bindable userAudioOffset; From b9b04c1b6e2fe5154e39e0d6dcba0c810c776868 Mon Sep 17 00:00:00 2001 From: Aergwyn Date: Sat, 9 Jun 2018 09:28:02 +0200 Subject: [PATCH 02/30] move back logic into GameplayMenuOverlay --- osu.Game/Screens/Play/FailOverlay.cs | 22 +++++-------------- osu.Game/Screens/Play/GameplayMenuOverlay.cs | 23 +++++++++++++++++++- osu.Game/Screens/Play/PauseContainer.cs | 18 +-------------- 3 files changed, 28 insertions(+), 35 deletions(-) diff --git a/osu.Game/Screens/Play/FailOverlay.cs b/osu.Game/Screens/Play/FailOverlay.cs index 8c3ab8f235..1295df2da0 100644 --- a/osu.Game/Screens/Play/FailOverlay.cs +++ b/osu.Game/Screens/Play/FailOverlay.cs @@ -1,38 +1,26 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System; +using System.Linq; using osu.Game.Graphics; using OpenTK.Graphics; using osu.Framework.Allocation; -using System.Linq; -using osu.Framework.Input.Bindings; -using osu.Game.Input.Bindings; namespace osu.Game.Screens.Play { - public class FailOverlay : GameplayMenuOverlay, IKeyBindingHandler + public class FailOverlay : GameplayMenuOverlay { public override string Header => "failed"; public override string Description => "you're dead, try again?"; + protected override Action DefaultBackAction => () => InternalButtons.Children.Last().TriggerOnClick(); + [BackgroundDependencyLoader] private void load(OsuColour colours) { AddButton("Retry", colours.YellowDark, () => OnRetry?.Invoke()); AddButton("Quit", new Color4(170, 27, 39, 255), () => OnQuit?.Invoke()); } - - public bool OnPressed(GlobalAction action) - { - if (action == GlobalAction.Back) - { - InternalButtons.Children.Last().TriggerOnClick(); - return true; - } - - return false; - } - - public bool OnReleased(GlobalAction action) => action == GlobalAction.Back; } } diff --git a/osu.Game/Screens/Play/GameplayMenuOverlay.cs b/osu.Game/Screens/Play/GameplayMenuOverlay.cs index db099cd16c..a72fca2532 100644 --- a/osu.Game/Screens/Play/GameplayMenuOverlay.cs +++ b/osu.Game/Screens/Play/GameplayMenuOverlay.cs @@ -15,10 +15,13 @@ using osu.Game.Graphics.UserInterface; using osu.Framework.Graphics.Shapes; using OpenTK.Input; using System.Collections.Generic; +using System.Linq; +using osu.Framework.Input.Bindings; +using osu.Game.Input.Bindings; namespace osu.Game.Screens.Play { - public abstract class GameplayMenuOverlay : OverlayContainer + public abstract class GameplayMenuOverlay : OverlayContainer, IKeyBindingHandler { private const int transition_duration = 200; private const int button_height = 70; @@ -31,6 +34,11 @@ namespace osu.Game.Screens.Play public Action OnRetry; public Action OnQuit; + /// + /// Action that is invoked if is triggered. + /// + protected virtual Action DefaultBackAction => () => InternalButtons.Children.First().TriggerOnClick(); + public abstract string Header { get; } public abstract string Description { get; } @@ -219,6 +227,19 @@ namespace osu.Game.Screens.Play return base.OnKeyDown(state, args); } + public bool OnPressed(GlobalAction action) + { + if (action == GlobalAction.Back) + { + DefaultBackAction.Invoke(); + return true; + } + + return false; + } + + public bool OnReleased(GlobalAction action) => action == GlobalAction.Back; + private void buttonSelectionChanged(DialogButton button, bool isSelected) { if (!isSelected) diff --git a/osu.Game/Screens/Play/PauseContainer.cs b/osu.Game/Screens/Play/PauseContainer.cs index d814bb46a2..494e28a78e 100644 --- a/osu.Game/Screens/Play/PauseContainer.cs +++ b/osu.Game/Screens/Play/PauseContainer.cs @@ -2,14 +2,11 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; -using System.Linq; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Framework.Input.Bindings; using osu.Framework.Timing; using osu.Game.Graphics; -using osu.Game.Input.Bindings; using OpenTK.Graphics; namespace osu.Game.Screens.Play @@ -131,7 +128,7 @@ namespace osu.Game.Screens.Play base.Update(); } - public class PauseOverlay : GameplayMenuOverlay, IKeyBindingHandler + public class PauseOverlay : GameplayMenuOverlay { public Action OnResume; @@ -145,19 +142,6 @@ namespace osu.Game.Screens.Play AddButton("Retry", colours.YellowDark, () => OnRetry?.Invoke()); AddButton("Quit", new Color4(170, 27, 39, 255), () => OnQuit?.Invoke()); } - - public bool OnPressed(GlobalAction action) - { - if (action == GlobalAction.Back) - { - InternalButtons.Children.First().TriggerOnClick(); - return true; - } - - return false; - } - - public bool OnReleased(GlobalAction action) => action == GlobalAction.Back; } } } From b95042e370bcb946cf75ec2eb5e6c4e4ec438e0b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 20 Jun 2018 12:43:48 +0900 Subject: [PATCH 03/30] Fix background screens not supporting early-exit condition Closes #2681. --- osu.Game/Screens/BackgroundScreen.cs | 11 +++++++++-- osu.Game/Screens/OsuScreen.cs | 9 ++++----- osu.Game/osu.Game.csproj | 2 +- 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/osu.Game/Screens/BackgroundScreen.cs b/osu.Game/Screens/BackgroundScreen.cs index 5e9863f642..61277439c1 100644 --- a/osu.Game/Screens/BackgroundScreen.cs +++ b/osu.Game/Screens/BackgroundScreen.cs @@ -37,10 +37,17 @@ namespace osu.Game.Screens } // Make sure the in-progress loading is complete before pushing the screen. - while (screen.LoadState < LoadState.Ready) + while (screen.LoadState != LoadState.Ready) Thread.Sleep(1); - base.Push(screen); + try + { + base.Push(screen); + } + catch (InvalidOperationException) + { + // screen may have exited before the push was successful. + } } protected override void Update() diff --git a/osu.Game/Screens/OsuScreen.cs b/osu.Game/Screens/OsuScreen.cs index 61018f9e08..865b4c9070 100644 --- a/osu.Game/Screens/OsuScreen.cs +++ b/osu.Game/Screens/OsuScreen.cs @@ -195,11 +195,10 @@ namespace osu.Game.Screens if (Background != null && !Background.Equals(nextOsu?.Background)) { - if (nextOsu != null) - //We need to use MakeCurrent in case we are jumping up multiple game screens. - nextOsu.Background?.MakeCurrent(); - else - Background.Exit(); + Background.Exit(); + + //We need to use MakeCurrent in case we are jumping up multiple game screens. + nextOsu?.Background?.MakeCurrent(); } if (base.OnExiting(next)) diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index f0bc330994..21ba229543 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -18,7 +18,7 @@ - + From 2a72062c338dab4845b706bcca22dd142f1adfca Mon Sep 17 00:00:00 2001 From: Roman Kapustin Date: Tue, 26 Jun 2018 00:53:31 +0300 Subject: [PATCH 04/30] Perhaps the '??' operator works in a different way than it was expected. Its priority is lower than priority of other operators in its left part. --- osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapProcessor.cs | 4 ++-- osu.Game.Rulesets.Taiko/UI/TaikoRulesetContainer.cs | 2 +- osu.Game/Rulesets/Replays/FramedReplayInputHandler.cs | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapProcessor.cs b/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapProcessor.cs index c7c9f4a01a..8223855b14 100644 --- a/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapProcessor.cs +++ b/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapProcessor.cs @@ -44,7 +44,7 @@ namespace osu.Game.Rulesets.Osu.Beatmaps continue; double endTime = (stackBaseObject as IHasEndTime)?.EndTime ?? stackBaseObject.StartTime; - double stackThreshold = objectN.TimePreempt * beatmap.BeatmapInfo?.StackLeniency ?? 0.7f; + double stackThreshold = objectN.TimePreempt * (beatmap.BeatmapInfo?.StackLeniency ?? 0.7f); if (objectN.StartTime - endTime > stackThreshold) //We are no longer within stacking range of the next object. @@ -87,7 +87,7 @@ namespace osu.Game.Rulesets.Osu.Beatmaps OsuHitObject objectI = beatmap.HitObjects[i]; if (objectI.StackHeight != 0 || objectI is Spinner) continue; - double stackThreshold = objectI.TimePreempt * beatmap.BeatmapInfo?.StackLeniency ?? 0.7f; + double stackThreshold = objectI.TimePreempt * (beatmap.BeatmapInfo?.StackLeniency ?? 0.7f); /* If this object is a hitcircle, then we enter this "special" case. * It either ends with a stack of hitcircles only, or a stack of hitcircles that are underneath a slider. diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoRulesetContainer.cs b/osu.Game.Rulesets.Taiko/UI/TaikoRulesetContainer.cs index 999e33e51a..e04b4d45f6 100644 --- a/osu.Game.Rulesets.Taiko/UI/TaikoRulesetContainer.cs +++ b/osu.Game.Rulesets.Taiko/UI/TaikoRulesetContainer.cs @@ -37,7 +37,7 @@ namespace osu.Game.Rulesets.Taiko.UI private void loadBarLines() { TaikoHitObject lastObject = Beatmap.HitObjects[Beatmap.HitObjects.Count - 1]; - double lastHitTime = 1 + (lastObject as IHasEndTime)?.EndTime ?? lastObject.StartTime; + double lastHitTime = 1 + ((lastObject as IHasEndTime)?.EndTime ?? lastObject.StartTime); var timingPoints = Beatmap.ControlPointInfo.TimingPoints.ToList(); diff --git a/osu.Game/Rulesets/Replays/FramedReplayInputHandler.cs b/osu.Game/Rulesets/Replays/FramedReplayInputHandler.cs index f13d96b35e..6a1b3f8502 100644 --- a/osu.Game/Rulesets/Replays/FramedReplayInputHandler.cs +++ b/osu.Game/Rulesets/Replays/FramedReplayInputHandler.cs @@ -69,7 +69,7 @@ namespace osu.Game.Rulesets.Replays //a button is in a pressed state IsImportant(currentDirection > 0 ? CurrentFrame : NextFrame) && //the next frame is within an allowable time span - Math.Abs(CurrentTime - NextFrame?.Time ?? 0) <= sixty_frame_time * 1.2; + Math.Abs(CurrentTime - (NextFrame?.Time ?? 0)) <= sixty_frame_time * 1.2; protected virtual bool IsImportant(TFrame frame) => false; From 4bcc05a7fcc3917228eeaeddea72b0ca9ce701bc Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 26 Jun 2018 18:24:34 +0900 Subject: [PATCH 05/30] Remove null checks on ruleset Add a default ruleset to `OsuTestCase` to cover testing scenarios. --- osu.Game/Overlays/Mods/ModSelectOverlay.cs | 13 ++++--------- osu.Game/Overlays/Toolbar/ToolbarModeSelector.cs | 8 ++------ osu.Game/Screens/OsuScreen.cs | 7 ++----- osu.Game/Screens/Select/BeatmapInfoWedge.cs | 3 +-- osu.Game/Screens/Select/FilterControl.cs | 8 +++++--- osu.Game/Screens/Select/Leaderboards/Leaderboard.cs | 5 ++--- osu.Game/Tests/Visual/OsuTestCase.cs | 11 ++++++++++- 7 files changed, 26 insertions(+), 29 deletions(-) diff --git a/osu.Game/Overlays/Mods/ModSelectOverlay.cs b/osu.Game/Overlays/Mods/ModSelectOverlay.cs index 48b7907572..7e4c986810 100644 --- a/osu.Game/Overlays/Mods/ModSelectOverlay.cs +++ b/osu.Game/Overlays/Mods/ModSelectOverlay.cs @@ -51,8 +51,8 @@ namespace osu.Game.Overlays.Mods refreshSelectedMods(); } - [BackgroundDependencyLoader(permitNulls: true)] - private void load(OsuColour colours, Bindable ruleset, RulesetStore rulesets, AudioManager audio) + [BackgroundDependencyLoader] + private void load(OsuColour colours, Bindable ruleset, AudioManager audio) { SelectedMods.ValueChanged += selectedModsChanged; @@ -60,13 +60,8 @@ namespace osu.Game.Overlays.Mods HighMultiplierColour = colours.Green; UnrankedLabel.Colour = colours.Blue; - if (ruleset != null) - Ruleset.BindTo(ruleset); - else - Ruleset.Value = rulesets.AvailableRulesets.First(); - - Ruleset.ValueChanged += rulesetChanged; - Ruleset.TriggerChange(); + Ruleset.BindTo(ruleset); + Ruleset.BindValueChanged(rulesetChanged, true); sampleOn = audio.Sample.Get(@"UI/check-on"); sampleOff = audio.Sample.Get(@"UI/check-off"); diff --git a/osu.Game/Overlays/Toolbar/ToolbarModeSelector.cs b/osu.Game/Overlays/Toolbar/ToolbarModeSelector.cs index 6926502d9b..dae4f84b1a 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarModeSelector.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarModeSelector.cs @@ -67,7 +67,7 @@ namespace osu.Game.Overlays.Toolbar }; } - [BackgroundDependencyLoader(true)] + [BackgroundDependencyLoader] private void load(RulesetStore rulesets, Bindable parentRuleset) { this.rulesets = rulesets; @@ -82,11 +82,7 @@ namespace osu.Game.Overlays.Toolbar ruleset.ValueChanged += rulesetChanged; ruleset.DisabledChanged += disabledChanged; - - if (parentRuleset != null) - ruleset.BindTo(parentRuleset); - else - ruleset.Value = rulesets.AvailableRulesets.FirstOrDefault(); + ruleset.BindTo(parentRuleset); } protected override bool OnKeyDown(InputState state, KeyDownEventArgs args) diff --git a/osu.Game/Screens/OsuScreen.cs b/osu.Game/Screens/OsuScreen.cs index bf650dd514..8f7ab14937 100644 --- a/osu.Game/Screens/OsuScreen.cs +++ b/osu.Game/Screens/OsuScreen.cs @@ -84,11 +84,8 @@ namespace osu.Game.Screens [BackgroundDependencyLoader(true)] private void load(BindableBeatmap beatmap, OsuGame osu, AudioManager audio, Bindable ruleset) { - if (beatmap != null) - Beatmap.BindTo(beatmap); - - if (ruleset != null) - Ruleset.BindTo(ruleset); + Beatmap.BindTo(beatmap); + Ruleset.BindTo(ruleset); if (osu != null) { diff --git a/osu.Game/Screens/Select/BeatmapInfoWedge.cs b/osu.Game/Screens/Select/BeatmapInfoWedge.cs index 27089311f2..d26702fcf9 100644 --- a/osu.Game/Screens/Select/BeatmapInfoWedge.cs +++ b/osu.Game/Screens/Select/BeatmapInfoWedge.cs @@ -55,8 +55,7 @@ namespace osu.Game.Screens.Select [BackgroundDependencyLoader(true)] private void load([CanBeNull] Bindable parentRuleset) { - if (parentRuleset != null) - ruleset.BindTo(parentRuleset); + ruleset.BindTo(parentRuleset); ruleset.ValueChanged += _ => updateDisplay(); } diff --git a/osu.Game/Screens/Select/FilterControl.cs b/osu.Game/Screens/Select/FilterControl.cs index abf14a653b..fca6ee23d1 100644 --- a/osu.Game/Screens/Select/FilterControl.cs +++ b/osu.Game/Screens/Select/FilterControl.cs @@ -29,6 +29,7 @@ namespace osu.Game.Screens.Select private readonly TabControl groupTabs; private SortMode sort = SortMode.Title; + public SortMode Sort { get { return sort; } @@ -43,6 +44,7 @@ namespace osu.Game.Screens.Select } private GroupMode group = GroupMode.All; + public GroupMode Group { get { return group; } @@ -69,7 +71,8 @@ namespace osu.Game.Screens.Select private readonly SearchTextBox searchTextBox; - public override bool ReceiveMouseInputAt(Vector2 screenSpacePos) => base.ReceiveMouseInputAt(screenSpacePos) || groupTabs.ReceiveMouseInputAt(screenSpacePos) || sortTabs.ReceiveMouseInputAt(screenSpacePos); + public override bool ReceiveMouseInputAt(Vector2 screenSpacePos) => + base.ReceiveMouseInputAt(screenSpacePos) || groupTabs.ReceiveMouseInputAt(screenSpacePos) || sortTabs.ReceiveMouseInputAt(screenSpacePos); public FilterControl() { @@ -177,8 +180,7 @@ namespace osu.Game.Screens.Select showConverted = config.GetBindable(OsuSetting.ShowConvertedBeatmaps); showConverted.ValueChanged += val => updateCriteria(); - if (parentRuleset != null) - ruleset.BindTo(parentRuleset); + ruleset.BindTo(parentRuleset); ruleset.ValueChanged += val => updateCriteria(); ruleset.TriggerChange(); } diff --git a/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs b/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs index c2a76c14c9..560fd4e375 100644 --- a/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs +++ b/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs @@ -41,6 +41,7 @@ namespace osu.Game.Screens.Select.Leaderboards private ScheduledDelegate showScoresDelegate; private IEnumerable scores; + public IEnumerable Scores { get { return scores; } @@ -196,9 +197,7 @@ namespace osu.Game.Screens.Select.Leaderboards { this.api = api; - if (parentRuleset != null) - ruleset.BindTo(parentRuleset); - + ruleset.BindTo(parentRuleset); ruleset.ValueChanged += _ => updateScores(); if (api != null) diff --git a/osu.Game/Tests/Visual/OsuTestCase.cs b/osu.Game/Tests/Visual/OsuTestCase.cs index 1740658da6..a877ce2333 100644 --- a/osu.Game/Tests/Visual/OsuTestCase.cs +++ b/osu.Game/Tests/Visual/OsuTestCase.cs @@ -1,10 +1,13 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System.Linq; using osu.Framework.Allocation; using osu.Framework.Audio; +using osu.Framework.Configuration; using osu.Framework.Testing; using osu.Game.Beatmaps; +using osu.Game.Rulesets; namespace osu.Game.Tests.Visual { @@ -13,6 +16,8 @@ namespace osu.Game.Tests.Visual private readonly OsuTestBeatmap beatmap = new OsuTestBeatmap(new DummyWorkingBeatmap()); protected BindableBeatmap Beatmap => beatmap; + private readonly Bindable ruleset = new Bindable(); + protected DependencyContainer Dependencies { get; private set; } protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) @@ -22,13 +27,17 @@ namespace osu.Game.Tests.Visual Dependencies.CacheAs(beatmap); Dependencies.CacheAs(beatmap); + Dependencies.CacheAs(ruleset); + return Dependencies; } [BackgroundDependencyLoader] - private void load(AudioManager audioManager) + private void load(AudioManager audioManager, RulesetStore rulesets) { beatmap.SetAudioManager(audioManager); + + ruleset.Value = rulesets.AvailableRulesets.First(); } protected override void Dispose(bool isDisposing) From 018dcc98b40304437a9440c925b233679a65ad40 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 26 Jun 2018 18:59:13 +0900 Subject: [PATCH 06/30] Fix failing tests --- osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs | 8 +++++--- osu.Game/Tests/Visual/OsuTestCase.cs | 6 +++--- osu.Game/Tests/Visual/TestCasePlayer.cs | 6 +++++- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs b/osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs index f52fecfd02..ee66f53ddc 100644 --- a/osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs +++ b/osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs @@ -65,17 +65,19 @@ namespace osu.Game.Tests.Visual foreach (var rulesetInfo in rulesets.AvailableRulesets) { - var ruleset = rulesetInfo.CreateInstance(); + var instance = rulesetInfo.CreateInstance(); var testBeatmap = createTestBeatmap(rulesetInfo); beatmaps.Add(testBeatmap); + AddStep("set ruleset", () => Ruleset.Value = rulesetInfo); + selectBeatmap(testBeatmap); - testBeatmapLabels(ruleset); + testBeatmapLabels(instance); // TODO: adjust cases once more info is shown for other gamemodes - switch (ruleset) + switch (instance) { case OsuRuleset _: testInfoLabels(5); diff --git a/osu.Game/Tests/Visual/OsuTestCase.cs b/osu.Game/Tests/Visual/OsuTestCase.cs index a877ce2333..b3e523b63c 100644 --- a/osu.Game/Tests/Visual/OsuTestCase.cs +++ b/osu.Game/Tests/Visual/OsuTestCase.cs @@ -16,7 +16,7 @@ namespace osu.Game.Tests.Visual private readonly OsuTestBeatmap beatmap = new OsuTestBeatmap(new DummyWorkingBeatmap()); protected BindableBeatmap Beatmap => beatmap; - private readonly Bindable ruleset = new Bindable(); + protected readonly Bindable Ruleset = new Bindable(); protected DependencyContainer Dependencies { get; private set; } @@ -27,7 +27,7 @@ namespace osu.Game.Tests.Visual Dependencies.CacheAs(beatmap); Dependencies.CacheAs(beatmap); - Dependencies.CacheAs(ruleset); + Dependencies.CacheAs(Ruleset); return Dependencies; } @@ -37,7 +37,7 @@ namespace osu.Game.Tests.Visual { beatmap.SetAudioManager(audioManager); - ruleset.Value = rulesets.AvailableRulesets.First(); + Ruleset.Value = rulesets.AvailableRulesets.First(); } protected override void Dispose(bool isDisposing) diff --git a/osu.Game/Tests/Visual/TestCasePlayer.cs b/osu.Game/Tests/Visual/TestCasePlayer.cs index 20c9646aa3..9afb1dd6cd 100644 --- a/osu.Game/Tests/Visual/TestCasePlayer.cs +++ b/osu.Game/Tests/Visual/TestCasePlayer.cs @@ -86,7 +86,11 @@ namespace osu.Game.Tests.Visual private readonly WeakList workingWeakReferences = new WeakList(); private readonly WeakList playerWeakReferences = new WeakList(); - private Player loadPlayerFor(RulesetInfo ri) => loadPlayerFor(ri.CreateInstance()); + private Player loadPlayerFor(RulesetInfo ri) + { + Ruleset.Value = ri; + return loadPlayerFor(ri.CreateInstance()); + } private Player loadPlayerFor(Ruleset r) { From 0866dd11bd2eafe83e9303caf1417cde6f262e75 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 27 Jun 2018 12:57:26 +0900 Subject: [PATCH 07/30] DefaultBackAction -> BackAction, defaults to last button The last button is more commonly the escape condition. --- osu.Game/Screens/Play/FailOverlay.cs | 4 ---- osu.Game/Screens/Play/GameplayMenuOverlay.cs | 6 +++--- osu.Game/Screens/Play/PauseContainer.cs | 3 +++ 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/osu.Game/Screens/Play/FailOverlay.cs b/osu.Game/Screens/Play/FailOverlay.cs index 1295df2da0..bbed0c8843 100644 --- a/osu.Game/Screens/Play/FailOverlay.cs +++ b/osu.Game/Screens/Play/FailOverlay.cs @@ -1,8 +1,6 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using System; -using System.Linq; using osu.Game.Graphics; using OpenTK.Graphics; using osu.Framework.Allocation; @@ -14,8 +12,6 @@ namespace osu.Game.Screens.Play public override string Header => "failed"; public override string Description => "you're dead, try again?"; - protected override Action DefaultBackAction => () => InternalButtons.Children.Last().TriggerOnClick(); - [BackgroundDependencyLoader] private void load(OsuColour colours) { diff --git a/osu.Game/Screens/Play/GameplayMenuOverlay.cs b/osu.Game/Screens/Play/GameplayMenuOverlay.cs index a72fca2532..52c08bb351 100644 --- a/osu.Game/Screens/Play/GameplayMenuOverlay.cs +++ b/osu.Game/Screens/Play/GameplayMenuOverlay.cs @@ -35,9 +35,9 @@ namespace osu.Game.Screens.Play public Action OnQuit; /// - /// Action that is invoked if is triggered. + /// Action that is invoked when is triggered. /// - protected virtual Action DefaultBackAction => () => InternalButtons.Children.First().TriggerOnClick(); + protected virtual Action BackAction => () => InternalButtons.Children.Last().TriggerOnClick(); public abstract string Header { get; } public abstract string Description { get; } @@ -231,7 +231,7 @@ namespace osu.Game.Screens.Play { if (action == GlobalAction.Back) { - DefaultBackAction.Invoke(); + BackAction.Invoke(); return true; } diff --git a/osu.Game/Screens/Play/PauseContainer.cs b/osu.Game/Screens/Play/PauseContainer.cs index 494e28a78e..e2f133dde3 100644 --- a/osu.Game/Screens/Play/PauseContainer.cs +++ b/osu.Game/Screens/Play/PauseContainer.cs @@ -2,6 +2,7 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; +using System.Linq; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -135,6 +136,8 @@ namespace osu.Game.Screens.Play public override string Header => "paused"; public override string Description => "you're not going to do what i think you're going to do, are ya?"; + protected override Action BackAction => () => InternalButtons.Children.First().TriggerOnClick(); + [BackgroundDependencyLoader] private void load(OsuColour colours) { From 756cabd5d01a433413032bd5e500eec6c1aad4ba Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 29 Jun 2018 12:45:48 +0900 Subject: [PATCH 08/30] Add a preprocess method to BeatmapProcessor --- .../Beatmaps/CatchBeatmapProcessor.cs | 79 ++++++++++--------- .../Beatmaps/OsuBeatmapProcessor.cs | 4 +- osu.Game/Beatmaps/BeatmapProcessor.cs | 32 +++++--- osu.Game/Beatmaps/WorkingBeatmap.cs | 7 +- 4 files changed, 73 insertions(+), 49 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs index 8473f5a36c..02395331dc 100644 --- a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs +++ b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs @@ -15,19 +15,26 @@ namespace osu.Game.Rulesets.Catch.Beatmaps { public class CatchBeatmapProcessor : BeatmapProcessor { + public const int RNG_SEED = 1337; + public CatchBeatmapProcessor(IBeatmap beatmap) : base(beatmap) { } - public override void PostProcess() + public override void PreProcess() { - applyPositionOffsets(); + base.PreProcess(); initialiseHyperDash((List)Beatmap.HitObjects); + } + public override void PostProcess() + { base.PostProcess(); + applyPositionOffsets(); + int index = 0; foreach (var obj in Beatmap.HitObjects.OfType()) { @@ -37,41 +44,6 @@ namespace osu.Game.Rulesets.Catch.Beatmaps } } - public const int RNG_SEED = 1337; - - private void applyPositionOffsets() - { - var rng = new FastRandom(RNG_SEED); - // todo: HardRock displacement should be applied here - - foreach (var obj in Beatmap.HitObjects) - { - switch (obj) - { - case BananaShower bananaShower: - foreach (var nested in bananaShower.NestedHitObjects) - { - ((BananaShower.Banana)nested).X = (float)rng.NextDouble(); - rng.Next(); // osu!stable retrieved a random banana type - rng.Next(); // osu!stable retrieved a random banana rotation - rng.Next(); // osu!stable retrieved a random banana colour - } - break; - case JuiceStream juiceStream: - foreach (var nested in juiceStream.NestedHitObjects) - { - var hitObject = (CatchHitObject)nested; - if (hitObject is TinyDroplet) - hitObject.X += rng.Next(-20, 20) / CatchPlayfield.BASE_WIDTH; - else if (hitObject is Droplet) - rng.Next(); // osu!stable retrieved a random droplet rotation - hitObject.X = MathHelper.Clamp(hitObject.X, 0, 1); - } - break; - } - } - } - private void initialiseHyperDash(List objects) { // todo: add difficulty adjust. @@ -115,5 +87,38 @@ namespace osu.Game.Rulesets.Catch.Beatmaps lastDirection = thisDirection; } } + + private void applyPositionOffsets() + { + var rng = new FastRandom(RNG_SEED); + // todo: HardRock displacement should be applied here + + foreach (var obj in Beatmap.HitObjects) + { + switch (obj) + { + case BananaShower bananaShower: + foreach (var nested in bananaShower.NestedHitObjects) + { + ((BananaShower.Banana)nested).X = (float)rng.NextDouble(); + rng.Next(); // osu!stable retrieved a random banana type + rng.Next(); // osu!stable retrieved a random banana rotation + rng.Next(); // osu!stable retrieved a random banana colour + } + break; + case JuiceStream juiceStream: + foreach (var nested in juiceStream.NestedHitObjects) + { + var hitObject = (CatchHitObject)nested; + if (hitObject is TinyDroplet) + hitObject.X += rng.Next(-20, 20) / CatchPlayfield.BASE_WIDTH; + else if (hitObject is Droplet) + rng.Next(); // osu!stable retrieved a random droplet rotation + hitObject.X = MathHelper.Clamp(hitObject.X, 0, 1); + } + break; + } + } + } } } diff --git a/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapProcessor.cs b/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapProcessor.cs index c7c9f4a01a..6cea5df078 100644 --- a/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapProcessor.cs +++ b/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapProcessor.cs @@ -15,10 +15,10 @@ namespace osu.Game.Rulesets.Osu.Beatmaps { } - public override void PostProcess() + public override void PreProcess() { + base.PreProcess(); applyStacking((Beatmap)Beatmap); - base.PostProcess(); } private void applyStacking(Beatmap beatmap) diff --git a/osu.Game/Beatmaps/BeatmapProcessor.cs b/osu.Game/Beatmaps/BeatmapProcessor.cs index bf1cd7d4ee..1fc22197fe 100644 --- a/osu.Game/Beatmaps/BeatmapProcessor.cs +++ b/osu.Game/Beatmaps/BeatmapProcessor.cs @@ -11,11 +11,27 @@ namespace osu.Game.Beatmaps IBeatmap Beatmap { get; } /// - /// Post-processes to add mode-specific components that aren't added during conversion. + /// Processes the converted prior to being invoked. /// - /// An example of such a usage is for combo colours. + /// Nested s generated during will not be present by this point, + /// and no mods will have been applied to the s. /// /// + /// + /// This can only be used to add alterations to s generated directly through the conversion process. + /// + void PreProcess(); + + /// + /// Processes the converted after has been invoked. + /// + /// Nested s generated during will be present by this point, + /// and mods will have been applied to all s. + /// + /// + /// + /// This should be used to add alterations to s while they are in their most playable state. + /// void PostProcess(); } @@ -32,13 +48,7 @@ namespace osu.Game.Beatmaps Beatmap = beatmap; } - /// - /// Post-processes a Beatmap to add mode-specific components that aren't added during conversion. - /// - /// An example of such a usage is for combo colours. - /// - /// - public virtual void PostProcess() + public virtual void PreProcess() { IHasComboInformation lastObj = null; @@ -62,5 +72,9 @@ namespace osu.Game.Beatmaps lastObj = obj; } } + + public virtual void PostProcess() + { + } } } diff --git a/osu.Game/Beatmaps/WorkingBeatmap.cs b/osu.Game/Beatmaps/WorkingBeatmap.cs index 1a65611a3d..1dc90b3d6c 100644 --- a/osu.Game/Beatmaps/WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/WorkingBeatmap.cs @@ -116,6 +116,11 @@ namespace osu.Game.Beatmaps mod.ApplyToDifficulty(converted.BeatmapInfo.BaseDifficulty); } + IBeatmapProcessor processor = rulesetInstance.CreateBeatmapProcessor(converted); + + // Pre-process + processor?.PreProcess(); + // Compute default values for hitobjects, including creating nested hitobjects in-case they're needed foreach (var obj in converted.HitObjects) obj.ApplyDefaults(converted.ControlPointInfo, converted.BeatmapInfo.BaseDifficulty); @@ -125,7 +130,7 @@ namespace osu.Game.Beatmaps mod.ApplyToHitObject(obj); // Post-process - rulesetInstance.CreateBeatmapProcessor(converted)?.PostProcess(); + processor?.PostProcess(); return converted; } From 99068debc41b68636402b866feab04700a01ef82 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 29 Jun 2018 13:07:00 +0900 Subject: [PATCH 09/30] Split out into separate interface + add xmldocs --- osu.Game/Beatmaps/BeatmapProcessor.cs | 32 +-------------------- osu.Game/Beatmaps/IBeatmapConverter.cs | 3 ++ osu.Game/Beatmaps/IBeatmapProcessor.cs | 40 ++++++++++++++++++++++++++ osu.Game/Rulesets/Ruleset.cs | 10 +++++++ 4 files changed, 54 insertions(+), 31 deletions(-) create mode 100644 osu.Game/Beatmaps/IBeatmapProcessor.cs diff --git a/osu.Game/Beatmaps/BeatmapProcessor.cs b/osu.Game/Beatmaps/BeatmapProcessor.cs index 1fc22197fe..0173125e8b 100644 --- a/osu.Game/Beatmaps/BeatmapProcessor.cs +++ b/osu.Game/Beatmaps/BeatmapProcessor.cs @@ -6,39 +6,9 @@ using osu.Game.Rulesets.Objects.Types; namespace osu.Game.Beatmaps { - public interface IBeatmapProcessor - { - IBeatmap Beatmap { get; } - - /// - /// Processes the converted prior to being invoked. - /// - /// Nested s generated during will not be present by this point, - /// and no mods will have been applied to the s. - /// - /// - /// - /// This can only be used to add alterations to s generated directly through the conversion process. - /// - void PreProcess(); - - /// - /// Processes the converted after has been invoked. - /// - /// Nested s generated during will be present by this point, - /// and mods will have been applied to all s. - /// - /// - /// - /// This should be used to add alterations to s while they are in their most playable state. - /// - void PostProcess(); - } - /// - /// Processes a post-converted Beatmap. + /// Provides functionality to alter a after it has been converted. /// - /// The type of HitObject contained in the Beatmap. public class BeatmapProcessor : IBeatmapProcessor { public IBeatmap Beatmap { get; } diff --git a/osu.Game/Beatmaps/IBeatmapConverter.cs b/osu.Game/Beatmaps/IBeatmapConverter.cs index 00566093b8..cbf9d184ac 100644 --- a/osu.Game/Beatmaps/IBeatmapConverter.cs +++ b/osu.Game/Beatmaps/IBeatmapConverter.cs @@ -7,6 +7,9 @@ using osu.Game.Rulesets.Objects; namespace osu.Game.Beatmaps { + /// + /// Provides functionality to convert a for a . + /// public interface IBeatmapConverter { /// diff --git a/osu.Game/Beatmaps/IBeatmapProcessor.cs b/osu.Game/Beatmaps/IBeatmapProcessor.cs new file mode 100644 index 0000000000..282662373a --- /dev/null +++ b/osu.Game/Beatmaps/IBeatmapProcessor.cs @@ -0,0 +1,40 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +namespace osu.Game.Beatmaps +{ + /// + /// Provides functionality to alter a after it has been converted. + /// + public interface IBeatmapProcessor + { + /// + /// The to process. This should already be converted to the applicable . + /// + IBeatmap Beatmap { get; } + + /// + /// Processes the converted prior to being invoked. + /// + /// Nested s generated during will not be present by this point, + /// and no mods will have been applied to the s. + /// + /// + /// + /// This can only be used to add alterations to s generated directly through the conversion process. + /// + void PreProcess(); + + /// + /// Processes the converted after has been invoked. + /// + /// Nested s generated during will be present by this point, + /// and mods will have been applied to all s. + /// + /// + /// + /// This should be used to add alterations to s while they are in their most playable state. + /// + void PostProcess(); + } +} diff --git a/osu.Game/Rulesets/Ruleset.cs b/osu.Game/Rulesets/Ruleset.cs index f818523a3d..82d9945ef7 100644 --- a/osu.Game/Rulesets/Ruleset.cs +++ b/osu.Game/Rulesets/Ruleset.cs @@ -57,8 +57,18 @@ namespace osu.Game.Rulesets /// public abstract RulesetContainer CreateRulesetContainerWith(WorkingBeatmap beatmap); + /// + /// Creates a to convert a to one that is applicable for this . + /// + /// The to be converted. + /// The . public abstract IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap); + /// + /// Optionally creates a to alter a after it has been converted. + /// + /// The to be processed. + /// The . public virtual IBeatmapProcessor CreateBeatmapProcessor(IBeatmap beatmap) => null; public abstract DifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap); From 4fb276bab7ebfdabec52023027d30eeb1ebd3f98 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 29 Jun 2018 13:52:13 +0900 Subject: [PATCH 10/30] Move hyperdash init to PostProcess --- .../Beatmaps/CatchBeatmapProcessor.cs | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs index 02395331dc..aa05e5a4d6 100644 --- a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs +++ b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs @@ -22,19 +22,14 @@ namespace osu.Game.Rulesets.Catch.Beatmaps { } - public override void PreProcess() - { - base.PreProcess(); - - initialiseHyperDash((List)Beatmap.HitObjects); - } - public override void PostProcess() { base.PostProcess(); applyPositionOffsets(); + initialiseHyperDash((List)Beatmap.HitObjects); + int index = 0; foreach (var obj in Beatmap.HitObjects.OfType()) { From 34fef3caba8b226859d8182d6be420acf816aef5 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 29 Jun 2018 20:13:29 +0900 Subject: [PATCH 11/30] Update exception type --- osu.Game/Screens/BackgroundScreen.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/BackgroundScreen.cs b/osu.Game/Screens/BackgroundScreen.cs index 61277439c1..d3192aa612 100644 --- a/osu.Game/Screens/BackgroundScreen.cs +++ b/osu.Game/Screens/BackgroundScreen.cs @@ -44,7 +44,7 @@ namespace osu.Game.Screens { base.Push(screen); } - catch (InvalidOperationException) + catch (ScreenAlreadyExitedException) { // screen may have exited before the push was successful. } From 0e649b8866bc932f532060f500dc9694289aa9fc Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 29 Jun 2018 20:16:24 +0900 Subject: [PATCH 12/30] Change logic --- osu.Game/Screens/BackgroundScreen.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/BackgroundScreen.cs b/osu.Game/Screens/BackgroundScreen.cs index d3192aa612..9d9432b2ce 100644 --- a/osu.Game/Screens/BackgroundScreen.cs +++ b/osu.Game/Screens/BackgroundScreen.cs @@ -37,7 +37,7 @@ namespace osu.Game.Screens } // Make sure the in-progress loading is complete before pushing the screen. - while (screen.LoadState != LoadState.Ready) + while (screen.LoadState < LoadState.Ready) Thread.Sleep(1); try From 6a80a21078d7ad2c9dbe3dd552fbdbbaadf5f7e0 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 27 Jun 2018 16:06:26 +0900 Subject: [PATCH 13/30] Tidy up escape handling --- .../Graphics/UserInterface/FocusedTextBox.cs | 16 +++--------- osu.Game/Graphics/UserInterface/OsuTextBox.cs | 25 +++++++++++++++---- .../Graphics/UserInterface/SearchTextBox.cs | 2 +- osu.Game/Overlays/KeyBinding/KeyBindingRow.cs | 3 --- osu.Game/Screens/Menu/ButtonSystem.cs | 13 +--------- osu.Game/Screens/Menu/ExitConfirmOverlay.cs | 18 ++++++------- osu.Game/Screens/OsuScreen.cs | 18 ++----------- 7 files changed, 37 insertions(+), 58 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/FocusedTextBox.cs b/osu.Game/Graphics/UserInterface/FocusedTextBox.cs index 6500578de3..af5765a791 100644 --- a/osu.Game/Graphics/UserInterface/FocusedTextBox.cs +++ b/osu.Game/Graphics/UserInterface/FocusedTextBox.cs @@ -2,7 +2,6 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using OpenTK.Graphics; -using OpenTK.Input; using osu.Framework.Input; using System; @@ -26,6 +25,7 @@ namespace osu.Game.Graphics.UserInterface { focus = value; if (!focus && HasFocus) + //todo: replace with KillInput after ppy/osu-framework#1656 is merged. GetContainingInputManager().ChangeFocus(null); } } @@ -39,18 +39,10 @@ namespace osu.Game.Graphics.UserInterface BorderThickness = 0; } - protected override bool OnKeyDown(InputState state, KeyDownEventArgs args) + protected override void KillFocus() { - if (!args.Repeat && args.Key == Key.Escape) - { - if (Text.Length > 0) - Text = string.Empty; - else - Exit?.Invoke(); - return true; - } - - return base.OnKeyDown(state, args); + base.KillFocus(); + Exit?.Invoke(); } public override bool RequestsFocus => HoldFocus; diff --git a/osu.Game/Graphics/UserInterface/OsuTextBox.cs b/osu.Game/Graphics/UserInterface/OsuTextBox.cs index 6021af2028..f21491c257 100644 --- a/osu.Game/Graphics/UserInterface/OsuTextBox.cs +++ b/osu.Game/Graphics/UserInterface/OsuTextBox.cs @@ -9,10 +9,12 @@ using osu.Framework.Input; using osu.Game.Graphics.Sprites; using OpenTK.Graphics; using osu.Framework.Extensions.Color4Extensions; +using osu.Framework.Input.Bindings; +using osu.Game.Input.Bindings; namespace osu.Game.Graphics.UserInterface { - public class OsuTextBox : TextBox + public class OsuTextBox : TextBox, IKeyBindingHandler { protected override Color4 BackgroundUnfocused => Color4.Black.Opacity(0.5f); protected override Color4 BackgroundFocused => OsuColour.Gray(0.3f).Opacity(0.8f); @@ -33,10 +35,7 @@ namespace osu.Game.Graphics.UserInterface TextContainer.Height = 0.5f; CornerRadius = 5; - Current.DisabledChanged += disabled => - { - Alpha = disabled ? 0.3f : 1; - }; + Current.DisabledChanged += disabled => { Alpha = disabled ? 0.3f : 1; }; } [BackgroundDependencyLoader] @@ -59,5 +58,21 @@ namespace osu.Game.Graphics.UserInterface } protected override Drawable GetDrawableCharacter(char c) => new OsuSpriteText { Text = c.ToString(), TextSize = CalculatedTextSize }; + + public bool OnPressed(GlobalAction action) + { + if (action == GlobalAction.Back) + { + if (Text.Length > 0) + Text = string.Empty; + else + KillFocus(); + return true; + } + + return true; + } + + public bool OnReleased(GlobalAction action) => false; } } diff --git a/osu.Game/Graphics/UserInterface/SearchTextBox.cs b/osu.Game/Graphics/UserInterface/SearchTextBox.cs index e50539e120..09f5968acd 100644 --- a/osu.Game/Graphics/UserInterface/SearchTextBox.cs +++ b/osu.Game/Graphics/UserInterface/SearchTextBox.cs @@ -34,7 +34,7 @@ namespace osu.Game.Graphics.UserInterface protected override bool OnKeyDown(InputState state, KeyDownEventArgs args) { - if (HandlePendingText(state)) return true; + if (HandlePendingText(state)) return false; if (!state.Keyboard.ControlPressed && !state.Keyboard.ShiftPressed) { diff --git a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs index a12f9dee7e..29eb1094cf 100644 --- a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs +++ b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs @@ -202,9 +202,6 @@ namespace osu.Game.Overlays.KeyBinding switch (args.Key) { - case Key.Escape: - finalise(); - return true; case Key.Delete: { if (state.Keyboard.ShiftPressed) diff --git a/osu.Game/Screens/Menu/ButtonSystem.cs b/osu.Game/Screens/Menu/ButtonSystem.cs index 81abc4cd3d..374877673f 100644 --- a/osu.Game/Screens/Menu/ButtonSystem.cs +++ b/osu.Game/Screens/Menu/ButtonSystem.cs @@ -148,8 +148,6 @@ namespace osu.Game.Screens.Menu case Key.Space: logo?.TriggerOnClick(state); return true; - case Key.Escape: - return goBack(); } return false; @@ -181,16 +179,7 @@ namespace osu.Game.Screens.Menu } } - public bool OnReleased(GlobalAction action) - { - switch (action) - { - case GlobalAction.Back: - return true; - default: - return false; - } - } + public bool OnReleased(GlobalAction action) => false; private void onPlay() { diff --git a/osu.Game/Screens/Menu/ExitConfirmOverlay.cs b/osu.Game/Screens/Menu/ExitConfirmOverlay.cs index 62605da5a4..4ada46749c 100644 --- a/osu.Game/Screens/Menu/ExitConfirmOverlay.cs +++ b/osu.Game/Screens/Menu/ExitConfirmOverlay.cs @@ -1,34 +1,34 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using osu.Framework.Input; +using osu.Framework.Input.Bindings; +using osu.Game.Input.Bindings; using osu.Game.Overlays; -using OpenTK.Input; namespace osu.Game.Screens.Menu { - public class ExitConfirmOverlay : HoldToConfirmOverlay + public class ExitConfirmOverlay : HoldToConfirmOverlay, IKeyBindingHandler { - protected override bool OnKeyDown(InputState state, KeyDownEventArgs args) + public bool OnPressed(GlobalAction action) { - if (args.Key == Key.Escape && !args.Repeat) + if (action == GlobalAction.Back) { BeginConfirm(); return true; } - return base.OnKeyDown(state, args); + return false; } - protected override bool OnKeyUp(InputState state, KeyUpEventArgs args) + public bool OnReleased(GlobalAction action) { - if (args.Key == Key.Escape) + if (action == GlobalAction.Back) { AbortConfirm(); return true; } - return base.OnKeyUp(state, args); + return false; } } } diff --git a/osu.Game/Screens/OsuScreen.cs b/osu.Game/Screens/OsuScreen.cs index 61018f9e08..510f7b9726 100644 --- a/osu.Game/Screens/OsuScreen.cs +++ b/osu.Game/Screens/OsuScreen.cs @@ -8,7 +8,6 @@ using osu.Framework.Audio; using osu.Framework.Audio.Sample; using osu.Framework.Configuration; using osu.Framework.Graphics; -using osu.Framework.Input; using osu.Framework.Input.Bindings; using osu.Framework.Screens; using osu.Game.Beatmaps; @@ -17,7 +16,6 @@ using osu.Game.Input.Bindings; using osu.Game.Rulesets; using osu.Game.Screens.Menu; using OpenTK; -using OpenTK.Input; using osu.Game.Overlays; using osu.Framework.Graphics.Containers; @@ -106,6 +104,8 @@ namespace osu.Game.Screens public bool OnPressed(GlobalAction action) { + if (!IsCurrentScreen) return false; + if (action == GlobalAction.Back && AllowBackButton) { Exit(); @@ -117,20 +117,6 @@ namespace osu.Game.Screens public bool OnReleased(GlobalAction action) => action == GlobalAction.Back && AllowBackButton; - protected override bool OnKeyDown(InputState state, KeyDownEventArgs args) - { - if (args.Repeat || !IsCurrentScreen) return false; - - switch (args.Key) - { - case Key.Escape: - Exit(); - return true; - } - - return base.OnKeyDown(state, args); - } - protected override void OnResuming(Screen last) { sampleExit?.Play(); From cd47bd2cf8be75f18844d482643557592fe6f32c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 29 Jun 2018 21:06:43 +0900 Subject: [PATCH 14/30] Update framework --- osu.Game/Graphics/UserInterface/SearchTextBox.cs | 2 -- osu.Game/osu.Game.csproj | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/SearchTextBox.cs b/osu.Game/Graphics/UserInterface/SearchTextBox.cs index 09f5968acd..7d53c9e9d9 100644 --- a/osu.Game/Graphics/UserInterface/SearchTextBox.cs +++ b/osu.Game/Graphics/UserInterface/SearchTextBox.cs @@ -34,8 +34,6 @@ namespace osu.Game.Graphics.UserInterface protected override bool OnKeyDown(InputState state, KeyDownEventArgs args) { - if (HandlePendingText(state)) return false; - if (!state.Keyboard.ControlPressed && !state.Keyboard.ShiftPressed) { switch (args.Key) diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index b4fccf0898..56c33c47af 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -18,7 +18,7 @@ - + From ad28f88498d8081372b0070f29509ef6cdb181de Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 29 Jun 2018 21:25:51 +0900 Subject: [PATCH 15/30] Fix protection change --- osu.Game/Graphics/UserInterface/OsuPasswordTextBox.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Graphics/UserInterface/OsuPasswordTextBox.cs b/osu.Game/Graphics/UserInterface/OsuPasswordTextBox.cs index d34d2b2a7c..07920865c0 100644 --- a/osu.Game/Graphics/UserInterface/OsuPasswordTextBox.cs +++ b/osu.Game/Graphics/UserInterface/OsuPasswordTextBox.cs @@ -18,7 +18,7 @@ namespace osu.Game.Graphics.UserInterface { protected override Drawable GetDrawableCharacter(char c) => new PasswordMaskChar(CalculatedTextSize); - public override bool AllowClipboardExport => false; + protected override bool AllowClipboardExport => false; private readonly CapsWarning warning; From 7c0547b4ee00f053b87124b55cc65ac1ed7d47e0 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 29 Jun 2018 23:16:05 +0900 Subject: [PATCH 16/30] Replace todo --- osu.Game/Graphics/UserInterface/FocusedTextBox.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/FocusedTextBox.cs b/osu.Game/Graphics/UserInterface/FocusedTextBox.cs index af5765a791..77b6d3f618 100644 --- a/osu.Game/Graphics/UserInterface/FocusedTextBox.cs +++ b/osu.Game/Graphics/UserInterface/FocusedTextBox.cs @@ -25,8 +25,7 @@ namespace osu.Game.Graphics.UserInterface { focus = value; if (!focus && HasFocus) - //todo: replace with KillInput after ppy/osu-framework#1656 is merged. - GetContainingInputManager().ChangeFocus(null); + KillFocus(); } } From fb90a4924b04e9fe2c19039dd0e6f789aa323110 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 29 Jun 2018 23:28:15 +0900 Subject: [PATCH 17/30] Only clear text in FocusedTextBox --- .../Graphics/UserInterface/FocusedTextBox.cs | 16 ++++++++++++++++ osu.Game/Graphics/UserInterface/OsuTextBox.cs | 7 ++----- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/FocusedTextBox.cs b/osu.Game/Graphics/UserInterface/FocusedTextBox.cs index 77b6d3f618..4b2f40b7ae 100644 --- a/osu.Game/Graphics/UserInterface/FocusedTextBox.cs +++ b/osu.Game/Graphics/UserInterface/FocusedTextBox.cs @@ -4,6 +4,7 @@ using OpenTK.Graphics; using osu.Framework.Input; using System; +using osu.Game.Input.Bindings; namespace osu.Game.Graphics.UserInterface { @@ -18,6 +19,7 @@ namespace osu.Game.Graphics.UserInterface public Action Exit; private bool focus; + public bool HoldFocus { get { return focus; } @@ -38,6 +40,20 @@ namespace osu.Game.Graphics.UserInterface BorderThickness = 0; } + public override bool OnPressed(GlobalAction action) + { + if (action == GlobalAction.Back) + { + if (Text.Length > 0) + { + Text = string.Empty; + return true; + } + } + + return base.OnPressed(action); + } + protected override void KillFocus() { base.KillFocus(); diff --git a/osu.Game/Graphics/UserInterface/OsuTextBox.cs b/osu.Game/Graphics/UserInterface/OsuTextBox.cs index f21491c257..ca45d1087a 100644 --- a/osu.Game/Graphics/UserInterface/OsuTextBox.cs +++ b/osu.Game/Graphics/UserInterface/OsuTextBox.cs @@ -59,14 +59,11 @@ namespace osu.Game.Graphics.UserInterface protected override Drawable GetDrawableCharacter(char c) => new OsuSpriteText { Text = c.ToString(), TextSize = CalculatedTextSize }; - public bool OnPressed(GlobalAction action) + public virtual bool OnPressed(GlobalAction action) { if (action == GlobalAction.Back) { - if (Text.Length > 0) - Text = string.Empty; - else - KillFocus(); + KillFocus(); return true; } From 754e072e015c4e613d86103eac82f9d38aaceada Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 29 Jun 2018 23:35:14 +0900 Subject: [PATCH 18/30] Don't handle all actions --- osu.Game/Graphics/UserInterface/OsuTextBox.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Graphics/UserInterface/OsuTextBox.cs b/osu.Game/Graphics/UserInterface/OsuTextBox.cs index ca45d1087a..88b0543de0 100644 --- a/osu.Game/Graphics/UserInterface/OsuTextBox.cs +++ b/osu.Game/Graphics/UserInterface/OsuTextBox.cs @@ -67,7 +67,7 @@ namespace osu.Game.Graphics.UserInterface return true; } - return true; + return false; } public bool OnReleased(GlobalAction action) => false; From 00fd5c8dbca797a6b4069e57082b5f4dfe8c98e1 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 30 Jun 2018 23:51:27 +0900 Subject: [PATCH 19/30] Fix regression causing binding settings to fail --- osu.Game/Graphics/UserInterface/FocusedTextBox.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/osu.Game/Graphics/UserInterface/FocusedTextBox.cs b/osu.Game/Graphics/UserInterface/FocusedTextBox.cs index 4b2f40b7ae..10509a4639 100644 --- a/osu.Game/Graphics/UserInterface/FocusedTextBox.cs +++ b/osu.Game/Graphics/UserInterface/FocusedTextBox.cs @@ -40,6 +40,13 @@ namespace osu.Game.Graphics.UserInterface BorderThickness = 0; } + protected override bool OnKeyDown(InputState state, KeyDownEventArgs args) + { + if (!HasFocus) return false; + + return base.OnKeyDown(state, args); + } + public override bool OnPressed(GlobalAction action) { if (action == GlobalAction.Back) From 7028767e50cf248272d3b34f83d6df8f987a45f4 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 1 Jul 2018 14:08:34 +0900 Subject: [PATCH 20/30] Fix regression in HoldFocus behaviour --- osu.Game/Graphics/UserInterface/FocusedTextBox.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Graphics/UserInterface/FocusedTextBox.cs b/osu.Game/Graphics/UserInterface/FocusedTextBox.cs index 10509a4639..dd45452944 100644 --- a/osu.Game/Graphics/UserInterface/FocusedTextBox.cs +++ b/osu.Game/Graphics/UserInterface/FocusedTextBox.cs @@ -27,7 +27,7 @@ namespace osu.Game.Graphics.UserInterface { focus = value; if (!focus && HasFocus) - KillFocus(); + base.KillFocus(); } } From b1403d837e7c0adc3c538b811ea6a9fccb7cdf6a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 1 Jul 2018 15:52:47 +0900 Subject: [PATCH 21/30] Add back support for closing focused overlays using back key --- .../Containers/OsuFocusedOverlayContainer.cs | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs b/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs index 323046f758..39369350ef 100644 --- a/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs +++ b/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs @@ -8,12 +8,14 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Input; using OpenTK; using osu.Framework.Configuration; +using osu.Framework.Input.Bindings; using osu.Game.Audio; +using osu.Game.Input.Bindings; using osu.Game.Overlays; namespace osu.Game.Graphics.Containers { - public class OsuFocusedOverlayContainer : FocusedOverlayContainer, IPreviewTrackOwner + public class OsuFocusedOverlayContainer : FocusedOverlayContainer, IPreviewTrackOwner, IKeyBindingHandler { private SampleChannel samplePopIn; private SampleChannel samplePopOut; @@ -65,6 +67,19 @@ namespace osu.Game.Graphics.Containers return base.OnClick(state); } + public bool OnPressed(GlobalAction action) + { + if (action == GlobalAction.Back) + { + State = Visibility.Hidden; + return true; + } + + return false; + } + + public bool OnReleased(GlobalAction action) => false; + private void onStateChanged(Visibility visibility) { switch (visibility) From 98fb2e03c0bcf3ebc47e65855d82ab6ada6bf04e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 1 Jul 2018 18:03:15 +0900 Subject: [PATCH 22/30] Fix rulesets not loading in debug builds after running a release build --- osu.Game/Rulesets/RulesetStore.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/RulesetStore.cs b/osu.Game/Rulesets/RulesetStore.cs index a7a9fea5f2..513173ef2f 100644 --- a/osu.Game/Rulesets/RulesetStore.cs +++ b/osu.Game/Rulesets/RulesetStore.cs @@ -84,7 +84,13 @@ namespace osu.Game.Rulesets { try { - var instanceInfo = ((Ruleset)Activator.CreateInstance(Type.GetType(r.InstantiationInfo), (RulesetInfo)null)).RulesetInfo; + var instanceInfo = ((Ruleset)Activator.CreateInstance(Type.GetType(r.InstantiationInfo, asm => + { + // for the time being, let's ignore the version being loaded. + // this allows for debug builds to successfully load rulesets (even though debug rulesets have a 0.0.0 version). + asm.Version = null; + return Assembly.Load(asm); + }, null), (RulesetInfo)null)).RulesetInfo; r.Name = instanceInfo.Name; r.ShortName = instanceInfo.ShortName; From 6a459efd8f47aeba5a1c27a032eb038c3023db3b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 2 Jul 2018 11:04:40 +0900 Subject: [PATCH 23/30] Don't allow Key.Escape --- osu.Game/Graphics/UserInterface/FocusedTextBox.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/osu.Game/Graphics/UserInterface/FocusedTextBox.cs b/osu.Game/Graphics/UserInterface/FocusedTextBox.cs index dd45452944..28d04c9a82 100644 --- a/osu.Game/Graphics/UserInterface/FocusedTextBox.cs +++ b/osu.Game/Graphics/UserInterface/FocusedTextBox.cs @@ -5,6 +5,7 @@ using OpenTK.Graphics; using osu.Framework.Input; using System; using osu.Game.Input.Bindings; +using OpenTK.Input; namespace osu.Game.Graphics.UserInterface { @@ -44,6 +45,9 @@ namespace osu.Game.Graphics.UserInterface { if (!HasFocus) return false; + if (args.Key == Key.Escape) + return false; // disable the framework-level handling of escape key for confority (we use GlobalAction.Back). + return base.OnKeyDown(state, args); } From f007e71c87369e7e07e65fe5c1fdb2dae23d6ba2 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 2 Jul 2018 12:31:41 +0900 Subject: [PATCH 24/30] Retrieve the mania key action through DI --- .../TestCaseColumn.cs | 6 ++-- .../TestCaseNotes.cs | 12 +++++-- .../TestCaseStage.cs | 4 +-- .../Objects/Drawables/DrawableHoldNote.cs | 22 ++++++------ .../Drawables/DrawableManiaHitObject.cs | 35 ++++++++++++------- .../Objects/Drawables/DrawableNote.cs | 6 ++-- osu.Game.Rulesets.Mania/UI/Column.cs | 25 ++++++------- .../UI/Components/ColumnBackground.cs | 10 +++--- .../UI/Components/ColumnKeyArea.cs | 11 +++--- .../UI/ManiaRulesetContainer.cs | 20 +++++------ osu.Game.Rulesets.Mania/UI/ManiaStage.cs | 2 +- 11 files changed, 83 insertions(+), 70 deletions(-) diff --git a/osu.Game.Rulesets.Mania.Tests/TestCaseColumn.cs b/osu.Game.Rulesets.Mania.Tests/TestCaseColumn.cs index 72f0b046b6..de2bfaed9c 100644 --- a/osu.Game.Rulesets.Mania.Tests/TestCaseColumn.cs +++ b/osu.Game.Rulesets.Mania.Tests/TestCaseColumn.cs @@ -69,7 +69,7 @@ namespace osu.Game.Rulesets.Mania.Tests var obj = new Note { Column = i, StartTime = Time.Current + 2000 }; obj.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty()); - columns[i].Add(new DrawableNote(obj, columns[i].Action)); + columns[i].Add(new DrawableNote(obj)); } } @@ -80,7 +80,7 @@ namespace osu.Game.Rulesets.Mania.Tests var obj = new HoldNote { Column = i, StartTime = Time.Current + 2000, Duration = 500 }; obj.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty()); - columns[i].Add(new DrawableHoldNote(obj, columns[i].Action)); + columns[i].Add(new DrawableHoldNote(obj)); } } @@ -92,7 +92,7 @@ namespace osu.Game.Rulesets.Mania.Tests Origin = Anchor.Centre, Height = 0.85f, AccentColour = Color4.OrangeRed, - Action = action, + Action = { Value = action }, VisibleTimeRange = { Value = 2000 } }; diff --git a/osu.Game.Rulesets.Mania.Tests/TestCaseNotes.cs b/osu.Game.Rulesets.Mania.Tests/TestCaseNotes.cs index 4fdfac93b7..0f70ceece2 100644 --- a/osu.Game.Rulesets.Mania.Tests/TestCaseNotes.cs +++ b/osu.Game.Rulesets.Mania.Tests/TestCaseNotes.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.Linq; using NUnit.Framework; using osu.Framework.Allocation; +using osu.Framework.Configuration; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -63,7 +64,7 @@ namespace osu.Game.Rulesets.Mania.Tests AutoSizeAxes = Axes.Both, Child = new NoteContainer(direction, $"note, scrolling {direction.ToString().ToLower()}") { - Child = new DrawableNote(note, ManiaAction.Key1) { AccentColour = Color4.OrangeRed } + Child = new DrawableNote(note) { AccentColour = Color4.OrangeRed } } }; } @@ -78,7 +79,7 @@ namespace osu.Game.Rulesets.Mania.Tests AutoSizeAxes = Axes.Both, Child = new NoteContainer(direction, $"hold note, scrolling {direction.ToString().ToLower()}") { - Child = new DrawableHoldNote(note, ManiaAction.Key1) + Child = new DrawableHoldNote(note) { RelativeSizeAxes = Axes.Both, AccentColour = Color4.OrangeRed, @@ -136,6 +137,13 @@ namespace osu.Game.Rulesets.Mania.Tests }; } + protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) + { + var dependencies = new DependencyContainer(base.CreateLocalDependencies(parent)); + dependencies.CacheAs>(new Bindable()); + return dependencies; + } + protected override void Update() { base.Update(); diff --git a/osu.Game.Rulesets.Mania.Tests/TestCaseStage.cs b/osu.Game.Rulesets.Mania.Tests/TestCaseStage.cs index 9aff853ffd..8046c46fc1 100644 --- a/osu.Game.Rulesets.Mania.Tests/TestCaseStage.cs +++ b/osu.Game.Rulesets.Mania.Tests/TestCaseStage.cs @@ -65,7 +65,7 @@ namespace osu.Game.Rulesets.Mania.Tests var obj = new Note { Column = i, StartTime = Time.Current + 2000 }; obj.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty()); - stage.Add(new DrawableNote(obj, stage.Columns[i].Action)); + stage.Add(new DrawableNote(obj)); } } } @@ -79,7 +79,7 @@ namespace osu.Game.Rulesets.Mania.Tests var obj = new HoldNote { Column = i, StartTime = Time.Current + 2000, Duration = 500 }; obj.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty()); - stage.Add(new DrawableHoldNote(obj, stage.Columns[i].Action)); + stage.Add(new DrawableHoldNote(obj)); } } } diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs index ce0276f759..597450f223 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs @@ -38,8 +38,8 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables private readonly Container tickContainer; - public DrawableHoldNote(HoldNote hitObject, ManiaAction action) - : base(hitObject, action) + public DrawableHoldNote(HoldNote hitObject) + : base(hitObject) { RelativeSizeAxes = Axes.X; @@ -57,12 +57,12 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables HoldStartTime = () => holdStartTime }) }, - head = new DrawableHeadNote(this, action) + head = new DrawableHeadNote(this) { Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre }, - tail = new DrawableTailNote(this, action) + tail = new DrawableTailNote(this) { Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre @@ -118,7 +118,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables if (Time.Current < HitObject.StartTime || Time.Current > HitObject.EndTime) return false; - if (action != Action) + if (action != Action.Value) return false; // The user has pressed during the body of the hold note, after the head note and its hit windows have passed @@ -135,7 +135,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables if (!holdStartTime.HasValue) return false; - if (action != Action) + if (action != Action.Value) return false; holdStartTime = null; @@ -154,8 +154,8 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables { private readonly DrawableHoldNote holdNote; - public DrawableHeadNote(DrawableHoldNote holdNote, ManiaAction action) - : base(holdNote.HitObject.Head, action) + public DrawableHeadNote(DrawableHoldNote holdNote) + : base(holdNote.HitObject.Head) { this.holdNote = holdNote; } @@ -191,8 +191,8 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables private readonly DrawableHoldNote holdNote; - public DrawableTailNote(DrawableHoldNote holdNote, ManiaAction action) - : base(holdNote.HitObject.Tail, action) + public DrawableTailNote(DrawableHoldNote holdNote) + : base(holdNote.HitObject.Tail) { this.holdNote = holdNote; } @@ -235,7 +235,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables if (!holdNote.holdStartTime.HasValue) return false; - if (action != Action) + if (action != Action.Value) return false; UpdateJudgement(true); diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs index 1271fae0c1..cb6196a890 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) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using JetBrains.Annotations; using osu.Framework.Allocation; using osu.Framework.Configuration; using osu.Framework.Graphics; @@ -10,30 +11,26 @@ using osu.Game.Rulesets.UI.Scrolling; namespace osu.Game.Rulesets.Mania.Objects.Drawables { - public abstract class DrawableManiaHitObject : DrawableHitObject - where TObject : ManiaHitObject + public abstract class DrawableManiaHitObject : DrawableHitObject { /// - /// The key that will trigger input for this hit object. + /// The which causes this to be hit. /// - protected ManiaAction Action { get; } - - public new TObject HitObject; + protected readonly IBindable Action = new Bindable(); protected readonly IBindable Direction = new Bindable(); - protected DrawableManiaHitObject(TObject hitObject, ManiaAction? action = null) + protected DrawableManiaHitObject(ManiaHitObject hitObject) : base(hitObject) { - HitObject = hitObject; - - if (action != null) - Action = action.Value; } - [BackgroundDependencyLoader] - private void load(IScrollingInfo scrollingInfo) + [BackgroundDependencyLoader(true)] + private void load([CanBeNull] IBindable action, [NotNull] IScrollingInfo scrollingInfo) { + if (action != null) + Action.BindTo(action); + Direction.BindTo(scrollingInfo.Direction); Direction.BindValueChanged(OnDirectionChanged, true); } @@ -42,6 +39,18 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables { Anchor = Origin = direction == ScrollingDirection.Up ? Anchor.TopCentre : Anchor.BottomCentre; } + } + + public abstract class DrawableManiaHitObject : DrawableManiaHitObject + where TObject : ManiaHitObject + { + public new readonly TObject HitObject; + + protected DrawableManiaHitObject(TObject hitObject) + : base(hitObject) + { + HitObject = hitObject; + } protected override void UpdateState(ArmedState state) { diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs index fb4aa74ad1..18084c4c08 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs @@ -20,8 +20,8 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables { private readonly NotePiece headPiece; - public DrawableNote(Note hitObject, ManiaAction action) - : base(hitObject, action) + public DrawableNote(Note hitObject) + : base(hitObject) { RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; @@ -74,7 +74,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables public virtual bool OnPressed(ManiaAction action) { - if (action != Action) + if (action != Action.Value) return false; return UpdateJudgement(true); diff --git a/osu.Game.Rulesets.Mania/UI/Column.cs b/osu.Game.Rulesets.Mania/UI/Column.cs index e731ce9195..a19a6fb5d4 100644 --- a/osu.Game.Rulesets.Mania/UI/Column.cs +++ b/osu.Game.Rulesets.Mania/UI/Column.cs @@ -7,6 +7,8 @@ using osu.Framework.Graphics.Containers; using osu.Game.Graphics; using osu.Game.Rulesets.Objects.Drawables; using System.Linq; +using osu.Framework.Allocation; +using osu.Framework.Configuration; using osu.Framework.Input.Bindings; using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Mania.UI.Components; @@ -19,21 +21,7 @@ namespace osu.Game.Rulesets.Mania.UI private const float column_width = 45; private const float special_column_width = 70; - private ManiaAction action; - - public ManiaAction Action - { - get => action; - set - { - if (action == value) - return; - action = value; - - background.Action = value; - keyArea.Action = value; - } - } + public readonly Bindable Action = new Bindable(); private readonly ColumnBackground background; private readonly ColumnKeyArea keyArea; @@ -130,6 +118,13 @@ namespace osu.Game.Rulesets.Mania.UI } } + protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) + { + var dependencies = new DependencyContainer(base.CreateLocalDependencies(parent)); + dependencies.CacheAs>(Action); + return dependencies; + } + /// /// Adds a DrawableHitObject to this Playfield. /// diff --git a/osu.Game.Rulesets.Mania/UI/Components/ColumnBackground.cs b/osu.Game.Rulesets.Mania/UI/Components/ColumnBackground.cs index 9b744bd254..19cc8fffef 100644 --- a/osu.Game.Rulesets.Mania/UI/Components/ColumnBackground.cs +++ b/osu.Game.Rulesets.Mania/UI/Components/ColumnBackground.cs @@ -17,7 +17,7 @@ namespace osu.Game.Rulesets.Mania.UI.Components { public class ColumnBackground : CompositeDrawable, IKeyBindingHandler, IHasAccentColour { - public ManiaAction Action; + private readonly IBindable action = new Bindable(); private Box background; private Box backgroundOverlay; @@ -25,8 +25,10 @@ namespace osu.Game.Rulesets.Mania.UI.Components private readonly IBindable direction = new Bindable(); [BackgroundDependencyLoader] - private void load(IScrollingInfo scrollingInfo) + private void load(IBindable action, IScrollingInfo scrollingInfo) { + this.action.BindTo(action); + InternalChildren = new[] { background = new Box @@ -91,14 +93,14 @@ namespace osu.Game.Rulesets.Mania.UI.Components public bool OnPressed(ManiaAction action) { - if (action == Action) + if (action == this.action.Value) backgroundOverlay.FadeTo(1, 50, Easing.OutQuint).Then().FadeTo(0.5f, 250, Easing.OutQuint); return false; } public bool OnReleased(ManiaAction action) { - if (action == Action) + if (action == this.action.Value) backgroundOverlay.FadeTo(0, 250, Easing.OutQuint); return false; } diff --git a/osu.Game.Rulesets.Mania/UI/Components/ColumnKeyArea.cs b/osu.Game.Rulesets.Mania/UI/Components/ColumnKeyArea.cs index 4ce1614310..e30a033831 100644 --- a/osu.Game.Rulesets.Mania/UI/Components/ColumnKeyArea.cs +++ b/osu.Game.Rulesets.Mania/UI/Components/ColumnKeyArea.cs @@ -21,15 +21,16 @@ namespace osu.Game.Rulesets.Mania.UI.Components private const float key_icon_size = 10; private const float key_icon_corner_radius = 3; - public ManiaAction Action; - + private readonly IBindable action = new Bindable(); private readonly IBindable direction = new Bindable(); private Container keyIcon; [BackgroundDependencyLoader] - private void load(IScrollingInfo scrollingInfo) + private void load(IBindable action, IScrollingInfo scrollingInfo) { + this.action.BindTo(action); + Drawable gradient; InternalChildren = new[] @@ -107,14 +108,14 @@ namespace osu.Game.Rulesets.Mania.UI.Components public bool OnPressed(ManiaAction action) { - if (action == Action) + if (action == this.action.Value) keyIcon.ScaleTo(1.4f, 50, Easing.OutQuint).Then().ScaleTo(1.3f, 250, Easing.OutQuint); return false; } public bool OnReleased(ManiaAction action) { - if (action == Action) + if (action == this.action.Value) keyIcon.ScaleTo(1f, 125, Easing.OutQuint); return false; } diff --git a/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs b/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs index fa6fba0cd8..e6ebf43c67 100644 --- a/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs +++ b/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs @@ -101,17 +101,15 @@ namespace osu.Game.Rulesets.Mania.UI protected override DrawableHitObject GetVisualRepresentation(ManiaHitObject h) { - ManiaAction action = Playfield.Columns.ElementAt(h.Column).Action; - - var holdNote = h as HoldNote; - if (holdNote != null) - return new DrawableHoldNote(holdNote, action); - - var note = h as Note; - if (note != null) - return new DrawableNote(note, action); - - return null; + switch (h) + { + case HoldNote holdNote: + return new DrawableHoldNote(holdNote); + case Note note: + return new DrawableNote(note); + default: + return null; + } } protected override Vector2 PlayfieldArea => new Vector2(1, 0.8f); diff --git a/osu.Game.Rulesets.Mania/UI/ManiaStage.cs b/osu.Game.Rulesets.Mania/UI/ManiaStage.cs index 7b68582944..4c7deb4567 100644 --- a/osu.Game.Rulesets.Mania/UI/ManiaStage.cs +++ b/osu.Game.Rulesets.Mania/UI/ManiaStage.cs @@ -127,7 +127,7 @@ namespace osu.Game.Rulesets.Mania.UI var column = new Column(direction) { IsSpecial = isSpecial, - Action = isSpecial ? specialColumnStartAction++ : normalColumnStartAction++ + Action = { Value = isSpecial ? specialColumnStartAction++ : normalColumnStartAction++ } }; AddColumn(column); From b7893bc9947780cd5517fc09ea5ab90d98f66607 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 2 Jul 2018 13:05:09 +0900 Subject: [PATCH 25/30] Remove unnecessary comments --- osu.Game/Beatmaps/WorkingBeatmap.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.Game/Beatmaps/WorkingBeatmap.cs b/osu.Game/Beatmaps/WorkingBeatmap.cs index 1dc90b3d6c..74da978d9c 100644 --- a/osu.Game/Beatmaps/WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/WorkingBeatmap.cs @@ -118,7 +118,6 @@ namespace osu.Game.Beatmaps IBeatmapProcessor processor = rulesetInstance.CreateBeatmapProcessor(converted); - // Pre-process processor?.PreProcess(); // Compute default values for hitobjects, including creating nested hitobjects in-case they're needed @@ -129,7 +128,6 @@ namespace osu.Game.Beatmaps foreach (var obj in converted.HitObjects) mod.ApplyToHitObject(obj); - // Post-process processor?.PostProcess(); return converted; From 9a54bf68542a9e46dcadb04a9a3e0ab193ba3237 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 2 Jul 2018 14:27:42 +0900 Subject: [PATCH 26/30] Revert unnecessary change --- osu.Game/Rulesets/Replays/FramedReplayInputHandler.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Replays/FramedReplayInputHandler.cs b/osu.Game/Rulesets/Replays/FramedReplayInputHandler.cs index 6a1b3f8502..f13d96b35e 100644 --- a/osu.Game/Rulesets/Replays/FramedReplayInputHandler.cs +++ b/osu.Game/Rulesets/Replays/FramedReplayInputHandler.cs @@ -69,7 +69,7 @@ namespace osu.Game.Rulesets.Replays //a button is in a pressed state IsImportant(currentDirection > 0 ? CurrentFrame : NextFrame) && //the next frame is within an allowable time span - Math.Abs(CurrentTime - (NextFrame?.Time ?? 0)) <= sixty_frame_time * 1.2; + Math.Abs(CurrentTime - NextFrame?.Time ?? 0) <= sixty_frame_time * 1.2; protected virtual bool IsImportant(TFrame frame) => false; From 831b11ff974d177dc4b48a6e0c9c7eb42b6566ae Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 2 Jul 2018 14:28:56 +0900 Subject: [PATCH 27/30] Remove unnecessary null checks --- osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapProcessor.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapProcessor.cs b/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapProcessor.cs index 187cad33f6..bbe2d67baa 100644 --- a/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapProcessor.cs +++ b/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapProcessor.cs @@ -44,7 +44,7 @@ namespace osu.Game.Rulesets.Osu.Beatmaps continue; double endTime = (stackBaseObject as IHasEndTime)?.EndTime ?? stackBaseObject.StartTime; - double stackThreshold = objectN.TimePreempt * (beatmap.BeatmapInfo?.StackLeniency ?? 0.7f); + double stackThreshold = objectN.TimePreempt * beatmap.BeatmapInfo.StackLeniency; if (objectN.StartTime - endTime > stackThreshold) //We are no longer within stacking range of the next object. @@ -87,7 +87,7 @@ namespace osu.Game.Rulesets.Osu.Beatmaps OsuHitObject objectI = beatmap.HitObjects[i]; if (objectI.StackHeight != 0 || objectI is Spinner) continue; - double stackThreshold = objectI.TimePreempt * (beatmap.BeatmapInfo?.StackLeniency ?? 0.7f); + double stackThreshold = objectI.TimePreempt * beatmap.BeatmapInfo.StackLeniency; /* If this object is a hitcircle, then we enter this "special" case. * It either ends with a stack of hitcircles only, or a stack of hitcircles that are underneath a slider. From b61fe10f62fd53cf2f63fcfc5532f260bc030b78 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 2 Jul 2018 15:07:13 +0900 Subject: [PATCH 28/30] Adapt to IBindables --- osu.Game/Overlays/Mods/ModSelectOverlay.cs | 4 ++-- osu.Game/Tests/Visual/OsuTestCase.cs | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Mods/ModSelectOverlay.cs b/osu.Game/Overlays/Mods/ModSelectOverlay.cs index 7e4c986810..c584a32a82 100644 --- a/osu.Game/Overlays/Mods/ModSelectOverlay.cs +++ b/osu.Game/Overlays/Mods/ModSelectOverlay.cs @@ -40,7 +40,7 @@ namespace osu.Game.Overlays.Mods public readonly Bindable> SelectedMods = new Bindable>(); - public readonly Bindable Ruleset = new Bindable(); + public readonly IBindable Ruleset = new Bindable(); private void rulesetChanged(RulesetInfo newRuleset) { @@ -52,7 +52,7 @@ namespace osu.Game.Overlays.Mods } [BackgroundDependencyLoader] - private void load(OsuColour colours, Bindable ruleset, AudioManager audio) + private void load(OsuColour colours, IBindable ruleset, AudioManager audio) { SelectedMods.ValueChanged += selectedModsChanged; diff --git a/osu.Game/Tests/Visual/OsuTestCase.cs b/osu.Game/Tests/Visual/OsuTestCase.cs index b3e523b63c..5f70055021 100644 --- a/osu.Game/Tests/Visual/OsuTestCase.cs +++ b/osu.Game/Tests/Visual/OsuTestCase.cs @@ -28,6 +28,7 @@ namespace osu.Game.Tests.Visual Dependencies.CacheAs(beatmap); Dependencies.CacheAs(Ruleset); + Dependencies.CacheAs>(Ruleset); return Dependencies; } From 90d90370c2afc7964fc90574ece2599b1bcf399b Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 2 Jul 2018 15:25:37 +0900 Subject: [PATCH 29/30] Use testcase ruleset --- osu.Game.Tests/Visual/TestCaseMods.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/TestCaseMods.cs b/osu.Game.Tests/Visual/TestCaseMods.cs index 3255478bea..73c37348d5 100644 --- a/osu.Game.Tests/Visual/TestCaseMods.cs +++ b/osu.Game.Tests/Visual/TestCaseMods.cs @@ -77,7 +77,7 @@ namespace osu.Game.Tests.Visual foreach (var rulesetInfo in rulesets.AvailableRulesets) { Ruleset ruleset = rulesetInfo.CreateInstance(); - AddStep($"switch to {ruleset.Description}", () => modSelect.Ruleset.Value = rulesetInfo); + AddStep($"switch to {ruleset.Description}", () => Ruleset.Value = rulesetInfo); switch (ruleset) { From 9f405b0894910d02716545b9b28e39ea52ceca07 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 2 Jul 2018 16:49:07 +0900 Subject: [PATCH 30/30] Don't hard-bail if config skin doesn't exist anymore --- osu.Game/Overlays/Settings/Sections/SkinSection.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Settings/Sections/SkinSection.cs b/osu.Game/Overlays/Settings/Sections/SkinSection.cs index 930b3c1eaa..18a371e904 100644 --- a/osu.Game/Overlays/Settings/Sections/SkinSection.cs +++ b/osu.Game/Overlays/Settings/Sections/SkinSection.cs @@ -56,7 +56,13 @@ namespace osu.Game.Overlays.Settings.Sections reloadSkins(); - skinDropdown.Bindable = config.GetBindable(OsuSetting.Skin); + var skinBindable = config.GetBindable(OsuSetting.Skin); + + // Todo: This should not be necessary when OsuConfigManager is databased + if (skinDropdown.Items.All(s => s.Value != skinBindable.Value)) + skinBindable.Value = 0; + + skinDropdown.Bindable = skinBindable; } private void reloadSkins() => skinDropdown.Items = skins.GetAllUsableSkins().Select(s => new KeyValuePair(s.ToString(), s.ID));