From 0abb48882cdeb636d20aa9030582642458dbb545 Mon Sep 17 00:00:00 2001 From: EVAST9919 Date: Tue, 4 Jun 2019 16:22:54 +0300 Subject: [PATCH 001/148] Implement GamemodeControl --- .../Header/Components/GamemodeControl.cs | 142 ++++++++++++++++++ osu.Game/Overlays/Profile/ProfileHeader.cs | 12 +- 2 files changed, 153 insertions(+), 1 deletion(-) create mode 100644 osu.Game/Overlays/Profile/Header/Components/GamemodeControl.cs diff --git a/osu.Game/Overlays/Profile/Header/Components/GamemodeControl.cs b/osu.Game/Overlays/Profile/Header/Components/GamemodeControl.cs new file mode 100644 index 0000000000..5909082fc8 --- /dev/null +++ b/osu.Game/Overlays/Profile/Header/Components/GamemodeControl.cs @@ -0,0 +1,142 @@ +// 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.UserInterface; +using osu.Framework.Input.Events; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; +using osu.Game.Graphics.UserInterface; +using osu.Game.Rulesets; +using osuTK; +using osuTK.Graphics; + +namespace osu.Game.Overlays.Profile.Header.Components +{ + public class GamemodeControl : TabControl + { + protected override Dropdown CreateDropdown() => null; + + protected override TabItem CreateTabItem(string value) => new GamemodeTabItem(value) + { + AccentColour = AccentColour + }; + + private Color4 accentColour = Color4.White; + + public Color4 AccentColour + { + get => accentColour; + set + { + if (accentColour == value) + return; + + accentColour = value; + + foreach (TabItem tabItem in TabContainer) + { + ((GamemodeTabItem)tabItem).AccentColour = value; + } + } + } + + public GamemodeControl() + { + TabContainer.Masking = false; + TabContainer.Spacing = new Vector2(15, 0); + AutoSizeAxes = Axes.Both; + } + + [BackgroundDependencyLoader] + private void load(RulesetStore rulesets) + { + foreach (var r in rulesets.AvailableRulesets) + AddItem(r.Name); + } + + protected override TabFillFlowContainer CreateTabFlow() => new TabFillFlowContainer + { + Direction = FillDirection.Horizontal, + AutoSizeAxes = Axes.Both, + }; + + private class GamemodeTabItem : TabItem + { + private readonly OsuSpriteText text; + + private Color4 accentColour; + + public Color4 AccentColour + { + get => accentColour; + set + { + if (accentColour == value) + return; + + accentColour = value; + + updateState(); + } + } + + public GamemodeTabItem(string value) + : base(value) + { + AutoSizeAxes = Axes.Both; + + Children = new Drawable[] + { + text = new OsuSpriteText + { + Margin = new MarginPadding { Bottom = 10 }, + Origin = Anchor.BottomLeft, + Anchor = Anchor.BottomLeft, + Text = value, + Font = OsuFont.GetFont() + }, + new HoverClickSounds() + }; + } + + protected override bool OnHover(HoverEvent e) + { + base.OnHover(e); + + updateState(); + + return true; + } + + protected override void OnHoverLost(HoverLostEvent e) + { + base.OnHoverLost(e); + + updateState(); + } + + protected override void OnActivated() => updateState(); + + protected override void OnDeactivated() => updateState(); + + private void updateState() + { + if (Active.Value || IsHovered) + { + text.FadeColour(Color4.White, 120, Easing.InQuad); + + if (Active.Value) + text.Font = text.Font.With(weight: FontWeight.Bold); + } + else + { + text.FadeColour(AccentColour, 120, Easing.InQuad); + text.Font = text.Font.With(weight: FontWeight.Medium); + } + } + } + } +} diff --git a/osu.Game/Overlays/Profile/ProfileHeader.cs b/osu.Game/Overlays/Profile/ProfileHeader.cs index 76613c156d..46751eea25 100644 --- a/osu.Game/Overlays/Profile/ProfileHeader.cs +++ b/osu.Game/Overlays/Profile/ProfileHeader.cs @@ -11,6 +11,7 @@ using osu.Framework.Graphics.Shapes; using osu.Game.Graphics; using osu.Game.Graphics.UserInterface; using osu.Game.Overlays.Profile.Header; +using osu.Game.Overlays.Profile.Header.Components; using osu.Game.Users; namespace osu.Game.Overlays.Profile @@ -18,6 +19,7 @@ namespace osu.Game.Overlays.Profile public class ProfileHeader : OverlayHeader { private UserCoverBackground coverContainer; + private readonly GamemodeControl gamemodeControl; public Bindable User = new Bindable(); @@ -32,12 +34,20 @@ namespace osu.Game.Overlays.Profile TabControl.AddItem("Modding"); centreHeaderContainer.DetailsVisible.BindValueChanged(visible => detailHeaderContainer.Expanded = visible.NewValue, true); + + Add(gamemodeControl = new GamemodeControl + { + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, + Y = 100, + Margin = new MarginPadding { Right = 30 }, + }); } [BackgroundDependencyLoader] private void load(OsuColour colours) { - TabControl.AccentColour = colours.Seafoam; + TabControl.AccentColour = gamemodeControl.AccentColour = colours.Seafoam; } protected override Drawable CreateBackground() => From a0f7f69f463eb8edefd68ed71b94dd74cb8f104d Mon Sep 17 00:00:00 2001 From: EVAST9919 Date: Tue, 4 Jun 2019 17:51:56 +0300 Subject: [PATCH 002/148] retrieve user's default playmode --- .../Header/Components/GamemodeControl.cs | 64 +++++++++++++++++-- osu.Game/Overlays/Profile/ProfileHeader.cs | 12 +++- 2 files changed, 69 insertions(+), 7 deletions(-) diff --git a/osu.Game/Overlays/Profile/Header/Components/GamemodeControl.cs b/osu.Game/Overlays/Profile/Header/Components/GamemodeControl.cs index 5909082fc8..f66023c958 100644 --- a/osu.Game/Overlays/Profile/Header/Components/GamemodeControl.cs +++ b/osu.Game/Overlays/Profile/Header/Components/GamemodeControl.cs @@ -4,6 +4,7 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.UserInterface; using osu.Framework.Input.Events; using osu.Game.Graphics; @@ -46,7 +47,7 @@ namespace osu.Game.Overlays.Profile.Header.Components public GamemodeControl() { TabContainer.Masking = false; - TabContainer.Spacing = new Vector2(15, 0); + TabContainer.Spacing = new Vector2(10, 0); AutoSizeAxes = Axes.Both; } @@ -54,7 +55,20 @@ namespace osu.Game.Overlays.Profile.Header.Components private void load(RulesetStore rulesets) { foreach (var r in rulesets.AvailableRulesets) - AddItem(r.Name); + AddItem(r.ShortName); + //AddItem(r.Name); + } + + public void SetDefaultGamemode(string gamemode) + { + foreach (GamemodeTabItem i in TabContainer) + { + if (i.Value == gamemode) + { + i.IsDefault = true; + return; + } + } } protected override TabFillFlowContainer CreateTabFlow() => new TabFillFlowContainer @@ -66,6 +80,7 @@ namespace osu.Game.Overlays.Profile.Header.Components private class GamemodeTabItem : TabItem { private readonly OsuSpriteText text; + private readonly SpriteIcon icon; private Color4 accentColour; @@ -83,6 +98,22 @@ namespace osu.Game.Overlays.Profile.Header.Components } } + private bool isDefault; + + public bool IsDefault + { + get => isDefault; + set + { + if (isDefault == value) + return; + + isDefault = value; + + icon.FadeTo(isDefault ? 1 : 0, 100, Easing.OutQuint); + } + } + public GamemodeTabItem(string value) : base(value) { @@ -90,13 +121,32 @@ namespace osu.Game.Overlays.Profile.Header.Components Children = new Drawable[] { - text = new OsuSpriteText + new FillFlowContainer { - Margin = new MarginPadding { Bottom = 10 }, + AutoSizeAxes = Axes.Both, Origin = Anchor.BottomLeft, Anchor = Anchor.BottomLeft, - Text = value, - Font = OsuFont.GetFont() + Direction = FillDirection.Horizontal, + Spacing = new Vector2(3, 0), + Children = new Drawable[] + { + text = new OsuSpriteText + { + Origin = Anchor.Centre, + Anchor = Anchor.Centre, + Text = value, + Font = OsuFont.GetFont() + }, + icon = new SpriteIcon + { + Origin = Anchor.Centre, + Anchor = Anchor.Centre, + Alpha = 0, + AlwaysPresent = true, + Icon = FontAwesome.Solid.Star, + Size = new Vector2(12), + }, + } }, new HoverClickSounds() }; @@ -127,6 +177,7 @@ namespace osu.Game.Overlays.Profile.Header.Components if (Active.Value || IsHovered) { text.FadeColour(Color4.White, 120, Easing.InQuad); + icon.FadeColour(Color4.White, 120, Easing.InQuad); if (Active.Value) text.Font = text.Font.With(weight: FontWeight.Bold); @@ -134,6 +185,7 @@ namespace osu.Game.Overlays.Profile.Header.Components else { text.FadeColour(AccentColour, 120, Easing.InQuad); + icon.FadeColour(AccentColour, 120, Easing.InQuad); text.Font = text.Font.With(weight: FontWeight.Medium); } } diff --git a/osu.Game/Overlays/Profile/ProfileHeader.cs b/osu.Game/Overlays/Profile/ProfileHeader.cs index 46751eea25..23a31614a7 100644 --- a/osu.Game/Overlays/Profile/ProfileHeader.cs +++ b/osu.Game/Overlays/Profile/ProfileHeader.cs @@ -37,6 +37,7 @@ namespace osu.Game.Overlays.Profile Add(gamemodeControl = new GamemodeControl { + Alpha = 0, Anchor = Anchor.TopRight, Origin = Anchor.TopRight, Y = 100, @@ -105,7 +106,16 @@ namespace osu.Game.Overlays.Profile protected override ScreenTitle CreateTitle() => new ProfileHeaderTitle(); - private void updateDisplay(User user) => coverContainer.User = user; + private void updateDisplay(User user) + { + coverContainer.User = user; + + string playMode = user.PlayMode; + + gamemodeControl.Current.Value = playMode; + gamemodeControl.SetDefaultGamemode(playMode); + gamemodeControl.FadeInFromZero(100, Easing.OutQuint); + } private class ProfileHeaderTitle : ScreenTitle { From 367fdcf51987368bf3c7a79988f50af4f4cac599 Mon Sep 17 00:00:00 2001 From: EVAST9919 Date: Tue, 4 Jun 2019 18:07:52 +0300 Subject: [PATCH 003/148] Make GamemodeControl depend on rulesets --- .../Header/Components/GamemodeControl.cs | 24 ++++++++++--------- osu.Game/Overlays/Profile/ProfileHeader.cs | 1 - 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/osu.Game/Overlays/Profile/Header/Components/GamemodeControl.cs b/osu.Game/Overlays/Profile/Header/Components/GamemodeControl.cs index f66023c958..d0caeea62e 100644 --- a/osu.Game/Overlays/Profile/Header/Components/GamemodeControl.cs +++ b/osu.Game/Overlays/Profile/Header/Components/GamemodeControl.cs @@ -16,11 +16,11 @@ using osuTK.Graphics; namespace osu.Game.Overlays.Profile.Header.Components { - public class GamemodeControl : TabControl + public class GamemodeControl : TabControl { - protected override Dropdown CreateDropdown() => null; + protected override Dropdown CreateDropdown() => null; - protected override TabItem CreateTabItem(string value) => new GamemodeTabItem(value) + protected override TabItem CreateTabItem(RulesetInfo value) => new GamemodeTabItem(value) { AccentColour = AccentColour }; @@ -37,9 +37,9 @@ namespace osu.Game.Overlays.Profile.Header.Components accentColour = value; - foreach (TabItem tabItem in TabContainer) + foreach (GamemodeTabItem tabItem in TabContainer) { - ((GamemodeTabItem)tabItem).AccentColour = value; + tabItem.AccentColour = value; } } } @@ -55,17 +55,19 @@ namespace osu.Game.Overlays.Profile.Header.Components private void load(RulesetStore rulesets) { foreach (var r in rulesets.AvailableRulesets) - AddItem(r.ShortName); - //AddItem(r.Name); + { + AddItem(r); + } } public void SetDefaultGamemode(string gamemode) { foreach (GamemodeTabItem i in TabContainer) { - if (i.Value == gamemode) + if (i.Value.ShortName == gamemode) { i.IsDefault = true; + Current.Value = i.Value; return; } } @@ -77,7 +79,7 @@ namespace osu.Game.Overlays.Profile.Header.Components AutoSizeAxes = Axes.Both, }; - private class GamemodeTabItem : TabItem + private class GamemodeTabItem : TabItem { private readonly OsuSpriteText text; private readonly SpriteIcon icon; @@ -114,7 +116,7 @@ namespace osu.Game.Overlays.Profile.Header.Components } } - public GamemodeTabItem(string value) + public GamemodeTabItem(RulesetInfo value) : base(value) { AutoSizeAxes = Axes.Both; @@ -134,7 +136,7 @@ namespace osu.Game.Overlays.Profile.Header.Components { Origin = Anchor.Centre, Anchor = Anchor.Centre, - Text = value, + Text = value.Name, Font = OsuFont.GetFont() }, icon = new SpriteIcon diff --git a/osu.Game/Overlays/Profile/ProfileHeader.cs b/osu.Game/Overlays/Profile/ProfileHeader.cs index 23a31614a7..85541cd0ae 100644 --- a/osu.Game/Overlays/Profile/ProfileHeader.cs +++ b/osu.Game/Overlays/Profile/ProfileHeader.cs @@ -112,7 +112,6 @@ namespace osu.Game.Overlays.Profile string playMode = user.PlayMode; - gamemodeControl.Current.Value = playMode; gamemodeControl.SetDefaultGamemode(playMode); gamemodeControl.FadeInFromZero(100, Easing.OutQuint); } From d0d846469a6dcc4fec55767b5252c4eaef1b11f3 Mon Sep 17 00:00:00 2001 From: EVAST9919 Date: Tue, 4 Jun 2019 18:14:03 +0300 Subject: [PATCH 004/148] Move GamemodeTabItem to a distinct class --- .../Header/Components/GamemodeControl.cs | 119 ---------------- .../Header/Components/GamemodeTabItem.cs | 131 ++++++++++++++++++ 2 files changed, 131 insertions(+), 119 deletions(-) create mode 100644 osu.Game/Overlays/Profile/Header/Components/GamemodeTabItem.cs diff --git a/osu.Game/Overlays/Profile/Header/Components/GamemodeControl.cs b/osu.Game/Overlays/Profile/Header/Components/GamemodeControl.cs index d0caeea62e..bca4cd0cfa 100644 --- a/osu.Game/Overlays/Profile/Header/Components/GamemodeControl.cs +++ b/osu.Game/Overlays/Profile/Header/Components/GamemodeControl.cs @@ -4,12 +4,7 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.UserInterface; -using osu.Framework.Input.Events; -using osu.Game.Graphics; -using osu.Game.Graphics.Sprites; -using osu.Game.Graphics.UserInterface; using osu.Game.Rulesets; using osuTK; using osuTK.Graphics; @@ -78,119 +73,5 @@ namespace osu.Game.Overlays.Profile.Header.Components Direction = FillDirection.Horizontal, AutoSizeAxes = Axes.Both, }; - - private class GamemodeTabItem : TabItem - { - private readonly OsuSpriteText text; - private readonly SpriteIcon icon; - - private Color4 accentColour; - - public Color4 AccentColour - { - get => accentColour; - set - { - if (accentColour == value) - return; - - accentColour = value; - - updateState(); - } - } - - private bool isDefault; - - public bool IsDefault - { - get => isDefault; - set - { - if (isDefault == value) - return; - - isDefault = value; - - icon.FadeTo(isDefault ? 1 : 0, 100, Easing.OutQuint); - } - } - - public GamemodeTabItem(RulesetInfo value) - : base(value) - { - AutoSizeAxes = Axes.Both; - - Children = new Drawable[] - { - new FillFlowContainer - { - AutoSizeAxes = Axes.Both, - Origin = Anchor.BottomLeft, - Anchor = Anchor.BottomLeft, - Direction = FillDirection.Horizontal, - Spacing = new Vector2(3, 0), - Children = new Drawable[] - { - text = new OsuSpriteText - { - Origin = Anchor.Centre, - Anchor = Anchor.Centre, - Text = value.Name, - Font = OsuFont.GetFont() - }, - icon = new SpriteIcon - { - Origin = Anchor.Centre, - Anchor = Anchor.Centre, - Alpha = 0, - AlwaysPresent = true, - Icon = FontAwesome.Solid.Star, - Size = new Vector2(12), - }, - } - }, - new HoverClickSounds() - }; - } - - protected override bool OnHover(HoverEvent e) - { - base.OnHover(e); - - updateState(); - - return true; - } - - protected override void OnHoverLost(HoverLostEvent e) - { - base.OnHoverLost(e); - - updateState(); - } - - protected override void OnActivated() => updateState(); - - protected override void OnDeactivated() => updateState(); - - private void updateState() - { - if (Active.Value || IsHovered) - { - text.FadeColour(Color4.White, 120, Easing.InQuad); - icon.FadeColour(Color4.White, 120, Easing.InQuad); - - if (Active.Value) - text.Font = text.Font.With(weight: FontWeight.Bold); - } - else - { - text.FadeColour(AccentColour, 120, Easing.InQuad); - icon.FadeColour(AccentColour, 120, Easing.InQuad); - text.Font = text.Font.With(weight: FontWeight.Medium); - } - } - } } } diff --git a/osu.Game/Overlays/Profile/Header/Components/GamemodeTabItem.cs b/osu.Game/Overlays/Profile/Header/Components/GamemodeTabItem.cs new file mode 100644 index 0000000000..b6e27da522 --- /dev/null +++ b/osu.Game/Overlays/Profile/Header/Components/GamemodeTabItem.cs @@ -0,0 +1,131 @@ +// 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.Sprites; +using osu.Framework.Graphics.UserInterface; +using osu.Framework.Input.Events; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; +using osu.Game.Graphics.UserInterface; +using osu.Game.Rulesets; +using osuTK; +using osuTK.Graphics; + +namespace osu.Game.Overlays.Profile.Header.Components +{ + public class GamemodeTabItem : TabItem + { + private readonly OsuSpriteText text; + private readonly SpriteIcon icon; + + private Color4 accentColour; + + public Color4 AccentColour + { + get => accentColour; + set + { + if (accentColour == value) + return; + + accentColour = value; + + updateState(); + } + } + + private bool isDefault; + + public bool IsDefault + { + get => isDefault; + set + { + if (isDefault == value) + return; + + isDefault = value; + + icon.FadeTo(isDefault ? 1 : 0, 100, Easing.OutQuint); + } + } + + public GamemodeTabItem(RulesetInfo value) + : base(value) + { + AutoSizeAxes = Axes.Both; + + Children = new Drawable[] + { + new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Origin = Anchor.BottomLeft, + Anchor = Anchor.BottomLeft, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(3, 0), + Children = new Drawable[] + { + text = new OsuSpriteText + { + Origin = Anchor.Centre, + Anchor = Anchor.Centre, + Text = value.Name, + Font = OsuFont.GetFont() + }, + icon = new SpriteIcon + { + Origin = Anchor.Centre, + Anchor = Anchor.Centre, + Alpha = 0, + AlwaysPresent = true, + Icon = FontAwesome.Solid.Star, + Size = new Vector2(12), + }, + } + }, + new HoverClickSounds() + }; + } + + protected override bool OnHover(HoverEvent e) + { + base.OnHover(e); + + updateState(); + + return true; + } + + protected override void OnHoverLost(HoverLostEvent e) + { + base.OnHoverLost(e); + + updateState(); + } + + protected override void OnActivated() => updateState(); + + protected override void OnDeactivated() => updateState(); + + private void updateState() + { + if (Active.Value || IsHovered) + { + text.FadeColour(Color4.White, 120, Easing.InQuad); + icon.FadeColour(Color4.White, 120, Easing.InQuad); + + if (Active.Value) + text.Font = text.Font.With(weight: FontWeight.Bold); + } + else + { + text.FadeColour(AccentColour, 120, Easing.InQuad); + icon.FadeColour(AccentColour, 120, Easing.InQuad); + text.Font = text.Font.With(weight: FontWeight.Medium); + } + } + } +} From 0c48aec265275d24cef316e072ec1018a7eac30f Mon Sep 17 00:00:00 2001 From: EVAST9919 Date: Tue, 4 Jun 2019 18:37:31 +0300 Subject: [PATCH 005/148] Split SetDefaultGamemode into two functions --- .../Header/Components/GamemodeControl.cs | 11 +++- .../Header/Components/GamemodeTabItem.cs | 54 +++++++++---------- osu.Game/Overlays/Profile/ProfileHeader.cs | 1 + 3 files changed, 37 insertions(+), 29 deletions(-) diff --git a/osu.Game/Overlays/Profile/Header/Components/GamemodeControl.cs b/osu.Game/Overlays/Profile/Header/Components/GamemodeControl.cs index bca4cd0cfa..59c8ec8ecb 100644 --- a/osu.Game/Overlays/Profile/Header/Components/GamemodeControl.cs +++ b/osu.Game/Overlays/Profile/Header/Components/GamemodeControl.cs @@ -59,9 +59,16 @@ namespace osu.Game.Overlays.Profile.Header.Components { foreach (GamemodeTabItem i in TabContainer) { - if (i.Value.ShortName == gamemode) + i.IsDefault = i.Value.ShortName == gamemode; + } + } + + public void SelectDefaultGamemode() + { + foreach (GamemodeTabItem i in TabContainer) + { + if (i.IsDefault) { - i.IsDefault = true; Current.Value = i.Value; return; } diff --git a/osu.Game/Overlays/Profile/Header/Components/GamemodeTabItem.cs b/osu.Game/Overlays/Profile/Header/Components/GamemodeTabItem.cs index b6e27da522..688109ad2f 100644 --- a/osu.Game/Overlays/Profile/Header/Components/GamemodeTabItem.cs +++ b/osu.Game/Overlays/Profile/Header/Components/GamemodeTabItem.cs @@ -48,7 +48,7 @@ namespace osu.Game.Overlays.Profile.Header.Components isDefault = value; - icon.FadeTo(isDefault ? 1 : 0, 100, Easing.OutQuint); + icon.FadeTo(isDefault ? 1 : 0, 200, Easing.OutQuint); } } @@ -59,34 +59,34 @@ namespace osu.Game.Overlays.Profile.Header.Components Children = new Drawable[] { - new FillFlowContainer + new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Origin = Anchor.BottomLeft, + Anchor = Anchor.BottomLeft, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(3, 0), + Children = new Drawable[] { - AutoSizeAxes = Axes.Both, - Origin = Anchor.BottomLeft, - Anchor = Anchor.BottomLeft, - Direction = FillDirection.Horizontal, - Spacing = new Vector2(3, 0), - Children = new Drawable[] + text = new OsuSpriteText { - text = new OsuSpriteText - { - Origin = Anchor.Centre, - Anchor = Anchor.Centre, - Text = value.Name, - Font = OsuFont.GetFont() - }, - icon = new SpriteIcon - { - Origin = Anchor.Centre, - Anchor = Anchor.Centre, - Alpha = 0, - AlwaysPresent = true, - Icon = FontAwesome.Solid.Star, - Size = new Vector2(12), - }, - } - }, - new HoverClickSounds() + Origin = Anchor.Centre, + Anchor = Anchor.Centre, + Text = value.Name, + Font = OsuFont.GetFont() + }, + icon = new SpriteIcon + { + Origin = Anchor.Centre, + Anchor = Anchor.Centre, + Alpha = 0, + AlwaysPresent = true, + Icon = FontAwesome.Solid.Star, + Size = new Vector2(12), + }, + } + }, + new HoverClickSounds() }; } diff --git a/osu.Game/Overlays/Profile/ProfileHeader.cs b/osu.Game/Overlays/Profile/ProfileHeader.cs index 85541cd0ae..b0c1f9a587 100644 --- a/osu.Game/Overlays/Profile/ProfileHeader.cs +++ b/osu.Game/Overlays/Profile/ProfileHeader.cs @@ -113,6 +113,7 @@ namespace osu.Game.Overlays.Profile string playMode = user.PlayMode; gamemodeControl.SetDefaultGamemode(playMode); + gamemodeControl.SelectDefaultGamemode(); gamemodeControl.FadeInFromZero(100, Easing.OutQuint); } From 8dea191998e901c60b1867bd893bcad44c76e958 Mon Sep 17 00:00:00 2001 From: EVAST9919 Date: Tue, 4 Jun 2019 18:37:41 +0300 Subject: [PATCH 006/148] Add a testcase --- .../Visual/Online/TestSceneGamemodeControl.cs | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 osu.Game.Tests/Visual/Online/TestSceneGamemodeControl.cs diff --git a/osu.Game.Tests/Visual/Online/TestSceneGamemodeControl.cs b/osu.Game.Tests/Visual/Online/TestSceneGamemodeControl.cs new file mode 100644 index 0000000000..02eaef09b8 --- /dev/null +++ b/osu.Game.Tests/Visual/Online/TestSceneGamemodeControl.cs @@ -0,0 +1,48 @@ +// 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.MathUtils; +using osu.Game.Graphics; +using osu.Game.Overlays.Profile.Header.Components; +using osuTK.Graphics; +using System; +using System.Collections.Generic; + +namespace osu.Game.Tests.Visual.Online +{ + public class TestSceneGamemodeControl : OsuTestScene + { + public override IReadOnlyList RequiredTypes => new[] + { + typeof(GamemodeControl), + typeof(GamemodeTabItem), + }; + + private readonly GamemodeControl control; + + public TestSceneGamemodeControl() + { + Child = control = new GamemodeControl + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + }; + + AddStep("set osu! as default", () => control.SetDefaultGamemode("osu")); + AddStep("set mania as default", () => control.SetDefaultGamemode("mania")); + AddStep("set taiko as default", () => control.SetDefaultGamemode("taiko")); + AddStep("set catch as default", () => control.SetDefaultGamemode("fruits")); + AddStep("select default gamemode", () => control.SelectDefaultGamemode()); + + AddStep("set random colour", () => control.AccentColour = new Color4(RNG.NextSingle(), RNG.NextSingle(), RNG.NextSingle(), 1)); + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + control.AccentColour = colours.Seafoam; + } + } +} From 8260b61db5ecc418a937a83303b49bcdd245570c Mon Sep 17 00:00:00 2001 From: EVAST9919 Date: Tue, 4 Jun 2019 19:02:09 +0300 Subject: [PATCH 007/148] Fix CI issues --- .../Profile/Header/Components/GamemodeControl.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/osu.Game/Overlays/Profile/Header/Components/GamemodeControl.cs b/osu.Game/Overlays/Profile/Header/Components/GamemodeControl.cs index 59c8ec8ecb..3beee674fd 100644 --- a/osu.Game/Overlays/Profile/Header/Components/GamemodeControl.cs +++ b/osu.Game/Overlays/Profile/Header/Components/GamemodeControl.cs @@ -32,9 +32,9 @@ namespace osu.Game.Overlays.Profile.Header.Components accentColour = value; - foreach (GamemodeTabItem tabItem in TabContainer) + foreach (TabItem tabItem in TabContainer) { - tabItem.AccentColour = value; + ((GamemodeTabItem)tabItem).AccentColour = value; } } } @@ -57,19 +57,19 @@ namespace osu.Game.Overlays.Profile.Header.Components public void SetDefaultGamemode(string gamemode) { - foreach (GamemodeTabItem i in TabContainer) + foreach (TabItem tabItem in TabContainer) { - i.IsDefault = i.Value.ShortName == gamemode; + ((GamemodeTabItem)tabItem).IsDefault = ((GamemodeTabItem)tabItem).Value.ShortName == gamemode; } } public void SelectDefaultGamemode() { - foreach (GamemodeTabItem i in TabContainer) + foreach (TabItem tabItem in TabContainer) { - if (i.IsDefault) + if (((GamemodeTabItem)tabItem).IsDefault) { - Current.Value = i.Value; + Current.Value = ((GamemodeTabItem)tabItem).Value; return; } } From e9403bf2f7a59987bfccc8a97c692d1519f19e21 Mon Sep 17 00:00:00 2001 From: EVAST9919 Date: Tue, 4 Jun 2019 19:33:55 +0300 Subject: [PATCH 008/148] Move GamemodeControl to UserProfileOverlay --- .../Visual/Online/TestSceneGamemodeControl.cs | 8 ------- .../Header/Components/GamemodeControl.cs | 5 +++- osu.Game/Overlays/Profile/ProfileHeader.cs | 24 ++----------------- osu.Game/Overlays/UserProfileOverlay.cs | 20 ++++++++++++++-- 4 files changed, 24 insertions(+), 33 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneGamemodeControl.cs b/osu.Game.Tests/Visual/Online/TestSceneGamemodeControl.cs index 02eaef09b8..7e3ddbfd3d 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneGamemodeControl.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneGamemodeControl.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 osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.MathUtils; -using osu.Game.Graphics; using osu.Game.Overlays.Profile.Header.Components; using osuTK.Graphics; using System; @@ -38,11 +36,5 @@ namespace osu.Game.Tests.Visual.Online AddStep("set random colour", () => control.AccentColour = new Color4(RNG.NextSingle(), RNG.NextSingle(), RNG.NextSingle(), 1)); } - - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { - control.AccentColour = colours.Seafoam; - } } } diff --git a/osu.Game/Overlays/Profile/Header/Components/GamemodeControl.cs b/osu.Game/Overlays/Profile/Header/Components/GamemodeControl.cs index 3beee674fd..56f84741f3 100644 --- a/osu.Game/Overlays/Profile/Header/Components/GamemodeControl.cs +++ b/osu.Game/Overlays/Profile/Header/Components/GamemodeControl.cs @@ -5,6 +5,7 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.UserInterface; +using osu.Game.Graphics; using osu.Game.Rulesets; using osuTK; using osuTK.Graphics; @@ -47,12 +48,14 @@ namespace osu.Game.Overlays.Profile.Header.Components } [BackgroundDependencyLoader] - private void load(RulesetStore rulesets) + private void load(RulesetStore rulesets, OsuColour colours) { foreach (var r in rulesets.AvailableRulesets) { AddItem(r); } + + AccentColour = colours.Seafoam; } public void SetDefaultGamemode(string gamemode) diff --git a/osu.Game/Overlays/Profile/ProfileHeader.cs b/osu.Game/Overlays/Profile/ProfileHeader.cs index b0c1f9a587..76613c156d 100644 --- a/osu.Game/Overlays/Profile/ProfileHeader.cs +++ b/osu.Game/Overlays/Profile/ProfileHeader.cs @@ -11,7 +11,6 @@ using osu.Framework.Graphics.Shapes; using osu.Game.Graphics; using osu.Game.Graphics.UserInterface; using osu.Game.Overlays.Profile.Header; -using osu.Game.Overlays.Profile.Header.Components; using osu.Game.Users; namespace osu.Game.Overlays.Profile @@ -19,7 +18,6 @@ namespace osu.Game.Overlays.Profile public class ProfileHeader : OverlayHeader { private UserCoverBackground coverContainer; - private readonly GamemodeControl gamemodeControl; public Bindable User = new Bindable(); @@ -34,21 +32,12 @@ namespace osu.Game.Overlays.Profile TabControl.AddItem("Modding"); centreHeaderContainer.DetailsVisible.BindValueChanged(visible => detailHeaderContainer.Expanded = visible.NewValue, true); - - Add(gamemodeControl = new GamemodeControl - { - Alpha = 0, - Anchor = Anchor.TopRight, - Origin = Anchor.TopRight, - Y = 100, - Margin = new MarginPadding { Right = 30 }, - }); } [BackgroundDependencyLoader] private void load(OsuColour colours) { - TabControl.AccentColour = gamemodeControl.AccentColour = colours.Seafoam; + TabControl.AccentColour = colours.Seafoam; } protected override Drawable CreateBackground() => @@ -106,16 +95,7 @@ namespace osu.Game.Overlays.Profile protected override ScreenTitle CreateTitle() => new ProfileHeaderTitle(); - private void updateDisplay(User user) - { - coverContainer.User = user; - - string playMode = user.PlayMode; - - gamemodeControl.SetDefaultGamemode(playMode); - gamemodeControl.SelectDefaultGamemode(); - gamemodeControl.FadeInFromZero(100, Easing.OutQuint); - } + private void updateDisplay(User user) => coverContainer.User = user; private class ProfileHeaderTitle : ScreenTitle { diff --git a/osu.Game/Overlays/UserProfileOverlay.cs b/osu.Game/Overlays/UserProfileOverlay.cs index 8a133a1d1e..f61ca0affc 100644 --- a/osu.Game/Overlays/UserProfileOverlay.cs +++ b/osu.Game/Overlays/UserProfileOverlay.cs @@ -11,6 +11,7 @@ using osu.Game.Graphics.Containers; using osu.Game.Graphics.UserInterface; using osu.Game.Online.API.Requests; using osu.Game.Overlays.Profile; +using osu.Game.Overlays.Profile.Header.Components; using osu.Game.Overlays.Profile.Sections; using osu.Game.Users; using osuTK; @@ -25,6 +26,7 @@ namespace osu.Game.Overlays protected ProfileHeader Header; private SectionsContainer sectionsContainer; private ProfileTabControl tabs; + private GamemodeControl gamemodeControl; public const float CONTENT_X_MARGIN = 70; @@ -32,7 +34,8 @@ namespace osu.Game.Overlays public void ShowUser(User user, bool fetchOnline = true) { - if (user == User.SYSTEM_USER) return; + if (user == User.SYSTEM_USER) + return; Show(); @@ -77,7 +80,7 @@ namespace osu.Game.Overlays { Colour = OsuColour.Gray(34), RelativeSizeAxes = Axes.Both - } + }, }); sectionsContainer.SelectedSection.ValueChanged += section => { @@ -118,6 +121,15 @@ namespace osu.Game.Overlays } sectionsContainer.ScrollToTop(); + + Header.Add(gamemodeControl = new GamemodeControl + { + Alpha = 0, + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, + Y = 100, + Margin = new MarginPadding { Right = 30 }, + }); } private void userLoadComplete(User user) @@ -139,6 +151,10 @@ namespace osu.Game.Overlays } } } + + gamemodeControl.SetDefaultGamemode(user.PlayMode); + gamemodeControl.SelectDefaultGamemode(); + gamemodeControl.FadeInFromZero(100, Easing.OutQuint); } private class ProfileTabControl : PageTabControl From 54800aa4dfb932bb751366f967251f5b07423a30 Mon Sep 17 00:00:00 2001 From: EVAST9919 Date: Tue, 4 Jun 2019 19:45:46 +0300 Subject: [PATCH 009/148] make the variable local --- osu.Game.Tests/Visual/Online/TestSceneGamemodeControl.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneGamemodeControl.cs b/osu.Game.Tests/Visual/Online/TestSceneGamemodeControl.cs index 7e3ddbfd3d..a2a75566d5 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneGamemodeControl.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneGamemodeControl.cs @@ -18,10 +18,10 @@ namespace osu.Game.Tests.Visual.Online typeof(GamemodeTabItem), }; - private readonly GamemodeControl control; - public TestSceneGamemodeControl() { + GamemodeControl control; + Child = control = new GamemodeControl { Anchor = Anchor.Centre, @@ -32,7 +32,7 @@ namespace osu.Game.Tests.Visual.Online AddStep("set mania as default", () => control.SetDefaultGamemode("mania")); AddStep("set taiko as default", () => control.SetDefaultGamemode("taiko")); AddStep("set catch as default", () => control.SetDefaultGamemode("fruits")); - AddStep("select default gamemode", () => control.SelectDefaultGamemode()); + AddStep("select default gamemode", control.SelectDefaultGamemode); AddStep("set random colour", () => control.AccentColour = new Color4(RNG.NextSingle(), RNG.NextSingle(), RNG.NextSingle(), 1)); } From 05aeb6697393cf6dcbd0cf14afc25c957991c24f Mon Sep 17 00:00:00 2001 From: EVAST9919 Date: Tue, 4 Jun 2019 20:20:07 +0300 Subject: [PATCH 010/148] Fix possible crash due to null user or playmode --- osu.Game/Overlays/UserProfileOverlay.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/UserProfileOverlay.cs b/osu.Game/Overlays/UserProfileOverlay.cs index f61ca0affc..58d1fe4046 100644 --- a/osu.Game/Overlays/UserProfileOverlay.cs +++ b/osu.Game/Overlays/UserProfileOverlay.cs @@ -152,8 +152,9 @@ namespace osu.Game.Overlays } } - gamemodeControl.SetDefaultGamemode(user.PlayMode); + gamemodeControl.SetDefaultGamemode(user?.PlayMode ?? "osu"); gamemodeControl.SelectDefaultGamemode(); + gamemodeControl.FadeInFromZero(100, Easing.OutQuint); } From e20a8992655f86b57ed442fda10c011435773482 Mon Sep 17 00:00:00 2001 From: EVAST9919 Date: Tue, 4 Jun 2019 21:46:43 +0300 Subject: [PATCH 011/148] remove excessive null check --- osu.Game/Overlays/UserProfileOverlay.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/UserProfileOverlay.cs b/osu.Game/Overlays/UserProfileOverlay.cs index 58d1fe4046..1d8775ad04 100644 --- a/osu.Game/Overlays/UserProfileOverlay.cs +++ b/osu.Game/Overlays/UserProfileOverlay.cs @@ -152,7 +152,7 @@ namespace osu.Game.Overlays } } - gamemodeControl.SetDefaultGamemode(user?.PlayMode ?? "osu"); + gamemodeControl.SetDefaultGamemode(user.PlayMode ?? "osu"); gamemodeControl.SelectDefaultGamemode(); gamemodeControl.FadeInFromZero(100, Easing.OutQuint); From 923f9fb6cdb1b2480420c43448ff048596023ffe Mon Sep 17 00:00:00 2001 From: EVAST9919 Date: Fri, 7 Jun 2019 01:43:26 +0300 Subject: [PATCH 012/148] Naming adjustments --- .../Visual/Online/TestSceneGamemodeControl.cs | 40 ------------------- .../Online/TestSceneProfileRulesetSelector.cs | 40 +++++++++++++++++++ ...deControl.cs => ProfileRulesetSelector.cs} | 14 +++---- .../{GamemodeTabItem.cs => RulesetTabItem.cs} | 4 +- osu.Game/Overlays/UserProfileOverlay.cs | 10 ++--- 5 files changed, 54 insertions(+), 54 deletions(-) delete mode 100644 osu.Game.Tests/Visual/Online/TestSceneGamemodeControl.cs create mode 100644 osu.Game.Tests/Visual/Online/TestSceneProfileRulesetSelector.cs rename osu.Game/Overlays/Profile/Header/Components/{GamemodeControl.cs => ProfileRulesetSelector.cs} (82%) rename osu.Game/Overlays/Profile/Header/Components/{GamemodeTabItem.cs => RulesetTabItem.cs} (97%) diff --git a/osu.Game.Tests/Visual/Online/TestSceneGamemodeControl.cs b/osu.Game.Tests/Visual/Online/TestSceneGamemodeControl.cs deleted file mode 100644 index a2a75566d5..0000000000 --- a/osu.Game.Tests/Visual/Online/TestSceneGamemodeControl.cs +++ /dev/null @@ -1,40 +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.Framework.MathUtils; -using osu.Game.Overlays.Profile.Header.Components; -using osuTK.Graphics; -using System; -using System.Collections.Generic; - -namespace osu.Game.Tests.Visual.Online -{ - public class TestSceneGamemodeControl : OsuTestScene - { - public override IReadOnlyList RequiredTypes => new[] - { - typeof(GamemodeControl), - typeof(GamemodeTabItem), - }; - - public TestSceneGamemodeControl() - { - GamemodeControl control; - - Child = control = new GamemodeControl - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - }; - - AddStep("set osu! as default", () => control.SetDefaultGamemode("osu")); - AddStep("set mania as default", () => control.SetDefaultGamemode("mania")); - AddStep("set taiko as default", () => control.SetDefaultGamemode("taiko")); - AddStep("set catch as default", () => control.SetDefaultGamemode("fruits")); - AddStep("select default gamemode", control.SelectDefaultGamemode); - - AddStep("set random colour", () => control.AccentColour = new Color4(RNG.NextSingle(), RNG.NextSingle(), RNG.NextSingle(), 1)); - } - } -} diff --git a/osu.Game.Tests/Visual/Online/TestSceneProfileRulesetSelector.cs b/osu.Game.Tests/Visual/Online/TestSceneProfileRulesetSelector.cs new file mode 100644 index 0000000000..687cbbebad --- /dev/null +++ b/osu.Game.Tests/Visual/Online/TestSceneProfileRulesetSelector.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.MathUtils; +using osu.Game.Overlays.Profile.Header.Components; +using osuTK.Graphics; +using System; +using System.Collections.Generic; + +namespace osu.Game.Tests.Visual.Online +{ + public class TestSceneProfileRulesetSelector : OsuTestScene + { + public override IReadOnlyList RequiredTypes => new[] + { + typeof(ProfileRulesetSelector), + typeof(RulesetTabItem), + }; + + public TestSceneProfileRulesetSelector() + { + ProfileRulesetSelector selector; + + Child = selector = new ProfileRulesetSelector + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + }; + + AddStep("set osu! as default", () => selector.SetDefaultGamemode("osu")); + AddStep("set mania as default", () => selector.SetDefaultGamemode("mania")); + AddStep("set taiko as default", () => selector.SetDefaultGamemode("taiko")); + AddStep("set catch as default", () => selector.SetDefaultGamemode("fruits")); + AddStep("select default gamemode", selector.SelectDefaultGamemode); + + AddStep("set random colour", () => selector.AccentColour = new Color4(RNG.NextSingle(), RNG.NextSingle(), RNG.NextSingle(), 1)); + } + } +} diff --git a/osu.Game/Overlays/Profile/Header/Components/GamemodeControl.cs b/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetSelector.cs similarity index 82% rename from osu.Game/Overlays/Profile/Header/Components/GamemodeControl.cs rename to osu.Game/Overlays/Profile/Header/Components/ProfileRulesetSelector.cs index 56f84741f3..b189878b0d 100644 --- a/osu.Game/Overlays/Profile/Header/Components/GamemodeControl.cs +++ b/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetSelector.cs @@ -12,11 +12,11 @@ using osuTK.Graphics; namespace osu.Game.Overlays.Profile.Header.Components { - public class GamemodeControl : TabControl + public class ProfileRulesetSelector : TabControl { protected override Dropdown CreateDropdown() => null; - protected override TabItem CreateTabItem(RulesetInfo value) => new GamemodeTabItem(value) + protected override TabItem CreateTabItem(RulesetInfo value) => new RulesetTabItem(value) { AccentColour = AccentColour }; @@ -35,12 +35,12 @@ namespace osu.Game.Overlays.Profile.Header.Components foreach (TabItem tabItem in TabContainer) { - ((GamemodeTabItem)tabItem).AccentColour = value; + ((RulesetTabItem)tabItem).AccentColour = value; } } } - public GamemodeControl() + public ProfileRulesetSelector() { TabContainer.Masking = false; TabContainer.Spacing = new Vector2(10, 0); @@ -62,7 +62,7 @@ namespace osu.Game.Overlays.Profile.Header.Components { foreach (TabItem tabItem in TabContainer) { - ((GamemodeTabItem)tabItem).IsDefault = ((GamemodeTabItem)tabItem).Value.ShortName == gamemode; + ((RulesetTabItem)tabItem).IsDefault = ((RulesetTabItem)tabItem).Value.ShortName == gamemode; } } @@ -70,9 +70,9 @@ namespace osu.Game.Overlays.Profile.Header.Components { foreach (TabItem tabItem in TabContainer) { - if (((GamemodeTabItem)tabItem).IsDefault) + if (((RulesetTabItem)tabItem).IsDefault) { - Current.Value = ((GamemodeTabItem)tabItem).Value; + Current.Value = ((RulesetTabItem)tabItem).Value; return; } } diff --git a/osu.Game/Overlays/Profile/Header/Components/GamemodeTabItem.cs b/osu.Game/Overlays/Profile/Header/Components/RulesetTabItem.cs similarity index 97% rename from osu.Game/Overlays/Profile/Header/Components/GamemodeTabItem.cs rename to osu.Game/Overlays/Profile/Header/Components/RulesetTabItem.cs index 688109ad2f..0a6f2f5123 100644 --- a/osu.Game/Overlays/Profile/Header/Components/GamemodeTabItem.cs +++ b/osu.Game/Overlays/Profile/Header/Components/RulesetTabItem.cs @@ -15,7 +15,7 @@ using osuTK.Graphics; namespace osu.Game.Overlays.Profile.Header.Components { - public class GamemodeTabItem : TabItem + public class RulesetTabItem : TabItem { private readonly OsuSpriteText text; private readonly SpriteIcon icon; @@ -52,7 +52,7 @@ namespace osu.Game.Overlays.Profile.Header.Components } } - public GamemodeTabItem(RulesetInfo value) + public RulesetTabItem(RulesetInfo value) : base(value) { AutoSizeAxes = Axes.Both; diff --git a/osu.Game/Overlays/UserProfileOverlay.cs b/osu.Game/Overlays/UserProfileOverlay.cs index 1d8775ad04..ec81193896 100644 --- a/osu.Game/Overlays/UserProfileOverlay.cs +++ b/osu.Game/Overlays/UserProfileOverlay.cs @@ -26,7 +26,7 @@ namespace osu.Game.Overlays protected ProfileHeader Header; private SectionsContainer sectionsContainer; private ProfileTabControl tabs; - private GamemodeControl gamemodeControl; + private ProfileRulesetSelector rulesetSelector; public const float CONTENT_X_MARGIN = 70; @@ -122,7 +122,7 @@ namespace osu.Game.Overlays sectionsContainer.ScrollToTop(); - Header.Add(gamemodeControl = new GamemodeControl + Header.Add(rulesetSelector = new ProfileRulesetSelector { Alpha = 0, Anchor = Anchor.TopRight, @@ -152,10 +152,10 @@ namespace osu.Game.Overlays } } - gamemodeControl.SetDefaultGamemode(user.PlayMode ?? "osu"); - gamemodeControl.SelectDefaultGamemode(); + rulesetSelector.SetDefaultGamemode(user.PlayMode ?? "osu"); + rulesetSelector.SelectDefaultGamemode(); - gamemodeControl.FadeInFromZero(100, Easing.OutQuint); + rulesetSelector.FadeInFromZero(100, Easing.OutQuint); } private class ProfileTabControl : PageTabControl From d1d3cfa991b6a3c9c64b5b82128ecebfe7180fa4 Mon Sep 17 00:00:00 2001 From: EVAST9919 Date: Sat, 8 Jun 2019 11:55:52 +0300 Subject: [PATCH 013/148] Remove ruleset selector from the user overlay --- osu.Game/Overlays/UserProfileOverlay.cs | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/osu.Game/Overlays/UserProfileOverlay.cs b/osu.Game/Overlays/UserProfileOverlay.cs index ec81193896..70ce83806e 100644 --- a/osu.Game/Overlays/UserProfileOverlay.cs +++ b/osu.Game/Overlays/UserProfileOverlay.cs @@ -11,7 +11,6 @@ using osu.Game.Graphics.Containers; using osu.Game.Graphics.UserInterface; using osu.Game.Online.API.Requests; using osu.Game.Overlays.Profile; -using osu.Game.Overlays.Profile.Header.Components; using osu.Game.Overlays.Profile.Sections; using osu.Game.Users; using osuTK; @@ -26,7 +25,6 @@ namespace osu.Game.Overlays protected ProfileHeader Header; private SectionsContainer sectionsContainer; private ProfileTabControl tabs; - private ProfileRulesetSelector rulesetSelector; public const float CONTENT_X_MARGIN = 70; @@ -121,15 +119,6 @@ namespace osu.Game.Overlays } sectionsContainer.ScrollToTop(); - - Header.Add(rulesetSelector = new ProfileRulesetSelector - { - Alpha = 0, - Anchor = Anchor.TopRight, - Origin = Anchor.TopRight, - Y = 100, - Margin = new MarginPadding { Right = 30 }, - }); } private void userLoadComplete(User user) @@ -151,11 +140,6 @@ namespace osu.Game.Overlays } } } - - rulesetSelector.SetDefaultGamemode(user.PlayMode ?? "osu"); - rulesetSelector.SelectDefaultGamemode(); - - rulesetSelector.FadeInFromZero(100, Easing.OutQuint); } private class ProfileTabControl : PageTabControl From 06dfa42a5ad09ca8ca31f128d433e56a0dc900cb Mon Sep 17 00:00:00 2001 From: EVAST9919 Date: Sat, 8 Jun 2019 18:27:40 +0300 Subject: [PATCH 014/148] Refactor --- .../Overlays/Toolbar/ToolbarRulesetButton.cs | 73 +++++++------ .../Toolbar/ToolbarRulesetSelector.cs | 101 +++++++++--------- 2 files changed, 90 insertions(+), 84 deletions(-) diff --git a/osu.Game/Overlays/Toolbar/ToolbarRulesetButton.cs b/osu.Game/Overlays/Toolbar/ToolbarRulesetButton.cs index 87b18ba9f4..efb540cd45 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarRulesetButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarRulesetButton.cs @@ -2,57 +2,68 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Graphics.Effects; +using osu.Framework.Graphics.UserInterface; using osu.Game.Rulesets; using osuTK.Graphics; +using osu.Framework.Graphics; namespace osu.Game.Overlays.Toolbar { - public class ToolbarRulesetButton : ToolbarButton + public class ToolbarRulesetButton : TabItem { - private RulesetInfo ruleset; + private readonly DrawableRuleset ruleset; - public RulesetInfo Ruleset + public ToolbarRulesetButton(RulesetInfo value) + : base(value) { - get => ruleset; - set + AutoSizeAxes = Axes.X; + RelativeSizeAxes = Axes.Y; + Child = ruleset = new DrawableRuleset { - ruleset = value; + Active = false, + }; - var rInstance = ruleset.CreateInstance(); + var rInstance = value.CreateInstance(); - TooltipMain = rInstance.Description; - TooltipSub = $"Play some {rInstance.Description}"; - SetIcon(rInstance.CreateIcon()); - } + ruleset.TooltipMain = rInstance.Description; + ruleset.TooltipSub = $"Play some {rInstance.Description}"; + ruleset.SetIcon(rInstance.CreateIcon()); } - public bool Active + protected override void OnActivated() => ruleset.Active = true; + + protected override void OnDeactivated() => ruleset.Active = false; + + private class DrawableRuleset : ToolbarButton { - set + public bool Active { - if (value) + set { - IconContainer.Colour = Color4.White; - IconContainer.EdgeEffect = new EdgeEffectParameters + if (value) { - Type = EdgeEffectType.Glow, - Colour = new Color4(255, 194, 224, 100), - Radius = 15, - Roundness = 15, - }; - } - else - { - IconContainer.Colour = new Color4(255, 194, 224, 255); - IconContainer.EdgeEffect = new EdgeEffectParameters(); + IconContainer.Colour = Color4.White; + IconContainer.EdgeEffect = new EdgeEffectParameters + { + Type = EdgeEffectType.Glow, + Colour = new Color4(255, 194, 224, 100), + Radius = 15, + Roundness = 15, + }; + } + else + { + IconContainer.Colour = new Color4(255, 194, 224, 255); + IconContainer.EdgeEffect = new EdgeEffectParameters(); + } } } - } - protected override void LoadComplete() - { - base.LoadComplete(); - IconContainer.Scale *= 1.4f; + protected override void LoadComplete() + { + base.LoadComplete(); + IconContainer.Scale *= 1.4f; + } } } } diff --git a/osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.cs b/osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.cs index 90412ec1d1..abea9b217d 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.cs @@ -1,53 +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 System.Linq; using osu.Framework.Allocation; -using osu.Framework.Bindables; using osu.Framework.Caching; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Effects; using osuTK; -using osuTK.Input; using osuTK.Graphics; using osu.Framework.Graphics.Shapes; -using osu.Framework.Input.Events; using osu.Game.Rulesets; +using osu.Framework.Graphics.UserInterface; +using osu.Framework.Bindables; +using osu.Framework.Input.Events; +using osuTK.Input; +using System.Linq; namespace osu.Game.Overlays.Toolbar { - public class ToolbarRulesetSelector : Container + public class ToolbarRulesetSelector : TabControl { private const float padding = 10; - - private readonly FillFlowContainer modeButtons; private readonly Drawable modeButtonLine; - private ToolbarRulesetButton activeButton; - private RulesetStore rulesets; - private readonly Bindable ruleset = new Bindable(); + + public override bool HandleNonPositionalInput => !Current.Disabled && base.HandleNonPositionalInput; + public override bool HandlePositionalInput => !Current.Disabled && base.HandlePositionalInput; + + public override bool PropagatePositionalInputSubTree => !Current.Disabled && base.PropagatePositionalInputSubTree; + + private void disabledChanged(bool isDisabled) => this.FadeColour(isDisabled ? Color4.Gray : Color4.White, 300); + + protected override Dropdown CreateDropdown() => null; + + protected override TabItem CreateTabItem(RulesetInfo value) => new ToolbarRulesetButton(value); public ToolbarRulesetSelector() { RelativeSizeAxes = Axes.Y; AutoSizeAxes = Axes.X; - Children = new[] + AddRangeInternal(new Drawable[] { - new OpaqueBackground(), - modeButtons = new FillFlowContainer + new OpaqueBackground { - RelativeSizeAxes = Axes.Y, - AutoSizeAxes = Axes.X, - Direction = FillDirection.Horizontal, - Anchor = Anchor.TopCentre, - Origin = Anchor.TopCentre, - Padding = new MarginPadding { Left = padding, Right = padding }, + Depth = 1, }, modeButtonLine = new Container { - Size = new Vector2(padding * 2 + ToolbarButton.WIDTH, 3), + Size = new Vector2(padding* 2 + ToolbarButton.WIDTH, 3), Anchor = Anchor.BottomLeft, Origin = Anchor.TopLeft, Masking = true, @@ -58,17 +59,22 @@ namespace osu.Game.Overlays.Toolbar Radius = 15, Roundness = 15, }, - Children = new[] + Child = new Box { - new Box - { - RelativeSizeAxes = Axes.Both, - } + RelativeSizeAxes = Axes.Both, } } - }; + }); } + protected override TabFillFlowContainer CreateTabFlow() => new TabFillFlowContainer + { + RelativeSizeAxes = Axes.Y, + AutoSizeAxes = Axes.X, + Direction = FillDirection.Horizontal, + Padding = new MarginPadding { Left = padding, Right = padding }, + }; + [BackgroundDependencyLoader] private void load(RulesetStore rulesets, Bindable parentRuleset) { @@ -76,16 +82,13 @@ namespace osu.Game.Overlays.Toolbar foreach (var r in rulesets.AvailableRulesets) { - modeButtons.Add(new ToolbarRulesetButton - { - Ruleset = r, - Action = delegate { ruleset.Value = r; } - }); + AddItem(r); } - ruleset.ValueChanged += rulesetChanged; - ruleset.DisabledChanged += disabledChanged; - ruleset.BindTo(parentRuleset); + Current.BindTo(parentRuleset); + Current.Disabled = false; + Current.DisabledChanged += disabledChanged; + Current.BindValueChanged(rulesetChanged); } protected override bool OnKeyDown(KeyDownEvent e) @@ -98,43 +101,35 @@ namespace osu.Game.Overlays.Toolbar RulesetInfo found = rulesets.AvailableRulesets.Skip(requested).FirstOrDefault(); if (found != null) - ruleset.Value = found; + Current.Value = found; return true; } return false; } - public override bool HandleNonPositionalInput => !ruleset.Disabled && base.HandleNonPositionalInput; - public override bool HandlePositionalInput => !ruleset.Disabled && base.HandlePositionalInput; - - public override bool PropagatePositionalInputSubTree => !ruleset.Disabled && base.PropagatePositionalInputSubTree; - - private void disabledChanged(bool isDisabled) => this.FadeColour(isDisabled ? Color4.Gray : Color4.White, 300); + private readonly Cached activeMode = new Cached(); private void rulesetChanged(ValueChangedEvent e) { - foreach (ToolbarRulesetButton m in modeButtons.Children.Cast()) - { - bool isActive = m.Ruleset.ID == e.NewValue.ID; - m.Active = isActive; - if (isActive) - activeButton = m; - } - activeMode.Invalidate(); } - private Cached activeMode = new Cached(); - protected override void UpdateAfterChildren() { base.UpdateAfterChildren(); if (!activeMode.IsValid) { - modeButtonLine.MoveToX(activeButton.DrawPosition.X, 200, Easing.OutQuint); - activeMode.Validate(); + foreach (TabItem tabItem in TabContainer) + { + if (tabItem.Value == Current.Value) + { + modeButtonLine.MoveToX(tabItem.DrawPosition.X, 200, Easing.OutQuint); + activeMode.Validate(); + return; + } + } } } } From 62eadf21c96964fa52f748d8b3a128f6c282c000 Mon Sep 17 00:00:00 2001 From: EVAST9919 Date: Sat, 8 Jun 2019 18:38:52 +0300 Subject: [PATCH 015/148] Remove useless line --- osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.cs b/osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.cs index abea9b217d..8590c9fbc0 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.cs @@ -86,7 +86,6 @@ namespace osu.Game.Overlays.Toolbar } Current.BindTo(parentRuleset); - Current.Disabled = false; Current.DisabledChanged += disabledChanged; Current.BindValueChanged(rulesetChanged); } From 9b8540d8180b9485c13f3043226f1840c07e8df6 Mon Sep 17 00:00:00 2001 From: EVAST9919 Date: Mon, 10 Jun 2019 03:35:00 +0300 Subject: [PATCH 016/148] Add a testcase --- .../TestSceneToolbarRulesetSelector.cs | 35 +++++++++++++++++++ .../Toolbar/ToolbarRulesetSelector.cs | 4 +-- 2 files changed, 37 insertions(+), 2 deletions(-) create mode 100644 osu.Game.Tests/Visual/UserInterface/TestSceneToolbarRulesetSelector.cs diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneToolbarRulesetSelector.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneToolbarRulesetSelector.cs new file mode 100644 index 0000000000..1a0e712337 --- /dev/null +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneToolbarRulesetSelector.cs @@ -0,0 +1,35 @@ +// 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.Containers; +using osu.Game.Overlays.Toolbar; +using System; +using System.Collections.Generic; +using osu.Framework.Graphics; + +namespace osu.Game.Tests.Visual.UserInterface +{ + public class TestSceneToolbarRulesetSelector : OsuTestScene + { + public override IReadOnlyList RequiredTypes => new[] + { + typeof(ToolbarRulesetSelector), + typeof(ToolbarRulesetButton), + }; + + public TestSceneToolbarRulesetSelector() + { + ToolbarRulesetSelector selector; + + Add(new Container + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + AutoSizeAxes = Axes.X, + Height = Toolbar.HEIGHT, + Child = selector = new ToolbarRulesetSelector() + + }); + } + } +} diff --git a/osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.cs b/osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.cs index 8590c9fbc0..f8ac610a3a 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.cs @@ -40,7 +40,7 @@ namespace osu.Game.Overlays.Toolbar RelativeSizeAxes = Axes.Y; AutoSizeAxes = Axes.X; - AddRangeInternal(new Drawable[] + AddRangeInternal(new[] { new OpaqueBackground { @@ -48,7 +48,7 @@ namespace osu.Game.Overlays.Toolbar }, modeButtonLine = new Container { - Size = new Vector2(padding* 2 + ToolbarButton.WIDTH, 3), + Size = new Vector2(padding * 2 + ToolbarButton.WIDTH, 3), Anchor = Anchor.BottomLeft, Origin = Anchor.TopLeft, Masking = true, From ff9dc189286ec6e8f9f48a14b12e1312ccb7839f Mon Sep 17 00:00:00 2001 From: EVAST9919 Date: Mon, 10 Jun 2019 03:54:15 +0300 Subject: [PATCH 017/148] TestCaseImprovements --- .../Visual/UserInterface/TestSceneToolbarRulesetSelector.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneToolbarRulesetSelector.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneToolbarRulesetSelector.cs index 1a0e712337..7d0491aa60 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneToolbarRulesetSelector.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneToolbarRulesetSelector.cs @@ -6,6 +6,8 @@ using osu.Game.Overlays.Toolbar; using System; using System.Collections.Generic; using osu.Framework.Graphics; +using System.Linq; +using osu.Framework.MathUtils; namespace osu.Game.Tests.Visual.UserInterface { @@ -28,7 +30,11 @@ namespace osu.Game.Tests.Visual.UserInterface AutoSizeAxes = Axes.X, Height = Toolbar.HEIGHT, Child = selector = new ToolbarRulesetSelector() + }); + AddStep("Select random", () => + { + selector.Current.Value = selector.Items.ElementAt(RNG.Next(selector.Items.Count())); }); } } From ec8c09dd39f86c21449638f994df3ae6449e19c2 Mon Sep 17 00:00:00 2001 From: EVAST9919 Date: Mon, 10 Jun 2019 04:36:34 +0300 Subject: [PATCH 018/148] Fix unability to mannualy switch ruleset --- osu.Game/Overlays/Toolbar/ToolbarRulesetButton.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/osu.Game/Overlays/Toolbar/ToolbarRulesetButton.cs b/osu.Game/Overlays/Toolbar/ToolbarRulesetButton.cs index efb540cd45..defe1da5bf 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarRulesetButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarRulesetButton.cs @@ -6,6 +6,7 @@ using osu.Framework.Graphics.UserInterface; using osu.Game.Rulesets; using osuTK.Graphics; using osu.Framework.Graphics; +using osu.Framework.Input.Events; namespace osu.Game.Overlays.Toolbar { @@ -59,6 +60,12 @@ namespace osu.Game.Overlays.Toolbar } } + protected override bool OnClick(ClickEvent e) + { + Parent.Click(); + return base.OnClick(e); + } + protected override void LoadComplete() { base.LoadComplete(); From 27163c999686b4842ac41a170b63c2d41b2fa0fc Mon Sep 17 00:00:00 2001 From: EVAST9919 Date: Mon, 10 Jun 2019 09:18:48 +0300 Subject: [PATCH 019/148] Fix crashes in some cases When we want to switch ruleset from outside of the selector, but it's blocked (multiplayer is a good example) --- .../Overlays/Toolbar/ToolbarRulesetSelector.cs | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.cs b/osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.cs index f8ac610a3a..1f35d0f293 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.cs @@ -23,6 +23,7 @@ namespace osu.Game.Overlays.Toolbar private const float padding = 10; private readonly Drawable modeButtonLine; private RulesetStore rulesets; + private readonly Bindable globalRuleset = new Bindable(); public override bool HandleNonPositionalInput => !Current.Disabled && base.HandleNonPositionalInput; public override bool HandlePositionalInput => !Current.Disabled && base.HandlePositionalInput; @@ -79,17 +80,20 @@ namespace osu.Game.Overlays.Toolbar private void load(RulesetStore rulesets, Bindable parentRuleset) { this.rulesets = rulesets; + globalRuleset.BindTo(parentRuleset); foreach (var r in rulesets.AvailableRulesets) { AddItem(r); } - Current.BindTo(parentRuleset); - Current.DisabledChanged += disabledChanged; - Current.BindValueChanged(rulesetChanged); + globalRuleset.BindValueChanged(globalRulesetChanged); + globalRuleset.DisabledChanged += disabledChanged; + Current.BindValueChanged(localRulesetChanged); } + private void globalRulesetChanged(ValueChangedEvent e) => Current.Value = e.NewValue; + protected override bool OnKeyDown(KeyDownEvent e) { base.OnKeyDown(e); @@ -109,8 +113,13 @@ namespace osu.Game.Overlays.Toolbar private readonly Cached activeMode = new Cached(); - private void rulesetChanged(ValueChangedEvent e) + private void localRulesetChanged(ValueChangedEvent e) { + if (!globalRuleset.Disabled) + { + globalRuleset.Value = e.NewValue; + } + activeMode.Invalidate(); } From 3fc604b60a6a2ee39b99c06beb3b0d3d6fb944fd Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Mon, 10 Jun 2019 13:18:38 +0300 Subject: [PATCH 020/148] Add Availability to BeatmapSetOnlineInfo --- osu.Game/Beatmaps/BeatmapSetOnlineInfo.cs | 16 +++++++++++++++- .../API/Requests/Responses/APIBeatmapSet.cs | 7 +++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/BeatmapSetOnlineInfo.cs b/osu.Game/Beatmaps/BeatmapSetOnlineInfo.cs index 0ccc9a924c..e88def6321 100644 --- a/osu.Game/Beatmaps/BeatmapSetOnlineInfo.cs +++ b/osu.Game/Beatmaps/BeatmapSetOnlineInfo.cs @@ -65,6 +65,11 @@ namespace osu.Game.Beatmaps /// The amount of people who have favourited this beatmap set. /// public int FavouriteCount { get; set; } + + /// + /// The availability of this beatmap set. + /// + public BeatmapSetOnlineAvailability Availability { get; set; } } public class BeatmapSetOnlineCovers @@ -73,7 +78,7 @@ namespace osu.Game.Beatmaps [JsonProperty(@"cover@2x")] public string Cover { get; set; } - + public string CardLowRes { get; set; } [JsonProperty(@"card@2x")] @@ -84,4 +89,13 @@ namespace osu.Game.Beatmaps [JsonProperty(@"list@2x")] public string List { get; set; } } + + public class BeatmapSetOnlineAvailability + { + [JsonProperty(@"download_disabled")] + public bool DownloadDisabled { get; set; } + + [JsonProperty(@"more_information")] + public string ExternalLink { get; set; } + } } diff --git a/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs b/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs index 1abb7c1a7d..2b8a783e2e 100644 --- a/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs +++ b/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs @@ -60,6 +60,12 @@ namespace osu.Game.Online.API.Requests.Responses set => Author.Id = value; } + [JsonProperty(@"availability")] + private BeatmapSetOnlineAvailability availability { get; set; } + + [JsonProperty(@"download_unavailable")] + private bool test { get; set; } + [JsonProperty(@"beatmaps")] private IEnumerable beatmaps { get; set; } @@ -83,6 +89,7 @@ namespace osu.Game.Online.API.Requests.Responses Submitted = submitted, Ranked = ranked, LastUpdated = lastUpdated, + Availability = availability, }, Beatmaps = beatmaps?.Select(b => b.ToBeatmap(rulesets)).ToList(), }; From adbf4d374e6f90f5a53e3abde23fc9b14f994bad Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Mon, 10 Jun 2019 14:15:49 +0300 Subject: [PATCH 021/148] Redirecting ShowBeatmapSet to FetchAndShowBeatmapSet --- osu.Game/Overlays/BeatmapSetOverlay.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSetOverlay.cs b/osu.Game/Overlays/BeatmapSetOverlay.cs index 3ed398d31a..b7331f551e 100644 --- a/osu.Game/Overlays/BeatmapSetOverlay.cs +++ b/osu.Game/Overlays/BeatmapSetOverlay.cs @@ -120,8 +120,8 @@ namespace osu.Game.Overlays public void ShowBeatmapSet(BeatmapSetInfo set) { - beatmapSet.Value = set; - Show(); + // Re-fetching is the correct way forward. + FetchAndShowBeatmapSet((int)set.OnlineBeatmapSetID); scroll.ScrollTo(0); } } From 3202110b80d805aed875587ac4935af6ea268cab Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Mon, 10 Jun 2019 20:17:44 +0300 Subject: [PATCH 022/148] Add a container for Beatmap Availability --- .../API/Requests/Responses/APIBeatmapSet.cs | 3 - .../BeatmapSet/BeatmapNotAvailable.cs | 69 +++++++++++++++++++ osu.Game/Overlays/BeatmapSet/Header.cs | 62 ++++++++++++----- 3 files changed, 112 insertions(+), 22 deletions(-) create mode 100644 osu.Game/Overlays/BeatmapSet/BeatmapNotAvailable.cs diff --git a/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs b/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs index 2b8a783e2e..82af723a9a 100644 --- a/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs +++ b/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs @@ -63,9 +63,6 @@ namespace osu.Game.Online.API.Requests.Responses [JsonProperty(@"availability")] private BeatmapSetOnlineAvailability availability { get; set; } - [JsonProperty(@"download_unavailable")] - private bool test { get; set; } - [JsonProperty(@"beatmaps")] private IEnumerable beatmaps { get; set; } diff --git a/osu.Game/Overlays/BeatmapSet/BeatmapNotAvailable.cs b/osu.Game/Overlays/BeatmapSet/BeatmapNotAvailable.cs new file mode 100644 index 0000000000..15463b353a --- /dev/null +++ b/osu.Game/Overlays/BeatmapSet/BeatmapNotAvailable.cs @@ -0,0 +1,69 @@ +// 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.Text; +using osu.Framework.Extensions.Color4Extensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Game.Graphics; +using osu.Game.Graphics.Containers; +using osu.Game.Graphics.Sprites; +using osuTK; +using osuTK.Graphics; + +namespace osu.Game.Overlays.BeatmapSet +{ + public class BeatmapNotAvailable : Container + { + private LinkFlowContainer linkContainer; + + public override void Show() + { + AutoSizeAxes = Axes.Both; + Margin = new MarginPadding() { Top = 10 }; + + Children = new Drawable[] + { + new Box + { + Colour = Color4.Black.Opacity(0.6f), + RelativeSizeAxes = Axes.Both, + }, + new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Vertical, + Margin = new MarginPadding() { Top = 10, Left = 5, Right = 20 }, + + Children = new Drawable[] + { + new OsuSpriteText + { + Margin = new MarginPadding() { Bottom = 10, Horizontal = 5 }, + Font = OsuFont.GetFont(size: 20, weight: FontWeight.Medium), + Text = "This beatmap is currently not available for download.", + Colour = Color4.Orange, + }, + linkContainer = new LinkFlowContainer(text => text.Font = OsuFont.GetFont(size: 14)) + { + Direction = FillDirection.Full, + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Margin = new MarginPadding { Bottom = 10, Horizontal = 5 }, + }, + }, + }, + }; + + base.Show(); + } + + public string Link + { + set => linkContainer.AddLink("Check here for more information.", value); + } + } +} diff --git a/osu.Game/Overlays/BeatmapSet/Header.cs b/osu.Game/Overlays/BeatmapSet/Header.cs index a0f71d05c0..0b24a8cdd8 100644 --- a/osu.Game/Overlays/BeatmapSet/Header.cs +++ b/osu.Game/Overlays/BeatmapSet/Header.cs @@ -11,6 +11,7 @@ using osu.Framework.Graphics.Shapes; using osu.Game.Beatmaps; using osu.Game.Beatmaps.Drawables; using osu.Game.Graphics; +using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; using osu.Game.Overlays.BeatmapSet.Buttons; @@ -32,6 +33,7 @@ namespace osu.Game.Overlays.BeatmapSet private readonly UpdateableBeatmapSetCover cover; private readonly OsuSpriteText title, artist; private readonly AuthorInfo author; + private readonly BeatmapNotAvailable unavailableContainer; private readonly FillFlowContainer downloadButtonsContainer; private readonly BeatmapSetOnlineStatusPill onlineStatusPill; public Details Details; @@ -134,6 +136,7 @@ namespace osu.Game.Overlays.BeatmapSet Margin = new MarginPadding { Top = 20 }, Child = author = new AuthorInfo(), }, + unavailableContainer = new BeatmapNotAvailable(), new Container { RelativeSizeAxes = Axes.X, @@ -207,6 +210,18 @@ namespace osu.Game.Overlays.BeatmapSet downloadButtonsContainer.FadeOut(transition_duration); favouriteButton.FadeOut(transition_duration); } + + if (setInfo.NewValue?.OnlineInfo.Availability?.DownloadDisabled ?? false) + { + this.ResizeHeightTo(460, transition_duration / 2); + unavailableContainer.Show(); + unavailableContainer.Link = setInfo.NewValue.OnlineInfo.Availability.ExternalLink; + } + else + { + this.ResizeHeightTo(400, transition_duration / 2); + unavailableContainer.Hide(); + } updateDownloadButtons(); }, true); @@ -216,28 +231,37 @@ namespace osu.Game.Overlays.BeatmapSet { if (BeatmapSet.Value == null) return; - switch (State.Value) + if (BeatmapSet.Value.OnlineInfo.Availability?.DownloadDisabled ?? false) { - case DownloadState.LocallyAvailable: - // temporary for UX until new design is implemented. - downloadButtonsContainer.Child = new osu.Game.Overlays.Direct.DownloadButton(BeatmapSet.Value) - { - Width = 50, - RelativeSizeAxes = Axes.Y - }; - break; + downloadButtonsContainer.RemoveAll(x => true); + return; + } - case DownloadState.Downloading: - case DownloadState.Downloaded: - // temporary to avoid showing two buttons for maps with novideo. will be fixed in new beatmap overlay design. - downloadButtonsContainer.Child = new DownloadButton(BeatmapSet.Value); - break; + else + { + switch (State.Value) + { + case DownloadState.LocallyAvailable: + // temporary for UX until new design is implemented. + downloadButtonsContainer.Child = new osu.Game.Overlays.Direct.DownloadButton(BeatmapSet.Value) + { + Width = 50, + RelativeSizeAxes = Axes.Y + }; + break; - default: - downloadButtonsContainer.Child = new DownloadButton(BeatmapSet.Value); - if (BeatmapSet.Value.OnlineInfo.HasVideo) - downloadButtonsContainer.Add(new DownloadButton(BeatmapSet.Value, true)); - break; + case DownloadState.Downloading: + case DownloadState.Downloaded: + // temporary to avoid showing two buttons for maps with novideo. will be fixed in new beatmap overlay design. + downloadButtonsContainer.Child = new DownloadButton(BeatmapSet.Value); + break; + + default: + downloadButtonsContainer.Child = new DownloadButton(BeatmapSet.Value); + if (BeatmapSet.Value.OnlineInfo.HasVideo) + downloadButtonsContainer.Add(new DownloadButton(BeatmapSet.Value, true)); + break; + } } } } From 70fdd4ba5b4fe1cafca5dbbe84d1eca9e6cf4c57 Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Mon, 10 Jun 2019 21:13:37 +0300 Subject: [PATCH 023/148] Disable download button + Fix AppVeyor Errors --- osu.Game/Beatmaps/BeatmapSetOnlineInfo.cs | 2 +- .../BeatmapSet/BeatmapNotAvailable.cs | 10 ++--- osu.Game/Overlays/BeatmapSet/Header.cs | 44 +++++++++---------- osu.Game/Overlays/BeatmapSetOverlay.cs | 2 +- osu.Game/Overlays/Direct/DownloadButton.cs | 6 +++ 5 files changed, 31 insertions(+), 33 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapSetOnlineInfo.cs b/osu.Game/Beatmaps/BeatmapSetOnlineInfo.cs index e88def6321..ea3f0b61b9 100644 --- a/osu.Game/Beatmaps/BeatmapSetOnlineInfo.cs +++ b/osu.Game/Beatmaps/BeatmapSetOnlineInfo.cs @@ -78,7 +78,7 @@ namespace osu.Game.Beatmaps [JsonProperty(@"cover@2x")] public string Cover { get; set; } - + public string CardLowRes { get; set; } [JsonProperty(@"card@2x")] diff --git a/osu.Game/Overlays/BeatmapSet/BeatmapNotAvailable.cs b/osu.Game/Overlays/BeatmapSet/BeatmapNotAvailable.cs index 15463b353a..b893fd0703 100644 --- a/osu.Game/Overlays/BeatmapSet/BeatmapNotAvailable.cs +++ b/osu.Game/Overlays/BeatmapSet/BeatmapNotAvailable.cs @@ -1,9 +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.Text; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -11,7 +8,6 @@ using osu.Framework.Graphics.Shapes; using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; -using osuTK; using osuTK.Graphics; namespace osu.Game.Overlays.BeatmapSet @@ -23,7 +19,7 @@ namespace osu.Game.Overlays.BeatmapSet public override void Show() { AutoSizeAxes = Axes.Both; - Margin = new MarginPadding() { Top = 10 }; + Margin = new MarginPadding { Top = 10 }; Children = new Drawable[] { @@ -36,13 +32,13 @@ namespace osu.Game.Overlays.BeatmapSet { AutoSizeAxes = Axes.Both, Direction = FillDirection.Vertical, - Margin = new MarginPadding() { Top = 10, Left = 5, Right = 20 }, + Margin = new MarginPadding { Top = 10, Left = 5, Right = 20 }, Children = new Drawable[] { new OsuSpriteText { - Margin = new MarginPadding() { Bottom = 10, Horizontal = 5 }, + Margin = new MarginPadding { Bottom = 10, Horizontal = 5 }, Font = OsuFont.GetFont(size: 20, weight: FontWeight.Medium), Text = "This beatmap is currently not available for download.", Colour = Color4.Orange, diff --git a/osu.Game/Overlays/BeatmapSet/Header.cs b/osu.Game/Overlays/BeatmapSet/Header.cs index 0b24a8cdd8..9a4e7d4754 100644 --- a/osu.Game/Overlays/BeatmapSet/Header.cs +++ b/osu.Game/Overlays/BeatmapSet/Header.cs @@ -11,7 +11,6 @@ using osu.Framework.Graphics.Shapes; using osu.Game.Beatmaps; using osu.Game.Beatmaps.Drawables; using osu.Game.Graphics; -using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; using osu.Game.Overlays.BeatmapSet.Buttons; @@ -210,7 +209,7 @@ namespace osu.Game.Overlays.BeatmapSet downloadButtonsContainer.FadeOut(transition_duration); favouriteButton.FadeOut(transition_duration); } - + if (setInfo.NewValue?.OnlineInfo.Availability?.DownloadDisabled ?? false) { this.ResizeHeightTo(460, transition_duration / 2); @@ -237,31 +236,28 @@ namespace osu.Game.Overlays.BeatmapSet return; } - else + switch (State.Value) { - switch (State.Value) - { - case DownloadState.LocallyAvailable: - // temporary for UX until new design is implemented. - downloadButtonsContainer.Child = new osu.Game.Overlays.Direct.DownloadButton(BeatmapSet.Value) - { - Width = 50, - RelativeSizeAxes = Axes.Y - }; - break; + case DownloadState.LocallyAvailable: + // temporary for UX until new design is implemented. + downloadButtonsContainer.Child = new osu.Game.Overlays.Direct.DownloadButton(BeatmapSet.Value) + { + Width = 50, + RelativeSizeAxes = Axes.Y + }; + break; - case DownloadState.Downloading: - case DownloadState.Downloaded: - // temporary to avoid showing two buttons for maps with novideo. will be fixed in new beatmap overlay design. - downloadButtonsContainer.Child = new DownloadButton(BeatmapSet.Value); - break; + case DownloadState.Downloading: + case DownloadState.Downloaded: + // temporary to avoid showing two buttons for maps with novideo. will be fixed in new beatmap overlay design. + downloadButtonsContainer.Child = new DownloadButton(BeatmapSet.Value); + break; - default: - downloadButtonsContainer.Child = new DownloadButton(BeatmapSet.Value); - if (BeatmapSet.Value.OnlineInfo.HasVideo) - downloadButtonsContainer.Add(new DownloadButton(BeatmapSet.Value, true)); - break; - } + default: + downloadButtonsContainer.Child = new DownloadButton(BeatmapSet.Value); + if (BeatmapSet.Value.OnlineInfo.HasVideo) + downloadButtonsContainer.Add(new DownloadButton(BeatmapSet.Value, true)); + break; } } } diff --git a/osu.Game/Overlays/BeatmapSetOverlay.cs b/osu.Game/Overlays/BeatmapSetOverlay.cs index b7331f551e..8d3d78e79a 100644 --- a/osu.Game/Overlays/BeatmapSetOverlay.cs +++ b/osu.Game/Overlays/BeatmapSetOverlay.cs @@ -121,7 +121,7 @@ namespace osu.Game.Overlays public void ShowBeatmapSet(BeatmapSetInfo set) { // Re-fetching is the correct way forward. - FetchAndShowBeatmapSet((int)set.OnlineBeatmapSetID); + FetchAndShowBeatmapSet(set.OnlineBeatmapSetID ?? 0); scroll.ScrollTo(0); } } diff --git a/osu.Game/Overlays/Direct/DownloadButton.cs b/osu.Game/Overlays/Direct/DownloadButton.cs index 3f44d854e5..deccf819ea 100644 --- a/osu.Game/Overlays/Direct/DownloadButton.cs +++ b/osu.Game/Overlays/Direct/DownloadButton.cs @@ -77,6 +77,12 @@ namespace osu.Game.Overlays.Direct { this.colours = colours; + if (BeatmapSet.Value.OnlineInfo.Availability?.DownloadDisabled ?? false) + { + button.Enabled.Value = false; + button.TooltipText = "Unavailable"; + } + button.Action = () => { switch (State.Value) From 75716af25e67f997a669096e0cddc012c6b5e881 Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Mon, 10 Jun 2019 21:14:12 +0300 Subject: [PATCH 024/148] Forgot to return --- osu.Game/Overlays/Direct/DownloadButton.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Overlays/Direct/DownloadButton.cs b/osu.Game/Overlays/Direct/DownloadButton.cs index deccf819ea..33e09e95aa 100644 --- a/osu.Game/Overlays/Direct/DownloadButton.cs +++ b/osu.Game/Overlays/Direct/DownloadButton.cs @@ -81,6 +81,7 @@ namespace osu.Game.Overlays.Direct { button.Enabled.Value = false; button.TooltipText = "Unavailable"; + return; } button.Action = () => From fc3e1e6a8686ccb1a8a85af180f3da3302910ade Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Mon, 10 Jun 2019 21:50:08 +0300 Subject: [PATCH 025/148] Fix issue --- osu.Game/Overlays/BeatmapSetOverlay.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/BeatmapSetOverlay.cs b/osu.Game/Overlays/BeatmapSetOverlay.cs index 8d3d78e79a..6bd2e1b72e 100644 --- a/osu.Game/Overlays/BeatmapSetOverlay.cs +++ b/osu.Game/Overlays/BeatmapSetOverlay.cs @@ -121,7 +121,7 @@ namespace osu.Game.Overlays public void ShowBeatmapSet(BeatmapSetInfo set) { // Re-fetching is the correct way forward. - FetchAndShowBeatmapSet(set.OnlineBeatmapSetID ?? 0); + FetchAndShowBeatmapSet(set?.OnlineBeatmapSetID ?? 0); scroll.ScrollTo(0); } } From 94a7794ff71382d93cd28397aecb74d8ae95697a Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Mon, 10 Jun 2019 21:54:33 +0300 Subject: [PATCH 026/148] Fix issue --- osu.Game/Overlays/BeatmapSetOverlay.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/BeatmapSetOverlay.cs b/osu.Game/Overlays/BeatmapSetOverlay.cs index 8d3d78e79a..6bd2e1b72e 100644 --- a/osu.Game/Overlays/BeatmapSetOverlay.cs +++ b/osu.Game/Overlays/BeatmapSetOverlay.cs @@ -121,7 +121,7 @@ namespace osu.Game.Overlays public void ShowBeatmapSet(BeatmapSetInfo set) { // Re-fetching is the correct way forward. - FetchAndShowBeatmapSet(set.OnlineBeatmapSetID ?? 0); + FetchAndShowBeatmapSet(set?.OnlineBeatmapSetID ?? 0); scroll.ScrollTo(0); } } From 130ff5688694921246ee1dba0faaac987c4b46b3 Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Tue, 11 Jun 2019 12:29:42 +0300 Subject: [PATCH 027/148] Move logic into BeatmapNotAvailable --- .../BeatmapSet/BeatmapNotAvailable.cs | 54 ++++++++++++++++--- osu.Game/Overlays/BeatmapSet/Header.cs | 36 +++++-------- 2 files changed, 59 insertions(+), 31 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/BeatmapNotAvailable.cs b/osu.Game/Overlays/BeatmapSet/BeatmapNotAvailable.cs index b893fd0703..c111861206 100644 --- a/osu.Game/Overlays/BeatmapSet/BeatmapNotAvailable.cs +++ b/osu.Game/Overlays/BeatmapSet/BeatmapNotAvailable.cs @@ -5,6 +5,7 @@ using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; +using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; @@ -14,9 +15,36 @@ namespace osu.Game.Overlays.BeatmapSet { public class BeatmapNotAvailable : Container { - private LinkFlowContainer linkContainer; + private BeatmapSetInfo beatmapSet; - public override void Show() + public BeatmapSetInfo BeatmapSet + { + get => beatmapSet; + set + { + if (value == beatmapSet) return; + + beatmapSet = value; + + if (beatmapSet?.OnlineInfo.Availability != null) + { + Header?.ResizeHeightTo(450, 500); + Show(); + } + else + { + Header?.ResizeHeightTo(400, 500); + Hide(); + } + } + } + + public Header Header; + + private readonly OsuSpriteText text; + private readonly LinkFlowContainer link; + + public BeatmapNotAvailable() { AutoSizeAxes = Axes.Both; Margin = new MarginPadding { Top = 10 }; @@ -36,14 +64,13 @@ namespace osu.Game.Overlays.BeatmapSet Children = new Drawable[] { - new OsuSpriteText + text = new OsuSpriteText { Margin = new MarginPadding { Bottom = 10, Horizontal = 5 }, Font = OsuFont.GetFont(size: 20, weight: FontWeight.Medium), - Text = "This beatmap is currently not available for download.", Colour = Color4.Orange, }, - linkContainer = new LinkFlowContainer(text => text.Font = OsuFont.GetFont(size: 14)) + link = new LinkFlowContainer(t => t.Font = OsuFont.GetFont(size: 14)) { Direction = FillDirection.Full, RelativeSizeAxes = Axes.X, @@ -54,12 +81,25 @@ namespace osu.Game.Overlays.BeatmapSet }, }; + Hide(); + } + + public override void Show() + { + text.Text = BeatmapSet.OnlineInfo.Availability.DownloadDisabled + ? "This beatmap is currently not available for download." + : "Portions of this beatmap have been removed at the request of the creator or a third-party rights holder."; + + link.AddLink("Check here for more information.", BeatmapSet.OnlineInfo.Availability.ExternalLink); + base.Show(); } - public string Link + public override void Hide() { - set => linkContainer.AddLink("Check here for more information.", value); + link.RemoveAll(x => true); + + base.Hide(); } } } diff --git a/osu.Game/Overlays/BeatmapSet/Header.cs b/osu.Game/Overlays/BeatmapSet/Header.cs index 9a4e7d4754..a53b4a2e68 100644 --- a/osu.Game/Overlays/BeatmapSet/Header.cs +++ b/osu.Game/Overlays/BeatmapSet/Header.cs @@ -32,10 +32,10 @@ namespace osu.Game.Overlays.BeatmapSet private readonly UpdateableBeatmapSetCover cover; private readonly OsuSpriteText title, artist; private readonly AuthorInfo author; - private readonly BeatmapNotAvailable unavailableContainer; - private readonly FillFlowContainer downloadButtonsContainer; + private readonly BeatmapNotAvailable beatmapNotAvailable; private readonly BeatmapSetOnlineStatusPill onlineStatusPill; public Details Details; + public FillFlowContainer DownloadButtonsContainer; public readonly BeatmapPicker Picker; @@ -135,7 +135,7 @@ namespace osu.Game.Overlays.BeatmapSet Margin = new MarginPadding { Top = 20 }, Child = author = new AuthorInfo(), }, - unavailableContainer = new BeatmapNotAvailable(), + beatmapNotAvailable = new BeatmapNotAvailable { Header = this }, new Container { RelativeSizeAxes = Axes.X, @@ -144,7 +144,7 @@ namespace osu.Game.Overlays.BeatmapSet Children = new Drawable[] { favouriteButton = new FavouriteButton(), - downloadButtonsContainer = new FillFlowContainer + DownloadButtonsContainer = new FillFlowContainer { RelativeSizeAxes = Axes.Both, Padding = new MarginPadding { Left = buttons_height + buttons_spacing }, @@ -192,7 +192,7 @@ namespace osu.Game.Overlays.BeatmapSet BeatmapSet.BindValueChanged(setInfo => { - Picker.BeatmapSet = author.BeatmapSet = Details.BeatmapSet = setInfo.NewValue; + Picker.BeatmapSet = author.BeatmapSet = beatmapNotAvailable.BeatmapSet = Details.BeatmapSet = setInfo.NewValue; title.Text = setInfo.NewValue?.Metadata.Title ?? string.Empty; artist.Text = setInfo.NewValue?.Metadata.Artist ?? string.Empty; @@ -201,27 +201,15 @@ namespace osu.Game.Overlays.BeatmapSet if (setInfo.NewValue != null) { - downloadButtonsContainer.FadeIn(transition_duration); + DownloadButtonsContainer.FadeIn(transition_duration); favouriteButton.FadeIn(transition_duration); } else { - downloadButtonsContainer.FadeOut(transition_duration); + DownloadButtonsContainer.FadeOut(transition_duration); favouriteButton.FadeOut(transition_duration); } - if (setInfo.NewValue?.OnlineInfo.Availability?.DownloadDisabled ?? false) - { - this.ResizeHeightTo(460, transition_duration / 2); - unavailableContainer.Show(); - unavailableContainer.Link = setInfo.NewValue.OnlineInfo.Availability.ExternalLink; - } - else - { - this.ResizeHeightTo(400, transition_duration / 2); - unavailableContainer.Hide(); - } - updateDownloadButtons(); }, true); } @@ -232,7 +220,7 @@ namespace osu.Game.Overlays.BeatmapSet if (BeatmapSet.Value.OnlineInfo.Availability?.DownloadDisabled ?? false) { - downloadButtonsContainer.RemoveAll(x => true); + DownloadButtonsContainer.RemoveAll(x => true); return; } @@ -240,7 +228,7 @@ namespace osu.Game.Overlays.BeatmapSet { case DownloadState.LocallyAvailable: // temporary for UX until new design is implemented. - downloadButtonsContainer.Child = new osu.Game.Overlays.Direct.DownloadButton(BeatmapSet.Value) + DownloadButtonsContainer.Child = new osu.Game.Overlays.Direct.DownloadButton(BeatmapSet.Value) { Width = 50, RelativeSizeAxes = Axes.Y @@ -250,13 +238,13 @@ namespace osu.Game.Overlays.BeatmapSet case DownloadState.Downloading: case DownloadState.Downloaded: // temporary to avoid showing two buttons for maps with novideo. will be fixed in new beatmap overlay design. - downloadButtonsContainer.Child = new DownloadButton(BeatmapSet.Value); + DownloadButtonsContainer.Child = new DownloadButton(BeatmapSet.Value); break; default: - downloadButtonsContainer.Child = new DownloadButton(BeatmapSet.Value); + DownloadButtonsContainer.Child = new DownloadButton(BeatmapSet.Value); if (BeatmapSet.Value.OnlineInfo.HasVideo) - downloadButtonsContainer.Add(new DownloadButton(BeatmapSet.Value, true)); + DownloadButtonsContainer.Add(new DownloadButton(BeatmapSet.Value, true)); break; } } From 13cd22e397f336eeb86b1be076f4cf6aabbafc85 Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Tue, 11 Jun 2019 14:58:46 +0300 Subject: [PATCH 028/148] Test scene for BeatmapNotAvailable --- .../Online/TestSceneBeatmapNotAvailable.cs | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 osu.Game.Tests/Visual/Online/TestSceneBeatmapNotAvailable.cs diff --git a/osu.Game.Tests/Visual/Online/TestSceneBeatmapNotAvailable.cs b/osu.Game.Tests/Visual/Online/TestSceneBeatmapNotAvailable.cs new file mode 100644 index 0000000000..bd4570470d --- /dev/null +++ b/osu.Game.Tests/Visual/Online/TestSceneBeatmapNotAvailable.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.Game.Beatmaps; +using osu.Game.Overlays.BeatmapSet; + +namespace osu.Game.Tests.Visual.Online +{ + [TestFixture] + public class TestSceneBeatmapNotAvailable : OsuTestScene + { + public TestSceneBeatmapNotAvailable() + { + var container = new BeatmapNotAvailable(); + + Add(container); + + AddAssert("is container hidden", () => container.Alpha == 0); + AddStep("set undownloadable beatmapset", () => container.BeatmapSet = new BeatmapSetInfo + { + OnlineInfo = new BeatmapSetOnlineInfo + { + Availability = new BeatmapSetOnlineAvailability + { + DownloadDisabled = true, + ExternalLink = @"https://gist.githubusercontent.com/peppy/99e6959772083cdfde8a/raw", + }, + }, + }); + + AddAssert("is container visible", () => container.Alpha == 1); + AddStep("set downloadable beatmapset", () => container.BeatmapSet = new BeatmapSetInfo + { + OnlineInfo = new BeatmapSetOnlineInfo + { + Availability = new BeatmapSetOnlineAvailability + { + DownloadDisabled = false, + ExternalLink = @"https://gist.githubusercontent.com/peppy/99e6959772083cdfde8a/raw", + }, + }, + }); + + AddAssert("is container still visible", () => container.Alpha == 1); + AddStep("set normal beatmapset", () => container.BeatmapSet = new BeatmapSetInfo + { + OnlineInfo = new BeatmapSetOnlineInfo(), + }); + + AddAssert("is container hidden", () => container.Alpha == 0); + } + } +} From b4de51b612c62b563ec1303b84dead7a219be938 Mon Sep 17 00:00:00 2001 From: naoey Date: Tue, 11 Jun 2019 18:29:33 +0530 Subject: [PATCH 029/148] Create a generic base archive download manager class --- .../Database/ArchiveDownloadModelManager.cs | 117 ++++++++++++++++++ .../Online/API/ArchiveDownloadModelRequest.cs | 23 ++++ 2 files changed, 140 insertions(+) create mode 100644 osu.Game/Database/ArchiveDownloadModelManager.cs create mode 100644 osu.Game/Online/API/ArchiveDownloadModelRequest.cs diff --git a/osu.Game/Database/ArchiveDownloadModelManager.cs b/osu.Game/Database/ArchiveDownloadModelManager.cs new file mode 100644 index 0000000000..8c7a0fba87 --- /dev/null +++ b/osu.Game/Database/ArchiveDownloadModelManager.cs @@ -0,0 +1,117 @@ +using osu.Framework.Logging; +using osu.Framework.Platform; +using osu.Game.Online.API; +using osu.Game.Overlays.Notifications; +using System; +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace osu.Game.Database +{ + public abstract class ArchiveDownloadModelManager : ArchiveModelManager + where TModel : class, IHasFiles, IHasPrimaryKey, ISoftDelete + where TFileModel : INamedFileInfo, new() + where TDownloadRequestModel : ArchiveDownloadModelRequest + { + public event Action DownloadBegan; + + public event Action DownloadFailed; + + private readonly IAPIProvider api; + + private readonly List currentDownloads = new List(); + + protected ArchiveDownloadModelManager(Storage storage, IDatabaseContextFactory contextFactory, IAPIProvider api, MutableDatabaseBackedStoreWithFileIncludes modelStore, IIpcHost importHost = null) + :base(storage, contextFactory, modelStore, importHost) + { + this.api = api; + } + + protected abstract TDownloadRequestModel CreateDownloadRequest(TModel model); + + public bool Download(TModel model) + { + var existing = GetExistingDownload(model); + + if (existing != null || api == null) return false; + + DownloadNotification notification = new DownloadNotification + { + Text = $"Downloading {model}", + }; + + var request = CreateDownloadRequest(model); + + request.DownloadProgressed += progress => + { + notification.State = ProgressNotificationState.Active; + notification.Progress = progress; + }; + + request.Success += filename => + { + Task.Factory.StartNew(() => + { + Import(notification, filename); + currentDownloads.Remove(request); + }, TaskCreationOptions.LongRunning); + }; + + request.Failure += error => + { + DownloadFailed?.Invoke(request); + + if (error is OperationCanceledException) return; + + notification.State = ProgressNotificationState.Cancelled; + // TODO: implement a Name for every model that we can use in this message + Logger.Error(error, "Download failed!"); + currentDownloads.Remove(request); + }; + + notification.CancelRequested += () => + { + request.Cancel(); + currentDownloads.Remove(request); + notification.State = ProgressNotificationState.Cancelled; + return true; + }; + + currentDownloads.Add(request); + PostNotification?.Invoke(notification); + + Task.Factory.StartNew(() => + { + try + { + request.Perform(api); + } + catch + { + } + }, TaskCreationOptions.LongRunning); + + DownloadBegan?.Invoke(request); + + return true; + } + + public TDownloadRequestModel GetExistingDownload(TModel model) => currentDownloads.Find(r => r.Info.Equals(model)); + + private class DownloadNotification : ProgressNotification + { + public override bool IsImportant => false; + + protected override Notification CreateCompletionNotification() => new SilencedProgressCompletionNotification + { + Activated = CompletionClickAction, + Text = CompletionText + }; + + private class SilencedProgressCompletionNotification : ProgressCompletionNotification + { + public override bool IsImportant => false; + } + } + } +} diff --git a/osu.Game/Online/API/ArchiveDownloadModelRequest.cs b/osu.Game/Online/API/ArchiveDownloadModelRequest.cs new file mode 100644 index 0000000000..377166e657 --- /dev/null +++ b/osu.Game/Online/API/ArchiveDownloadModelRequest.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace osu.Game.Online.API +{ + public abstract class ArchiveDownloadModelRequest : APIDownloadRequest + where TModel : class + { + public readonly TModel Info; + + public float Progress; + + public event Action DownloadProgressed; + + protected ArchiveDownloadModelRequest(TModel model) + { + Info = model; + + Progressed += (current, total) => DownloadProgressed?.Invoke(Progress = (float)current / total); + } + } +} From 341d137f5c10c9e575419100e355fc6d312c0103 Mon Sep 17 00:00:00 2001 From: naoey Date: Tue, 11 Jun 2019 19:36:08 +0530 Subject: [PATCH 030/148] Make BeatmapManager inherit from new base class --- osu.Game/Beatmaps/BeatmapManager.cs | 113 +----------------- .../Database/ArchiveDownloadModelManager.cs | 29 +++-- .../Online/API/ArchiveDownloadModelRequest.cs | 2 - .../API/Requests/DownloadBeatmapSetRequest.cs | 10 +- .../Direct/DownloadTrackingComposite.cs | 4 +- 5 files changed, 25 insertions(+), 133 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index b6fe7f88fa..c4975501ed 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -27,7 +27,7 @@ namespace osu.Game.Beatmaps /// /// Handles the storage and retrieval of Beatmaps/WorkingBeatmaps. /// - public partial class BeatmapManager : ArchiveModelManager + public partial class BeatmapManager : ArchiveDownloadModelManager { /// /// Fired when a single difficulty has been hidden. @@ -39,16 +39,6 @@ namespace osu.Game.Beatmaps /// public event Action BeatmapRestored; - /// - /// Fired when a beatmap download begins. - /// - public event Action BeatmapDownloadBegan; - - /// - /// Fired when a beatmap download is interrupted, due to user cancellation or other failures. - /// - public event Action BeatmapDownloadFailed; - /// /// A default representation of a WorkingBeatmap to use when no beatmap is available. /// @@ -74,7 +64,7 @@ namespace osu.Game.Beatmaps public BeatmapManager(Storage storage, IDatabaseContextFactory contextFactory, RulesetStore rulesets, IAPIProvider api, AudioManager audioManager, GameHost host = null, WorkingBeatmap defaultBeatmap = null) - : base(storage, contextFactory, new BeatmapStore(contextFactory), host) + : base(storage, contextFactory, api, new BeatmapStore(contextFactory), host) { this.rulesets = rulesets; this.api = api; @@ -88,6 +78,8 @@ namespace osu.Game.Beatmaps beatmaps.BeatmapRestored += b => BeatmapRestored?.Invoke(b); } + protected override DownloadBeatmapSetRequest CreateDownloadRequest(BeatmapSetInfo set) => new DownloadBeatmapSetRequest(set, false); + protected override void Populate(BeatmapSetInfo beatmapSet, ArchiveReader archive) { if (archive != null) @@ -153,87 +145,6 @@ namespace osu.Game.Beatmaps void resetIds() => beatmapSet.Beatmaps.ForEach(b => b.OnlineBeatmapID = null); } - /// - /// Downloads a beatmap. - /// This will post notifications tracking progress. - /// - /// The to be downloaded. - /// Whether the beatmap should be downloaded without video. Defaults to false. - /// Downloading can happen - public bool Download(BeatmapSetInfo beatmapSetInfo, bool noVideo = false) - { - var existing = GetExistingDownload(beatmapSetInfo); - - if (existing != null || api == null) return false; - - var downloadNotification = new DownloadNotification - { - Text = $"Downloading {beatmapSetInfo}", - }; - - var request = new DownloadBeatmapSetRequest(beatmapSetInfo, noVideo); - - request.DownloadProgressed += progress => - { - downloadNotification.State = ProgressNotificationState.Active; - downloadNotification.Progress = progress; - }; - - request.Success += filename => - { - Task.Factory.StartNew(() => - { - // This gets scheduled back to the update thread, but we want the import to run in the background. - Import(downloadNotification, filename); - currentDownloads.Remove(request); - }, TaskCreationOptions.LongRunning); - }; - - request.Failure += error => - { - BeatmapDownloadFailed?.Invoke(request); - - if (error is OperationCanceledException) return; - - downloadNotification.State = ProgressNotificationState.Cancelled; - Logger.Error(error, "Beatmap download failed!"); - currentDownloads.Remove(request); - }; - - downloadNotification.CancelRequested += () => - { - request.Cancel(); - currentDownloads.Remove(request); - downloadNotification.State = ProgressNotificationState.Cancelled; - return true; - }; - - currentDownloads.Add(request); - PostNotification?.Invoke(downloadNotification); - - // don't run in the main api queue as this is a long-running task. - Task.Factory.StartNew(() => - { - try - { - request.Perform(api); - } - catch - { - // no need to handle here as exceptions will filter down to request.Failure above. - } - }, TaskCreationOptions.LongRunning); - BeatmapDownloadBegan?.Invoke(request); - return true; - } - - /// - /// Get an existing download request if it exists. - /// - /// The whose download request is wanted. - /// The object if it exists, or null. - public DownloadBeatmapSetRequest GetExistingDownload(BeatmapSetInfo beatmap) => currentDownloads.Find(d => d.BeatmapSet.OnlineBeatmapSetID == beatmap.OnlineBeatmapSetID); - /// /// Delete a beatmap difficulty. /// @@ -439,21 +350,5 @@ namespace osu.Game.Beatmaps protected override Texture GetBackground() => null; protected override Track GetTrack() => null; } - - private class DownloadNotification : ProgressNotification - { - public override bool IsImportant => false; - - protected override Notification CreateCompletionNotification() => new SilencedProgressCompletionNotification - { - Activated = CompletionClickAction, - Text = CompletionText - }; - - private class SilencedProgressCompletionNotification : ProgressCompletionNotification - { - public override bool IsImportant => false; - } - } } } diff --git a/osu.Game/Database/ArchiveDownloadModelManager.cs b/osu.Game/Database/ArchiveDownloadModelManager.cs index 8c7a0fba87..6580da0d54 100644 --- a/osu.Game/Database/ArchiveDownloadModelManager.cs +++ b/osu.Game/Database/ArchiveDownloadModelManager.cs @@ -31,17 +31,26 @@ namespace osu.Game.Database public bool Download(TModel model) { - var existing = GetExistingDownload(model); - - if (existing != null || api == null) return false; - - DownloadNotification notification = new DownloadNotification - { - Text = $"Downloading {model}", - }; + if (!canDownload(model)) return false; var request = CreateDownloadRequest(model); + performDownloadWithRequest(request); + + return true; + } + + public TDownloadRequestModel GetExistingDownload(TModel model) => currentDownloads.Find(r => r.Info.Equals(model)); + + private bool canDownload(TModel model) => GetExistingDownload(model) == null && api != null; + + private void performDownloadWithRequest(TDownloadRequestModel request) + { + DownloadNotification notification = new DownloadNotification + { + Text = $"Downloading {request.Info}", + }; + request.DownloadProgressed += progress => { notification.State = ProgressNotificationState.Active; @@ -92,12 +101,8 @@ namespace osu.Game.Database }, TaskCreationOptions.LongRunning); DownloadBegan?.Invoke(request); - - return true; } - public TDownloadRequestModel GetExistingDownload(TModel model) => currentDownloads.Find(r => r.Info.Equals(model)); - private class DownloadNotification : ProgressNotification { public override bool IsImportant => false; diff --git a/osu.Game/Online/API/ArchiveDownloadModelRequest.cs b/osu.Game/Online/API/ArchiveDownloadModelRequest.cs index 377166e657..862d017228 100644 --- a/osu.Game/Online/API/ArchiveDownloadModelRequest.cs +++ b/osu.Game/Online/API/ArchiveDownloadModelRequest.cs @@ -1,6 +1,4 @@ using System; -using System.Collections.Generic; -using System.Text; namespace osu.Game.Online.API { diff --git a/osu.Game/Online/API/Requests/DownloadBeatmapSetRequest.cs b/osu.Game/Online/API/Requests/DownloadBeatmapSetRequest.cs index 26e8acc2fc..7d0a8f9f46 100644 --- a/osu.Game/Online/API/Requests/DownloadBeatmapSetRequest.cs +++ b/osu.Game/Online/API/Requests/DownloadBeatmapSetRequest.cs @@ -2,26 +2,20 @@ // See the LICENCE file in the repository root for full licence text. using osu.Game.Beatmaps; -using System; namespace osu.Game.Online.API.Requests { - public class DownloadBeatmapSetRequest : APIDownloadRequest + public class DownloadBeatmapSetRequest : ArchiveDownloadModelRequest { public readonly BeatmapSetInfo BeatmapSet; - public float Progress; - - public event Action DownloadProgressed; - private readonly bool noVideo; public DownloadBeatmapSetRequest(BeatmapSetInfo set, bool noVideo) + : base(set) { this.noVideo = noVideo; BeatmapSet = set; - - Progressed += (current, total) => DownloadProgressed?.Invoke(Progress = (float)current / total); } protected override string Target => $@"beatmapsets/{BeatmapSet.OnlineBeatmapSetID}/download{(noVideo ? "?noVideo=1" : "")}"; diff --git a/osu.Game/Overlays/Direct/DownloadTrackingComposite.cs b/osu.Game/Overlays/Direct/DownloadTrackingComposite.cs index 37f13aefc8..9beedb195f 100644 --- a/osu.Game/Overlays/Direct/DownloadTrackingComposite.cs +++ b/osu.Game/Overlays/Direct/DownloadTrackingComposite.cs @@ -47,7 +47,7 @@ namespace osu.Game.Overlays.Direct attachDownload(beatmaps.GetExistingDownload(setInfo.NewValue)); }, true); - beatmaps.BeatmapDownloadBegan += download => + beatmaps.DownloadBegan += download => { if (download.BeatmapSet.OnlineBeatmapSetID == BeatmapSet.Value?.OnlineBeatmapSetID) attachDownload(download); @@ -65,7 +65,7 @@ namespace osu.Game.Overlays.Direct if (beatmaps != null) { - beatmaps.BeatmapDownloadBegan -= attachDownload; + beatmaps.DownloadBegan -= attachDownload; beatmaps.ItemAdded -= setAdded; } From 8ff26a8fbcf7ef1f1d3483d4dd0047807ef05ff1 Mon Sep 17 00:00:00 2001 From: naoey Date: Tue, 11 Jun 2019 19:49:10 +0530 Subject: [PATCH 031/148] Add license headers and xmldoc --- .../Database/ArchiveDownloadModelManager.cs | 31 +++++++++++++++++-- .../Online/API/ArchiveDownloadModelRequest.cs | 5 ++- 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/osu.Game/Database/ArchiveDownloadModelManager.cs b/osu.Game/Database/ArchiveDownloadModelManager.cs index 6580da0d54..d0881fb251 100644 --- a/osu.Game/Database/ArchiveDownloadModelManager.cs +++ b/osu.Game/Database/ArchiveDownloadModelManager.cs @@ -1,4 +1,7 @@ -using osu.Framework.Logging; +// 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.Logging; using osu.Framework.Platform; using osu.Game.Online.API; using osu.Game.Overlays.Notifications; @@ -8,13 +11,26 @@ using System.Threading.Tasks; namespace osu.Game.Database { + /// + /// An that has the ability to download models using an and + /// import them into the store. + /// + /// The model type. + /// The associated file join type. + /// The associated for this model. public abstract class ArchiveDownloadModelManager : ArchiveModelManager where TModel : class, IHasFiles, IHasPrimaryKey, ISoftDelete where TFileModel : INamedFileInfo, new() where TDownloadRequestModel : ArchiveDownloadModelRequest { + /// + /// Fired when a download begins. + /// public event Action DownloadBegan; + /// + /// Fired when a download is interrupted, either due to user cancellation or failure. + /// public event Action DownloadFailed; private readonly IAPIProvider api; @@ -29,6 +45,12 @@ namespace osu.Game.Database protected abstract TDownloadRequestModel CreateDownloadRequest(TModel model); + /// + /// Downloads a . + /// This will post notifications tracking progress. + /// + /// The to be downloaded. + /// Whether downloading can happen. public bool Download(TModel model) { if (!canDownload(model)) return false; @@ -40,6 +62,11 @@ namespace osu.Game.Database return true; } + /// + /// Gets an existing download request if it exists. + /// + /// The whose request is wanted. + /// The object if it exists, otherwise null. public TDownloadRequestModel GetExistingDownload(TModel model) => currentDownloads.Find(r => r.Info.Equals(model)); private bool canDownload(TModel model) => GetExistingDownload(model) == null && api != null; @@ -73,7 +100,7 @@ namespace osu.Game.Database if (error is OperationCanceledException) return; notification.State = ProgressNotificationState.Cancelled; - // TODO: implement a Name for every model that we can use in this message + // TODO: maybe implement a Name for every model that we can use in this message? Logger.Error(error, "Download failed!"); currentDownloads.Remove(request); }; diff --git a/osu.Game/Online/API/ArchiveDownloadModelRequest.cs b/osu.Game/Online/API/ArchiveDownloadModelRequest.cs index 862d017228..7f161f1e98 100644 --- a/osu.Game/Online/API/ArchiveDownloadModelRequest.cs +++ b/osu.Game/Online/API/ArchiveDownloadModelRequest.cs @@ -1,4 +1,7 @@ -using System; +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System; namespace osu.Game.Online.API { From 802f48712d95b148efc45ae25bf8fa4fdc040423 Mon Sep 17 00:00:00 2001 From: naoey Date: Tue, 11 Jun 2019 20:14:36 +0530 Subject: [PATCH 032/148] Add ability to perform a download request with options --- osu.Game/Beatmaps/BeatmapManager.cs | 2 +- .../Database/ArchiveDownloadModelManager.cs | 29 +++++++++++++++++-- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index c4975501ed..6f27cbd7c6 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -78,7 +78,7 @@ namespace osu.Game.Beatmaps beatmaps.BeatmapRestored += b => BeatmapRestored?.Invoke(b); } - protected override DownloadBeatmapSetRequest CreateDownloadRequest(BeatmapSetInfo set) => new DownloadBeatmapSetRequest(set, false); + protected override DownloadBeatmapSetRequest CreateDownloadRequest(BeatmapSetInfo set, object[] options) => new DownloadBeatmapSetRequest(set, (options?.FirstOrDefault() as bool?) ?? false); protected override void Populate(BeatmapSetInfo beatmapSet, ArchiveReader archive) { diff --git a/osu.Game/Database/ArchiveDownloadModelManager.cs b/osu.Game/Database/ArchiveDownloadModelManager.cs index d0881fb251..a4d2180559 100644 --- a/osu.Game/Database/ArchiveDownloadModelManager.cs +++ b/osu.Game/Database/ArchiveDownloadModelManager.cs @@ -43,7 +43,15 @@ namespace osu.Game.Database this.api = api; } - protected abstract TDownloadRequestModel CreateDownloadRequest(TModel model); + /// + /// Creates the download request for this . + /// The parameters will be provided when the download was initiated with extra options meant + /// to be used in the creation of the request. + /// + /// The to be downloaded. + /// Extra parameters for request creation, null if none were passed. + /// The request object. + protected abstract TDownloadRequestModel CreateDownloadRequest(TModel model, object[] options); /// /// Downloads a . @@ -55,7 +63,24 @@ namespace osu.Game.Database { if (!canDownload(model)) return false; - var request = CreateDownloadRequest(model); + var request = CreateDownloadRequest(model, null); + + performDownloadWithRequest(request); + + return true; + } + + /// + /// Downloads a with optional parameters for the download request. + /// + /// The to be downloaded. + /// Optional parameters to be used for creating the download request. + /// Whether downloading can happen. + public bool Download(TModel model, params object[] extra) + { + if (!canDownload(model)) return false; + + var request = CreateDownloadRequest(model, extra); performDownloadWithRequest(request); From 709ca03a08a3cad591a3911b01734fd100ad3923 Mon Sep 17 00:00:00 2001 From: naoey Date: Tue, 11 Jun 2019 20:21:06 +0530 Subject: [PATCH 033/148] Remove unused usings --- osu.Game/Beatmaps/BeatmapManager.cs | 2 -- osu.Game/Database/ArchiveDownloadModelManager.cs | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index 6f27cbd7c6..6ad5ce6617 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -6,7 +6,6 @@ using System.Collections.Generic; using System.IO; using System.Linq; using System.Linq.Expressions; -using System.Threading.Tasks; using Microsoft.EntityFrameworkCore; using osu.Framework.Audio; using osu.Framework.Audio.Track; @@ -19,7 +18,6 @@ using osu.Game.Database; using osu.Game.IO.Archives; using osu.Game.Online.API; using osu.Game.Online.API.Requests; -using osu.Game.Overlays.Notifications; using osu.Game.Rulesets; namespace osu.Game.Beatmaps diff --git a/osu.Game/Database/ArchiveDownloadModelManager.cs b/osu.Game/Database/ArchiveDownloadModelManager.cs index a4d2180559..629cb81440 100644 --- a/osu.Game/Database/ArchiveDownloadModelManager.cs +++ b/osu.Game/Database/ArchiveDownloadModelManager.cs @@ -38,7 +38,7 @@ namespace osu.Game.Database private readonly List currentDownloads = new List(); protected ArchiveDownloadModelManager(Storage storage, IDatabaseContextFactory contextFactory, IAPIProvider api, MutableDatabaseBackedStoreWithFileIncludes modelStore, IIpcHost importHost = null) - :base(storage, contextFactory, modelStore, importHost) + : base(storage, contextFactory, modelStore, importHost) { this.api = api; } From f4dab4da85df762b3998c1ad4d157529a42d031b Mon Sep 17 00:00:00 2001 From: naoey Date: Tue, 11 Jun 2019 20:53:44 +0530 Subject: [PATCH 034/148] Add method to check if model exists locally already --- osu.Game/Database/ArchiveDownloadModelManager.cs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/osu.Game/Database/ArchiveDownloadModelManager.cs b/osu.Game/Database/ArchiveDownloadModelManager.cs index 629cb81440..3c0de0b566 100644 --- a/osu.Game/Database/ArchiveDownloadModelManager.cs +++ b/osu.Game/Database/ArchiveDownloadModelManager.cs @@ -7,6 +7,7 @@ using osu.Game.Online.API; using osu.Game.Overlays.Notifications; using System; using System.Collections.Generic; +using System.Linq; using System.Threading.Tasks; namespace osu.Game.Database @@ -37,10 +38,13 @@ namespace osu.Game.Database private readonly List currentDownloads = new List(); + private readonly MutableDatabaseBackedStoreWithFileIncludes modelStore; + protected ArchiveDownloadModelManager(Storage storage, IDatabaseContextFactory contextFactory, IAPIProvider api, MutableDatabaseBackedStoreWithFileIncludes modelStore, IIpcHost importHost = null) : base(storage, contextFactory, modelStore, importHost) { this.api = api; + this.modelStore = modelStore; } /// @@ -70,6 +74,13 @@ namespace osu.Game.Database return true; } + /// + /// Checks whether a given is available in the local store already. + /// + /// The whose existence needs to be checked. + /// Whether the exists locally. + public bool IsAvailableLocally(TModel model) => modelStore.ConsumableItems.Any(m => m.Equals(model)); + /// /// Downloads a with optional parameters for the download request. /// From 06a558c4b7127107b494d8dfe9db3f50263e86e5 Mon Sep 17 00:00:00 2001 From: naoey Date: Tue, 11 Jun 2019 21:11:30 +0530 Subject: [PATCH 035/148] Remove unecessary third generic and change usages to match --- osu.Game/Beatmaps/BeatmapManager.cs | 6 ++---- .../Database/ArchiveDownloadModelManager.cs | 18 ++++++++---------- .../API/Requests/DownloadBeatmapSetRequest.cs | 7 +++---- .../Direct/DownloadTrackingComposite.cs | 8 ++++---- 4 files changed, 17 insertions(+), 22 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index 6ad5ce6617..2dcd1b137c 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -25,7 +25,7 @@ namespace osu.Game.Beatmaps /// /// Handles the storage and retrieval of Beatmaps/WorkingBeatmaps. /// - public partial class BeatmapManager : ArchiveDownloadModelManager + public partial class BeatmapManager : ArchiveDownloadModelManager { /// /// Fired when a single difficulty has been hidden. @@ -58,8 +58,6 @@ namespace osu.Game.Beatmaps private readonly GameHost host; - private readonly List currentDownloads = new List(); - public BeatmapManager(Storage storage, IDatabaseContextFactory contextFactory, RulesetStore rulesets, IAPIProvider api, AudioManager audioManager, GameHost host = null, WorkingBeatmap defaultBeatmap = null) : base(storage, contextFactory, api, new BeatmapStore(contextFactory), host) @@ -76,7 +74,7 @@ namespace osu.Game.Beatmaps beatmaps.BeatmapRestored += b => BeatmapRestored?.Invoke(b); } - protected override DownloadBeatmapSetRequest CreateDownloadRequest(BeatmapSetInfo set, object[] options) => new DownloadBeatmapSetRequest(set, (options?.FirstOrDefault() as bool?) ?? false); + protected override ArchiveDownloadModelRequest CreateDownloadRequest(BeatmapSetInfo set, object[] options) => new DownloadBeatmapSetRequest(set, (options?.FirstOrDefault() as bool?) ?? false); protected override void Populate(BeatmapSetInfo beatmapSet, ArchiveReader archive) { diff --git a/osu.Game/Database/ArchiveDownloadModelManager.cs b/osu.Game/Database/ArchiveDownloadModelManager.cs index 3c0de0b566..64920710bc 100644 --- a/osu.Game/Database/ArchiveDownloadModelManager.cs +++ b/osu.Game/Database/ArchiveDownloadModelManager.cs @@ -18,25 +18,23 @@ namespace osu.Game.Database /// /// The model type. /// The associated file join type. - /// The associated for this model. - public abstract class ArchiveDownloadModelManager : ArchiveModelManager + public abstract class ArchiveDownloadModelManager : ArchiveModelManager where TModel : class, IHasFiles, IHasPrimaryKey, ISoftDelete where TFileModel : INamedFileInfo, new() - where TDownloadRequestModel : ArchiveDownloadModelRequest { /// /// Fired when a download begins. /// - public event Action DownloadBegan; + public event Action> DownloadBegan; /// /// Fired when a download is interrupted, either due to user cancellation or failure. /// - public event Action DownloadFailed; + public event Action> DownloadFailed; private readonly IAPIProvider api; - private readonly List currentDownloads = new List(); + private readonly List> currentDownloads = new List>(); private readonly MutableDatabaseBackedStoreWithFileIncludes modelStore; @@ -55,7 +53,7 @@ namespace osu.Game.Database /// The to be downloaded. /// Extra parameters for request creation, null if none were passed. /// The request object. - protected abstract TDownloadRequestModel CreateDownloadRequest(TModel model, object[] options); + protected abstract ArchiveDownloadModelRequest CreateDownloadRequest(TModel model, object[] options); /// /// Downloads a . @@ -102,12 +100,12 @@ namespace osu.Game.Database /// Gets an existing download request if it exists. /// /// The whose request is wanted. - /// The object if it exists, otherwise null. - public TDownloadRequestModel GetExistingDownload(TModel model) => currentDownloads.Find(r => r.Info.Equals(model)); + /// The object if it exists, otherwise null. + public ArchiveDownloadModelRequest GetExistingDownload(TModel model) => currentDownloads.Find(r => r.Info.Equals(model)); private bool canDownload(TModel model) => GetExistingDownload(model) == null && api != null; - private void performDownloadWithRequest(TDownloadRequestModel request) + private void performDownloadWithRequest(ArchiveDownloadModelRequest request) { DownloadNotification notification = new DownloadNotification { diff --git a/osu.Game/Online/API/Requests/DownloadBeatmapSetRequest.cs b/osu.Game/Online/API/Requests/DownloadBeatmapSetRequest.cs index 7d0a8f9f46..8d636f6730 100644 --- a/osu.Game/Online/API/Requests/DownloadBeatmapSetRequest.cs +++ b/osu.Game/Online/API/Requests/DownloadBeatmapSetRequest.cs @@ -7,17 +7,16 @@ namespace osu.Game.Online.API.Requests { public class DownloadBeatmapSetRequest : ArchiveDownloadModelRequest { - public readonly BeatmapSetInfo BeatmapSet; - private readonly bool noVideo; + private readonly BeatmapSetInfo set; public DownloadBeatmapSetRequest(BeatmapSetInfo set, bool noVideo) : base(set) { this.noVideo = noVideo; - BeatmapSet = set; + this.set = set; } - protected override string Target => $@"beatmapsets/{BeatmapSet.OnlineBeatmapSetID}/download{(noVideo ? "?noVideo=1" : "")}"; + protected override string Target => $@"beatmapsets/{set.OnlineBeatmapSetID}/download{(noVideo ? "?noVideo=1" : "")}"; } } diff --git a/osu.Game/Overlays/Direct/DownloadTrackingComposite.cs b/osu.Game/Overlays/Direct/DownloadTrackingComposite.cs index 9beedb195f..c1ff6ecb60 100644 --- a/osu.Game/Overlays/Direct/DownloadTrackingComposite.cs +++ b/osu.Game/Overlays/Direct/DownloadTrackingComposite.cs @@ -7,7 +7,7 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics.Containers; using osu.Game.Beatmaps; -using osu.Game.Online.API.Requests; +using osu.Game.Online.API; namespace osu.Game.Overlays.Direct { @@ -49,7 +49,7 @@ namespace osu.Game.Overlays.Direct beatmaps.DownloadBegan += download => { - if (download.BeatmapSet.OnlineBeatmapSetID == BeatmapSet.Value?.OnlineBeatmapSetID) + if (download.Info.OnlineBeatmapSetID == BeatmapSet.Value?.OnlineBeatmapSetID) attachDownload(download); }; @@ -76,9 +76,9 @@ namespace osu.Game.Overlays.Direct #endregion - private DownloadBeatmapSetRequest attachedRequest; + private ArchiveDownloadModelRequest attachedRequest; - private void attachDownload(DownloadBeatmapSetRequest request) + private void attachDownload(ArchiveDownloadModelRequest request) { if (attachedRequest != null) { From d903ad2186ed7c6e81fc2c4982eef2e5b89e5ee3 Mon Sep 17 00:00:00 2001 From: naoey Date: Tue, 11 Jun 2019 21:30:25 +0530 Subject: [PATCH 036/148] Fix order --- osu.Game/Database/ArchiveDownloadModelManager.cs | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/osu.Game/Database/ArchiveDownloadModelManager.cs b/osu.Game/Database/ArchiveDownloadModelManager.cs index 64920710bc..2fb661ccce 100644 --- a/osu.Game/Database/ArchiveDownloadModelManager.cs +++ b/osu.Game/Database/ArchiveDownloadModelManager.cs @@ -72,15 +72,9 @@ namespace osu.Game.Database return true; } - /// - /// Checks whether a given is available in the local store already. - /// - /// The whose existence needs to be checked. - /// Whether the exists locally. - public bool IsAvailableLocally(TModel model) => modelStore.ConsumableItems.Any(m => m.Equals(model)); - /// /// Downloads a with optional parameters for the download request. + /// This will post notifications tracking progress. /// /// The to be downloaded. /// Optional parameters to be used for creating the download request. @@ -96,6 +90,13 @@ namespace osu.Game.Database return true; } + /// + /// Checks whether a given is available in the local store already. + /// + /// The whose existence needs to be checked. + /// Whether the exists locally. + public bool IsAvailableLocally(TModel model) => modelStore.ConsumableItems.Any(m => m.Equals(model)); + /// /// Gets an existing download request if it exists. /// From 4a6074865e270a66c170fa508a9cb1ee126f4dec Mon Sep 17 00:00:00 2001 From: naoey Date: Tue, 11 Jun 2019 22:42:57 +0530 Subject: [PATCH 037/148] Create interfaces for DownloadTrackingComposite to consume --- osu.Game/Beatmaps/BeatmapManager.cs | 2 + .../Database/ArchiveDownloadModelManager.cs | 28 +---------- osu.Game/Database/ArchiveModelManager.cs | 2 +- osu.Game/Database/IDownloadModelManager.cs | 47 +++++++++++++++++++ osu.Game/Database/IModelManager.cs | 20 ++++++++ 5 files changed, 72 insertions(+), 27 deletions(-) create mode 100644 osu.Game/Database/IDownloadModelManager.cs create mode 100644 osu.Game/Database/IModelManager.cs diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index 2dcd1b137c..e124e38dd9 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -229,6 +229,8 @@ namespace osu.Game.Beatmaps /// Results from the provided query. public IQueryable QueryBeatmaps(Expression> query) => beatmaps.Beatmaps.AsNoTracking().Where(query); + public override bool IsAvailableLocally(BeatmapSetInfo set) => beatmaps.ConsumableItems.Any(s => s.OnlineBeatmapSetID == set.OnlineBeatmapSetID && !s.DeletePending && !s.Protected); + protected override BeatmapSetInfo CreateModel(ArchiveReader reader) { // let's make sure there are actually .osu files to import. diff --git a/osu.Game/Database/ArchiveDownloadModelManager.cs b/osu.Game/Database/ArchiveDownloadModelManager.cs index 2fb661ccce..c868b8d1d5 100644 --- a/osu.Game/Database/ArchiveDownloadModelManager.cs +++ b/osu.Game/Database/ArchiveDownloadModelManager.cs @@ -18,18 +18,12 @@ namespace osu.Game.Database /// /// The model type. /// The associated file join type. - public abstract class ArchiveDownloadModelManager : ArchiveModelManager + public abstract class ArchiveDownloadModelManager : ArchiveModelManager, IDownloadModelManager where TModel : class, IHasFiles, IHasPrimaryKey, ISoftDelete where TFileModel : INamedFileInfo, new() { - /// - /// Fired when a download begins. - /// public event Action> DownloadBegan; - /// - /// Fired when a download is interrupted, either due to user cancellation or failure. - /// public event Action> DownloadFailed; private readonly IAPIProvider api; @@ -55,12 +49,6 @@ namespace osu.Game.Database /// The request object. protected abstract ArchiveDownloadModelRequest CreateDownloadRequest(TModel model, object[] options); - /// - /// Downloads a . - /// This will post notifications tracking progress. - /// - /// The to be downloaded. - /// Whether downloading can happen. public bool Download(TModel model) { if (!canDownload(model)) return false; @@ -72,13 +60,6 @@ namespace osu.Game.Database return true; } - /// - /// Downloads a with optional parameters for the download request. - /// This will post notifications tracking progress. - /// - /// The to be downloaded. - /// Optional parameters to be used for creating the download request. - /// Whether downloading can happen. public bool Download(TModel model, params object[] extra) { if (!canDownload(model)) return false; @@ -90,12 +71,7 @@ namespace osu.Game.Database return true; } - /// - /// Checks whether a given is available in the local store already. - /// - /// The whose existence needs to be checked. - /// Whether the exists locally. - public bool IsAvailableLocally(TModel model) => modelStore.ConsumableItems.Any(m => m.Equals(model)); + public virtual bool IsAvailableLocally(TModel model) => modelStore.ConsumableItems.Any(m => m.Equals(model) && !m.DeletePending); /// /// Gets an existing download request if it exists. diff --git a/osu.Game/Database/ArchiveModelManager.cs b/osu.Game/Database/ArchiveModelManager.cs index 54dbae9ddc..50cb9dac8b 100644 --- a/osu.Game/Database/ArchiveModelManager.cs +++ b/osu.Game/Database/ArchiveModelManager.cs @@ -29,7 +29,7 @@ namespace osu.Game.Database /// /// The model type. /// The associated file join type. - public abstract class ArchiveModelManager : ICanAcceptFiles + public abstract class ArchiveModelManager : ICanAcceptFiles, IModelManager where TModel : class, IHasFiles, IHasPrimaryKey, ISoftDelete where TFileModel : INamedFileInfo, new() { diff --git a/osu.Game/Database/IDownloadModelManager.cs b/osu.Game/Database/IDownloadModelManager.cs new file mode 100644 index 0000000000..3231d855ea --- /dev/null +++ b/osu.Game/Database/IDownloadModelManager.cs @@ -0,0 +1,47 @@ +using osu.Game.Online.API; +using System; +using System.Collections.Generic; +using System.Text; + +namespace osu.Game.Database +{ + public interface IDownloadModelManager : IModelManager + where TModel : class + { + /// + /// Fired when a download begins. + /// + event Action> DownloadBegan; + + /// + /// Fired when a download is interrupted, either due to user cancellation or failure. + /// + event Action> DownloadFailed; + + bool IsAvailableLocally(TModel model); + + /// + /// Downloads a . + /// This will post notifications tracking progress. + /// + /// The to be downloaded. + /// Whether downloading can happen. + bool Download(TModel model); + + /// + /// Downloads a with optional parameters for the download request. + /// This will post notifications tracking progress. + /// + /// The to be downloaded. + /// Optional parameters to be used for creating the download request. + /// Whether downloading can happen. + bool Download(TModel model, params object[] extra); + + /// + /// Checks whether a given is available in the local store already. + /// + /// The whose existence needs to be checked. + /// Whether the exists locally. + ArchiveDownloadModelRequest GetExistingDownload(TModel model); + } +} diff --git a/osu.Game/Database/IModelManager.cs b/osu.Game/Database/IModelManager.cs new file mode 100644 index 0000000000..6a0b2bde44 --- /dev/null +++ b/osu.Game/Database/IModelManager.cs @@ -0,0 +1,20 @@ + +using System; + +namespace osu.Game.Database +{ + public interface IModelManager + { + /// + /// Fired when a new becomes available in the database. + /// This is not guaranteed to run on the update thread. + /// + event Action ItemAdded; + + /// + /// Fired when a is removed from the database. + /// This is not guaranteed to run on the update thread. + /// + event Action ItemRemoved; + } +} From ab27d82cd581acba8e738a33704484335edd0f69 Mon Sep 17 00:00:00 2001 From: naoey Date: Tue, 11 Jun 2019 23:01:01 +0530 Subject: [PATCH 038/148] Make beatmap download buttons inherit BeatmapDownloadTrackingComposite - Move DownloadTrackingComposite into the online namespace --- osu.Game/Database/ArchiveModelManager.cs | 4 +- .../Direct => Online}/DownloadState.cs | 2 +- .../DownloadTrackingComposite.cs | 53 ++++++++++--------- .../BeatmapSet/Buttons/DownloadButton.cs | 3 +- osu.Game/Overlays/BeatmapSet/Header.cs | 3 +- .../BeatmapDownloadTrackingComposite.cs | 16 ++++++ osu.Game/Overlays/Direct/DownloadButton.cs | 3 +- .../Overlays/Direct/DownloadProgressBar.cs | 3 +- 8 files changed, 55 insertions(+), 32 deletions(-) rename osu.Game/{Overlays/Direct => Online}/DownloadState.cs (89%) rename osu.Game/{Overlays/Direct => Online}/DownloadTrackingComposite.cs (63%) create mode 100644 osu.Game/Overlays/Direct/BeatmapDownloadTrackingComposite.cs diff --git a/osu.Game/Database/ArchiveModelManager.cs b/osu.Game/Database/ArchiveModelManager.cs index 50cb9dac8b..ccaba99427 100644 --- a/osu.Game/Database/ArchiveModelManager.cs +++ b/osu.Game/Database/ArchiveModelManager.cs @@ -29,7 +29,7 @@ namespace osu.Game.Database /// /// The model type. /// The associated file join type. - public abstract class ArchiveModelManager : ICanAcceptFiles, IModelManager + public abstract class ArchiveModelManager : ICanAcceptFiles, IModelManager where TModel : class, IHasFiles, IHasPrimaryKey, ISoftDelete where TFileModel : INamedFileInfo, new() { @@ -44,7 +44,7 @@ namespace osu.Game.Database /// Fired when a new becomes available in the database. /// This is not guaranteed to run on the update thread. /// - public event ItemAddedDelegate ItemAdded; + public event Action ItemAdded; /// /// Fired when a is removed from the database. diff --git a/osu.Game/Overlays/Direct/DownloadState.cs b/osu.Game/Online/DownloadState.cs similarity index 89% rename from osu.Game/Overlays/Direct/DownloadState.cs rename to osu.Game/Online/DownloadState.cs index a301c6a3bd..72efbc286e 100644 --- a/osu.Game/Overlays/Direct/DownloadState.cs +++ b/osu.Game/Online/DownloadState.cs @@ -1,7 +1,7 @@ // 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.Direct +namespace osu.Game.Online { public enum DownloadState { diff --git a/osu.Game/Overlays/Direct/DownloadTrackingComposite.cs b/osu.Game/Online/DownloadTrackingComposite.cs similarity index 63% rename from osu.Game/Overlays/Direct/DownloadTrackingComposite.cs rename to osu.Game/Online/DownloadTrackingComposite.cs index c1ff6ecb60..157211e6c2 100644 --- a/osu.Game/Overlays/Direct/DownloadTrackingComposite.cs +++ b/osu.Game/Online/DownloadTrackingComposite.cs @@ -7,18 +7,21 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics.Containers; using osu.Game.Beatmaps; +using osu.Game.Database; using osu.Game.Online.API; -namespace osu.Game.Overlays.Direct +namespace osu.Game.Online { /// /// A component which tracks a beatmap through potential download/import/deletion. /// - public abstract class DownloadTrackingComposite : CompositeDrawable + public abstract class DownloadTrackingComposite : CompositeDrawable + where TModel : class + where TModelManager : class, IDownloadModelManager { - public readonly Bindable BeatmapSet = new Bindable(); + public readonly Bindable ModelInfo = new Bindable(); - private BeatmapManager beatmaps; + private TModelManager manager; /// /// Holds the current download state of the beatmap, whether is has already been downloaded, is in progress, or is not downloaded. @@ -27,34 +30,34 @@ namespace osu.Game.Overlays.Direct protected readonly Bindable Progress = new Bindable(); - protected DownloadTrackingComposite(BeatmapSetInfo beatmapSet = null) + protected DownloadTrackingComposite(TModel model = null) { - BeatmapSet.Value = beatmapSet; + ModelInfo.Value = model; } [BackgroundDependencyLoader(true)] - private void load(BeatmapManager beatmaps) + private void load(TModelManager manager) { - this.beatmaps = beatmaps; + this.manager = manager; - BeatmapSet.BindValueChanged(setInfo => + ModelInfo.BindValueChanged(modelInfo => { - if (setInfo.NewValue == null) + if (modelInfo.NewValue == null) attachDownload(null); - else if (beatmaps.GetAllUsableBeatmapSetsEnumerable().Any(s => s.OnlineBeatmapSetID == setInfo.NewValue.OnlineBeatmapSetID)) + else if (manager.IsAvailableLocally(modelInfo.NewValue)) State.Value = DownloadState.LocallyAvailable; else - attachDownload(beatmaps.GetExistingDownload(setInfo.NewValue)); + attachDownload(manager.GetExistingDownload(modelInfo.NewValue)); }, true); - beatmaps.DownloadBegan += download => + manager.DownloadBegan += download => { - if (download.Info.OnlineBeatmapSetID == BeatmapSet.Value?.OnlineBeatmapSetID) + if (download.Info.Equals(ModelInfo.Value)) attachDownload(download); }; - beatmaps.ItemAdded += setAdded; - beatmaps.ItemRemoved += setRemoved; + manager.ItemAdded += itemAdded; + manager.ItemRemoved += itemRemoved; } #region Disposal @@ -63,10 +66,10 @@ namespace osu.Game.Overlays.Direct { base.Dispose(isDisposing); - if (beatmaps != null) + if (manager != null) { - beatmaps.DownloadBegan -= attachDownload; - beatmaps.ItemAdded -= setAdded; + manager.DownloadBegan -= attachDownload; + manager.ItemAdded -= itemAdded; } State.UnbindAll(); @@ -76,9 +79,9 @@ namespace osu.Game.Overlays.Direct #endregion - private ArchiveDownloadModelRequest attachedRequest; + private ArchiveDownloadModelRequest attachedRequest; - private void attachDownload(ArchiveDownloadModelRequest request) + private void attachDownload(ArchiveDownloadModelRequest request) { if (attachedRequest != null) { @@ -118,13 +121,13 @@ namespace osu.Game.Overlays.Direct private void onRequestFailure(Exception e) => Schedule(() => attachDownload(null)); - private void setAdded(BeatmapSetInfo s, bool existing) => setDownloadStateFromManager(s, DownloadState.LocallyAvailable); + private void itemAdded(TModel s, bool existing) => setDownloadStateFromManager(s, DownloadState.LocallyAvailable); - private void setRemoved(BeatmapSetInfo s) => setDownloadStateFromManager(s, DownloadState.NotDownloaded); + private void itemRemoved(TModel s) => setDownloadStateFromManager(s, DownloadState.NotDownloaded); - private void setDownloadStateFromManager(BeatmapSetInfo s, DownloadState state) => Schedule(() => + private void setDownloadStateFromManager(TModel s, DownloadState state) => Schedule(() => { - if (s.OnlineBeatmapSetID != BeatmapSet.Value?.OnlineBeatmapSetID) + if (s.Equals(ModelInfo.Value)) return; State.Value = state; diff --git a/osu.Game/Overlays/BeatmapSet/Buttons/DownloadButton.cs b/osu.Game/Overlays/BeatmapSet/Buttons/DownloadButton.cs index 0a159507fe..3e8a5a8324 100644 --- a/osu.Game/Overlays/BeatmapSet/Buttons/DownloadButton.cs +++ b/osu.Game/Overlays/BeatmapSet/Buttons/DownloadButton.cs @@ -11,6 +11,7 @@ using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; +using osu.Game.Online; using osu.Game.Online.API; using osu.Game.Overlays.Direct; using osu.Game.Users; @@ -19,7 +20,7 @@ using osuTK.Graphics; namespace osu.Game.Overlays.BeatmapSet.Buttons { - public class DownloadButton : DownloadTrackingComposite, IHasTooltip + public class DownloadButton : BeatmapDownloadTrackingComposite, IHasTooltip { private readonly bool noVideo; diff --git a/osu.Game/Overlays/BeatmapSet/Header.cs b/osu.Game/Overlays/BeatmapSet/Header.cs index a0f71d05c0..d0c6e4aa62 100644 --- a/osu.Game/Overlays/BeatmapSet/Header.cs +++ b/osu.Game/Overlays/BeatmapSet/Header.cs @@ -13,6 +13,7 @@ using osu.Game.Beatmaps.Drawables; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; +using osu.Game.Online; using osu.Game.Overlays.BeatmapSet.Buttons; using osu.Game.Overlays.Direct; using osuTK; @@ -21,7 +22,7 @@ using DownloadButton = osu.Game.Overlays.BeatmapSet.Buttons.DownloadButton; namespace osu.Game.Overlays.BeatmapSet { - public class Header : DownloadTrackingComposite + public class Header : BeatmapDownloadTrackingComposite { private const float transition_duration = 200; private const float tabs_height = 50; diff --git a/osu.Game/Overlays/Direct/BeatmapDownloadTrackingComposite.cs b/osu.Game/Overlays/Direct/BeatmapDownloadTrackingComposite.cs new file mode 100644 index 0000000000..67fc5b48bd --- /dev/null +++ b/osu.Game/Overlays/Direct/BeatmapDownloadTrackingComposite.cs @@ -0,0 +1,16 @@ +using osu.Framework.Bindables; +using osu.Game.Beatmaps; +using osu.Game.Online; + +namespace osu.Game.Overlays.Direct +{ + public abstract class BeatmapDownloadTrackingComposite : DownloadTrackingComposite + { + public Bindable BeatmapSet => ModelInfo; + + public BeatmapDownloadTrackingComposite(BeatmapSetInfo set = null) + : base(set) + { + } + } +} diff --git a/osu.Game/Overlays/Direct/DownloadButton.cs b/osu.Game/Overlays/Direct/DownloadButton.cs index 3f44d854e5..348ce427bd 100644 --- a/osu.Game/Overlays/Direct/DownloadButton.cs +++ b/osu.Game/Overlays/Direct/DownloadButton.cs @@ -9,11 +9,12 @@ using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Graphics.UserInterface; +using osu.Game.Online; using osuTK; namespace osu.Game.Overlays.Direct { - public class DownloadButton : DownloadTrackingComposite + public class DownloadButton : BeatmapDownloadTrackingComposite { private readonly bool noVideo; private readonly SpriteIcon icon; diff --git a/osu.Game/Overlays/Direct/DownloadProgressBar.cs b/osu.Game/Overlays/Direct/DownloadProgressBar.cs index 57500b3531..a6cefaae84 100644 --- a/osu.Game/Overlays/Direct/DownloadProgressBar.cs +++ b/osu.Game/Overlays/Direct/DownloadProgressBar.cs @@ -7,11 +7,12 @@ using osu.Framework.Graphics; using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Graphics.UserInterface; +using osu.Game.Online; using osuTK.Graphics; namespace osu.Game.Overlays.Direct { - public class DownloadProgressBar : DownloadTrackingComposite + public class DownloadProgressBar : BeatmapDownloadTrackingComposite { private readonly ProgressBar progressBar; From 41da491a7eb3d9287c7e1725214f4e456576bdd7 Mon Sep 17 00:00:00 2001 From: naoey Date: Tue, 11 Jun 2019 23:23:40 +0530 Subject: [PATCH 039/148] Make BeatmapSetInfo equatable --- osu.Game/Beatmaps/BeatmapSetInfo.cs | 4 +++- osu.Game/Online/DownloadTrackingComposite.cs | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapSetInfo.cs b/osu.Game/Beatmaps/BeatmapSetInfo.cs index 390236e053..aa5ed48641 100644 --- a/osu.Game/Beatmaps/BeatmapSetInfo.cs +++ b/osu.Game/Beatmaps/BeatmapSetInfo.cs @@ -9,7 +9,7 @@ using osu.Game.Database; namespace osu.Game.Beatmaps { - public class BeatmapSetInfo : IHasPrimaryKey, IHasFiles, ISoftDelete + public class BeatmapSetInfo : IHasPrimaryKey, IHasFiles, ISoftDelete, IEquatable { public int ID { get; set; } @@ -46,5 +46,7 @@ namespace osu.Game.Beatmaps public override string ToString() => Metadata?.ToString() ?? base.ToString(); public bool Protected { get; set; } + + public bool Equals(BeatmapSetInfo other) => OnlineBeatmapSetID == other?.OnlineBeatmapSetID; } } diff --git a/osu.Game/Online/DownloadTrackingComposite.cs b/osu.Game/Online/DownloadTrackingComposite.cs index 157211e6c2..d233be19f5 100644 --- a/osu.Game/Online/DownloadTrackingComposite.cs +++ b/osu.Game/Online/DownloadTrackingComposite.cs @@ -16,7 +16,7 @@ namespace osu.Game.Online /// A component which tracks a beatmap through potential download/import/deletion. /// public abstract class DownloadTrackingComposite : CompositeDrawable - where TModel : class + where TModel : class, IEquatable where TModelManager : class, IDownloadModelManager { public readonly Bindable ModelInfo = new Bindable(); From c320b6110cf463a1f5e74050e320468a26a484a1 Mon Sep 17 00:00:00 2001 From: naoey Date: Tue, 11 Jun 2019 23:47:05 +0530 Subject: [PATCH 040/148] Rename interface - Fix wrong inheritance in ArchiveModelManager - Add license headers --- osu.Game/Database/ArchiveDownloadModelManager.cs | 2 +- osu.Game/Database/ArchiveModelManager.cs | 4 ++-- ...{IDownloadModelManager.cs => IModelDownloader.cs} | 9 +++++---- osu.Game/Database/IModelManager.cs | 12 +++--------- 4 files changed, 11 insertions(+), 16 deletions(-) rename osu.Game/Database/{IDownloadModelManager.cs => IModelDownloader.cs} (87%) diff --git a/osu.Game/Database/ArchiveDownloadModelManager.cs b/osu.Game/Database/ArchiveDownloadModelManager.cs index c868b8d1d5..8d221bd3ea 100644 --- a/osu.Game/Database/ArchiveDownloadModelManager.cs +++ b/osu.Game/Database/ArchiveDownloadModelManager.cs @@ -18,7 +18,7 @@ namespace osu.Game.Database /// /// The model type. /// The associated file join type. - public abstract class ArchiveDownloadModelManager : ArchiveModelManager, IDownloadModelManager + public abstract class ArchiveDownloadModelManager : ArchiveModelManager, IModelDownloader where TModel : class, IHasFiles, IHasPrimaryKey, ISoftDelete where TFileModel : INamedFileInfo, new() { diff --git a/osu.Game/Database/ArchiveModelManager.cs b/osu.Game/Database/ArchiveModelManager.cs index 50cb9dac8b..ccaba99427 100644 --- a/osu.Game/Database/ArchiveModelManager.cs +++ b/osu.Game/Database/ArchiveModelManager.cs @@ -29,7 +29,7 @@ namespace osu.Game.Database /// /// The model type. /// The associated file join type. - public abstract class ArchiveModelManager : ICanAcceptFiles, IModelManager + public abstract class ArchiveModelManager : ICanAcceptFiles, IModelManager where TModel : class, IHasFiles, IHasPrimaryKey, ISoftDelete where TFileModel : INamedFileInfo, new() { @@ -44,7 +44,7 @@ namespace osu.Game.Database /// Fired when a new becomes available in the database. /// This is not guaranteed to run on the update thread. /// - public event ItemAddedDelegate ItemAdded; + public event Action ItemAdded; /// /// Fired when a is removed from the database. diff --git a/osu.Game/Database/IDownloadModelManager.cs b/osu.Game/Database/IModelDownloader.cs similarity index 87% rename from osu.Game/Database/IDownloadModelManager.cs rename to osu.Game/Database/IModelDownloader.cs index 3231d855ea..bf987bb53c 100644 --- a/osu.Game/Database/IDownloadModelManager.cs +++ b/osu.Game/Database/IModelDownloader.cs @@ -1,11 +1,12 @@ -using osu.Game.Online.API; +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Game.Online.API; using System; -using System.Collections.Generic; -using System.Text; namespace osu.Game.Database { - public interface IDownloadModelManager : IModelManager + public interface IModelDownloader : IModelManager where TModel : class { /// diff --git a/osu.Game/Database/IModelManager.cs b/osu.Game/Database/IModelManager.cs index 6a0b2bde44..ee78df3db4 100644 --- a/osu.Game/Database/IModelManager.cs +++ b/osu.Game/Database/IModelManager.cs @@ -1,20 +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; namespace osu.Game.Database { public interface IModelManager { - /// - /// Fired when a new becomes available in the database. - /// This is not guaranteed to run on the update thread. - /// event Action ItemAdded; - /// - /// Fired when a is removed from the database. - /// This is not guaranteed to run on the update thread. - /// event Action ItemRemoved; } } From c69d3e2d388c794a0fcc33efdbc8b37999c48c68 Mon Sep 17 00:00:00 2001 From: naoey Date: Wed, 12 Jun 2019 00:02:53 +0530 Subject: [PATCH 041/148] Fix doc move derp --- osu.Game/Database/ArchiveDownloadModelManager.cs | 10 +++++----- osu.Game/Database/IModelDownloader.cs | 6 +++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/osu.Game/Database/ArchiveDownloadModelManager.cs b/osu.Game/Database/ArchiveDownloadModelManager.cs index 8d221bd3ea..ded44337dd 100644 --- a/osu.Game/Database/ArchiveDownloadModelManager.cs +++ b/osu.Game/Database/ArchiveDownloadModelManager.cs @@ -71,13 +71,13 @@ namespace osu.Game.Database return true; } + /// + /// Checks whether a given is available in the local store already. + /// + /// The whose existence needs to be checked. + /// Whether the exists locally. public virtual bool IsAvailableLocally(TModel model) => modelStore.ConsumableItems.Any(m => m.Equals(model) && !m.DeletePending); - /// - /// Gets an existing download request if it exists. - /// - /// The whose request is wanted. - /// The object if it exists, otherwise null. public ArchiveDownloadModelRequest GetExistingDownload(TModel model) => currentDownloads.Find(r => r.Info.Equals(model)); private bool canDownload(TModel model) => GetExistingDownload(model) == null && api != null; diff --git a/osu.Game/Database/IModelDownloader.cs b/osu.Game/Database/IModelDownloader.cs index bf987bb53c..150ad9522f 100644 --- a/osu.Game/Database/IModelDownloader.cs +++ b/osu.Game/Database/IModelDownloader.cs @@ -39,10 +39,10 @@ namespace osu.Game.Database bool Download(TModel model, params object[] extra); /// - /// Checks whether a given is available in the local store already. + /// Gets an existing download request if it exists. /// - /// The whose existence needs to be checked. - /// Whether the exists locally. + /// The whose request is wanted. + /// The object if it exists, otherwise null. ArchiveDownloadModelRequest GetExistingDownload(TModel model); } } From 7495bc5d3a97f457407a8f561b16d4b856f058ea Mon Sep 17 00:00:00 2001 From: naoey Date: Wed, 12 Jun 2019 00:41:17 +0530 Subject: [PATCH 042/148] Post merge and inverted condition fix --- osu.Game/Online/DownloadTrackingComposite.cs | 4 ++-- osu.Game/Overlays/Direct/BeatmapDownloadTrackingComposite.cs | 5 ++++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/osu.Game/Online/DownloadTrackingComposite.cs b/osu.Game/Online/DownloadTrackingComposite.cs index d233be19f5..0cb3acf019 100644 --- a/osu.Game/Online/DownloadTrackingComposite.cs +++ b/osu.Game/Online/DownloadTrackingComposite.cs @@ -17,7 +17,7 @@ namespace osu.Game.Online /// public abstract class DownloadTrackingComposite : CompositeDrawable where TModel : class, IEquatable - where TModelManager : class, IDownloadModelManager + where TModelManager : class, IModelDownloader { public readonly Bindable ModelInfo = new Bindable(); @@ -127,7 +127,7 @@ namespace osu.Game.Online private void setDownloadStateFromManager(TModel s, DownloadState state) => Schedule(() => { - if (s.Equals(ModelInfo.Value)) + if (!s.Equals(ModelInfo.Value)) return; State.Value = state; diff --git a/osu.Game/Overlays/Direct/BeatmapDownloadTrackingComposite.cs b/osu.Game/Overlays/Direct/BeatmapDownloadTrackingComposite.cs index 67fc5b48bd..b6304b82c4 100644 --- a/osu.Game/Overlays/Direct/BeatmapDownloadTrackingComposite.cs +++ b/osu.Game/Overlays/Direct/BeatmapDownloadTrackingComposite.cs @@ -1,4 +1,7 @@ -using osu.Framework.Bindables; +// 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.Bindables; using osu.Game.Beatmaps; using osu.Game.Online; From ba6546038c582d1d7249a078dac56624a49ac657 Mon Sep 17 00:00:00 2001 From: naoey Date: Wed, 12 Jun 2019 00:47:02 +0530 Subject: [PATCH 043/148] Make ModelInfo and abstract class constructor protected - Implementing classes would be better off exposing it if necessary under a different name --- osu.Game/Online/DownloadTrackingComposite.cs | 4 +--- osu.Game/Overlays/Direct/BeatmapDownloadTrackingComposite.cs | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/osu.Game/Online/DownloadTrackingComposite.cs b/osu.Game/Online/DownloadTrackingComposite.cs index 0cb3acf019..d07aed9206 100644 --- a/osu.Game/Online/DownloadTrackingComposite.cs +++ b/osu.Game/Online/DownloadTrackingComposite.cs @@ -2,11 +2,9 @@ // See the LICENCE file in the repository root for full licence text. using System; -using System.Linq; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics.Containers; -using osu.Game.Beatmaps; using osu.Game.Database; using osu.Game.Online.API; @@ -19,7 +17,7 @@ namespace osu.Game.Online where TModel : class, IEquatable where TModelManager : class, IModelDownloader { - public readonly Bindable ModelInfo = new Bindable(); + protected readonly Bindable ModelInfo = new Bindable(); private TModelManager manager; diff --git a/osu.Game/Overlays/Direct/BeatmapDownloadTrackingComposite.cs b/osu.Game/Overlays/Direct/BeatmapDownloadTrackingComposite.cs index b6304b82c4..6f348c4fd7 100644 --- a/osu.Game/Overlays/Direct/BeatmapDownloadTrackingComposite.cs +++ b/osu.Game/Overlays/Direct/BeatmapDownloadTrackingComposite.cs @@ -11,7 +11,7 @@ namespace osu.Game.Overlays.Direct { public Bindable BeatmapSet => ModelInfo; - public BeatmapDownloadTrackingComposite(BeatmapSetInfo set = null) + protected BeatmapDownloadTrackingComposite(BeatmapSetInfo set = null) : base(set) { } From 35cc45c9d9dff91795a90ef8785aa3bf99fe7228 Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Tue, 11 Jun 2019 23:11:03 +0300 Subject: [PATCH 044/148] Small update --- osu.Game.Tests/Visual/Online/TestSceneBeatmapNotAvailable.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneBeatmapNotAvailable.cs b/osu.Game.Tests/Visual/Online/TestSceneBeatmapNotAvailable.cs index bd4570470d..e2a5ab1e35 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneBeatmapNotAvailable.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneBeatmapNotAvailable.cs @@ -1,13 +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 NUnit.Framework; using osu.Game.Beatmaps; using osu.Game.Overlays.BeatmapSet; namespace osu.Game.Tests.Visual.Online { - [TestFixture] public class TestSceneBeatmapNotAvailable : OsuTestScene { public TestSceneBeatmapNotAvailable() From eaeeffaa866fd7a16108ffc96ac7544319232cf8 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 12 Jun 2019 13:28:44 +0900 Subject: [PATCH 045/148] Rename to DownloadableArchiveModelManager --- osu.Game/Beatmaps/BeatmapManager.cs | 2 +- ...loadModelManager.cs => DownloadableArchiveModelManager.cs} | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) rename osu.Game/Database/{ArchiveDownloadModelManager.cs => DownloadableArchiveModelManager.cs} (94%) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index e124e38dd9..023b6c74ea 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -25,7 +25,7 @@ namespace osu.Game.Beatmaps /// /// Handles the storage and retrieval of Beatmaps/WorkingBeatmaps. /// - public partial class BeatmapManager : ArchiveDownloadModelManager + public partial class BeatmapManager : DownloadableArchiveModelManager { /// /// Fired when a single difficulty has been hidden. diff --git a/osu.Game/Database/ArchiveDownloadModelManager.cs b/osu.Game/Database/DownloadableArchiveModelManager.cs similarity index 94% rename from osu.Game/Database/ArchiveDownloadModelManager.cs rename to osu.Game/Database/DownloadableArchiveModelManager.cs index ded44337dd..71bbbc4f78 100644 --- a/osu.Game/Database/ArchiveDownloadModelManager.cs +++ b/osu.Game/Database/DownloadableArchiveModelManager.cs @@ -18,7 +18,7 @@ namespace osu.Game.Database /// /// The model type. /// The associated file join type. - public abstract class ArchiveDownloadModelManager : ArchiveModelManager, IModelDownloader + public abstract class DownloadableArchiveModelManager : ArchiveModelManager, IModelDownloader where TModel : class, IHasFiles, IHasPrimaryKey, ISoftDelete where TFileModel : INamedFileInfo, new() { @@ -32,7 +32,7 @@ namespace osu.Game.Database private readonly MutableDatabaseBackedStoreWithFileIncludes modelStore; - protected ArchiveDownloadModelManager(Storage storage, IDatabaseContextFactory contextFactory, IAPIProvider api, MutableDatabaseBackedStoreWithFileIncludes modelStore, IIpcHost importHost = null) + protected DownloadableArchiveModelManager(Storage storage, IDatabaseContextFactory contextFactory, IAPIProvider api, MutableDatabaseBackedStoreWithFileIncludes modelStore, IIpcHost importHost = null) : base(storage, contextFactory, modelStore, importHost) { this.api = api; From c591a6f1fadd26a0c39855a867d95c2056bd6d82 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 12 Jun 2019 13:30:23 +0900 Subject: [PATCH 046/148] Rename request type to be less verbose --- osu.Game/Beatmaps/BeatmapManager.cs | 2 +- osu.Game/Database/DownloadableArchiveModelManager.cs | 12 ++++++------ osu.Game/Database/IModelDownloader.cs | 8 ++++---- ...loadModelRequest.cs => ArchiveDownloadRequest.cs} | 4 ++-- .../Online/API/Requests/DownloadBeatmapSetRequest.cs | 2 +- .../Overlays/Direct/DownloadTrackingComposite.cs | 4 ++-- 6 files changed, 16 insertions(+), 16 deletions(-) rename osu.Game/Online/API/{ArchiveDownloadModelRequest.cs => ArchiveDownloadRequest.cs} (78%) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index 023b6c74ea..3fc3de41e6 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -74,7 +74,7 @@ namespace osu.Game.Beatmaps beatmaps.BeatmapRestored += b => BeatmapRestored?.Invoke(b); } - protected override ArchiveDownloadModelRequest CreateDownloadRequest(BeatmapSetInfo set, object[] options) => new DownloadBeatmapSetRequest(set, (options?.FirstOrDefault() as bool?) ?? false); + protected override ArchiveDownloadRequest CreateDownloadRequest(BeatmapSetInfo set, object[] options) => new DownloadBeatmapSetRequest(set, (options?.FirstOrDefault() as bool?) ?? false); protected override void Populate(BeatmapSetInfo beatmapSet, ArchiveReader archive) { diff --git a/osu.Game/Database/DownloadableArchiveModelManager.cs b/osu.Game/Database/DownloadableArchiveModelManager.cs index 71bbbc4f78..c22c8d7508 100644 --- a/osu.Game/Database/DownloadableArchiveModelManager.cs +++ b/osu.Game/Database/DownloadableArchiveModelManager.cs @@ -22,13 +22,13 @@ namespace osu.Game.Database where TModel : class, IHasFiles, IHasPrimaryKey, ISoftDelete where TFileModel : INamedFileInfo, new() { - public event Action> DownloadBegan; + public event Action> DownloadBegan; - public event Action> DownloadFailed; + public event Action> DownloadFailed; private readonly IAPIProvider api; - private readonly List> currentDownloads = new List>(); + private readonly List> currentDownloads = new List>(); private readonly MutableDatabaseBackedStoreWithFileIncludes modelStore; @@ -47,7 +47,7 @@ namespace osu.Game.Database /// The to be downloaded. /// Extra parameters for request creation, null if none were passed. /// The request object. - protected abstract ArchiveDownloadModelRequest CreateDownloadRequest(TModel model, object[] options); + protected abstract ArchiveDownloadRequest CreateDownloadRequest(TModel model, object[] options); public bool Download(TModel model) { @@ -78,11 +78,11 @@ namespace osu.Game.Database /// Whether the exists locally. public virtual bool IsAvailableLocally(TModel model) => modelStore.ConsumableItems.Any(m => m.Equals(model) && !m.DeletePending); - public ArchiveDownloadModelRequest GetExistingDownload(TModel model) => currentDownloads.Find(r => r.Info.Equals(model)); + public ArchiveDownloadRequest GetExistingDownload(TModel model) => currentDownloads.Find(r => r.Info.Equals(model)); private bool canDownload(TModel model) => GetExistingDownload(model) == null && api != null; - private void performDownloadWithRequest(ArchiveDownloadModelRequest request) + private void performDownloadWithRequest(ArchiveDownloadRequest request) { DownloadNotification notification = new DownloadNotification { diff --git a/osu.Game/Database/IModelDownloader.cs b/osu.Game/Database/IModelDownloader.cs index 150ad9522f..83427bdc17 100644 --- a/osu.Game/Database/IModelDownloader.cs +++ b/osu.Game/Database/IModelDownloader.cs @@ -12,12 +12,12 @@ namespace osu.Game.Database /// /// Fired when a download begins. /// - event Action> DownloadBegan; + event Action> DownloadBegan; /// /// Fired when a download is interrupted, either due to user cancellation or failure. /// - event Action> DownloadFailed; + event Action> DownloadFailed; bool IsAvailableLocally(TModel model); @@ -42,7 +42,7 @@ namespace osu.Game.Database /// Gets an existing download request if it exists. /// /// The whose request is wanted. - /// The object if it exists, otherwise null. - ArchiveDownloadModelRequest GetExistingDownload(TModel model); + /// The object if it exists, otherwise null. + ArchiveDownloadRequest GetExistingDownload(TModel model); } } diff --git a/osu.Game/Online/API/ArchiveDownloadModelRequest.cs b/osu.Game/Online/API/ArchiveDownloadRequest.cs similarity index 78% rename from osu.Game/Online/API/ArchiveDownloadModelRequest.cs rename to osu.Game/Online/API/ArchiveDownloadRequest.cs index 7f161f1e98..01f066694d 100644 --- a/osu.Game/Online/API/ArchiveDownloadModelRequest.cs +++ b/osu.Game/Online/API/ArchiveDownloadRequest.cs @@ -5,7 +5,7 @@ using System; namespace osu.Game.Online.API { - public abstract class ArchiveDownloadModelRequest : APIDownloadRequest + public abstract class ArchiveDownloadRequest : APIDownloadRequest where TModel : class { public readonly TModel Info; @@ -14,7 +14,7 @@ namespace osu.Game.Online.API public event Action DownloadProgressed; - protected ArchiveDownloadModelRequest(TModel model) + protected ArchiveDownloadRequest(TModel model) { Info = model; diff --git a/osu.Game/Online/API/Requests/DownloadBeatmapSetRequest.cs b/osu.Game/Online/API/Requests/DownloadBeatmapSetRequest.cs index 8d636f6730..999864a6eb 100644 --- a/osu.Game/Online/API/Requests/DownloadBeatmapSetRequest.cs +++ b/osu.Game/Online/API/Requests/DownloadBeatmapSetRequest.cs @@ -5,7 +5,7 @@ using osu.Game.Beatmaps; namespace osu.Game.Online.API.Requests { - public class DownloadBeatmapSetRequest : ArchiveDownloadModelRequest + public class DownloadBeatmapSetRequest : ArchiveDownloadRequest { private readonly bool noVideo; private readonly BeatmapSetInfo set; diff --git a/osu.Game/Overlays/Direct/DownloadTrackingComposite.cs b/osu.Game/Overlays/Direct/DownloadTrackingComposite.cs index c1ff6ecb60..9d0266c00e 100644 --- a/osu.Game/Overlays/Direct/DownloadTrackingComposite.cs +++ b/osu.Game/Overlays/Direct/DownloadTrackingComposite.cs @@ -76,9 +76,9 @@ namespace osu.Game.Overlays.Direct #endregion - private ArchiveDownloadModelRequest attachedRequest; + private ArchiveDownloadRequest attachedRequest; - private void attachDownload(ArchiveDownloadModelRequest request) + private void attachDownload(ArchiveDownloadRequest request) { if (attachedRequest != null) { From 9cd5519da3d2244b6a250d676a25fd951578197d Mon Sep 17 00:00:00 2001 From: naoey Date: Wed, 12 Jun 2019 18:35:34 +0530 Subject: [PATCH 047/148] Remove unused delegate, use model name in notifications, add more xmldoc - Applies a `class` constraint to the generic type in `IModelManager` - Add xmldoc --- osu.Game/Beatmaps/BeatmapManager.cs | 5 +---- osu.Game/Database/ArchiveModelManager.cs | 2 -- osu.Game/Database/DownloadableArchiveModelManager.cs | 4 ++-- osu.Game/Database/IModelDownloader.cs | 8 ++++++-- osu.Game/Database/IModelManager.cs | 5 +++++ 5 files changed, 14 insertions(+), 10 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index c2adf1ac5b..2cb7e8b901 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -55,8 +55,6 @@ namespace osu.Game.Beatmaps private readonly BeatmapStore beatmaps; - private readonly IAPIProvider api; - private readonly AudioManager audioManager; private readonly GameHost host; @@ -68,7 +66,6 @@ namespace osu.Game.Beatmaps : base(storage, contextFactory, api, new BeatmapStore(contextFactory), host) { this.rulesets = rulesets; - this.api = api; this.audioManager = audioManager; this.host = host; @@ -80,7 +77,7 @@ namespace osu.Game.Beatmaps updateQueue = new BeatmapUpdateQueue(api); } - + protected override ArchiveDownloadRequest CreateDownloadRequest(BeatmapSetInfo set, object[] options) => new DownloadBeatmapSetRequest(set, (options?.FirstOrDefault() as bool?) ?? false); protected override Task Populate(BeatmapSetInfo beatmapSet, ArchiveReader archive, CancellationToken cancellationToken = default) diff --git a/osu.Game/Database/ArchiveModelManager.cs b/osu.Game/Database/ArchiveModelManager.cs index 49e0330c21..434e5b9525 100644 --- a/osu.Game/Database/ArchiveModelManager.cs +++ b/osu.Game/Database/ArchiveModelManager.cs @@ -35,8 +35,6 @@ namespace osu.Game.Database where TModel : class, IHasFiles, IHasPrimaryKey, ISoftDelete where TFileModel : INamedFileInfo, new() { - public delegate void ItemAddedDelegate(TModel model, bool existing); - /// /// Set an endpoint for notifications to be posted to. /// diff --git a/osu.Game/Database/DownloadableArchiveModelManager.cs b/osu.Game/Database/DownloadableArchiveModelManager.cs index 519b22b912..4a21673d2b 100644 --- a/osu.Game/Database/DownloadableArchiveModelManager.cs +++ b/osu.Game/Database/DownloadableArchiveModelManager.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 Humanizer; using osu.Framework.Logging; using osu.Framework.Platform; using osu.Game.Online.API; @@ -112,8 +113,7 @@ namespace osu.Game.Database if (error is OperationCanceledException) return; notification.State = ProgressNotificationState.Cancelled; - // TODO: maybe implement a Name for every model that we can use in this message? - Logger.Error(error, "Download failed!"); + Logger.Error(error, $"{HumanisedModelName.Titleize()} download failed!"); currentDownloads.Remove(request); }; diff --git a/osu.Game/Database/IModelDownloader.cs b/osu.Game/Database/IModelDownloader.cs index 83427bdc17..42c64ba67b 100644 --- a/osu.Game/Database/IModelDownloader.cs +++ b/osu.Game/Database/IModelDownloader.cs @@ -6,6 +6,10 @@ using System; namespace osu.Game.Database { + /// + /// Represents a that can download new models from an external source. + /// + /// The model type. public interface IModelDownloader : IModelManager where TModel : class { @@ -23,7 +27,7 @@ namespace osu.Game.Database /// /// Downloads a . - /// This will post notifications tracking progress. + /// This may post notifications tracking progress. /// /// The to be downloaded. /// Whether downloading can happen. @@ -31,7 +35,7 @@ namespace osu.Game.Database /// /// Downloads a with optional parameters for the download request. - /// This will post notifications tracking progress. + /// This may post notifications tracking progress. /// /// The to be downloaded. /// Optional parameters to be used for creating the download request. diff --git a/osu.Game/Database/IModelManager.cs b/osu.Game/Database/IModelManager.cs index ee78df3db4..cb80ce49b2 100644 --- a/osu.Game/Database/IModelManager.cs +++ b/osu.Game/Database/IModelManager.cs @@ -5,7 +5,12 @@ using System; namespace osu.Game.Database { + /// + /// Represents a model manager that publishes events when s are added or removed. + /// + /// The model type. public interface IModelManager + where TModel : class { event Action ItemAdded; From efd9766fb301121f46776b1d4a64b7ce849b53c1 Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Wed, 12 Jun 2019 17:37:34 +0300 Subject: [PATCH 048/148] Make Header accessible by BeatmapSetOverlay --- osu.Game/Overlays/BeatmapSetOverlay.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSetOverlay.cs b/osu.Game/Overlays/BeatmapSetOverlay.cs index 6bd2e1b72e..f0525aa843 100644 --- a/osu.Game/Overlays/BeatmapSetOverlay.cs +++ b/osu.Game/Overlays/BeatmapSetOverlay.cs @@ -26,7 +26,7 @@ namespace osu.Game.Overlays public const float X_PADDING = 40; public const float RIGHT_WIDTH = 275; - private readonly Header header; + public readonly Header Header; private RulesetStore rulesets; @@ -60,7 +60,7 @@ namespace osu.Game.Overlays Direction = FillDirection.Vertical, Children = new Drawable[] { - header = new Header(), + Header = new Header(), info = new Info(), scores = new ScoresContainer(), }, @@ -68,10 +68,10 @@ namespace osu.Game.Overlays }, }; - header.BeatmapSet.BindTo(beatmapSet); + Header.BeatmapSet.BindTo(beatmapSet); info.BeatmapSet.BindTo(beatmapSet); - header.Picker.Beatmap.ValueChanged += b => + Header.Picker.Beatmap.ValueChanged += b => { info.Beatmap = b.NewValue; scores.Beatmap = b.NewValue; @@ -103,7 +103,7 @@ namespace osu.Game.Overlays req.Success += res => { beatmapSet.Value = res.ToBeatmapSet(rulesets); - header.Picker.Beatmap.Value = header.BeatmapSet.Value.Beatmaps.First(b => b.OnlineBeatmapID == beatmapId); + Header.Picker.Beatmap.Value = Header.BeatmapSet.Value.Beatmaps.First(b => b.OnlineBeatmapID == beatmapId); }; API.Queue(req); Show(); From a069a3029e995ad200694abd1588c2053d59ffea Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Wed, 12 Jun 2019 18:07:57 +0300 Subject: [PATCH 049/148] Make DownloadButton accessible by DirectPanel --- osu.Game/Overlays/Direct/DirectGridPanel.cs | 4 +++- osu.Game/Overlays/Direct/DirectListPanel.cs | 4 +++- osu.Game/Overlays/Direct/DirectPanel.cs | 1 + osu.Game/Overlays/Direct/DownloadButton.cs | 7 ++++++- 4 files changed, 13 insertions(+), 3 deletions(-) diff --git a/osu.Game/Overlays/Direct/DirectGridPanel.cs b/osu.Game/Overlays/Direct/DirectGridPanel.cs index 5756a4593d..9e7aa5372b 100644 --- a/osu.Game/Overlays/Direct/DirectGridPanel.cs +++ b/osu.Game/Overlays/Direct/DirectGridPanel.cs @@ -25,9 +25,11 @@ namespace osu.Game.Overlays.Direct private const float vertical_padding = 5; private FillFlowContainer bottomPanel, statusContainer; + private DownloadButton downloadButton; private PlayButton playButton; private Box progressBar; + public override DownloadButton DownloadButton => downloadButton; protected override PlayButton PlayButton => playButton; protected override Box PreviewBar => progressBar; @@ -155,7 +157,7 @@ namespace osu.Game.Overlays.Direct }, }, }, - new DownloadButton(SetInfo) + downloadButton = new DownloadButton(SetInfo) { Size = new Vector2(50, 30), Margin = new MarginPadding(horizontal_padding), diff --git a/osu.Game/Overlays/Direct/DirectListPanel.cs b/osu.Game/Overlays/Direct/DirectListPanel.cs index b731e95d54..076fed19bd 100644 --- a/osu.Game/Overlays/Direct/DirectListPanel.cs +++ b/osu.Game/Overlays/Direct/DirectListPanel.cs @@ -27,11 +27,13 @@ namespace osu.Game.Overlays.Direct private const float height = 70; private FillFlowContainer statusContainer; + private DownloadButton downloadButton; private PlayButton playButton; private Box progressBar; protected override bool FadePlayButton => false; + public override DownloadButton DownloadButton => downloadButton; protected override PlayButton PlayButton => playButton; protected override Box PreviewBar => progressBar; @@ -149,7 +151,7 @@ namespace osu.Game.Overlays.Direct Anchor = Anchor.CentreRight, Origin = Anchor.CentreRight, AutoSizeAxes = Axes.Both, - Child = new DownloadButton(SetInfo) + Child = downloadButton = new DownloadButton(SetInfo) { Size = new Vector2(height - vertical_padding * 3), Margin = new MarginPadding { Left = vertical_padding * 2, Right = vertical_padding }, diff --git a/osu.Game/Overlays/Direct/DirectPanel.cs b/osu.Game/Overlays/Direct/DirectPanel.cs index f413dc3771..c9fe4aaa05 100644 --- a/osu.Game/Overlays/Direct/DirectPanel.cs +++ b/osu.Game/Overlays/Direct/DirectPanel.cs @@ -34,6 +34,7 @@ namespace osu.Game.Overlays.Direct public PreviewTrack Preview => PlayButton.Preview; public Bindable PreviewPlaying => PlayButton.Playing; + public abstract DownloadButton DownloadButton { get; } protected abstract PlayButton PlayButton { get; } protected abstract Box PreviewBar { get; } diff --git a/osu.Game/Overlays/Direct/DownloadButton.cs b/osu.Game/Overlays/Direct/DownloadButton.cs index 33e09e95aa..10e6f8a6e1 100644 --- a/osu.Game/Overlays/Direct/DownloadButton.cs +++ b/osu.Game/Overlays/Direct/DownloadButton.cs @@ -2,6 +2,7 @@ // 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.Shapes; using osu.Framework.Graphics.Sprites; @@ -26,6 +27,8 @@ namespace osu.Game.Overlays.Direct private readonly OsuAnimatedButton button; + public readonly BindableBool Enabled = new BindableBool(true); + public DownloadButton(BeatmapSetInfo beatmapSet, bool noVideo = false) : base(beatmapSet) { @@ -62,6 +65,8 @@ namespace osu.Game.Overlays.Direct } } }; + + Enabled.BindTo(button.Enabled); } protected override void LoadComplete() @@ -79,7 +84,7 @@ namespace osu.Game.Overlays.Direct if (BeatmapSet.Value.OnlineInfo.Availability?.DownloadDisabled ?? false) { - button.Enabled.Value = false; + Enabled.Value = false; button.TooltipText = "Unavailable"; return; } From c5c6f6b9e05ee517fc6483344d3125d675ba6ee4 Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Wed, 12 Jun 2019 18:36:47 +0300 Subject: [PATCH 050/148] Allow for not refetching in ShowBeatmapSet (will be used for tests) --- osu.Game/Overlays/BeatmapSetOverlay.cs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSetOverlay.cs b/osu.Game/Overlays/BeatmapSetOverlay.cs index f0525aa843..a44a7fa45f 100644 --- a/osu.Game/Overlays/BeatmapSetOverlay.cs +++ b/osu.Game/Overlays/BeatmapSetOverlay.cs @@ -118,10 +118,17 @@ namespace osu.Game.Overlays Show(); } - public void ShowBeatmapSet(BeatmapSetInfo set) + public void ShowBeatmapSet(BeatmapSetInfo set, bool refetch = true) { // Re-fetching is the correct way forward. - FetchAndShowBeatmapSet(set?.OnlineBeatmapSetID ?? 0); + if (refetch) + FetchAndShowBeatmapSet(set?.OnlineBeatmapSetID ?? 0); + else + { + beatmapSet.Value = set; + Show(); + } + scroll.ScrollTo(0); } } From 744f32ab35dc7a397a4ebb8954152c80bdb3b6f3 Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Wed, 12 Jun 2019 19:11:05 +0300 Subject: [PATCH 051/148] Fix little bug --- osu.Game/Overlays/BeatmapSet/BeatmapNotAvailable.cs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/BeatmapNotAvailable.cs b/osu.Game/Overlays/BeatmapSet/BeatmapNotAvailable.cs index c111861206..b9c0a1af39 100644 --- a/osu.Game/Overlays/BeatmapSet/BeatmapNotAvailable.cs +++ b/osu.Game/Overlays/BeatmapSet/BeatmapNotAvailable.cs @@ -26,6 +26,7 @@ namespace osu.Game.Overlays.BeatmapSet beatmapSet = value; + removeLinks(); if (beatmapSet?.OnlineInfo.Availability != null) { Header?.ResizeHeightTo(450, 500); @@ -95,11 +96,6 @@ namespace osu.Game.Overlays.BeatmapSet base.Show(); } - public override void Hide() - { - link.RemoveAll(x => true); - - base.Hide(); - } + private void removeLinks() => link?.RemoveAll(x => true); } } From 7ba676ad31328fc63353d98036d471498f983afe Mon Sep 17 00:00:00 2001 From: naoey Date: Wed, 12 Jun 2019 21:56:36 +0530 Subject: [PATCH 052/148] Rename Info to Model --- osu.Game/Database/DownloadableArchiveModelManager.cs | 4 ++-- osu.Game/Online/API/ArchiveDownloadRequest.cs | 4 ++-- osu.Game/Overlays/Direct/DownloadTrackingComposite.cs | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/osu.Game/Database/DownloadableArchiveModelManager.cs b/osu.Game/Database/DownloadableArchiveModelManager.cs index 4a21673d2b..0735452ce3 100644 --- a/osu.Game/Database/DownloadableArchiveModelManager.cs +++ b/osu.Game/Database/DownloadableArchiveModelManager.cs @@ -79,7 +79,7 @@ namespace osu.Game.Database /// Whether the exists locally. public virtual bool IsAvailableLocally(TModel model) => modelStore.ConsumableItems.Any(m => m.Equals(model) && !m.DeletePending); - public ArchiveDownloadRequest GetExistingDownload(TModel model) => currentDownloads.Find(r => r.Info.Equals(model)); + public ArchiveDownloadRequest GetExistingDownload(TModel model) => currentDownloads.Find(r => r.Model.Equals(model)); private bool canDownload(TModel model) => GetExistingDownload(model) == null && api != null; @@ -87,7 +87,7 @@ namespace osu.Game.Database { DownloadNotification notification = new DownloadNotification { - Text = $"Downloading {request.Info}", + Text = $"Downloading {request.Model}", }; request.DownloadProgressed += progress => diff --git a/osu.Game/Online/API/ArchiveDownloadRequest.cs b/osu.Game/Online/API/ArchiveDownloadRequest.cs index 01f066694d..f1966aeb2b 100644 --- a/osu.Game/Online/API/ArchiveDownloadRequest.cs +++ b/osu.Game/Online/API/ArchiveDownloadRequest.cs @@ -8,7 +8,7 @@ namespace osu.Game.Online.API public abstract class ArchiveDownloadRequest : APIDownloadRequest where TModel : class { - public readonly TModel Info; + public readonly TModel Model; public float Progress; @@ -16,7 +16,7 @@ namespace osu.Game.Online.API protected ArchiveDownloadRequest(TModel model) { - Info = model; + Model = model; Progressed += (current, total) => DownloadProgressed?.Invoke(Progress = (float)current / total); } diff --git a/osu.Game/Overlays/Direct/DownloadTrackingComposite.cs b/osu.Game/Overlays/Direct/DownloadTrackingComposite.cs index 9d0266c00e..494b18307e 100644 --- a/osu.Game/Overlays/Direct/DownloadTrackingComposite.cs +++ b/osu.Game/Overlays/Direct/DownloadTrackingComposite.cs @@ -49,7 +49,7 @@ namespace osu.Game.Overlays.Direct beatmaps.DownloadBegan += download => { - if (download.Info.OnlineBeatmapSetID == BeatmapSet.Value?.OnlineBeatmapSetID) + if (download.Model.OnlineBeatmapSetID == BeatmapSet.Value?.OnlineBeatmapSetID) attachDownload(download); }; From 1a50544c9465ec75278420b8d0c22666612be8c1 Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Wed, 12 Jun 2019 20:42:52 +0300 Subject: [PATCH 053/148] Add tests for undownloadable / parts-removed beatmapsets --- .../Online/TestSceneBeatmapSetOverlay.cs | 306 +++++++++++++++++- .../Visual/Online/TestSceneDirectPanel.cs | 43 ++- .../BeatmapSet/BeatmapNotAvailable.cs | 1 + 3 files changed, 342 insertions(+), 8 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs index 5910da7b88..5e7ccc7ed4 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs @@ -39,6 +39,7 @@ namespace osu.Game.Tests.Visual.Online typeof(Info), typeof(PreviewButton), typeof(SuccessRate), + typeof(BeatmapNotAvailable), }; public TestSceneBeatmapSetOverlay() @@ -49,6 +50,7 @@ namespace osu.Game.Tests.Visual.Online [BackgroundDependencyLoader] private void load(RulesetStore rulesets) { + var osu = rulesets.GetRuleset(0); var mania = rulesets.GetRuleset(3); var taiko = rulesets.GetRuleset(1); @@ -225,7 +227,7 @@ namespace osu.Game.Tests.Visual.Online }, }, }, - }); + }, false); }); AddStep(@"show second", () => @@ -396,9 +398,309 @@ namespace osu.Game.Tests.Visual.Online }, }, }, - }); + }, false); }); + AddStep(@"show parts-removed", () => + { + overlay.ShowBeatmapSet(new BeatmapSetInfo + { + Metadata = new BeatmapMetadata + { + Title = @"Sakura Kagetsu", + Artist = @"AKITO", + Source = @"DJMAX", + Tags = @"J-Trance Pasonia", + Author = new User + { + Username = @"Kharl", + Id = 452, + }, + }, + OnlineInfo = new BeatmapSetOnlineInfo + { + Availability = new BeatmapSetOnlineAvailability + { + DownloadDisabled = false, + ExternalLink = @"https://gist.githubusercontent.com/peppy/079dc3f77e316f9cd40077d411319a72/raw", + }, + Preview = @"https://b.ppy.sh/preview/119.mp3", + PlayCount = 626927, + FavouriteCount = 157, + Submitted = new DateTime(2007, 10, 24), + Ranked = new DateTime(2008, 4, 21), + Status = BeatmapSetOnlineStatus.Ranked, + BPM = 138, + Covers = new BeatmapSetOnlineCovers + { + Cover = @"https://assets.ppy.sh/beatmaps/119/covers/cover.jpg?1539847784", + }, + }, + Beatmaps = new List + { + new BeatmapInfo + { + StarDifficulty = 1.51, + Version = "Easy", + Ruleset = osu, + BaseDifficulty = new BeatmapDifficulty + { + CircleSize = 4, + DrainRate = 2, + OverallDifficulty = 1, + ApproachRate = 1, + }, + OnlineInfo = new BeatmapOnlineInfo + { + Length = 126000, + CircleCount = 371, + SliderCount = 35, + PlayCount = 84498, + PassCount = 37482, + }, + Metrics = new BeatmapMetrics + { + Ratings = Enumerable.Range(0, 11), + Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6), + Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6), + }, + }, + new BeatmapInfo + { + StarDifficulty = 2.23, + Version = "Normal", + Ruleset = osu, + BaseDifficulty = new BeatmapDifficulty + { + CircleSize = 5, + DrainRate = 4, + OverallDifficulty = 3, + ApproachRate = 3, + }, + OnlineInfo = new BeatmapOnlineInfo + { + Length = 126000, + CircleCount = 98, + SliderCount = 28, + PlayCount = 86427, + PassCount = 23273, + }, + Metrics = new BeatmapMetrics + { + Ratings = Enumerable.Range(0, 11), + Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6), + Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6), + }, + }, + new BeatmapInfo + { + StarDifficulty = 2.83, + Version = "Hard", + Ruleset = osu, + BaseDifficulty = new BeatmapDifficulty + { + CircleSize = 6, + DrainRate = 6, + OverallDifficulty = 6, + ApproachRate = 6, + }, + OnlineInfo = new BeatmapOnlineInfo + { + Length = 126000, + CircleCount = 139, + SliderCount = 37, + PlayCount = 206523, + PassCount = 44366, + }, + Metrics = new BeatmapMetrics + { + Ratings = Enumerable.Range(0, 11), + Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6), + Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6), + }, + }, + new BeatmapInfo + { + StarDifficulty = 4.26, + Version = "Pasonia's Insane", + Ruleset = osu, + BaseDifficulty = new BeatmapDifficulty + { + CircleSize = 6, + DrainRate = 6, + OverallDifficulty = 6, + ApproachRate = 6, + }, + OnlineInfo = new BeatmapOnlineInfo + { + Length = 126000, + CircleCount = 371, + SliderCount = 35, + PlayCount = 249479, + PassCount = 14042, + }, + Metrics = new BeatmapMetrics + { + Ratings = Enumerable.Range(0, 11), + Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6), + Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6), + }, + }, + }, + }, false); + }); + + AddStep(@"show undownloadable", () => + { + overlay.ShowBeatmapSet(new BeatmapSetInfo + { + Metadata = new BeatmapMetadata + { + Title = @"China Express", + Artist = @"Ryu*", + Source = @"REFLEC BEAT", + Tags = @"konami bemani lincle link iidx iidx18 iidx19 resort anthem plus la cataline mmzz", + Author = new User + { + Username = @"yeahyeahyeahhh", + Id = 58042, + }, + }, + OnlineInfo = new BeatmapSetOnlineInfo + { + Availability = new BeatmapSetOnlineAvailability + { + DownloadDisabled = true, + ExternalLink = @"https://gist.githubusercontent.com/peppy/99e6959772083cdfde8a/raw", + }, + Preview = @"https://b.ppy.sh/preview/53853.mp3", + PlayCount = 436213, + FavouriteCount = 105, + Submitted = new DateTime(2012, 7, 1), + Ranked = new DateTime(2012, 7, 18), + Status = BeatmapSetOnlineStatus.Ranked, + BPM = 171, + Covers = new BeatmapSetOnlineCovers + { + Cover = @"https://assets.ppy.sh/beatmaps/53853/covers/cover.jpg?1456498562", + }, + }, + Beatmaps = new List + { + new BeatmapInfo + { + StarDifficulty = 1.85, + Version = "Easy", + Ruleset = osu, + BaseDifficulty = new BeatmapDifficulty + { + CircleSize = 3, + DrainRate = 2, + OverallDifficulty = 2, + ApproachRate = 3, + }, + OnlineInfo = new BeatmapOnlineInfo + { + Length = 95000, + CircleCount = 49, + SliderCount = 60, + PlayCount = 20308, + PassCount = 10233, + }, + Metrics = new BeatmapMetrics + { + Ratings = Enumerable.Range(0, 11), + Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6), + Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6), + }, + }, + new BeatmapInfo + { + StarDifficulty = 2.36, + Version = "Normal", + Ruleset = osu, + BaseDifficulty = new BeatmapDifficulty + { + CircleSize = 3, + DrainRate = 2, + OverallDifficulty = 2, + ApproachRate = 5, + }, + OnlineInfo = new BeatmapOnlineInfo + { + Length = 96000, + CircleCount = 86, + SliderCount = 67, + PlayCount = 54015, + PassCount = 25603, + }, + Metrics = new BeatmapMetrics + { + Ratings = Enumerable.Range(0, 11), + Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6), + Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6), + }, + }, + new BeatmapInfo + { + StarDifficulty = 4.42, + Version = "Hyper", + Ruleset = osu, + BaseDifficulty = new BeatmapDifficulty + { + CircleSize = 4, + DrainRate = 7, + OverallDifficulty = 6, + ApproachRate = 8, + }, + OnlineInfo = new BeatmapOnlineInfo + { + Length = 96000, + CircleCount = 215, + SliderCount = 120, + PlayCount = 111400, + PassCount = 12583, + }, + Metrics = new BeatmapMetrics + { + Ratings = Enumerable.Range(0, 11), + Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6), + Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6), + }, + }, + new BeatmapInfo + { + StarDifficulty = 5.05, + Version = "Another", + Ruleset = osu, + BaseDifficulty = new BeatmapDifficulty + { + CircleSize = 4, + DrainRate = 7, + OverallDifficulty = 9, + ApproachRate = 9, + }, + OnlineInfo = new BeatmapOnlineInfo + { + Length = 96000, + CircleCount = 250, + SliderCount = 75, + PlayCount = 228253, + PassCount = 53037, + }, + Metrics = new BeatmapMetrics + { + Ratings = Enumerable.Range(0, 11), + Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6), + Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6), + }, + }, + }, + }, false); + }); + + AddAssert(@"is download button removed", () => overlay.Header.DownloadButtonsContainer.Count == 0); + AddStep(@"hide", overlay.Hide); AddStep(@"show without reload", overlay.Show); } diff --git a/osu.Game.Tests/Visual/Online/TestSceneDirectPanel.cs b/osu.Game.Tests/Visual/Online/TestSceneDirectPanel.cs index 8b67892fbb..a2767611ac 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneDirectPanel.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneDirectPanel.cs @@ -6,7 +6,9 @@ using System.Collections.Generic; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Game.Beatmaps; using osu.Game.Overlays.Direct; +using osu.Game.Rulesets; using osu.Game.Rulesets.Osu; using osuTK; @@ -21,12 +23,34 @@ namespace osu.Game.Tests.Visual.Online typeof(IconPill) }; + private BeatmapSetInfo getBeatmapSet(RulesetInfo ruleset, bool downloadable) + { + var beatmap = CreateWorkingBeatmap(ruleset).BeatmapSetInfo; + beatmap.OnlineInfo.HasVideo = true; + beatmap.OnlineInfo.HasStoryboard = true; + + beatmap.OnlineInfo.Availability = new BeatmapSetOnlineAvailability + { + DownloadDisabled = !downloadable, + ExternalLink = "http://localhost", + }; + + return beatmap; + } + [BackgroundDependencyLoader] private void load() { - var beatmap = CreateWorkingBeatmap(new OsuRuleset().RulesetInfo); - beatmap.BeatmapSetInfo.OnlineInfo.HasVideo = true; - beatmap.BeatmapSetInfo.OnlineInfo.HasStoryboard = true; + var ruleset = new OsuRuleset().RulesetInfo; + + var normal = CreateWorkingBeatmap(ruleset).BeatmapSetInfo; + normal.OnlineInfo.HasVideo = true; + normal.OnlineInfo.HasStoryboard = true; + + var downloadable = getBeatmapSet(ruleset, true); + var undownloadable = getBeatmapSet(ruleset, false); + + DirectPanel undownloadableGridPanel, undownloadableListPanel; Child = new FillFlowContainer { @@ -37,10 +61,17 @@ namespace osu.Game.Tests.Visual.Online Spacing = new Vector2(0, 20), Children = new Drawable[] { - new DirectGridPanel(beatmap.BeatmapSetInfo), - new DirectListPanel(beatmap.BeatmapSetInfo) - } + new DirectGridPanel(normal), + new DirectGridPanel(downloadable), + undownloadableGridPanel = new DirectGridPanel(undownloadable), + new DirectListPanel(normal), + new DirectListPanel(downloadable), + undownloadableListPanel = new DirectListPanel(undownloadable), + }, }; + + AddAssert("is download button disabled on last grid panel", () => !undownloadableGridPanel.DownloadButton.Enabled.Value); + AddAssert("is download button disabled on last list panel", () => !undownloadableListPanel.DownloadButton.Enabled.Value); } } } diff --git a/osu.Game/Overlays/BeatmapSet/BeatmapNotAvailable.cs b/osu.Game/Overlays/BeatmapSet/BeatmapNotAvailable.cs index b9c0a1af39..31ed0d9396 100644 --- a/osu.Game/Overlays/BeatmapSet/BeatmapNotAvailable.cs +++ b/osu.Game/Overlays/BeatmapSet/BeatmapNotAvailable.cs @@ -27,6 +27,7 @@ namespace osu.Game.Overlays.BeatmapSet beatmapSet = value; removeLinks(); + if (beatmapSet?.OnlineInfo.Availability != null) { Header?.ResizeHeightTo(450, 500); From 3150b5cfb42d9c33960606698bf3ccdf824a11f9 Mon Sep 17 00:00:00 2001 From: EVAST9919 Date: Wed, 12 Jun 2019 20:51:21 +0300 Subject: [PATCH 054/148] Naming adjustments --- osu.Game.Tests/Visual/Menus/TestSceneToolbar.cs | 2 +- .../UserInterface/TestSceneToolbarRulesetSelector.cs | 2 +- osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.cs | 2 +- ...lbarRulesetButton.cs => ToolbarRulesetTabButton.cs} | 10 +++++----- 4 files changed, 8 insertions(+), 8 deletions(-) rename osu.Game/Overlays/Toolbar/{ToolbarRulesetButton.cs => ToolbarRulesetTabButton.cs} (88%) diff --git a/osu.Game.Tests/Visual/Menus/TestSceneToolbar.cs b/osu.Game.Tests/Visual/Menus/TestSceneToolbar.cs index 0df6605cdd..f24589ed35 100644 --- a/osu.Game.Tests/Visual/Menus/TestSceneToolbar.cs +++ b/osu.Game.Tests/Visual/Menus/TestSceneToolbar.cs @@ -17,7 +17,7 @@ namespace osu.Game.Tests.Visual.Menus { typeof(ToolbarButton), typeof(ToolbarRulesetSelector), - typeof(ToolbarRulesetButton), + typeof(ToolbarRulesetTabButton), typeof(ToolbarNotificationButton), }; diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneToolbarRulesetSelector.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneToolbarRulesetSelector.cs index 7d0491aa60..3e61da73a5 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneToolbarRulesetSelector.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneToolbarRulesetSelector.cs @@ -16,7 +16,7 @@ namespace osu.Game.Tests.Visual.UserInterface public override IReadOnlyList RequiredTypes => new[] { typeof(ToolbarRulesetSelector), - typeof(ToolbarRulesetButton), + typeof(ToolbarRulesetTabButton), }; public TestSceneToolbarRulesetSelector() diff --git a/osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.cs b/osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.cs index 1f35d0f293..63cf2bba9c 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.cs @@ -34,7 +34,7 @@ namespace osu.Game.Overlays.Toolbar protected override Dropdown CreateDropdown() => null; - protected override TabItem CreateTabItem(RulesetInfo value) => new ToolbarRulesetButton(value); + protected override TabItem CreateTabItem(RulesetInfo value) => new ToolbarRulesetTabButton(value); public ToolbarRulesetSelector() { diff --git a/osu.Game/Overlays/Toolbar/ToolbarRulesetButton.cs b/osu.Game/Overlays/Toolbar/ToolbarRulesetTabButton.cs similarity index 88% rename from osu.Game/Overlays/Toolbar/ToolbarRulesetButton.cs rename to osu.Game/Overlays/Toolbar/ToolbarRulesetTabButton.cs index defe1da5bf..a5194ea752 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarRulesetButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarRulesetTabButton.cs @@ -10,16 +10,16 @@ using osu.Framework.Input.Events; namespace osu.Game.Overlays.Toolbar { - public class ToolbarRulesetButton : TabItem + public class ToolbarRulesetTabButton : TabItem { - private readonly DrawableRuleset ruleset; + private readonly RulesetButton ruleset; - public ToolbarRulesetButton(RulesetInfo value) + public ToolbarRulesetTabButton(RulesetInfo value) : base(value) { AutoSizeAxes = Axes.X; RelativeSizeAxes = Axes.Y; - Child = ruleset = new DrawableRuleset + Child = ruleset = new RulesetButton { Active = false, }; @@ -35,7 +35,7 @@ namespace osu.Game.Overlays.Toolbar protected override void OnDeactivated() => ruleset.Active = false; - private class DrawableRuleset : ToolbarButton + private class RulesetButton : ToolbarButton { public bool Active { From 8d8615773ceecd629038441ad12421f6d9840bac Mon Sep 17 00:00:00 2001 From: EVAST9919 Date: Wed, 12 Jun 2019 20:54:19 +0300 Subject: [PATCH 055/148] Fix selection is being possible even in disabled state --- osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.cs b/osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.cs index 63cf2bba9c..3baf9a1e49 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.cs @@ -25,10 +25,10 @@ namespace osu.Game.Overlays.Toolbar private RulesetStore rulesets; private readonly Bindable globalRuleset = new Bindable(); - public override bool HandleNonPositionalInput => !Current.Disabled && base.HandleNonPositionalInput; - public override bool HandlePositionalInput => !Current.Disabled && base.HandlePositionalInput; + public override bool HandleNonPositionalInput => !globalRuleset.Disabled && base.HandleNonPositionalInput; + public override bool HandlePositionalInput => !globalRuleset.Disabled && base.HandlePositionalInput; - public override bool PropagatePositionalInputSubTree => !Current.Disabled && base.PropagatePositionalInputSubTree; + public override bool PropagatePositionalInputSubTree => !globalRuleset.Disabled && base.PropagatePositionalInputSubTree; private void disabledChanged(bool isDisabled) => this.FadeColour(isDisabled ? Color4.Gray : Color4.White, 300); From e5a6d920cda80b2946c7fcde80c3b8545e50f047 Mon Sep 17 00:00:00 2001 From: EVAST9919 Date: Wed, 12 Jun 2019 23:23:01 +0300 Subject: [PATCH 056/148] Implement an abstract RulesetSelector class --- .../Toolbar/ToolbarRulesetSelector.cs | 42 +++---------- osu.Game/Rulesets/RulesetSelector.cs | 63 +++++++++++++++++++ 2 files changed, 72 insertions(+), 33 deletions(-) create mode 100644 osu.Game/Rulesets/RulesetSelector.cs diff --git a/osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.cs b/osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.cs index 3baf9a1e49..bd7ac13c9e 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.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.Caching; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -18,22 +17,18 @@ using System.Linq; namespace osu.Game.Overlays.Toolbar { - public class ToolbarRulesetSelector : TabControl + public class ToolbarRulesetSelector : RulesetSelector { private const float padding = 10; private readonly Drawable modeButtonLine; - private RulesetStore rulesets; - private readonly Bindable globalRuleset = new Bindable(); - public override bool HandleNonPositionalInput => !globalRuleset.Disabled && base.HandleNonPositionalInput; - public override bool HandlePositionalInput => !globalRuleset.Disabled && base.HandlePositionalInput; + public override bool HandleNonPositionalInput => !GlobalRuleset.Disabled && base.HandleNonPositionalInput; + public override bool HandlePositionalInput => !GlobalRuleset.Disabled && base.HandlePositionalInput; - public override bool PropagatePositionalInputSubTree => !globalRuleset.Disabled && base.PropagatePositionalInputSubTree; + public override bool PropagatePositionalInputSubTree => !GlobalRuleset.Disabled && base.PropagatePositionalInputSubTree; private void disabledChanged(bool isDisabled) => this.FadeColour(isDisabled ? Color4.Gray : Color4.White, 300); - protected override Dropdown CreateDropdown() => null; - protected override TabItem CreateTabItem(RulesetInfo value) => new ToolbarRulesetTabButton(value); public ToolbarRulesetSelector() @@ -66,6 +61,8 @@ namespace osu.Game.Overlays.Toolbar } } }); + + GlobalRuleset.DisabledChanged += disabledChanged; } protected override TabFillFlowContainer CreateTabFlow() => new TabFillFlowContainer @@ -76,24 +73,6 @@ namespace osu.Game.Overlays.Toolbar Padding = new MarginPadding { Left = padding, Right = padding }, }; - [BackgroundDependencyLoader] - private void load(RulesetStore rulesets, Bindable parentRuleset) - { - this.rulesets = rulesets; - globalRuleset.BindTo(parentRuleset); - - foreach (var r in rulesets.AvailableRulesets) - { - AddItem(r); - } - - globalRuleset.BindValueChanged(globalRulesetChanged); - globalRuleset.DisabledChanged += disabledChanged; - Current.BindValueChanged(localRulesetChanged); - } - - private void globalRulesetChanged(ValueChangedEvent e) => Current.Value = e.NewValue; - protected override bool OnKeyDown(KeyDownEvent e) { base.OnKeyDown(e); @@ -102,7 +81,7 @@ namespace osu.Game.Overlays.Toolbar { int requested = e.Key - Key.Number1; - RulesetInfo found = rulesets.AvailableRulesets.Skip(requested).FirstOrDefault(); + RulesetInfo found = AvaliableRulesets.AvailableRulesets.Skip(requested).FirstOrDefault(); if (found != null) Current.Value = found; return true; @@ -113,12 +92,9 @@ namespace osu.Game.Overlays.Toolbar private readonly Cached activeMode = new Cached(); - private void localRulesetChanged(ValueChangedEvent e) + protected override void OnLocalRulesetChanged(ValueChangedEvent e) { - if (!globalRuleset.Disabled) - { - globalRuleset.Value = e.NewValue; - } + base.OnLocalRulesetChanged(e); activeMode.Invalidate(); } diff --git a/osu.Game/Rulesets/RulesetSelector.cs b/osu.Game/Rulesets/RulesetSelector.cs new file mode 100644 index 0000000000..e646c2676b --- /dev/null +++ b/osu.Game/Rulesets/RulesetSelector.cs @@ -0,0 +1,63 @@ +// 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.UserInterface; +using osu.Framework.Bindables; +using osu.Framework.Allocation; + +namespace osu.Game.Rulesets +{ + public abstract class RulesetSelector : TabControl + { + protected RulesetStore AvaliableRulesets; + protected readonly Bindable GlobalRuleset = new Bindable(); + + protected override Dropdown CreateDropdown() => null; + + /// + /// Whether we want to change a global ruleset when local one is changed. + /// + protected virtual bool AllowGlobalRulesetChange => true; + + /// + /// Whether we want to change a local ruleset when global one is changed. + /// /// + protected virtual bool AllowLocalRulesetChange => true; + + [BackgroundDependencyLoader] + private void load(RulesetStore rulesets, Bindable parentRuleset) + { + AvaliableRulesets = rulesets; + GlobalRuleset.BindTo(parentRuleset); + + foreach (var r in rulesets.AvailableRulesets) + { + AddItem(r); + } + + GlobalRuleset.BindValueChanged(globalRulesetChanged); + Current.BindValueChanged(OnLocalRulesetChanged); + } + + private void globalRulesetChanged(ValueChangedEvent e) + { + if (AllowLocalRulesetChange) + { + OnGlobalRulesetChanged(e); + } + } + + protected virtual void OnGlobalRulesetChanged(ValueChangedEvent e) + { + Current.Value = e.NewValue; + } + + protected virtual void OnLocalRulesetChanged(ValueChangedEvent e) + { + if (!GlobalRuleset.Disabled && AllowGlobalRulesetChange) + { + GlobalRuleset.Value = e.NewValue; + } + } + } +} From 155f7c7e03541a3e8f825a6c6ce229f015c0d78d Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Thu, 13 Jun 2019 17:32:27 +0300 Subject: [PATCH 057/148] Use OsuTextFlowContainer for multi-lines --- .../BeatmapSet/BeatmapNotAvailable.cs | 26 +++++++------------ osu.Game/Overlays/BeatmapSet/Header.cs | 2 +- 2 files changed, 11 insertions(+), 17 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/BeatmapNotAvailable.cs b/osu.Game/Overlays/BeatmapSet/BeatmapNotAvailable.cs index 31ed0d9396..59ac8ce6e2 100644 --- a/osu.Game/Overlays/BeatmapSet/BeatmapNotAvailable.cs +++ b/osu.Game/Overlays/BeatmapSet/BeatmapNotAvailable.cs @@ -8,7 +8,6 @@ using osu.Framework.Graphics.Shapes; using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Graphics.Containers; -using osu.Game.Graphics.Sprites; using osuTK.Graphics; namespace osu.Game.Overlays.BeatmapSet @@ -29,47 +28,42 @@ namespace osu.Game.Overlays.BeatmapSet removeLinks(); if (beatmapSet?.OnlineInfo.Availability != null) - { - Header?.ResizeHeightTo(450, 500); Show(); - } else - { - Header?.ResizeHeightTo(400, 500); Hide(); - } } } - public Header Header; - - private readonly OsuSpriteText text; + private readonly OsuTextFlowContainer text; private readonly LinkFlowContainer link; public BeatmapNotAvailable() { - AutoSizeAxes = Axes.Both; - Margin = new MarginPadding { Top = 10 }; + RelativeSizeAxes = Axes.X; + AutoSizeAxes = Axes.Y; + Padding = new MarginPadding { Top = 10, Right = 20 }; Children = new Drawable[] { new Box { - Colour = Color4.Black.Opacity(0.6f), RelativeSizeAxes = Axes.Both, + Colour = Color4.Black.Opacity(0.6f), }, new FillFlowContainer { - AutoSizeAxes = Axes.Both, + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, Direction = FillDirection.Vertical, Margin = new MarginPadding { Top = 10, Left = 5, Right = 20 }, Children = new Drawable[] { - text = new OsuSpriteText + text = new OsuTextFlowContainer(t => t.Font = OsuFont.GetFont(size: 20, weight: FontWeight.Medium)) { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, Margin = new MarginPadding { Bottom = 10, Horizontal = 5 }, - Font = OsuFont.GetFont(size: 20, weight: FontWeight.Medium), Colour = Color4.Orange, }, link = new LinkFlowContainer(t => t.Font = OsuFont.GetFont(size: 14)) diff --git a/osu.Game/Overlays/BeatmapSet/Header.cs b/osu.Game/Overlays/BeatmapSet/Header.cs index a53b4a2e68..0f3ce008cf 100644 --- a/osu.Game/Overlays/BeatmapSet/Header.cs +++ b/osu.Game/Overlays/BeatmapSet/Header.cs @@ -135,7 +135,7 @@ namespace osu.Game.Overlays.BeatmapSet Margin = new MarginPadding { Top = 20 }, Child = author = new AuthorInfo(), }, - beatmapNotAvailable = new BeatmapNotAvailable { Header = this }, + beatmapNotAvailable = new BeatmapNotAvailable(), new Container { RelativeSizeAxes = Axes.X, From 3c2a2b23901baad45667c3fddbe044a1c0da7339 Mon Sep 17 00:00:00 2001 From: naoey Date: Thu, 13 Jun 2019 21:28:32 +0530 Subject: [PATCH 058/148] Move doc to interface --- osu.Game/Database/DownloadableArchiveModelManager.cs | 5 ----- osu.Game/Database/IModelDownloader.cs | 6 ++++++ 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/osu.Game/Database/DownloadableArchiveModelManager.cs b/osu.Game/Database/DownloadableArchiveModelManager.cs index 0735452ce3..fc50a4720a 100644 --- a/osu.Game/Database/DownloadableArchiveModelManager.cs +++ b/osu.Game/Database/DownloadableArchiveModelManager.cs @@ -72,11 +72,6 @@ namespace osu.Game.Database return true; } - /// - /// Checks whether a given is available in the local store already. - /// - /// The whose existence needs to be checked. - /// Whether the exists locally. public virtual bool IsAvailableLocally(TModel model) => modelStore.ConsumableItems.Any(m => m.Equals(model) && !m.DeletePending); public ArchiveDownloadRequest GetExistingDownload(TModel model) => currentDownloads.Find(r => r.Model.Equals(model)); diff --git a/osu.Game/Database/IModelDownloader.cs b/osu.Game/Database/IModelDownloader.cs index 42c64ba67b..b4f8c1e24a 100644 --- a/osu.Game/Database/IModelDownloader.cs +++ b/osu.Game/Database/IModelDownloader.cs @@ -23,6 +23,12 @@ namespace osu.Game.Database /// event Action> DownloadFailed; + + /// + /// Checks whether a given is already available in the local store. + /// + /// The whose existence needs to be checked. + /// Whether the exists. bool IsAvailableLocally(TModel model); /// From 4a16ac53bab407adeceadc992c5ec6c8eb1dd10e Mon Sep 17 00:00:00 2001 From: naoey Date: Sat, 15 Jun 2019 12:28:23 +0530 Subject: [PATCH 059/148] Remove extra newline --- osu.Game/Database/IModelDownloader.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Database/IModelDownloader.cs b/osu.Game/Database/IModelDownloader.cs index b4f8c1e24a..b4df7cc0e3 100644 --- a/osu.Game/Database/IModelDownloader.cs +++ b/osu.Game/Database/IModelDownloader.cs @@ -23,7 +23,6 @@ namespace osu.Game.Database /// event Action> DownloadFailed; - /// /// Checks whether a given is already available in the local store. /// From c95e3da3ec6b3f577ae5116f491701bd6275bfd2 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 18 Jun 2019 00:23:00 +0300 Subject: [PATCH 060/148] Implement a BindableRulesetSelector --- .../Toolbar/ToolbarRulesetSelector.cs | 2 +- osu.Game/Rulesets/BindableRulesetSelector.cs | 37 ++++++++++++++++++ osu.Game/Rulesets/RulesetSelector.cs | 39 +------------------ 3 files changed, 39 insertions(+), 39 deletions(-) create mode 100644 osu.Game/Rulesets/BindableRulesetSelector.cs diff --git a/osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.cs b/osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.cs index bd7ac13c9e..62abca06c6 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.cs @@ -17,7 +17,7 @@ using System.Linq; namespace osu.Game.Overlays.Toolbar { - public class ToolbarRulesetSelector : RulesetSelector + public class ToolbarRulesetSelector : BindableRulesetSelector { private const float padding = 10; private readonly Drawable modeButtonLine; diff --git a/osu.Game/Rulesets/BindableRulesetSelector.cs b/osu.Game/Rulesets/BindableRulesetSelector.cs new file mode 100644 index 0000000000..0da79af263 --- /dev/null +++ b/osu.Game/Rulesets/BindableRulesetSelector.cs @@ -0,0 +1,37 @@ +// 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; + +namespace osu.Game.Rulesets +{ + public abstract class BindableRulesetSelector : RulesetSelector + { + protected readonly Bindable GlobalRuleset = new Bindable(); + + [BackgroundDependencyLoader] + private void load(Bindable parentRuleset) + { + GlobalRuleset.BindTo(parentRuleset); + + GlobalRuleset.BindValueChanged(globalRulesetChanged); + Current.BindValueChanged(OnLocalRulesetChanged); + } + + private void globalRulesetChanged(ValueChangedEvent e) => OnGlobalRulesetChanged(e); + + protected virtual void OnGlobalRulesetChanged(ValueChangedEvent e) + { + Current.Value = e.NewValue; + } + + protected virtual void OnLocalRulesetChanged(ValueChangedEvent e) + { + if (!GlobalRuleset.Disabled) + { + GlobalRuleset.Value = e.NewValue; + } + } + } +} diff --git a/osu.Game/Rulesets/RulesetSelector.cs b/osu.Game/Rulesets/RulesetSelector.cs index e646c2676b..d7ffb866ab 100644 --- a/osu.Game/Rulesets/RulesetSelector.cs +++ b/osu.Game/Rulesets/RulesetSelector.cs @@ -2,7 +2,6 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Graphics.UserInterface; -using osu.Framework.Bindables; using osu.Framework.Allocation; namespace osu.Game.Rulesets @@ -10,54 +9,18 @@ namespace osu.Game.Rulesets public abstract class RulesetSelector : TabControl { protected RulesetStore AvaliableRulesets; - protected readonly Bindable GlobalRuleset = new Bindable(); protected override Dropdown CreateDropdown() => null; - /// - /// Whether we want to change a global ruleset when local one is changed. - /// - protected virtual bool AllowGlobalRulesetChange => true; - - /// - /// Whether we want to change a local ruleset when global one is changed. - /// /// - protected virtual bool AllowLocalRulesetChange => true; - [BackgroundDependencyLoader] - private void load(RulesetStore rulesets, Bindable parentRuleset) + private void load(RulesetStore rulesets) { AvaliableRulesets = rulesets; - GlobalRuleset.BindTo(parentRuleset); foreach (var r in rulesets.AvailableRulesets) { AddItem(r); } - - GlobalRuleset.BindValueChanged(globalRulesetChanged); - Current.BindValueChanged(OnLocalRulesetChanged); - } - - private void globalRulesetChanged(ValueChangedEvent e) - { - if (AllowLocalRulesetChange) - { - OnGlobalRulesetChanged(e); - } - } - - protected virtual void OnGlobalRulesetChanged(ValueChangedEvent e) - { - Current.Value = e.NewValue; - } - - protected virtual void OnLocalRulesetChanged(ValueChangedEvent e) - { - if (!GlobalRuleset.Disabled && AllowGlobalRulesetChange) - { - GlobalRuleset.Value = e.NewValue; - } } } } From 413c2158e25a56728d9116aab22078453d364004 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 18 Jun 2019 01:11:05 +0300 Subject: [PATCH 061/148] Simplify bindables usage --- .../Toolbar/ToolbarRulesetSelector.cs | 12 +++++------ osu.Game/Rulesets/BindableRulesetSelector.cs | 21 +++++-------------- 2 files changed, 11 insertions(+), 22 deletions(-) diff --git a/osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.cs b/osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.cs index 62abca06c6..d89418b50c 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.cs @@ -22,10 +22,10 @@ namespace osu.Game.Overlays.Toolbar private const float padding = 10; private readonly Drawable modeButtonLine; - public override bool HandleNonPositionalInput => !GlobalRuleset.Disabled && base.HandleNonPositionalInput; - public override bool HandlePositionalInput => !GlobalRuleset.Disabled && base.HandlePositionalInput; + public override bool HandleNonPositionalInput => !Current.Disabled && base.HandleNonPositionalInput; + public override bool HandlePositionalInput => !Current.Disabled && base.HandlePositionalInput; - public override bool PropagatePositionalInputSubTree => !GlobalRuleset.Disabled && base.PropagatePositionalInputSubTree; + public override bool PropagatePositionalInputSubTree => !Current.Disabled && base.PropagatePositionalInputSubTree; private void disabledChanged(bool isDisabled) => this.FadeColour(isDisabled ? Color4.Gray : Color4.White, 300); @@ -62,7 +62,7 @@ namespace osu.Game.Overlays.Toolbar } }); - GlobalRuleset.DisabledChanged += disabledChanged; + Current.DisabledChanged += disabledChanged; } protected override TabFillFlowContainer CreateTabFlow() => new TabFillFlowContainer @@ -92,9 +92,9 @@ namespace osu.Game.Overlays.Toolbar private readonly Cached activeMode = new Cached(); - protected override void OnLocalRulesetChanged(ValueChangedEvent e) + protected override void OnRulesetChanged(ValueChangedEvent e) { - base.OnLocalRulesetChanged(e); + base.OnRulesetChanged(e); activeMode.Invalidate(); } diff --git a/osu.Game/Rulesets/BindableRulesetSelector.cs b/osu.Game/Rulesets/BindableRulesetSelector.cs index 0da79af263..8c9bbcea0d 100644 --- a/osu.Game/Rulesets/BindableRulesetSelector.cs +++ b/osu.Game/Rulesets/BindableRulesetSelector.cs @@ -8,29 +8,18 @@ namespace osu.Game.Rulesets { public abstract class BindableRulesetSelector : RulesetSelector { - protected readonly Bindable GlobalRuleset = new Bindable(); - [BackgroundDependencyLoader] private void load(Bindable parentRuleset) { - GlobalRuleset.BindTo(parentRuleset); - - GlobalRuleset.BindValueChanged(globalRulesetChanged); - Current.BindValueChanged(OnLocalRulesetChanged); + Current.BindTo(parentRuleset); + Current.BindValueChanged(OnRulesetChanged); } - private void globalRulesetChanged(ValueChangedEvent e) => OnGlobalRulesetChanged(e); - - protected virtual void OnGlobalRulesetChanged(ValueChangedEvent e) + protected virtual void OnRulesetChanged(ValueChangedEvent e) { - Current.Value = e.NewValue; - } - - protected virtual void OnLocalRulesetChanged(ValueChangedEvent e) - { - if (!GlobalRuleset.Disabled) + if (Current.Disabled) { - GlobalRuleset.Value = e.NewValue; + return; } } } From f2e0ced05272f44851ffc067c4fe59552e4893a9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 19 Jun 2019 01:32:37 +0900 Subject: [PATCH 062/148] Move private event handling logic to bottom of class --- osu.Game/Database/ArchiveModelManager.cs | 92 ++++++++++++------------ 1 file changed, 48 insertions(+), 44 deletions(-) diff --git a/osu.Game/Database/ArchiveModelManager.cs b/osu.Game/Database/ArchiveModelManager.cs index 434e5b9525..a64bca57cb 100644 --- a/osu.Game/Database/ArchiveModelManager.cs +++ b/osu.Game/Database/ArchiveModelManager.cs @@ -65,50 +65,6 @@ namespace osu.Game.Database // ReSharper disable once NotAccessedField.Local (we should keep a reference to this so it is not finalised) private ArchiveImportIPCChannel ipc; - private readonly List queuedEvents = new List(); - - /// - /// Allows delaying of outwards events until an operation is confirmed (at a database level). - /// - private bool delayingEvents; - - /// - /// Begin delaying outwards events. - /// - private void delayEvents() => delayingEvents = true; - - /// - /// Flush delayed events and disable delaying. - /// - /// Whether the flushed events should be performed. - private void flushEvents(bool perform) - { - Action[] events; - - lock (queuedEvents) - { - events = queuedEvents.ToArray(); - queuedEvents.Clear(); - } - - if (perform) - { - foreach (var a in events) - a.Invoke(); - } - - delayingEvents = false; - } - - private void handleEvent(Action a) - { - if (delayingEvents) - lock (queuedEvents) - queuedEvents.Add(a); - else - a.Invoke(); - } - protected ArchiveModelManager(Storage storage, IDatabaseContextFactory contextFactory, MutableDatabaseBackedStoreWithFileIncludes modelStore, IIpcHost importHost = null) { ContextFactory = contextFactory; @@ -630,6 +586,54 @@ namespace osu.Game.Database throw new InvalidFormatException($"{path} is not a valid archive"); } + + #region Event handling / delaying + + private readonly List queuedEvents = new List(); + + /// + /// Allows delaying of outwards events until an operation is confirmed (at a database level). + /// + private bool delayingEvents; + + /// + /// Begin delaying outwards events. + /// + private void delayEvents() => delayingEvents = true; + + /// + /// Flush delayed events and disable delaying. + /// + /// Whether the flushed events should be performed. + private void flushEvents(bool perform) + { + Action[] events; + + lock (queuedEvents) + { + events = queuedEvents.ToArray(); + queuedEvents.Clear(); + } + + if (perform) + { + foreach (var a in events) + a.Invoke(); + } + + delayingEvents = false; + } + + private void handleEvent(Action a) + { + if (delayingEvents) + lock (queuedEvents) + queuedEvents.Add(a); + else + a.Invoke(); + } + + #endregion } public abstract class ArchiveModelManager From 341dc74834187d6e7fb498d4c0ec138cf45d7d92 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 19 Jun 2019 01:41:19 +0900 Subject: [PATCH 063/148] Simplify download method --- osu.Game/Beatmaps/BeatmapManager.cs | 3 ++- .../DownloadableArchiveModelManager.cs | 27 +++++++------------ osu.Game/Database/IModelDownloader.cs | 17 +++--------- 3 files changed, 16 insertions(+), 31 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index 2cb7e8b901..b7a08c068f 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -78,7 +78,8 @@ namespace osu.Game.Beatmaps updateQueue = new BeatmapUpdateQueue(api); } - protected override ArchiveDownloadRequest CreateDownloadRequest(BeatmapSetInfo set, object[] options) => new DownloadBeatmapSetRequest(set, (options?.FirstOrDefault() as bool?) ?? false); + protected override ArchiveDownloadRequest CreateDownloadRequest(BeatmapSetInfo set, bool minimiseDownloadSize) => + new DownloadBeatmapSetRequest(set, minimiseDownloadSize); protected override Task Populate(BeatmapSetInfo beatmapSet, ArchiveReader archive, CancellationToken cancellationToken = default) { diff --git a/osu.Game/Database/DownloadableArchiveModelManager.cs b/osu.Game/Database/DownloadableArchiveModelManager.cs index fc50a4720a..d9ebd0c06a 100644 --- a/osu.Game/Database/DownloadableArchiveModelManager.cs +++ b/osu.Game/Database/DownloadableArchiveModelManager.cs @@ -42,30 +42,23 @@ namespace osu.Game.Database /// /// Creates the download request for this . - /// The parameters will be provided when the download was initiated with extra options meant - /// to be used in the creation of the request. /// /// The to be downloaded. - /// Extra parameters for request creation, null if none were passed. + /// Whether this download should be optimised for slow connections. Generally means extras are not included in the download bundle.. /// The request object. - protected abstract ArchiveDownloadRequest CreateDownloadRequest(TModel model, object[] options); + protected abstract ArchiveDownloadRequest CreateDownloadRequest(TModel model, bool minimiseDownloadSize); - public bool Download(TModel model) + /// + /// Begin a download for the requested . + /// + /// The to be downloaded. + /// Whether this download should be optimised for slow connections. Generally means extras are not included in the download bundle.. + /// Whether the download was started. + public bool Download(TModel model, bool minimiseDownloadSize = false) { if (!canDownload(model)) return false; - var request = CreateDownloadRequest(model, null); - - performDownloadWithRequest(request); - - return true; - } - - public bool Download(TModel model, params object[] extra) - { - if (!canDownload(model)) return false; - - var request = CreateDownloadRequest(model, extra); + var request = CreateDownloadRequest(model, minimiseDownloadSize); performDownloadWithRequest(request); diff --git a/osu.Game/Database/IModelDownloader.cs b/osu.Game/Database/IModelDownloader.cs index b4df7cc0e3..f6f4b0aa42 100644 --- a/osu.Game/Database/IModelDownloader.cs +++ b/osu.Game/Database/IModelDownloader.cs @@ -31,21 +31,12 @@ namespace osu.Game.Database bool IsAvailableLocally(TModel model); /// - /// Downloads a . - /// This may post notifications tracking progress. + /// Begin a download for the requested . /// /// The to be downloaded. - /// Whether downloading can happen. - bool Download(TModel model); - - /// - /// Downloads a with optional parameters for the download request. - /// This may post notifications tracking progress. - /// - /// The to be downloaded. - /// Optional parameters to be used for creating the download request. - /// Whether downloading can happen. - bool Download(TModel model, params object[] extra); + /// Whether this download should be optimised for slow connections. Generally means extras are not included in the download bundle.. + /// Whether the download was started. + bool Download(TModel model, bool minimiseDownloadSize); /// /// Gets an existing download request if it exists. From 1bcff8a3e26c43c31890456cc3528d1c63bcd0ce Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 19 Jun 2019 01:57:38 +0900 Subject: [PATCH 064/148] Make generic covariant --- osu.Game/Database/IModelManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Database/IModelManager.cs b/osu.Game/Database/IModelManager.cs index cb80ce49b2..e41ef3efef 100644 --- a/osu.Game/Database/IModelManager.cs +++ b/osu.Game/Database/IModelManager.cs @@ -9,7 +9,7 @@ namespace osu.Game.Database /// Represents a model manager that publishes events when s are added or removed. /// /// The model type. - public interface IModelManager + public interface IModelManager where TModel : class { event Action ItemAdded; From a0609f28d71fc5e5e770ac5c10f064bc1559b339 Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Wed, 19 Jun 2019 01:43:28 +0300 Subject: [PATCH 065/148] Revert some changes + simplify BeatmapNotAvailable --- .../Online/TestSceneBeatmapSetOverlay.cs | 40 ++++++++----------- .../BeatmapSet/BeatmapNotAvailable.cs | 22 +++++----- 2 files changed, 27 insertions(+), 35 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs index 553be1d38d..c97aa5a13c 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs @@ -473,9 +473,8 @@ namespace osu.Game.Tests.Visual.Online }, Metrics = new BeatmapMetrics { - Ratings = Enumerable.Range(0, 11), - Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6), - Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6), + Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6).ToArray(), + Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6).ToArray(), }, }, new BeatmapInfo @@ -500,9 +499,8 @@ namespace osu.Game.Tests.Visual.Online }, Metrics = new BeatmapMetrics { - Ratings = Enumerable.Range(0, 11), - Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6), - Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6), + Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6).ToArray(), + Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6).ToArray(), }, }, new BeatmapInfo @@ -527,9 +525,8 @@ namespace osu.Game.Tests.Visual.Online }, Metrics = new BeatmapMetrics { - Ratings = Enumerable.Range(0, 11), - Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6), - Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6), + Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6).ToArray(), + Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6).ToArray(), }, }, new BeatmapInfo @@ -554,9 +551,8 @@ namespace osu.Game.Tests.Visual.Online }, Metrics = new BeatmapMetrics { - Ratings = Enumerable.Range(0, 11), - Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6), - Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6), + Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6).ToArray(), + Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6).ToArray(), }, }, }, @@ -623,9 +619,8 @@ namespace osu.Game.Tests.Visual.Online }, Metrics = new BeatmapMetrics { - Ratings = Enumerable.Range(0, 11), - Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6), - Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6), + Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6).ToArray(), + Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6).ToArray(), }, }, new BeatmapInfo @@ -650,9 +645,8 @@ namespace osu.Game.Tests.Visual.Online }, Metrics = new BeatmapMetrics { - Ratings = Enumerable.Range(0, 11), - Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6), - Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6), + Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6).ToArray(), + Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6).ToArray(), }, }, new BeatmapInfo @@ -677,9 +671,8 @@ namespace osu.Game.Tests.Visual.Online }, Metrics = new BeatmapMetrics { - Ratings = Enumerable.Range(0, 11), - Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6), - Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6), + Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6).ToArray(), + Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6).ToArray(), }, }, new BeatmapInfo @@ -704,9 +697,8 @@ namespace osu.Game.Tests.Visual.Online }, Metrics = new BeatmapMetrics { - Ratings = Enumerable.Range(0, 11), - Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6), - Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6), + Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6).ToArray(), + Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6).ToArray(), }, }, }, diff --git a/osu.Game/Overlays/BeatmapSet/BeatmapNotAvailable.cs b/osu.Game/Overlays/BeatmapSet/BeatmapNotAvailable.cs index 59ac8ce6e2..6472077c8b 100644 --- a/osu.Game/Overlays/BeatmapSet/BeatmapNotAvailable.cs +++ b/osu.Game/Overlays/BeatmapSet/BeatmapNotAvailable.cs @@ -8,6 +8,7 @@ using osu.Framework.Graphics.Shapes; using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Graphics.Containers; +using osu.Game.Graphics.Sprites; using osuTK.Graphics; namespace osu.Game.Overlays.BeatmapSet @@ -25,7 +26,7 @@ namespace osu.Game.Overlays.BeatmapSet beatmapSet = value; - removeLinks(); + link?.Clear(); if (beatmapSet?.OnlineInfo.Availability != null) Show(); @@ -34,9 +35,11 @@ namespace osu.Game.Overlays.BeatmapSet } } - private readonly OsuTextFlowContainer text; + private readonly OsuSpriteText text; private readonly LinkFlowContainer link; + private BeatmapSetOnlineAvailability availability => BeatmapSet?.OnlineInfo.Availability; + public BeatmapNotAvailable() { RelativeSizeAxes = Axes.X; @@ -56,14 +59,14 @@ namespace osu.Game.Overlays.BeatmapSet AutoSizeAxes = Axes.Y, Direction = FillDirection.Vertical, Margin = new MarginPadding { Top = 10, Left = 5, Right = 20 }, - Children = new Drawable[] { - text = new OsuTextFlowContainer(t => t.Font = OsuFont.GetFont(size: 20, weight: FontWeight.Medium)) + text = new OsuSpriteText { RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, + AllowMultiline = true, Margin = new MarginPadding { Bottom = 10, Horizontal = 5 }, + Font = OsuFont.GetFont(size: 20, weight: FontWeight.Medium), Colour = Color4.Orange, }, link = new LinkFlowContainer(t => t.Font = OsuFont.GetFont(size: 14)) @@ -76,21 +79,18 @@ namespace osu.Game.Overlays.BeatmapSet }, }, }; - - Hide(); } public override void Show() { - text.Text = BeatmapSet.OnlineInfo.Availability.DownloadDisabled + text.Text = availability.DownloadDisabled ? "This beatmap is currently not available for download." : "Portions of this beatmap have been removed at the request of the creator or a third-party rights holder."; - link.AddLink("Check here for more information.", BeatmapSet.OnlineInfo.Availability.ExternalLink); + if (!string.IsNullOrEmpty(availability.ExternalLink)) + link.AddLink("Check here for more information.", availability.ExternalLink); base.Show(); } - - private void removeLinks() => link?.RemoveAll(x => true); } } From 387644214390e440ce99ab8294022d8b51b7df10 Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Wed, 19 Jun 2019 03:37:08 +0300 Subject: [PATCH 066/148] More simplifies + fix test --- .../Visual/Online/TestSceneBeatmapSetOverlay.cs | 13 ++++++++++++- .../Overlays/BeatmapSet/BeatmapNotAvailable.cs | 17 +++++++---------- osu.Game/Overlays/BeatmapSet/Header.cs | 4 ++-- 3 files changed, 21 insertions(+), 13 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs index c97aa5a13c..2e68be981c 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs @@ -242,6 +242,8 @@ namespace osu.Game.Tests.Visual.Online }, false); }); + downloadAssert(true); + AddStep(@"show second", () => { overlay.ShowBeatmapSet(new BeatmapSetInfo @@ -408,6 +410,8 @@ namespace osu.Game.Tests.Visual.Online }, }, false); }); + + downloadAssert(true); } [Test] @@ -559,6 +563,8 @@ namespace osu.Game.Tests.Visual.Online }, false); }); + downloadAssert(true); + AddStep(@"show undownloadable", () => { overlay.ShowBeatmapSet(new BeatmapSetInfo @@ -705,7 +711,12 @@ namespace osu.Game.Tests.Visual.Online }, false); }); - AddAssert(@"is download button removed", () => overlay.Header.DownloadButtonsContainer.Any()); + downloadAssert(false); + } + + private void downloadAssert(bool shown) + { + AddAssert($"is download button {(shown ? "shown" : "hidden")}", () => overlay.Header.DownloadButtonsContainer.Any() == shown); } [Test] diff --git a/osu.Game/Overlays/BeatmapSet/BeatmapNotAvailable.cs b/osu.Game/Overlays/BeatmapSet/BeatmapNotAvailable.cs index 6472077c8b..23d7faefc1 100644 --- a/osu.Game/Overlays/BeatmapSet/BeatmapNotAvailable.cs +++ b/osu.Game/Overlays/BeatmapSet/BeatmapNotAvailable.cs @@ -22,16 +22,12 @@ namespace osu.Game.Overlays.BeatmapSet get => beatmapSet; set { - if (value == beatmapSet) return; + if (value == beatmapSet) + return; beatmapSet = value; - link?.Clear(); - - if (beatmapSet?.OnlineInfo.Availability != null) - Show(); - else - Hide(); + updateText(); } } @@ -81,16 +77,17 @@ namespace osu.Game.Overlays.BeatmapSet }; } - public override void Show() + private void updateText() { + if (availability == null) + return; + text.Text = availability.DownloadDisabled ? "This beatmap is currently not available for download." : "Portions of this beatmap have been removed at the request of the creator or a third-party rights holder."; if (!string.IsNullOrEmpty(availability.ExternalLink)) link.AddLink("Check here for more information.", availability.ExternalLink); - - base.Show(); } } } diff --git a/osu.Game/Overlays/BeatmapSet/Header.cs b/osu.Game/Overlays/BeatmapSet/Header.cs index 0f3ce008cf..0439ee4797 100644 --- a/osu.Game/Overlays/BeatmapSet/Header.cs +++ b/osu.Game/Overlays/BeatmapSet/Header.cs @@ -220,7 +220,7 @@ namespace osu.Game.Overlays.BeatmapSet if (BeatmapSet.Value.OnlineInfo.Availability?.DownloadDisabled ?? false) { - DownloadButtonsContainer.RemoveAll(x => true); + DownloadButtonsContainer.Clear(); return; } @@ -228,7 +228,7 @@ namespace osu.Game.Overlays.BeatmapSet { case DownloadState.LocallyAvailable: // temporary for UX until new design is implemented. - DownloadButtonsContainer.Child = new osu.Game.Overlays.Direct.DownloadButton(BeatmapSet.Value) + DownloadButtonsContainer.Child = new Direct.DownloadButton(BeatmapSet.Value) { Width = 50, RelativeSizeAxes = Axes.Y From 6e282941822a10b8263d725f3446f674dc27b63a Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Wed, 19 Jun 2019 04:27:31 +0300 Subject: [PATCH 067/148] Fix another test --- .../Visual/Online/TestSceneBeatmapNotAvailable.cs | 1 - osu.Game/Overlays/BeatmapSet/BeatmapNotAvailable.cs | 9 +++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneBeatmapNotAvailable.cs b/osu.Game.Tests/Visual/Online/TestSceneBeatmapNotAvailable.cs index e2a5ab1e35..22e3e63c28 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneBeatmapNotAvailable.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneBeatmapNotAvailable.cs @@ -14,7 +14,6 @@ namespace osu.Game.Tests.Visual.Online Add(container); - AddAssert("is container hidden", () => container.Alpha == 0); AddStep("set undownloadable beatmapset", () => container.BeatmapSet = new BeatmapSetInfo { OnlineInfo = new BeatmapSetOnlineInfo diff --git a/osu.Game/Overlays/BeatmapSet/BeatmapNotAvailable.cs b/osu.Game/Overlays/BeatmapSet/BeatmapNotAvailable.cs index 23d7faefc1..48f80fc812 100644 --- a/osu.Game/Overlays/BeatmapSet/BeatmapNotAvailable.cs +++ b/osu.Game/Overlays/BeatmapSet/BeatmapNotAvailable.cs @@ -27,7 +27,11 @@ namespace osu.Game.Overlays.BeatmapSet beatmapSet = value; - updateText(); + var unavailable = availability != null; + this.FadeTo(unavailable ? 1 : 0); + + if (unavailable) + updateText(); } } @@ -79,9 +83,6 @@ namespace osu.Game.Overlays.BeatmapSet private void updateText() { - if (availability == null) - return; - text.Text = availability.DownloadDisabled ? "This beatmap is currently not available for download." : "Portions of this beatmap have been removed at the request of the creator or a third-party rights holder."; From 46003365812c03baf5cd8224705b6a9f05b6702d Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Wed, 19 Jun 2019 14:43:18 +0300 Subject: [PATCH 068/148] Use TextFlowContainer + small changes --- .../BeatmapSet/BeatmapNotAvailable.cs | 25 +++++++++---------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/BeatmapNotAvailable.cs b/osu.Game/Overlays/BeatmapSet/BeatmapNotAvailable.cs index 48f80fc812..979d0b6fa2 100644 --- a/osu.Game/Overlays/BeatmapSet/BeatmapNotAvailable.cs +++ b/osu.Game/Overlays/BeatmapSet/BeatmapNotAvailable.cs @@ -8,7 +8,6 @@ using osu.Framework.Graphics.Shapes; using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Graphics.Containers; -using osu.Game.Graphics.Sprites; using osuTK.Graphics; namespace osu.Game.Overlays.BeatmapSet @@ -27,18 +26,17 @@ namespace osu.Game.Overlays.BeatmapSet beatmapSet = value; - var unavailable = availability != null; + bool unavailable = BeatmapSet?.OnlineInfo.Availability != null; this.FadeTo(unavailable ? 1 : 0); + linkContainer.Clear(); if (unavailable) updateText(); } } - private readonly OsuSpriteText text; - private readonly LinkFlowContainer link; - - private BeatmapSetOnlineAvailability availability => BeatmapSet?.OnlineInfo.Availability; + private readonly TextFlowContainer textContainer; + private readonly LinkFlowContainer linkContainer; public BeatmapNotAvailable() { @@ -61,15 +59,16 @@ namespace osu.Game.Overlays.BeatmapSet Margin = new MarginPadding { Top = 10, Left = 5, Right = 20 }, Children = new Drawable[] { - text = new OsuSpriteText + textContainer = new TextFlowContainer(t => t.Font = OsuFont.GetFont(size: 20, weight: FontWeight.Medium)) { + + Direction = FillDirection.Full, RelativeSizeAxes = Axes.X, - AllowMultiline = true, + AutoSizeAxes = Axes.Y, Margin = new MarginPadding { Bottom = 10, Horizontal = 5 }, - Font = OsuFont.GetFont(size: 20, weight: FontWeight.Medium), Colour = Color4.Orange, }, - link = new LinkFlowContainer(t => t.Font = OsuFont.GetFont(size: 14)) + linkContainer = new LinkFlowContainer(t => t.Font = OsuFont.GetFont(size: 14)) { Direction = FillDirection.Full, RelativeSizeAxes = Axes.X, @@ -83,12 +82,12 @@ namespace osu.Game.Overlays.BeatmapSet private void updateText() { - text.Text = availability.DownloadDisabled + textContainer.Text = BeatmapSet.OnlineInfo.Availability.DownloadDisabled ? "This beatmap is currently not available for download." : "Portions of this beatmap have been removed at the request of the creator or a third-party rights holder."; - if (!string.IsNullOrEmpty(availability.ExternalLink)) - link.AddLink("Check here for more information.", availability.ExternalLink); + if (!string.IsNullOrEmpty(BeatmapSet.OnlineInfo.Availability.ExternalLink)) + linkContainer.AddLink("Check here for more information.", BeatmapSet.OnlineInfo.Availability.ExternalLink); } } } From 475b40cc0295192cae8346cb7050766deb495076 Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Wed, 19 Jun 2019 14:47:29 +0300 Subject: [PATCH 069/148] Remove empty line --- osu.Game/Overlays/BeatmapSet/BeatmapNotAvailable.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Overlays/BeatmapSet/BeatmapNotAvailable.cs b/osu.Game/Overlays/BeatmapSet/BeatmapNotAvailable.cs index 979d0b6fa2..34be01543b 100644 --- a/osu.Game/Overlays/BeatmapSet/BeatmapNotAvailable.cs +++ b/osu.Game/Overlays/BeatmapSet/BeatmapNotAvailable.cs @@ -61,7 +61,6 @@ namespace osu.Game.Overlays.BeatmapSet { textContainer = new TextFlowContainer(t => t.Font = OsuFont.GetFont(size: 20, weight: FontWeight.Medium)) { - Direction = FillDirection.Full, RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, From a6c268ef5ca84f4a64e736ab924a8a81e89f0ed6 Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Wed, 19 Jun 2019 15:05:53 +0300 Subject: [PATCH 070/148] Move the horizontal margin into the sprite text itself --- osu.Game/Overlays/BeatmapSet/BeatmapNotAvailable.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/BeatmapNotAvailable.cs b/osu.Game/Overlays/BeatmapSet/BeatmapNotAvailable.cs index 34be01543b..cb9284a295 100644 --- a/osu.Game/Overlays/BeatmapSet/BeatmapNotAvailable.cs +++ b/osu.Game/Overlays/BeatmapSet/BeatmapNotAvailable.cs @@ -59,20 +59,20 @@ namespace osu.Game.Overlays.BeatmapSet Margin = new MarginPadding { Top = 10, Left = 5, Right = 20 }, Children = new Drawable[] { - textContainer = new TextFlowContainer(t => t.Font = OsuFont.GetFont(size: 20, weight: FontWeight.Medium)) + textContainer = new TextFlowContainer(t => { t.Font = OsuFont.GetFont(size: 20, weight: FontWeight.Medium); t.Margin = new MarginPadding { Horizontal = 5 }; }) { Direction = FillDirection.Full, RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, - Margin = new MarginPadding { Bottom = 10, Horizontal = 5 }, + Margin = new MarginPadding { Bottom = 10 }, Colour = Color4.Orange, }, - linkContainer = new LinkFlowContainer(t => t.Font = OsuFont.GetFont(size: 14)) + linkContainer = new LinkFlowContainer(t => { t.Font = OsuFont.GetFont(size: 14); t.Margin = new MarginPadding { Horizontal = 5 }; }) { Direction = FillDirection.Full, RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, - Margin = new MarginPadding { Bottom = 10, Horizontal = 5 }, + Margin = new MarginPadding { Bottom = 10 }, }, }, }, From 4b46601eae6efda450b70dc70aa9c86cb5f01fa5 Mon Sep 17 00:00:00 2001 From: naoey Date: Wed, 19 Jun 2019 19:43:09 +0530 Subject: [PATCH 071/148] Remove redundant variable, handle all request failures --- .../DownloadableArchiveModelManager.cs | 26 +++++++++++-------- .../API/Requests/DownloadBeatmapSetRequest.cs | 4 +-- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/osu.Game/Database/DownloadableArchiveModelManager.cs b/osu.Game/Database/DownloadableArchiveModelManager.cs index d9ebd0c06a..90d5ec3f17 100644 --- a/osu.Game/Database/DownloadableArchiveModelManager.cs +++ b/osu.Game/Database/DownloadableArchiveModelManager.cs @@ -94,16 +94,7 @@ namespace osu.Game.Database }, TaskCreationOptions.LongRunning); }; - request.Failure += error => - { - DownloadFailed?.Invoke(request); - - if (error is OperationCanceledException) return; - - notification.State = ProgressNotificationState.Cancelled; - Logger.Error(error, $"{HumanisedModelName.Titleize()} download failed!"); - currentDownloads.Remove(request); - }; + request.Failure += error => handleRequestFailure(request, notification, error); notification.CancelRequested += () => { @@ -122,14 +113,27 @@ namespace osu.Game.Database { request.Perform(api); } - catch + catch (Exception e) { + // 404s (and maybe other failures) don't fire request.Failure so for now they handled here as well + handleRequestFailure(request, notification, e); } }, TaskCreationOptions.LongRunning); DownloadBegan?.Invoke(request); } + private void handleRequestFailure(ArchiveDownloadRequest req, ProgressNotification notification, Exception e) + { + DownloadFailed?.Invoke(req); + + if (e is OperationCanceledException) return; + + notification.State = ProgressNotificationState.Cancelled; + Logger.Error(e, $"{HumanisedModelName.Titleize()} download failed!"); + currentDownloads.Remove(req); + } + private class DownloadNotification : ProgressNotification { public override bool IsImportant => false; diff --git a/osu.Game/Online/API/Requests/DownloadBeatmapSetRequest.cs b/osu.Game/Online/API/Requests/DownloadBeatmapSetRequest.cs index 999864a6eb..707c59436d 100644 --- a/osu.Game/Online/API/Requests/DownloadBeatmapSetRequest.cs +++ b/osu.Game/Online/API/Requests/DownloadBeatmapSetRequest.cs @@ -8,15 +8,13 @@ namespace osu.Game.Online.API.Requests public class DownloadBeatmapSetRequest : ArchiveDownloadRequest { private readonly bool noVideo; - private readonly BeatmapSetInfo set; public DownloadBeatmapSetRequest(BeatmapSetInfo set, bool noVideo) : base(set) { this.noVideo = noVideo; - this.set = set; } - protected override string Target => $@"beatmapsets/{set.OnlineBeatmapSetID}/download{(noVideo ? "?noVideo=1" : "")}"; + protected override string Target => $@"beatmapsets/{Model.OnlineBeatmapSetID}/download{(noVideo ? "?noVideo=1" : "")}"; } } From 9f25d3cd72972042881cf6254332425a1a4db3d8 Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Wed, 19 Jun 2019 17:55:36 +0300 Subject: [PATCH 072/148] More changes and improvements --- .../Online/TestSceneBeatmapNotAvailable.cs | 68 ++++++++++++++++--- .../Online/TestSceneBeatmapSetOverlay.cs | 3 +- .../BeatmapSet/BeatmapNotAvailable.cs | 11 ++- 3 files changed, 63 insertions(+), 19 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneBeatmapNotAvailable.cs b/osu.Game.Tests/Visual/Online/TestSceneBeatmapNotAvailable.cs index 22e3e63c28..553b081f28 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneBeatmapNotAvailable.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneBeatmapNotAvailable.cs @@ -1,51 +1,97 @@ // 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.Overlays.BeatmapSet; namespace osu.Game.Tests.Visual.Online { + [TestFixture] public class TestSceneBeatmapNotAvailable : OsuTestScene { + BeatmapNotAvailable container; + public TestSceneBeatmapNotAvailable() { - var container = new BeatmapNotAvailable(); + Add(container = new BeatmapNotAvailable()); + } - Add(container); - - AddStep("set undownloadable beatmapset", () => container.BeatmapSet = new BeatmapSetInfo + [Test] + public void TestUndownloadableWithLink() + { + AddStep("set undownloadable beatmapset with link", () => container.BeatmapSet = new BeatmapSetInfo { OnlineInfo = new BeatmapSetOnlineInfo { Availability = new BeatmapSetOnlineAvailability { DownloadDisabled = true, - ExternalLink = @"https://gist.githubusercontent.com/peppy/99e6959772083cdfde8a/raw", + ExternalLink = @"https://osu.ppy.sh", }, }, }); - AddAssert("is container visible", () => container.Alpha == 1); - AddStep("set downloadable beatmapset", () => container.BeatmapSet = new BeatmapSetInfo + visiblityAssert(true); + } + + [Test] + public void TestUndownloadableNoLink() + { + AddStep("set undownloadable beatmapset without link", () => container.BeatmapSet = new BeatmapSetInfo + { + OnlineInfo = new BeatmapSetOnlineInfo + { + Availability = new BeatmapSetOnlineAvailability + { + DownloadDisabled = true, + }, + }, + }); + + visiblityAssert(true); + } + + + + [Test] + public void TestPartsRemovedWithLink() + { + AddStep("set parts-removed beatmapset with link", () => container.BeatmapSet = new BeatmapSetInfo { OnlineInfo = new BeatmapSetOnlineInfo { Availability = new BeatmapSetOnlineAvailability { DownloadDisabled = false, - ExternalLink = @"https://gist.githubusercontent.com/peppy/99e6959772083cdfde8a/raw", + ExternalLink = @"https://osu.ppy.sh", }, }, }); - AddAssert("is container still visible", () => container.Alpha == 1); + visiblityAssert(true); + } + + [Test] + public void TestNormal() + { AddStep("set normal beatmapset", () => container.BeatmapSet = new BeatmapSetInfo { - OnlineInfo = new BeatmapSetOnlineInfo(), + OnlineInfo = new BeatmapSetOnlineInfo + { + Availability = new BeatmapSetOnlineAvailability + { + DownloadDisabled = false, + }, + }, }); - AddAssert("is container hidden", () => container.Alpha == 0); + visiblityAssert(false); + } + + private void visiblityAssert(bool shown) + { + AddAssert($"is container {(shown ? "visible" : "hidden")}", () => container.Alpha == (shown ? 1 : 0)); } } } diff --git a/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs index 2e68be981c..e365368c18 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs @@ -565,7 +565,7 @@ namespace osu.Game.Tests.Visual.Online downloadAssert(true); - AddStep(@"show undownloadable", () => + AddStep(@"show undownloadable (no link)", () => { overlay.ShowBeatmapSet(new BeatmapSetInfo { @@ -586,7 +586,6 @@ namespace osu.Game.Tests.Visual.Online Availability = new BeatmapSetOnlineAvailability { DownloadDisabled = true, - ExternalLink = @"https://gist.githubusercontent.com/peppy/99e6959772083cdfde8a/raw", }, Preview = @"https://b.ppy.sh/preview/53853.mp3", PlayCount = 436213, diff --git a/osu.Game/Overlays/BeatmapSet/BeatmapNotAvailable.cs b/osu.Game/Overlays/BeatmapSet/BeatmapNotAvailable.cs index cb9284a295..55ad70aec0 100644 --- a/osu.Game/Overlays/BeatmapSet/BeatmapNotAvailable.cs +++ b/osu.Game/Overlays/BeatmapSet/BeatmapNotAvailable.cs @@ -26,7 +26,7 @@ namespace osu.Game.Overlays.BeatmapSet beatmapSet = value; - bool unavailable = BeatmapSet?.OnlineInfo.Availability != null; + bool unavailable = (BeatmapSet?.OnlineInfo.Availability?.DownloadDisabled ?? false) || (BeatmapSet?.OnlineInfo.Availability?.ExternalLink != null); this.FadeTo(unavailable ? 1 : 0); linkContainer.Clear(); @@ -56,23 +56,22 @@ namespace osu.Game.Overlays.BeatmapSet RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, Direction = FillDirection.Vertical, - Margin = new MarginPadding { Top = 10, Left = 5, Right = 20 }, + Padding = new MarginPadding(10), Children = new Drawable[] { - textContainer = new TextFlowContainer(t => { t.Font = OsuFont.GetFont(size: 20, weight: FontWeight.Medium); t.Margin = new MarginPadding { Horizontal = 5 }; }) + textContainer = new TextFlowContainer(t => t.Font = OsuFont.GetFont(size: 20, weight: FontWeight.Medium)) { Direction = FillDirection.Full, RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, - Margin = new MarginPadding { Bottom = 10 }, Colour = Color4.Orange, }, - linkContainer = new LinkFlowContainer(t => { t.Font = OsuFont.GetFont(size: 14); t.Margin = new MarginPadding { Horizontal = 5 }; }) + linkContainer = new LinkFlowContainer(t => t.Font = OsuFont.GetFont(size: 14)) { Direction = FillDirection.Full, RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, - Margin = new MarginPadding { Bottom = 10 }, + Padding = new MarginPadding { Top = 10 }, }, }, }, From 4fba255bd93babdba8f78140e466d898ae6e70b3 Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Wed, 19 Jun 2019 17:56:40 +0300 Subject: [PATCH 073/148] Remove gap --- osu.Game.Tests/Visual/Online/TestSceneBeatmapNotAvailable.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneBeatmapNotAvailable.cs b/osu.Game.Tests/Visual/Online/TestSceneBeatmapNotAvailable.cs index 553b081f28..665be4d075 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneBeatmapNotAvailable.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneBeatmapNotAvailable.cs @@ -52,8 +52,6 @@ namespace osu.Game.Tests.Visual.Online visiblityAssert(true); } - - [Test] public void TestPartsRemovedWithLink() { From a9f87e06f82a3a6b960e7f6136845bc378bae6c2 Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Wed, 19 Jun 2019 19:08:18 +0300 Subject: [PATCH 074/148] Make field readonly --- osu.Game.Tests/Visual/Online/TestSceneBeatmapNotAvailable.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneBeatmapNotAvailable.cs b/osu.Game.Tests/Visual/Online/TestSceneBeatmapNotAvailable.cs index 665be4d075..00ab89389e 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneBeatmapNotAvailable.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneBeatmapNotAvailable.cs @@ -10,7 +10,7 @@ namespace osu.Game.Tests.Visual.Online [TestFixture] public class TestSceneBeatmapNotAvailable : OsuTestScene { - BeatmapNotAvailable container; + private readonly BeatmapNotAvailable container; public TestSceneBeatmapNotAvailable() { From eb9022257db7483f0398aabd0ef43b9b8e5c5d7b Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Thu, 20 Jun 2019 18:57:52 +0300 Subject: [PATCH 075/148] Update direct panel test --- .../Visual/Online/TestSceneDirectPanel.cs | 46 ++++++++++--------- 1 file changed, 25 insertions(+), 21 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneDirectPanel.cs b/osu.Game.Tests/Visual/Online/TestSceneDirectPanel.cs index a2767611ac..9667e5a752 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneDirectPanel.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneDirectPanel.cs @@ -23,16 +23,20 @@ namespace osu.Game.Tests.Visual.Online typeof(IconPill) }; - private BeatmapSetInfo getBeatmapSet(RulesetInfo ruleset, bool downloadable) + private BeatmapSetInfo getUndownloadableBeatmapSet(RulesetInfo ruleset) { var beatmap = CreateWorkingBeatmap(ruleset).BeatmapSetInfo; + beatmap.Metadata.Artist = "test"; + beatmap.Metadata.Title = "undownloadable"; + beatmap.Metadata.AuthorString = "test"; + beatmap.OnlineInfo.HasVideo = true; beatmap.OnlineInfo.HasStoryboard = true; beatmap.OnlineInfo.Availability = new BeatmapSetOnlineAvailability { - DownloadDisabled = !downloadable, - ExternalLink = "http://localhost", + DownloadDisabled = true, + ExternalLink = "http://osu.ppy.sh", }; return beatmap; @@ -47,31 +51,31 @@ namespace osu.Game.Tests.Visual.Online normal.OnlineInfo.HasVideo = true; normal.OnlineInfo.HasStoryboard = true; - var downloadable = getBeatmapSet(ruleset, true); - var undownloadable = getBeatmapSet(ruleset, false); - + var undownloadable = getUndownloadableBeatmapSet(ruleset); DirectPanel undownloadableGridPanel, undownloadableListPanel; - Child = new FillFlowContainer + Child = new BasicScrollContainer { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Direction = FillDirection.Vertical, - Padding = new MarginPadding(20), - Spacing = new Vector2(0, 20), - Children = new Drawable[] + RelativeSizeAxes = Axes.Both, + Child = new FillFlowContainer { - new DirectGridPanel(normal), - new DirectGridPanel(downloadable), - undownloadableGridPanel = new DirectGridPanel(undownloadable), - new DirectListPanel(normal), - new DirectListPanel(downloadable), - undownloadableListPanel = new DirectListPanel(undownloadable), + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Vertical, + Padding = new MarginPadding(20), + Spacing = new Vector2(0, 20), + Children = new Drawable[] + { + new DirectGridPanel(normal), + new DirectListPanel(normal), + undownloadableGridPanel = new DirectGridPanel(undownloadable), + undownloadableListPanel = new DirectListPanel(undownloadable), + }, }, }; - AddAssert("is download button disabled on last grid panel", () => !undownloadableGridPanel.DownloadButton.Enabled.Value); - AddAssert("is download button disabled on last list panel", () => !undownloadableListPanel.DownloadButton.Enabled.Value); + AddAssert("is download button disabled on second grid panel", () => !undownloadableGridPanel.DownloadButton.Enabled.Value); + AddAssert("is download button disabled on second list panel", () => !undownloadableListPanel.DownloadButton.Enabled.Value); } } } From d75481945379f8861b8e441b3da58c2c2f32eaeb Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Thu, 20 Jun 2019 19:09:40 +0300 Subject: [PATCH 076/148] Small changes --- .../Overlays/BeatmapSet/BeatmapNotAvailable.cs | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/BeatmapNotAvailable.cs b/osu.Game/Overlays/BeatmapSet/BeatmapNotAvailable.cs index 55ad70aec0..5eb48220c6 100644 --- a/osu.Game/Overlays/BeatmapSet/BeatmapNotAvailable.cs +++ b/osu.Game/Overlays/BeatmapSet/BeatmapNotAvailable.cs @@ -16,6 +16,9 @@ namespace osu.Game.Overlays.BeatmapSet { private BeatmapSetInfo beatmapSet; + private bool downloadDisabled => BeatmapSet?.OnlineInfo.Availability.DownloadDisabled ?? false; + private bool hasExternalLink => !string.IsNullOrEmpty(BeatmapSet?.OnlineInfo.Availability.ExternalLink); + public BeatmapSetInfo BeatmapSet { get => beatmapSet; @@ -26,12 +29,14 @@ namespace osu.Game.Overlays.BeatmapSet beatmapSet = value; - bool unavailable = (BeatmapSet?.OnlineInfo.Availability?.DownloadDisabled ?? false) || (BeatmapSet?.OnlineInfo.Availability?.ExternalLink != null); - this.FadeTo(unavailable ? 1 : 0); - linkContainer.Clear(); - if (unavailable) + + if (downloadDisabled || hasExternalLink) + { + Show(); updateText(); + } + else Hide(); } } @@ -80,11 +85,11 @@ namespace osu.Game.Overlays.BeatmapSet private void updateText() { - textContainer.Text = BeatmapSet.OnlineInfo.Availability.DownloadDisabled + textContainer.Text = downloadDisabled ? "This beatmap is currently not available for download." : "Portions of this beatmap have been removed at the request of the creator or a third-party rights holder."; - if (!string.IsNullOrEmpty(BeatmapSet.OnlineInfo.Availability.ExternalLink)) + if (hasExternalLink) linkContainer.AddLink("Check here for more information.", BeatmapSet.OnlineInfo.Availability.ExternalLink); } } From 13578e5c2179352dd2b7f0056e965804ef3530e2 Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Thu, 20 Jun 2019 19:43:31 +0300 Subject: [PATCH 077/148] Add the null conditional operator back --- osu.Game/Overlays/BeatmapSet/BeatmapNotAvailable.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/BeatmapNotAvailable.cs b/osu.Game/Overlays/BeatmapSet/BeatmapNotAvailable.cs index 5eb48220c6..0e51d473a5 100644 --- a/osu.Game/Overlays/BeatmapSet/BeatmapNotAvailable.cs +++ b/osu.Game/Overlays/BeatmapSet/BeatmapNotAvailable.cs @@ -16,8 +16,8 @@ namespace osu.Game.Overlays.BeatmapSet { private BeatmapSetInfo beatmapSet; - private bool downloadDisabled => BeatmapSet?.OnlineInfo.Availability.DownloadDisabled ?? false; - private bool hasExternalLink => !string.IsNullOrEmpty(BeatmapSet?.OnlineInfo.Availability.ExternalLink); + private bool downloadDisabled => BeatmapSet?.OnlineInfo.Availability?.DownloadDisabled ?? false; + private bool hasExternalLink => !string.IsNullOrEmpty(BeatmapSet?.OnlineInfo.Availability?.ExternalLink); public BeatmapSetInfo BeatmapSet { From 0cc7a604edb40b3e85cbf5e8c0cda8965380b7ff Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Fri, 21 Jun 2019 14:18:20 +0300 Subject: [PATCH 078/148] Update font sizes --- osu.Game/Overlays/BeatmapSet/BeatmapNotAvailable.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/BeatmapNotAvailable.cs b/osu.Game/Overlays/BeatmapSet/BeatmapNotAvailable.cs index 0e51d473a5..44e29a5011 100644 --- a/osu.Game/Overlays/BeatmapSet/BeatmapNotAvailable.cs +++ b/osu.Game/Overlays/BeatmapSet/BeatmapNotAvailable.cs @@ -64,14 +64,14 @@ namespace osu.Game.Overlays.BeatmapSet Padding = new MarginPadding(10), Children = new Drawable[] { - textContainer = new TextFlowContainer(t => t.Font = OsuFont.GetFont(size: 20, weight: FontWeight.Medium)) + textContainer = new TextFlowContainer(t => t.Font = OsuFont.GetFont(size: 14, weight: FontWeight.Medium)) { Direction = FillDirection.Full, RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, Colour = Color4.Orange, }, - linkContainer = new LinkFlowContainer(t => t.Font = OsuFont.GetFont(size: 14)) + linkContainer = new LinkFlowContainer(t => t.Font = OsuFont.GetFont(size: 10)) { Direction = FillDirection.Full, RelativeSizeAxes = Axes.X, From bd842f2a8c0b2941e04851b5dc3e18510e349787 Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Fri, 21 Jun 2019 16:38:16 +0300 Subject: [PATCH 079/148] Update tooltip text --- osu.Game/Overlays/Direct/DownloadButton.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Direct/DownloadButton.cs b/osu.Game/Overlays/Direct/DownloadButton.cs index 10e6f8a6e1..bb2c68a9a1 100644 --- a/osu.Game/Overlays/Direct/DownloadButton.cs +++ b/osu.Game/Overlays/Direct/DownloadButton.cs @@ -85,7 +85,7 @@ namespace osu.Game.Overlays.Direct if (BeatmapSet.Value.OnlineInfo.Availability?.DownloadDisabled ?? false) { Enabled.Value = false; - button.TooltipText = "Unavailable"; + button.TooltipText = "This beatmap is currently not available for download."; return; } From 94e819578e51b4ad8cf30a28531c16d7d72633d5 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Mon, 24 Jun 2019 01:55:35 +0300 Subject: [PATCH 080/148] Finally fix the problem when we can't apply a ruleset in the multi screen because it's disabled --- osu.Game/Screens/Multi/Match/MatchSubScreen.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/osu.Game/Screens/Multi/Match/MatchSubScreen.cs b/osu.Game/Screens/Multi/Match/MatchSubScreen.cs index a80056d164..c1bb5e262d 100644 --- a/osu.Game/Screens/Multi/Match/MatchSubScreen.cs +++ b/osu.Game/Screens/Multi/Match/MatchSubScreen.cs @@ -196,7 +196,11 @@ namespace osu.Game.Screens.Multi.Match Beatmap.Value = beatmapManager.GetWorkingBeatmap(localBeatmap); Mods.Value = e.NewValue?.RequiredMods?.ToArray() ?? Array.Empty(); if (e.NewValue?.Ruleset != null) + { + Ruleset.Disabled = false; Ruleset.Value = e.NewValue.Ruleset; + Ruleset.Disabled = true; + } } /// From 35db20a3378fd35df275faa7b6742beebea3c131 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Mon, 24 Jun 2019 02:01:00 +0300 Subject: [PATCH 081/148] Remove useless bindable check --- osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.cs | 7 +------ osu.Game/Rulesets/BindableRulesetSelector.cs | 8 +------- 2 files changed, 2 insertions(+), 13 deletions(-) diff --git a/osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.cs b/osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.cs index d89418b50c..5cd061f3da 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.cs @@ -92,12 +92,7 @@ namespace osu.Game.Overlays.Toolbar private readonly Cached activeMode = new Cached(); - protected override void OnRulesetChanged(ValueChangedEvent e) - { - base.OnRulesetChanged(e); - - activeMode.Invalidate(); - } + protected override void OnRulesetChanged(ValueChangedEvent e) => activeMode.Invalidate(); protected override void UpdateAfterChildren() { diff --git a/osu.Game/Rulesets/BindableRulesetSelector.cs b/osu.Game/Rulesets/BindableRulesetSelector.cs index 8c9bbcea0d..d752088a25 100644 --- a/osu.Game/Rulesets/BindableRulesetSelector.cs +++ b/osu.Game/Rulesets/BindableRulesetSelector.cs @@ -15,12 +15,6 @@ namespace osu.Game.Rulesets Current.BindValueChanged(OnRulesetChanged); } - protected virtual void OnRulesetChanged(ValueChangedEvent e) - { - if (Current.Disabled) - { - return; - } - } + protected abstract void OnRulesetChanged(ValueChangedEvent e); } } From bbdb114f045ea66cd59e3e85d1ec44b276e7f0aa Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Mon, 24 Jun 2019 02:09:00 +0300 Subject: [PATCH 082/148] Add missing blank line --- osu.Game/Screens/Multi/Match/MatchSubScreen.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Screens/Multi/Match/MatchSubScreen.cs b/osu.Game/Screens/Multi/Match/MatchSubScreen.cs index c1bb5e262d..d33ff74a2b 100644 --- a/osu.Game/Screens/Multi/Match/MatchSubScreen.cs +++ b/osu.Game/Screens/Multi/Match/MatchSubScreen.cs @@ -195,6 +195,7 @@ namespace osu.Game.Screens.Multi.Match Beatmap.Value = beatmapManager.GetWorkingBeatmap(localBeatmap); Mods.Value = e.NewValue?.RequiredMods?.ToArray() ?? Array.Empty(); + if (e.NewValue?.Ruleset != null) { Ruleset.Disabled = false; From 9dedd62d9a058979a32ffb69d61df482271c6612 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Mon, 24 Jun 2019 22:57:18 +0300 Subject: [PATCH 083/148] Revert a hotfix in multi screen since it's been fixed in a framework --- osu.Game/Screens/Multi/Match/MatchSubScreen.cs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/osu.Game/Screens/Multi/Match/MatchSubScreen.cs b/osu.Game/Screens/Multi/Match/MatchSubScreen.cs index d33ff74a2b..b7fb758298 100644 --- a/osu.Game/Screens/Multi/Match/MatchSubScreen.cs +++ b/osu.Game/Screens/Multi/Match/MatchSubScreen.cs @@ -197,11 +197,7 @@ namespace osu.Game.Screens.Multi.Match Mods.Value = e.NewValue?.RequiredMods?.ToArray() ?? Array.Empty(); if (e.NewValue?.Ruleset != null) - { - Ruleset.Disabled = false; Ruleset.Value = e.NewValue.Ruleset; - Ruleset.Disabled = true; - } } /// From 4a05c560cf7459558ab6eb4cf1f194a344a7cac1 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Mon, 24 Jun 2019 23:13:28 +0300 Subject: [PATCH 084/148] Remove unwanted class and move the bind logic outside the RulesetSelector --- osu.Game/Overlays/Toolbar/Toolbar.cs | 8 ++++++-- .../Toolbar/ToolbarRulesetSelector.cs | 6 ++---- osu.Game/Rulesets/BindableRulesetSelector.cs | 20 ------------------- 3 files changed, 8 insertions(+), 26 deletions(-) delete mode 100644 osu.Game/Rulesets/BindableRulesetSelector.cs diff --git a/osu.Game/Overlays/Toolbar/Toolbar.cs b/osu.Game/Overlays/Toolbar/Toolbar.cs index 982fb26b6b..19e3e1c833 100644 --- a/osu.Game/Overlays/Toolbar/Toolbar.cs +++ b/osu.Game/Overlays/Toolbar/Toolbar.cs @@ -12,6 +12,7 @@ using osu.Framework.Graphics.Shapes; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Input.Events; +using osu.Game.Rulesets; namespace osu.Game.Overlays.Toolbar { @@ -23,6 +24,7 @@ namespace osu.Game.Overlays.Toolbar public Action OnHome; private ToolbarUserButton userButton; + private ToolbarRulesetSelector rulesetSelector; protected override bool BlockPositionalInput => false; @@ -40,7 +42,7 @@ namespace osu.Game.Overlays.Toolbar } [BackgroundDependencyLoader(true)] - private void load(OsuGame osuGame) + private void load(OsuGame osuGame, Bindable parentRuleset) { Children = new Drawable[] { @@ -57,7 +59,7 @@ namespace osu.Game.Overlays.Toolbar { Action = () => OnHome?.Invoke() }, - new ToolbarRulesetSelector() + rulesetSelector = new ToolbarRulesetSelector() } }, new FillFlowContainer @@ -84,6 +86,8 @@ namespace osu.Game.Overlays.Toolbar } }; + rulesetSelector.Current.BindTarget = parentRuleset; + State.ValueChanged += visibility => { if (overlayActivationMode.Value == OverlayActivation.Disabled) diff --git a/osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.cs b/osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.cs index 5cd061f3da..7f3c14057b 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.cs @@ -10,14 +10,13 @@ using osuTK.Graphics; using osu.Framework.Graphics.Shapes; using osu.Game.Rulesets; using osu.Framework.Graphics.UserInterface; -using osu.Framework.Bindables; using osu.Framework.Input.Events; using osuTK.Input; using System.Linq; namespace osu.Game.Overlays.Toolbar { - public class ToolbarRulesetSelector : BindableRulesetSelector + public class ToolbarRulesetSelector : RulesetSelector { private const float padding = 10; private readonly Drawable modeButtonLine; @@ -63,6 +62,7 @@ namespace osu.Game.Overlays.Toolbar }); Current.DisabledChanged += disabledChanged; + Current.ValueChanged += (value) => activeMode.Invalidate(); } protected override TabFillFlowContainer CreateTabFlow() => new TabFillFlowContainer @@ -92,8 +92,6 @@ namespace osu.Game.Overlays.Toolbar private readonly Cached activeMode = new Cached(); - protected override void OnRulesetChanged(ValueChangedEvent e) => activeMode.Invalidate(); - protected override void UpdateAfterChildren() { base.UpdateAfterChildren(); diff --git a/osu.Game/Rulesets/BindableRulesetSelector.cs b/osu.Game/Rulesets/BindableRulesetSelector.cs deleted file mode 100644 index d752088a25..0000000000 --- a/osu.Game/Rulesets/BindableRulesetSelector.cs +++ /dev/null @@ -1,20 +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.Bindables; - -namespace osu.Game.Rulesets -{ - public abstract class BindableRulesetSelector : RulesetSelector - { - [BackgroundDependencyLoader] - private void load(Bindable parentRuleset) - { - Current.BindTo(parentRuleset); - Current.BindValueChanged(OnRulesetChanged); - } - - protected abstract void OnRulesetChanged(ValueChangedEvent e); - } -} From b7d15982d7109a0de86d1019626ed704da50f546 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Mon, 24 Jun 2019 23:30:35 +0300 Subject: [PATCH 085/148] Remove useless parentheses --- osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.cs b/osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.cs index 7f3c14057b..2e4a6fe8fc 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.cs @@ -62,7 +62,7 @@ namespace osu.Game.Overlays.Toolbar }); Current.DisabledChanged += disabledChanged; - Current.ValueChanged += (value) => activeMode.Invalidate(); + Current.ValueChanged += value => activeMode.Invalidate(); } protected override TabFillFlowContainer CreateTabFlow() => new TabFillFlowContainer From 4d8f49b9bc5ab17cbe1eb70a41794227ddf856c1 Mon Sep 17 00:00:00 2001 From: jorolf Date: Mon, 24 Jun 2019 23:17:07 +0200 Subject: [PATCH 086/148] update code to work with https://github.com/ppy/osu-framework/pull/2568 --- osu.Game/Graphics/UserInterface/OsuDropdown.cs | 7 ++++++- osu.Game/Graphics/UserInterface/OsuMenu.cs | 3 +++ osu.Game/Graphics/UserInterface/OsuTabControl.cs | 2 +- .../Overlays/Settings/Sections/General/LoginSettings.cs | 2 +- 4 files changed, 11 insertions(+), 3 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/OsuDropdown.cs b/osu.Game/Graphics/UserInterface/OsuDropdown.cs index 8245de9f70..2aa4734476 100644 --- a/osu.Game/Graphics/UserInterface/OsuDropdown.cs +++ b/osu.Game/Graphics/UserInterface/OsuDropdown.cs @@ -9,6 +9,7 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.UserInterface; +using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; using osuTK; @@ -95,7 +96,11 @@ namespace osu.Game.Graphics.UserInterface } } - protected override DrawableMenuItem CreateDrawableMenuItem(MenuItem item) => new DrawableOsuDropdownMenuItem(item) { AccentColour = accentColour }; + protected override Menu CreateSubMenu() => new OsuMenu(Direction.Vertical); + + protected override ScrollContainer CreateScrollContainer(Direction direction) => new OsuScrollContainer(direction); + + protected override DrawableDropdownMenuItem CreateDrawableDropdownMenuItem(MenuItem item) => new DrawableOsuDropdownMenuItem(item) { AccentColour = accentColour }; #region DrawableOsuDropdownMenuItem diff --git a/osu.Game/Graphics/UserInterface/OsuMenu.cs b/osu.Game/Graphics/UserInterface/OsuMenu.cs index f8234cb81f..74ca809395 100644 --- a/osu.Game/Graphics/UserInterface/OsuMenu.cs +++ b/osu.Game/Graphics/UserInterface/OsuMenu.cs @@ -11,6 +11,7 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.UserInterface; using osu.Framework.Input.Events; +using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; using osuTK; @@ -44,6 +45,8 @@ namespace osu.Game.Graphics.UserInterface } } + protected override ScrollContainer CreateScrollContainer(Direction direction) => new OsuScrollContainer(direction); + protected override DrawableMenuItem CreateDrawableMenuItem(MenuItem item) => new DrawableOsuMenuItem(item); protected override Menu CreateSubMenu() => new OsuMenu(Direction.Vertical) diff --git a/osu.Game/Graphics/UserInterface/OsuTabControl.cs b/osu.Game/Graphics/UserInterface/OsuTabControl.cs index fadc905541..11f41b1a48 100644 --- a/osu.Game/Graphics/UserInterface/OsuTabControl.cs +++ b/osu.Game/Graphics/UserInterface/OsuTabControl.cs @@ -210,7 +210,7 @@ namespace osu.Game.Graphics.UserInterface MaxHeight = 400; } - protected override DrawableMenuItem CreateDrawableMenuItem(MenuItem item) => new DrawableOsuTabDropdownMenuItem(item) { AccentColour = AccentColour }; + protected override DrawableDropdownMenuItem CreateDrawableDropdownMenuItem(MenuItem item) => new DrawableOsuTabDropdownMenuItem(item) { AccentColour = AccentColour }; private class DrawableOsuTabDropdownMenuItem : DrawableOsuDropdownMenuItem { diff --git a/osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs b/osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs index 1454b6592d..66fec1ecf9 100644 --- a/osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs @@ -319,7 +319,7 @@ namespace osu.Game.Overlays.Settings.Sections.General BackgroundColour = colours.Gray3; } - protected override DrawableMenuItem CreateDrawableMenuItem(MenuItem item) => new DrawableUserDropdownMenuItem(item); + protected override DrawableDropdownMenuItem CreateDrawableDropdownMenuItem(MenuItem item) => new DrawableUserDropdownMenuItem(item); private class DrawableUserDropdownMenuItem : DrawableOsuDropdownMenuItem { From c76505c9c30530b7680e98d83e50b67ea4e69820 Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Tue, 25 Jun 2019 03:21:55 +0300 Subject: [PATCH 087/148] Use test beatmap sets instead of real info --- .../Online/TestSceneBeatmapSetOverlay.cs | 341 +++--------------- 1 file changed, 46 insertions(+), 295 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs index e365368c18..5539152598 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs @@ -417,305 +417,14 @@ namespace osu.Game.Tests.Visual.Online [Test] public void TestUnavailable() { - AddStep(@"show parts-removed", () => - { - overlay.ShowBeatmapSet(new BeatmapSetInfo - { - Metadata = new BeatmapMetadata - { - Title = @"Sakura Kagetsu", - Artist = @"AKITO", - Source = @"DJMAX", - Tags = @"J-Trance Pasonia", - Author = new User - { - Username = @"Kharl", - Id = 452, - }, - }, - OnlineInfo = new BeatmapSetOnlineInfo - { - Availability = new BeatmapSetOnlineAvailability - { - DownloadDisabled = false, - ExternalLink = @"https://gist.githubusercontent.com/peppy/079dc3f77e316f9cd40077d411319a72/raw", - }, - Preview = @"https://b.ppy.sh/preview/119.mp3", - PlayCount = 626927, - FavouriteCount = 157, - Submitted = new DateTime(2007, 10, 24), - Ranked = new DateTime(2008, 4, 21), - Status = BeatmapSetOnlineStatus.Ranked, - BPM = 138, - Covers = new BeatmapSetOnlineCovers - { - Cover = @"https://assets.ppy.sh/beatmaps/119/covers/cover.jpg?1539847784", - }, - }, - Metrics = new BeatmapSetMetrics { Ratings = Enumerable.Range(0, 11).ToArray() }, - Beatmaps = new List - { - new BeatmapInfo - { - StarDifficulty = 1.51, - Version = "Easy", - Ruleset = osuRuleset, - BaseDifficulty = new BeatmapDifficulty - { - CircleSize = 4, - DrainRate = 2, - OverallDifficulty = 1, - ApproachRate = 1, - }, - OnlineInfo = new BeatmapOnlineInfo - { - Length = 126000, - CircleCount = 371, - SliderCount = 35, - PlayCount = 84498, - PassCount = 37482, - }, - Metrics = new BeatmapMetrics - { - Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6).ToArray(), - Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6).ToArray(), - }, - }, - new BeatmapInfo - { - StarDifficulty = 2.23, - Version = "Normal", - Ruleset = osuRuleset, - BaseDifficulty = new BeatmapDifficulty - { - CircleSize = 5, - DrainRate = 4, - OverallDifficulty = 3, - ApproachRate = 3, - }, - OnlineInfo = new BeatmapOnlineInfo - { - Length = 126000, - CircleCount = 98, - SliderCount = 28, - PlayCount = 86427, - PassCount = 23273, - }, - Metrics = new BeatmapMetrics - { - Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6).ToArray(), - Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6).ToArray(), - }, - }, - new BeatmapInfo - { - StarDifficulty = 2.83, - Version = "Hard", - Ruleset = osuRuleset, - BaseDifficulty = new BeatmapDifficulty - { - CircleSize = 6, - DrainRate = 6, - OverallDifficulty = 6, - ApproachRate = 6, - }, - OnlineInfo = new BeatmapOnlineInfo - { - Length = 126000, - CircleCount = 139, - SliderCount = 37, - PlayCount = 206523, - PassCount = 44366, - }, - Metrics = new BeatmapMetrics - { - Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6).ToArray(), - Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6).ToArray(), - }, - }, - new BeatmapInfo - { - StarDifficulty = 4.26, - Version = "Pasonia's Insane", - Ruleset = osuRuleset, - BaseDifficulty = new BeatmapDifficulty - { - CircleSize = 6, - DrainRate = 6, - OverallDifficulty = 6, - ApproachRate = 6, - }, - OnlineInfo = new BeatmapOnlineInfo - { - Length = 126000, - CircleCount = 371, - SliderCount = 35, - PlayCount = 249479, - PassCount = 14042, - }, - Metrics = new BeatmapMetrics - { - Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6).ToArray(), - Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6).ToArray(), - }, - }, - }, - }, false); - }); - + AddStep(@"show parts-removed (has link)", () => overlay.ShowBeatmapSet(getTestUnavailableBeatmapSet(false, true), false)); downloadAssert(true); - AddStep(@"show undownloadable (no link)", () => - { - overlay.ShowBeatmapSet(new BeatmapSetInfo - { - Metadata = new BeatmapMetadata - { - Title = @"China Express", - Artist = @"Ryu*", - Source = @"REFLEC BEAT", - Tags = @"konami bemani lincle link iidx iidx18 iidx19 resort anthem plus la cataline mmzz", - Author = new User - { - Username = @"yeahyeahyeahhh", - Id = 58042, - }, - }, - OnlineInfo = new BeatmapSetOnlineInfo - { - Availability = new BeatmapSetOnlineAvailability - { - DownloadDisabled = true, - }, - Preview = @"https://b.ppy.sh/preview/53853.mp3", - PlayCount = 436213, - FavouriteCount = 105, - Submitted = new DateTime(2012, 7, 1), - Ranked = new DateTime(2012, 7, 18), - Status = BeatmapSetOnlineStatus.Ranked, - BPM = 171, - Covers = new BeatmapSetOnlineCovers - { - Cover = @"https://assets.ppy.sh/beatmaps/53853/covers/cover.jpg?1456498562", - }, - }, - Metrics = new BeatmapSetMetrics { Ratings = Enumerable.Range(0, 11).ToArray() }, - Beatmaps = new List - { - new BeatmapInfo - { - StarDifficulty = 1.85, - Version = "Easy", - Ruleset = osuRuleset, - BaseDifficulty = new BeatmapDifficulty - { - CircleSize = 3, - DrainRate = 2, - OverallDifficulty = 2, - ApproachRate = 3, - }, - OnlineInfo = new BeatmapOnlineInfo - { - Length = 95000, - CircleCount = 49, - SliderCount = 60, - PlayCount = 20308, - PassCount = 10233, - }, - Metrics = new BeatmapMetrics - { - Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6).ToArray(), - Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6).ToArray(), - }, - }, - new BeatmapInfo - { - StarDifficulty = 2.36, - Version = "Normal", - Ruleset = osuRuleset, - BaseDifficulty = new BeatmapDifficulty - { - CircleSize = 3, - DrainRate = 2, - OverallDifficulty = 2, - ApproachRate = 5, - }, - OnlineInfo = new BeatmapOnlineInfo - { - Length = 96000, - CircleCount = 86, - SliderCount = 67, - PlayCount = 54015, - PassCount = 25603, - }, - Metrics = new BeatmapMetrics - { - Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6).ToArray(), - Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6).ToArray(), - }, - }, - new BeatmapInfo - { - StarDifficulty = 4.42, - Version = "Hyper", - Ruleset = osuRuleset, - BaseDifficulty = new BeatmapDifficulty - { - CircleSize = 4, - DrainRate = 7, - OverallDifficulty = 6, - ApproachRate = 8, - }, - OnlineInfo = new BeatmapOnlineInfo - { - Length = 96000, - CircleCount = 215, - SliderCount = 120, - PlayCount = 111400, - PassCount = 12583, - }, - Metrics = new BeatmapMetrics - { - Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6).ToArray(), - Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6).ToArray(), - }, - }, - new BeatmapInfo - { - StarDifficulty = 5.05, - Version = "Another", - Ruleset = osuRuleset, - BaseDifficulty = new BeatmapDifficulty - { - CircleSize = 4, - DrainRate = 7, - OverallDifficulty = 9, - ApproachRate = 9, - }, - OnlineInfo = new BeatmapOnlineInfo - { - Length = 96000, - CircleCount = 250, - SliderCount = 75, - PlayCount = 228253, - PassCount = 53037, - }, - Metrics = new BeatmapMetrics - { - Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6).ToArray(), - Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6).ToArray(), - }, - }, - }, - }, false); - }); - + AddStep(@"show undownloadable (no link)", () => overlay.ShowBeatmapSet(getTestUnavailableBeatmapSet(true, false), false)); downloadAssert(false); - } - private void downloadAssert(bool shown) - { - AddAssert($"is download button {(shown ? "shown" : "hidden")}", () => overlay.Header.DownloadButtonsContainer.Any() == shown); + AddStep(@"show undownloadable (has link)", () => overlay.ShowBeatmapSet(getTestUnavailableBeatmapSet(true, true), false)); + downloadAssert(false); } [Test] @@ -729,5 +438,47 @@ namespace osu.Game.Tests.Visual.Online { AddStep(@"show without reload", overlay.Show); } + + private void downloadAssert(bool shown) + { + AddAssert($"is download button {(shown ? "shown" : "hidden")}", () => overlay.Header.DownloadButtonsContainer.Any() == shown); + } + + private BeatmapSetInfo getTestUnavailableBeatmapSet(bool undownloadable, bool hasLink) => new BeatmapSetInfo + { + Metadata = new BeatmapMetadata + { + Title = undownloadable ? "undownloadable" : "parts-removed", + Artist = "test beatmapset", + AuthorString = "test", + }, + OnlineInfo = new BeatmapSetOnlineInfo + { + Availability = new BeatmapSetOnlineAvailability + { + DownloadDisabled = undownloadable, + ExternalLink = hasLink ? "https://osu.ppy.sh" : null, + }, + Preview = @"https://b.ppy.sh/preview/1.mp3", + Covers = new BeatmapSetOnlineCovers(), + }, + Metrics = new BeatmapSetMetrics { Ratings = Enumerable.Range(0, 11).ToArray() }, + Beatmaps = new List + { + new BeatmapInfo + { + StarDifficulty = 1.23, + Version = "Test", + Ruleset = osuRuleset, + BaseDifficulty = new BeatmapDifficulty(), + OnlineInfo = new BeatmapOnlineInfo(), + Metrics = new BeatmapMetrics + { + Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6).ToArray(), + Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6).ToArray(), + }, + }, + }, + }; } } From 08e31159fca22f2f599415f03de9b632073daa39 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 25 Jun 2019 14:27:29 +0300 Subject: [PATCH 088/148] Make testcase even more useful --- .../Visual/UserInterface/TestSceneToolbarRulesetSelector.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneToolbarRulesetSelector.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneToolbarRulesetSelector.cs index 3e61da73a5..582303024b 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneToolbarRulesetSelector.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneToolbarRulesetSelector.cs @@ -36,6 +36,7 @@ namespace osu.Game.Tests.Visual.UserInterface { selector.Current.Value = selector.Items.ElementAt(RNG.Next(selector.Items.Count())); }); + AddStep("Toggle disabled state", () => selector.Current.Disabled = !selector.Current.Disabled); } } } From 6f5fbd7ea136ca5f7295dc53aac34a9cbf151b56 Mon Sep 17 00:00:00 2001 From: naoey Date: Tue, 25 Jun 2019 18:28:59 +0530 Subject: [PATCH 089/148] Remove unnecessary try-catch block --- .../Database/DownloadableArchiveModelManager.cs | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/osu.Game/Database/DownloadableArchiveModelManager.cs b/osu.Game/Database/DownloadableArchiveModelManager.cs index 90d5ec3f17..cff2e8f01b 100644 --- a/osu.Game/Database/DownloadableArchiveModelManager.cs +++ b/osu.Game/Database/DownloadableArchiveModelManager.cs @@ -107,18 +107,7 @@ namespace osu.Game.Database currentDownloads.Add(request); PostNotification?.Invoke(notification); - Task.Factory.StartNew(() => - { - try - { - request.Perform(api); - } - catch (Exception e) - { - // 404s (and maybe other failures) don't fire request.Failure so for now they handled here as well - handleRequestFailure(request, notification, e); - } - }, TaskCreationOptions.LongRunning); + Task.Factory.StartNew(() => request.Perform(api), TaskCreationOptions.LongRunning); DownloadBegan?.Invoke(request); } From c476e46a8e3817706918cce627c512880622a8f6 Mon Sep 17 00:00:00 2001 From: naoey Date: Tue, 25 Jun 2019 21:16:30 +0530 Subject: [PATCH 090/148] Remove unnecessary private methods and inline used-once code --- .../DownloadableArchiveModelManager.cs | 37 ++++++++----------- 1 file changed, 15 insertions(+), 22 deletions(-) diff --git a/osu.Game/Database/DownloadableArchiveModelManager.cs b/osu.Game/Database/DownloadableArchiveModelManager.cs index cff2e8f01b..e0ac221cfc 100644 --- a/osu.Game/Database/DownloadableArchiveModelManager.cs +++ b/osu.Game/Database/DownloadableArchiveModelManager.cs @@ -60,19 +60,6 @@ namespace osu.Game.Database var request = CreateDownloadRequest(model, minimiseDownloadSize); - performDownloadWithRequest(request); - - return true; - } - - public virtual bool IsAvailableLocally(TModel model) => modelStore.ConsumableItems.Any(m => m.Equals(model) && !m.DeletePending); - - public ArchiveDownloadRequest GetExistingDownload(TModel model) => currentDownloads.Find(r => r.Model.Equals(model)); - - private bool canDownload(TModel model) => GetExistingDownload(model) == null && api != null; - - private void performDownloadWithRequest(ArchiveDownloadRequest request) - { DownloadNotification notification = new DownloadNotification { Text = $"Downloading {request.Model}", @@ -94,7 +81,16 @@ namespace osu.Game.Database }, TaskCreationOptions.LongRunning); }; - request.Failure += error => handleRequestFailure(request, notification, error); + request.Failure += error => + { + DownloadFailed?.Invoke(request); + + if (error is OperationCanceledException) return; + + notification.State = ProgressNotificationState.Cancelled; + Logger.Error(error, $"{HumanisedModelName.Titleize()} download failed!"); + currentDownloads.Remove(request); + }; notification.CancelRequested += () => { @@ -110,18 +106,15 @@ namespace osu.Game.Database Task.Factory.StartNew(() => request.Perform(api), TaskCreationOptions.LongRunning); DownloadBegan?.Invoke(request); + + return true; } - private void handleRequestFailure(ArchiveDownloadRequest req, ProgressNotification notification, Exception e) - { - DownloadFailed?.Invoke(req); + public virtual bool IsAvailableLocally(TModel model) => modelStore.ConsumableItems.Any(m => m.Equals(model) && !m.DeletePending); - if (e is OperationCanceledException) return; + public ArchiveDownloadRequest GetExistingDownload(TModel model) => currentDownloads.Find(r => r.Model.Equals(model)); - notification.State = ProgressNotificationState.Cancelled; - Logger.Error(e, $"{HumanisedModelName.Titleize()} download failed!"); - currentDownloads.Remove(req); - } + private bool canDownload(TModel model) => GetExistingDownload(model) == null && api != null; private class DownloadNotification : ProgressNotification { From 33fbf56b4c9f088bca1e6a35cfd609c3f5f18ed2 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Wed, 26 Jun 2019 05:01:29 +0300 Subject: [PATCH 091/148] Remove test beatmapsets and use existing set info --- .../Online/TestSceneBeatmapSetOverlay.cs | 67 ++++--------------- 1 file changed, 12 insertions(+), 55 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs index 5539152598..db2db2c6c9 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs @@ -42,7 +42,6 @@ namespace osu.Game.Tests.Visual.Online typeof(BeatmapNotAvailable), }; - private RulesetInfo osuRuleset; private RulesetInfo taikoRuleset; private RulesetInfo maniaRuleset; @@ -54,7 +53,6 @@ namespace osu.Game.Tests.Visual.Online [BackgroundDependencyLoader] private void load(RulesetStore rulesets) { - osuRuleset = rulesets.GetRuleset(0); taikoRuleset = rulesets.GetRuleset(1); maniaRuleset = rulesets.GetRuleset(3); } @@ -241,10 +239,14 @@ namespace osu.Game.Tests.Visual.Online }, }, false); }); - + downloadAssert(true); + } - AddStep(@"show second", () => + [Test] + public void TestUnavailable() + { + AddStep(@"show undownloadable", () => { overlay.ShowBeatmapSet(new BeatmapSetInfo { @@ -261,6 +263,11 @@ namespace osu.Game.Tests.Visual.Online }, OnlineInfo = new BeatmapSetOnlineInfo { + Availability = new BeatmapSetOnlineAvailability + { + DownloadDisabled = true, + ExternalLink = "https://osu.ppy.sh", + }, Preview = @"https://b.ppy.sh/preview/625493.mp3", PlayCount = 22996, FavouriteCount = 58, @@ -410,20 +417,7 @@ namespace osu.Game.Tests.Visual.Online }, }, false); }); - - downloadAssert(true); - } - - [Test] - public void TestUnavailable() - { - AddStep(@"show parts-removed (has link)", () => overlay.ShowBeatmapSet(getTestUnavailableBeatmapSet(false, true), false)); - downloadAssert(true); - - AddStep(@"show undownloadable (no link)", () => overlay.ShowBeatmapSet(getTestUnavailableBeatmapSet(true, false), false)); - downloadAssert(false); - - AddStep(@"show undownloadable (has link)", () => overlay.ShowBeatmapSet(getTestUnavailableBeatmapSet(true, true), false)); + downloadAssert(false); } @@ -443,42 +437,5 @@ namespace osu.Game.Tests.Visual.Online { AddAssert($"is download button {(shown ? "shown" : "hidden")}", () => overlay.Header.DownloadButtonsContainer.Any() == shown); } - - private BeatmapSetInfo getTestUnavailableBeatmapSet(bool undownloadable, bool hasLink) => new BeatmapSetInfo - { - Metadata = new BeatmapMetadata - { - Title = undownloadable ? "undownloadable" : "parts-removed", - Artist = "test beatmapset", - AuthorString = "test", - }, - OnlineInfo = new BeatmapSetOnlineInfo - { - Availability = new BeatmapSetOnlineAvailability - { - DownloadDisabled = undownloadable, - ExternalLink = hasLink ? "https://osu.ppy.sh" : null, - }, - Preview = @"https://b.ppy.sh/preview/1.mp3", - Covers = new BeatmapSetOnlineCovers(), - }, - Metrics = new BeatmapSetMetrics { Ratings = Enumerable.Range(0, 11).ToArray() }, - Beatmaps = new List - { - new BeatmapInfo - { - StarDifficulty = 1.23, - Version = "Test", - Ruleset = osuRuleset, - BaseDifficulty = new BeatmapDifficulty(), - OnlineInfo = new BeatmapOnlineInfo(), - Metrics = new BeatmapMetrics - { - Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6).ToArray(), - Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6).ToArray(), - }, - }, - }, - }; } } From 2e383a1f83597184358478fe5e6abfa23bef6faf Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Wed, 26 Jun 2019 05:17:28 +0300 Subject: [PATCH 092/148] Trim whitespaces --- osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs index db2db2c6c9..910fc17fc3 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs @@ -239,7 +239,7 @@ namespace osu.Game.Tests.Visual.Online }, }, false); }); - + downloadAssert(true); } @@ -417,7 +417,7 @@ namespace osu.Game.Tests.Visual.Online }, }, false); }); - + downloadAssert(false); } From eaf6f6891de34f20d677590457c3e8170509030e Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Wed, 26 Jun 2019 05:22:08 +0300 Subject: [PATCH 093/148] Rename to DownloadButtonsContainer --- osu.Game/Overlays/BeatmapSet/Header.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/Header.cs b/osu.Game/Overlays/BeatmapSet/Header.cs index c2355ad8e0..e17e952df4 100644 --- a/osu.Game/Overlays/BeatmapSet/Header.cs +++ b/osu.Game/Overlays/BeatmapSet/Header.cs @@ -158,7 +158,7 @@ namespace osu.Game.Overlays.BeatmapSet Children = new Drawable[] { favouriteButton = new FavouriteButton(), - downloadButtonsContainer = new FillFlowContainer + DownloadButtonsContainer = new FillFlowContainer { RelativeSizeAxes = Axes.Both, Padding = new MarginPadding { Left = buttons_height + buttons_spacing }, @@ -225,7 +225,7 @@ namespace osu.Game.Overlays.BeatmapSet loading.Show(); - downloadButtonsContainer.FadeOut(transition_duration); + DownloadButtonsContainer.FadeOut(transition_duration); favouriteButton.FadeOut(transition_duration); } else @@ -240,7 +240,7 @@ namespace osu.Game.Overlays.BeatmapSet onlineStatusPill.FadeIn(500, Easing.OutQuint); onlineStatusPill.Status = setInfo.NewValue.OnlineInfo.Status; - downloadButtonsContainer.FadeIn(transition_duration); + DownloadButtonsContainer.FadeIn(transition_duration); favouriteButton.FadeIn(transition_duration); updateDownloadButtons(); From 9e1cb90dd86c76aeaa2b3f7d8dae9ce8730bfae6 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 26 Jun 2019 11:40:33 +0900 Subject: [PATCH 094/148] Remove existing argument for ItemAdded event For all usages, it looks like this was unnecessary. --- .../Beatmaps/IO/ImportBeatmapTest.cs | 2 +- osu.Game/Database/ArchiveModelManager.cs | 6 +- osu.Game/Database/IModelManager.cs | 2 +- osu.Game/OsuGameBase.cs | 2 +- .../Direct/DownloadTrackingComposite.cs | 2 +- osu.Game/Overlays/Music/PlaylistList.cs | 7 +-- osu.Game/Overlays/MusicController.cs | 10 +--- .../Overlays/Settings/Sections/SkinSection.cs | 8 +-- .../Multi/Match/Components/ReadyButton.cs | 5 +- .../Screens/Multi/Match/MatchSubScreen.cs | 2 +- osu.Game/Screens/Select/BeatmapCarousel.cs | 59 +++++++++---------- osu.Game/Screens/Select/SongSelect.cs | 2 +- 12 files changed, 42 insertions(+), 65 deletions(-) diff --git a/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs b/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs index 5fc05a4b2f..ad0ed00989 100644 --- a/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs +++ b/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs @@ -108,7 +108,7 @@ namespace osu.Game.Tests.Beatmaps.IO var manager = osu.Dependencies.Get(); // ReSharper disable once AccessToModifiedClosure - manager.ItemAdded += (_, __) => Interlocked.Increment(ref itemAddRemoveFireCount); + manager.ItemAdded += _ => Interlocked.Increment(ref itemAddRemoveFireCount); manager.ItemRemoved += _ => Interlocked.Increment(ref itemAddRemoveFireCount); var imported = await LoadOszIntoOsu(osu); diff --git a/osu.Game/Database/ArchiveModelManager.cs b/osu.Game/Database/ArchiveModelManager.cs index a64bca57cb..01455e7d50 100644 --- a/osu.Game/Database/ArchiveModelManager.cs +++ b/osu.Game/Database/ArchiveModelManager.cs @@ -44,7 +44,7 @@ namespace osu.Game.Database /// Fired when a new becomes available in the database. /// This is not guaranteed to run on the update thread. /// - public event Action ItemAdded; + public event Action ItemAdded; /// /// Fired when a is removed from the database. @@ -70,7 +70,7 @@ namespace osu.Game.Database ContextFactory = contextFactory; ModelStore = modelStore; - ModelStore.ItemAdded += item => handleEvent(() => ItemAdded?.Invoke(item, false)); + ModelStore.ItemAdded += item => handleEvent(() => ItemAdded?.Invoke(item)); ModelStore.ItemRemoved += s => handleEvent(() => ItemRemoved?.Invoke(s)); Files = new FileStore(contextFactory, storage); @@ -299,8 +299,6 @@ namespace osu.Game.Database { Undelete(existing); LogForModel(item, $"Found existing {HumanisedModelName} for {item} (ID {existing.ID}) – skipping import."); - handleEvent(() => ItemAdded?.Invoke(existing, true)); - // existing item will be used; rollback new import and exit early. rollback(); flushEvents(true); diff --git a/osu.Game/Database/IModelManager.cs b/osu.Game/Database/IModelManager.cs index e41ef3efef..884814cb38 100644 --- a/osu.Game/Database/IModelManager.cs +++ b/osu.Game/Database/IModelManager.cs @@ -12,7 +12,7 @@ namespace osu.Game.Database public interface IModelManager where TModel : class { - event Action ItemAdded; + event Action ItemAdded; event Action ItemRemoved; } diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index 87ff721bbb..3bdf37d769 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -183,7 +183,7 @@ namespace osu.Game } BeatmapManager.ItemRemoved += i => ScoreManager.Delete(getBeatmapScores(i), true); - BeatmapManager.ItemAdded += (i, existing) => ScoreManager.Undelete(getBeatmapScores(i), true); + BeatmapManager.ItemAdded += i => ScoreManager.Undelete(getBeatmapScores(i), true); dependencies.Cache(KeyBindingStore = new KeyBindingStore(contextFactory, RulesetStore)); dependencies.Cache(SettingsStore = new SettingsStore(contextFactory)); diff --git a/osu.Game/Overlays/Direct/DownloadTrackingComposite.cs b/osu.Game/Overlays/Direct/DownloadTrackingComposite.cs index 494b18307e..3e68f58837 100644 --- a/osu.Game/Overlays/Direct/DownloadTrackingComposite.cs +++ b/osu.Game/Overlays/Direct/DownloadTrackingComposite.cs @@ -118,7 +118,7 @@ namespace osu.Game.Overlays.Direct private void onRequestFailure(Exception e) => Schedule(() => attachDownload(null)); - private void setAdded(BeatmapSetInfo s, bool existing) => setDownloadStateFromManager(s, DownloadState.LocallyAvailable); + private void setAdded(BeatmapSetInfo s) => setDownloadStateFromManager(s, DownloadState.LocallyAvailable); private void setRemoved(BeatmapSetInfo s) => setDownloadStateFromManager(s, DownloadState.NotDownloaded); diff --git a/osu.Game/Overlays/Music/PlaylistList.cs b/osu.Game/Overlays/Music/PlaylistList.cs index 89d166b788..07040f166d 100644 --- a/osu.Game/Overlays/Music/PlaylistList.cs +++ b/osu.Game/Overlays/Music/PlaylistList.cs @@ -75,7 +75,7 @@ namespace osu.Game.Overlays.Music [BackgroundDependencyLoader] private void load(BeatmapManager beatmaps, IBindable beatmap) { - beatmaps.GetAllUsableBeatmapSets().ForEach(b => addBeatmapSet(b, false)); + beatmaps.GetAllUsableBeatmapSets().ForEach(addBeatmapSet); beatmaps.ItemAdded += addBeatmapSet; beatmaps.ItemRemoved += removeBeatmapSet; @@ -83,11 +83,8 @@ namespace osu.Game.Overlays.Music beatmapBacking.ValueChanged += _ => updateSelectedSet(); } - private void addBeatmapSet(BeatmapSetInfo obj, bool existing) => Schedule(() => + private void addBeatmapSet(BeatmapSetInfo obj) => Schedule(() => { - if (existing) - return; - var newItem = new PlaylistItem(obj) { OnSelect = set => Selected?.Invoke(set) }; items.Add(newItem); diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index 36937def2b..a312ab711d 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -218,15 +218,9 @@ namespace osu.Game.Overlays beatmapSets.Insert(index, beatmapSetInfo); } - private void handleBeatmapAdded(BeatmapSetInfo obj, bool existing) - { - if (existing) - return; + private void handleBeatmapAdded(BeatmapSetInfo set) => Schedule(() => beatmapSets.Add(set)); - Schedule(() => beatmapSets.Add(obj)); - } - - private void handleBeatmapRemoved(BeatmapSetInfo obj) => Schedule(() => beatmapSets.RemoveAll(s => s.ID == obj.ID)); + private void handleBeatmapRemoved(BeatmapSetInfo set) => Schedule(() => beatmapSets.RemoveAll(s => s.ID == set.ID)); protected override void LoadComplete() { diff --git a/osu.Game/Overlays/Settings/Sections/SkinSection.cs b/osu.Game/Overlays/Settings/Sections/SkinSection.cs index 51c687314a..5d7542ca2b 100644 --- a/osu.Game/Overlays/Settings/Sections/SkinSection.cs +++ b/osu.Game/Overlays/Settings/Sections/SkinSection.cs @@ -82,13 +82,7 @@ namespace osu.Game.Overlays.Settings.Sections private void itemRemoved(SkinInfo s) => Schedule(() => skinDropdown.Items = skinDropdown.Items.Where(i => i.ID != s.ID).ToArray()); - private void itemAdded(SkinInfo s, bool existing) - { - if (existing) - return; - - Schedule(() => skinDropdown.Items = skinDropdown.Items.Append(s).ToArray()); - } + private void itemAdded(SkinInfo s) => Schedule(() => skinDropdown.Items = skinDropdown.Items.Append(s).ToArray()); protected override void Dispose(bool isDisposing) { diff --git a/osu.Game/Screens/Multi/Match/Components/ReadyButton.cs b/osu.Game/Screens/Multi/Match/Components/ReadyButton.cs index 86b4cfbfa7..8ab0b8f61f 100644 --- a/osu.Game/Screens/Multi/Match/Components/ReadyButton.cs +++ b/osu.Game/Screens/Multi/Match/Components/ReadyButton.cs @@ -54,11 +54,8 @@ namespace osu.Game.Screens.Multi.Match.Components hasBeatmap = beatmaps.QueryBeatmap(b => b.OnlineBeatmapID == beatmap.OnlineBeatmapID) != null; } - private void beatmapAdded(BeatmapSetInfo model, bool existing) + private void beatmapAdded(BeatmapSetInfo model) { - if (Beatmap.Value == null) - return; - if (model.Beatmaps.Any(b => b.OnlineBeatmapID == Beatmap.Value.OnlineBeatmapID)) Schedule(() => hasBeatmap = true); } diff --git a/osu.Game/Screens/Multi/Match/MatchSubScreen.cs b/osu.Game/Screens/Multi/Match/MatchSubScreen.cs index a80056d164..ced9fcfa59 100644 --- a/osu.Game/Screens/Multi/Match/MatchSubScreen.cs +++ b/osu.Game/Screens/Multi/Match/MatchSubScreen.cs @@ -202,7 +202,7 @@ namespace osu.Game.Screens.Multi.Match /// /// Handle the case where a beatmap is imported (and can be used by this match). /// - private void beatmapAdded(BeatmapSetInfo model, bool existing) => Schedule(() => + private void beatmapAdded(BeatmapSetInfo model) => Schedule(() => { if (Beatmap.Value != beatmapManager.DefaultBeatmap) return; diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index cf21c78c7f..a6fbb1ff94 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -148,40 +148,37 @@ namespace osu.Game.Screens.Select }); } - public void UpdateBeatmapSet(BeatmapSetInfo beatmapSet) + public void UpdateBeatmapSet(BeatmapSetInfo beatmapSet) => Schedule(() => { - Schedule(() => + int? previouslySelectedID = null; + CarouselBeatmapSet existingSet = beatmapSets.FirstOrDefault(b => b.BeatmapSet.ID == beatmapSet.ID); + + // If the selected beatmap is about to be removed, store its ID so it can be re-selected if required + if (existingSet?.State?.Value == CarouselItemState.Selected) + previouslySelectedID = selectedBeatmap?.Beatmap.ID; + + var newSet = createCarouselSet(beatmapSet); + + if (existingSet != null) + root.RemoveChild(existingSet); + + if (newSet == null) { - int? previouslySelectedID = null; - CarouselBeatmapSet existingSet = beatmapSets.FirstOrDefault(b => b.BeatmapSet.ID == beatmapSet.ID); - - // If the selected beatmap is about to be removed, store its ID so it can be re-selected if required - if (existingSet?.State?.Value == CarouselItemState.Selected) - previouslySelectedID = selectedBeatmap?.Beatmap.ID; - - var newSet = createCarouselSet(beatmapSet); - - if (existingSet != null) - root.RemoveChild(existingSet); - - if (newSet == null) - { - itemsCache.Invalidate(); - return; - } - - root.AddChild(newSet); - - applyActiveCriteria(false, false); - - //check if we can/need to maintain our current selection. - if (previouslySelectedID != null) - select((CarouselItem)newSet.Beatmaps.FirstOrDefault(b => b.Beatmap.ID == previouslySelectedID) ?? newSet); - itemsCache.Invalidate(); - Schedule(() => BeatmapSetsChanged?.Invoke()); - }); - } + return; + } + + root.AddChild(newSet); + + applyActiveCriteria(false, false); + + //check if we can/need to maintain our current selection. + if (previouslySelectedID != null) + select((CarouselItem)newSet.Beatmaps.FirstOrDefault(b => b.Beatmap.ID == previouslySelectedID) ?? newSet); + + itemsCache.Invalidate(); + Schedule(() => BeatmapSetsChanged?.Invoke()); + }); /// /// Selects a given beatmap on the carousel. diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index dfda252deb..7c62a49a97 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -578,7 +578,7 @@ namespace osu.Game.Screens.Select } } - private void onBeatmapSetAdded(BeatmapSetInfo s, bool existing) => Carousel.UpdateBeatmapSet(s); + private void onBeatmapSetAdded(BeatmapSetInfo s) => Carousel.UpdateBeatmapSet(s); private void onBeatmapSetRemoved(BeatmapSetInfo s) => Carousel.RemoveBeatmapSet(s); private void onBeatmapRestored(BeatmapInfo b) => Carousel.UpdateBeatmapSet(beatmaps.QueryBeatmapSet(s => s.ID == b.BeatmapSetInfoID)); private void onBeatmapHidden(BeatmapInfo b) => Carousel.UpdateBeatmapSet(beatmaps.QueryBeatmapSet(s => s.ID == b.BeatmapSetInfoID)); From 2707a7179e66ec67d2958772cfe99d4fdd4b6f2a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 26 Jun 2019 13:18:03 +0900 Subject: [PATCH 095/148] Fix MusiController holding references to beatmaps while inactive --- osu.Game/Overlays/MusicController.cs | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index 36937def2b..6a22ad11ff 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -259,6 +259,12 @@ namespace osu.Game.Overlays { base.Update(); + if (pendingBeatmapSwitch != null) + { + pendingBeatmapSwitch(); + pendingBeatmapSwitch = null; + } + var track = current?.TrackLoaded ?? false ? current.Track : null; if (track?.IsDummyDevice == false) @@ -368,15 +374,12 @@ namespace osu.Game.Overlays mod.ApplyToClock(track); } - private ScheduledDelegate pendingBeatmapSwitch; + private Action pendingBeatmapSwitch; private void updateDisplay(WorkingBeatmap beatmap, TransformDirection direction) { - //we might be off-screen when this update comes in. - //rather than Scheduling, manually handle this to avoid possible memory contention. - pendingBeatmapSwitch?.Cancel(); - - pendingBeatmapSwitch = Schedule(delegate + // avoid using scheduler as our scheduler may not be run for a long time, holding references to beatmaps. + pendingBeatmapSwitch = delegate { // todo: this can likely be replaced with WorkingBeatmap.GetBeatmapAsync() Task.Run(() => @@ -416,7 +419,7 @@ namespace osu.Game.Overlays playerContainer.Add(newBackground); }); - }); + }; } protected override void PopIn() From 7dd1479050e3ecd1b61b3476c5aae69a33b30b67 Mon Sep 17 00:00:00 2001 From: Welsar55 Date: Wed, 26 Jun 2019 00:20:33 -0500 Subject: [PATCH 096/148] Add combobreak sound --- osu.Game/Screens/Play/Player.cs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index c3e351a0ca..530145a604 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -66,6 +66,7 @@ namespace osu.Game.Screens.Play private IAPIProvider api; private SampleChannel sampleRestart; + private SampleChannel sampleComboBreak; protected ScoreProcessor ScoreProcessor { get; private set; } protected DrawableRuleset DrawableRuleset { get; private set; } @@ -80,6 +81,8 @@ namespace osu.Game.Screens.Play [Cached(Type = typeof(IBindable>))] protected new readonly Bindable> Mods = new Bindable>(Array.Empty()); + protected readonly BindableInt Combo = new BindableInt(); + private readonly bool allowPause; private readonly bool showResults; @@ -107,12 +110,15 @@ namespace osu.Game.Screens.Play return; sampleRestart = audio.Samples.Get(@"Gameplay/restart"); + sampleComboBreak = audio.Samples.Get(@"Gameplay/combobreak"); mouseWheelDisabled = config.GetBindable(OsuSetting.MouseDisableWheel); showStoryboard = config.GetBindable(OsuSetting.ShowStoryboard); ScoreProcessor = DrawableRuleset.CreateScoreProcessor(); ScoreProcessor.Mods.BindTo(Mods); + ScoreProcessor.Combo.BindTo(Combo); + Combo.BindValueChanged(onComboChange); if (!ScoreProcessor.Mode.Disabled) config.BindWith(OsuSetting.ScoreDisplayMode, ScoreProcessor.Mode); @@ -264,6 +270,12 @@ namespace osu.Game.Screens.Play private ScheduledDelegate onCompletionEvent; + private void onComboChange(ValueChangedEvent combo) + { + if (combo.NewValue == 0 && combo.OldValue > 20) + sampleComboBreak?.Play(); + } + private void onCompletion() { // Only show the completion screen if the player hasn't failed From 15b140b2eed1ac695abbd93f552958cf6577dfb4 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 26 Jun 2019 17:10:22 +0900 Subject: [PATCH 097/148] Shortcut checking for whether directories are files --- osu.Game/Utils/ZipUtils.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/osu.Game/Utils/ZipUtils.cs b/osu.Game/Utils/ZipUtils.cs index 98e24590a8..cd4d876451 100644 --- a/osu.Game/Utils/ZipUtils.cs +++ b/osu.Game/Utils/ZipUtils.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System; +using System.IO; using SharpCompress.Archives.Zip; namespace osu.Game.Utils @@ -10,6 +11,9 @@ namespace osu.Game.Utils { public static bool IsZipArchive(string path) { + if (!File.Exists(path)) + return false; + try { using (var arc = ZipArchive.Open(path)) From cb65fc63170f8c6727da3e96143bcda86a48315a Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 26 Jun 2019 17:23:12 +0900 Subject: [PATCH 098/148] Don't throw exception for non-existent files --- 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 4b1bddbf0d..5657b8fb8a 100644 --- a/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs @@ -41,7 +41,7 @@ namespace osu.Game.Beatmaps } } - private string getPathForFile(string filename) => BeatmapSetInfo.Files.First(f => string.Equals(f.Filename, filename, StringComparison.InvariantCultureIgnoreCase)).FileInfo.StoragePath; + private string getPathForFile(string filename) => BeatmapSetInfo.Files.FirstOrDefault(f => string.Equals(f.Filename, filename, StringComparison.InvariantCultureIgnoreCase))?.FileInfo.StoragePath; private TextureStore textureStore; From 6ce86e608317f33d1d1f641e47014e45e4972161 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 26 Jun 2019 17:52:25 +0900 Subject: [PATCH 099/148] General refactoring --- osu.Game/Overlays/Toolbar/Toolbar.cs | 3 +- .../Toolbar/ToolbarRulesetSelector.cs | 69 ++++++++++--------- osu.Game/Rulesets/RulesetSelector.cs | 11 ++- 3 files changed, 41 insertions(+), 42 deletions(-) diff --git a/osu.Game/Overlays/Toolbar/Toolbar.cs b/osu.Game/Overlays/Toolbar/Toolbar.cs index 19e3e1c833..19038c3981 100644 --- a/osu.Game/Overlays/Toolbar/Toolbar.cs +++ b/osu.Game/Overlays/Toolbar/Toolbar.cs @@ -86,7 +86,8 @@ namespace osu.Game.Overlays.Toolbar } }; - rulesetSelector.Current.BindTarget = parentRuleset; + // Bound after the selector is added to the hierarchy to give it a chance to load the available rulesets + rulesetSelector.Current.BindTo(parentRuleset); State.ValueChanged += visibility => { diff --git a/osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.cs b/osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.cs index 2e4a6fe8fc..95d7d3f73a 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.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.Caching; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Effects; @@ -13,28 +12,25 @@ using osu.Framework.Graphics.UserInterface; using osu.Framework.Input.Events; using osuTK.Input; using System.Linq; +using osu.Framework.Allocation; namespace osu.Game.Overlays.Toolbar { public class ToolbarRulesetSelector : RulesetSelector { private const float padding = 10; - private readonly Drawable modeButtonLine; - public override bool HandleNonPositionalInput => !Current.Disabled && base.HandleNonPositionalInput; - public override bool HandlePositionalInput => !Current.Disabled && base.HandlePositionalInput; - - public override bool PropagatePositionalInputSubTree => !Current.Disabled && base.PropagatePositionalInputSubTree; - - private void disabledChanged(bool isDisabled) => this.FadeColour(isDisabled ? Color4.Gray : Color4.White, 300); - - protected override TabItem CreateTabItem(RulesetInfo value) => new ToolbarRulesetTabButton(value); + private Drawable modeButtonLine; public ToolbarRulesetSelector() { RelativeSizeAxes = Axes.Y; AutoSizeAxes = Axes.X; + } + [BackgroundDependencyLoader] + private void load() + { AddRangeInternal(new[] { new OpaqueBackground @@ -60,11 +56,36 @@ namespace osu.Game.Overlays.Toolbar } } }); - - Current.DisabledChanged += disabledChanged; - Current.ValueChanged += value => activeMode.Invalidate(); } + protected override void LoadComplete() + { + base.LoadComplete(); + + Current.BindDisabledChanged(disabled => this.FadeColour(disabled ? Color4.Gray : Color4.White, 300), true); + Current.BindValueChanged(_ => moveLineToCurrent(), true); + } + + private void moveLineToCurrent() + { + foreach (TabItem tabItem in TabContainer) + { + if (tabItem.Value == Current.Value) + { + modeButtonLine.MoveToX(tabItem.DrawPosition.X, 200, Easing.OutQuint); + break; + } + } + } + + public override bool HandleNonPositionalInput => !Current.Disabled && base.HandleNonPositionalInput; + + public override bool HandlePositionalInput => !Current.Disabled && base.HandlePositionalInput; + + public override bool PropagatePositionalInputSubTree => !Current.Disabled && base.PropagatePositionalInputSubTree; + + protected override TabItem CreateTabItem(RulesetInfo value) => new ToolbarRulesetTabButton(value); + protected override TabFillFlowContainer CreateTabFlow() => new TabFillFlowContainer { RelativeSizeAxes = Axes.Y, @@ -81,7 +102,7 @@ namespace osu.Game.Overlays.Toolbar { int requested = e.Key - Key.Number1; - RulesetInfo found = AvaliableRulesets.AvailableRulesets.Skip(requested).FirstOrDefault(); + RulesetInfo found = Rulesets.AvailableRulesets.Skip(requested).FirstOrDefault(); if (found != null) Current.Value = found; return true; @@ -89,25 +110,5 @@ namespace osu.Game.Overlays.Toolbar return false; } - - private readonly Cached activeMode = new Cached(); - - protected override void UpdateAfterChildren() - { - base.UpdateAfterChildren(); - - if (!activeMode.IsValid) - { - foreach (TabItem tabItem in TabContainer) - { - if (tabItem.Value == Current.Value) - { - modeButtonLine.MoveToX(tabItem.DrawPosition.X, 200, Easing.OutQuint); - activeMode.Validate(); - return; - } - } - } - } } } diff --git a/osu.Game/Rulesets/RulesetSelector.cs b/osu.Game/Rulesets/RulesetSelector.cs index d7ffb866ab..8e6ec556d2 100644 --- a/osu.Game/Rulesets/RulesetSelector.cs +++ b/osu.Game/Rulesets/RulesetSelector.cs @@ -8,19 +8,16 @@ namespace osu.Game.Rulesets { public abstract class RulesetSelector : TabControl { - protected RulesetStore AvaliableRulesets; + [Resolved] + protected RulesetStore Rulesets { get; private set; } protected override Dropdown CreateDropdown() => null; [BackgroundDependencyLoader] - private void load(RulesetStore rulesets) + private void load() { - AvaliableRulesets = rulesets; - - foreach (var r in rulesets.AvailableRulesets) - { + foreach (var r in Rulesets.AvailableRulesets) AddItem(r); - } } } } From da65658bc3009405a33a39aea367de970903eb1a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 26 Jun 2019 20:07:01 +0900 Subject: [PATCH 100/148] Fix comments --- osu.Game/Database/DownloadableArchiveModelManager.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Database/DownloadableArchiveModelManager.cs b/osu.Game/Database/DownloadableArchiveModelManager.cs index e0ac221cfc..647eb3cbd3 100644 --- a/osu.Game/Database/DownloadableArchiveModelManager.cs +++ b/osu.Game/Database/DownloadableArchiveModelManager.cs @@ -44,7 +44,7 @@ namespace osu.Game.Database /// Creates the download request for this . /// /// The to be downloaded. - /// Whether this download should be optimised for slow connections. Generally means extras are not included in the download bundle.. + /// Whether this download should be optimised for slow connections. Generally means extras are not included in the download bundle. /// The request object. protected abstract ArchiveDownloadRequest CreateDownloadRequest(TModel model, bool minimiseDownloadSize); @@ -52,7 +52,7 @@ namespace osu.Game.Database /// Begin a download for the requested . /// /// The to be downloaded. - /// Whether this download should be optimised for slow connections. Generally means extras are not included in the download bundle.. + /// Whether this download should be optimised for slow connections. Generally means extras are not included in the download bundle. /// Whether the download was started. public bool Download(TModel model, bool minimiseDownloadSize = false) { From 8efc504817e099a106e6d19312a479f01ea0cbb2 Mon Sep 17 00:00:00 2001 From: naoey Date: Wed, 26 Jun 2019 18:22:37 +0530 Subject: [PATCH 101/148] Post merge fixes --- osu.Game/Online/DownloadTrackingComposite.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game/Online/DownloadTrackingComposite.cs b/osu.Game/Online/DownloadTrackingComposite.cs index d07aed9206..18197a0b2c 100644 --- a/osu.Game/Online/DownloadTrackingComposite.cs +++ b/osu.Game/Online/DownloadTrackingComposite.cs @@ -50,7 +50,7 @@ namespace osu.Game.Online manager.DownloadBegan += download => { - if (download.Info.Equals(ModelInfo.Value)) + if (download.Model.Equals(ModelInfo.Value)) attachDownload(download); }; @@ -77,9 +77,9 @@ namespace osu.Game.Online #endregion - private ArchiveDownloadModelRequest attachedRequest; + private ArchiveDownloadRequest attachedRequest; - private void attachDownload(ArchiveDownloadModelRequest request) + private void attachDownload(ArchiveDownloadRequest request) { if (attachedRequest != null) { @@ -119,7 +119,7 @@ namespace osu.Game.Online private void onRequestFailure(Exception e) => Schedule(() => attachDownload(null)); - private void itemAdded(TModel s, bool existing) => setDownloadStateFromManager(s, DownloadState.LocallyAvailable); + private void itemAdded(TModel s) => setDownloadStateFromManager(s, DownloadState.LocallyAvailable); private void itemRemoved(TModel s) => setDownloadStateFromManager(s, DownloadState.NotDownloaded); From 768d6c2fb38b6aaabe95fe78d28d490997126a1f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 27 Jun 2019 00:29:09 +0900 Subject: [PATCH 102/148] ModelInfo -> Model --- osu.Game/Online/DownloadTrackingComposite.cs | 10 +++++----- .../Direct/BeatmapDownloadTrackingComposite.cs | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/osu.Game/Online/DownloadTrackingComposite.cs b/osu.Game/Online/DownloadTrackingComposite.cs index 18197a0b2c..7003506a13 100644 --- a/osu.Game/Online/DownloadTrackingComposite.cs +++ b/osu.Game/Online/DownloadTrackingComposite.cs @@ -17,7 +17,7 @@ namespace osu.Game.Online where TModel : class, IEquatable where TModelManager : class, IModelDownloader { - protected readonly Bindable ModelInfo = new Bindable(); + protected readonly Bindable Model = new Bindable(); private TModelManager manager; @@ -30,7 +30,7 @@ namespace osu.Game.Online protected DownloadTrackingComposite(TModel model = null) { - ModelInfo.Value = model; + Model.Value = model; } [BackgroundDependencyLoader(true)] @@ -38,7 +38,7 @@ namespace osu.Game.Online { this.manager = manager; - ModelInfo.BindValueChanged(modelInfo => + Model.BindValueChanged(modelInfo => { if (modelInfo.NewValue == null) attachDownload(null); @@ -50,7 +50,7 @@ namespace osu.Game.Online manager.DownloadBegan += download => { - if (download.Model.Equals(ModelInfo.Value)) + if (download.Model.Equals(Model.Value)) attachDownload(download); }; @@ -125,7 +125,7 @@ namespace osu.Game.Online private void setDownloadStateFromManager(TModel s, DownloadState state) => Schedule(() => { - if (!s.Equals(ModelInfo.Value)) + if (!s.Equals(Model.Value)) return; State.Value = state; diff --git a/osu.Game/Overlays/Direct/BeatmapDownloadTrackingComposite.cs b/osu.Game/Overlays/Direct/BeatmapDownloadTrackingComposite.cs index 6f348c4fd7..fd04a1541e 100644 --- a/osu.Game/Overlays/Direct/BeatmapDownloadTrackingComposite.cs +++ b/osu.Game/Overlays/Direct/BeatmapDownloadTrackingComposite.cs @@ -9,7 +9,7 @@ namespace osu.Game.Overlays.Direct { public abstract class BeatmapDownloadTrackingComposite : DownloadTrackingComposite { - public Bindable BeatmapSet => ModelInfo; + public Bindable BeatmapSet => Model; protected BeatmapDownloadTrackingComposite(BeatmapSetInfo set = null) : base(set) From 9edd98efdc9b6882368fedea9b27e17ecc338780 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 27 Jun 2019 00:29:38 +0900 Subject: [PATCH 103/148] Move disposal to end of class --- osu.Game/Online/DownloadTrackingComposite.cs | 38 ++++++++++---------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/osu.Game/Online/DownloadTrackingComposite.cs b/osu.Game/Online/DownloadTrackingComposite.cs index 7003506a13..5eb2bb74bb 100644 --- a/osu.Game/Online/DownloadTrackingComposite.cs +++ b/osu.Game/Online/DownloadTrackingComposite.cs @@ -58,25 +58,6 @@ namespace osu.Game.Online manager.ItemRemoved += itemRemoved; } - #region Disposal - - protected override void Dispose(bool isDisposing) - { - base.Dispose(isDisposing); - - if (manager != null) - { - manager.DownloadBegan -= attachDownload; - manager.ItemAdded -= itemAdded; - } - - State.UnbindAll(); - - attachDownload(null); - } - - #endregion - private ArchiveDownloadRequest attachedRequest; private void attachDownload(ArchiveDownloadRequest request) @@ -130,5 +111,24 @@ namespace osu.Game.Online State.Value = state; }); + + #region Disposal + + protected override void Dispose(bool isDisposing) + { + base.Dispose(isDisposing); + + if (manager != null) + { + manager.DownloadBegan -= attachDownload; + manager.ItemAdded -= itemAdded; + } + + State.UnbindAll(); + + attachDownload(null); + } + + #endregion } } From 2e49b4ffcd8b6b03d2d8cc1e5db898f1db7081c2 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 26 Jun 2019 18:56:40 +0300 Subject: [PATCH 104/148] Update the component with an abstract RulesetSelector class --- .../Components/ProfileRulesetSelector.cs | 11 +---- .../Header/Components/RulesetTabItem.cs | 46 ++++++++++++------- 2 files changed, 31 insertions(+), 26 deletions(-) diff --git a/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetSelector.cs b/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetSelector.cs index b189878b0d..95065f2c72 100644 --- a/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetSelector.cs +++ b/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetSelector.cs @@ -12,10 +12,8 @@ using osuTK.Graphics; namespace osu.Game.Overlays.Profile.Header.Components { - public class ProfileRulesetSelector : TabControl + public class ProfileRulesetSelector : RulesetSelector { - protected override Dropdown CreateDropdown() => null; - protected override TabItem CreateTabItem(RulesetInfo value) => new RulesetTabItem(value) { AccentColour = AccentColour @@ -48,13 +46,8 @@ namespace osu.Game.Overlays.Profile.Header.Components } [BackgroundDependencyLoader] - private void load(RulesetStore rulesets, OsuColour colours) + private void load(OsuColour colours) { - foreach (var r in rulesets.AvailableRulesets) - { - AddItem(r); - } - AccentColour = colours.Seafoam; } diff --git a/osu.Game/Overlays/Profile/Header/Components/RulesetTabItem.cs b/osu.Game/Overlays/Profile/Header/Components/RulesetTabItem.cs index 0a6f2f5123..0c49b3179c 100644 --- a/osu.Game/Overlays/Profile/Header/Components/RulesetTabItem.cs +++ b/osu.Game/Overlays/Profile/Header/Components/RulesetTabItem.cs @@ -94,7 +94,8 @@ namespace osu.Game.Overlays.Profile.Header.Components { base.OnHover(e); - updateState(); + if (!Active.Value) + hoverAction(); return true; } @@ -103,29 +104,40 @@ namespace osu.Game.Overlays.Profile.Header.Components { base.OnHoverLost(e); - updateState(); + if (!Active.Value) + unhoverAction(); } - protected override void OnActivated() => updateState(); + protected override void OnActivated() + { + hoverAction(); + text.Font = text.Font.With(weight: FontWeight.Bold); + } - protected override void OnDeactivated() => updateState(); + protected override void OnDeactivated() + { + unhoverAction(); + text.Font = text.Font.With(weight: FontWeight.Medium); + } private void updateState() { - if (Active.Value || IsHovered) - { - text.FadeColour(Color4.White, 120, Easing.InQuad); - icon.FadeColour(Color4.White, 120, Easing.InQuad); - - if (Active.Value) - text.Font = text.Font.With(weight: FontWeight.Bold); - } + if (Active.Value) + OnActivated(); else - { - text.FadeColour(AccentColour, 120, Easing.InQuad); - icon.FadeColour(AccentColour, 120, Easing.InQuad); - text.Font = text.Font.With(weight: FontWeight.Medium); - } + OnDeactivated(); + } + + private void hoverAction() + { + text.FadeColour(Color4.White, 120, Easing.InQuad); + icon.FadeColour(Color4.White, 120, Easing.InQuad); + } + + private void unhoverAction() + { + text.FadeColour(AccentColour, 120, Easing.InQuad); + icon.FadeColour(AccentColour, 120, Easing.InQuad); } } } From 826699a7e75d33527da0b723878a47fcabd26e7d Mon Sep 17 00:00:00 2001 From: Welsar55 Date: Wed, 26 Jun 2019 12:16:44 -0500 Subject: [PATCH 105/148] Remove unneeded bindable --- osu.Game/Screens/Play/Player.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 530145a604..f620c790aa 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -81,8 +81,6 @@ namespace osu.Game.Screens.Play [Cached(Type = typeof(IBindable>))] protected new readonly Bindable> Mods = new Bindable>(Array.Empty()); - protected readonly BindableInt Combo = new BindableInt(); - private readonly bool allowPause; private readonly bool showResults; @@ -117,8 +115,7 @@ namespace osu.Game.Screens.Play ScoreProcessor = DrawableRuleset.CreateScoreProcessor(); ScoreProcessor.Mods.BindTo(Mods); - ScoreProcessor.Combo.BindTo(Combo); - Combo.BindValueChanged(onComboChange); + ScoreProcessor.Combo.BindValueChanged(onComboChange); if (!ScoreProcessor.Mode.Disabled) config.BindWith(OsuSetting.ScoreDisplayMode, ScoreProcessor.Mode); From 9ada4d68b170a75a56e42b63105a76221ade854d Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Wed, 26 Jun 2019 22:42:34 +0300 Subject: [PATCH 106/148] Make fields protected and expose them in tests --- .../Online/TestSceneBeatmapSetOverlay.cs | 11 +++++-- .../Visual/Online/TestSceneDirectPanel.cs | 31 ++++++++++++++++--- osu.Game/Overlays/BeatmapSet/Header.cs | 3 +- osu.Game/Overlays/BeatmapSetOverlay.cs | 2 +- osu.Game/Overlays/Direct/DirectGridPanel.cs | 2 +- osu.Game/Overlays/Direct/DirectListPanel.cs | 2 +- osu.Game/Overlays/Direct/DirectPanel.cs | 3 +- 7 files changed, 41 insertions(+), 13 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs index 910fc17fc3..e12299f291 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs @@ -19,7 +19,7 @@ namespace osu.Game.Tests.Visual.Online [TestFixture] public class TestSceneBeatmapSetOverlay : OsuTestScene { - private readonly BeatmapSetOverlay overlay; + private readonly TestBeatmapSetOverlay overlay; public override IReadOnlyList RequiredTypes => new[] { @@ -47,7 +47,7 @@ namespace osu.Game.Tests.Visual.Online public TestSceneBeatmapSetOverlay() { - Add(overlay = new BeatmapSetOverlay()); + Add(overlay = new TestBeatmapSetOverlay()); } [BackgroundDependencyLoader] @@ -435,7 +435,12 @@ namespace osu.Game.Tests.Visual.Online private void downloadAssert(bool shown) { - AddAssert($"is download button {(shown ? "shown" : "hidden")}", () => overlay.Header.DownloadButtonsContainer.Any() == shown); + AddAssert($"is download button {(shown ? "shown" : "hidden")}", () => overlay.IsDownloadButtonsShown == shown); + } + + private class TestBeatmapSetOverlay : BeatmapSetOverlay + { + public bool IsDownloadButtonsShown => Header.DownloadButtonsContainer.Any(); } } } diff --git a/osu.Game.Tests/Visual/Online/TestSceneDirectPanel.cs b/osu.Game.Tests/Visual/Online/TestSceneDirectPanel.cs index 9667e5a752..7a305f0328 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneDirectPanel.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneDirectPanel.cs @@ -52,7 +52,8 @@ namespace osu.Game.Tests.Visual.Online normal.OnlineInfo.HasStoryboard = true; var undownloadable = getUndownloadableBeatmapSet(ruleset); - DirectPanel undownloadableGridPanel, undownloadableListPanel; + TestDirectGridPanel undownloadableGridPanel; + TestDirectListPanel undownloadableListPanel; Child = new BasicScrollContainer { @@ -68,14 +69,34 @@ namespace osu.Game.Tests.Visual.Online { new DirectGridPanel(normal), new DirectListPanel(normal), - undownloadableGridPanel = new DirectGridPanel(undownloadable), - undownloadableListPanel = new DirectListPanel(undownloadable), + undownloadableGridPanel = new TestDirectGridPanel(undownloadable), + undownloadableListPanel = new TestDirectListPanel(undownloadable), }, }, }; - AddAssert("is download button disabled on second grid panel", () => !undownloadableGridPanel.DownloadButton.Enabled.Value); - AddAssert("is download button disabled on second list panel", () => !undownloadableListPanel.DownloadButton.Enabled.Value); + AddAssert("is download button disabled on second grid panel", () => !undownloadableGridPanel.IsDownloadButtonEnabled); + AddAssert("is download button disabled on second list panel", () => !undownloadableListPanel.IsDownloadButtonEnabled); + } + + private class TestDirectGridPanel : DirectGridPanel + { + public bool IsDownloadButtonEnabled => DownloadButton.Enabled.Value; + + public TestDirectGridPanel(BeatmapSetInfo beatmap) + : base(beatmap) + { + } + } + + private class TestDirectListPanel : DirectListPanel + { + public bool IsDownloadButtonEnabled => DownloadButton.Enabled.Value; + + public TestDirectListPanel(BeatmapSetInfo beatmap) + : base(beatmap) + { + } } } } diff --git a/osu.Game/Overlays/BeatmapSet/Header.cs b/osu.Game/Overlays/BeatmapSet/Header.cs index e17e952df4..b156fe9028 100644 --- a/osu.Game/Overlays/BeatmapSet/Header.cs +++ b/osu.Game/Overlays/BeatmapSet/Header.cs @@ -34,7 +34,8 @@ namespace osu.Game.Overlays.BeatmapSet private readonly BeatmapNotAvailable beatmapNotAvailable; private readonly BeatmapSetOnlineStatusPill onlineStatusPill; public Details Details; - public FillFlowContainer DownloadButtonsContainer; + + public readonly FillFlowContainer DownloadButtonsContainer; public readonly BeatmapPicker Picker; diff --git a/osu.Game/Overlays/BeatmapSetOverlay.cs b/osu.Game/Overlays/BeatmapSetOverlay.cs index e9ea8f7a55..821840ef95 100644 --- a/osu.Game/Overlays/BeatmapSetOverlay.cs +++ b/osu.Game/Overlays/BeatmapSetOverlay.cs @@ -27,7 +27,7 @@ namespace osu.Game.Overlays public const float TOP_PADDING = 25; public const float RIGHT_WIDTH = 275; - public readonly Header Header; + protected readonly Header Header; private RulesetStore rulesets; diff --git a/osu.Game/Overlays/Direct/DirectGridPanel.cs b/osu.Game/Overlays/Direct/DirectGridPanel.cs index 9e7aa5372b..5ee00d94d4 100644 --- a/osu.Game/Overlays/Direct/DirectGridPanel.cs +++ b/osu.Game/Overlays/Direct/DirectGridPanel.cs @@ -29,7 +29,7 @@ namespace osu.Game.Overlays.Direct private PlayButton playButton; private Box progressBar; - public override DownloadButton DownloadButton => downloadButton; + protected override DownloadButton DownloadButton => downloadButton; protected override PlayButton PlayButton => playButton; protected override Box PreviewBar => progressBar; diff --git a/osu.Game/Overlays/Direct/DirectListPanel.cs b/osu.Game/Overlays/Direct/DirectListPanel.cs index 076fed19bd..c701002d2e 100644 --- a/osu.Game/Overlays/Direct/DirectListPanel.cs +++ b/osu.Game/Overlays/Direct/DirectListPanel.cs @@ -33,7 +33,7 @@ namespace osu.Game.Overlays.Direct protected override bool FadePlayButton => false; - public override DownloadButton DownloadButton => downloadButton; + protected override DownloadButton DownloadButton => downloadButton; protected override PlayButton PlayButton => playButton; protected override Box PreviewBar => progressBar; diff --git a/osu.Game/Overlays/Direct/DirectPanel.cs b/osu.Game/Overlays/Direct/DirectPanel.cs index c9fe4aaa05..c918a84ab0 100644 --- a/osu.Game/Overlays/Direct/DirectPanel.cs +++ b/osu.Game/Overlays/Direct/DirectPanel.cs @@ -34,7 +34,8 @@ namespace osu.Game.Overlays.Direct public PreviewTrack Preview => PlayButton.Preview; public Bindable PreviewPlaying => PlayButton.Playing; - public abstract DownloadButton DownloadButton { get; } + + protected abstract DownloadButton DownloadButton { get; } protected abstract PlayButton PlayButton { get; } protected abstract Box PreviewBar { get; } From 322d92d3e003a67418e281885396fcd21c4204e9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 27 Jun 2019 11:40:22 +0900 Subject: [PATCH 107/148] Rename class to BeatmapAvailability --- ...mapNotAvailable.cs => TestSceneBeatmapAvailability.cs} | 8 ++++---- .../Visual/Online/TestSceneBeatmapSetOverlay.cs | 4 ++-- osu.Game/Online/Chat/ChannelManager.cs | 1 + .../{BeatmapNotAvailable.cs => BeatmapAvailability.cs} | 4 ++-- osu.Game/Overlays/BeatmapSet/Header.cs | 6 +++--- 5 files changed, 12 insertions(+), 11 deletions(-) rename osu.Game.Tests/Visual/Online/{TestSceneBeatmapNotAvailable.cs => TestSceneBeatmapAvailability.cs} (92%) rename osu.Game/Overlays/BeatmapSet/{BeatmapNotAvailable.cs => BeatmapAvailability.cs} (97%) diff --git a/osu.Game.Tests/Visual/Online/TestSceneBeatmapNotAvailable.cs b/osu.Game.Tests/Visual/Online/TestSceneBeatmapAvailability.cs similarity index 92% rename from osu.Game.Tests/Visual/Online/TestSceneBeatmapNotAvailable.cs rename to osu.Game.Tests/Visual/Online/TestSceneBeatmapAvailability.cs index 00ab89389e..fe94165777 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneBeatmapNotAvailable.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneBeatmapAvailability.cs @@ -8,13 +8,13 @@ using osu.Game.Overlays.BeatmapSet; namespace osu.Game.Tests.Visual.Online { [TestFixture] - public class TestSceneBeatmapNotAvailable : OsuTestScene + public class TestSceneBeatmapAvailability : OsuTestScene { - private readonly BeatmapNotAvailable container; + private readonly BeatmapAvailability container; - public TestSceneBeatmapNotAvailable() + public TestSceneBeatmapAvailability() { - Add(container = new BeatmapNotAvailable()); + Add(container = new BeatmapAvailability()); } [Test] diff --git a/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs index e12299f291..c069197f94 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs @@ -1,4 +1,4 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// 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; @@ -39,7 +39,7 @@ namespace osu.Game.Tests.Visual.Online typeof(Info), typeof(PreviewButton), typeof(SuccessRate), - typeof(BeatmapNotAvailable), + typeof(BeatmapAvailability), }; private RulesetInfo taikoRuleset; diff --git a/osu.Game/Online/Chat/ChannelManager.cs b/osu.Game/Online/Chat/ChannelManager.cs index 3af11ff20f..f722eb9e41 100644 --- a/osu.Game/Online/Chat/ChannelManager.cs +++ b/osu.Game/Online/Chat/ChannelManager.cs @@ -18,6 +18,7 @@ namespace osu.Game.Online.Chat /// /// Manages everything channel related /// + [Cached] public class ChannelManager : PollingComponent { /// diff --git a/osu.Game/Overlays/BeatmapSet/BeatmapNotAvailable.cs b/osu.Game/Overlays/BeatmapSet/BeatmapAvailability.cs similarity index 97% rename from osu.Game/Overlays/BeatmapSet/BeatmapNotAvailable.cs rename to osu.Game/Overlays/BeatmapSet/BeatmapAvailability.cs index 44e29a5011..30c89e23d0 100644 --- a/osu.Game/Overlays/BeatmapSet/BeatmapNotAvailable.cs +++ b/osu.Game/Overlays/BeatmapSet/BeatmapAvailability.cs @@ -12,7 +12,7 @@ using osuTK.Graphics; namespace osu.Game.Overlays.BeatmapSet { - public class BeatmapNotAvailable : Container + public class BeatmapAvailability : Container { private BeatmapSetInfo beatmapSet; @@ -43,7 +43,7 @@ namespace osu.Game.Overlays.BeatmapSet private readonly TextFlowContainer textContainer; private readonly LinkFlowContainer linkContainer; - public BeatmapNotAvailable() + public BeatmapAvailability() { RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; diff --git a/osu.Game/Overlays/BeatmapSet/Header.cs b/osu.Game/Overlays/BeatmapSet/Header.cs index b156fe9028..e02bf2be64 100644 --- a/osu.Game/Overlays/BeatmapSet/Header.cs +++ b/osu.Game/Overlays/BeatmapSet/Header.cs @@ -31,7 +31,7 @@ namespace osu.Game.Overlays.BeatmapSet private readonly UpdateableBeatmapSetCover cover; private readonly OsuSpriteText title, artist; private readonly AuthorInfo author; - private readonly BeatmapNotAvailable beatmapNotAvailable; + private readonly BeatmapAvailability beatmapAvailability; private readonly BeatmapSetOnlineStatusPill onlineStatusPill; public Details Details; @@ -150,7 +150,7 @@ namespace osu.Game.Overlays.BeatmapSet Margin = new MarginPadding { Top = 20 }, Child = author = new AuthorInfo(), }, - beatmapNotAvailable = new BeatmapNotAvailable(), + beatmapAvailability = new BeatmapAvailability(), new Container { RelativeSizeAxes = Axes.X, @@ -216,7 +216,7 @@ namespace osu.Game.Overlays.BeatmapSet BeatmapSet.BindValueChanged(setInfo => { - Picker.BeatmapSet = author.BeatmapSet = beatmapNotAvailable.BeatmapSet = Details.BeatmapSet = setInfo.NewValue; + Picker.BeatmapSet = author.BeatmapSet = beatmapAvailability.BeatmapSet = Details.BeatmapSet = setInfo.NewValue; cover.BeatmapSet = setInfo.NewValue; if (setInfo.NewValue == null) From d6da21b0f0c75f6755a648aa88d97a1255f357ac Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 27 Jun 2019 12:00:31 +0900 Subject: [PATCH 108/148] Tidy up fetch methods Anonymise some test data further --- .../Online/TestSceneBeatmapSetOverlay.cs | 20 ++++++++-------- osu.Game/Overlays/BeatmapSetOverlay.cs | 23 ++++++++----------- osu.Game/Overlays/Direct/DirectPanel.cs | 8 ++++--- 3 files changed, 26 insertions(+), 25 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs index c069197f94..fad5c56d43 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs @@ -76,21 +76,22 @@ namespace osu.Game.Tests.Visual.Online { overlay.ShowBeatmapSet(new BeatmapSetInfo { + OnlineBeatmapSetID = 1235, Metadata = new BeatmapMetadata { - Title = @"Lachryma ", - Artist = @"Kaneko Chiharu", - Source = @"SOUND VOLTEX III GRAVITY WARS", - Tags = @"sdvx grace the 5th kac original song contest konami bemani", + Title = @"an awesome beatmap", + Artist = @"naru narusegawa", + Source = @"hinata sou", + Tags = @"test tag tag more tag", Author = new User { - Username = @"Fresh Chicken", - Id = 3984370, + Username = @"BanchoBot", + Id = 3, }, }, OnlineInfo = new BeatmapSetOnlineInfo { - Preview = @"https://b.ppy.sh/preview/415886.mp3", + Preview = @"https://b.ppy.sh/preview/12345.mp3", PlayCount = 681380, FavouriteCount = 356, Submitted = new DateTime(2016, 2, 10), @@ -237,7 +238,7 @@ namespace osu.Game.Tests.Visual.Online }, }, }, - }, false); + }); }); downloadAssert(true); @@ -250,6 +251,7 @@ namespace osu.Game.Tests.Visual.Online { overlay.ShowBeatmapSet(new BeatmapSetInfo { + OnlineBeatmapSetID = 1234, Metadata = new BeatmapMetadata { Title = @"Soumatou Labyrinth", @@ -415,7 +417,7 @@ namespace osu.Game.Tests.Visual.Online }, }, }, - }, false); + }); }); downloadAssert(false); diff --git a/osu.Game/Overlays/BeatmapSetOverlay.cs b/osu.Game/Overlays/BeatmapSetOverlay.cs index 821840ef95..19f6a3f692 100644 --- a/osu.Game/Overlays/BeatmapSetOverlay.cs +++ b/osu.Game/Overlays/BeatmapSetOverlay.cs @@ -31,8 +31,6 @@ namespace osu.Game.Overlays private RulesetStore rulesets; - private readonly OsuScrollContainer scroll; - private readonly Bindable beatmapSet = new Bindable(); // receive input outside our bounds so we can trigger a close event on ourselves. @@ -40,6 +38,7 @@ namespace osu.Game.Overlays public BeatmapSetOverlay() { + OsuScrollContainer scroll; Info info; ScoresContainer scores; @@ -76,6 +75,8 @@ namespace osu.Game.Overlays { info.Beatmap = b.NewValue; scores.Beatmap = b.NewValue; + + scroll.ScrollToStart(); }; } @@ -119,18 +120,14 @@ namespace osu.Game.Overlays Show(); } - public void ShowBeatmapSet(BeatmapSetInfo set, bool refetch = true) + /// + /// Show an already fully-populated beatmap set. + /// + /// The set to show. + public void ShowBeatmapSet(BeatmapSetInfo set) { - // Re-fetching is the correct way forward. - if (refetch) - FetchAndShowBeatmapSet(set?.OnlineBeatmapSetID ?? 0); - else - { - beatmapSet.Value = set; - Show(); - } - - scroll.ScrollTo(0); + beatmapSet.Value = set; + Show(); } } } diff --git a/osu.Game/Overlays/Direct/DirectPanel.cs b/osu.Game/Overlays/Direct/DirectPanel.cs index c918a84ab0..584b25f83f 100644 --- a/osu.Game/Overlays/Direct/DirectPanel.cs +++ b/osu.Game/Overlays/Direct/DirectPanel.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System.Collections.Generic; +using System.Diagnostics; using System.Linq; using osu.Framework.Allocation; using osu.Framework.Bindables; @@ -45,6 +46,8 @@ namespace osu.Game.Overlays.Direct protected DirectPanel(BeatmapSetInfo setInfo) { + Debug.Assert(setInfo.OnlineBeatmapSetID != null); + SetInfo = setInfo; } @@ -119,12 +122,11 @@ namespace osu.Game.Overlays.Direct protected override bool OnClick(ClickEvent e) { - ShowInformation(); + Debug.Assert(SetInfo.OnlineBeatmapSetID != null); + beatmapSetOverlay?.FetchAndShowBeatmapSet(SetInfo.OnlineBeatmapSetID.Value); return true; } - protected void ShowInformation() => beatmapSetOverlay?.ShowBeatmapSet(SetInfo); - protected override void LoadComplete() { base.LoadComplete(); From cc9a7839c9d3242f8c044ea69c4a0861c6639f29 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 27 Jun 2019 12:04:01 +0900 Subject: [PATCH 109/148] Fix layout regression --- osu.Game/Overlays/BeatmapSet/Header.cs | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/Header.cs b/osu.Game/Overlays/BeatmapSet/Header.cs index abd643e5a2..bd6900016e 100644 --- a/osu.Game/Overlays/BeatmapSet/Header.cs +++ b/osu.Game/Overlays/BeatmapSet/Header.cs @@ -102,7 +102,8 @@ namespace osu.Game.Overlays.BeatmapSet }, new Container { - RelativeSizeAxes = Axes.Both, + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, Padding = new MarginPadding { Top = 20, @@ -170,13 +171,14 @@ namespace osu.Game.Overlays.BeatmapSet }, }, }, - loading = new LoadingAnimation - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - } } }, + loading = new LoadingAnimation + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Scale = new Vector2(1.5f), + }, new FillFlowContainer { Anchor = Anchor.BottomRight, From 32c3bee71b88926a115d16c3210abc01f2a8d279 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 27 Jun 2019 12:11:04 +0900 Subject: [PATCH 110/148] Avoid public exposure --- .../Online/TestSceneBeatmapSetOverlay.cs | 4 ++-- osu.Game/Overlays/BeatmapSet/Header.cs | 20 ++++++++++--------- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs index fad5c56d43..e50e30ae1d 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs @@ -437,12 +437,12 @@ namespace osu.Game.Tests.Visual.Online private void downloadAssert(bool shown) { - AddAssert($"is download button {(shown ? "shown" : "hidden")}", () => overlay.IsDownloadButtonsShown == shown); + AddAssert($"is download button {(shown ? "shown" : "hidden")}", () => overlay.DownloadButtonsVisible == shown); } private class TestBeatmapSetOverlay : BeatmapSetOverlay { - public bool IsDownloadButtonsShown => Header.DownloadButtonsContainer.Any(); + public bool DownloadButtonsVisible => Header.DownloadButtonsVisibile; } } } diff --git a/osu.Game/Overlays/BeatmapSet/Header.cs b/osu.Game/Overlays/BeatmapSet/Header.cs index bd6900016e..62384065ec 100644 --- a/osu.Game/Overlays/BeatmapSet/Header.cs +++ b/osu.Game/Overlays/BeatmapSet/Header.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 osu.Framework.Allocation; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; @@ -32,11 +33,12 @@ namespace osu.Game.Overlays.BeatmapSet private readonly UpdateableBeatmapSetCover cover; private readonly OsuSpriteText title, artist; private readonly AuthorInfo author; + private readonly FillFlowContainer downloadButtonsContainer; private readonly BeatmapAvailability beatmapAvailability; private readonly BeatmapSetOnlineStatusPill onlineStatusPill; public Details Details; - public readonly FillFlowContainer DownloadButtonsContainer; + public bool DownloadButtonsVisibile => downloadButtonsContainer.Any(); public readonly BeatmapPicker Picker; @@ -161,7 +163,7 @@ namespace osu.Game.Overlays.BeatmapSet Children = new Drawable[] { favouriteButton = new FavouriteButton(), - DownloadButtonsContainer = new FillFlowContainer + downloadButtonsContainer = new FillFlowContainer { RelativeSizeAxes = Axes.Both, Padding = new MarginPadding { Left = buttons_height + buttons_spacing }, @@ -229,7 +231,7 @@ namespace osu.Game.Overlays.BeatmapSet loading.Show(); - DownloadButtonsContainer.FadeOut(transition_duration); + downloadButtonsContainer.FadeOut(transition_duration); favouriteButton.FadeOut(transition_duration); } else @@ -244,7 +246,7 @@ namespace osu.Game.Overlays.BeatmapSet onlineStatusPill.FadeIn(500, Easing.OutQuint); onlineStatusPill.Status = setInfo.NewValue.OnlineInfo.Status; - DownloadButtonsContainer.FadeIn(transition_duration); + downloadButtonsContainer.FadeIn(transition_duration); favouriteButton.FadeIn(transition_duration); updateDownloadButtons(); @@ -258,7 +260,7 @@ namespace osu.Game.Overlays.BeatmapSet if (BeatmapSet.Value.OnlineInfo.Availability?.DownloadDisabled ?? false) { - DownloadButtonsContainer.Clear(); + downloadButtonsContainer.Clear(); return; } @@ -266,7 +268,7 @@ namespace osu.Game.Overlays.BeatmapSet { case DownloadState.LocallyAvailable: // temporary for UX until new design is implemented. - DownloadButtonsContainer.Child = new Direct.DownloadButton(BeatmapSet.Value) + downloadButtonsContainer.Child = new Direct.DownloadButton(BeatmapSet.Value) { Width = 50, RelativeSizeAxes = Axes.Y @@ -276,13 +278,13 @@ namespace osu.Game.Overlays.BeatmapSet case DownloadState.Downloading: case DownloadState.Downloaded: // temporary to avoid showing two buttons for maps with novideo. will be fixed in new beatmap overlay design. - DownloadButtonsContainer.Child = new DownloadButton(BeatmapSet.Value); + downloadButtonsContainer.Child = new DownloadButton(BeatmapSet.Value); break; default: - DownloadButtonsContainer.Child = new DownloadButton(BeatmapSet.Value); + downloadButtonsContainer.Child = new DownloadButton(BeatmapSet.Value); if (BeatmapSet.Value.OnlineInfo.HasVideo) - DownloadButtonsContainer.Add(new DownloadButton(BeatmapSet.Value, true)); + downloadButtonsContainer.Add(new DownloadButton(BeatmapSet.Value, true)); break; } } From a4929f19e572d47fbd5b3888647e935d6428f298 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 27 Jun 2019 12:17:28 +0900 Subject: [PATCH 111/148] Adjust background colour of non-loaded beatmap set cover to play better with black foreground elements --- osu.Game/Beatmaps/Drawables/UpdateableBeatmapSetCover.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/osu.Game/Beatmaps/Drawables/UpdateableBeatmapSetCover.cs b/osu.Game/Beatmaps/Drawables/UpdateableBeatmapSetCover.cs index c7c4c1fb1e..16eecb7198 100644 --- a/osu.Game/Beatmaps/Drawables/UpdateableBeatmapSetCover.cs +++ b/osu.Game/Beatmaps/Drawables/UpdateableBeatmapSetCover.cs @@ -2,9 +2,10 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Graphics; +using osu.Framework.Graphics.Colour; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; -using osuTK.Graphics; +using osu.Game.Graphics; namespace osu.Game.Beatmaps.Drawables { @@ -49,7 +50,7 @@ namespace osu.Game.Beatmaps.Drawables Child = new Box { RelativeSizeAxes = Axes.Both, - Colour = Color4.Black, + Colour = ColourInfo.GradientVertical(OsuColour.Gray(0.2f), OsuColour.Gray(0.1f)), }; } From c49b8b1883037ca6970dd7dc20ee3dd1ac2075bb Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 27 Jun 2019 12:19:49 +0900 Subject: [PATCH 112/148] Remove accidental change --- osu.Game/Online/Chat/ChannelManager.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Online/Chat/ChannelManager.cs b/osu.Game/Online/Chat/ChannelManager.cs index f722eb9e41..3af11ff20f 100644 --- a/osu.Game/Online/Chat/ChannelManager.cs +++ b/osu.Game/Online/Chat/ChannelManager.cs @@ -18,7 +18,6 @@ namespace osu.Game.Online.Chat /// /// Manages everything channel related /// - [Cached] public class ChannelManager : PollingComponent { /// From cd6f452bfabd710b4ab50d52d13e2e7eb7f302f1 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 27 Jun 2019 12:22:38 +0900 Subject: [PATCH 113/148] Remove weird download button exposure --- osu.Game/Overlays/Direct/DirectGridPanel.cs | 5 ++--- osu.Game/Overlays/Direct/DirectListPanel.cs | 5 ++--- osu.Game/Overlays/Direct/DirectPanel.cs | 1 - 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/osu.Game/Overlays/Direct/DirectGridPanel.cs b/osu.Game/Overlays/Direct/DirectGridPanel.cs index 5ee00d94d4..571fb40d39 100644 --- a/osu.Game/Overlays/Direct/DirectGridPanel.cs +++ b/osu.Game/Overlays/Direct/DirectGridPanel.cs @@ -25,11 +25,10 @@ namespace osu.Game.Overlays.Direct private const float vertical_padding = 5; private FillFlowContainer bottomPanel, statusContainer; - private DownloadButton downloadButton; + protected DownloadButton DownloadButton; private PlayButton playButton; private Box progressBar; - protected override DownloadButton DownloadButton => downloadButton; protected override PlayButton PlayButton => playButton; protected override Box PreviewBar => progressBar; @@ -157,7 +156,7 @@ namespace osu.Game.Overlays.Direct }, }, }, - downloadButton = new DownloadButton(SetInfo) + DownloadButton = new DownloadButton(SetInfo) { Size = new Vector2(50, 30), Margin = new MarginPadding(horizontal_padding), diff --git a/osu.Game/Overlays/Direct/DirectListPanel.cs b/osu.Game/Overlays/Direct/DirectListPanel.cs index c701002d2e..6f3b5bc5f1 100644 --- a/osu.Game/Overlays/Direct/DirectListPanel.cs +++ b/osu.Game/Overlays/Direct/DirectListPanel.cs @@ -27,13 +27,12 @@ namespace osu.Game.Overlays.Direct private const float height = 70; private FillFlowContainer statusContainer; - private DownloadButton downloadButton; + protected DownloadButton DownloadButton; private PlayButton playButton; private Box progressBar; protected override bool FadePlayButton => false; - protected override DownloadButton DownloadButton => downloadButton; protected override PlayButton PlayButton => playButton; protected override Box PreviewBar => progressBar; @@ -151,7 +150,7 @@ namespace osu.Game.Overlays.Direct Anchor = Anchor.CentreRight, Origin = Anchor.CentreRight, AutoSizeAxes = Axes.Both, - Child = downloadButton = new DownloadButton(SetInfo) + Child = DownloadButton = new DownloadButton(SetInfo) { Size = new Vector2(height - vertical_padding * 3), Margin = new MarginPadding { Left = vertical_padding * 2, Right = vertical_padding }, diff --git a/osu.Game/Overlays/Direct/DirectPanel.cs b/osu.Game/Overlays/Direct/DirectPanel.cs index 584b25f83f..8199d80528 100644 --- a/osu.Game/Overlays/Direct/DirectPanel.cs +++ b/osu.Game/Overlays/Direct/DirectPanel.cs @@ -36,7 +36,6 @@ namespace osu.Game.Overlays.Direct public PreviewTrack Preview => PlayButton.Preview; public Bindable PreviewPlaying => PlayButton.Playing; - protected abstract DownloadButton DownloadButton { get; } protected abstract PlayButton PlayButton { get; } protected abstract Box PreviewBar { get; } From be901294f7b0361c978d2590367b76b41cc3caec Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 27 Jun 2019 12:33:14 +0900 Subject: [PATCH 114/148] Simplify text layout --- .../BeatmapSet/BeatmapAvailability.cs | 66 +++++++++---------- 1 file changed, 31 insertions(+), 35 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/BeatmapAvailability.cs b/osu.Game/Overlays/BeatmapSet/BeatmapAvailability.cs index 30c89e23d0..00cc2ec605 100644 --- a/osu.Game/Overlays/BeatmapSet/BeatmapAvailability.cs +++ b/osu.Game/Overlays/BeatmapSet/BeatmapAvailability.cs @@ -19,29 +19,7 @@ namespace osu.Game.Overlays.BeatmapSet private bool downloadDisabled => BeatmapSet?.OnlineInfo.Availability?.DownloadDisabled ?? false; private bool hasExternalLink => !string.IsNullOrEmpty(BeatmapSet?.OnlineInfo.Availability?.ExternalLink); - public BeatmapSetInfo BeatmapSet - { - get => beatmapSet; - set - { - if (value == beatmapSet) - return; - - beatmapSet = value; - - linkContainer.Clear(); - - if (downloadDisabled || hasExternalLink) - { - Show(); - updateText(); - } - else Hide(); - } - } - - private readonly TextFlowContainer textContainer; - private readonly LinkFlowContainer linkContainer; + private readonly LinkFlowContainer textContainer; public BeatmapAvailability() { @@ -64,33 +42,51 @@ namespace osu.Game.Overlays.BeatmapSet Padding = new MarginPadding(10), Children = new Drawable[] { - textContainer = new TextFlowContainer(t => t.Font = OsuFont.GetFont(size: 14, weight: FontWeight.Medium)) + textContainer = new LinkFlowContainer(t => t.Font = OsuFont.GetFont(size: 14)) { Direction = FillDirection.Full, RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, - Colour = Color4.Orange, - }, - linkContainer = new LinkFlowContainer(t => t.Font = OsuFont.GetFont(size: 10)) - { - Direction = FillDirection.Full, - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Padding = new MarginPadding { Top = 10 }, }, }, }, }; } + public BeatmapSetInfo BeatmapSet + { + get => beatmapSet; + set + { + if (value == beatmapSet) + return; + + beatmapSet = value; + + if (downloadDisabled || hasExternalLink) + { + Show(); + updateText(); + } + else + Hide(); + } + } + private void updateText() { - textContainer.Text = downloadDisabled + textContainer.Clear(); + + textContainer.AddParagraph(downloadDisabled ? "This beatmap is currently not available for download." - : "Portions of this beatmap have been removed at the request of the creator or a third-party rights holder."; + : "Portions of this beatmap have been removed at the request of the creator or a third-party rights holder.", t => t.Colour = Color4.Orange); if (hasExternalLink) - linkContainer.AddLink("Check here for more information.", BeatmapSet.OnlineInfo.Availability.ExternalLink); + { + textContainer.NewParagraph(); + textContainer.NewParagraph(); + textContainer.AddLink("Check here for more information.", BeatmapSet.OnlineInfo.Availability.ExternalLink, creationParameters: t => t.Font = OsuFont.GetFont(size: 10)); + } } } } From a5ccfeb18ede010a35591e0e4e89ec1f00c3616b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 27 Jun 2019 12:34:22 +0900 Subject: [PATCH 115/148] Remove unnecessary fill flow --- .../Overlays/BeatmapSet/BeatmapAvailability.cs | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/BeatmapAvailability.cs b/osu.Game/Overlays/BeatmapSet/BeatmapAvailability.cs index 00cc2ec605..896c646552 100644 --- a/osu.Game/Overlays/BeatmapSet/BeatmapAvailability.cs +++ b/osu.Game/Overlays/BeatmapSet/BeatmapAvailability.cs @@ -34,21 +34,12 @@ namespace osu.Game.Overlays.BeatmapSet RelativeSizeAxes = Axes.Both, Colour = Color4.Black.Opacity(0.6f), }, - new FillFlowContainer + textContainer = new LinkFlowContainer(t => t.Font = OsuFont.GetFont(size: 14)) { + Direction = FillDirection.Full, RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, - Direction = FillDirection.Vertical, Padding = new MarginPadding(10), - Children = new Drawable[] - { - textContainer = new LinkFlowContainer(t => t.Font = OsuFont.GetFont(size: 14)) - { - Direction = FillDirection.Full, - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - }, - }, }, }; } @@ -56,6 +47,7 @@ namespace osu.Game.Overlays.BeatmapSet public BeatmapSetInfo BeatmapSet { get => beatmapSet; + set { if (value == beatmapSet) @@ -76,7 +68,6 @@ namespace osu.Game.Overlays.BeatmapSet private void updateText() { textContainer.Clear(); - textContainer.AddParagraph(downloadDisabled ? "This beatmap is currently not available for download." : "Portions of this beatmap have been removed at the request of the creator or a third-party rights holder.", t => t.Colour = Color4.Orange); From 3294464bc6e2d03b167ea238f5209cf9a780d159 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 27 Jun 2019 12:47:05 +0900 Subject: [PATCH 116/148] Fix typo in variable --- osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs | 2 +- osu.Game/Overlays/BeatmapSet/Header.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs index e50e30ae1d..00dc143019 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs @@ -442,7 +442,7 @@ namespace osu.Game.Tests.Visual.Online private class TestBeatmapSetOverlay : BeatmapSetOverlay { - public bool DownloadButtonsVisible => Header.DownloadButtonsVisibile; + public bool DownloadButtonsVisible => Header.DownloadButtonsVisible; } } } diff --git a/osu.Game/Overlays/BeatmapSet/Header.cs b/osu.Game/Overlays/BeatmapSet/Header.cs index 62384065ec..1c1167d08e 100644 --- a/osu.Game/Overlays/BeatmapSet/Header.cs +++ b/osu.Game/Overlays/BeatmapSet/Header.cs @@ -38,7 +38,7 @@ namespace osu.Game.Overlays.BeatmapSet private readonly BeatmapSetOnlineStatusPill onlineStatusPill; public Details Details; - public bool DownloadButtonsVisibile => downloadButtonsContainer.Any(); + public bool DownloadButtonsVisible => downloadButtonsContainer.Any(); public readonly BeatmapPicker Picker; From f3aab143aa5b204c98d0e357acc8cb3d897bcd15 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 27 Jun 2019 13:16:16 +0900 Subject: [PATCH 117/148] Fix settings subpanels dimming main content --- osu.Game/Overlays/SettingsSubPanel.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Overlays/SettingsSubPanel.cs b/osu.Game/Overlays/SettingsSubPanel.cs index 576be71ee6..7f794e2927 100644 --- a/osu.Game/Overlays/SettingsSubPanel.cs +++ b/osu.Game/Overlays/SettingsSubPanel.cs @@ -34,6 +34,8 @@ namespace osu.Game.Overlays }); } + protected override bool DimMainContent => false; // dimming is handled by main overlay + private class BackButton : OsuClickableContainer, IKeyBindingHandler { private AspectContainer aspect; From c1277b5db2137bf0f3e601db70c88207ddb44688 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 27 Jun 2019 13:35:14 +0900 Subject: [PATCH 118/148] Test the download button directly for safety --- .../Online/TestSceneDirectDownloadButton.cs | 95 +++++++++++++++++++ .../Visual/Online/TestSceneDirectPanel.cs | 29 +----- osu.Game/Overlays/Direct/DirectGridPanel.cs | 3 +- osu.Game/Overlays/Direct/DownloadButton.cs | 13 +-- 4 files changed, 102 insertions(+), 38 deletions(-) create mode 100644 osu.Game.Tests/Visual/Online/TestSceneDirectDownloadButton.cs diff --git a/osu.Game.Tests/Visual/Online/TestSceneDirectDownloadButton.cs b/osu.Game.Tests/Visual/Online/TestSceneDirectDownloadButton.cs new file mode 100644 index 0000000000..4c97c00a59 --- /dev/null +++ b/osu.Game.Tests/Visual/Online/TestSceneDirectDownloadButton.cs @@ -0,0 +1,95 @@ +// 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 NUnit.Framework; +using osu.Framework.Graphics; +using osu.Game.Beatmaps; +using osu.Game.Rulesets; +using osu.Game.Rulesets.Osu; +using osuTK; +using DownloadButton = osu.Game.Overlays.Direct.DownloadButton; + +namespace osu.Game.Tests.Visual.Online +{ + public class TestSceneDirectDownloadButton : OsuTestScene + { + public override IReadOnlyList RequiredTypes => new[] + { + typeof(DownloadButton) + }; + + private TestDownloadButton downloadButton; + + [Test] + public void TestDownloadableBeatmap() + { + createButton(true); + assertEnabled(true); + } + + [Test] + public void TestUndownloadableBeatmap() + { + createButton(false); + assertEnabled(false); + } + + private void assertEnabled(bool enabled) + { + AddAssert($"button {(enabled ? "enabled" : "disabled")}", () => downloadButton.DownloadAllowed == enabled); + } + + private void createButton(bool downloadable) + { + AddStep("create button", () => + { + Child = downloadButton = new TestDownloadButton(downloadable ? getDownloadableBeatmapSet() : getUndownloadableBeatmapSet()) + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Size = new Vector2(75, 50), + }; + }); + } + + private BeatmapSetInfo getDownloadableBeatmapSet() + { + var normal = CreateWorkingBeatmap(new OsuRuleset().RulesetInfo).BeatmapSetInfo; + normal.OnlineInfo.HasVideo = true; + normal.OnlineInfo.HasStoryboard = true; + + return normal; + } + + private BeatmapSetInfo getUndownloadableBeatmapSet() + { + var beatmap = CreateWorkingBeatmap(new OsuRuleset().RulesetInfo).BeatmapSetInfo; + beatmap.Metadata.Artist = "test"; + beatmap.Metadata.Title = "undownloadable"; + beatmap.Metadata.AuthorString = "test"; + + beatmap.OnlineInfo.HasVideo = true; + beatmap.OnlineInfo.HasStoryboard = true; + + beatmap.OnlineInfo.Availability = new BeatmapSetOnlineAvailability + { + DownloadDisabled = true, + ExternalLink = "http://osu.ppy.sh", + }; + + return beatmap; + } + + private class TestDownloadButton : DownloadButton + { + public new bool DownloadAllowed => base.DownloadAllowed; + + public TestDownloadButton(BeatmapSetInfo beatmapSet, bool noVideo = false) + : base(beatmapSet, noVideo) + { + } + } + } +} diff --git a/osu.Game.Tests/Visual/Online/TestSceneDirectPanel.cs b/osu.Game.Tests/Visual/Online/TestSceneDirectPanel.cs index 7a305f0328..051724579b 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneDirectPanel.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneDirectPanel.cs @@ -52,8 +52,6 @@ namespace osu.Game.Tests.Visual.Online normal.OnlineInfo.HasStoryboard = true; var undownloadable = getUndownloadableBeatmapSet(ruleset); - TestDirectGridPanel undownloadableGridPanel; - TestDirectListPanel undownloadableListPanel; Child = new BasicScrollContainer { @@ -69,34 +67,11 @@ namespace osu.Game.Tests.Visual.Online { new DirectGridPanel(normal), new DirectListPanel(normal), - undownloadableGridPanel = new TestDirectGridPanel(undownloadable), - undownloadableListPanel = new TestDirectListPanel(undownloadable), + new DirectGridPanel(undownloadable), + new DirectListPanel(undownloadable), }, }, }; - - AddAssert("is download button disabled on second grid panel", () => !undownloadableGridPanel.IsDownloadButtonEnabled); - AddAssert("is download button disabled on second list panel", () => !undownloadableListPanel.IsDownloadButtonEnabled); - } - - private class TestDirectGridPanel : DirectGridPanel - { - public bool IsDownloadButtonEnabled => DownloadButton.Enabled.Value; - - public TestDirectGridPanel(BeatmapSetInfo beatmap) - : base(beatmap) - { - } - } - - private class TestDirectListPanel : DirectListPanel - { - public bool IsDownloadButtonEnabled => DownloadButton.Enabled.Value; - - public TestDirectListPanel(BeatmapSetInfo beatmap) - : base(beatmap) - { - } } } } diff --git a/osu.Game/Overlays/Direct/DirectGridPanel.cs b/osu.Game/Overlays/Direct/DirectGridPanel.cs index 571fb40d39..5756a4593d 100644 --- a/osu.Game/Overlays/Direct/DirectGridPanel.cs +++ b/osu.Game/Overlays/Direct/DirectGridPanel.cs @@ -25,7 +25,6 @@ namespace osu.Game.Overlays.Direct private const float vertical_padding = 5; private FillFlowContainer bottomPanel, statusContainer; - protected DownloadButton DownloadButton; private PlayButton playButton; private Box progressBar; @@ -156,7 +155,7 @@ namespace osu.Game.Overlays.Direct }, }, }, - DownloadButton = new DownloadButton(SetInfo) + new DownloadButton(SetInfo) { Size = new Vector2(50, 30), Margin = new MarginPadding(horizontal_padding), diff --git a/osu.Game/Overlays/Direct/DownloadButton.cs b/osu.Game/Overlays/Direct/DownloadButton.cs index 1225eef8d8..25cdddd3ae 100644 --- a/osu.Game/Overlays/Direct/DownloadButton.cs +++ b/osu.Game/Overlays/Direct/DownloadButton.cs @@ -2,7 +2,6 @@ // 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.Shapes; using osu.Framework.Graphics.Sprites; @@ -17,19 +16,17 @@ namespace osu.Game.Overlays.Direct { public class DownloadButton : BeatmapDownloadTrackingComposite { + protected bool DownloadAllowed => button.Enabled.Value; + private readonly bool noVideo; private readonly SpriteIcon icon; private readonly SpriteIcon checkmark; private readonly Box background; private OsuColour colours; - private readonly ShakeContainer shakeContainer; - private readonly OsuAnimatedButton button; - public readonly BindableBool Enabled = new BindableBool(true); - public DownloadButton(BeatmapSetInfo beatmapSet, bool noVideo = false) : base(beatmapSet) { @@ -66,8 +63,6 @@ namespace osu.Game.Overlays.Direct } } }; - - Enabled.BindTo(button.Enabled); } protected override void LoadComplete() @@ -78,14 +73,14 @@ namespace osu.Game.Overlays.Direct FinishTransforms(true); } - [BackgroundDependencyLoader(permitNulls: true)] + [BackgroundDependencyLoader(true)] private void load(OsuColour colours, OsuGame game, BeatmapManager beatmaps) { this.colours = colours; if (BeatmapSet.Value.OnlineInfo.Availability?.DownloadDisabled ?? false) { - Enabled.Value = false; + button.Enabled.Value = false; button.TooltipText = "This beatmap is currently not available for download."; return; } From 9e2e393ab7a29172bc8ae53c42373740e9703365 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 27 Jun 2019 13:38:21 +0900 Subject: [PATCH 119/148] DownloadAllowed -> DownloadEnabled --- .../Visual/Online/TestSceneDirectDownloadButton.cs | 7 +++---- osu.Game/Overlays/Direct/DownloadButton.cs | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneDirectDownloadButton.cs b/osu.Game.Tests/Visual/Online/TestSceneDirectDownloadButton.cs index 4c97c00a59..ceb19a3ec6 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneDirectDownloadButton.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneDirectDownloadButton.cs @@ -6,10 +6,9 @@ using System.Collections.Generic; using NUnit.Framework; using osu.Framework.Graphics; using osu.Game.Beatmaps; -using osu.Game.Rulesets; +using osu.Game.Overlays.Direct; using osu.Game.Rulesets.Osu; using osuTK; -using DownloadButton = osu.Game.Overlays.Direct.DownloadButton; namespace osu.Game.Tests.Visual.Online { @@ -38,7 +37,7 @@ namespace osu.Game.Tests.Visual.Online private void assertEnabled(bool enabled) { - AddAssert($"button {(enabled ? "enabled" : "disabled")}", () => downloadButton.DownloadAllowed == enabled); + AddAssert($"button {(enabled ? "enabled" : "disabled")}", () => downloadButton.DownloadEnabled == enabled); } private void createButton(bool downloadable) @@ -84,7 +83,7 @@ namespace osu.Game.Tests.Visual.Online private class TestDownloadButton : DownloadButton { - public new bool DownloadAllowed => base.DownloadAllowed; + public new bool DownloadEnabled => base.DownloadEnabled; public TestDownloadButton(BeatmapSetInfo beatmapSet, bool noVideo = false) : base(beatmapSet, noVideo) diff --git a/osu.Game/Overlays/Direct/DownloadButton.cs b/osu.Game/Overlays/Direct/DownloadButton.cs index 25cdddd3ae..81709187e7 100644 --- a/osu.Game/Overlays/Direct/DownloadButton.cs +++ b/osu.Game/Overlays/Direct/DownloadButton.cs @@ -16,7 +16,7 @@ namespace osu.Game.Overlays.Direct { public class DownloadButton : BeatmapDownloadTrackingComposite { - protected bool DownloadAllowed => button.Enabled.Value; + protected bool DownloadEnabled => button.Enabled.Value; private readonly bool noVideo; private readonly SpriteIcon icon; From e78ecb9757e431cc8c536d881e7635e22805b864 Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Thu, 27 Jun 2019 07:48:57 +0300 Subject: [PATCH 120/148] More anonymising in tests --- .../Online/TestSceneBeatmapSetOverlay.cs | 303 +++--------------- .../Visual/Online/TestSceneDirectPanel.cs | 53 ++- 2 files changed, 82 insertions(+), 274 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs index 00dc143019..c494f5ef33 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs @@ -92,144 +92,37 @@ namespace osu.Game.Tests.Visual.Online OnlineInfo = new BeatmapSetOnlineInfo { Preview = @"https://b.ppy.sh/preview/12345.mp3", - PlayCount = 681380, - FavouriteCount = 356, - Submitted = new DateTime(2016, 2, 10), - Ranked = new DateTime(2016, 6, 19), - Status = BeatmapSetOnlineStatus.Ranked, - BPM = 236, + PlayCount = 123, + FavouriteCount = 456, + Submitted = DateTime.Now, + Ranked = DateTime.Now, + BPM = 111, HasVideo = true, - Covers = new BeatmapSetOnlineCovers - { - Cover = @"https://assets.ppy.sh/beatmaps/415886/covers/cover.jpg?1465651778", - }, + HasStoryboard = true, + Covers = new BeatmapSetOnlineCovers(), }, Metrics = new BeatmapSetMetrics { Ratings = Enumerable.Range(0, 11).ToArray() }, Beatmaps = new List { new BeatmapInfo { - StarDifficulty = 1.36, - Version = @"BASIC", + StarDifficulty = 9.99, + Version = @"TEST", Ruleset = maniaRuleset, BaseDifficulty = new BeatmapDifficulty { - CircleSize = 4, - DrainRate = 6.5f, - OverallDifficulty = 6.5f, - ApproachRate = 5, + CircleSize = 1, + DrainRate = 2.3f, + OverallDifficulty = 4.5f, + ApproachRate = 6, }, OnlineInfo = new BeatmapOnlineInfo { - Length = 115000, - CircleCount = 265, - SliderCount = 71, - PlayCount = 47906, - PassCount = 19899, - }, - Metrics = new BeatmapMetrics - { - Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6).ToArray(), - Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6).ToArray(), - }, - }, - new BeatmapInfo - { - StarDifficulty = 2.22, - Version = @"NOVICE", - Ruleset = maniaRuleset, - BaseDifficulty = new BeatmapDifficulty - { - CircleSize = 4, - DrainRate = 7, - OverallDifficulty = 7, - ApproachRate = 5, - }, - OnlineInfo = new BeatmapOnlineInfo - { - Length = 118000, - CircleCount = 592, - SliderCount = 62, - PlayCount = 162021, - PassCount = 72116, - }, - Metrics = new BeatmapMetrics - { - Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6).ToArray(), - Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6).ToArray(), - }, - }, - new BeatmapInfo - { - StarDifficulty = 3.49, - Version = @"ADVANCED", - Ruleset = maniaRuleset, - BaseDifficulty = new BeatmapDifficulty - { - CircleSize = 4, - DrainRate = 7.5f, - OverallDifficulty = 7.5f, - ApproachRate = 5, - }, - OnlineInfo = new BeatmapOnlineInfo - { - Length = 118000, - CircleCount = 1042, - SliderCount = 79, - PlayCount = 225178, - PassCount = 73001, - }, - Metrics = new BeatmapMetrics - { - Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6).ToArray(), - Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6).ToArray(), - }, - }, - new BeatmapInfo - { - StarDifficulty = 4.24, - Version = @"EXHAUST", - Ruleset = maniaRuleset, - BaseDifficulty = new BeatmapDifficulty - { - CircleSize = 4, - DrainRate = 8, - OverallDifficulty = 8, - ApproachRate = 5, - }, - OnlineInfo = new BeatmapOnlineInfo - { - Length = 118000, - CircleCount = 1352, - SliderCount = 69, - PlayCount = 131545, - PassCount = 42703, - }, - Metrics = new BeatmapMetrics - { - Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6).ToArray(), - Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6).ToArray(), - }, - }, - new BeatmapInfo - { - StarDifficulty = 5.26, - Version = @"GRAVITY", - Ruleset = maniaRuleset, - BaseDifficulty = new BeatmapDifficulty - { - CircleSize = 4, - DrainRate = 8.5f, - OverallDifficulty = 8.5f, - ApproachRate = 5, - }, - OnlineInfo = new BeatmapOnlineInfo - { - Length = 118000, - CircleCount = 1730, - SliderCount = 115, - PlayCount = 117673, - PassCount = 24241, + Length = 456000, + CircleCount = 111, + SliderCount = 12, + PlayCount = 222, + PassCount = 21, }, Metrics = new BeatmapMetrics { @@ -245,7 +138,7 @@ namespace osu.Game.Tests.Visual.Online } [Test] - public void TestUnavailable() + public void TestAvailability() { AddStep(@"show undownloadable", () => { @@ -254,13 +147,14 @@ namespace osu.Game.Tests.Visual.Online OnlineBeatmapSetID = 1234, Metadata = new BeatmapMetadata { - Title = @"Soumatou Labyrinth", - Artist = @"Yunomi with Momobako&miko", - Tags = @"mmbk.com yuzu__rinrin charlotte", + Title = @"undownloadable beatmap", + Artist = @"no one", + Source = @"some source", + Tags = @"another test tag tag more test tags", Author = new User { - Username = @"komasy", - Id = 1980256, + Username = @"BanchoBot", + Id = 3, }, }, OnlineInfo = new BeatmapSetOnlineInfo @@ -270,145 +164,38 @@ namespace osu.Game.Tests.Visual.Online DownloadDisabled = true, ExternalLink = "https://osu.ppy.sh", }, - Preview = @"https://b.ppy.sh/preview/625493.mp3", - PlayCount = 22996, - FavouriteCount = 58, - Submitted = new DateTime(2016, 6, 11), - Ranked = new DateTime(2016, 7, 12), - Status = BeatmapSetOnlineStatus.Pending, - BPM = 160, - HasVideo = false, - Covers = new BeatmapSetOnlineCovers - { - Cover = @"https://assets.ppy.sh/beatmaps/625493/covers/cover.jpg?1499167472", - }, + Preview = @"https://b.ppy.sh/preview/1234.mp3", + PlayCount = 123, + FavouriteCount = 456, + Submitted = DateTime.Now, + Ranked = DateTime.Now, + BPM = 111, + HasVideo = true, + HasStoryboard = true, + Covers = new BeatmapSetOnlineCovers(), }, Metrics = new BeatmapSetMetrics { Ratings = Enumerable.Range(0, 11).ToArray() }, Beatmaps = new List { new BeatmapInfo { - StarDifficulty = 1.40, - Version = @"yzrin's Kantan", + StarDifficulty = 5.67, + Version = @"ANOTHER TEST", Ruleset = taikoRuleset, BaseDifficulty = new BeatmapDifficulty { - CircleSize = 2, - DrainRate = 7, - OverallDifficulty = 3, - ApproachRate = 10, + CircleSize = 9, + DrainRate = 8, + OverallDifficulty = 7, + ApproachRate = 6, }, OnlineInfo = new BeatmapOnlineInfo { - Length = 193000, - CircleCount = 262, - SliderCount = 0, - PlayCount = 3952, - PassCount = 1373, - }, - Metrics = new BeatmapMetrics - { - Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6).ToArray(), - Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6).ToArray(), - }, - }, - new BeatmapInfo - { - StarDifficulty = 2.23, - Version = @"Futsuu", - Ruleset = taikoRuleset, - BaseDifficulty = new BeatmapDifficulty - { - CircleSize = 2, - DrainRate = 6, - OverallDifficulty = 4, - ApproachRate = 10, - }, - OnlineInfo = new BeatmapOnlineInfo - { - Length = 193000, - CircleCount = 464, - SliderCount = 0, - PlayCount = 4833, - PassCount = 920, - }, - Metrics = new BeatmapMetrics - { - Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6).ToArray(), - Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6).ToArray(), - }, - }, - new BeatmapInfo - { - StarDifficulty = 3.19, - Version = @"Muzukashii", - Ruleset = taikoRuleset, - BaseDifficulty = new BeatmapDifficulty - { - CircleSize = 2, - DrainRate = 6, - OverallDifficulty = 5, - ApproachRate = 10, - }, - OnlineInfo = new BeatmapOnlineInfo - { - Length = 193000, - CircleCount = 712, - SliderCount = 0, - PlayCount = 4405, - PassCount = 854, - }, - Metrics = new BeatmapMetrics - { - Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6).ToArray(), - Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6).ToArray(), - }, - }, - new BeatmapInfo - { - StarDifficulty = 3.97, - Version = @"Charlotte's Oni", - Ruleset = taikoRuleset, - BaseDifficulty = new BeatmapDifficulty - { - CircleSize = 5, - DrainRate = 6, - OverallDifficulty = 5.5f, - ApproachRate = 10, - }, - OnlineInfo = new BeatmapOnlineInfo - { - Length = 193000, - CircleCount = 943, - SliderCount = 0, - PlayCount = 3950, - PassCount = 693, - }, - Metrics = new BeatmapMetrics - { - Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6).ToArray(), - Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6).ToArray(), - }, - }, - new BeatmapInfo - { - StarDifficulty = 5.08, - Version = @"Labyrinth Oni", - Ruleset = taikoRuleset, - BaseDifficulty = new BeatmapDifficulty - { - CircleSize = 5, - DrainRate = 5, - OverallDifficulty = 6, - ApproachRate = 10, - }, - OnlineInfo = new BeatmapOnlineInfo - { - Length = 193000, - CircleCount = 1068, - SliderCount = 0, - PlayCount = 5856, - PassCount = 1207, + Length = 123000, + CircleCount = 123, + SliderCount = 45, + PlayCount = 567, + PassCount = 89, }, Metrics = new BeatmapMetrics { diff --git a/osu.Game.Tests/Visual/Online/TestSceneDirectPanel.cs b/osu.Game.Tests/Visual/Online/TestSceneDirectPanel.cs index 7a305f0328..027d9a3a75 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneDirectPanel.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneDirectPanel.cs @@ -10,6 +10,7 @@ using osu.Game.Beatmaps; using osu.Game.Overlays.Direct; using osu.Game.Rulesets; using osu.Game.Rulesets.Osu; +using osu.Game.Users; using osuTK; namespace osu.Game.Tests.Visual.Online @@ -23,24 +24,44 @@ namespace osu.Game.Tests.Visual.Online typeof(IconPill) }; - private BeatmapSetInfo getUndownloadableBeatmapSet(RulesetInfo ruleset) + private BeatmapSetInfo getUndownloadableBeatmapSet(RulesetInfo ruleset) => new BeatmapSetInfo { - var beatmap = CreateWorkingBeatmap(ruleset).BeatmapSetInfo; - beatmap.Metadata.Artist = "test"; - beatmap.Metadata.Title = "undownloadable"; - beatmap.Metadata.AuthorString = "test"; - - beatmap.OnlineInfo.HasVideo = true; - beatmap.OnlineInfo.HasStoryboard = true; - - beatmap.OnlineInfo.Availability = new BeatmapSetOnlineAvailability + OnlineBeatmapSetID = 123, + Metadata = new BeatmapMetadata { - DownloadDisabled = true, - ExternalLink = "http://osu.ppy.sh", - }; - - return beatmap; - } + Title = "undownloadable beatmap", + Artist = "test", + Source = "more tests", + Author = new User + { + Username = "BanchoBot", + Id = 3, + }, + }, + OnlineInfo = new BeatmapSetOnlineInfo + { + Availability = new BeatmapSetOnlineAvailability + { + DownloadDisabled = true, + }, + Preview = @"https://b.ppy.sh/preview/12345.mp3", + PlayCount = 123, + FavouriteCount = 456, + BPM = 111, + HasVideo = true, + HasStoryboard = true, + Covers = new BeatmapSetOnlineCovers(), + }, + Beatmaps = new List + { + new BeatmapInfo + { + Ruleset = ruleset, + Version = "Test", + StarDifficulty = 6.42, + } + } + }; [BackgroundDependencyLoader] private void load() From 803198ff209b1591868dc4c94cb129d6486fdeec Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 27 Jun 2019 14:53:18 +0900 Subject: [PATCH 121/148] Gamemode -> Ruleset --- .../Online/TestSceneProfileRulesetSelector.cs | 14 ++++++++----- .../Components/ProfileRulesetSelector.cs | 20 +++++++++---------- 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneProfileRulesetSelector.cs b/osu.Game.Tests/Visual/Online/TestSceneProfileRulesetSelector.cs index 687cbbebad..37adc6eb68 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneProfileRulesetSelector.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneProfileRulesetSelector.cs @@ -7,6 +7,10 @@ using osu.Game.Overlays.Profile.Header.Components; using osuTK.Graphics; using System; using System.Collections.Generic; +using osu.Game.Rulesets.Catch; +using osu.Game.Rulesets.Mania; +using osu.Game.Rulesets.Osu; +using osu.Game.Rulesets.Taiko; namespace osu.Game.Tests.Visual.Online { @@ -28,11 +32,11 @@ namespace osu.Game.Tests.Visual.Online Origin = Anchor.Centre, }; - AddStep("set osu! as default", () => selector.SetDefaultGamemode("osu")); - AddStep("set mania as default", () => selector.SetDefaultGamemode("mania")); - AddStep("set taiko as default", () => selector.SetDefaultGamemode("taiko")); - AddStep("set catch as default", () => selector.SetDefaultGamemode("fruits")); - AddStep("select default gamemode", selector.SelectDefaultGamemode); + AddStep("set osu! as default", () => selector.SetDefaultRuleset(new OsuRuleset().RulesetInfo)); + AddStep("set mania as default", () => selector.SetDefaultRuleset(new ManiaRuleset().RulesetInfo)); + AddStep("set taiko as default", () => selector.SetDefaultRuleset(new TaikoRuleset().RulesetInfo)); + AddStep("set catch as default", () => selector.SetDefaultRuleset(new CatchRuleset().RulesetInfo)); + AddStep("select default ruleset", selector.SelectDefaultRuleset); AddStep("set random colour", () => selector.AccentColour = new Color4(RNG.NextSingle(), RNG.NextSingle(), RNG.NextSingle(), 1)); } diff --git a/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetSelector.cs b/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetSelector.cs index 95065f2c72..87b785b906 100644 --- a/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetSelector.cs +++ b/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetSelector.cs @@ -14,11 +14,6 @@ namespace osu.Game.Overlays.Profile.Header.Components { public class ProfileRulesetSelector : RulesetSelector { - protected override TabItem CreateTabItem(RulesetInfo value) => new RulesetTabItem(value) - { - AccentColour = AccentColour - }; - private Color4 accentColour = Color4.White; public Color4 AccentColour @@ -51,16 +46,21 @@ namespace osu.Game.Overlays.Profile.Header.Components AccentColour = colours.Seafoam; } - public void SetDefaultGamemode(string gamemode) + protected override TabItem CreateTabItem(RulesetInfo value) => new RulesetTabItem(value) { + AccentColour = AccentColour + }; + + public void SetDefaultRuleset(RulesetInfo ruleset) + { + // Todo: This method shouldn't exist, but bindables don't provide the concept of observing a change to the default value foreach (TabItem tabItem in TabContainer) - { - ((RulesetTabItem)tabItem).IsDefault = ((RulesetTabItem)tabItem).Value.ShortName == gamemode; - } + ((RulesetTabItem)tabItem).IsDefault = ((RulesetTabItem)tabItem).Value.ID == ruleset.ID; } - public void SelectDefaultGamemode() + public void SelectDefaultRuleset() { + // Todo: This method shouldn't exist, but bindables don't provide the concept of observing a change to the default value foreach (TabItem tabItem in TabContainer) { if (((RulesetTabItem)tabItem).IsDefault) From 7f5587d894d7fe5ac805d349c781374c65060175 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 27 Jun 2019 14:54:31 +0900 Subject: [PATCH 122/148] RulesetTabItem -> ProfileRulesetTabItem --- .../Visual/Online/TestSceneProfileRulesetSelector.cs | 2 +- .../Header/Components/ProfileRulesetSelector.cs | 10 +++++----- .../{RulesetTabItem.cs => ProfileRulesetTabItem.cs} | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) rename osu.Game/Overlays/Profile/Header/Components/{RulesetTabItem.cs => ProfileRulesetTabItem.cs} (97%) diff --git a/osu.Game.Tests/Visual/Online/TestSceneProfileRulesetSelector.cs b/osu.Game.Tests/Visual/Online/TestSceneProfileRulesetSelector.cs index 37adc6eb68..ce484f72bb 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneProfileRulesetSelector.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneProfileRulesetSelector.cs @@ -19,7 +19,7 @@ namespace osu.Game.Tests.Visual.Online public override IReadOnlyList RequiredTypes => new[] { typeof(ProfileRulesetSelector), - typeof(RulesetTabItem), + typeof(ProfileRulesetTabItem), }; public TestSceneProfileRulesetSelector() diff --git a/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetSelector.cs b/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetSelector.cs index 87b785b906..cea16a918b 100644 --- a/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetSelector.cs +++ b/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetSelector.cs @@ -28,7 +28,7 @@ namespace osu.Game.Overlays.Profile.Header.Components foreach (TabItem tabItem in TabContainer) { - ((RulesetTabItem)tabItem).AccentColour = value; + ((ProfileRulesetTabItem)tabItem).AccentColour = value; } } } @@ -46,7 +46,7 @@ namespace osu.Game.Overlays.Profile.Header.Components AccentColour = colours.Seafoam; } - protected override TabItem CreateTabItem(RulesetInfo value) => new RulesetTabItem(value) + protected override TabItem CreateTabItem(RulesetInfo value) => new ProfileRulesetTabItem(value) { AccentColour = AccentColour }; @@ -55,7 +55,7 @@ namespace osu.Game.Overlays.Profile.Header.Components { // Todo: This method shouldn't exist, but bindables don't provide the concept of observing a change to the default value foreach (TabItem tabItem in TabContainer) - ((RulesetTabItem)tabItem).IsDefault = ((RulesetTabItem)tabItem).Value.ID == ruleset.ID; + ((ProfileRulesetTabItem)tabItem).IsDefault = ((ProfileRulesetTabItem)tabItem).Value.ID == ruleset.ID; } public void SelectDefaultRuleset() @@ -63,9 +63,9 @@ namespace osu.Game.Overlays.Profile.Header.Components // Todo: This method shouldn't exist, but bindables don't provide the concept of observing a change to the default value foreach (TabItem tabItem in TabContainer) { - if (((RulesetTabItem)tabItem).IsDefault) + if (((ProfileRulesetTabItem)tabItem).IsDefault) { - Current.Value = ((RulesetTabItem)tabItem).Value; + Current.Value = ((ProfileRulesetTabItem)tabItem).Value; return; } } diff --git a/osu.Game/Overlays/Profile/Header/Components/RulesetTabItem.cs b/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetTabItem.cs similarity index 97% rename from osu.Game/Overlays/Profile/Header/Components/RulesetTabItem.cs rename to osu.Game/Overlays/Profile/Header/Components/ProfileRulesetTabItem.cs index 0c49b3179c..a1ee8a09a7 100644 --- a/osu.Game/Overlays/Profile/Header/Components/RulesetTabItem.cs +++ b/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetTabItem.cs @@ -15,7 +15,7 @@ using osuTK.Graphics; namespace osu.Game.Overlays.Profile.Header.Components { - public class RulesetTabItem : TabItem + public class ProfileRulesetTabItem : TabItem { private readonly OsuSpriteText text; private readonly SpriteIcon icon; @@ -52,7 +52,7 @@ namespace osu.Game.Overlays.Profile.Header.Components } } - public RulesetTabItem(RulesetInfo value) + public ProfileRulesetTabItem(RulesetInfo value) : base(value) { AutoSizeAxes = Axes.Both; From b397652af4a08870262c94eaf41d83b9e59f1ea0 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 27 Jun 2019 15:02:26 +0900 Subject: [PATCH 123/148] Remove ability to set arbitrary accent colours --- .../Online/TestSceneProfileRulesetSelector.cs | 4 --- .../Components/ProfileRulesetSelector.cs | 32 ++++++------------- .../Components/ProfileRulesetTabItem.cs | 2 +- 3 files changed, 10 insertions(+), 28 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneProfileRulesetSelector.cs b/osu.Game.Tests/Visual/Online/TestSceneProfileRulesetSelector.cs index ce484f72bb..c344cb9598 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneProfileRulesetSelector.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneProfileRulesetSelector.cs @@ -2,9 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Graphics; -using osu.Framework.MathUtils; using osu.Game.Overlays.Profile.Header.Components; -using osuTK.Graphics; using System; using System.Collections.Generic; using osu.Game.Rulesets.Catch; @@ -37,8 +35,6 @@ namespace osu.Game.Tests.Visual.Online AddStep("set taiko as default", () => selector.SetDefaultRuleset(new TaikoRuleset().RulesetInfo)); AddStep("set catch as default", () => selector.SetDefaultRuleset(new CatchRuleset().RulesetInfo)); AddStep("select default ruleset", selector.SelectDefaultRuleset); - - AddStep("set random colour", () => selector.AccentColour = new Color4(RNG.NextSingle(), RNG.NextSingle(), RNG.NextSingle(), 1)); } } } diff --git a/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetSelector.cs b/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetSelector.cs index cea16a918b..b6112a6501 100644 --- a/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetSelector.cs +++ b/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetSelector.cs @@ -16,23 +16,6 @@ namespace osu.Game.Overlays.Profile.Header.Components { private Color4 accentColour = Color4.White; - public Color4 AccentColour - { - get => accentColour; - set - { - if (accentColour == value) - return; - - accentColour = value; - - foreach (TabItem tabItem in TabContainer) - { - ((ProfileRulesetTabItem)tabItem).AccentColour = value; - } - } - } - public ProfileRulesetSelector() { TabContainer.Masking = false; @@ -43,13 +26,11 @@ namespace osu.Game.Overlays.Profile.Header.Components [BackgroundDependencyLoader] private void load(OsuColour colours) { - AccentColour = colours.Seafoam; - } + accentColour = colours.Seafoam; - protected override TabItem CreateTabItem(RulesetInfo value) => new ProfileRulesetTabItem(value) - { - AccentColour = AccentColour - }; + foreach (TabItem tabItem in TabContainer) + ((ProfileRulesetTabItem)tabItem).AccentColour = accentColour; + } public void SetDefaultRuleset(RulesetInfo ruleset) { @@ -71,6 +52,11 @@ namespace osu.Game.Overlays.Profile.Header.Components } } + protected override TabItem CreateTabItem(RulesetInfo value) => new ProfileRulesetTabItem(value) + { + AccentColour = accentColour + }; + protected override TabFillFlowContainer CreateTabFlow() => new TabFillFlowContainer { Direction = FillDirection.Horizontal, diff --git a/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetTabItem.cs b/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetTabItem.cs index a1ee8a09a7..63f7783451 100644 --- a/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetTabItem.cs +++ b/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetTabItem.cs @@ -15,7 +15,7 @@ using osuTK.Graphics; namespace osu.Game.Overlays.Profile.Header.Components { - public class ProfileRulesetTabItem : TabItem + public class ProfileRulesetTabItem : TabItem, IHasAccentColour { private readonly OsuSpriteText text; private readonly SpriteIcon icon; From 25499f74a721e7040f79e6182d6292ae996cdb27 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 27 Jun 2019 15:31:36 +0900 Subject: [PATCH 124/148] Remove redundant font set --- .../Profile/Header/Components/ProfileRulesetTabItem.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetTabItem.cs b/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetTabItem.cs index 63f7783451..fdd05705a9 100644 --- a/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetTabItem.cs +++ b/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetTabItem.cs @@ -1,4 +1,4 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// 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; @@ -73,7 +73,6 @@ namespace osu.Game.Overlays.Profile.Header.Components Origin = Anchor.Centre, Anchor = Anchor.Centre, Text = value.Name, - Font = OsuFont.GetFont() }, icon = new SpriteIcon { From d6c28dc6d71e79baa30d9ebb220386e1abab407a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 27 Jun 2019 15:31:47 +0900 Subject: [PATCH 125/148] Simplify and fix state management --- .../Components/ProfileRulesetTabItem.cs | 49 ++++++------------- 1 file changed, 16 insertions(+), 33 deletions(-) diff --git a/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetTabItem.cs b/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetTabItem.cs index fdd05705a9..b5170ea3a2 100644 --- a/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetTabItem.cs +++ b/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetTabItem.cs @@ -1,4 +1,4 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// 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; @@ -92,51 +92,34 @@ namespace osu.Game.Overlays.Profile.Header.Components protected override bool OnHover(HoverEvent e) { base.OnHover(e); - - if (!Active.Value) - hoverAction(); - + updateState(); return true; } protected override void OnHoverLost(HoverLostEvent e) { base.OnHoverLost(e); - - if (!Active.Value) - unhoverAction(); + updateState(); } - protected override void OnActivated() - { - hoverAction(); - text.Font = text.Font.With(weight: FontWeight.Bold); - } + protected override void OnActivated() => updateState(); - protected override void OnDeactivated() - { - unhoverAction(); - text.Font = text.Font.With(weight: FontWeight.Medium); - } + protected override void OnDeactivated() => updateState(); private void updateState() { - if (Active.Value) - OnActivated(); + text.Font = text.Font.With(weight: Active.Value ? FontWeight.Bold : FontWeight.Medium); + + if (IsHovered || Active.Value) + { + text.FadeColour(Color4.White, 120, Easing.InQuad); + icon.FadeColour(Color4.White, 120, Easing.InQuad); + } else - OnDeactivated(); - } - - private void hoverAction() - { - text.FadeColour(Color4.White, 120, Easing.InQuad); - icon.FadeColour(Color4.White, 120, Easing.InQuad); - } - - private void unhoverAction() - { - text.FadeColour(AccentColour, 120, Easing.InQuad); - icon.FadeColour(AccentColour, 120, Easing.InQuad); + { + text.FadeColour(AccentColour, 120, Easing.InQuad); + icon.FadeColour(AccentColour, 120, Easing.InQuad); + } } } } From f6f547a91b4fa5bbe86c0392bbce9619d969b085 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 27 Jun 2019 18:25:38 +0900 Subject: [PATCH 126/148] Fix ruleset selector line not moving on first display --- .../TestSceneToolbarRulesetSelector.cs | 55 ++++++++++++++++--- .../Toolbar/ToolbarRulesetSelector.cs | 17 ++++-- 2 files changed, 57 insertions(+), 15 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneToolbarRulesetSelector.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneToolbarRulesetSelector.cs index 582303024b..0da256855a 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneToolbarRulesetSelector.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneToolbarRulesetSelector.cs @@ -7,7 +7,10 @@ using System; using System.Collections.Generic; using osu.Framework.Graphics; using System.Linq; +using NUnit.Framework; +using osu.Framework.Allocation; using osu.Framework.MathUtils; +using osu.Game.Rulesets; namespace osu.Game.Tests.Visual.UserInterface { @@ -19,17 +22,24 @@ namespace osu.Game.Tests.Visual.UserInterface typeof(ToolbarRulesetTabButton), }; - public TestSceneToolbarRulesetSelector() - { - ToolbarRulesetSelector selector; + [Resolved] + private RulesetStore rulesets { get; set; } - Add(new Container + [Test] + public void TestDisplay() + { + ToolbarRulesetSelector selector = null; + + AddStep("create selector", () => { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - AutoSizeAxes = Axes.X, - Height = Toolbar.HEIGHT, - Child = selector = new ToolbarRulesetSelector() + Child = new Container + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + AutoSizeAxes = Axes.X, + Height = Toolbar.HEIGHT, + Child = selector = new ToolbarRulesetSelector() + }; }); AddStep("Select random", () => @@ -38,5 +48,32 @@ namespace osu.Game.Tests.Visual.UserInterface }); AddStep("Toggle disabled state", () => selector.Current.Disabled = !selector.Current.Disabled); } + + [Test] + public void TestNonFirstRulesetInitialState() + { + TestSelector selector = null; + + AddStep("create selector", () => + { + Child = new Container + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + AutoSizeAxes = Axes.X, + Height = Toolbar.HEIGHT, + Child = selector = new TestSelector() + }; + + selector.Current.Value = rulesets.GetRuleset(2); + }); + + AddAssert("mode line has moved", () => selector.ModeButtonLine.DrawPosition.X > 0); + } + + private class TestSelector : ToolbarRulesetSelector + { + public new Drawable ModeButtonLine => base.ModeButtonLine; + } } } diff --git a/osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.cs b/osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.cs index 95d7d3f73a..f4272ab15c 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.cs @@ -20,7 +20,7 @@ namespace osu.Game.Overlays.Toolbar { private const float padding = 10; - private Drawable modeButtonLine; + protected Drawable ModeButtonLine { get; private set; } public ToolbarRulesetSelector() { @@ -37,7 +37,7 @@ namespace osu.Game.Overlays.Toolbar { Depth = 1, }, - modeButtonLine = new Container + ModeButtonLine = new Container { Size = new Vector2(padding * 2 + ToolbarButton.WIDTH, 3), Anchor = Anchor.BottomLeft, @@ -66,17 +66,22 @@ namespace osu.Game.Overlays.Toolbar Current.BindValueChanged(_ => moveLineToCurrent(), true); } - private void moveLineToCurrent() + private bool hasInitialPosition; + + // Scheduled to allow the flow layout to be computed before the line position is updated + private void moveLineToCurrent() => ScheduleAfterChildren(() => { - foreach (TabItem tabItem in TabContainer) + foreach (var tabItem in TabContainer) { if (tabItem.Value == Current.Value) { - modeButtonLine.MoveToX(tabItem.DrawPosition.X, 200, Easing.OutQuint); + ModeButtonLine.MoveToX(tabItem.DrawPosition.X, !hasInitialPosition ? 0 : 200, Easing.OutQuint); break; } } - } + + hasInitialPosition = true; + }); public override bool HandleNonPositionalInput => !Current.Disabled && base.HandleNonPositionalInput; From ba48331fcbdbb8159aa73915dcfca0eee5230b2d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 27 Jun 2019 17:37:43 +0900 Subject: [PATCH 127/148] Remove no longer necessary HandleInput overrides --- osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index 1cce5598e1..35c3a0e5e4 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -77,10 +77,6 @@ namespace osu.Game.Rulesets.Objects.Drawables private bool judgementOccurred; - public bool Interactive = true; - public override bool HandleNonPositionalInput => Interactive; - public override bool HandlePositionalInput => Interactive; - public override bool RemoveWhenNotAlive => false; public override bool RemoveCompletedTransforms => false; protected override bool RequiresChildrenUpdate => true; From 72bb6f8c12c5361b1574406b1ae5a662728554b7 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 27 Jun 2019 16:53:44 +0900 Subject: [PATCH 128/148] Fix download buttons not correctly finding existing downloads --- osu.Game/Database/DownloadableArchiveModelManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Database/DownloadableArchiveModelManager.cs b/osu.Game/Database/DownloadableArchiveModelManager.cs index 647eb3cbd3..2e7d70c941 100644 --- a/osu.Game/Database/DownloadableArchiveModelManager.cs +++ b/osu.Game/Database/DownloadableArchiveModelManager.cs @@ -20,7 +20,7 @@ namespace osu.Game.Database /// The model type. /// The associated file join type. public abstract class DownloadableArchiveModelManager : ArchiveModelManager, IModelDownloader - where TModel : class, IHasFiles, IHasPrimaryKey, ISoftDelete + where TModel : class, IHasFiles, IHasPrimaryKey, ISoftDelete, IEquatable where TFileModel : INamedFileInfo, new() { public event Action> DownloadBegan; From 61260cf599f07cbaaeaa7a2e03c744b8dcd8e5cf Mon Sep 17 00:00:00 2001 From: naoey Date: Thu, 27 Jun 2019 15:14:57 +0530 Subject: [PATCH 129/148] Hand off comparison logic for database query to implementors Equals overrides are not used in EF queries without running the comaprison locally instead of on the database, so to preserve that the comparison logic is instead implemented on a per manager basis. --- osu.Game/Beatmaps/BeatmapManager.cs | 2 ++ osu.Game/Database/DownloadableArchiveModelManager.cs | 10 +++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index d5b19485de..fe8fef3e07 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -145,6 +145,8 @@ namespace osu.Game.Beatmaps void resetIds() => beatmapSet.Beatmaps.ForEach(b => b.OnlineBeatmapID = null); } + protected override bool CheckLocalAvailability(BeatmapSetInfo model, IQueryable items) => items.Any(b => b.OnlineBeatmapSetID == model.OnlineBeatmapSetID); + /// /// Delete a beatmap difficulty. /// diff --git a/osu.Game/Database/DownloadableArchiveModelManager.cs b/osu.Game/Database/DownloadableArchiveModelManager.cs index 2e7d70c941..78c0837ce9 100644 --- a/osu.Game/Database/DownloadableArchiveModelManager.cs +++ b/osu.Game/Database/DownloadableArchiveModelManager.cs @@ -110,7 +110,15 @@ namespace osu.Game.Database return true; } - public virtual bool IsAvailableLocally(TModel model) => modelStore.ConsumableItems.Any(m => m.Equals(model) && !m.DeletePending); + public bool IsAvailableLocally(TModel model) => CheckLocalAvailability(model, modelStore.ConsumableItems.Where(m => !m.DeletePending)); + + /// + /// Performs implementation specific comparisons to determine whether a given model is present in the local store. + /// + /// The whose existence needs to be checked. + /// The usable items present in the store. + /// Whether the exists. + protected abstract bool CheckLocalAvailability(TModel model, IQueryable items); public ArchiveDownloadRequest GetExistingDownload(TModel model) => currentDownloads.Find(r => r.Model.Equals(model)); From e7419f382e81444a44ccaec61c4b232de68ef430 Mon Sep 17 00:00:00 2001 From: David Zhao Date: Thu, 27 Jun 2019 19:19:22 +0900 Subject: [PATCH 130/148] Fix TestSceneHyperDash in test browser --- osu.Game.Rulesets.Catch.Tests/TestSceneHyperDash.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneHyperDash.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneHyperDash.cs index 9cbff8c5d3..a603d96201 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneHyperDash.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneHyperDash.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.Beatmaps; using osu.Game.Rulesets.Catch.Objects; using osu.Game.Tests.Visual; @@ -17,8 +16,8 @@ namespace osu.Game.Rulesets.Catch.Tests { } - [BackgroundDependencyLoader] - private void load() + [Test] + public void TestHyperDash() { AddAssert("First note is hyperdash", () => Beatmap.Value.Beatmap.HitObjects[0] is Fruit f && f.HyperDash); } From 3cfa5a767f6daef49737d1f5c13ae64ffd9d543f Mon Sep 17 00:00:00 2001 From: naoey Date: Thu, 27 Jun 2019 17:31:21 +0530 Subject: [PATCH 131/148] Add test for download button states --- .../Online/TestSceneDirectDownloadButton.cs | 64 +++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/osu.Game.Tests/Visual/Online/TestSceneDirectDownloadButton.cs b/osu.Game.Tests/Visual/Online/TestSceneDirectDownloadButton.cs index ceb19a3ec6..5a5833feb6 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneDirectDownloadButton.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneDirectDownloadButton.cs @@ -3,11 +3,15 @@ using System; using System.Collections.Generic; +using System.Linq; using NUnit.Framework; +using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Game.Beatmaps; +using osu.Game.Online; using osu.Game.Overlays.Direct; using osu.Game.Rulesets.Osu; +using osu.Game.Tests.Resources; using osuTK; namespace osu.Game.Tests.Visual.Online @@ -21,6 +25,9 @@ namespace osu.Game.Tests.Visual.Online private TestDownloadButton downloadButton; + [Resolved] + private BeatmapManager beatmaps { get; set; } + [Test] public void TestDownloadableBeatmap() { @@ -35,11 +42,66 @@ namespace osu.Game.Tests.Visual.Online assertEnabled(false); } + [Test] + public void TestDownloadState() + { + AddUntilStep("ensure manager loaded", () => beatmaps != null); + ensureSoleilyRemoved(); + createButtonWithBeatmap(createSoleily()); + AddAssert("button state not downloaded", () => downloadButton.DownloadState == DownloadState.NotDownloaded); + AddStep("import soleily", () => beatmaps.Import(new[] { TestResources.GetTestBeatmapForImport() })); + AddUntilStep("wait for beatmap import", () => beatmaps.GetAllUsableBeatmapSets().Any(b => b.OnlineBeatmapSetID == 241526)); + createButtonWithBeatmap(createSoleily()); + AddAssert("button state downloaded", () => downloadButton.DownloadState == DownloadState.LocallyAvailable); + ensureSoleilyRemoved(); + AddAssert("button state not downloaded", () => downloadButton.DownloadState == DownloadState.NotDownloaded); + } + + private void ensureSoleilyRemoved() + { + AddStep("remove soleily", () => + { + var beatmap = beatmaps.QueryBeatmapSet(b => b.OnlineBeatmapSetID == 241526); + + if (beatmap != null) beatmaps.Delete(beatmap); + }); + } + private void assertEnabled(bool enabled) { AddAssert($"button {(enabled ? "enabled" : "disabled")}", () => downloadButton.DownloadEnabled == enabled); } + private BeatmapSetInfo createSoleily() + { + return new BeatmapSetInfo + { + ID = 1, + OnlineBeatmapSetID = 241526, + OnlineInfo = new BeatmapSetOnlineInfo + { + Availability = new BeatmapSetOnlineAvailability + { + DownloadDisabled = false, + ExternalLink = string.Empty, + }, + }, + }; + } + + private void createButtonWithBeatmap(BeatmapSetInfo beatmap) + { + AddStep("create button", () => + { + Child = downloadButton = new TestDownloadButton(beatmap) + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Size = new Vector2(75, 50), + }; + }); + } + private void createButton(bool downloadable) { AddStep("create button", () => @@ -85,6 +147,8 @@ namespace osu.Game.Tests.Visual.Online { public new bool DownloadEnabled => base.DownloadEnabled; + public DownloadState DownloadState => State.Value; + public TestDownloadButton(BeatmapSetInfo beatmapSet, bool noVideo = false) : base(beatmapSet, noVideo) { From 6d0cc1f7706d3a720bda383e4071581ea51fc6ea Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 28 Jun 2019 15:58:50 +0900 Subject: [PATCH 132/148] Remove GC debug setting --- .../Settings/Sections/Debug/GCSettings.cs | 22 ------------------- 1 file changed, 22 deletions(-) diff --git a/osu.Game/Overlays/Settings/Sections/Debug/GCSettings.cs b/osu.Game/Overlays/Settings/Sections/Debug/GCSettings.cs index 8ed196fd01..6897b42f4f 100644 --- a/osu.Game/Overlays/Settings/Sections/Debug/GCSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Debug/GCSettings.cs @@ -2,9 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System; -using System.Runtime; using osu.Framework.Allocation; -using osu.Framework.Bindables; using osu.Framework.Configuration; using osu.Framework.Graphics; @@ -14,37 +12,17 @@ namespace osu.Game.Overlays.Settings.Sections.Debug { protected override string Header => "Garbage Collector"; - private readonly Bindable latencyMode = new Bindable(); - private Bindable configLatencyMode; - [BackgroundDependencyLoader] private void load(FrameworkDebugConfigManager config) { Children = new Drawable[] { - new SettingsEnumDropdown - { - LabelText = "Active mode", - Bindable = latencyMode - }, new SettingsButton { Text = "Force garbage collection", Action = GC.Collect }, }; - - configLatencyMode = config.GetBindable(DebugSetting.ActiveGCMode); - configLatencyMode.BindValueChanged(mode => latencyMode.Value = (LatencyMode)mode.NewValue, true); - latencyMode.BindValueChanged(mode => configLatencyMode.Value = (GCLatencyMode)mode.NewValue); - } - - private enum LatencyMode - { - Batch = GCLatencyMode.Batch, - Interactive = GCLatencyMode.Interactive, - LowLatency = GCLatencyMode.LowLatency, - SustainedLowLatency = GCLatencyMode.SustainedLowLatency } } } From c2f82f86d61051c76c82a3eb9d75ebef85c1ffad Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 28 Jun 2019 18:14:08 +0900 Subject: [PATCH 133/148] Update framework --- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index b4af007447..9612ffb81a 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -15,7 +15,7 @@ - + diff --git a/osu.iOS.props b/osu.iOS.props index 9f21af05a1..ce8b62cc3f 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -105,8 +105,8 @@ - - + + From 02541ee6e59c8abb82d5e5df0201e2266cd265ee Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 28 Jun 2019 19:57:23 +0900 Subject: [PATCH 134/148] Add missing info.plist identifier --- osu.iOS/Info.plist | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.iOS/Info.plist b/osu.iOS/Info.plist index 0627feab78..d7992353cf 100644 --- a/osu.iOS/Info.plist +++ b/osu.iOS/Info.plist @@ -6,6 +6,8 @@ sh.ppy.osulazer CFBundleName osu! + CFBundleDisplayName + osu! CFBundleShortVersionString 0.1 CFBundleVersion From d5577371438ae1339b3d563c040c9a57e0e335e3 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 28 Jun 2019 20:37:53 +0900 Subject: [PATCH 135/148] Fix windows updater showing false failures --- osu.Desktop/Updater/SquirrelUpdateManager.cs | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/osu.Desktop/Updater/SquirrelUpdateManager.cs b/osu.Desktop/Updater/SquirrelUpdateManager.cs index e2c7a5e892..0819801f1d 100644 --- a/osu.Desktop/Updater/SquirrelUpdateManager.cs +++ b/osu.Desktop/Updater/SquirrelUpdateManager.cs @@ -1,4 +1,4 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using System; @@ -46,7 +46,7 @@ namespace osu.Desktop.Updater private async void checkForUpdateAsync(bool useDeltaPatching = true, UpdateProgressNotification notification = null) { //should we schedule a retry on completion of this check? - bool scheduleRetry = true; + bool scheduleRecheck = true; try { @@ -86,10 +86,12 @@ namespace osu.Desktop.Updater //could fail if deltas are unavailable for full update path (https://github.com/Squirrel/Squirrel.Windows/issues/959) //try again without deltas. checkForUpdateAsync(false, notification); - scheduleRetry = false; + scheduleRecheck = false; } else { + if (notification != null) + notification.State = ProgressNotificationState.Cancelled; Logger.Error(e, @"update failed!"); } } @@ -100,11 +102,8 @@ namespace osu.Desktop.Updater } finally { - if (scheduleRetry) + if (scheduleRecheck) { - if (notification != null) - notification.State = ProgressNotificationState.Cancelled; - //check again in 30 minutes. Scheduler.AddDelayed(() => checkForUpdateAsync(), 60000 * 30); } From 1898a6750dccd647ae7576ab2766200ba540a30a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 28 Jun 2019 20:45:25 +0900 Subject: [PATCH 136/148] Fix stutter during update process --- osu.Desktop/Updater/SquirrelUpdateManager.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Desktop/Updater/SquirrelUpdateManager.cs b/osu.Desktop/Updater/SquirrelUpdateManager.cs index 0819801f1d..cc9cd2843a 100644 --- a/osu.Desktop/Updater/SquirrelUpdateManager.cs +++ b/osu.Desktop/Updater/SquirrelUpdateManager.cs @@ -133,8 +133,8 @@ namespace osu.Desktop.Updater Text = @"Update ready to install. Click to restart!", Activated = () => { - updateManager.PrepareUpdate(); - game.GracefullyExit(); + updateManager.PrepareUpdateAsync() + .ContinueWith(_ => Schedule(() => game.GracefullyExit())); return true; } }; From 1289b7f5fe1f24982efd454be008f9bb49cea112 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 28 Jun 2019 21:03:35 +0900 Subject: [PATCH 137/148] Commit missing piece of puzzle --- osu.Desktop/Updater/SquirrelUpdateManager.cs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/osu.Desktop/Updater/SquirrelUpdateManager.cs b/osu.Desktop/Updater/SquirrelUpdateManager.cs index cc9cd2843a..7e7130d554 100644 --- a/osu.Desktop/Updater/SquirrelUpdateManager.cs +++ b/osu.Desktop/Updater/SquirrelUpdateManager.cs @@ -25,11 +25,7 @@ namespace osu.Desktop.Updater private UpdateManager updateManager; private NotificationOverlay notificationOverlay; - public void PrepareUpdate() - { - // Squirrel returns execution to us after the update process is started, so it's safe to use Wait() here - UpdateManager.RestartAppWhenExited().Wait(); - } + public Task PrepareUpdate() => UpdateManager.RestartAppWhenExited(); [BackgroundDependencyLoader] private void load(NotificationOverlay notification, OsuGameBase game) From c9104e91766273aa5654649ace9354f5c7298d9b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 28 Jun 2019 21:26:31 +0900 Subject: [PATCH 138/148] Fix remaining issues --- osu.Desktop/Updater/SquirrelUpdateManager.cs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/osu.Desktop/Updater/SquirrelUpdateManager.cs b/osu.Desktop/Updater/SquirrelUpdateManager.cs index 7e7130d554..69064a40cb 100644 --- a/osu.Desktop/Updater/SquirrelUpdateManager.cs +++ b/osu.Desktop/Updater/SquirrelUpdateManager.cs @@ -25,7 +25,7 @@ namespace osu.Desktop.Updater private UpdateManager updateManager; private NotificationOverlay notificationOverlay; - public Task PrepareUpdate() => UpdateManager.RestartAppWhenExited(); + public Task PrepareUpdateAsync() => UpdateManager.RestartAppWhenExited(); [BackgroundDependencyLoader] private void load(NotificationOverlay notification, OsuGameBase game) @@ -86,8 +86,7 @@ namespace osu.Desktop.Updater } else { - if (notification != null) - notification.State = ProgressNotificationState.Cancelled; + notification.State = ProgressNotificationState.Cancelled; Logger.Error(e, @"update failed!"); } } @@ -130,7 +129,7 @@ namespace osu.Desktop.Updater Activated = () => { updateManager.PrepareUpdateAsync() - .ContinueWith(_ => Schedule(() => game.GracefullyExit())); + .ContinueWith(_ => Schedule(() => game.GracefullyExit())); return true; } }; From 4465e42b85b4180c19e703fe8c00af8eee414d78 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 28 Jun 2019 23:21:14 +0300 Subject: [PATCH 139/148] HandlePositionalInput must be true To update IsHovered --- osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index 1cce5598e1..1aec2c513c 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -85,6 +85,8 @@ namespace osu.Game.Rulesets.Objects.Drawables public override bool RemoveCompletedTransforms => false; protected override bool RequiresChildrenUpdate => true; + public override bool HandlePositionalInput => true; + public override bool IsPresent => base.IsPresent || (State.Value == ArmedState.Idle && Clock?.CurrentTime >= LifetimeStart); public readonly Bindable State = new Bindable(); From a57218e50ee3883d4fc938b87b7cbdf7f1998a2d Mon Sep 17 00:00:00 2001 From: Welsar55 Date: Fri, 28 Jun 2019 20:45:11 -0500 Subject: [PATCH 140/148] Move to LocalSkinOverride --- .../Gameplay/TestSceneSkinReloadable.cs | 5 ++-- osu.Game/Screens/Play/Player.cs | 11 +------- .../Skinning/LocalSkinOverrideContainer.cs | 26 ++++++++++++++++++- 3 files changed, 29 insertions(+), 13 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinReloadable.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinReloadable.cs index c7a0df6e9f..f03ffea5dc 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinReloadable.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinReloadable.cs @@ -4,6 +4,7 @@ using System; using NUnit.Framework; using osu.Framework.Audio.Sample; +using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; @@ -28,7 +29,7 @@ namespace osu.Game.Tests.Visual.Gameplay Child = new SkinSourceContainer { RelativeSizeAxes = Axes.Both, - Child = new LocalSkinOverrideContainer(secondarySource) + Child = new LocalSkinOverrideContainer(secondarySource, new BindableInt()) { RelativeSizeAxes = Axes.Both, Child = consumer = new SkinConsumer("test", name => new NamedBox("Default Implementation"), source => true) @@ -53,7 +54,7 @@ namespace osu.Game.Tests.Visual.Gameplay Child = new SkinSourceContainer { RelativeSizeAxes = Axes.Both, - Child = target = new LocalSkinOverrideContainer(secondarySource) + Child = target = new LocalSkinOverrideContainer(secondarySource, new BindableInt()) { RelativeSizeAxes = Axes.Both, } diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index f620c790aa..55d43bb4c8 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -66,7 +66,6 @@ namespace osu.Game.Screens.Play private IAPIProvider api; private SampleChannel sampleRestart; - private SampleChannel sampleComboBreak; protected ScoreProcessor ScoreProcessor { get; private set; } protected DrawableRuleset DrawableRuleset { get; private set; } @@ -108,14 +107,12 @@ namespace osu.Game.Screens.Play return; sampleRestart = audio.Samples.Get(@"Gameplay/restart"); - sampleComboBreak = audio.Samples.Get(@"Gameplay/combobreak"); mouseWheelDisabled = config.GetBindable(OsuSetting.MouseDisableWheel); showStoryboard = config.GetBindable(OsuSetting.ShowStoryboard); ScoreProcessor = DrawableRuleset.CreateScoreProcessor(); ScoreProcessor.Mods.BindTo(Mods); - ScoreProcessor.Combo.BindValueChanged(onComboChange); if (!ScoreProcessor.Mode.Disabled) config.BindWith(OsuSetting.ScoreDisplayMode, ScoreProcessor.Mode); @@ -127,7 +124,7 @@ namespace osu.Game.Screens.Play StoryboardContainer = CreateStoryboardContainer(), new ScalingContainer(ScalingMode.Gameplay) { - Child = new LocalSkinOverrideContainer(working.Skin) + Child = new LocalSkinOverrideContainer(working.Skin, ScoreProcessor.Combo) { RelativeSizeAxes = Axes.Both, Child = DrawableRuleset @@ -267,12 +264,6 @@ namespace osu.Game.Screens.Play private ScheduledDelegate onCompletionEvent; - private void onComboChange(ValueChangedEvent combo) - { - if (combo.NewValue == 0 && combo.OldValue > 20) - sampleComboBreak?.Play(); - } - private void onCompletion() { // Only show the completion screen if the player hasn't failed diff --git a/osu.Game/Skinning/LocalSkinOverrideContainer.cs b/osu.Game/Skinning/LocalSkinOverrideContainer.cs index f1ed14595e..a3606ef00c 100644 --- a/osu.Game/Skinning/LocalSkinOverrideContainer.cs +++ b/osu.Game/Skinning/LocalSkinOverrideContainer.cs @@ -3,6 +3,7 @@ using System; using osu.Framework.Allocation; +using osu.Framework.Audio; using osu.Framework.Audio.Sample; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -23,11 +24,15 @@ namespace osu.Game.Skinning private readonly Bindable beatmapHitsounds = new Bindable(); private readonly ISkin skin; + + private readonly ComboEffects comboEffects; + private ISkinSource fallbackSource; - public LocalSkinOverrideContainer(ISkin skin) + public LocalSkinOverrideContainer(ISkin skin, BindableInt combo) { this.skin = skin; + comboEffects = new ComboEffects(combo); } public Drawable GetDrawableComponent(string componentName) @@ -87,6 +92,9 @@ namespace osu.Game.Skinning beatmapSkins.BindValueChanged(_ => onSourceChanged()); beatmapHitsounds.BindValueChanged(_ => onSourceChanged()); + AudioManager audio = dependencies.Get(); + comboEffects.SampleComboBreak = GetSample(@"Gameplay/combobreak") ?? audio.Samples.Get(@"Gameplay/combobreak"); + return dependencies; } @@ -100,5 +108,21 @@ namespace osu.Game.Skinning if (fallbackSource != null) fallbackSource.SourceChanged -= onSourceChanged; } + + private class ComboEffects + { + public SampleChannel SampleComboBreak; + + public ComboEffects(BindableInt combo) + { + combo.BindValueChanged(onComboChange); + } + + private void onComboChange(ValueChangedEvent combo) + { + if (combo.NewValue == 0 && combo.OldValue > 20) + SampleComboBreak?.Play(); + } + } } } From a22c166575f50867c3761739834c2a490d80863c Mon Sep 17 00:00:00 2001 From: Welsar55 Date: Sat, 29 Jun 2019 11:28:40 -0500 Subject: [PATCH 141/148] Make ComboEffects its own class --- .../Gameplay/TestSceneSkinReloadable.cs | 5 ++- osu.Game/Screens/Play/ComboEffects.cs | 35 +++++++++++++++++++ osu.Game/Screens/Play/Player.cs | 8 +++-- .../Skinning/LocalSkinOverrideContainer.cs | 25 +------------ 4 files changed, 44 insertions(+), 29 deletions(-) create mode 100644 osu.Game/Screens/Play/ComboEffects.cs diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinReloadable.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinReloadable.cs index f03ffea5dc..c7a0df6e9f 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinReloadable.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinReloadable.cs @@ -4,7 +4,6 @@ using System; using NUnit.Framework; using osu.Framework.Audio.Sample; -using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; @@ -29,7 +28,7 @@ namespace osu.Game.Tests.Visual.Gameplay Child = new SkinSourceContainer { RelativeSizeAxes = Axes.Both, - Child = new LocalSkinOverrideContainer(secondarySource, new BindableInt()) + Child = new LocalSkinOverrideContainer(secondarySource) { RelativeSizeAxes = Axes.Both, Child = consumer = new SkinConsumer("test", name => new NamedBox("Default Implementation"), source => true) @@ -54,7 +53,7 @@ namespace osu.Game.Tests.Visual.Gameplay Child = new SkinSourceContainer { RelativeSizeAxes = Axes.Both, - Child = target = new LocalSkinOverrideContainer(secondarySource, new BindableInt()) + Child = target = new LocalSkinOverrideContainer(secondarySource) { RelativeSizeAxes = Axes.Both, } diff --git a/osu.Game/Screens/Play/ComboEffects.cs b/osu.Game/Screens/Play/ComboEffects.cs new file mode 100644 index 0000000000..d752f4a556 --- /dev/null +++ b/osu.Game/Screens/Play/ComboEffects.cs @@ -0,0 +1,35 @@ +// 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.Audio; +using osu.Framework.Audio.Sample; +using osu.Framework.Bindables; +using osu.Framework.Graphics.Containers; +using osu.Game.Rulesets.Scoring; +using osu.Game.Skinning; + +namespace osu.Game.Screens.Play +{ + public class ComboEffects : CompositeDrawable + { + private SampleChannel sampleComboBreak; + + public ComboEffects(ScoreProcessor processor) + { + processor.Combo.BindValueChanged(onComboChange); + } + + private void onComboChange(ValueChangedEvent combo) + { + if (combo.NewValue == 0 && combo.OldValue > 20) + sampleComboBreak?.Play(); + } + + [BackgroundDependencyLoader] + private void load(ISkinSource skin, AudioManager audio) + { + sampleComboBreak = skin.GetSample(@"Gameplay/combobreak") ?? audio.Samples.Get(@"Gameplay/combobreak"); + } + } +} \ No newline at end of file diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 55d43bb4c8..7c4863fbf5 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -124,10 +124,14 @@ namespace osu.Game.Screens.Play StoryboardContainer = CreateStoryboardContainer(), new ScalingContainer(ScalingMode.Gameplay) { - Child = new LocalSkinOverrideContainer(working.Skin, ScoreProcessor.Combo) + Child = new LocalSkinOverrideContainer(working.Skin) { RelativeSizeAxes = Axes.Both, - Child = DrawableRuleset + Children = new Drawable[] + { + DrawableRuleset, + new ComboEffects(ScoreProcessor) + } } }, new BreakOverlay(working.Beatmap.BeatmapInfo.LetterboxInBreaks, ScoreProcessor) diff --git a/osu.Game/Skinning/LocalSkinOverrideContainer.cs b/osu.Game/Skinning/LocalSkinOverrideContainer.cs index a3606ef00c..37f4cc28a2 100644 --- a/osu.Game/Skinning/LocalSkinOverrideContainer.cs +++ b/osu.Game/Skinning/LocalSkinOverrideContainer.cs @@ -3,7 +3,6 @@ using System; using osu.Framework.Allocation; -using osu.Framework.Audio; using osu.Framework.Audio.Sample; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -25,14 +24,11 @@ namespace osu.Game.Skinning private readonly ISkin skin; - private readonly ComboEffects comboEffects; - private ISkinSource fallbackSource; - public LocalSkinOverrideContainer(ISkin skin, BindableInt combo) + public LocalSkinOverrideContainer(ISkin skin) { this.skin = skin; - comboEffects = new ComboEffects(combo); } public Drawable GetDrawableComponent(string componentName) @@ -92,9 +88,6 @@ namespace osu.Game.Skinning beatmapSkins.BindValueChanged(_ => onSourceChanged()); beatmapHitsounds.BindValueChanged(_ => onSourceChanged()); - AudioManager audio = dependencies.Get(); - comboEffects.SampleComboBreak = GetSample(@"Gameplay/combobreak") ?? audio.Samples.Get(@"Gameplay/combobreak"); - return dependencies; } @@ -108,21 +101,5 @@ namespace osu.Game.Skinning if (fallbackSource != null) fallbackSource.SourceChanged -= onSourceChanged; } - - private class ComboEffects - { - public SampleChannel SampleComboBreak; - - public ComboEffects(BindableInt combo) - { - combo.BindValueChanged(onComboChange); - } - - private void onComboChange(ValueChangedEvent combo) - { - if (combo.NewValue == 0 && combo.OldValue > 20) - SampleComboBreak?.Play(); - } - } } } From dbb1369eaffc650371d99af750e1eb566d44e91f Mon Sep 17 00:00:00 2001 From: Welsar55 Date: Sat, 29 Jun 2019 11:54:02 -0500 Subject: [PATCH 142/148] Use resources build 627 --- 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 9dd8c8572e..5f02a75470 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -14,7 +14,7 @@ - + From 5b26ef75b173da1c577fc35f6f48da33b4a3c95a Mon Sep 17 00:00:00 2001 From: Unknown Date: Sun, 30 Jun 2019 12:31:31 +0200 Subject: [PATCH 143/148] allow exiting editor again --- osu.Game/Screens/Edit/Editor.cs | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index 660c1235d1..82d820c925 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -24,11 +24,13 @@ using osu.Game.Screens.Edit.Design; using osuTK.Input; using System.Collections.Generic; using osu.Framework; +using osu.Framework.Input.Bindings; +using osu.Game.Input.Bindings; using osu.Game.Users; namespace osu.Game.Screens.Edit { - public class Editor : OsuScreen + public class Editor : OsuScreen, IKeyBindingHandler { protected override BackgroundScreen CreateBackground() => new BackgroundScreenCustom(@"Backgrounds/bg4"); @@ -206,6 +208,19 @@ namespace osu.Game.Screens.Edit return true; } + public bool OnPressed(GlobalAction action) + { + if (action == GlobalAction.Back) + { + this.Exit(); + return true; + } + + return false; + } + + public bool OnReleased(GlobalAction action) => action == GlobalAction.Back; + public override void OnResuming(IScreen last) { Beatmap.Value.Track?.Stop(); From fa879b4b60603c5c2124fddf2bc1985697dc73a1 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 30 Jun 2019 20:46:51 +0900 Subject: [PATCH 144/148] Add a note explaining why manual handling is required --- osu.Game/Screens/Edit/Editor.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index 82d820c925..89da9ae063 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -212,6 +212,7 @@ namespace osu.Game.Screens.Edit { if (action == GlobalAction.Back) { + // as we don't want to display the back button, manual handling of exit action is required. this.Exit(); return true; } From 60ea3d4e1aeeed90a359ad4155f00c2bafc9c7b3 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 30 Jun 2019 21:58:30 +0900 Subject: [PATCH 145/148] Fix skinning support for combobreak --- .../Objects/JuiceStream.cs | 4 +- .../Beatmaps/ManiaBeatmapConverter.cs | 2 +- .../Legacy/DistanceObjectPatternGenerator.cs | 6 +- .../Legacy/EndTimeObjectPatternGenerator.cs | 6 +- .../Legacy/HitObjectPatternGenerator.cs | 8 +-- .../TestSceneSlider.cs | 10 +-- osu.Game.Rulesets.Osu/Objects/Slider.cs | 10 +-- .../TestSceneInputDrum.cs | 2 +- .../Audio/DrumSampleMapping.cs | 6 +- .../Beatmaps/TaikoBeatmapConverter.cs | 14 ++-- .../Drawables/DrawableTaikoHitObject.cs | 2 +- .../Formats/LegacyBeatmapDecoderTest.cs | 38 +++++----- .../Beatmaps/Formats/OsuJsonDecoderTest.cs | 4 +- osu.Game/Audio/HitSampleInfo.cs | 70 +++++++++++++++++++ osu.Game/Audio/ISampleInfo.cs | 17 +++++ osu.Game/Audio/SampleInfo.cs | 65 +++-------------- .../ControlPoints/SampleControlPoint.cs | 18 ++--- osu.Game/Beatmaps/Formats/LegacyDecoder.cs | 4 +- .../Objects/Drawables/DrawableHitObject.cs | 4 +- osu.Game/Rulesets/Objects/HitObject.cs | 6 +- .../Legacy/Catch/ConvertHitObjectParser.cs | 2 +- .../Objects/Legacy/ConvertHitObjectParser.cs | 32 ++++----- .../Rulesets/Objects/Legacy/ConvertSlider.cs | 2 +- .../Legacy/Mania/ConvertHitObjectParser.cs | 2 +- .../Legacy/Osu/ConvertHitObjectParser.cs | 2 +- .../Legacy/Taiko/ConvertHitObjectParser.cs | 2 +- .../Rulesets/Objects/Types/IHasRepeats.cs | 2 +- osu.Game/Screens/Play/ComboEffects.cs | 31 ++++---- osu.Game/Skinning/SkinnableSound.cs | 16 +++-- 29 files changed, 222 insertions(+), 165 deletions(-) create mode 100644 osu.Game/Audio/HitSampleInfo.cs create mode 100644 osu.Game/Audio/ISampleInfo.cs diff --git a/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs index a9fd34455a..0952e8981a 100644 --- a/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs +++ b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs @@ -46,7 +46,7 @@ namespace osu.Game.Rulesets.Catch.Objects { base.CreateNestedHitObjects(); - var tickSamples = Samples.Select(s => new SampleInfo + var tickSamples = Samples.Select(s => new HitSampleInfo { Bank = s.Bank, Name = @"slidertick", @@ -126,7 +126,7 @@ namespace osu.Game.Rulesets.Catch.Objects public double Distance => Path.Distance; - public List> NodeSamples { get; set; } = new List>(); + public List> NodeSamples { get; set; } = new List>(); public double? LegacyLastTickOffset { get; set; } } diff --git a/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs index 704deba78b..e10602312e 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs @@ -255,7 +255,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps /// /// The time to retrieve the sample info list from. /// - private List sampleInfoListAt(double time) + private List sampleInfoListAt(double time) { var curveData = HitObject as IHasCurve; diff --git a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs index 1b6ff16388..ea418eedb4 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs @@ -364,7 +364,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy break; } - bool isDoubleSample(SampleInfo sample) => sample.Name == SampleInfo.HIT_CLAP || sample.Name == SampleInfo.HIT_FINISH; + bool isDoubleSample(HitSampleInfo sample) => sample.Name == HitSampleInfo.HIT_CLAP || sample.Name == HitSampleInfo.HIT_FINISH; bool canGenerateTwoNotes = !convertType.HasFlag(PatternType.LowProbability); canGenerateTwoNotes &= HitObject.Samples.Any(isDoubleSample) || sampleInfoListAt(HitObject.StartTime).Any(isDoubleSample); @@ -443,7 +443,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy noteCount = 0; noteCount = Math.Min(TotalColumns - 1, noteCount); - bool ignoreHead = !sampleInfoListAt(startTime).Any(s => s.Name == SampleInfo.HIT_WHISTLE || s.Name == SampleInfo.HIT_FINISH || s.Name == SampleInfo.HIT_CLAP); + bool ignoreHead = !sampleInfoListAt(startTime).Any(s => s.Name == HitSampleInfo.HIT_WHISTLE || s.Name == HitSampleInfo.HIT_FINISH || s.Name == HitSampleInfo.HIT_CLAP); var rowPattern = new Pattern(); @@ -472,7 +472,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy /// /// The time to retrieve the sample info list from. /// - private List sampleInfoListAt(double time) + private List sampleInfoListAt(double time) { var curveData = HitObject as IHasCurve; diff --git a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/EndTimeObjectPatternGenerator.cs b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/EndTimeObjectPatternGenerator.cs index 9e95be35fa..b3be08e1f7 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/EndTimeObjectPatternGenerator.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/EndTimeObjectPatternGenerator.cs @@ -35,7 +35,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy switch (TotalColumns) { - case 8 when HitObject.Samples.Any(s => s.Name == SampleInfo.HIT_FINISH) && endTime - HitObject.StartTime < 1000: + case 8 when HitObject.Samples.Any(s => s.Name == HitSampleInfo.HIT_FINISH) && endTime - HitObject.StartTime < 1000: addToPattern(pattern, 0, generateHold); break; @@ -72,9 +72,9 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy }; if (hold.Head.Samples == null) - hold.Head.Samples = new List(); + hold.Head.Samples = new List(); - hold.Head.Samples.Add(new SampleInfo { Name = SampleInfo.HIT_NORMAL }); + hold.Head.Samples.Add(new HitSampleInfo { Name = HitSampleInfo.HIT_NORMAL }); hold.Tail.Samples = HitObject.Samples; diff --git a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/HitObjectPatternGenerator.cs b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/HitObjectPatternGenerator.cs index d13b21183b..decd159ee9 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/HitObjectPatternGenerator.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/HitObjectPatternGenerator.cs @@ -79,9 +79,9 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy if (!convertType.HasFlag(PatternType.KeepSingle)) { - if (HitObject.Samples.Any(s => s.Name == SampleInfo.HIT_FINISH) && TotalColumns != 8) + if (HitObject.Samples.Any(s => s.Name == HitSampleInfo.HIT_FINISH) && TotalColumns != 8) convertType |= PatternType.Mirror; - else if (HitObject.Samples.Any(s => s.Name == SampleInfo.HIT_CLAP)) + else if (HitObject.Samples.Any(s => s.Name == HitSampleInfo.HIT_CLAP)) convertType |= PatternType.Gathered; } } @@ -263,7 +263,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy /// /// Whether this hit object can generate a note in the special column. /// - private bool hasSpecialColumn => HitObject.Samples.Any(s => s.Name == SampleInfo.HIT_CLAP) && HitObject.Samples.Any(s => s.Name == SampleInfo.HIT_FINISH); + private bool hasSpecialColumn => HitObject.Samples.Any(s => s.Name == HitSampleInfo.HIT_CLAP) && HitObject.Samples.Any(s => s.Name == HitSampleInfo.HIT_FINISH); /// /// Generates a random pattern. @@ -364,7 +364,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy break; } - if (HitObject.Samples.Any(s => s.Name == SampleInfo.HIT_CLAP)) + if (HitObject.Samples.Any(s => s.Name == HitSampleInfo.HIT_CLAP)) p2 = 1; return GetRandomNoteCount(p2, p3, p4, p5); diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSlider.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSlider.cs index 1ba6d107be..c5a27205d6 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSlider.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSlider.cs @@ -248,9 +248,9 @@ namespace osu.Game.Rulesets.Osu.Tests private void createCatmull(int repeats = 0) { - var repeatSamples = new List>(); + var repeatSamples = new List>(); for (int i = 0; i < repeats; i++) - repeatSamples.Add(new List()); + repeatSamples.Add(new List()); var slider = new Slider { @@ -270,11 +270,11 @@ namespace osu.Game.Rulesets.Osu.Tests addSlider(slider, 3, 1); } - private List> createEmptySamples(int repeats) + private List> createEmptySamples(int repeats) { - var repeatSamples = new List>(); + var repeatSamples = new List>(); for (int i = 0; i < repeats; i++) - repeatSamples.Add(new List()); + repeatSamples.Add(new List()); return repeatSamples; } diff --git a/osu.Game.Rulesets.Osu/Objects/Slider.cs b/osu.Game.Rulesets.Osu/Objects/Slider.cs index a8aec005d1..a4638c31f2 100644 --- a/osu.Game.Rulesets.Osu/Objects/Slider.cs +++ b/osu.Game.Rulesets.Osu/Objects/Slider.cs @@ -99,7 +99,7 @@ namespace osu.Game.Rulesets.Osu.Objects /// internal float LazyTravelDistance; - public List> NodeSamples { get; set; } = new List>(); + public List> NodeSamples { get; set; } = new List>(); private int repeatCount; @@ -157,12 +157,12 @@ namespace osu.Game.Rulesets.Osu.Objects foreach (var e in SliderEventGenerator.Generate(StartTime, SpanDuration, Velocity, TickDistance, Path.Distance, this.SpanCount(), LegacyLastTickOffset)) { - var firstSample = Samples.Find(s => s.Name == SampleInfo.HIT_NORMAL) + var firstSample = Samples.Find(s => s.Name == HitSampleInfo.HIT_NORMAL) ?? Samples.FirstOrDefault(); // TODO: remove this when guaranteed sort is present for samples (https://github.com/ppy/osu/issues/1933) - var sampleList = new List(); + var sampleList = new List(); if (firstSample != null) - sampleList.Add(new SampleInfo + sampleList.Add(new HitSampleInfo { Bank = firstSample.Bank, Volume = firstSample.Volume, @@ -225,7 +225,7 @@ namespace osu.Game.Rulesets.Osu.Objects } } - private List getNodeSamples(int nodeIndex) => + private List getNodeSamples(int nodeIndex) => nodeIndex < NodeSamples.Count ? NodeSamples[nodeIndex] : Samples; public override Judgement CreateJudgement() => new OsuJudgement(); diff --git a/osu.Game.Rulesets.Taiko.Tests/TestSceneInputDrum.cs b/osu.Game.Rulesets.Taiko.Tests/TestSceneInputDrum.cs index 02300a5dde..8c1b0c4c62 100644 --- a/osu.Game.Rulesets.Taiko.Tests/TestSceneInputDrum.cs +++ b/osu.Game.Rulesets.Taiko.Tests/TestSceneInputDrum.cs @@ -22,7 +22,7 @@ namespace osu.Game.Rulesets.Taiko.Tests { typeof(InputDrum), typeof(DrumSampleMapping), - typeof(SampleInfo), + typeof(HitSampleInfo), typeof(SampleControlPoint) }; diff --git a/osu.Game.Rulesets.Taiko/Audio/DrumSampleMapping.cs b/osu.Game.Rulesets.Taiko/Audio/DrumSampleMapping.cs index d7fa661e8a..ad2596931d 100644 --- a/osu.Game.Rulesets.Taiko/Audio/DrumSampleMapping.cs +++ b/osu.Game.Rulesets.Taiko/Audio/DrumSampleMapping.cs @@ -29,7 +29,7 @@ namespace osu.Game.Rulesets.Taiko.Audio foreach (var s in samplePoints) { var centre = s.GetSampleInfo(); - var rim = s.GetSampleInfo(SampleInfo.HIT_CLAP); + var rim = s.GetSampleInfo(HitSampleInfo.HIT_CLAP); // todo: this is ugly centre.Namespace = "taiko"; @@ -43,9 +43,9 @@ namespace osu.Game.Rulesets.Taiko.Audio } } - private SkinnableSound addSound(SampleInfo sampleInfo) + private SkinnableSound addSound(HitSampleInfo hitSampleInfo) { - var drawable = new SkinnableSound(sampleInfo); + var drawable = new SkinnableSound(hitSampleInfo); Sounds.Add(drawable); return drawable; } diff --git a/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs b/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs index f8672037cd..f0cf8d9c7d 100644 --- a/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs +++ b/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs @@ -79,9 +79,9 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps var curveData = obj as IHasCurve; // Old osu! used hit sounding to determine various hit type information - List samples = obj.Samples; + List samples = obj.Samples; - bool strong = samples.Any(s => s.Name == SampleInfo.HIT_FINISH); + bool strong = samples.Any(s => s.Name == HitSampleInfo.HIT_FINISH); if (distanceData != null) { @@ -117,15 +117,15 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps if (!isForCurrentRuleset && tickSpacing > 0 && osuDuration < 2 * speedAdjustedBeatLength) { - List> allSamples = curveData != null ? curveData.NodeSamples : new List>(new[] { samples }); + List> allSamples = curveData != null ? curveData.NodeSamples : new List>(new[] { samples }); int i = 0; for (double j = obj.StartTime; j <= obj.StartTime + taikoDuration + tickSpacing / 8; j += tickSpacing) { - List currentSamples = allSamples[i]; - bool isRim = currentSamples.Any(s => s.Name == SampleInfo.HIT_CLAP || s.Name == SampleInfo.HIT_WHISTLE); - strong = currentSamples.Any(s => s.Name == SampleInfo.HIT_FINISH); + List currentSamples = allSamples[i]; + bool isRim = currentSamples.Any(s => s.Name == HitSampleInfo.HIT_CLAP || s.Name == HitSampleInfo.HIT_WHISTLE); + strong = currentSamples.Any(s => s.Name == HitSampleInfo.HIT_FINISH); if (isRim) { @@ -175,7 +175,7 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps } else { - bool isRim = samples.Any(s => s.Name == SampleInfo.HIT_CLAP || s.Name == SampleInfo.HIT_WHISTLE); + bool isRim = samples.Any(s => s.Name == HitSampleInfo.HIT_CLAP || s.Name == HitSampleInfo.HIT_WHISTLE); if (isRim) { diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs index 119940536e..bd45b52d7b 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs @@ -122,7 +122,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables } // Normal and clap samples are handled by the drum - protected override IEnumerable GetSamples() => HitObject.Samples.Where(s => s.Name != SampleInfo.HIT_NORMAL && s.Name != SampleInfo.HIT_CLAP); + protected override IEnumerable GetSamples() => HitObject.Samples.Where(s => s.Name != HitSampleInfo.HIT_NORMAL && s.Name != HitSampleInfo.HIT_CLAP); protected override string SampleNamespace => "Taiko"; diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs index 5fd5fe342d..d087251e7e 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs @@ -354,14 +354,14 @@ namespace osu.Game.Tests.Beatmaps.Formats Assert.IsNotNull(curveData); Assert.AreEqual(new Vector2(192, 168), positionData.Position); Assert.AreEqual(956, hitObjects[0].StartTime); - Assert.IsTrue(hitObjects[0].Samples.Any(s => s.Name == SampleInfo.HIT_NORMAL)); + Assert.IsTrue(hitObjects[0].Samples.Any(s => s.Name == HitSampleInfo.HIT_NORMAL)); positionData = hitObjects[1] as IHasPosition; Assert.IsNotNull(positionData); Assert.AreEqual(new Vector2(304, 56), positionData.Position); Assert.AreEqual(1285, hitObjects[1].StartTime); - Assert.IsTrue(hitObjects[1].Samples.Any(s => s.Name == SampleInfo.HIT_CLAP)); + Assert.IsTrue(hitObjects[1].Samples.Any(s => s.Name == HitSampleInfo.HIT_CLAP)); } } @@ -384,7 +384,7 @@ namespace osu.Game.Tests.Beatmaps.Formats Assert.AreEqual("soft-hitnormal8", getTestableSampleInfo(hitObjects[4]).LookupNames.First()); } - SampleInfo getTestableSampleInfo(HitObject hitObject) => hitObject.SampleControlPoint.ApplyTo(hitObject.Samples[0]); + HitSampleInfo getTestableSampleInfo(HitObject hitObject) => hitObject.SampleControlPoint.ApplyTo(hitObject.Samples[0]); } [Test] @@ -402,7 +402,7 @@ namespace osu.Game.Tests.Beatmaps.Formats Assert.AreEqual("normal-hitnormal3", getTestableSampleInfo(hitObjects[2]).LookupNames.First()); } - SampleInfo getTestableSampleInfo(HitObject hitObject) => hitObject.SampleControlPoint.ApplyTo(hitObject.Samples[0]); + HitSampleInfo getTestableSampleInfo(HitObject hitObject) => hitObject.SampleControlPoint.ApplyTo(hitObject.Samples[0]); } [Test] @@ -422,7 +422,7 @@ namespace osu.Game.Tests.Beatmaps.Formats Assert.AreEqual(70, getTestableSampleInfo(hitObjects[3]).Volume); } - SampleInfo getTestableSampleInfo(HitObject hitObject) => hitObject.SampleControlPoint.ApplyTo(hitObject.Samples[0]); + HitSampleInfo getTestableSampleInfo(HitObject hitObject) => hitObject.SampleControlPoint.ApplyTo(hitObject.Samples[0]); } [Test] @@ -438,34 +438,34 @@ namespace osu.Game.Tests.Beatmaps.Formats var slider1 = (ConvertSlider)hitObjects[0]; Assert.AreEqual(1, slider1.NodeSamples[0].Count); - Assert.AreEqual(SampleInfo.HIT_NORMAL, slider1.NodeSamples[0][0].Name); + Assert.AreEqual(HitSampleInfo.HIT_NORMAL, slider1.NodeSamples[0][0].Name); Assert.AreEqual(1, slider1.NodeSamples[1].Count); - Assert.AreEqual(SampleInfo.HIT_NORMAL, slider1.NodeSamples[1][0].Name); + Assert.AreEqual(HitSampleInfo.HIT_NORMAL, slider1.NodeSamples[1][0].Name); Assert.AreEqual(1, slider1.NodeSamples[2].Count); - Assert.AreEqual(SampleInfo.HIT_NORMAL, slider1.NodeSamples[2][0].Name); + Assert.AreEqual(HitSampleInfo.HIT_NORMAL, slider1.NodeSamples[2][0].Name); var slider2 = (ConvertSlider)hitObjects[1]; Assert.AreEqual(2, slider2.NodeSamples[0].Count); - Assert.AreEqual(SampleInfo.HIT_NORMAL, slider2.NodeSamples[0][0].Name); - Assert.AreEqual(SampleInfo.HIT_CLAP, slider2.NodeSamples[0][1].Name); + Assert.AreEqual(HitSampleInfo.HIT_NORMAL, slider2.NodeSamples[0][0].Name); + Assert.AreEqual(HitSampleInfo.HIT_CLAP, slider2.NodeSamples[0][1].Name); Assert.AreEqual(2, slider2.NodeSamples[1].Count); - Assert.AreEqual(SampleInfo.HIT_NORMAL, slider2.NodeSamples[1][0].Name); - Assert.AreEqual(SampleInfo.HIT_CLAP, slider2.NodeSamples[1][1].Name); + Assert.AreEqual(HitSampleInfo.HIT_NORMAL, slider2.NodeSamples[1][0].Name); + Assert.AreEqual(HitSampleInfo.HIT_CLAP, slider2.NodeSamples[1][1].Name); Assert.AreEqual(2, slider2.NodeSamples[2].Count); - Assert.AreEqual(SampleInfo.HIT_NORMAL, slider2.NodeSamples[2][0].Name); - Assert.AreEqual(SampleInfo.HIT_CLAP, slider2.NodeSamples[2][1].Name); + Assert.AreEqual(HitSampleInfo.HIT_NORMAL, slider2.NodeSamples[2][0].Name); + Assert.AreEqual(HitSampleInfo.HIT_CLAP, slider2.NodeSamples[2][1].Name); var slider3 = (ConvertSlider)hitObjects[2]; Assert.AreEqual(2, slider3.NodeSamples[0].Count); - Assert.AreEqual(SampleInfo.HIT_NORMAL, slider3.NodeSamples[0][0].Name); - Assert.AreEqual(SampleInfo.HIT_WHISTLE, slider3.NodeSamples[0][1].Name); + Assert.AreEqual(HitSampleInfo.HIT_NORMAL, slider3.NodeSamples[0][0].Name); + Assert.AreEqual(HitSampleInfo.HIT_WHISTLE, slider3.NodeSamples[0][1].Name); Assert.AreEqual(1, slider3.NodeSamples[1].Count); - Assert.AreEqual(SampleInfo.HIT_NORMAL, slider3.NodeSamples[1][0].Name); + Assert.AreEqual(HitSampleInfo.HIT_NORMAL, slider3.NodeSamples[1][0].Name); Assert.AreEqual(2, slider3.NodeSamples[2].Count); - Assert.AreEqual(SampleInfo.HIT_NORMAL, slider3.NodeSamples[2][0].Name); - Assert.AreEqual(SampleInfo.HIT_CLAP, slider3.NodeSamples[2][1].Name); + Assert.AreEqual(HitSampleInfo.HIT_NORMAL, slider3.NodeSamples[2][0].Name); + Assert.AreEqual(HitSampleInfo.HIT_CLAP, slider3.NodeSamples[2][1].Name); } } diff --git a/osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs index 39b7735a55..a725c58462 100644 --- a/osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs @@ -101,14 +101,14 @@ namespace osu.Game.Tests.Beatmaps.Formats Assert.IsNotNull(curveData); Assert.AreEqual(new Vector2(192, 168), positionData.Position); Assert.AreEqual(956, beatmap.HitObjects[0].StartTime); - Assert.IsTrue(beatmap.HitObjects[0].Samples.Any(s => s.Name == SampleInfo.HIT_NORMAL)); + Assert.IsTrue(beatmap.HitObjects[0].Samples.Any(s => s.Name == HitSampleInfo.HIT_NORMAL)); positionData = beatmap.HitObjects[1] as IHasPosition; Assert.IsNotNull(positionData); Assert.AreEqual(new Vector2(304, 56), positionData.Position); Assert.AreEqual(1285, beatmap.HitObjects[1].StartTime); - Assert.IsTrue(beatmap.HitObjects[1].Samples.Any(s => s.Name == SampleInfo.HIT_CLAP)); + Assert.IsTrue(beatmap.HitObjects[1].Samples.Any(s => s.Name == HitSampleInfo.HIT_CLAP)); } [TestCase(normal)] diff --git a/osu.Game/Audio/HitSampleInfo.cs b/osu.Game/Audio/HitSampleInfo.cs new file mode 100644 index 0000000000..23a74d3fa6 --- /dev/null +++ b/osu.Game/Audio/HitSampleInfo.cs @@ -0,0 +1,70 @@ +// 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; + +namespace osu.Game.Audio +{ + /// + /// Describes a gameplay hit sample. + /// + [Serializable] + public class HitSampleInfo : ISampleInfo + { + public const string HIT_WHISTLE = @"hitwhistle"; + public const string HIT_FINISH = @"hitfinish"; + public const string HIT_NORMAL = @"hitnormal"; + public const string HIT_CLAP = @"hitclap"; + + /// + /// An optional ruleset namespace. + /// + public string Namespace; + + /// + /// The bank to load the sample from. + /// + public string Bank; + + /// + /// The name of the sample to load. + /// + public string Name; + + /// + /// An optional suffix to provide priority lookup. Falls back to non-suffixed . + /// + public string Suffix; + + /// + /// The sample volume. + /// + public int Volume { get; set; } + + /// + /// Retrieve all possible filenames that can be used as a source, returned in order of preference (highest first). + /// + public virtual IEnumerable LookupNames + { + get + { + if (!string.IsNullOrEmpty(Namespace)) + { + if (!string.IsNullOrEmpty(Suffix)) + yield return $"{Namespace}/{Bank}-{Name}{Suffix}"; + + yield return $"{Namespace}/{Bank}-{Name}"; + } + + // check non-namespace as a fallback even when we have a namespace + if (!string.IsNullOrEmpty(Suffix)) + yield return $"{Bank}-{Name}{Suffix}"; + + yield return $"{Bank}-{Name}"; + } + } + + public HitSampleInfo Clone() => (HitSampleInfo)MemberwiseClone(); + } +} diff --git a/osu.Game/Audio/ISampleInfo.cs b/osu.Game/Audio/ISampleInfo.cs new file mode 100644 index 0000000000..4f81d37e78 --- /dev/null +++ b/osu.Game/Audio/ISampleInfo.cs @@ -0,0 +1,17 @@ +// 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; + +namespace osu.Game.Audio +{ + public interface ISampleInfo + { + /// + /// Retrieve all possible filenames that can be used as a source, returned in order of preference (highest first). + /// + IEnumerable LookupNames { get; } + + int Volume { get; } + } +} diff --git a/osu.Game/Audio/SampleInfo.cs b/osu.Game/Audio/SampleInfo.cs index 5bc6dce60b..66c07209f3 100644 --- a/osu.Game/Audio/SampleInfo.cs +++ b/osu.Game/Audio/SampleInfo.cs @@ -1,67 +1,24 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// 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; namespace osu.Game.Audio { - [Serializable] - public class SampleInfo + /// + /// Describes a gameplay sample. + /// + public class SampleInfo : ISampleInfo { - public const string HIT_WHISTLE = @"hitwhistle"; - public const string HIT_FINISH = @"hitfinish"; - public const string HIT_NORMAL = @"hitnormal"; - public const string HIT_CLAP = @"hitclap"; + private readonly string sampleName; - /// - /// An optional ruleset namespace. - /// - public string Namespace; - - /// - /// The bank to load the sample from. - /// - public string Bank; - - /// - /// The name of the sample to load. - /// - public string Name; - - /// - /// An optional suffix to provide priority lookup. Falls back to non-suffixed . - /// - public string Suffix; - - /// - /// The sample volume. - /// - public int Volume; - - /// - /// Retrieve all possible filenames that can be used as a source, returned in order of preference (highest first). - /// - public virtual IEnumerable LookupNames + public SampleInfo(string sampleName) { - get - { - if (!string.IsNullOrEmpty(Namespace)) - { - if (!string.IsNullOrEmpty(Suffix)) - yield return $"{Namespace}/{Bank}-{Name}{Suffix}"; - - yield return $"{Namespace}/{Bank}-{Name}"; - } - - // check non-namespace as a fallback even when we have a namespace - if (!string.IsNullOrEmpty(Suffix)) - yield return $"{Bank}-{Name}{Suffix}"; - - yield return $"{Bank}-{Name}"; - } + this.sampleName = sampleName; } - public SampleInfo Clone() => (SampleInfo)MemberwiseClone(); + public IEnumerable LookupNames => new[] { sampleName }; + + public int Volume { get; set; } = 100; } } diff --git a/osu.Game/Beatmaps/ControlPoints/SampleControlPoint.cs b/osu.Game/Beatmaps/ControlPoints/SampleControlPoint.cs index 4c45bef862..7bc7a9056d 100644 --- a/osu.Game/Beatmaps/ControlPoints/SampleControlPoint.cs +++ b/osu.Game/Beatmaps/ControlPoints/SampleControlPoint.cs @@ -24,8 +24,8 @@ namespace osu.Game.Beatmaps.ControlPoints /// Create a SampleInfo based on the sample settings in this control point. /// /// The name of the same. - /// A populated . - public SampleInfo GetSampleInfo(string sampleName = SampleInfo.HIT_NORMAL) => new SampleInfo + /// A populated . + public HitSampleInfo GetSampleInfo(string sampleName = HitSampleInfo.HIT_NORMAL) => new HitSampleInfo { Bank = SampleBank, Name = sampleName, @@ -33,15 +33,15 @@ namespace osu.Game.Beatmaps.ControlPoints }; /// - /// Applies and to a if necessary, returning the modified . + /// Applies and to a if necessary, returning the modified . /// - /// The . This will not be modified. - /// The modified . This does not share a reference with . - public virtual SampleInfo ApplyTo(SampleInfo sampleInfo) + /// The . This will not be modified. + /// The modified . This does not share a reference with . + public virtual HitSampleInfo ApplyTo(HitSampleInfo hitSampleInfo) { - var newSampleInfo = sampleInfo.Clone(); - newSampleInfo.Bank = sampleInfo.Bank ?? SampleBank; - newSampleInfo.Volume = sampleInfo.Volume > 0 ? sampleInfo.Volume : SampleVolume; + var newSampleInfo = hitSampleInfo.Clone(); + newSampleInfo.Bank = hitSampleInfo.Bank ?? SampleBank; + newSampleInfo.Volume = hitSampleInfo.Volume > 0 ? hitSampleInfo.Volume : SampleVolume; return newSampleInfo; } diff --git a/osu.Game/Beatmaps/Formats/LegacyDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyDecoder.cs index 7b7e0e7101..7999c82761 100644 --- a/osu.Game/Beatmaps/Formats/LegacyDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyDecoder.cs @@ -193,9 +193,9 @@ namespace osu.Game.Beatmaps.Formats { public int CustomSampleBank; - public override SampleInfo ApplyTo(SampleInfo sampleInfo) + public override HitSampleInfo ApplyTo(HitSampleInfo hitSampleInfo) { - var baseInfo = base.ApplyTo(sampleInfo); + var baseInfo = base.ApplyTo(hitSampleInfo); if (string.IsNullOrEmpty(baseInfo.Suffix) && CustomSampleBank > 1) baseInfo.Suffix = CustomSampleBank.ToString(); diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index 35c3a0e5e4..1f6ca4dd73 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -33,7 +33,7 @@ namespace osu.Game.Rulesets.Objects.Drawables protected SkinnableSound Samples; - protected virtual IEnumerable GetSamples() => HitObject.Samples; + protected virtual IEnumerable GetSamples() => HitObject.Samples; private readonly Lazy> nestedHitObjects = new Lazy>(); public IEnumerable NestedHitObjects => nestedHitObjects.IsValueCreated ? nestedHitObjects.Value : Enumerable.Empty(); @@ -104,7 +104,7 @@ namespace osu.Game.Rulesets.Objects.Drawables var samples = GetSamples().ToArray(); - if (samples.Any()) + if (samples.Length > 0) { if (HitObject.SampleControlPoint == null) throw new ArgumentNullException(nameof(HitObject.SampleControlPoint), $"{nameof(HitObject)}s must always have an attached {nameof(HitObject.SampleControlPoint)}." diff --git a/osu.Game/Rulesets/Objects/HitObject.cs b/osu.Game/Rulesets/Objects/HitObject.cs index cede2e50d0..bf04963b76 100644 --- a/osu.Game/Rulesets/Objects/HitObject.cs +++ b/osu.Game/Rulesets/Objects/HitObject.cs @@ -29,7 +29,7 @@ namespace osu.Game.Rulesets.Objects /// public virtual double StartTime { get; set; } - private List samples; + private List samples; /// /// The samples to be played when this hit object is hit. @@ -38,9 +38,9 @@ namespace osu.Game.Rulesets.Objects /// and can be treated as the default samples for the hit object. /// /// - public List Samples + public List Samples { - get => samples ?? (samples = new List()); + get => samples ?? (samples = new List()); set => samples = value; } diff --git a/osu.Game/Rulesets/Objects/Legacy/Catch/ConvertHitObjectParser.cs b/osu.Game/Rulesets/Objects/Legacy/Catch/ConvertHitObjectParser.cs index 48f637dfe8..6e79d0b766 100644 --- a/osu.Game/Rulesets/Objects/Legacy/Catch/ConvertHitObjectParser.cs +++ b/osu.Game/Rulesets/Objects/Legacy/Catch/ConvertHitObjectParser.cs @@ -37,7 +37,7 @@ namespace osu.Game.Rulesets.Objects.Legacy.Catch }; } - protected override HitObject CreateSlider(Vector2 position, bool newCombo, int comboOffset, Vector2[] controlPoints, double length, PathType pathType, int repeatCount, List> nodeSamples) + protected override HitObject CreateSlider(Vector2 position, bool newCombo, int comboOffset, Vector2[] controlPoints, double length, PathType pathType, int repeatCount, List> nodeSamples) { newCombo |= forceNewCombo; comboOffset += extraComboOffset; diff --git a/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs b/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs index c14f3b6a42..f5b1cbcebf 100644 --- a/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs +++ b/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs @@ -180,7 +180,7 @@ namespace osu.Game.Rulesets.Objects.Legacy } // Generate the final per-node samples - var nodeSamples = new List>(nodes); + var nodeSamples = new List>(nodes); for (int i = 0; i < nodes; i++) nodeSamples.Add(convertSoundType(nodeSoundTypes[i], nodeBankInfos[i])); @@ -291,7 +291,7 @@ namespace osu.Game.Rulesets.Objects.Legacy /// The slider repeat count. /// The samples to be played when the slider nodes are hit. This includes the head and tail of the slider. /// The hit object. - protected abstract HitObject CreateSlider(Vector2 position, bool newCombo, int comboOffset, Vector2[] controlPoints, double length, PathType pathType, int repeatCount, List> nodeSamples); + protected abstract HitObject CreateSlider(Vector2 position, bool newCombo, int comboOffset, Vector2[] controlPoints, double length, PathType pathType, int repeatCount, List> nodeSamples); /// /// Creates a legacy Spinner-type hit object. @@ -312,14 +312,14 @@ namespace osu.Game.Rulesets.Objects.Legacy /// The hold end time. protected abstract HitObject CreateHold(Vector2 position, bool newCombo, int comboOffset, double endTime); - private List convertSoundType(LegacySoundType type, SampleBankInfo bankInfo) + private List convertSoundType(LegacySoundType type, SampleBankInfo bankInfo) { // Todo: This should return the normal SampleInfos if the specified sample file isn't found, but that's a pretty edge-case scenario if (!string.IsNullOrEmpty(bankInfo.Filename)) { - return new List + return new List { - new FileSampleInfo + new FileHitSampleInfo { Filename = bankInfo.Filename, Volume = bankInfo.Volume @@ -327,12 +327,12 @@ namespace osu.Game.Rulesets.Objects.Legacy }; } - var soundTypes = new List + var soundTypes = new List { - new LegacySampleInfo + new LegacyHitSampleInfo { Bank = bankInfo.Normal, - Name = SampleInfo.HIT_NORMAL, + Name = HitSampleInfo.HIT_NORMAL, Volume = bankInfo.Volume, CustomSampleBank = bankInfo.CustomSampleBank } @@ -340,10 +340,10 @@ namespace osu.Game.Rulesets.Objects.Legacy if (type.HasFlag(LegacySoundType.Finish)) { - soundTypes.Add(new LegacySampleInfo + soundTypes.Add(new LegacyHitSampleInfo { Bank = bankInfo.Add, - Name = SampleInfo.HIT_FINISH, + Name = HitSampleInfo.HIT_FINISH, Volume = bankInfo.Volume, CustomSampleBank = bankInfo.CustomSampleBank }); @@ -351,10 +351,10 @@ namespace osu.Game.Rulesets.Objects.Legacy if (type.HasFlag(LegacySoundType.Whistle)) { - soundTypes.Add(new LegacySampleInfo + soundTypes.Add(new LegacyHitSampleInfo { Bank = bankInfo.Add, - Name = SampleInfo.HIT_WHISTLE, + Name = HitSampleInfo.HIT_WHISTLE, Volume = bankInfo.Volume, CustomSampleBank = bankInfo.CustomSampleBank }); @@ -362,10 +362,10 @@ namespace osu.Game.Rulesets.Objects.Legacy if (type.HasFlag(LegacySoundType.Clap)) { - soundTypes.Add(new LegacySampleInfo + soundTypes.Add(new LegacyHitSampleInfo { Bank = bankInfo.Add, - Name = SampleInfo.HIT_CLAP, + Name = HitSampleInfo.HIT_CLAP, Volume = bankInfo.Volume, CustomSampleBank = bankInfo.CustomSampleBank }); @@ -387,7 +387,7 @@ namespace osu.Game.Rulesets.Objects.Legacy public SampleBankInfo Clone() => (SampleBankInfo)MemberwiseClone(); } - private class LegacySampleInfo : SampleInfo + private class LegacyHitSampleInfo : HitSampleInfo { public int CustomSampleBank { @@ -399,7 +399,7 @@ namespace osu.Game.Rulesets.Objects.Legacy } } - private class FileSampleInfo : SampleInfo + private class FileHitSampleInfo : HitSampleInfo { public string Filename; diff --git a/osu.Game/Rulesets/Objects/Legacy/ConvertSlider.cs b/osu.Game/Rulesets/Objects/Legacy/ConvertSlider.cs index bb1a5e200d..ff6b9be8b5 100644 --- a/osu.Game/Rulesets/Objects/Legacy/ConvertSlider.cs +++ b/osu.Game/Rulesets/Objects/Legacy/ConvertSlider.cs @@ -23,7 +23,7 @@ namespace osu.Game.Rulesets.Objects.Legacy public double Distance => Path.Distance; - public List> NodeSamples { get; set; } + public List> NodeSamples { get; set; } public int RepeatCount { get; set; } public double EndTime => StartTime + this.SpanCount() * Distance / Velocity; diff --git a/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertHitObjectParser.cs b/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertHitObjectParser.cs index 8a3e232e60..b20a027e78 100644 --- a/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertHitObjectParser.cs +++ b/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertHitObjectParser.cs @@ -26,7 +26,7 @@ namespace osu.Game.Rulesets.Objects.Legacy.Mania }; } - protected override HitObject CreateSlider(Vector2 position, bool newCombo, int comboOffset, Vector2[] controlPoints, double length, PathType pathType, int repeatCount, List> nodeSamples) + protected override HitObject CreateSlider(Vector2 position, bool newCombo, int comboOffset, Vector2[] controlPoints, double length, PathType pathType, int repeatCount, List> nodeSamples) { return new ConvertSlider { diff --git a/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertHitObjectParser.cs b/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertHitObjectParser.cs index b98de32bd0..0a4e38df02 100644 --- a/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertHitObjectParser.cs +++ b/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertHitObjectParser.cs @@ -38,7 +38,7 @@ namespace osu.Game.Rulesets.Objects.Legacy.Osu }; } - protected override HitObject CreateSlider(Vector2 position, bool newCombo, int comboOffset, Vector2[] controlPoints, double length, PathType pathType, int repeatCount, List> nodeSamples) + protected override HitObject CreateSlider(Vector2 position, bool newCombo, int comboOffset, Vector2[] controlPoints, double length, PathType pathType, int repeatCount, List> nodeSamples) { newCombo |= forceNewCombo; comboOffset += extraComboOffset; diff --git a/osu.Game/Rulesets/Objects/Legacy/Taiko/ConvertHitObjectParser.cs b/osu.Game/Rulesets/Objects/Legacy/Taiko/ConvertHitObjectParser.cs index bab21b31ad..7c1514c1eb 100644 --- a/osu.Game/Rulesets/Objects/Legacy/Taiko/ConvertHitObjectParser.cs +++ b/osu.Game/Rulesets/Objects/Legacy/Taiko/ConvertHitObjectParser.cs @@ -23,7 +23,7 @@ namespace osu.Game.Rulesets.Objects.Legacy.Taiko return new ConvertHit(); } - protected override HitObject CreateSlider(Vector2 position, bool newCombo, int comboOffset, Vector2[] controlPoints, double length, PathType pathType, int repeatCount, List> nodeSamples) + protected override HitObject CreateSlider(Vector2 position, bool newCombo, int comboOffset, Vector2[] controlPoints, double length, PathType pathType, int repeatCount, List> nodeSamples) { return new ConvertSlider { diff --git a/osu.Game/Rulesets/Objects/Types/IHasRepeats.cs b/osu.Game/Rulesets/Objects/Types/IHasRepeats.cs index 8be95c063d..697adeda98 100644 --- a/osu.Game/Rulesets/Objects/Types/IHasRepeats.cs +++ b/osu.Game/Rulesets/Objects/Types/IHasRepeats.cs @@ -25,7 +25,7 @@ namespace osu.Game.Rulesets.Objects.Types /// n-1: The last repeat.
/// n: The last node. ///
- List> NodeSamples { get; } + List> NodeSamples { get; } } public static class HasRepeatsExtensions diff --git a/osu.Game/Screens/Play/ComboEffects.cs b/osu.Game/Screens/Play/ComboEffects.cs index d752f4a556..1c4ac921f0 100644 --- a/osu.Game/Screens/Play/ComboEffects.cs +++ b/osu.Game/Screens/Play/ComboEffects.cs @@ -2,10 +2,9 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Allocation; -using osu.Framework.Audio; -using osu.Framework.Audio.Sample; using osu.Framework.Bindables; using osu.Framework.Graphics.Containers; +using osu.Game.Audio; using osu.Game.Rulesets.Scoring; using osu.Game.Skinning; @@ -13,23 +12,31 @@ namespace osu.Game.Screens.Play { public class ComboEffects : CompositeDrawable { - private SampleChannel sampleComboBreak; + private readonly ScoreProcessor processor; + + private SkinnableSound comboBreakSample; public ComboEffects(ScoreProcessor processor) { - processor.Combo.BindValueChanged(onComboChange); + this.processor = processor; + } + + [BackgroundDependencyLoader] + private void load() + { + InternalChild = comboBreakSample = new SkinnableSound(new SampleInfo("combobreak")); + } + + protected override void LoadComplete() + { + base.LoadComplete(); + processor.Combo.BindValueChanged(onComboChange, true); } private void onComboChange(ValueChangedEvent combo) { if (combo.NewValue == 0 && combo.OldValue > 20) - sampleComboBreak?.Play(); - } - - [BackgroundDependencyLoader] - private void load(ISkinSource skin, AudioManager audio) - { - sampleComboBreak = skin.GetSample(@"Gameplay/combobreak") ?? audio.Samples.Get(@"Gameplay/combobreak"); + comboBreakSample?.Play(); } } -} \ No newline at end of file +} diff --git a/osu.Game/Skinning/SkinnableSound.cs b/osu.Game/Skinning/SkinnableSound.cs index e88e088f5e..8e2b5cec98 100644 --- a/osu.Game/Skinning/SkinnableSound.cs +++ b/osu.Game/Skinning/SkinnableSound.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System; +using System.Collections.Generic; using System.Linq; using osu.Framework.Allocation; using osu.Framework.Audio; @@ -13,14 +14,19 @@ namespace osu.Game.Skinning { public class SkinnableSound : SkinReloadableDrawable { - private readonly SampleInfo[] samples; + private readonly ISampleInfo[] hitSamples; private SampleChannel[] channels; private AudioManager audio; - public SkinnableSound(params SampleInfo[] samples) + public SkinnableSound(IEnumerable hitSamples) { - this.samples = samples; + this.hitSamples = hitSamples.ToArray(); + } + + public SkinnableSound(ISampleInfo hitSamples) + { + this.hitSamples = new[] { hitSamples }; } [BackgroundDependencyLoader] @@ -35,7 +41,7 @@ namespace osu.Game.Skinning protected override void SkinChanged(ISkinSource skin, bool allowFallback) { - channels = samples.Select(s => + channels = hitSamples.Select(s => { var ch = loadChannel(s, skin.GetSample); if (ch == null && allowFallback) @@ -44,7 +50,7 @@ namespace osu.Game.Skinning }).Where(c => c != null).ToArray(); } - private SampleChannel loadChannel(SampleInfo info, Func getSampleFunction) + private SampleChannel loadChannel(ISampleInfo info, Func getSampleFunction) { foreach (var lookup in info.LookupNames) { From 489ca7b45786c762b1fea01cdfa60fb5b3e3b40b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 30 Jun 2019 22:26:49 +0900 Subject: [PATCH 146/148] Update resources in ios props --- osu.iOS.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.iOS.props b/osu.iOS.props index ce8b62cc3f..a8013914af 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -104,7 +104,7 @@ - + From f42ded343779ab6d168538892d0dc77d6a3ee00b Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Sun, 30 Jun 2019 18:27:47 +0300 Subject: [PATCH 147/148] Move to DrawableOsuHitObject --- osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs | 2 ++ osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs | 2 -- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs index 10b37af957..eb5b6aab36 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs @@ -18,6 +18,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables { private readonly ShakeContainer shakeContainer; + public override bool HandlePositionalInput => true; + protected DrawableOsuHitObject(OsuHitObject hitObject) : base(hitObject) { diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index cc1a1f370f..1f6ca4dd73 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -81,8 +81,6 @@ namespace osu.Game.Rulesets.Objects.Drawables public override bool RemoveCompletedTransforms => false; protected override bool RequiresChildrenUpdate => true; - public override bool HandlePositionalInput => true; - public override bool IsPresent => base.IsPresent || (State.Value == ArmedState.Idle && Clock?.CurrentTime >= LifetimeStart); public readonly Bindable State = new Bindable(); From d11b799571df4d06973b4955994b94ad0e520da9 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Sun, 30 Jun 2019 18:28:20 +0300 Subject: [PATCH 148/148] Add explaining comment --- osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs index eb5b6aab36..f372cb65ce 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs @@ -18,6 +18,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables { private readonly ShakeContainer shakeContainer; + // Must be set to update IsHovered as it's used in relax mdo to detect osu hit objects. public override bool HandlePositionalInput => true; protected DrawableOsuHitObject(OsuHitObject hitObject)