From 812d33f850c1f83351f8a6c17376e11f178f7c22 Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Tue, 1 Oct 2019 08:09:01 +0300 Subject: [PATCH 001/434] Add ExpandNumberPiece configuration with OsuLegacySkinTransformer --- osu.Game.Rulesets.Osu/Skinning/OsuLegacySkinTransformer.cs | 4 ++++ osu.Game.Rulesets.Osu/Skinning/OsuSkinConfiguration.cs | 1 + 2 files changed, 5 insertions(+) diff --git a/osu.Game.Rulesets.Osu/Skinning/OsuLegacySkinTransformer.cs b/osu.Game.Rulesets.Osu/Skinning/OsuLegacySkinTransformer.cs index 479c250eab..c9ed313593 100644 --- a/osu.Game.Rulesets.Osu/Skinning/OsuLegacySkinTransformer.cs +++ b/osu.Game.Rulesets.Osu/Skinning/OsuLegacySkinTransformer.cs @@ -123,6 +123,10 @@ namespace osu.Game.Rulesets.Osu.Skinning return SkinUtils.As(new BindableFloat(legacy_circle_radius)); break; + + case OsuSkinConfiguration.ExpandNumberPiece: + string legacyVersion = source.GetConfig("Version")?.Value ?? "1"; + return SkinUtils.As(new BindableBool(double.TryParse(legacyVersion, out double version) && version < 2.0)); } break; diff --git a/osu.Game.Rulesets.Osu/Skinning/OsuSkinConfiguration.cs b/osu.Game.Rulesets.Osu/Skinning/OsuSkinConfiguration.cs index 98219cafe8..85a7f5b0cd 100644 --- a/osu.Game.Rulesets.Osu/Skinning/OsuSkinConfiguration.cs +++ b/osu.Game.Rulesets.Osu/Skinning/OsuSkinConfiguration.cs @@ -7,6 +7,7 @@ namespace osu.Game.Rulesets.Osu.Skinning { HitCirclePrefix, HitCircleOverlap, + ExpandNumberPiece, SliderBorderSize, SliderPathRadius, AllowSliderBallTint, From 6ba1bc381c07d68d7af35d3e631dbe6cac7b9b93 Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Tue, 1 Oct 2019 08:14:15 +0300 Subject: [PATCH 002/434] Add version value to the DefaultSkinConfiguration dictionary --- osu.Game/Skinning/DefaultSkinConfiguration.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Skinning/DefaultSkinConfiguration.cs b/osu.Game/Skinning/DefaultSkinConfiguration.cs index f52fac6077..481360beb9 100644 --- a/osu.Game/Skinning/DefaultSkinConfiguration.cs +++ b/osu.Game/Skinning/DefaultSkinConfiguration.cs @@ -19,6 +19,8 @@ namespace osu.Game.Skinning new Color4(204, 102, 0, 255), new Color4(121, 9, 13, 255) }); + + ConfigDictionary.Add(@"Version", "latest"); } } } From 9e314cd664991c1836d0cb258405b6652e5f4a03 Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Tue, 1 Oct 2019 08:15:48 +0300 Subject: [PATCH 003/434] Add expand number piece bindable to hit circle --- .../Objects/Drawables/DrawableHitCircle.cs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs index bb227d76df..15c768fff9 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs @@ -10,9 +10,10 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Input.Bindings; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Osu.Objects.Drawables.Pieces; +using osu.Game.Rulesets.Osu.Skinning; using osu.Game.Rulesets.Scoring; -using osuTK; using osu.Game.Skinning; +using osuTK; namespace osu.Game.Rulesets.Osu.Objects.Drawables { @@ -20,6 +21,10 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables { public ApproachCircle ApproachCircle { get; } + public IBindable ExpandNumberPiece => expandNumberPiece; + + private readonly BindableBool expandNumberPiece = new BindableBool(); + private readonly IBindable positionBindable = new Bindable(); private readonly IBindable stackHeightBindable = new Bindable(); private readonly IBindable scaleBindable = new Bindable(); @@ -106,6 +111,13 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables } } + protected override void ApplySkin(ISkinSource skin, bool allowFallback) + { + base.ApplySkin(skin, allowFallback); + + expandNumberPiece.Value = skin.GetConfig(OsuSkinConfiguration.ExpandNumberPiece).Value; + } + protected override void CheckForResult(bool userTriggered, double timeOffset) { Debug.Assert(HitObject.HitWindows != null); From 5aa85968c232927d42a35344437a5f3376fe3321 Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Tue, 1 Oct 2019 08:23:41 +0300 Subject: [PATCH 004/434] Expand number piece for old skins in legacy circle pieces --- .../Skinning/LegacyMainCirclePiece.cs | 40 ++++++++++++++----- 1 file changed, 31 insertions(+), 9 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Skinning/LegacyMainCirclePiece.cs b/osu.Game.Rulesets.Osu/Skinning/LegacyMainCirclePiece.cs index 93ae0371df..d93d0506c3 100644 --- a/osu.Game.Rulesets.Osu/Skinning/LegacyMainCirclePiece.cs +++ b/osu.Game.Rulesets.Osu/Skinning/LegacyMainCirclePiece.cs @@ -10,9 +10,12 @@ using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Osu.Objects; +using osu.Game.Rulesets.Osu.Objects.Drawables; using osu.Game.Skinning; using osuTK; using osuTK.Graphics; +using System.Collections.Generic; +using System.Linq; namespace osu.Game.Rulesets.Osu.Skinning { @@ -23,17 +26,24 @@ namespace osu.Game.Rulesets.Osu.Skinning Size = new Vector2(OsuHitObject.OBJECT_RADIUS * 2); } + private Sprite hitCircleSprite; + private SkinnableSpriteText hitCircleText; + + private List scalables; + private readonly IBindable state = new Bindable(); private readonly Bindable accentColour = new Bindable(); private readonly IBindable indexInCurrentCombo = new Bindable(); + private readonly IBindable expandNumberPiece = new BindableBool(); + + [Resolved] + private DrawableHitObject drawableObject { get; set; } [BackgroundDependencyLoader] - private void load(DrawableHitObject drawableObject, ISkinSource skin) + private void load(ISkinSource skin) { OsuHitObject osuObject = (OsuHitObject)drawableObject.HitObject; - - Sprite hitCircleSprite; - SkinnableSpriteText hitCircleText; + DrawableHitCircle drawableCircle = (DrawableHitCircle)drawableObject; InternalChildren = new Drawable[] { @@ -58,13 +68,25 @@ namespace osu.Game.Rulesets.Osu.Skinning }; state.BindTo(drawableObject.State); - state.BindValueChanged(updateState, true); - accentColour.BindTo(drawableObject.AccentColour); - accentColour.BindValueChanged(colour => hitCircleSprite.Colour = colour.NewValue, true); - indexInCurrentCombo.BindTo(osuObject.IndexInCurrentComboBindable); + expandNumberPiece.BindTo(drawableCircle.ExpandNumberPiece); + } + + protected override void LoadComplete() + { + base.LoadComplete(); + + state.BindValueChanged(updateState, true); + accentColour.BindValueChanged(colour => hitCircleSprite.Colour = colour.NewValue, true); indexInCurrentCombo.BindValueChanged(index => hitCircleText.Text = (index.NewValue + 1).ToString(), true); + expandNumberPiece.BindValueChanged(expand => + { + scalables = InternalChildren.ToList(); + + if (!expand.NewValue) + scalables.Remove(hitCircleText); + }, true); } private void updateState(ValueChangedEvent state) @@ -75,7 +97,7 @@ namespace osu.Game.Rulesets.Osu.Skinning { case ArmedState.Hit: this.FadeOut(legacy_fade_duration, Easing.Out); - this.ScaleTo(1.4f, legacy_fade_duration, Easing.Out); + scalables.ForEach(d => d.ScaleTo(1.4f, legacy_fade_duration, Easing.Out)); break; } } From ef8f9aa276f9359b1c1f81df3644f52917b7dbfb Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Tue, 1 Oct 2019 08:43:03 +0300 Subject: [PATCH 005/434] Fix possible nullref exception --- osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs index 15c768fff9..bd4cb1f112 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs @@ -115,7 +115,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables { base.ApplySkin(skin, allowFallback); - expandNumberPiece.Value = skin.GetConfig(OsuSkinConfiguration.ExpandNumberPiece).Value; + expandNumberPiece.Value = skin.GetConfig(OsuSkinConfiguration.ExpandNumberPiece)?.Value ?? false; } protected override void CheckForResult(bool userTriggered, double timeOffset) From 957bbee3e4eb4569310eacf11c59f7e167795efe Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Thu, 3 Oct 2019 05:58:20 +0300 Subject: [PATCH 006/434] Scale pieces individually and use skin source directly --- .../Objects/Drawables/DrawableHitCircle.cs | 11 ------- .../Skinning/LegacyMainCirclePiece.cs | 30 ++++++++----------- 2 files changed, 13 insertions(+), 28 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs index bd4cb1f112..c37535521d 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs @@ -21,10 +21,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables { public ApproachCircle ApproachCircle { get; } - public IBindable ExpandNumberPiece => expandNumberPiece; - - private readonly BindableBool expandNumberPiece = new BindableBool(); - private readonly IBindable positionBindable = new Bindable(); private readonly IBindable stackHeightBindable = new Bindable(); private readonly IBindable scaleBindable = new Bindable(); @@ -111,13 +107,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables } } - protected override void ApplySkin(ISkinSource skin, bool allowFallback) - { - base.ApplySkin(skin, allowFallback); - - expandNumberPiece.Value = skin.GetConfig(OsuSkinConfiguration.ExpandNumberPiece)?.Value ?? false; - } - protected override void CheckForResult(bool userTriggered, double timeOffset) { Debug.Assert(HitObject.HitWindows != null); diff --git a/osu.Game.Rulesets.Osu/Skinning/LegacyMainCirclePiece.cs b/osu.Game.Rulesets.Osu/Skinning/LegacyMainCirclePiece.cs index d93d0506c3..8ba21d9f89 100644 --- a/osu.Game.Rulesets.Osu/Skinning/LegacyMainCirclePiece.cs +++ b/osu.Game.Rulesets.Osu/Skinning/LegacyMainCirclePiece.cs @@ -14,8 +14,6 @@ using osu.Game.Rulesets.Osu.Objects.Drawables; using osu.Game.Skinning; using osuTK; using osuTK.Graphics; -using System.Collections.Generic; -using System.Linq; namespace osu.Game.Rulesets.Osu.Skinning { @@ -26,21 +24,21 @@ namespace osu.Game.Rulesets.Osu.Skinning Size = new Vector2(OsuHitObject.OBJECT_RADIUS * 2); } - private Sprite hitCircleSprite; + private Sprite hitCircleSprite, hitCircleOverlay; private SkinnableSpriteText hitCircleText; - private List scalables; - private readonly IBindable state = new Bindable(); private readonly Bindable accentColour = new Bindable(); private readonly IBindable indexInCurrentCombo = new Bindable(); - private readonly IBindable expandNumberPiece = new BindableBool(); [Resolved] private DrawableHitObject drawableObject { get; set; } + [Resolved] + private ISkinSource skin { get; set; } + [BackgroundDependencyLoader] - private void load(ISkinSource skin) + private void load() { OsuHitObject osuObject = (OsuHitObject)drawableObject.HitObject; DrawableHitCircle drawableCircle = (DrawableHitCircle)drawableObject; @@ -59,7 +57,7 @@ namespace osu.Game.Rulesets.Osu.Skinning Font = OsuFont.Numeric.With(size: 40), UseFullGlyphHeight = false, }, confineMode: ConfineMode.NoScaling), - new Sprite + hitCircleOverlay = new Sprite { Texture = skin.GetTexture("hitcircleoverlay"), Anchor = Anchor.Centre, @@ -70,7 +68,6 @@ namespace osu.Game.Rulesets.Osu.Skinning state.BindTo(drawableObject.State); accentColour.BindTo(drawableObject.AccentColour); indexInCurrentCombo.BindTo(osuObject.IndexInCurrentComboBindable); - expandNumberPiece.BindTo(drawableCircle.ExpandNumberPiece); } protected override void LoadComplete() @@ -80,13 +77,6 @@ namespace osu.Game.Rulesets.Osu.Skinning state.BindValueChanged(updateState, true); accentColour.BindValueChanged(colour => hitCircleSprite.Colour = colour.NewValue, true); indexInCurrentCombo.BindValueChanged(index => hitCircleText.Text = (index.NewValue + 1).ToString(), true); - expandNumberPiece.BindValueChanged(expand => - { - scalables = InternalChildren.ToList(); - - if (!expand.NewValue) - scalables.Remove(hitCircleText); - }, true); } private void updateState(ValueChangedEvent state) @@ -97,7 +87,13 @@ namespace osu.Game.Rulesets.Osu.Skinning { case ArmedState.Hit: this.FadeOut(legacy_fade_duration, Easing.Out); - scalables.ForEach(d => d.ScaleTo(1.4f, legacy_fade_duration, Easing.Out)); + + hitCircleSprite.ScaleTo(1.4f, legacy_fade_duration, Easing.Out); + hitCircleOverlay.ScaleTo(1.4f, legacy_fade_duration, Easing.Out); + + if (skin.GetConfig(OsuSkinConfiguration.ExpandNumberPiece).Value) + hitCircleText.ScaleTo(1.4f, legacy_fade_duration, Easing.Out); + break; } } From 023c4d64d811e1abc49655ba37b766568117333f Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Thu, 3 Oct 2019 06:00:22 +0300 Subject: [PATCH 007/434] Remove redundant using directive --- osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs index c37535521d..4579e5cb59 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs @@ -10,7 +10,6 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Input.Bindings; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Osu.Objects.Drawables.Pieces; -using osu.Game.Rulesets.Osu.Skinning; using osu.Game.Rulesets.Scoring; using osu.Game.Skinning; using osuTK; From a73f6c6a5a3dfc12518a85442732a4c2469d0535 Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Thu, 3 Oct 2019 06:46:13 +0300 Subject: [PATCH 008/434] Specify version of osu!classic skin --- osu.Game/Skinning/DefaultLegacySkin.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Skinning/DefaultLegacySkin.cs b/osu.Game/Skinning/DefaultLegacySkin.cs index 4b6eea6b6e..8370b5e8ee 100644 --- a/osu.Game/Skinning/DefaultLegacySkin.cs +++ b/osu.Game/Skinning/DefaultLegacySkin.cs @@ -20,6 +20,8 @@ namespace osu.Game.Skinning new Color4(18, 124, 255, 255), new Color4(242, 24, 57, 255), }); + + Configuration.ConfigDictionary["Version"] = "2"; } public static SkinInfo Info { get; } = new SkinInfo From 89075c5655618c70b2d05f4943a11dca18350b89 Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Thu, 3 Oct 2019 06:48:07 +0300 Subject: [PATCH 009/434] Set version of not-configured skins to latest only --- osu.Game/Skinning/DefaultSkinConfiguration.cs | 9 +++++++-- osu.Game/Skinning/LegacySkin.cs | 2 +- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/osu.Game/Skinning/DefaultSkinConfiguration.cs b/osu.Game/Skinning/DefaultSkinConfiguration.cs index 481360beb9..1d22ce8c1d 100644 --- a/osu.Game/Skinning/DefaultSkinConfiguration.cs +++ b/osu.Game/Skinning/DefaultSkinConfiguration.cs @@ -10,7 +10,7 @@ namespace osu.Game.Skinning /// public class DefaultSkinConfiguration : SkinConfiguration { - public DefaultSkinConfiguration() + public DefaultSkinConfiguration(string version) { ComboColours.AddRange(new[] { @@ -20,7 +20,12 @@ namespace osu.Game.Skinning new Color4(121, 9, 13, 255) }); - ConfigDictionary.Add(@"Version", "latest"); + ConfigDictionary["Version"] = version; + } + + public DefaultSkinConfiguration() + : this("1") + { } } } diff --git a/osu.Game/Skinning/LegacySkin.cs b/osu.Game/Skinning/LegacySkin.cs index 0b1076be01..0f80aade1e 100644 --- a/osu.Game/Skinning/LegacySkin.cs +++ b/osu.Game/Skinning/LegacySkin.cs @@ -38,7 +38,7 @@ namespace osu.Game.Skinning using (StreamReader reader = new StreamReader(stream)) Configuration = new LegacySkinDecoder().Decode(reader); else - Configuration = new DefaultSkinConfiguration(); + Configuration = new DefaultSkinConfiguration("latest"); if (storage != null) { From 3fe56117005f375a8dcbea223cd48a0365d0af85 Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Thu, 3 Oct 2019 06:48:59 +0300 Subject: [PATCH 010/434] Retrieve numeric version value from legacy configuration --- .../Skinning/OsuLegacySkinTransformer.cs | 3 +-- osu.Game/Skinning/LegacySkin.cs | 13 +++++++++++++ osu.Game/Skinning/LegacySkinConfiguration.cs | 10 ++++++++++ 3 files changed, 24 insertions(+), 2 deletions(-) create mode 100644 osu.Game/Skinning/LegacySkinConfiguration.cs diff --git a/osu.Game.Rulesets.Osu/Skinning/OsuLegacySkinTransformer.cs b/osu.Game.Rulesets.Osu/Skinning/OsuLegacySkinTransformer.cs index c9ed313593..539b3d7d34 100644 --- a/osu.Game.Rulesets.Osu/Skinning/OsuLegacySkinTransformer.cs +++ b/osu.Game.Rulesets.Osu/Skinning/OsuLegacySkinTransformer.cs @@ -125,8 +125,7 @@ namespace osu.Game.Rulesets.Osu.Skinning break; case OsuSkinConfiguration.ExpandNumberPiece: - string legacyVersion = source.GetConfig("Version")?.Value ?? "1"; - return SkinUtils.As(new BindableBool(double.TryParse(legacyVersion, out double version) && version < 2.0)); + return SkinUtils.As(new BindableBool(source.GetConfig(LegacySkinConfiguration.LegacyVersion).Value < 2.0)); } break; diff --git a/osu.Game/Skinning/LegacySkin.cs b/osu.Game/Skinning/LegacySkin.cs index 0f80aade1e..90265ec066 100644 --- a/osu.Game/Skinning/LegacySkin.cs +++ b/osu.Game/Skinning/LegacySkin.cs @@ -70,6 +70,19 @@ namespace osu.Game.Skinning case GlobalSkinColour colour: return SkinUtils.As(getCustomColour(colour.ToString())); + case LegacySkinConfiguration legacy: + switch (legacy) + { + case LegacySkinConfiguration.LegacyVersion: + var versionString = GetConfig("Version").Value; + if (!double.TryParse(versionString, out double version)) + version = versionString == "latest" ? 2.7 : 1; + + return SkinUtils.As(new BindableDouble(version)); + } + + break; + case SkinCustomColourLookup customColour: return SkinUtils.As(getCustomColour(customColour.Lookup.ToString())); diff --git a/osu.Game/Skinning/LegacySkinConfiguration.cs b/osu.Game/Skinning/LegacySkinConfiguration.cs new file mode 100644 index 0000000000..2e75313d0c --- /dev/null +++ b/osu.Game/Skinning/LegacySkinConfiguration.cs @@ -0,0 +1,10 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +namespace osu.Game.Skinning +{ + public enum LegacySkinConfiguration + { + LegacyVersion, + } +} From dabc22403009b8d976ce4971c309ca4fea709cea Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Thu, 3 Oct 2019 06:49:32 +0300 Subject: [PATCH 011/434] Fix hit circle positioning --- osu.Game.Rulesets.Osu/Skinning/LegacyMainCirclePiece.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Skinning/LegacyMainCirclePiece.cs b/osu.Game.Rulesets.Osu/Skinning/LegacyMainCirclePiece.cs index 8ba21d9f89..705828131d 100644 --- a/osu.Game.Rulesets.Osu/Skinning/LegacyMainCirclePiece.cs +++ b/osu.Game.Rulesets.Osu/Skinning/LegacyMainCirclePiece.cs @@ -56,7 +56,11 @@ namespace osu.Game.Rulesets.Osu.Skinning { Font = OsuFont.Numeric.With(size: 40), UseFullGlyphHeight = false, - }, confineMode: ConfineMode.NoScaling), + }, confineMode: ConfineMode.NoScaling) + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + }, hitCircleOverlay = new Sprite { Texture = skin.GetTexture("hitcircleoverlay"), From 2d7acef0800903e3d6f52ce98de724576f107bbf Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Thu, 3 Oct 2019 11:06:38 +0300 Subject: [PATCH 012/434] Fix CI issues --- osu.Game.Rulesets.Osu/Skinning/LegacyMainCirclePiece.cs | 4 +--- osu.Game.Rulesets.Osu/Skinning/OsuLegacySkinTransformer.cs | 3 ++- osu.Game/Skinning/LegacySkin.cs | 4 ++-- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Skinning/LegacyMainCirclePiece.cs b/osu.Game.Rulesets.Osu/Skinning/LegacyMainCirclePiece.cs index 705828131d..89c8ea9d6c 100644 --- a/osu.Game.Rulesets.Osu/Skinning/LegacyMainCirclePiece.cs +++ b/osu.Game.Rulesets.Osu/Skinning/LegacyMainCirclePiece.cs @@ -10,7 +10,6 @@ using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Osu.Objects; -using osu.Game.Rulesets.Osu.Objects.Drawables; using osu.Game.Skinning; using osuTK; using osuTK.Graphics; @@ -41,7 +40,6 @@ namespace osu.Game.Rulesets.Osu.Skinning private void load() { OsuHitObject osuObject = (OsuHitObject)drawableObject.HitObject; - DrawableHitCircle drawableCircle = (DrawableHitCircle)drawableObject; InternalChildren = new Drawable[] { @@ -95,7 +93,7 @@ namespace osu.Game.Rulesets.Osu.Skinning hitCircleSprite.ScaleTo(1.4f, legacy_fade_duration, Easing.Out); hitCircleOverlay.ScaleTo(1.4f, legacy_fade_duration, Easing.Out); - if (skin.GetConfig(OsuSkinConfiguration.ExpandNumberPiece).Value) + if (skin.GetConfig(OsuSkinConfiguration.ExpandNumberPiece)?.Value ?? true) hitCircleText.ScaleTo(1.4f, legacy_fade_duration, Easing.Out); break; diff --git a/osu.Game.Rulesets.Osu/Skinning/OsuLegacySkinTransformer.cs b/osu.Game.Rulesets.Osu/Skinning/OsuLegacySkinTransformer.cs index 539b3d7d34..1303e2cace 100644 --- a/osu.Game.Rulesets.Osu/Skinning/OsuLegacySkinTransformer.cs +++ b/osu.Game.Rulesets.Osu/Skinning/OsuLegacySkinTransformer.cs @@ -125,7 +125,8 @@ namespace osu.Game.Rulesets.Osu.Skinning break; case OsuSkinConfiguration.ExpandNumberPiece: - return SkinUtils.As(new BindableBool(source.GetConfig(LegacySkinConfiguration.LegacyVersion).Value < 2.0)); + double legacyVersion = source.GetConfig(LegacySkinConfiguration.LegacyVersion)?.Value ?? 1.0; + return SkinUtils.As(new BindableBool(legacyVersion < 2.0)); } break; diff --git a/osu.Game/Skinning/LegacySkin.cs b/osu.Game/Skinning/LegacySkin.cs index 90265ec066..af5309eecd 100644 --- a/osu.Game/Skinning/LegacySkin.cs +++ b/osu.Game/Skinning/LegacySkin.cs @@ -74,9 +74,9 @@ namespace osu.Game.Skinning switch (legacy) { case LegacySkinConfiguration.LegacyVersion: - var versionString = GetConfig("Version").Value; + var versionString = GetConfig("Version")?.Value ?? "1"; if (!double.TryParse(versionString, out double version)) - version = versionString == "latest" ? 2.7 : 1; + version = versionString == "latest" ? 2.7 : 1.0; return SkinUtils.As(new BindableDouble(version)); } From f54eb448fa245c2fde8e5b23b3f526f25560122a Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Tue, 15 Oct 2019 22:00:34 +0300 Subject: [PATCH 013/434] Revert skin legacy version changes --- osu.Game/Skinning/DefaultLegacySkin.cs | 2 -- osu.Game/Skinning/DefaultSkinConfiguration.cs | 9 +-------- osu.Game/Skinning/LegacySkin.cs | 15 +-------------- osu.Game/Skinning/LegacySkinConfiguration.cs | 10 ---------- 4 files changed, 2 insertions(+), 34 deletions(-) delete mode 100644 osu.Game/Skinning/LegacySkinConfiguration.cs diff --git a/osu.Game/Skinning/DefaultLegacySkin.cs b/osu.Game/Skinning/DefaultLegacySkin.cs index 8370b5e8ee..4b6eea6b6e 100644 --- a/osu.Game/Skinning/DefaultLegacySkin.cs +++ b/osu.Game/Skinning/DefaultLegacySkin.cs @@ -20,8 +20,6 @@ namespace osu.Game.Skinning new Color4(18, 124, 255, 255), new Color4(242, 24, 57, 255), }); - - Configuration.ConfigDictionary["Version"] = "2"; } public static SkinInfo Info { get; } = new SkinInfo diff --git a/osu.Game/Skinning/DefaultSkinConfiguration.cs b/osu.Game/Skinning/DefaultSkinConfiguration.cs index 8c87e1d054..cd5975edac 100644 --- a/osu.Game/Skinning/DefaultSkinConfiguration.cs +++ b/osu.Game/Skinning/DefaultSkinConfiguration.cs @@ -10,7 +10,7 @@ namespace osu.Game.Skinning /// public class DefaultSkinConfiguration : SkinConfiguration { - public DefaultSkinConfiguration(string version) + public DefaultSkinConfiguration() { ComboColours.AddRange(new[] { @@ -19,13 +19,6 @@ namespace osu.Game.Skinning new Color4(18, 124, 255, 255), new Color4(242, 24, 57, 255), }); - - ConfigDictionary["Version"] = version; - } - - public DefaultSkinConfiguration() - : this("1") - { } } } diff --git a/osu.Game/Skinning/LegacySkin.cs b/osu.Game/Skinning/LegacySkin.cs index cbebdd9bd6..fea15458e4 100644 --- a/osu.Game/Skinning/LegacySkin.cs +++ b/osu.Game/Skinning/LegacySkin.cs @@ -39,7 +39,7 @@ namespace osu.Game.Skinning using (LineBufferedReader reader = new LineBufferedReader(stream)) Configuration = new LegacySkinDecoder().Decode(reader); else - Configuration = new DefaultSkinConfiguration("latest"); + Configuration = new DefaultSkinConfiguration(); if (storage != null) { @@ -71,19 +71,6 @@ namespace osu.Game.Skinning case GlobalSkinColour colour: return SkinUtils.As(getCustomColour(colour.ToString())); - case LegacySkinConfiguration legacy: - switch (legacy) - { - case LegacySkinConfiguration.LegacyVersion: - var versionString = GetConfig("Version")?.Value ?? "1"; - if (!double.TryParse(versionString, out double version)) - version = versionString == "latest" ? 2.7 : 1.0; - - return SkinUtils.As(new BindableDouble(version)); - } - - break; - case SkinCustomColourLookup customColour: return SkinUtils.As(getCustomColour(customColour.Lookup.ToString())); diff --git a/osu.Game/Skinning/LegacySkinConfiguration.cs b/osu.Game/Skinning/LegacySkinConfiguration.cs deleted file mode 100644 index 2e75313d0c..0000000000 --- a/osu.Game/Skinning/LegacySkinConfiguration.cs +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -namespace osu.Game.Skinning -{ - public enum LegacySkinConfiguration - { - LegacyVersion, - } -} From 9dcbef49d300458c897f3f40c77c9dddaf3bb5b4 Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Tue, 15 Oct 2019 22:28:50 +0300 Subject: [PATCH 014/434] Resolve DHO inside load() --- osu.Game.Rulesets.Osu/Skinning/LegacyMainCirclePiece.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Skinning/LegacyMainCirclePiece.cs b/osu.Game.Rulesets.Osu/Skinning/LegacyMainCirclePiece.cs index 89c8ea9d6c..f9e6400b18 100644 --- a/osu.Game.Rulesets.Osu/Skinning/LegacyMainCirclePiece.cs +++ b/osu.Game.Rulesets.Osu/Skinning/LegacyMainCirclePiece.cs @@ -30,14 +30,11 @@ namespace osu.Game.Rulesets.Osu.Skinning private readonly Bindable accentColour = new Bindable(); private readonly IBindable indexInCurrentCombo = new Bindable(); - [Resolved] - private DrawableHitObject drawableObject { get; set; } - [Resolved] private ISkinSource skin { get; set; } [BackgroundDependencyLoader] - private void load() + private void load(DrawableHitObject drawableObject) { OsuHitObject osuObject = (OsuHitObject)drawableObject.HitObject; From d6fb2283385c9cec966d01dcf684cb402ab1e7e1 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Thu, 12 Dec 2019 16:02:53 +0300 Subject: [PATCH 015/434] Update version retrieval logic in-line with new implementation --- osu.Game.Rulesets.Osu/Skinning/OsuLegacySkinTransformer.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Skinning/OsuLegacySkinTransformer.cs b/osu.Game.Rulesets.Osu/Skinning/OsuLegacySkinTransformer.cs index 1303e2cace..1c716b3ee9 100644 --- a/osu.Game.Rulesets.Osu/Skinning/OsuLegacySkinTransformer.cs +++ b/osu.Game.Rulesets.Osu/Skinning/OsuLegacySkinTransformer.cs @@ -9,6 +9,7 @@ using osu.Framework.Graphics.Textures; using osu.Game.Audio; using osu.Game.Skinning; using osuTK; +using static osu.Game.Skinning.LegacySkinConfiguration; namespace osu.Game.Rulesets.Osu.Skinning { @@ -125,8 +126,8 @@ namespace osu.Game.Rulesets.Osu.Skinning break; case OsuSkinConfiguration.ExpandNumberPiece: - double legacyVersion = source.GetConfig(LegacySkinConfiguration.LegacyVersion)?.Value ?? 1.0; - return SkinUtils.As(new BindableBool(legacyVersion < 2.0)); + decimal legacyVersion = source.GetConfig(LegacySetting.Version)?.Value ?? 1.0m; + return SkinUtils.As(new BindableBool(legacyVersion < 2.0m)); } break; From 41ca084fa591253d6406253c76cef99cc1196305 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Tue, 17 Dec 2019 22:00:21 +0300 Subject: [PATCH 016/434] Simplify expand number check --- osu.Game.Rulesets.Osu/Skinning/OsuLegacySkinTransformer.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Skinning/OsuLegacySkinTransformer.cs b/osu.Game.Rulesets.Osu/Skinning/OsuLegacySkinTransformer.cs index 1c716b3ee9..5926332ea5 100644 --- a/osu.Game.Rulesets.Osu/Skinning/OsuLegacySkinTransformer.cs +++ b/osu.Game.Rulesets.Osu/Skinning/OsuLegacySkinTransformer.cs @@ -126,8 +126,8 @@ namespace osu.Game.Rulesets.Osu.Skinning break; case OsuSkinConfiguration.ExpandNumberPiece: - decimal legacyVersion = source.GetConfig(LegacySetting.Version)?.Value ?? 1.0m; - return SkinUtils.As(new BindableBool(legacyVersion < 2.0m)); + bool expand = source.GetConfig(LegacySetting.Version)?.Value < 2.0m; + return SkinUtils.As(new BindableBool(expand)); } break; From 121ce2c3df5b95f48fec3546caee2e0d257b1d8b Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Thu, 19 Dec 2019 14:44:52 +0300 Subject: [PATCH 017/434] Fix checking for expand incorrectly --- osu.Game.Rulesets.Osu/Skinning/OsuLegacySkinTransformer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Skinning/OsuLegacySkinTransformer.cs b/osu.Game.Rulesets.Osu/Skinning/OsuLegacySkinTransformer.cs index 5926332ea5..3e41dc08d7 100644 --- a/osu.Game.Rulesets.Osu/Skinning/OsuLegacySkinTransformer.cs +++ b/osu.Game.Rulesets.Osu/Skinning/OsuLegacySkinTransformer.cs @@ -126,7 +126,7 @@ namespace osu.Game.Rulesets.Osu.Skinning break; case OsuSkinConfiguration.ExpandNumberPiece: - bool expand = source.GetConfig(LegacySetting.Version)?.Value < 2.0m; + bool expand = !(source.GetConfig(LegacySetting.Version)?.Value >= 2.0m); return SkinUtils.As(new BindableBool(expand)); } From de4c22c70923b2a9434eadc993eda361bd1c6bd6 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 8 Jul 2020 17:58:09 +0300 Subject: [PATCH 018/434] Implement news api request --- .../Online/API/Requests/GetNewsRequest.cs | 27 +++++++++++++++++++ .../Online/API/Requests/GetNewsResponse.cs | 15 +++++++++++ 2 files changed, 42 insertions(+) create mode 100644 osu.Game/Online/API/Requests/GetNewsRequest.cs create mode 100644 osu.Game/Online/API/Requests/GetNewsResponse.cs diff --git a/osu.Game/Online/API/Requests/GetNewsRequest.cs b/osu.Game/Online/API/Requests/GetNewsRequest.cs new file mode 100644 index 0000000000..36d9dc0652 --- /dev/null +++ b/osu.Game/Online/API/Requests/GetNewsRequest.cs @@ -0,0 +1,27 @@ +// 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.IO.Network; +using osu.Game.Extensions; + +namespace osu.Game.Online.API.Requests +{ + public class GetNewsRequest : APIRequest + { + private readonly Cursor cursor; + + public GetNewsRequest(Cursor cursor = null) + { + this.cursor = cursor; + } + + protected override WebRequest CreateWebRequest() + { + var req = base.CreateWebRequest(); + req.AddCursor(cursor); + return req; + } + + protected override string Target => "news"; + } +} diff --git a/osu.Game/Online/API/Requests/GetNewsResponse.cs b/osu.Game/Online/API/Requests/GetNewsResponse.cs new file mode 100644 index 0000000000..835289a51d --- /dev/null +++ b/osu.Game/Online/API/Requests/GetNewsResponse.cs @@ -0,0 +1,15 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Collections.Generic; +using Newtonsoft.Json; +using osu.Game.Online.API.Requests.Responses; + +namespace osu.Game.Online.API.Requests +{ + public class GetNewsResponse : ResponseWithCursor + { + [JsonProperty("news_posts")] + public IEnumerable NewsPosts; + } +} From 49d998c8db2f7a6be17d3fd25898015e5a3920b8 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 8 Jul 2020 18:24:13 +0300 Subject: [PATCH 019/434] Refactor NewsOverlay to use displays logic --- .../Visual/Online/TestSceneNewsOverlay.cs | 4 +- osu.Game/Overlays/DashboardOverlay.cs | 8 +-- osu.Game/Overlays/NewsOverlay.cs | 70 +++++++++++++------ 3 files changed, 53 insertions(+), 29 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneNewsOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneNewsOverlay.cs index d47c972564..0b3ede5d13 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneNewsOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneNewsOverlay.cs @@ -22,12 +22,12 @@ namespace osu.Game.Tests.Visual.Online AddStep(@"Show front page", () => news.ShowFrontPage()); AddStep(@"Custom article", () => news.Current.Value = "Test Article 101"); - AddStep(@"Article covers", () => news.LoadAndShowContent(new NewsCoverTest())); + AddStep(@"Article covers", () => news.LoadDisplay(new NewsCoverTest())); } private class TestNewsOverlay : NewsOverlay { - public new void LoadAndShowContent(NewsContent content) => base.LoadAndShowContent(content); + public void LoadDisplay(NewsContent content) => base.LoadDisplay(content); } private class NewsCoverTest : NewsContent diff --git a/osu.Game/Overlays/DashboardOverlay.cs b/osu.Game/Overlays/DashboardOverlay.cs index a72c3f4fa5..e3a4b0e152 100644 --- a/osu.Game/Overlays/DashboardOverlay.cs +++ b/osu.Game/Overlays/DashboardOverlay.cs @@ -19,7 +19,6 @@ namespace osu.Game.Overlays { private CancellationTokenSource cancellationToken; - private Box background; private Container content; private DashboardOverlayHeader header; private LoadingLayer loading; @@ -35,9 +34,10 @@ namespace osu.Game.Overlays { Children = new Drawable[] { - background = new Box + new Box { - RelativeSizeAxes = Axes.Both + RelativeSizeAxes = Axes.Both, + Colour = ColourProvider.Background5 }, scrollFlow = new OverlayScrollContainer { @@ -66,8 +66,6 @@ namespace osu.Game.Overlays }, loading = new LoadingLayer(content), }; - - background.Colour = ColourProvider.Background5; } protected override void LoadComplete() diff --git a/osu.Game/Overlays/NewsOverlay.cs b/osu.Game/Overlays/NewsOverlay.cs index 46d692d44d..ec25827b5a 100644 --- a/osu.Game/Overlays/NewsOverlay.cs +++ b/osu.Game/Overlays/NewsOverlay.cs @@ -7,37 +7,40 @@ using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; -using osu.Game.Graphics; +using osu.Game.Graphics.UserInterface; using osu.Game.Overlays.News; namespace osu.Game.Overlays { public class NewsOverlay : FullscreenOverlay { - private NewsHeader header; - - private Container content; - public readonly Bindable Current = new Bindable(null); + private Container content; + private LoadingLayer loading; + private OverlayScrollContainer scrollFlow; + public NewsOverlay() : base(OverlayColourScheme.Purple) { } [BackgroundDependencyLoader] - private void load(OsuColour colours) + private void load() { + NewsHeader header; + Children = new Drawable[] { new Box { RelativeSizeAxes = Axes.Both, - Colour = colours.PurpleDarkAlternative + Colour = ColourProvider.Background5, }, - new OverlayScrollContainer + scrollFlow = new OverlayScrollContainer { RelativeSizeAxes = Axes.Both, + ScrollbarVisible = false, Child = new FillFlowContainer { RelativeSizeAxes = Axes.X, @@ -49,7 +52,7 @@ namespace osu.Game.Overlays { ShowFrontPage = ShowFrontPage }, - content = new Container + content = new Container { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, @@ -57,25 +60,16 @@ namespace osu.Game.Overlays }, }, }, + loading = new LoadingLayer(content), }; header.Post.BindTo(Current); - Current.TriggerChange(); } - private CancellationTokenSource loadContentCancellation; - - protected void LoadAndShowContent(NewsContent newContent) + protected override void LoadComplete() { - content.FadeTo(0.2f, 300, Easing.OutQuint); - - loadContentCancellation?.Cancel(); - - LoadComponentAsync(newContent, c => - { - content.Child = c; - content.FadeIn(300, Easing.OutQuint); - }, (loadContentCancellation = new CancellationTokenSource()).Token); + base.LoadComplete(); + Current.BindValueChanged(onCurrentChanged, true); } public void ShowFrontPage() @@ -83,5 +77,37 @@ namespace osu.Game.Overlays Current.Value = null; Show(); } + + private CancellationTokenSource cancellationToken; + + private void onCurrentChanged(ValueChangedEvent current) + { + cancellationToken?.Cancel(); + loading.Show(); + + if (current.NewValue == null) + { + LoadDisplay(Empty()); + return; + } + + LoadDisplay(Empty()); + } + + protected void LoadDisplay(Drawable display) + { + scrollFlow.ScrollToStart(); + LoadComponentAsync(display, loaded => + { + content.Child = loaded; + loading.Hide(); + }, (cancellationToken = new CancellationTokenSource()).Token); + } + + protected override void Dispose(bool isDisposing) + { + cancellationToken?.Cancel(); + base.Dispose(isDisposing); + } } } From 0b4213f3307c5c0145c9d2185e575d56833ea8a5 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 8 Jul 2020 20:07:29 +0300 Subject: [PATCH 020/434] Implement FrontPageDisplay --- .../Visual/Online/TestSceneNewsOverlay.cs | 2 + .../News/Displays/FrontpageDisplay.cs | 133 ++++++++++++++++++ osu.Game/Overlays/NewsOverlay.cs | 3 +- 3 files changed, 137 insertions(+), 1 deletion(-) create mode 100644 osu.Game/Overlays/News/Displays/FrontpageDisplay.cs diff --git a/osu.Game.Tests/Visual/Online/TestSceneNewsOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneNewsOverlay.cs index 0b3ede5d13..151b3df68f 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneNewsOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneNewsOverlay.cs @@ -12,6 +12,8 @@ namespace osu.Game.Tests.Visual.Online { private TestNewsOverlay news; + protected override bool UseOnlineAPI => true; + protected override void LoadComplete() { base.LoadComplete(); diff --git a/osu.Game/Overlays/News/Displays/FrontpageDisplay.cs b/osu.Game/Overlays/News/Displays/FrontpageDisplay.cs new file mode 100644 index 0000000000..611a072047 --- /dev/null +++ b/osu.Game/Overlays/News/Displays/FrontpageDisplay.cs @@ -0,0 +1,133 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Threading; +using osu.Framework.Allocation; +using osu.Framework.Extensions.IEnumerableExtensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Game.Graphics.UserInterface; +using osu.Game.Online.API; +using osu.Game.Online.API.Requests; +using osuTK; + +namespace osu.Game.Overlays.News.Displays +{ + public class FrontpageDisplay : CompositeDrawable + { + [Resolved] + private IAPIProvider api { get; set; } + + private readonly FillFlowContainer content; + private readonly FrontpageShowMoreButton showMore; + + private GetNewsRequest request; + private Cursor lastCursor; + + public FrontpageDisplay() + { + RelativeSizeAxes = Axes.X; + AutoSizeAxes = Axes.Y; + Padding = new MarginPadding + { + Top = 20, + Bottom = 10, + Left = 35, + Right = 55 + }; + + InternalChild = new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Vertical, + Spacing = new Vector2(0, 10), + Children = new Drawable[] + { + content = new FillFlowContainer + { + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Vertical, + Spacing = new Vector2(0, 10) + }, + showMore = new FrontpageShowMoreButton + { + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + Margin = new MarginPadding + { + Vertical = 15 + }, + Action = fetchPage, + Alpha = 0 + } + } + }; + } + + [BackgroundDependencyLoader] + private void load() + { + fetchPage(); + } + + private void fetchPage() + { + request = new GetNewsRequest(lastCursor); + request.Success += response => Schedule(() => createContent(response)); + api.PerformAsync(request); + } + + private CancellationTokenSource cancellationToken; + + private void createContent(GetNewsResponse response) + { + lastCursor = response.Cursor; + + FillFlowContainer flow; + + flow = new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Vertical, + Spacing = new Vector2(0, 10) + }; + + response.NewsPosts.ForEach(p => + { + flow.Add(new NewsCard(p)); + }); + + LoadComponentAsync(flow, loaded => + { + content.Add(loaded); + showMore.IsLoading = false; + showMore.Show(); + }, (cancellationToken = new CancellationTokenSource()).Token); + } + + protected override void Dispose(bool isDisposing) + { + request?.Cancel(); + cancellationToken?.Cancel(); + base.Dispose(isDisposing); + } + + private class FrontpageShowMoreButton : ShowMoreButton + { + [BackgroundDependencyLoader] + private void load(OverlayColourProvider colourProvider) + { + Height = 20; + + IdleColour = colourProvider.Background3; + HoverColour = colourProvider.Background2; + ChevronIconColour = colourProvider.Foreground1; + } + } + } +} diff --git a/osu.Game/Overlays/NewsOverlay.cs b/osu.Game/Overlays/NewsOverlay.cs index ec25827b5a..c6c5d132c1 100644 --- a/osu.Game/Overlays/NewsOverlay.cs +++ b/osu.Game/Overlays/NewsOverlay.cs @@ -9,6 +9,7 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Game.Graphics.UserInterface; using osu.Game.Overlays.News; +using osu.Game.Overlays.News.Displays; namespace osu.Game.Overlays { @@ -87,7 +88,7 @@ namespace osu.Game.Overlays if (current.NewValue == null) { - LoadDisplay(Empty()); + LoadDisplay(new FrontpageDisplay()); return; } From 57b935ec50b42a8c1eb2ebff1b04fd42f65e6a63 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 8 Jul 2020 20:17:15 +0300 Subject: [PATCH 021/434] Remove outdated elements --- .../Visual/Online/TestSceneNewsOverlay.cs | 47 +---- .../News/Displays/FrontpageDisplay.cs | 4 +- osu.Game/Overlays/News/NewsArticleCover.cs | 174 ------------------ osu.Game/Overlays/News/NewsContent.cs | 19 -- 4 files changed, 3 insertions(+), 241 deletions(-) delete mode 100644 osu.Game/Overlays/News/NewsArticleCover.cs delete mode 100644 osu.Game/Overlays/News/NewsContent.cs diff --git a/osu.Game.Tests/Visual/Online/TestSceneNewsOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneNewsOverlay.cs index 151b3df68f..f0dc309d01 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneNewsOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneNewsOverlay.cs @@ -1,68 +1,25 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System; -using osu.Framework.Graphics; using osu.Game.Overlays; -using osu.Game.Overlays.News; namespace osu.Game.Tests.Visual.Online { public class TestSceneNewsOverlay : OsuTestScene { - private TestNewsOverlay news; + private NewsOverlay news; protected override bool UseOnlineAPI => true; protected override void LoadComplete() { base.LoadComplete(); - Add(news = new TestNewsOverlay()); + Add(news = new NewsOverlay()); AddStep(@"Show", news.Show); AddStep(@"Hide", news.Hide); AddStep(@"Show front page", () => news.ShowFrontPage()); AddStep(@"Custom article", () => news.Current.Value = "Test Article 101"); - - AddStep(@"Article covers", () => news.LoadDisplay(new NewsCoverTest())); - } - - private class TestNewsOverlay : NewsOverlay - { - public void LoadDisplay(NewsContent content) => base.LoadDisplay(content); - } - - private class NewsCoverTest : NewsContent - { - public NewsCoverTest() - { - Spacing = new osuTK.Vector2(0, 10); - - var article = new NewsArticleCover.ArticleInfo - { - Author = "Ephemeral", - CoverUrl = "https://assets.ppy.sh/artists/58/header.jpg", - Time = new DateTime(2019, 12, 4), - Title = "New Featured Artist: Kurokotei" - }; - - Children = new Drawable[] - { - new NewsArticleCover(article) - { - Height = 200 - }, - new NewsArticleCover(article) - { - Height = 120 - }, - new NewsArticleCover(article) - { - RelativeSizeAxes = Axes.None, - Size = new osuTK.Vector2(400, 200), - } - }; - } } } } diff --git a/osu.Game/Overlays/News/Displays/FrontpageDisplay.cs b/osu.Game/Overlays/News/Displays/FrontpageDisplay.cs index 611a072047..270c62d42f 100644 --- a/osu.Game/Overlays/News/Displays/FrontpageDisplay.cs +++ b/osu.Game/Overlays/News/Displays/FrontpageDisplay.cs @@ -87,9 +87,7 @@ namespace osu.Game.Overlays.News.Displays { lastCursor = response.Cursor; - FillFlowContainer flow; - - flow = new FillFlowContainer + var flow = new FillFlowContainer { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, diff --git a/osu.Game/Overlays/News/NewsArticleCover.cs b/osu.Game/Overlays/News/NewsArticleCover.cs deleted file mode 100644 index e3f5a8cea3..0000000000 --- a/osu.Game/Overlays/News/NewsArticleCover.cs +++ /dev/null @@ -1,174 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using System; -using osu.Framework.Allocation; -using osu.Framework.Extensions.Color4Extensions; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Colour; -using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Cursor; -using osu.Framework.Graphics.Shapes; -using osu.Framework.Graphics.Sprites; -using osu.Framework.Graphics.Textures; -using osu.Framework.Input.Events; -using osu.Game.Graphics; -using osu.Game.Graphics.Sprites; -using osuTK.Graphics; - -namespace osu.Game.Overlays.News -{ - public class NewsArticleCover : Container - { - private const int hover_duration = 300; - - private readonly Box gradient; - - public NewsArticleCover(ArticleInfo info) - { - RelativeSizeAxes = Axes.X; - Masking = true; - CornerRadius = 4; - - NewsBackground bg; - - Children = new Drawable[] - { - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = ColourInfo.GradientVertical(OsuColour.Gray(0.2f), OsuColour.Gray(0.1f)) - }, - new DelayedLoadWrapper(bg = new NewsBackground(info.CoverUrl) - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - RelativeSizeAxes = Axes.Both, - FillMode = FillMode.Fill, - Alpha = 0 - }) - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - RelativeSizeAxes = Axes.Both, - }, - gradient = new Box - { - RelativeSizeAxes = Axes.Both, - Colour = ColourInfo.GradientVertical(Color4.Black.Opacity(0.1f), Color4.Black.Opacity(0.7f)), - Alpha = 0 - }, - new DateContainer(info.Time) - { - Margin = new MarginPadding - { - Right = 20, - Top = 20, - } - }, - new OsuSpriteText - { - Anchor = Anchor.BottomLeft, - Origin = Anchor.BottomLeft, - Margin = new MarginPadding - { - Left = 25, - Bottom = 50, - }, - Font = OsuFont.GetFont(Typeface.Torus, 24, FontWeight.Bold), - Text = info.Title, - }, - new OsuSpriteText - { - Anchor = Anchor.BottomLeft, - Origin = Anchor.BottomLeft, - Margin = new MarginPadding - { - Left = 25, - Bottom = 30, - }, - Font = OsuFont.GetFont(Typeface.Torus, 16, FontWeight.Bold), - Text = "by " + info.Author - } - }; - - bg.OnLoadComplete += d => d.FadeIn(250, Easing.In); - } - - protected override bool OnHover(HoverEvent e) - { - gradient.FadeIn(hover_duration, Easing.OutQuint); - return base.OnHover(e); - } - - protected override void OnHoverLost(HoverLostEvent e) - { - base.OnHoverLost(e); - gradient.FadeOut(hover_duration, Easing.OutQuint); - } - - [LongRunningLoad] - private class NewsBackground : Sprite - { - private readonly string url; - - public NewsBackground(string coverUrl) - { - url = coverUrl ?? "Headers/news"; - } - - [BackgroundDependencyLoader] - private void load(LargeTextureStore store) - { - Texture = store.Get(url); - } - } - - private class DateContainer : Container, IHasTooltip - { - private readonly DateTime date; - - public DateContainer(DateTime date) - { - this.date = date; - - Anchor = Anchor.TopRight; - Origin = Anchor.TopRight; - Masking = true; - CornerRadius = 4; - AutoSizeAxes = Axes.Both; - Children = new Drawable[] - { - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = Color4.Black.Opacity(0.5f), - }, - new OsuSpriteText - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Font = OsuFont.GetFont(Typeface.Torus, 12, FontWeight.Bold, false, false), - Text = date.ToString("d MMM yyy").ToUpper(), - Margin = new MarginPadding - { - Vertical = 4, - Horizontal = 8, - } - } - }; - } - - public string TooltipText => date.ToString("dddd dd MMMM yyyy hh:mm:ss UTCz").ToUpper(); - } - - // fake API data struct to use for now as a skeleton for data, as there is no API struct for news article info for now - public class ArticleInfo - { - public string Title { get; set; } - public string CoverUrl { get; set; } - public DateTime Time { get; set; } - public string Author { get; set; } - } - } -} diff --git a/osu.Game/Overlays/News/NewsContent.cs b/osu.Game/Overlays/News/NewsContent.cs deleted file mode 100644 index 5ff210f9f5..0000000000 --- a/osu.Game/Overlays/News/NewsContent.cs +++ /dev/null @@ -1,19 +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.Graphics.Containers; - -namespace osu.Game.Overlays.News -{ - public abstract class NewsContent : FillFlowContainer - { - protected NewsContent() - { - RelativeSizeAxes = Axes.X; - AutoSizeAxes = Axes.Y; - Direction = FillDirection.Vertical; - Padding = new MarginPadding { Bottom = 100, Top = 20, Horizontal = 50 }; - } - } -} From 900f2d309b84f43d151685488b6824bb8c5c40c5 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 9 Jul 2020 01:26:56 +0300 Subject: [PATCH 022/434] Classes naming adjustments --- osu.Game/Overlays/News/Displays/FrontpageDisplay.cs | 10 +++++----- osu.Game/Overlays/NewsOverlay.cs | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/osu.Game/Overlays/News/Displays/FrontpageDisplay.cs b/osu.Game/Overlays/News/Displays/FrontpageDisplay.cs index 270c62d42f..f0b25c8143 100644 --- a/osu.Game/Overlays/News/Displays/FrontpageDisplay.cs +++ b/osu.Game/Overlays/News/Displays/FrontpageDisplay.cs @@ -13,18 +13,18 @@ using osuTK; namespace osu.Game.Overlays.News.Displays { - public class FrontpageDisplay : CompositeDrawable + public class FrontPageDisplay : CompositeDrawable { [Resolved] private IAPIProvider api { get; set; } private readonly FillFlowContainer content; - private readonly FrontpageShowMoreButton showMore; + private readonly FrontPageShowMoreButton showMore; private GetNewsRequest request; private Cursor lastCursor; - public FrontpageDisplay() + public FrontPageDisplay() { RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; @@ -53,7 +53,7 @@ namespace osu.Game.Overlays.News.Displays Direction = FillDirection.Vertical, Spacing = new Vector2(0, 10) }, - showMore = new FrontpageShowMoreButton + showMore = new FrontPageShowMoreButton { Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, @@ -115,7 +115,7 @@ namespace osu.Game.Overlays.News.Displays base.Dispose(isDisposing); } - private class FrontpageShowMoreButton : ShowMoreButton + private class FrontPageShowMoreButton : ShowMoreButton { [BackgroundDependencyLoader] private void load(OverlayColourProvider colourProvider) diff --git a/osu.Game/Overlays/NewsOverlay.cs b/osu.Game/Overlays/NewsOverlay.cs index c6c5d132c1..4cd83f83af 100644 --- a/osu.Game/Overlays/NewsOverlay.cs +++ b/osu.Game/Overlays/NewsOverlay.cs @@ -88,7 +88,7 @@ namespace osu.Game.Overlays if (current.NewValue == null) { - LoadDisplay(new FrontpageDisplay()); + LoadDisplay(new FrontPageDisplay()); return; } From 62e2bc11983cc46feffb35badfa82deee9740e6d Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 9 Jul 2020 01:29:27 +0300 Subject: [PATCH 023/434] Fix potential double-request situation --- osu.Game/Overlays/News/Displays/FrontpageDisplay.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Overlays/News/Displays/FrontpageDisplay.cs b/osu.Game/Overlays/News/Displays/FrontpageDisplay.cs index f0b25c8143..73af51c342 100644 --- a/osu.Game/Overlays/News/Displays/FrontpageDisplay.cs +++ b/osu.Game/Overlays/News/Displays/FrontpageDisplay.cs @@ -76,6 +76,8 @@ namespace osu.Game.Overlays.News.Displays private void fetchPage() { + request?.Cancel(); + request = new GetNewsRequest(lastCursor); request.Success += response => Schedule(() => createContent(response)); api.PerformAsync(request); From dfa22b1e4c48fa297508ed57cc84565899c34cd2 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 9 Jul 2020 02:37:42 +0300 Subject: [PATCH 024/434] Styles improvements --- .../Visual/Online/TestSceneShowMoreButton.cs | 20 +++----- .../Graphics/UserInterface/ShowMoreButton.cs | 47 +++++++++++-------- .../Comments/CommentsShowMoreButton.cs | 11 ----- .../News/Displays/FrontpageDisplay.cs | 26 +++------- .../Profile/Sections/PaginatedContainer.cs | 5 +- .../Profile/Sections/ProfileShowMoreButton.cs | 19 -------- 6 files changed, 42 insertions(+), 86 deletions(-) delete mode 100644 osu.Game/Overlays/Profile/Sections/ProfileShowMoreButton.cs diff --git a/osu.Game.Tests/Visual/Online/TestSceneShowMoreButton.cs b/osu.Game.Tests/Visual/Online/TestSceneShowMoreButton.cs index 273f593c32..f1c69f0ac3 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneShowMoreButton.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneShowMoreButton.cs @@ -4,19 +4,22 @@ using osu.Framework.Graphics; using osu.Game.Graphics.UserInterface; using osu.Framework.Allocation; -using osu.Game.Graphics; +using osu.Game.Overlays; namespace osu.Game.Tests.Visual.Online { public class TestSceneShowMoreButton : OsuTestScene { + [Cached] + private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Red); + public TestSceneShowMoreButton() { - TestButton button = null; + ShowMoreButton button = null; int fireCount = 0; - Add(button = new TestButton + Add(button = new ShowMoreButton { Anchor = Anchor.Centre, Origin = Anchor.Centre, @@ -46,16 +49,5 @@ namespace osu.Game.Tests.Visual.Online AddAssert("action fired twice", () => fireCount == 2); AddAssert("is in loading state", () => button.IsLoading); } - - private class TestButton : ShowMoreButton - { - [BackgroundDependencyLoader] - private void load(OsuColour colors) - { - IdleColour = colors.YellowDark; - HoverColour = colors.Yellow; - ChevronIconColour = colors.Red; - } - } } } diff --git a/osu.Game/Graphics/UserInterface/ShowMoreButton.cs b/osu.Game/Graphics/UserInterface/ShowMoreButton.cs index c9cd9f1158..db563b346c 100644 --- a/osu.Game/Graphics/UserInterface/ShowMoreButton.cs +++ b/osu.Game/Graphics/UserInterface/ShowMoreButton.cs @@ -1,13 +1,14 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Sprites; using osu.Game.Graphics.Sprites; +using osu.Game.Overlays; using osuTK; -using osuTK.Graphics; using System.Collections.Generic; namespace osu.Game.Graphics.UserInterface @@ -16,14 +17,6 @@ namespace osu.Game.Graphics.UserInterface { private const int duration = 200; - private Color4 chevronIconColour; - - protected Color4 ChevronIconColour - { - get => chevronIconColour; - set => chevronIconColour = leftChevron.Colour = rightChevron.Colour = value; - } - public string Text { get => text.Text; @@ -32,22 +25,26 @@ namespace osu.Game.Graphics.UserInterface protected override IEnumerable EffectTargets => new[] { background }; - private ChevronIcon leftChevron; - private ChevronIcon rightChevron; private SpriteText text; private Box background; private FillFlowContainer textContainer; public ShowMoreButton() { - Height = 30; - Width = 140; + AutoSizeAxes = Axes.Both; + } + + [BackgroundDependencyLoader] + private void load(OverlayColourProvider colourProvider) + { + IdleColour = colourProvider.Background2; + HoverColour = colourProvider.Background1; } protected override Drawable CreateContent() => new CircularContainer { Masking = true, - RelativeSizeAxes = Axes.Both, + AutoSizeAxes = Axes.Both, Children = new Drawable[] { background = new Box @@ -56,22 +53,28 @@ namespace osu.Game.Graphics.UserInterface }, textContainer = new FillFlowContainer { + AlwaysPresent = true, Anchor = Anchor.Centre, Origin = Anchor.Centre, AutoSizeAxes = Axes.Both, Direction = FillDirection.Horizontal, Spacing = new Vector2(7), + Margin = new MarginPadding + { + Horizontal = 20, + Vertical = 5, + }, Children = new Drawable[] { - leftChevron = new ChevronIcon(), + new ChevronIcon(), text = new OsuSpriteText { Anchor = Anchor.Centre, Origin = Anchor.Centre, - Font = OsuFont.GetFont(size: 12, weight: FontWeight.Bold), + Font = OsuFont.GetFont(size: 12, weight: FontWeight.SemiBold), Text = "show more".ToUpper(), }, - rightChevron = new ChevronIcon(), + new ChevronIcon() } } } @@ -83,15 +86,19 @@ namespace osu.Game.Graphics.UserInterface private class ChevronIcon : SpriteIcon { - private const int icon_size = 8; - public ChevronIcon() { Anchor = Anchor.Centre; Origin = Anchor.Centre; - Size = new Vector2(icon_size); + Size = new Vector2(8); Icon = FontAwesome.Solid.ChevronDown; } + + [BackgroundDependencyLoader] + private void load(OverlayColourProvider colourProvider) + { + Colour = colourProvider.Foreground1; + } } } } diff --git a/osu.Game/Overlays/Comments/CommentsShowMoreButton.cs b/osu.Game/Overlays/Comments/CommentsShowMoreButton.cs index d2ff7ecb1f..adf64eabb1 100644 --- a/osu.Game/Overlays/Comments/CommentsShowMoreButton.cs +++ b/osu.Game/Overlays/Comments/CommentsShowMoreButton.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.Bindables; using osu.Game.Graphics.UserInterface; @@ -11,16 +10,6 @@ namespace osu.Game.Overlays.Comments { public readonly BindableInt Current = new BindableInt(); - [BackgroundDependencyLoader] - private void load(OverlayColourProvider colourProvider) - { - Height = 20; - - IdleColour = colourProvider.Background2; - HoverColour = colourProvider.Background1; - ChevronIconColour = colourProvider.Foreground1; - } - protected override void LoadComplete() { Current.BindValueChanged(onCurrentChanged, true); diff --git a/osu.Game/Overlays/News/Displays/FrontpageDisplay.cs b/osu.Game/Overlays/News/Displays/FrontpageDisplay.cs index 73af51c342..386e0b0dca 100644 --- a/osu.Game/Overlays/News/Displays/FrontpageDisplay.cs +++ b/osu.Game/Overlays/News/Displays/FrontpageDisplay.cs @@ -19,7 +19,7 @@ namespace osu.Game.Overlays.News.Displays private IAPIProvider api { get; set; } private readonly FillFlowContainer content; - private readonly FrontPageShowMoreButton showMore; + private readonly ShowMoreButton showMore; private GetNewsRequest request; private Cursor lastCursor; @@ -30,10 +30,9 @@ namespace osu.Game.Overlays.News.Displays AutoSizeAxes = Axes.Y; Padding = new MarginPadding { - Top = 20, - Bottom = 10, - Left = 35, - Right = 55 + Vertical = 20, + Left = 30, + Right = 50 }; InternalChild = new FillFlowContainer @@ -53,13 +52,13 @@ namespace osu.Game.Overlays.News.Displays Direction = FillDirection.Vertical, Spacing = new Vector2(0, 10) }, - showMore = new FrontPageShowMoreButton + showMore = new ShowMoreButton { Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, Margin = new MarginPadding { - Vertical = 15 + Top = 15 }, Action = fetchPage, Alpha = 0 @@ -116,18 +115,5 @@ namespace osu.Game.Overlays.News.Displays cancellationToken?.Cancel(); base.Dispose(isDisposing); } - - private class FrontPageShowMoreButton : ShowMoreButton - { - [BackgroundDependencyLoader] - private void load(OverlayColourProvider colourProvider) - { - Height = 20; - - IdleColour = colourProvider.Background3; - HoverColour = colourProvider.Background2; - ChevronIconColour = colourProvider.Foreground1; - } - } } } diff --git a/osu.Game/Overlays/Profile/Sections/PaginatedContainer.cs b/osu.Game/Overlays/Profile/Sections/PaginatedContainer.cs index a30ff786fb..9720469548 100644 --- a/osu.Game/Overlays/Profile/Sections/PaginatedContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/PaginatedContainer.cs @@ -14,12 +14,13 @@ using osu.Game.Users; using System.Collections.Generic; using System.Linq; using System.Threading; +using osu.Game.Graphics.UserInterface; namespace osu.Game.Overlays.Profile.Sections { public abstract class PaginatedContainer : FillFlowContainer { - private readonly ProfileShowMoreButton moreButton; + private readonly ShowMoreButton moreButton; private readonly OsuSpriteText missingText; private APIRequest> retrievalRequest; private CancellationTokenSource loadCancellation; @@ -74,7 +75,7 @@ namespace osu.Game.Overlays.Profile.Sections RelativeSizeAxes = Axes.X, Spacing = new Vector2(0, 2), }, - moreButton = new ProfileShowMoreButton + moreButton = new ShowMoreButton { Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, diff --git a/osu.Game/Overlays/Profile/Sections/ProfileShowMoreButton.cs b/osu.Game/Overlays/Profile/Sections/ProfileShowMoreButton.cs deleted file mode 100644 index 426ebeebe6..0000000000 --- a/osu.Game/Overlays/Profile/Sections/ProfileShowMoreButton.cs +++ /dev/null @@ -1,19 +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.Game.Graphics.UserInterface; - -namespace osu.Game.Overlays.Profile.Sections -{ - public class ProfileShowMoreButton : ShowMoreButton - { - [BackgroundDependencyLoader] - private void load(OverlayColourProvider colourProvider) - { - IdleColour = colourProvider.Background2; - HoverColour = colourProvider.Background1; - ChevronIconColour = colourProvider.Foreground1; - } - } -} From 3ba8ec0fd75f73dda2db4d8bb855e7544a7f7aba Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 9 Jul 2020 03:40:14 +0300 Subject: [PATCH 025/434] Don't set null value to show front page --- .../Visual/Online/TestSceneNewsOverlay.cs | 16 ++++--- osu.Game/Overlays/News/NewsHeader.cs | 46 ++++++++++--------- osu.Game/Overlays/NewsOverlay.cs | 26 +++++------ 3 files changed, 45 insertions(+), 43 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneNewsOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneNewsOverlay.cs index f0dc309d01..e35ef4916b 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneNewsOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneNewsOverlay.cs @@ -7,19 +7,21 @@ namespace osu.Game.Tests.Visual.Online { public class TestSceneNewsOverlay : OsuTestScene { - private NewsOverlay news; - protected override bool UseOnlineAPI => true; protected override void LoadComplete() { base.LoadComplete(); - Add(news = new NewsOverlay()); - AddStep(@"Show", news.Show); - AddStep(@"Hide", news.Hide); - AddStep(@"Show front page", () => news.ShowFrontPage()); - AddStep(@"Custom article", () => news.Current.Value = "Test Article 101"); + NewsOverlay news; + Add(news = new NewsOverlay()); + + AddStep("Show", news.Show); + AddStep("Hide", news.Hide); + + AddStep("Show front page", () => news.ShowFrontPage()); + AddStep("Custom article", () => news.ShowArticle("Test Article 101")); + AddStep("Custom article", () => news.ShowArticle("Test Article 102")); } } } diff --git a/osu.Game/Overlays/News/NewsHeader.cs b/osu.Game/Overlays/News/NewsHeader.cs index 8214c71b3a..ee7991c0c6 100644 --- a/osu.Game/Overlays/News/NewsHeader.cs +++ b/osu.Game/Overlays/News/NewsHeader.cs @@ -3,44 +3,46 @@ using osu.Framework.Bindables; using osu.Framework.Graphics; -using System; namespace osu.Game.Overlays.News { public class NewsHeader : BreadcrumbControlOverlayHeader { - private const string front_page_string = "frontpage"; + public const string FRONT_PAGE_STRING = "frontpage"; - public readonly Bindable Post = new Bindable(null); - - public Action ShowFrontPage; + public readonly Bindable Post = new Bindable(FRONT_PAGE_STRING); public NewsHeader() { - TabControl.AddItem(front_page_string); - - Current.ValueChanged += e => - { - if (e.NewValue == front_page_string) - ShowFrontPage?.Invoke(); - }; - - Post.ValueChanged += showPost; + TabControl.AddItem(FRONT_PAGE_STRING); + Current.Value = FRONT_PAGE_STRING; + Current.BindValueChanged(onCurrentChanged); + Post.BindValueChanged(onPostChanged, true); } - private void showPost(ValueChangedEvent e) - { - if (e.OldValue != null) - TabControl.RemoveItem(e.OldValue); + public void SetFrontPage() => Post.Value = FRONT_PAGE_STRING; - if (e.NewValue != null) + public void SetArticle(string slug) => Post.Value = slug; + + private void onCurrentChanged(ValueChangedEvent current) + { + if (current.NewValue == FRONT_PAGE_STRING) + Post.Value = FRONT_PAGE_STRING; + } + + private void onPostChanged(ValueChangedEvent post) + { + if (post.OldValue != FRONT_PAGE_STRING) + TabControl.RemoveItem(post.OldValue); + + if (post.NewValue != FRONT_PAGE_STRING) { - TabControl.AddItem(e.NewValue); - Current.Value = e.NewValue; + TabControl.AddItem(post.NewValue); + Current.Value = post.NewValue; } else { - Current.Value = front_page_string; + Current.Value = FRONT_PAGE_STRING; } } diff --git a/osu.Game/Overlays/NewsOverlay.cs b/osu.Game/Overlays/NewsOverlay.cs index 4cd83f83af..db989e71bf 100644 --- a/osu.Game/Overlays/NewsOverlay.cs +++ b/osu.Game/Overlays/NewsOverlay.cs @@ -15,10 +15,9 @@ namespace osu.Game.Overlays { public class NewsOverlay : FullscreenOverlay { - public readonly Bindable Current = new Bindable(null); - private Container content; private LoadingLayer loading; + private NewsHeader header; private OverlayScrollContainer scrollFlow; public NewsOverlay() @@ -29,8 +28,6 @@ namespace osu.Game.Overlays [BackgroundDependencyLoader] private void load() { - NewsHeader header; - Children = new Drawable[] { new Box @@ -49,10 +46,7 @@ namespace osu.Game.Overlays Direction = FillDirection.Vertical, Children = new Drawable[] { - header = new NewsHeader - { - ShowFrontPage = ShowFrontPage - }, + header = new NewsHeader(), content = new Container { RelativeSizeAxes = Axes.X, @@ -63,30 +57,34 @@ namespace osu.Game.Overlays }, loading = new LoadingLayer(content), }; - - header.Post.BindTo(Current); } protected override void LoadComplete() { base.LoadComplete(); - Current.BindValueChanged(onCurrentChanged, true); + header.Post.BindValueChanged(onPostChanged, true); } public void ShowFrontPage() { - Current.Value = null; + header.SetFrontPage(); + Show(); + } + + public void ShowArticle(string slug) + { + header.SetArticle(slug); Show(); } private CancellationTokenSource cancellationToken; - private void onCurrentChanged(ValueChangedEvent current) + private void onPostChanged(ValueChangedEvent post) { cancellationToken?.Cancel(); loading.Show(); - if (current.NewValue == null) + if (post.NewValue == NewsHeader.FRONT_PAGE_STRING) { LoadDisplay(new FrontPageDisplay()); return; From aeb664aca759e7061a6140b7c51dabc31fa26132 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 9 Jul 2020 04:00:53 +0300 Subject: [PATCH 026/434] Delete broken file --- .../News/Displays/FrontpageDisplay.cs | 119 ------------------ 1 file changed, 119 deletions(-) delete mode 100644 osu.Game/Overlays/News/Displays/FrontpageDisplay.cs diff --git a/osu.Game/Overlays/News/Displays/FrontpageDisplay.cs b/osu.Game/Overlays/News/Displays/FrontpageDisplay.cs deleted file mode 100644 index 386e0b0dca..0000000000 --- a/osu.Game/Overlays/News/Displays/FrontpageDisplay.cs +++ /dev/null @@ -1,119 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using System.Threading; -using osu.Framework.Allocation; -using osu.Framework.Extensions.IEnumerableExtensions; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Game.Graphics.UserInterface; -using osu.Game.Online.API; -using osu.Game.Online.API.Requests; -using osuTK; - -namespace osu.Game.Overlays.News.Displays -{ - public class FrontPageDisplay : CompositeDrawable - { - [Resolved] - private IAPIProvider api { get; set; } - - private readonly FillFlowContainer content; - private readonly ShowMoreButton showMore; - - private GetNewsRequest request; - private Cursor lastCursor; - - public FrontPageDisplay() - { - RelativeSizeAxes = Axes.X; - AutoSizeAxes = Axes.Y; - Padding = new MarginPadding - { - Vertical = 20, - Left = 30, - Right = 50 - }; - - InternalChild = new FillFlowContainer - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Direction = FillDirection.Vertical, - Spacing = new Vector2(0, 10), - Children = new Drawable[] - { - content = new FillFlowContainer - { - Anchor = Anchor.TopCentre, - Origin = Anchor.TopCentre, - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Direction = FillDirection.Vertical, - Spacing = new Vector2(0, 10) - }, - showMore = new ShowMoreButton - { - Anchor = Anchor.TopCentre, - Origin = Anchor.TopCentre, - Margin = new MarginPadding - { - Top = 15 - }, - Action = fetchPage, - Alpha = 0 - } - } - }; - } - - [BackgroundDependencyLoader] - private void load() - { - fetchPage(); - } - - private void fetchPage() - { - request?.Cancel(); - - request = new GetNewsRequest(lastCursor); - request.Success += response => Schedule(() => createContent(response)); - api.PerformAsync(request); - } - - private CancellationTokenSource cancellationToken; - - private void createContent(GetNewsResponse response) - { - lastCursor = response.Cursor; - - var flow = new FillFlowContainer - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Direction = FillDirection.Vertical, - Spacing = new Vector2(0, 10) - }; - - response.NewsPosts.ForEach(p => - { - flow.Add(new NewsCard(p)); - }); - - LoadComponentAsync(flow, loaded => - { - content.Add(loaded); - showMore.IsLoading = false; - showMore.Show(); - }, (cancellationToken = new CancellationTokenSource()).Token); - } - - protected override void Dispose(bool isDisposing) - { - request?.Cancel(); - cancellationToken?.Cancel(); - base.Dispose(isDisposing); - } - } -} From f663dd18033e9cfc83dbbaa652f862a4e7fb8099 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 9 Jul 2020 04:02:14 +0300 Subject: [PATCH 027/434] Fix incorrect file name --- .../News/Displays/FrontPageDisplay.cs | 115 ++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 osu.Game/Overlays/News/Displays/FrontPageDisplay.cs diff --git a/osu.Game/Overlays/News/Displays/FrontPageDisplay.cs b/osu.Game/Overlays/News/Displays/FrontPageDisplay.cs new file mode 100644 index 0000000000..67b5edfafd --- /dev/null +++ b/osu.Game/Overlays/News/Displays/FrontPageDisplay.cs @@ -0,0 +1,115 @@ +// 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 System.Threading; +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Game.Graphics.UserInterface; +using osu.Game.Online.API; +using osu.Game.Online.API.Requests; +using osuTK; + +namespace osu.Game.Overlays.News.Displays +{ + public class FrontPageDisplay : CompositeDrawable + { + [Resolved] + private IAPIProvider api { get; set; } + + private readonly FillFlowContainer content; + private readonly ShowMoreButton showMore; + + private GetNewsRequest request; + private Cursor lastCursor; + + public FrontPageDisplay() + { + RelativeSizeAxes = Axes.X; + AutoSizeAxes = Axes.Y; + Padding = new MarginPadding + { + Vertical = 20, + Left = 30, + Right = 50 + }; + + InternalChild = new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Vertical, + Spacing = new Vector2(0, 10), + Children = new Drawable[] + { + content = new FillFlowContainer + { + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Vertical, + Spacing = new Vector2(0, 10) + }, + showMore = new ShowMoreButton + { + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + Margin = new MarginPadding + { + Top = 15 + }, + Action = fetchPage, + Alpha = 0 + } + } + }; + } + + [BackgroundDependencyLoader] + private void load() + { + fetchPage(); + } + + private void fetchPage() + { + request?.Cancel(); + + request = new GetNewsRequest(lastCursor); + request.Success += response => Schedule(() => createContent(response)); + api.PerformAsync(request); + } + + private CancellationTokenSource cancellationToken; + + private void createContent(GetNewsResponse response) + { + lastCursor = response.Cursor; + + var flow = new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Vertical, + Spacing = new Vector2(0, 10), + Children = response.NewsPosts.Select(p => new NewsCard(p)).ToList() + }; + + LoadComponentAsync(flow, loaded => + { + content.Add(loaded); + showMore.IsLoading = false; + showMore.Show(); + }, (cancellationToken = new CancellationTokenSource()).Token); + } + + protected override void Dispose(bool isDisposing) + { + request?.Cancel(); + cancellationToken?.Cancel(); + base.Dispose(isDisposing); + } + } +} From 598e48678e2e143b6671a9cd2c9f55dad36f3bff Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sun, 12 Jul 2020 15:45:48 +0300 Subject: [PATCH 028/434] Refactor NewsHeader --- osu.Game/Overlays/News/NewsHeader.cs | 54 ++++++++++++++-------------- osu.Game/Overlays/NewsOverlay.cs | 19 ++++++---- 2 files changed, 41 insertions(+), 32 deletions(-) diff --git a/osu.Game/Overlays/News/NewsHeader.cs b/osu.Game/Overlays/News/NewsHeader.cs index ee7991c0c6..ddada2bdaf 100644 --- a/osu.Game/Overlays/News/NewsHeader.cs +++ b/osu.Game/Overlays/News/NewsHeader.cs @@ -1,6 +1,7 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -8,41 +9,42 @@ namespace osu.Game.Overlays.News { public class NewsHeader : BreadcrumbControlOverlayHeader { - public const string FRONT_PAGE_STRING = "frontpage"; + private const string front_page_string = "frontpage"; - public readonly Bindable Post = new Bindable(FRONT_PAGE_STRING); + public Action ShowFrontPage; + + private readonly Bindable article = new Bindable(null); public NewsHeader() { - TabControl.AddItem(FRONT_PAGE_STRING); - Current.Value = FRONT_PAGE_STRING; - Current.BindValueChanged(onCurrentChanged); - Post.BindValueChanged(onPostChanged, true); - } + TabControl.AddItem(front_page_string); - public void SetFrontPage() => Post.Value = FRONT_PAGE_STRING; - - public void SetArticle(string slug) => Post.Value = slug; - - private void onCurrentChanged(ValueChangedEvent current) - { - if (current.NewValue == FRONT_PAGE_STRING) - Post.Value = FRONT_PAGE_STRING; - } - - private void onPostChanged(ValueChangedEvent post) - { - if (post.OldValue != FRONT_PAGE_STRING) - TabControl.RemoveItem(post.OldValue); - - if (post.NewValue != FRONT_PAGE_STRING) + Current.BindValueChanged(e => { - TabControl.AddItem(post.NewValue); - Current.Value = post.NewValue; + if (e.NewValue == front_page_string) + ShowFrontPage?.Invoke(); + }); + + article.BindValueChanged(onArticleChanged, true); + } + + public void SetFrontPage() => article.Value = null; + + public void SetArticle(string slug) => article.Value = slug; + + private void onArticleChanged(ValueChangedEvent e) + { + if (e.OldValue != null) + TabControl.RemoveItem(e.OldValue); + + if (e.NewValue != null) + { + TabControl.AddItem(e.NewValue); + Current.Value = e.NewValue; } else { - Current.Value = FRONT_PAGE_STRING; + Current.Value = front_page_string; } } diff --git a/osu.Game/Overlays/NewsOverlay.cs b/osu.Game/Overlays/NewsOverlay.cs index db989e71bf..a5687b77e2 100644 --- a/osu.Game/Overlays/NewsOverlay.cs +++ b/osu.Game/Overlays/NewsOverlay.cs @@ -15,6 +15,8 @@ namespace osu.Game.Overlays { public class NewsOverlay : FullscreenOverlay { + private readonly Bindable article = new Bindable(null); + private Container content; private LoadingLayer loading; private NewsHeader header; @@ -46,7 +48,10 @@ namespace osu.Game.Overlays Direction = FillDirection.Vertical, Children = new Drawable[] { - header = new NewsHeader(), + header = new NewsHeader + { + ShowFrontPage = ShowFrontPage + }, content = new Container { RelativeSizeAxes = Axes.X, @@ -62,34 +67,36 @@ namespace osu.Game.Overlays protected override void LoadComplete() { base.LoadComplete(); - header.Post.BindValueChanged(onPostChanged, true); + article.BindValueChanged(onArticleChanged, true); } public void ShowFrontPage() { - header.SetFrontPage(); + article.Value = null; Show(); } public void ShowArticle(string slug) { - header.SetArticle(slug); + article.Value = slug; Show(); } private CancellationTokenSource cancellationToken; - private void onPostChanged(ValueChangedEvent post) + private void onArticleChanged(ValueChangedEvent e) { cancellationToken?.Cancel(); loading.Show(); - if (post.NewValue == NewsHeader.FRONT_PAGE_STRING) + if (e.NewValue == null) { + header.SetFrontPage(); LoadDisplay(new FrontPageDisplay()); return; } + header.SetArticle(e.NewValue); LoadDisplay(Empty()); } From a72bb932661faa2442ceb9160d61b0d21e803790 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sun, 12 Jul 2020 15:57:18 +0300 Subject: [PATCH 029/434] Add test scene for NewsHeader --- .../Visual/Online/TestSceneNewsHeader.cs | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 osu.Game.Tests/Visual/Online/TestSceneNewsHeader.cs diff --git a/osu.Game.Tests/Visual/Online/TestSceneNewsHeader.cs b/osu.Game.Tests/Visual/Online/TestSceneNewsHeader.cs new file mode 100644 index 0000000000..65e86e925d --- /dev/null +++ b/osu.Game.Tests/Visual/Online/TestSceneNewsHeader.cs @@ -0,0 +1,53 @@ +// 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.Overlays.News; +using osu.Framework.Graphics; +using osu.Game.Overlays; +using osu.Framework.Allocation; + +namespace osu.Game.Tests.Visual.Online +{ + public class TestSceneNewsHeader : OsuTestScene + { + [Cached] + private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Purple); + + private TestHeader header; + + [SetUp] + public void Setup() + { + Child = header = new TestHeader + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre + }; + } + + [Test] + public void TestControl() + { + AddAssert("Front page selected", () => header.Current.Value == "frontpage"); + AddAssert("1 tab total", () => header.TabCount == 1); + + AddStep("Set article 1", () => header.SetArticle("1")); + AddAssert("Article 1 selected", () => header.Current.Value == "1"); + AddAssert("2 tabs total", () => header.TabCount == 2); + + AddStep("Set article 2", () => header.SetArticle("2")); + AddAssert("Article 2 selected", () => header.Current.Value == "2"); + AddAssert("2 tabs total", () => header.TabCount == 2); + + AddStep("Set front page", () => header.SetFrontPage()); + AddAssert("Front page selected", () => header.Current.Value == "frontpage"); + AddAssert("1 tab total", () => header.TabCount == 1); + } + + private class TestHeader : NewsHeader + { + public int TabCount => TabControl.Items.Count; + } + } +} From 444701fdd0c0903346177900acef014755da297f Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sun, 12 Jul 2020 16:13:48 +0300 Subject: [PATCH 030/434] Use dummy api for tests --- .../Visual/Online/TestSceneNewsHeader.cs | 4 +- .../Visual/Online/TestSceneNewsOverlay.cs | 64 +++++++++++++++---- 2 files changed, 53 insertions(+), 15 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneNewsHeader.cs b/osu.Game.Tests/Visual/Online/TestSceneNewsHeader.cs index 65e86e925d..78288bf6e4 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneNewsHeader.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneNewsHeader.cs @@ -17,14 +17,14 @@ namespace osu.Game.Tests.Visual.Online private TestHeader header; [SetUp] - public void Setup() + public void Setup() => Schedule(() => { Child = header = new TestHeader { Anchor = Anchor.Centre, Origin = Anchor.Centre }; - } + }); [Test] public void TestControl() diff --git a/osu.Game.Tests/Visual/Online/TestSceneNewsOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneNewsOverlay.cs index e35ef4916b..37d51c16d2 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneNewsOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneNewsOverlay.cs @@ -1,27 +1,65 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System; +using NUnit.Framework; +using osu.Game.Online.API; +using osu.Game.Online.API.Requests; +using osu.Game.Online.API.Requests.Responses; using osu.Game.Overlays; namespace osu.Game.Tests.Visual.Online { public class TestSceneNewsOverlay : OsuTestScene { - protected override bool UseOnlineAPI => true; + private DummyAPIAccess dummyAPI => (DummyAPIAccess)API; - protected override void LoadComplete() + private NewsOverlay news; + + [SetUp] + public void SetUp() => Schedule(() => Child = news = new NewsOverlay()); + + [Test] + public void TestRequest() { - base.LoadComplete(); - - NewsOverlay news; - Add(news = new NewsOverlay()); - - AddStep("Show", news.Show); - AddStep("Hide", news.Hide); - - AddStep("Show front page", () => news.ShowFrontPage()); - AddStep("Custom article", () => news.ShowArticle("Test Article 101")); - AddStep("Custom article", () => news.ShowArticle("Test Article 102")); + setUpNewsResponse(responseExample); + AddStep("Show", () => news.Show()); + AddStep("Show article", () => news.ShowArticle("article")); } + + private void setUpNewsResponse(GetNewsResponse r) + => AddStep("set up response", () => + { + dummyAPI.HandleRequest = request => + { + if (!(request is GetNewsRequest getNewsRequest)) + return; + + getNewsRequest.TriggerSuccess(r); + }; + }); + + private GetNewsResponse responseExample => new GetNewsResponse + { + NewsPosts = new[] + { + new APINewsPost + { + Title = "This post has an image which starts with \"/\" and has many authors!", + Preview = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.", + Author = "someone, someone1, someone2, someone3, someone4", + FirstImage = "/help/wiki/shared/news/banners/monthly-beatmapping-contest.png", + PublishedAt = DateTimeOffset.Now + }, + new APINewsPost + { + Title = "This post has a full-url image! (HTML entity: &)", + Preview = "boom (HTML entity: &)", + Author = "user (HTML entity: &)", + FirstImage = "https://assets.ppy.sh/artists/88/header.jpg", + PublishedAt = DateTimeOffset.Now + } + } + }; } } From 68d2888a8c16cd5e16c1f50f12e5d22279dfd2c4 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 16 Jul 2020 14:48:40 +0300 Subject: [PATCH 031/434] Add NewsOverlay to the game --- osu.Game.Tests/Visual/TestSceneOsuGame.cs | 1 + osu.Game/OsuGame.cs | 5 ++++- osu.Game/Overlays/Toolbar/Toolbar.cs | 1 + .../Overlays/Toolbar/ToolbarNewsButton.cs | 22 +++++++++++++++++++ 4 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 osu.Game/Overlays/Toolbar/ToolbarNewsButton.cs diff --git a/osu.Game.Tests/Visual/TestSceneOsuGame.cs b/osu.Game.Tests/Visual/TestSceneOsuGame.cs index 22ae5257e7..b347c39c1e 100644 --- a/osu.Game.Tests/Visual/TestSceneOsuGame.cs +++ b/osu.Game.Tests/Visual/TestSceneOsuGame.cs @@ -44,6 +44,7 @@ namespace osu.Game.Tests.Visual typeof(NotificationOverlay), typeof(BeatmapListingOverlay), typeof(DashboardOverlay), + typeof(NewsOverlay), typeof(ChannelManager), typeof(ChatOverlay), typeof(SettingsOverlay), diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 618049e72c..84b32673d5 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -71,6 +71,8 @@ namespace osu.Game private DashboardOverlay dashboard; + private NewsOverlay news; + private UserProfileOverlay userProfile; private BeatmapSetOverlay beatmapSetOverlay; @@ -630,6 +632,7 @@ namespace osu.Game // overlay elements loadComponentSingleFile(beatmapListing = new BeatmapListingOverlay(), overlayContent.Add, true); loadComponentSingleFile(dashboard = new DashboardOverlay(), overlayContent.Add, true); + loadComponentSingleFile(news = new NewsOverlay(), overlayContent.Add, true); var rankingsOverlay = loadComponentSingleFile(new RankingsOverlay(), overlayContent.Add, true); loadComponentSingleFile(channelManager = new ChannelManager(), AddInternal, true); loadComponentSingleFile(chatOverlay = new ChatOverlay(), overlayContent.Add, true); @@ -687,7 +690,7 @@ namespace osu.Game } // ensure only one of these overlays are open at once. - var singleDisplayOverlays = new OverlayContainer[] { chatOverlay, dashboard, beatmapListing, changelogOverlay, rankingsOverlay }; + var singleDisplayOverlays = new OverlayContainer[] { chatOverlay, news, dashboard, beatmapListing, changelogOverlay, rankingsOverlay }; foreach (var overlay in singleDisplayOverlays) { diff --git a/osu.Game/Overlays/Toolbar/Toolbar.cs b/osu.Game/Overlays/Toolbar/Toolbar.cs index de08b79f57..5bdd86c671 100644 --- a/osu.Game/Overlays/Toolbar/Toolbar.cs +++ b/osu.Game/Overlays/Toolbar/Toolbar.cs @@ -69,6 +69,7 @@ namespace osu.Game.Overlays.Toolbar AutoSizeAxes = Axes.X, Children = new Drawable[] { + new ToolbarNewsButton(), new ToolbarChangelogButton(), new ToolbarRankingsButton(), new ToolbarBeatmapListingButton(), diff --git a/osu.Game/Overlays/Toolbar/ToolbarNewsButton.cs b/osu.Game/Overlays/Toolbar/ToolbarNewsButton.cs new file mode 100644 index 0000000000..e813a3f4cb --- /dev/null +++ b/osu.Game/Overlays/Toolbar/ToolbarNewsButton.cs @@ -0,0 +1,22 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Allocation; +using osu.Framework.Graphics.Sprites; + +namespace osu.Game.Overlays.Toolbar +{ + public class ToolbarNewsButton : ToolbarOverlayToggleButton + { + public ToolbarNewsButton() + { + Icon = FontAwesome.Solid.Newspaper; + } + + [BackgroundDependencyLoader(true)] + private void load(NewsOverlay news) + { + StateContainer = news; + } + } +} From dac98c8914c7c7f873fa26945bf2195fd72f271b Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 16 Jul 2020 14:55:02 +0300 Subject: [PATCH 032/434] Add shortcut for news overlay --- osu.Game/Input/Bindings/GlobalActionContainer.cs | 4 ++++ osu.Game/OsuGame.cs | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/osu.Game/Input/Bindings/GlobalActionContainer.cs b/osu.Game/Input/Bindings/GlobalActionContainer.cs index 6ae420b162..9f59551b94 100644 --- a/osu.Game/Input/Bindings/GlobalActionContainer.cs +++ b/osu.Game/Input/Bindings/GlobalActionContainer.cs @@ -36,6 +36,7 @@ namespace osu.Game.Input.Bindings new KeyBinding(new[] { InputKey.Control, InputKey.O }, GlobalAction.ToggleSettings), new KeyBinding(new[] { InputKey.Control, InputKey.D }, GlobalAction.ToggleDirect), new KeyBinding(new[] { InputKey.Control, InputKey.N }, GlobalAction.ToggleNotifications), + new KeyBinding(new[] { InputKey.Control, InputKey.A }, GlobalAction.ToggleNews), new KeyBinding(InputKey.Escape, GlobalAction.Back), new KeyBinding(InputKey.ExtraMouseButton1, GlobalAction.Back), @@ -165,5 +166,8 @@ namespace osu.Game.Input.Bindings [Description("Pause")] PauseGameplay, + + [Description("Toggle news overlay")] + ToggleNews } } diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 84b32673d5..fc904cb09c 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -872,6 +872,10 @@ namespace osu.Game dashboard.ToggleVisibility(); return true; + case GlobalAction.ToggleNews: + news.ToggleVisibility(); + return true; + case GlobalAction.ResetInputSettings: var sensitivity = frameworkConfig.GetBindable(FrameworkSetting.CursorSensitivity); From 2d9909cdd89b658411b450ad6e6ee86a8ba67193 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 16 Jul 2020 15:18:01 +0300 Subject: [PATCH 033/434] Make news cards clickable --- .../Visual/Online/TestSceneNewsCard.cs | 7 +-- osu.Game/Overlays/News/NewsCard.cs | 50 ++++++++----------- 2 files changed, 26 insertions(+), 31 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneNewsCard.cs b/osu.Game.Tests/Visual/Online/TestSceneNewsCard.cs index 0446cadac9..17675bfbc0 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneNewsCard.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneNewsCard.cs @@ -31,15 +31,16 @@ namespace osu.Game.Tests.Visual.Online { new NewsCard(new APINewsPost { - Title = "This post has an image which starts with \"/\" and has many authors!", + Title = "This post has an image which starts with \"/\" and has many authors! (clickable)", Preview = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.", Author = "someone, someone1, someone2, someone3, someone4", FirstImage = "/help/wiki/shared/news/banners/monthly-beatmapping-contest.png", - PublishedAt = DateTimeOffset.Now + PublishedAt = DateTimeOffset.Now, + Slug = "2020-07-16-summer-theme-park-2020-voting-open" }), new NewsCard(new APINewsPost { - Title = "This post has a full-url image! (HTML entity: &)", + Title = "This post has a full-url image! (HTML entity: &) (non-clickable)", Preview = "boom (HTML entity: &)", Author = "user (HTML entity: &)", FirstImage = "https://assets.ppy.sh/artists/88/header.jpg", diff --git a/osu.Game/Overlays/News/NewsCard.cs b/osu.Game/Overlays/News/NewsCard.cs index 9c478a7c1d..38362038ae 100644 --- a/osu.Game/Overlays/News/NewsCard.cs +++ b/osu.Game/Overlays/News/NewsCard.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System; +using System.Collections.Generic; using osu.Framework.Allocation; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; @@ -10,18 +11,17 @@ using osu.Framework.Graphics.Cursor; using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Textures; -using osu.Framework.Input.Events; +using osu.Framework.Platform; using osu.Game.Graphics; +using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; -using osu.Game.Graphics.UserInterface; using osu.Game.Online.API.Requests.Responses; namespace osu.Game.Overlays.News { - public class NewsCard : CompositeDrawable + public class NewsCard : OsuHoverContainer { - [Resolved] - private OverlayColourProvider colourProvider { get; set; } + protected override IEnumerable EffectTargets => new[] { background }; private readonly APINewsPost post; @@ -31,24 +31,28 @@ namespace osu.Game.Overlays.News public NewsCard(APINewsPost post) { this.post = post; - } - [BackgroundDependencyLoader] - private void load() - { RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; Masking = true; CornerRadius = 6; + } + + [BackgroundDependencyLoader] + private void load(OverlayColourProvider colourProvider, GameHost host) + { + if (post.Slug != null) + { + TooltipText = "view in browser"; + Action = () => host.OpenUrlExternally("https://osu.ppy.sh/home/news/" + post.Slug); + } NewsBackground bg; - - InternalChildren = new Drawable[] + AddRange(new Drawable[] { background = new Box { - RelativeSizeAxes = Axes.Both, - Colour = colourProvider.Background4 + RelativeSizeAxes = Axes.Both }, new FillFlowContainer { @@ -104,9 +108,11 @@ namespace osu.Game.Overlays.News } } } - }, - new HoverClickSounds() - }; + } + }); + + IdleColour = colourProvider.Background4; + HoverColour = colourProvider.Background3; bg.OnLoadComplete += d => d.FadeIn(250, Easing.In); @@ -116,18 +122,6 @@ namespace osu.Game.Overlays.News main.AddText(post.Author, t => t.Font = OsuFont.GetFont(size: 12, weight: FontWeight.SemiBold)); } - protected override bool OnHover(HoverEvent e) - { - background.FadeColour(colourProvider.Background3, 200, Easing.OutQuint); - return true; - } - - protected override void OnHoverLost(HoverLostEvent e) - { - background.FadeColour(colourProvider.Background4, 200, Easing.OutQuint); - base.OnHoverLost(e); - } - [LongRunningLoad] private class NewsBackground : Sprite { From f67b93936ffeb85bb86b0d27e4cd5af94148ea3b Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 16 Jul 2020 23:11:55 +0300 Subject: [PATCH 034/434] Remove shortcut --- osu.Game/Input/Bindings/GlobalActionContainer.cs | 4 ---- osu.Game/OsuGame.cs | 4 ---- 2 files changed, 8 deletions(-) diff --git a/osu.Game/Input/Bindings/GlobalActionContainer.cs b/osu.Game/Input/Bindings/GlobalActionContainer.cs index 9f59551b94..6ae420b162 100644 --- a/osu.Game/Input/Bindings/GlobalActionContainer.cs +++ b/osu.Game/Input/Bindings/GlobalActionContainer.cs @@ -36,7 +36,6 @@ namespace osu.Game.Input.Bindings new KeyBinding(new[] { InputKey.Control, InputKey.O }, GlobalAction.ToggleSettings), new KeyBinding(new[] { InputKey.Control, InputKey.D }, GlobalAction.ToggleDirect), new KeyBinding(new[] { InputKey.Control, InputKey.N }, GlobalAction.ToggleNotifications), - new KeyBinding(new[] { InputKey.Control, InputKey.A }, GlobalAction.ToggleNews), new KeyBinding(InputKey.Escape, GlobalAction.Back), new KeyBinding(InputKey.ExtraMouseButton1, GlobalAction.Back), @@ -166,8 +165,5 @@ namespace osu.Game.Input.Bindings [Description("Pause")] PauseGameplay, - - [Description("Toggle news overlay")] - ToggleNews } } diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index fc904cb09c..84b32673d5 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -872,10 +872,6 @@ namespace osu.Game dashboard.ToggleVisibility(); return true; - case GlobalAction.ToggleNews: - news.ToggleVisibility(); - return true; - case GlobalAction.ResetInputSettings: var sensitivity = frameworkConfig.GetBindable(FrameworkSetting.CursorSensitivity); From ab23e7dfd4faad3040a8e24eb114a16b6956c183 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 16 Jul 2020 23:14:51 +0300 Subject: [PATCH 035/434] Protect the NewsCard from clicks while hovering DateContainer --- osu.Game/Overlays/News/NewsCard.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/osu.Game/Overlays/News/NewsCard.cs b/osu.Game/Overlays/News/NewsCard.cs index 38362038ae..201c3ce826 100644 --- a/osu.Game/Overlays/News/NewsCard.cs +++ b/osu.Game/Overlays/News/NewsCard.cs @@ -11,6 +11,7 @@ using osu.Framework.Graphics.Cursor; using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Textures; +using osu.Framework.Input.Events; using osu.Framework.Platform; using osu.Game.Graphics; using osu.Game.Graphics.Containers; @@ -187,6 +188,8 @@ namespace osu.Game.Overlays.News } }; } + + protected override bool OnClick(ClickEvent e) => true; // Protects the NewsCard from clicks while hovering DateContainer } } } From a8991bb8bfa69a62d9e9a753a7d8d8ba435d48bd Mon Sep 17 00:00:00 2001 From: Joehu Date: Mon, 20 Jul 2020 20:13:09 -0700 Subject: [PATCH 036/434] Fix keybind clear button always clearing first keybind regardless of target --- osu.Game/Overlays/KeyBinding/KeyBindingRow.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs index eafb4572ca..d58acc1ac4 100644 --- a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs +++ b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs @@ -187,7 +187,7 @@ namespace osu.Game.Overlays.KeyBinding if (bindTarget.IsHovered) finalise(); - else + else if (buttons.Any(b => b.IsHovered)) updateBindTarget(); } From 7e5147761fad18ea1bd904c0d718af15d8c2cc42 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sat, 25 Jul 2020 09:26:29 +0300 Subject: [PATCH 037/434] Use OverlayView for FrontPageDisplay --- .../News/Displays/FrontPageDisplay.cs | 46 +++++++++---------- 1 file changed, 21 insertions(+), 25 deletions(-) diff --git a/osu.Game/Overlays/News/Displays/FrontPageDisplay.cs b/osu.Game/Overlays/News/Displays/FrontPageDisplay.cs index 67b5edfafd..2c228e2f78 100644 --- a/osu.Game/Overlays/News/Displays/FrontPageDisplay.cs +++ b/osu.Game/Overlays/News/Displays/FrontPageDisplay.cs @@ -13,18 +13,18 @@ using osuTK; namespace osu.Game.Overlays.News.Displays { - public class FrontPageDisplay : CompositeDrawable + public class FrontPageDisplay : OverlayView { - [Resolved] - private IAPIProvider api { get; set; } + protected override APIRequest CreateRequest() => new GetNewsRequest(); - private readonly FillFlowContainer content; - private readonly ShowMoreButton showMore; + private FillFlowContainer content; + private ShowMoreButton showMore; - private GetNewsRequest request; + private GetNewsRequest olderPostsRequest; private Cursor lastCursor; - public FrontPageDisplay() + [BackgroundDependencyLoader] + private void load() { RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; @@ -60,32 +60,19 @@ namespace osu.Game.Overlays.News.Displays { Top = 15 }, - Action = fetchPage, + Action = fetchOlderPosts, Alpha = 0 } } }; } - [BackgroundDependencyLoader] - private void load() - { - fetchPage(); - } - - private void fetchPage() - { - request?.Cancel(); - - request = new GetNewsRequest(lastCursor); - request.Success += response => Schedule(() => createContent(response)); - api.PerformAsync(request); - } - private CancellationTokenSource cancellationToken; - private void createContent(GetNewsResponse response) + protected override void OnSuccess(GetNewsResponse response) { + cancellationToken?.Cancel(); + lastCursor = response.Cursor; var flow = new FillFlowContainer @@ -105,9 +92,18 @@ namespace osu.Game.Overlays.News.Displays }, (cancellationToken = new CancellationTokenSource()).Token); } + private void fetchOlderPosts() + { + olderPostsRequest?.Cancel(); + + olderPostsRequest = new GetNewsRequest(lastCursor); + olderPostsRequest.Success += response => Schedule(() => OnSuccess(response)); + API.PerformAsync(olderPostsRequest); + } + protected override void Dispose(bool isDisposing) { - request?.Cancel(); + olderPostsRequest?.Cancel(); cancellationToken?.Cancel(); base.Dispose(isDisposing); } From c6ae2f520e8a7c1ea2446acf401e8a352f57028b Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sat, 25 Jul 2020 10:39:10 +0300 Subject: [PATCH 038/434] Fix FrontPageDisplay is adding more news posts on api state change --- osu.Game/Overlays/News/Displays/FrontPageDisplay.cs | 2 ++ osu.Game/Overlays/OverlayView.cs | 12 +++++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/News/Displays/FrontPageDisplay.cs b/osu.Game/Overlays/News/Displays/FrontPageDisplay.cs index 2c228e2f78..fbacf53bf6 100644 --- a/osu.Game/Overlays/News/Displays/FrontPageDisplay.cs +++ b/osu.Game/Overlays/News/Displays/FrontPageDisplay.cs @@ -15,6 +15,8 @@ namespace osu.Game.Overlays.News.Displays { public class FrontPageDisplay : OverlayView { + protected override bool PerformFetchOnApiStateChange => false; + protected override APIRequest CreateRequest() => new GetNewsRequest(); private FillFlowContainer content; diff --git a/osu.Game/Overlays/OverlayView.cs b/osu.Game/Overlays/OverlayView.cs index 3e2c54c726..f73ca3aa6e 100644 --- a/osu.Game/Overlays/OverlayView.cs +++ b/osu.Game/Overlays/OverlayView.cs @@ -18,6 +18,11 @@ namespace osu.Game.Overlays public abstract class OverlayView : CompositeDrawable, IOnlineComponent where T : class { + /// + /// Whether we should perform fetch on api state change to online (true by default). + /// + protected virtual bool PerformFetchOnApiStateChange => true; + [Resolved] protected IAPIProvider API { get; private set; } @@ -33,6 +38,10 @@ namespace osu.Game.Overlays { base.LoadComplete(); API.Register(this); + + // If property is true - fetch will be triggered automatically by APIStateChanged and if not - we need to manually call it. + if (!PerformFetchOnApiStateChange) + PerformFetch(); } /// @@ -64,7 +73,8 @@ namespace osu.Game.Overlays switch (state) { case APIState.Online: - PerformFetch(); + if (PerformFetchOnApiStateChange) + PerformFetch(); break; } } From 788395f8bf24f1702697298c31a7435897c7e7f3 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sat, 25 Jul 2020 15:08:06 +0300 Subject: [PATCH 039/434] Revert changes regarding FrontPageDisplay and OverlayView --- .../News/Displays/FrontPageDisplay.cs | 35 ++++++++++--------- osu.Game/Overlays/OverlayView.cs | 12 +------ 2 files changed, 19 insertions(+), 28 deletions(-) diff --git a/osu.Game/Overlays/News/Displays/FrontPageDisplay.cs b/osu.Game/Overlays/News/Displays/FrontPageDisplay.cs index fbacf53bf6..0f177f151a 100644 --- a/osu.Game/Overlays/News/Displays/FrontPageDisplay.cs +++ b/osu.Game/Overlays/News/Displays/FrontPageDisplay.cs @@ -13,16 +13,15 @@ using osuTK; namespace osu.Game.Overlays.News.Displays { - public class FrontPageDisplay : OverlayView + public class FrontPageDisplay : CompositeDrawable { - protected override bool PerformFetchOnApiStateChange => false; - - protected override APIRequest CreateRequest() => new GetNewsRequest(); + [Resolved] + private IAPIProvider api { get; set; } private FillFlowContainer content; private ShowMoreButton showMore; - private GetNewsRequest olderPostsRequest; + private GetNewsRequest request; private Cursor lastCursor; [BackgroundDependencyLoader] @@ -62,16 +61,27 @@ namespace osu.Game.Overlays.News.Displays { Top = 15 }, - Action = fetchOlderPosts, + Action = performFetch, Alpha = 0 } } }; + + performFetch(); + } + + private void performFetch() + { + request?.Cancel(); + + request = new GetNewsRequest(lastCursor); + request.Success += response => Schedule(() => onSuccess(response)); + api.PerformAsync(request); } private CancellationTokenSource cancellationToken; - protected override void OnSuccess(GetNewsResponse response) + private void onSuccess(GetNewsResponse response) { cancellationToken?.Cancel(); @@ -94,18 +104,9 @@ namespace osu.Game.Overlays.News.Displays }, (cancellationToken = new CancellationTokenSource()).Token); } - private void fetchOlderPosts() - { - olderPostsRequest?.Cancel(); - - olderPostsRequest = new GetNewsRequest(lastCursor); - olderPostsRequest.Success += response => Schedule(() => OnSuccess(response)); - API.PerformAsync(olderPostsRequest); - } - protected override void Dispose(bool isDisposing) { - olderPostsRequest?.Cancel(); + request?.Cancel(); cancellationToken?.Cancel(); base.Dispose(isDisposing); } diff --git a/osu.Game/Overlays/OverlayView.cs b/osu.Game/Overlays/OverlayView.cs index f73ca3aa6e..3e2c54c726 100644 --- a/osu.Game/Overlays/OverlayView.cs +++ b/osu.Game/Overlays/OverlayView.cs @@ -18,11 +18,6 @@ namespace osu.Game.Overlays public abstract class OverlayView : CompositeDrawable, IOnlineComponent where T : class { - /// - /// Whether we should perform fetch on api state change to online (true by default). - /// - protected virtual bool PerformFetchOnApiStateChange => true; - [Resolved] protected IAPIProvider API { get; private set; } @@ -38,10 +33,6 @@ namespace osu.Game.Overlays { base.LoadComplete(); API.Register(this); - - // If property is true - fetch will be triggered automatically by APIStateChanged and if not - we need to manually call it. - if (!PerformFetchOnApiStateChange) - PerformFetch(); } /// @@ -73,8 +64,7 @@ namespace osu.Game.Overlays switch (state) { case APIState.Online: - if (PerformFetchOnApiStateChange) - PerformFetch(); + PerformFetch(); break; } } From 5439099b7cb23253179c270b9f4ddc2002163ded Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Wed, 29 Jul 2020 10:34:09 +0300 Subject: [PATCH 040/434] Merge GlobalSkinConfiguration settings into the LegacySetting enum --- .../Gameplay/TestSceneHitObjectSamples.cs | 8 ++++---- .../Objects/Legacy/ConvertHitObjectParser.cs | 2 +- osu.Game/Skinning/GlobalSkinConfiguration.cs | 11 ----------- osu.Game/Skinning/LegacySkin.cs | 14 ++++---------- osu.Game/Skinning/LegacySkinConfiguration.cs | 2 ++ osu.Game/Skinning/LegacySkinExtensions.cs | 3 ++- osu.Game/Skinning/LegacySkinTransformer.cs | 3 ++- 7 files changed, 15 insertions(+), 28 deletions(-) delete mode 100644 osu.Game/Skinning/GlobalSkinConfiguration.cs diff --git a/osu.Game.Tests/Gameplay/TestSceneHitObjectSamples.cs b/osu.Game.Tests/Gameplay/TestSceneHitObjectSamples.cs index 737946e1e0..583400f579 100644 --- a/osu.Game.Tests/Gameplay/TestSceneHitObjectSamples.cs +++ b/osu.Game.Tests/Gameplay/TestSceneHitObjectSamples.cs @@ -6,9 +6,9 @@ using osu.Framework.IO.Stores; using osu.Framework.Testing; using osu.Game.Rulesets; using osu.Game.Rulesets.Osu; -using osu.Game.Skinning; using osu.Game.Tests.Beatmaps; using osu.Game.Tests.Resources; +using static osu.Game.Skinning.LegacySkinConfiguration; namespace osu.Game.Tests.Gameplay { @@ -190,7 +190,7 @@ namespace osu.Game.Tests.Gameplay } /// - /// Tests that when a custom sample bank is used, but is disabled, + /// Tests that when a custom sample bank is used, but is disabled, /// only the additional sound will be looked up. /// [Test] @@ -209,7 +209,7 @@ namespace osu.Game.Tests.Gameplay } /// - /// Tests that when a normal sample bank is used and is disabled, + /// Tests that when a normal sample bank is used and is disabled, /// the normal sound will be looked up anyway. /// [Test] @@ -226,6 +226,6 @@ namespace osu.Game.Tests.Gameplay } private void disableLayeredHitSounds() - => AddStep("set LayeredHitSounds to false", () => Skin.Configuration.ConfigDictionary[GlobalSkinConfiguration.LayeredHitSounds.ToString()] = "0"); + => AddStep("set LayeredHitSounds to false", () => Skin.Configuration.ConfigDictionary[LegacySetting.LayeredHitSounds.ToString()] = "0"); } } diff --git a/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs b/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs index 77075b2abe..9afc0ecaf4 100644 --- a/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs +++ b/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs @@ -434,7 +434,7 @@ namespace osu.Game.Rulesets.Objects.Legacy /// /// /// Layered hit samples are automatically added in all modes (except osu!mania), but can be disabled - /// using the skin config option. + /// using the skin config option. /// public bool IsLayered { get; set; } } diff --git a/osu.Game/Skinning/GlobalSkinConfiguration.cs b/osu.Game/Skinning/GlobalSkinConfiguration.cs deleted file mode 100644 index d405702ea5..0000000000 --- a/osu.Game/Skinning/GlobalSkinConfiguration.cs +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -namespace osu.Game.Skinning -{ - public enum GlobalSkinConfiguration - { - AnimationFramerate, - LayeredHitSounds, - } -} diff --git a/osu.Game/Skinning/LegacySkin.cs b/osu.Game/Skinning/LegacySkin.cs index 3bbeff9918..5843cde94d 100644 --- a/osu.Game/Skinning/LegacySkin.cs +++ b/osu.Game/Skinning/LegacySkin.cs @@ -120,15 +120,6 @@ namespace osu.Game.Skinning break; - case LegacySkinConfiguration.LegacySetting legacy: - switch (legacy) - { - case LegacySkinConfiguration.LegacySetting.Version: - return SkinUtils.As(new Bindable(Configuration.LegacyVersion ?? LegacySkinConfiguration.LATEST_VERSION)); - } - - break; - case SkinCustomColourLookup customColour: return SkinUtils.As(getCustomColour(Configuration, customColour.Lookup.ToString())); @@ -142,8 +133,11 @@ namespace osu.Game.Skinning break; + case LegacySkinConfiguration.LegacySetting s when s == LegacySkinConfiguration.LegacySetting.Version: + return SkinUtils.As(new Bindable(Configuration.LegacyVersion ?? LegacySkinConfiguration.LATEST_VERSION)); + default: - // handles lookups like GlobalSkinConfiguration + // handles lookups like some in LegacySkinConfiguration.LegacySetting try { diff --git a/osu.Game/Skinning/LegacySkinConfiguration.cs b/osu.Game/Skinning/LegacySkinConfiguration.cs index 027f5b8883..41b7aea34b 100644 --- a/osu.Game/Skinning/LegacySkinConfiguration.cs +++ b/osu.Game/Skinning/LegacySkinConfiguration.cs @@ -15,6 +15,8 @@ namespace osu.Game.Skinning public enum LegacySetting { Version, + AnimationFramerate, + LayeredHitSounds, } } } diff --git a/osu.Game/Skinning/LegacySkinExtensions.cs b/osu.Game/Skinning/LegacySkinExtensions.cs index 7cf41ef3c1..bb46dc8b9f 100644 --- a/osu.Game/Skinning/LegacySkinExtensions.cs +++ b/osu.Game/Skinning/LegacySkinExtensions.cs @@ -9,6 +9,7 @@ using osu.Framework.Graphics.Animations; using osu.Framework.Graphics.OpenGL.Textures; using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Textures; +using static osu.Game.Skinning.LegacySkinConfiguration; namespace osu.Game.Skinning { @@ -89,7 +90,7 @@ namespace osu.Game.Skinning { if (applyConfigFrameRate) { - var iniRate = source.GetConfig(GlobalSkinConfiguration.AnimationFramerate); + var iniRate = source.GetConfig(LegacySetting.AnimationFramerate); if (iniRate?.Value > 0) return 1000f / iniRate.Value; diff --git a/osu.Game/Skinning/LegacySkinTransformer.cs b/osu.Game/Skinning/LegacySkinTransformer.cs index 786056b932..ebc4757e75 100644 --- a/osu.Game/Skinning/LegacySkinTransformer.cs +++ b/osu.Game/Skinning/LegacySkinTransformer.cs @@ -8,6 +8,7 @@ using osu.Framework.Graphics.OpenGL.Textures; using osu.Framework.Graphics.Textures; using osu.Game.Audio; using osu.Game.Rulesets.Objects.Legacy; +using static osu.Game.Skinning.LegacySkinConfiguration; namespace osu.Game.Skinning { @@ -38,7 +39,7 @@ namespace osu.Game.Skinning if (!(sampleInfo is ConvertHitObjectParser.LegacyHitSampleInfo legacySample)) return Source.GetSample(sampleInfo); - var playLayeredHitSounds = GetConfig(GlobalSkinConfiguration.LayeredHitSounds); + var playLayeredHitSounds = GetConfig(LegacySetting.LayeredHitSounds); if (legacySample.IsLayered && playLayeredHitSounds?.Value == false) return new SampleChannelVirtual(); From 6473bf503b91bdc6d8b8acb474530e7125862152 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Thu, 30 Jul 2020 07:09:40 +0300 Subject: [PATCH 041/434] Remove use of `case when` --- osu.Game/Skinning/LegacySkin.cs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/osu.Game/Skinning/LegacySkin.cs b/osu.Game/Skinning/LegacySkin.cs index 5843cde94d..d98f8aba83 100644 --- a/osu.Game/Skinning/LegacySkin.cs +++ b/osu.Game/Skinning/LegacySkin.cs @@ -133,8 +133,14 @@ namespace osu.Game.Skinning break; - case LegacySkinConfiguration.LegacySetting s when s == LegacySkinConfiguration.LegacySetting.Version: - return SkinUtils.As(new Bindable(Configuration.LegacyVersion ?? LegacySkinConfiguration.LATEST_VERSION)); + case LegacySkinConfiguration.LegacySetting legacy: + switch (legacy) + { + case LegacySkinConfiguration.LegacySetting.Version: + return SkinUtils.As(new Bindable(Configuration.LegacyVersion ?? LegacySkinConfiguration.LATEST_VERSION)); + } + + goto default; default: // handles lookups like some in LegacySkinConfiguration.LegacySetting From 74f70136fdf80faa47d53772c7c4f386d5e6c3e1 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sat, 1 Aug 2020 06:00:24 +0300 Subject: [PATCH 042/434] Implement DashboardBeatmapPanel component --- .../TestSceneDashboardBeatmapPanel.cs | 52 ++++++ .../Dashboard/DashboardBeatmapPanel.cs | 159 ++++++++++++++++++ 2 files changed, 211 insertions(+) create mode 100644 osu.Game.Tests/Visual/UserInterface/TestSceneDashboardBeatmapPanel.cs create mode 100644 osu.Game/Overlays/Dashboard/Dashboard/DashboardBeatmapPanel.cs diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneDashboardBeatmapPanel.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneDashboardBeatmapPanel.cs new file mode 100644 index 0000000000..a61cd37513 --- /dev/null +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneDashboardBeatmapPanel.cs @@ -0,0 +1,52 @@ +// 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.Framework.Graphics; +using osu.Game.Overlays.Dashboard.Dashboard; +using osu.Game.Beatmaps; +using osu.Game.Overlays; +using osu.Framework.Allocation; +using osu.Game.Users; + +namespace osu.Game.Tests.Visual.UserInterface +{ + public class TestSceneDashboardBeatmapPanel : OsuTestScene + { + [Cached] + private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Purple); + + public TestSceneDashboardBeatmapPanel() + { + Add(new Container + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + AutoSizeAxes = Axes.Y, + Width = 300, + Child = new DashboardBeatmapPanel(beatmap_set) + }); + } + + private static readonly BeatmapSetInfo beatmap_set = new BeatmapSetInfo + { + Metadata = new BeatmapMetadata + { + Title = "Very Long Title (TV size) [TATOE]", + Artist = "This artist has a really long name how is it possible", + Author = new User + { + Username = "author", + Id = 100 + } + }, + OnlineInfo = new BeatmapSetOnlineInfo + { + Covers = new BeatmapSetOnlineCovers + { + Cover = "https://assets.ppy.sh/beatmaps/1189904/covers/cover.jpg?1595456608", + } + } + }; + } +} diff --git a/osu.Game/Overlays/Dashboard/Dashboard/DashboardBeatmapPanel.cs b/osu.Game/Overlays/Dashboard/Dashboard/DashboardBeatmapPanel.cs new file mode 100644 index 0000000000..84cb5ae46a --- /dev/null +++ b/osu.Game/Overlays/Dashboard/Dashboard/DashboardBeatmapPanel.cs @@ -0,0 +1,159 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Input.Events; +using osu.Game.Beatmaps; +using osu.Game.Beatmaps.Drawables; +using osu.Game.Graphics; +using osu.Game.Graphics.Containers; +using osu.Game.Graphics.Sprites; +using osuTK; + +namespace osu.Game.Overlays.Dashboard.Dashboard +{ + public class DashboardBeatmapPanel : OsuClickableContainer + { + [Resolved] + private OverlayColourProvider colourProvider { get; set; } + + [Resolved(canBeNull: true)] + private BeatmapSetOverlay beatmapOverlay { get; set; } + + private readonly BeatmapSetInfo setInfo; + + private Box background; + private SpriteIcon chevron; + + public DashboardBeatmapPanel(BeatmapSetInfo setInfo) + { + this.setInfo = setInfo; + } + + [BackgroundDependencyLoader] + private void load() + { + RelativeSizeAxes = Axes.X; + Height = 60; + Children = new Drawable[] + { + background = new Box + { + RelativeSizeAxes = Axes.Both, + Colour = colourProvider.Background3, + Alpha = 0 + }, + new Container + { + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding { Horizontal = 10 }, + Child = new GridContainer + { + RelativeSizeAxes = Axes.Both, + ColumnDimensions = new[] + { + new Dimension(GridSizeMode.Absolute, 70), + new Dimension(), + new Dimension(GridSizeMode.AutoSize) + }, + RowDimensions = new[] + { + new Dimension() + }, + Content = new[] + { + new Drawable[] + { + new Container + { + RelativeSizeAxes = Axes.Both, + Masking = true, + CornerRadius = 6, + Child = new UpdateableBeatmapSetCover + { + RelativeSizeAxes = Axes.Both, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + BeatmapSet = setInfo + } + }, + new Container + { + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding { Horizontal = 10 }, + Child = new FillFlowContainer + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + AutoSizeAxes = Axes.Y, + RelativeSizeAxes = Axes.X, + Direction = FillDirection.Vertical, + Children = new Drawable[] + { + new OsuSpriteText + { + RelativeSizeAxes = Axes.X, + Truncate = true, + Font = OsuFont.GetFont(weight: FontWeight.SemiBold), + Text = setInfo.Metadata.Title + }, + new OsuSpriteText + { + RelativeSizeAxes = Axes.X, + Truncate = true, + Font = OsuFont.GetFont(size: 12, weight: FontWeight.SemiBold), + Text = setInfo.Metadata.Artist + }, + new LinkFlowContainer(f => f.Font = OsuFont.GetFont(size: 10, weight: FontWeight.SemiBold)) + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y + }.With(c => + { + c.AddText("by "); + c.AddUserLink(setInfo.Metadata.Author); + }) + } + } + }, + chevron = new SpriteIcon + { + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight, + Size = new Vector2(16), + Icon = FontAwesome.Solid.ChevronRight, + Colour = colourProvider.Foreground1 + } + } + } + } + } + }; + + Action = () => + { + if (setInfo.OnlineBeatmapSetID.HasValue) + beatmapOverlay?.FetchAndShowBeatmapSet(setInfo.OnlineBeatmapSetID.Value); + }; + } + + protected override bool OnHover(HoverEvent e) + { + base.OnHover(e); + background.FadeIn(200, Easing.OutQuint); + chevron.FadeColour(colourProvider.Light1, 200, Easing.OutQuint); + return true; + } + + protected override void OnHoverLost(HoverLostEvent e) + { + base.OnHoverLost(e); + background.FadeOut(200, Easing.OutQuint); + chevron.FadeColour(colourProvider.Foreground1, 200, Easing.OutQuint); + } + } +} From ce47a34991ce574265aeaf37134c3d9f6de02cee Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sat, 1 Aug 2020 06:14:24 +0300 Subject: [PATCH 043/434] Implement DashboardNewBeatmapPanel component --- .../TestSceneDashboardBeatmapPanel.cs | 8 ++- .../Dashboard/DashboardBeatmapPanel.cs | 56 +++++++++++-------- .../Dashboard/DashboardNewBeatmapPanel.cs | 22 ++++++++ 3 files changed, 61 insertions(+), 25 deletions(-) create mode 100644 osu.Game/Overlays/Dashboard/Dashboard/DashboardNewBeatmapPanel.cs diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneDashboardBeatmapPanel.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneDashboardBeatmapPanel.cs index a61cd37513..5f1af012db 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneDashboardBeatmapPanel.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneDashboardBeatmapPanel.cs @@ -8,6 +8,7 @@ using osu.Game.Beatmaps; using osu.Game.Overlays; using osu.Framework.Allocation; using osu.Game.Users; +using System; namespace osu.Game.Tests.Visual.UserInterface { @@ -24,7 +25,7 @@ namespace osu.Game.Tests.Visual.UserInterface Origin = Anchor.Centre, AutoSizeAxes = Axes.Y, Width = 300, - Child = new DashboardBeatmapPanel(beatmap_set) + Child = new DashboardNewBeatmapPanel(beatmap_set) }); } @@ -33,7 +34,7 @@ namespace osu.Game.Tests.Visual.UserInterface Metadata = new BeatmapMetadata { Title = "Very Long Title (TV size) [TATOE]", - Artist = "This artist has a really long name how is it possible", + Artist = "This artist has a really long name how is this possible", Author = new User { Username = "author", @@ -45,7 +46,8 @@ namespace osu.Game.Tests.Visual.UserInterface Covers = new BeatmapSetOnlineCovers { Cover = "https://assets.ppy.sh/beatmaps/1189904/covers/cover.jpg?1595456608", - } + }, + Ranked = DateTimeOffset.Now } }; } diff --git a/osu.Game/Overlays/Dashboard/Dashboard/DashboardBeatmapPanel.cs b/osu.Game/Overlays/Dashboard/Dashboard/DashboardBeatmapPanel.cs index 84cb5ae46a..30b0086b8a 100644 --- a/osu.Game/Overlays/Dashboard/Dashboard/DashboardBeatmapPanel.cs +++ b/osu.Game/Overlays/Dashboard/Dashboard/DashboardBeatmapPanel.cs @@ -16,22 +16,22 @@ using osuTK; namespace osu.Game.Overlays.Dashboard.Dashboard { - public class DashboardBeatmapPanel : OsuClickableContainer + public abstract class DashboardBeatmapPanel : OsuClickableContainer { [Resolved] - private OverlayColourProvider colourProvider { get; set; } + protected OverlayColourProvider ColourProvider { get; private set; } [Resolved(canBeNull: true)] private BeatmapSetOverlay beatmapOverlay { get; set; } - private readonly BeatmapSetInfo setInfo; + protected readonly BeatmapSetInfo SetInfo; private Box background; private SpriteIcon chevron; - public DashboardBeatmapPanel(BeatmapSetInfo setInfo) + protected DashboardBeatmapPanel(BeatmapSetInfo setInfo) { - this.setInfo = setInfo; + SetInfo = setInfo; } [BackgroundDependencyLoader] @@ -44,7 +44,7 @@ namespace osu.Game.Overlays.Dashboard.Dashboard background = new Box { RelativeSizeAxes = Axes.Both, - Colour = colourProvider.Background3, + Colour = ColourProvider.Background3, Alpha = 0 }, new Container @@ -78,7 +78,7 @@ namespace osu.Game.Overlays.Dashboard.Dashboard RelativeSizeAxes = Axes.Both, Anchor = Anchor.Centre, Origin = Anchor.Centre, - BeatmapSet = setInfo + BeatmapSet = SetInfo } }, new Container @@ -99,24 +99,34 @@ namespace osu.Game.Overlays.Dashboard.Dashboard RelativeSizeAxes = Axes.X, Truncate = true, Font = OsuFont.GetFont(weight: FontWeight.SemiBold), - Text = setInfo.Metadata.Title + Text = SetInfo.Metadata.Title }, new OsuSpriteText { RelativeSizeAxes = Axes.X, Truncate = true, Font = OsuFont.GetFont(size: 12, weight: FontWeight.SemiBold), - Text = setInfo.Metadata.Artist + Text = SetInfo.Metadata.Artist }, - new LinkFlowContainer(f => f.Font = OsuFont.GetFont(size: 10, weight: FontWeight.SemiBold)) + new FillFlowContainer { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y - }.With(c => - { - c.AddText("by "); - c.AddUserLink(setInfo.Metadata.Author); - }) + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(5, 0), + Margin = new MarginPadding { Top = 2 }, + Children = new Drawable[] + { + new LinkFlowContainer(f => f.Font = OsuFont.GetFont(size: 10, weight: FontWeight.SemiBold)) + { + AutoSizeAxes = Axes.Both + }.With(c => + { + c.AddText("by "); + c.AddUserLink(SetInfo.Metadata.Author); + }), + CreateInfo() + } + } } } }, @@ -126,7 +136,7 @@ namespace osu.Game.Overlays.Dashboard.Dashboard Origin = Anchor.CentreRight, Size = new Vector2(16), Icon = FontAwesome.Solid.ChevronRight, - Colour = colourProvider.Foreground1 + Colour = ColourProvider.Foreground1 } } } @@ -136,16 +146,18 @@ namespace osu.Game.Overlays.Dashboard.Dashboard Action = () => { - if (setInfo.OnlineBeatmapSetID.HasValue) - beatmapOverlay?.FetchAndShowBeatmapSet(setInfo.OnlineBeatmapSetID.Value); + if (SetInfo.OnlineBeatmapSetID.HasValue) + beatmapOverlay?.FetchAndShowBeatmapSet(SetInfo.OnlineBeatmapSetID.Value); }; } + protected abstract Drawable CreateInfo(); + protected override bool OnHover(HoverEvent e) { base.OnHover(e); background.FadeIn(200, Easing.OutQuint); - chevron.FadeColour(colourProvider.Light1, 200, Easing.OutQuint); + chevron.FadeColour(ColourProvider.Light1, 200, Easing.OutQuint); return true; } @@ -153,7 +165,7 @@ namespace osu.Game.Overlays.Dashboard.Dashboard { base.OnHoverLost(e); background.FadeOut(200, Easing.OutQuint); - chevron.FadeColour(colourProvider.Foreground1, 200, Easing.OutQuint); + chevron.FadeColour(ColourProvider.Foreground1, 200, Easing.OutQuint); } } } diff --git a/osu.Game/Overlays/Dashboard/Dashboard/DashboardNewBeatmapPanel.cs b/osu.Game/Overlays/Dashboard/Dashboard/DashboardNewBeatmapPanel.cs new file mode 100644 index 0000000000..6d2ec7ae37 --- /dev/null +++ b/osu.Game/Overlays/Dashboard/Dashboard/DashboardNewBeatmapPanel.cs @@ -0,0 +1,22 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Graphics; +using osu.Game.Beatmaps; +using osu.Game.Graphics; + +namespace osu.Game.Overlays.Dashboard.Dashboard +{ + public class DashboardNewBeatmapPanel : DashboardBeatmapPanel + { + public DashboardNewBeatmapPanel(BeatmapSetInfo setInfo) + : base(setInfo) + { + } + + protected override Drawable CreateInfo() => new DrawableDate(SetInfo.OnlineInfo.Ranked.Value, 10, false) + { + Colour = ColourProvider.Foreground1 + }; + } +} From 7624804edfacb185dc456c18eb32648287613665 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sat, 1 Aug 2020 06:23:06 +0300 Subject: [PATCH 044/434] Implement DashboardPopularBeatmapPanel component --- .../TestSceneDashboardBeatmapPanel.cs | 35 ++++++++++++++-- .../Dashboard/DashboardBeatmapPanel.cs | 2 +- .../Dashboard/DashboardPopularBeatmapPanel.cs | 42 +++++++++++++++++++ 3 files changed, 75 insertions(+), 4 deletions(-) create mode 100644 osu.Game/Overlays/Dashboard/Dashboard/DashboardPopularBeatmapPanel.cs diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneDashboardBeatmapPanel.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneDashboardBeatmapPanel.cs index 5f1af012db..10682490ae 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneDashboardBeatmapPanel.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneDashboardBeatmapPanel.cs @@ -9,6 +9,7 @@ using osu.Game.Overlays; using osu.Framework.Allocation; using osu.Game.Users; using System; +using osuTK; namespace osu.Game.Tests.Visual.UserInterface { @@ -19,17 +20,23 @@ namespace osu.Game.Tests.Visual.UserInterface public TestSceneDashboardBeatmapPanel() { - Add(new Container + Add(new FillFlowContainer { Anchor = Anchor.Centre, Origin = Anchor.Centre, AutoSizeAxes = Axes.Y, Width = 300, - Child = new DashboardNewBeatmapPanel(beatmap_set) + Spacing = new Vector2(0, 10), + Direction = FillDirection.Vertical, + Children = new Drawable[] + { + new DashboardNewBeatmapPanel(new_beatmap_set), + new DashboardPopularBeatmapPanel(popular_beatmap_set) + } }); } - private static readonly BeatmapSetInfo beatmap_set = new BeatmapSetInfo + private static readonly BeatmapSetInfo new_beatmap_set = new BeatmapSetInfo { Metadata = new BeatmapMetadata { @@ -50,5 +57,27 @@ namespace osu.Game.Tests.Visual.UserInterface Ranked = DateTimeOffset.Now } }; + + private static readonly BeatmapSetInfo popular_beatmap_set = new BeatmapSetInfo + { + Metadata = new BeatmapMetadata + { + Title = "Title", + Artist = "Artist", + Author = new User + { + Username = "author", + Id = 100 + } + }, + OnlineInfo = new BeatmapSetOnlineInfo + { + Covers = new BeatmapSetOnlineCovers + { + Cover = "https://assets.ppy.sh/beatmaps/1189904/covers/cover.jpg?1595456608", + }, + FavouriteCount = 100 + } + }; } } diff --git a/osu.Game/Overlays/Dashboard/Dashboard/DashboardBeatmapPanel.cs b/osu.Game/Overlays/Dashboard/Dashboard/DashboardBeatmapPanel.cs index 30b0086b8a..fc70d9d40a 100644 --- a/osu.Game/Overlays/Dashboard/Dashboard/DashboardBeatmapPanel.cs +++ b/osu.Game/Overlays/Dashboard/Dashboard/DashboardBeatmapPanel.cs @@ -112,7 +112,7 @@ namespace osu.Game.Overlays.Dashboard.Dashboard { AutoSizeAxes = Axes.Both, Direction = FillDirection.Horizontal, - Spacing = new Vector2(5, 0), + Spacing = new Vector2(3, 0), Margin = new MarginPadding { Top = 2 }, Children = new Drawable[] { diff --git a/osu.Game/Overlays/Dashboard/Dashboard/DashboardPopularBeatmapPanel.cs b/osu.Game/Overlays/Dashboard/Dashboard/DashboardPopularBeatmapPanel.cs new file mode 100644 index 0000000000..04bb261dce --- /dev/null +++ b/osu.Game/Overlays/Dashboard/Dashboard/DashboardPopularBeatmapPanel.cs @@ -0,0 +1,42 @@ +// 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.Game.Beatmaps; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; +using osuTK; + +namespace osu.Game.Overlays.Dashboard.Dashboard +{ + public class DashboardPopularBeatmapPanel : DashboardBeatmapPanel + { + public DashboardPopularBeatmapPanel(BeatmapSetInfo setInfo) + : base(setInfo) + { + } + + protected override Drawable CreateInfo() => new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(3, 0), + Colour = ColourProvider.Foreground1, + Children = new Drawable[] + { + new SpriteIcon + { + Size = new Vector2(10), + Icon = FontAwesome.Solid.Heart + }, + new OsuSpriteText + { + Font = OsuFont.GetFont(size: 10), + Text = SetInfo.OnlineInfo.FavouriteCount.ToString() + } + } + }; + } +} From b5f688e63aeb9168cb4d73c651889dab270871a3 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sat, 1 Aug 2020 07:04:39 +0300 Subject: [PATCH 045/434] Implement DashboardBeatmapListing component --- .../TestSceneDashboardBeatmapListing.cs | 144 ++++++++++++++++++ .../TestSceneDashboardBeatmapPanel.cs | 83 ---------- .../Dashboard/DashboardBeatmapListing.cs | 43 ++++++ .../Dashboard/DashboardBeatmapPanel.cs | 2 +- .../Dashboard/DashboardNewBeatmapPanel.cs | 3 +- .../Dashboard/DrawableBeatmapsList.cs | 57 +++++++ .../Dashboard/DrawableNewBeatmapsList.cs | 20 +++ .../Dashboard/DrawablePopularBeatmapsList.cs | 20 +++ 8 files changed, 287 insertions(+), 85 deletions(-) create mode 100644 osu.Game.Tests/Visual/UserInterface/TestSceneDashboardBeatmapListing.cs delete mode 100644 osu.Game.Tests/Visual/UserInterface/TestSceneDashboardBeatmapPanel.cs create mode 100644 osu.Game/Overlays/Dashboard/Dashboard/DashboardBeatmapListing.cs create mode 100644 osu.Game/Overlays/Dashboard/Dashboard/DrawableBeatmapsList.cs create mode 100644 osu.Game/Overlays/Dashboard/Dashboard/DrawableNewBeatmapsList.cs create mode 100644 osu.Game/Overlays/Dashboard/Dashboard/DrawablePopularBeatmapsList.cs diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneDashboardBeatmapListing.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneDashboardBeatmapListing.cs new file mode 100644 index 0000000000..be0cc5187e --- /dev/null +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneDashboardBeatmapListing.cs @@ -0,0 +1,144 @@ +// 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.Framework.Graphics; +using osu.Game.Overlays.Dashboard.Dashboard; +using osu.Game.Beatmaps; +using osu.Game.Overlays; +using osu.Framework.Allocation; +using osu.Game.Users; +using System; +using osu.Framework.Graphics.Shapes; +using System.Collections.Generic; + +namespace osu.Game.Tests.Visual.UserInterface +{ + public class TestSceneDashboardBeatmapListing : OsuTestScene + { + [Cached] + private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Purple); + + private readonly Container content; + + public TestSceneDashboardBeatmapListing() + { + Add(content = new Container + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + AutoSizeAxes = Axes.Y, + Width = 300, + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = colourProvider.Background4 + }, + new DashboardBeatmapListing(new_beatmaps, popular_beatmaps) + } + }); + } + + protected override void LoadComplete() + { + base.LoadComplete(); + + AddStep("Set width to 500", () => content.ResizeWidthTo(500, 500)); + AddStep("Set width to 300", () => content.ResizeWidthTo(300, 500)); + } + + private static readonly List new_beatmaps = new List + { + new BeatmapSetInfo + { + Metadata = new BeatmapMetadata + { + Title = "Very Long Title (TV size) [TATOE]", + Artist = "This artist has a really long name how is this possible", + Author = new User + { + Username = "author", + Id = 100 + } + }, + OnlineInfo = new BeatmapSetOnlineInfo + { + Covers = new BeatmapSetOnlineCovers + { + Cover = "https://assets.ppy.sh/beatmaps/1189904/covers/cover.jpg?1595456608", + }, + Ranked = DateTimeOffset.Now + } + }, + new BeatmapSetInfo + { + Metadata = new BeatmapMetadata + { + Title = "Very Long Title (TV size) [TATOE]", + Artist = "This artist has a really long name how is this possible", + Author = new User + { + Username = "author", + Id = 100 + } + }, + OnlineInfo = new BeatmapSetOnlineInfo + { + Covers = new BeatmapSetOnlineCovers + { + Cover = "https://assets.ppy.sh/beatmaps/1189904/covers/cover.jpg?1595456608", + }, + Ranked = DateTimeOffset.MinValue + } + } + }; + + private static readonly List popular_beatmaps = new List + { + new BeatmapSetInfo + { + Metadata = new BeatmapMetadata + { + Title = "Title", + Artist = "Artist", + Author = new User + { + Username = "author", + Id = 100 + } + }, + OnlineInfo = new BeatmapSetOnlineInfo + { + Covers = new BeatmapSetOnlineCovers + { + Cover = "https://assets.ppy.sh/beatmaps/1079428/covers/cover.jpg?1595295586", + }, + FavouriteCount = 100 + } + }, + new BeatmapSetInfo + { + Metadata = new BeatmapMetadata + { + Title = "Title 2", + Artist = "Artist 2", + Author = new User + { + Username = "someone", + Id = 100 + } + }, + OnlineInfo = new BeatmapSetOnlineInfo + { + Covers = new BeatmapSetOnlineCovers + { + Cover = "https://assets.ppy.sh/beatmaps/1079428/covers/cover.jpg?1595295586", + }, + FavouriteCount = 10 + } + } + }; + } +} diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneDashboardBeatmapPanel.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneDashboardBeatmapPanel.cs deleted file mode 100644 index 10682490ae..0000000000 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneDashboardBeatmapPanel.cs +++ /dev/null @@ -1,83 +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.Containers; -using osu.Framework.Graphics; -using osu.Game.Overlays.Dashboard.Dashboard; -using osu.Game.Beatmaps; -using osu.Game.Overlays; -using osu.Framework.Allocation; -using osu.Game.Users; -using System; -using osuTK; - -namespace osu.Game.Tests.Visual.UserInterface -{ - public class TestSceneDashboardBeatmapPanel : OsuTestScene - { - [Cached] - private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Purple); - - public TestSceneDashboardBeatmapPanel() - { - Add(new FillFlowContainer - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - AutoSizeAxes = Axes.Y, - Width = 300, - Spacing = new Vector2(0, 10), - Direction = FillDirection.Vertical, - Children = new Drawable[] - { - new DashboardNewBeatmapPanel(new_beatmap_set), - new DashboardPopularBeatmapPanel(popular_beatmap_set) - } - }); - } - - private static readonly BeatmapSetInfo new_beatmap_set = new BeatmapSetInfo - { - Metadata = new BeatmapMetadata - { - Title = "Very Long Title (TV size) [TATOE]", - Artist = "This artist has a really long name how is this possible", - Author = new User - { - Username = "author", - Id = 100 - } - }, - OnlineInfo = new BeatmapSetOnlineInfo - { - Covers = new BeatmapSetOnlineCovers - { - Cover = "https://assets.ppy.sh/beatmaps/1189904/covers/cover.jpg?1595456608", - }, - Ranked = DateTimeOffset.Now - } - }; - - private static readonly BeatmapSetInfo popular_beatmap_set = new BeatmapSetInfo - { - Metadata = new BeatmapMetadata - { - Title = "Title", - Artist = "Artist", - Author = new User - { - Username = "author", - Id = 100 - } - }, - OnlineInfo = new BeatmapSetOnlineInfo - { - Covers = new BeatmapSetOnlineCovers - { - Cover = "https://assets.ppy.sh/beatmaps/1189904/covers/cover.jpg?1595456608", - }, - FavouriteCount = 100 - } - }; - } -} diff --git a/osu.Game/Overlays/Dashboard/Dashboard/DashboardBeatmapListing.cs b/osu.Game/Overlays/Dashboard/Dashboard/DashboardBeatmapListing.cs new file mode 100644 index 0000000000..26c892174d --- /dev/null +++ b/osu.Game/Overlays/Dashboard/Dashboard/DashboardBeatmapListing.cs @@ -0,0 +1,43 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Collections.Generic; +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Game.Beatmaps; +using osuTK; + +namespace osu.Game.Overlays.Dashboard.Dashboard +{ + public class DashboardBeatmapListing : CompositeDrawable + { + private readonly List newBeatmaps; + private readonly List popularBeatmaps; + + public DashboardBeatmapListing(List newBeatmaps, List popularBeatmaps) + { + this.newBeatmaps = newBeatmaps; + this.popularBeatmaps = popularBeatmaps; + } + + [BackgroundDependencyLoader] + private void load() + { + RelativeSizeAxes = Axes.X; + AutoSizeAxes = Axes.Y; + InternalChild = new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Vertical, + Spacing = new Vector2(0, 10), + Children = new DrawableBeatmapsList[] + { + new DrawableNewBeatmapsList(newBeatmaps), + new DrawablePopularBeatmapsList(popularBeatmaps) + } + }; + } + } +} diff --git a/osu.Game/Overlays/Dashboard/Dashboard/DashboardBeatmapPanel.cs b/osu.Game/Overlays/Dashboard/Dashboard/DashboardBeatmapPanel.cs index fc70d9d40a..bb35ddd07c 100644 --- a/osu.Game/Overlays/Dashboard/Dashboard/DashboardBeatmapPanel.cs +++ b/osu.Game/Overlays/Dashboard/Dashboard/DashboardBeatmapPanel.cs @@ -114,7 +114,7 @@ namespace osu.Game.Overlays.Dashboard.Dashboard Direction = FillDirection.Horizontal, Spacing = new Vector2(3, 0), Margin = new MarginPadding { Top = 2 }, - Children = new Drawable[] + Children = new[] { new LinkFlowContainer(f => f.Font = OsuFont.GetFont(size: 10, weight: FontWeight.SemiBold)) { diff --git a/osu.Game/Overlays/Dashboard/Dashboard/DashboardNewBeatmapPanel.cs b/osu.Game/Overlays/Dashboard/Dashboard/DashboardNewBeatmapPanel.cs index 6d2ec7ae37..c4782b733d 100644 --- a/osu.Game/Overlays/Dashboard/Dashboard/DashboardNewBeatmapPanel.cs +++ b/osu.Game/Overlays/Dashboard/Dashboard/DashboardNewBeatmapPanel.cs @@ -1,6 +1,7 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System; using osu.Framework.Graphics; using osu.Game.Beatmaps; using osu.Game.Graphics; @@ -14,7 +15,7 @@ namespace osu.Game.Overlays.Dashboard.Dashboard { } - protected override Drawable CreateInfo() => new DrawableDate(SetInfo.OnlineInfo.Ranked.Value, 10, false) + protected override Drawable CreateInfo() => new DrawableDate(SetInfo.OnlineInfo.Ranked ?? DateTimeOffset.Now, 10, false) { Colour = ColourProvider.Foreground1 }; diff --git a/osu.Game/Overlays/Dashboard/Dashboard/DrawableBeatmapsList.cs b/osu.Game/Overlays/Dashboard/Dashboard/DrawableBeatmapsList.cs new file mode 100644 index 0000000000..dfe483a962 --- /dev/null +++ b/osu.Game/Overlays/Dashboard/Dashboard/DrawableBeatmapsList.cs @@ -0,0 +1,57 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Collections.Generic; +using System.Linq; +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Game.Beatmaps; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; +using osuTK; + +namespace osu.Game.Overlays.Dashboard.Dashboard +{ + public abstract class DrawableBeatmapsList : CompositeDrawable + { + private readonly List beatmaps; + + protected DrawableBeatmapsList(List beatmaps) + { + this.beatmaps = beatmaps; + } + + [BackgroundDependencyLoader] + private void load(OverlayColourProvider colourProvider) + { + FillFlowContainer flow; + + RelativeSizeAxes = Axes.X; + AutoSizeAxes = Axes.Y; + InternalChild = flow = new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Vertical, + Spacing = new Vector2(0, 10), + Children = new Drawable[] + { + new OsuSpriteText + { + Font = OsuFont.GetFont(size: 16, weight: FontWeight.Bold), + Colour = colourProvider.Light1, + Text = CreateTitle(), + Padding = new MarginPadding { Left = 10 } + } + } + }; + + flow.AddRange(beatmaps.Select(CreateBeatmapPanel)); + } + + protected abstract string CreateTitle(); + + protected abstract DashboardBeatmapPanel CreateBeatmapPanel(BeatmapSetInfo setInfo); + } +} diff --git a/osu.Game/Overlays/Dashboard/Dashboard/DrawableNewBeatmapsList.cs b/osu.Game/Overlays/Dashboard/Dashboard/DrawableNewBeatmapsList.cs new file mode 100644 index 0000000000..e89495dc99 --- /dev/null +++ b/osu.Game/Overlays/Dashboard/Dashboard/DrawableNewBeatmapsList.cs @@ -0,0 +1,20 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Collections.Generic; +using osu.Game.Beatmaps; + +namespace osu.Game.Overlays.Dashboard.Dashboard +{ + public class DrawableNewBeatmapsList : DrawableBeatmapsList + { + public DrawableNewBeatmapsList(List beatmaps) + : base(beatmaps) + { + } + + protected override DashboardBeatmapPanel CreateBeatmapPanel(BeatmapSetInfo setInfo) => new DashboardNewBeatmapPanel(setInfo); + + protected override string CreateTitle() => "New Ranked Beatmaps"; + } +} diff --git a/osu.Game/Overlays/Dashboard/Dashboard/DrawablePopularBeatmapsList.cs b/osu.Game/Overlays/Dashboard/Dashboard/DrawablePopularBeatmapsList.cs new file mode 100644 index 0000000000..8076e86ed0 --- /dev/null +++ b/osu.Game/Overlays/Dashboard/Dashboard/DrawablePopularBeatmapsList.cs @@ -0,0 +1,20 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Collections.Generic; +using osu.Game.Beatmaps; + +namespace osu.Game.Overlays.Dashboard.Dashboard +{ + public class DrawablePopularBeatmapsList : DrawableBeatmapsList + { + public DrawablePopularBeatmapsList(List beatmaps) + : base(beatmaps) + { + } + + protected override DashboardBeatmapPanel CreateBeatmapPanel(BeatmapSetInfo setInfo) => new DashboardPopularBeatmapPanel(setInfo); + + protected override string CreateTitle() => "Popular Beatmaps"; + } +} From 5b1e3e86220e7ba3b8024fa9ff6cfc035e34a82c Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sat, 1 Aug 2020 09:11:53 +0300 Subject: [PATCH 046/434] Remove redundant FillFlowContainer from DashboardBeatmapPanel --- .../Dashboard/DashboardBeatmapPanel.cs | 29 +++++++------------ 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/osu.Game/Overlays/Dashboard/Dashboard/DashboardBeatmapPanel.cs b/osu.Game/Overlays/Dashboard/Dashboard/DashboardBeatmapPanel.cs index bb35ddd07c..61324fdc7f 100644 --- a/osu.Game/Overlays/Dashboard/Dashboard/DashboardBeatmapPanel.cs +++ b/osu.Game/Overlays/Dashboard/Dashboard/DashboardBeatmapPanel.cs @@ -108,25 +108,18 @@ namespace osu.Game.Overlays.Dashboard.Dashboard Font = OsuFont.GetFont(size: 12, weight: FontWeight.SemiBold), Text = SetInfo.Metadata.Artist }, - new FillFlowContainer + new LinkFlowContainer(f => f.Font = OsuFont.GetFont(size: 10, weight: FontWeight.SemiBold)) { - AutoSizeAxes = Axes.Both, - Direction = FillDirection.Horizontal, - Spacing = new Vector2(3, 0), - Margin = new MarginPadding { Top = 2 }, - Children = new[] - { - new LinkFlowContainer(f => f.Font = OsuFont.GetFont(size: 10, weight: FontWeight.SemiBold)) - { - AutoSizeAxes = Axes.Both - }.With(c => - { - c.AddText("by "); - c.AddUserLink(SetInfo.Metadata.Author); - }), - CreateInfo() - } - } + AutoSizeAxes = Axes.Y, + RelativeSizeAxes = Axes.X, + Spacing = new Vector2(3), + Margin = new MarginPadding { Top = 2 } + }.With(c => + { + c.AddText("by"); + c.AddUserLink(SetInfo.Metadata.Author); + c.AddArbitraryDrawable(CreateInfo()); + }) } } }, From 2190e6443a0265ba4d4db20a44b207b3a63a4760 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Sat, 1 Aug 2020 10:02:46 +0300 Subject: [PATCH 047/434] Apply height constraints to all settings dropdown --- osu.Game/Overlays/Settings/Sections/SkinSection.cs | 2 -- osu.Game/Overlays/Settings/SettingsDropdown.cs | 2 ++ 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Settings/Sections/SkinSection.cs b/osu.Game/Overlays/Settings/Sections/SkinSection.cs index 04390a1193..596d3a9801 100644 --- a/osu.Game/Overlays/Settings/Sections/SkinSection.cs +++ b/osu.Game/Overlays/Settings/Sections/SkinSection.cs @@ -116,8 +116,6 @@ namespace osu.Game.Overlays.Settings.Sections private class SkinDropdownControl : DropdownControl { protected override string GenerateItemText(SkinInfo item) => item.ToString(); - - protected override DropdownMenu CreateMenu() => base.CreateMenu().With(m => m.MaxHeight = 200); } } diff --git a/osu.Game/Overlays/Settings/SettingsDropdown.cs b/osu.Game/Overlays/Settings/SettingsDropdown.cs index 167061f485..1175ddaab8 100644 --- a/osu.Game/Overlays/Settings/SettingsDropdown.cs +++ b/osu.Game/Overlays/Settings/SettingsDropdown.cs @@ -38,6 +38,8 @@ namespace osu.Game.Overlays.Settings Margin = new MarginPadding { Top = 5 }; RelativeSizeAxes = Axes.X; } + + protected override DropdownMenu CreateMenu() => base.CreateMenu().With(m => m.MaxHeight = 200); } } } From 5f52701273a8b41205bcd7a1c24fd02bb658560c Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Sat, 1 Aug 2020 10:11:34 +0300 Subject: [PATCH 048/434] Remove no longer necessary custom dropdown --- .../Ladder/Components/LadderEditorSettings.cs | 2 +- .../Components/LadderSettingsDropdown.cs | 26 ------------------- .../Ladder/Components/SettingsTeamDropdown.cs | 3 ++- 3 files changed, 3 insertions(+), 28 deletions(-) delete mode 100644 osu.Game.Tournament/Screens/Ladder/Components/LadderSettingsDropdown.cs diff --git a/osu.Game.Tournament/Screens/Ladder/Components/LadderEditorSettings.cs b/osu.Game.Tournament/Screens/Ladder/Components/LadderEditorSettings.cs index 4aea7ff4c0..fa530ea2c4 100644 --- a/osu.Game.Tournament/Screens/Ladder/Components/LadderEditorSettings.cs +++ b/osu.Game.Tournament/Screens/Ladder/Components/LadderEditorSettings.cs @@ -81,7 +81,7 @@ namespace osu.Game.Tournament.Screens.Ladder.Components { } - private class SettingsRoundDropdown : LadderSettingsDropdown + private class SettingsRoundDropdown : SettingsDropdown { public SettingsRoundDropdown(BindableList rounds) { diff --git a/osu.Game.Tournament/Screens/Ladder/Components/LadderSettingsDropdown.cs b/osu.Game.Tournament/Screens/Ladder/Components/LadderSettingsDropdown.cs deleted file mode 100644 index 347e4d91e0..0000000000 --- a/osu.Game.Tournament/Screens/Ladder/Components/LadderSettingsDropdown.cs +++ /dev/null @@ -1,26 +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.Game.Graphics.UserInterface; -using osu.Game.Overlays.Settings; - -namespace osu.Game.Tournament.Screens.Ladder.Components -{ - public class LadderSettingsDropdown : SettingsDropdown - { - protected override OsuDropdown CreateDropdown() => new DropdownControl(); - - private new class DropdownControl : SettingsDropdown.DropdownControl - { - protected override DropdownMenu CreateMenu() => new Menu(); - - private new class Menu : OsuDropdownMenu - { - public Menu() - { - MaxHeight = 200; - } - } - } - } -} diff --git a/osu.Game.Tournament/Screens/Ladder/Components/SettingsTeamDropdown.cs b/osu.Game.Tournament/Screens/Ladder/Components/SettingsTeamDropdown.cs index a630e51e44..6604e3a313 100644 --- a/osu.Game.Tournament/Screens/Ladder/Components/SettingsTeamDropdown.cs +++ b/osu.Game.Tournament/Screens/Ladder/Components/SettingsTeamDropdown.cs @@ -6,11 +6,12 @@ using System.Collections.Specialized; using System.Linq; using osu.Framework.Bindables; using osu.Framework.Extensions.IEnumerableExtensions; +using osu.Game.Overlays.Settings; using osu.Game.Tournament.Models; namespace osu.Game.Tournament.Screens.Ladder.Components { - public class SettingsTeamDropdown : LadderSettingsDropdown + public class SettingsTeamDropdown : SettingsDropdown { public SettingsTeamDropdown(BindableList teams) { From f4128083312843d9594c1b96d212914a43fee60b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sun, 2 Aug 2020 12:57:15 +0200 Subject: [PATCH 049/434] Check rotation with bigger tolerance to account for damp --- .../TestSceneSpinnerRotation.cs | 44 ++++++++++++++----- 1 file changed, 33 insertions(+), 11 deletions(-) diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerRotation.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerRotation.cs index 319d326a01..e4d89fb402 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerRotation.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerRotation.cs @@ -1,6 +1,7 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System; using System.Collections.Generic; using System.Linq; using NUnit.Framework; @@ -60,39 +61,60 @@ namespace osu.Game.Rulesets.Osu.Tests [Test] public void TestSpinnerRewindingRotation() { + double trackerRotationTolerance = 0; + addSeekStep(5000); + AddStep("calculate rotation tolerance", () => + { + trackerRotationTolerance = Math.Abs(drawableSpinner.RotationTracker.Rotation * 0.1f); + }); AddAssert("is disc rotation not almost 0", () => !Precision.AlmostEquals(drawableSpinner.RotationTracker.Rotation, 0, 100)); AddAssert("is disc rotation absolute not almost 0", () => !Precision.AlmostEquals(drawableSpinner.RotationTracker.CumulativeRotation, 0, 100)); addSeekStep(0); - AddAssert("is disc rotation almost 0", () => Precision.AlmostEquals(drawableSpinner.RotationTracker.Rotation, 0, 100)); + AddAssert("is disc rotation almost 0", () => Precision.AlmostEquals(drawableSpinner.RotationTracker.Rotation, 0, trackerRotationTolerance)); AddAssert("is disc rotation absolute almost 0", () => Precision.AlmostEquals(drawableSpinner.RotationTracker.CumulativeRotation, 0, 100)); } [Test] public void TestSpinnerMiddleRewindingRotation() { - double finalAbsoluteDiscRotation = 0, finalRelativeDiscRotation = 0, finalSpinnerSymbolRotation = 0; + double finalCumulativeTrackerRotation = 0; + double finalTrackerRotation = 0, trackerRotationTolerance = 0; + double finalSpinnerSymbolRotation = 0, spinnerSymbolRotationTolerance = 0; addSeekStep(5000); - AddStep("retrieve disc relative rotation", () => finalRelativeDiscRotation = drawableSpinner.RotationTracker.Rotation); - AddStep("retrieve disc absolute rotation", () => finalAbsoluteDiscRotation = drawableSpinner.RotationTracker.CumulativeRotation); - AddStep("retrieve spinner symbol rotation", () => finalSpinnerSymbolRotation = spinnerSymbol.Rotation); + AddStep("retrieve disc rotation", () => + { + finalTrackerRotation = drawableSpinner.RotationTracker.Rotation; + trackerRotationTolerance = Math.Abs(finalTrackerRotation * 0.05f); + }); + AddStep("retrieve spinner symbol rotation", () => + { + finalSpinnerSymbolRotation = spinnerSymbol.Rotation; + spinnerSymbolRotationTolerance = Math.Abs(finalSpinnerSymbolRotation * 0.05f); + }); + AddStep("retrieve cumulative disc rotation", () => finalCumulativeTrackerRotation = drawableSpinner.RotationTracker.CumulativeRotation); addSeekStep(2500); AddUntilStep("disc rotation rewound", // we want to make sure that the rotation at time 2500 is in the same direction as at time 5000, but about half-way in. - () => Precision.AlmostEquals(drawableSpinner.RotationTracker.Rotation, finalRelativeDiscRotation / 2, 100)); + // due to the exponential damping applied we're allowing a larger margin of error of about 10% + // (5% relative to the final rotation value, but we're half-way through the spin). + () => Precision.AlmostEquals(drawableSpinner.RotationTracker.Rotation, finalTrackerRotation / 2, trackerRotationTolerance)); AddUntilStep("symbol rotation rewound", - () => Precision.AlmostEquals(spinnerSymbol.Rotation, finalSpinnerSymbolRotation / 2, 100)); + () => Precision.AlmostEquals(spinnerSymbol.Rotation, finalSpinnerSymbolRotation / 2, spinnerSymbolRotationTolerance)); + AddAssert("is cumulative rotation rewound", + // cumulative rotation is not damped, so we're treating it as the "ground truth" and allowing a comparatively smaller margin of error. + () => Precision.AlmostEquals(drawableSpinner.RotationTracker.CumulativeRotation, finalCumulativeTrackerRotation / 2, 100)); addSeekStep(5000); AddAssert("is disc rotation almost same", - () => Precision.AlmostEquals(drawableSpinner.RotationTracker.Rotation, finalRelativeDiscRotation, 100)); + () => Precision.AlmostEquals(drawableSpinner.RotationTracker.Rotation, finalTrackerRotation, trackerRotationTolerance)); AddAssert("is symbol rotation almost same", - () => Precision.AlmostEquals(spinnerSymbol.Rotation, finalSpinnerSymbolRotation, 100)); - AddAssert("is disc rotation absolute almost same", - () => Precision.AlmostEquals(drawableSpinner.RotationTracker.CumulativeRotation, finalAbsoluteDiscRotation, 100)); + () => Precision.AlmostEquals(spinnerSymbol.Rotation, finalSpinnerSymbolRotation, spinnerSymbolRotationTolerance)); + AddAssert("is cumulative rotation almost same", + () => Precision.AlmostEquals(drawableSpinner.RotationTracker.CumulativeRotation, finalCumulativeTrackerRotation, 100)); } [Test] From efb08aeed32b1787e79b7ebd0e7501a874cf559c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sun, 2 Aug 2020 14:54:41 +0200 Subject: [PATCH 050/434] Switch unnecessary wait steps to asserts --- osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerRotation.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerRotation.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerRotation.cs index e4d89fb402..b46964e8b7 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerRotation.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerRotation.cs @@ -97,12 +97,12 @@ namespace osu.Game.Rulesets.Osu.Tests AddStep("retrieve cumulative disc rotation", () => finalCumulativeTrackerRotation = drawableSpinner.RotationTracker.CumulativeRotation); addSeekStep(2500); - AddUntilStep("disc rotation rewound", + AddAssert("disc rotation rewound", // we want to make sure that the rotation at time 2500 is in the same direction as at time 5000, but about half-way in. // due to the exponential damping applied we're allowing a larger margin of error of about 10% // (5% relative to the final rotation value, but we're half-way through the spin). () => Precision.AlmostEquals(drawableSpinner.RotationTracker.Rotation, finalTrackerRotation / 2, trackerRotationTolerance)); - AddUntilStep("symbol rotation rewound", + AddAssert("symbol rotation rewound", () => Precision.AlmostEquals(spinnerSymbol.Rotation, finalSpinnerSymbolRotation / 2, spinnerSymbolRotationTolerance)); AddAssert("is cumulative rotation rewound", // cumulative rotation is not damped, so we're treating it as the "ground truth" and allowing a comparatively smaller margin of error. From 3e5c3e256d3f0747afd8f89f05e622eba1d035ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sun, 2 Aug 2020 19:46:29 +0200 Subject: [PATCH 051/434] Extract method for performing generic config lookup --- osu.Game/Skinning/LegacySkin.cs | 46 ++++++++++++++++++--------------- 1 file changed, 25 insertions(+), 21 deletions(-) diff --git a/osu.Game/Skinning/LegacySkin.cs b/osu.Game/Skinning/LegacySkin.cs index d98f8aba83..d1acc51bed 100644 --- a/osu.Game/Skinning/LegacySkin.cs +++ b/osu.Game/Skinning/LegacySkin.cs @@ -143,27 +143,7 @@ namespace osu.Game.Skinning goto default; default: - // handles lookups like some in LegacySkinConfiguration.LegacySetting - - try - { - if (Configuration.ConfigDictionary.TryGetValue(lookup.ToString(), out var val)) - { - // special case for handling skins which use 1 or 0 to signify a boolean state. - if (typeof(TValue) == typeof(bool)) - val = val == "1" ? "true" : "false"; - - var bindable = new Bindable(); - if (val != null) - bindable.Parse(val); - return bindable; - } - } - catch - { - } - - break; + return genericLookup(lookup); } return null; @@ -286,6 +266,30 @@ namespace osu.Game.Skinning private IBindable getManiaImage(LegacyManiaSkinConfiguration source, string lookup) => source.ImageLookups.TryGetValue(lookup, out var image) ? new Bindable(image) : null; + [CanBeNull] + private IBindable genericLookup(TLookup lookup) + { + try + { + if (Configuration.ConfigDictionary.TryGetValue(lookup.ToString(), out var val)) + { + // special case for handling skins which use 1 or 0 to signify a boolean state. + if (typeof(TValue) == typeof(bool)) + val = val == "1" ? "true" : "false"; + + var bindable = new Bindable(); + if (val != null) + bindable.Parse(val); + return bindable; + } + } + catch + { + } + + return null; + } + public override Drawable GetDrawableComponent(ISkinComponent component) { switch (component) From ca7545917c85d5b5cf58ab54ec49aaab4c17d52f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sun, 2 Aug 2020 19:50:17 +0200 Subject: [PATCH 052/434] Extract method for performing legacy lookups --- osu.Game/Skinning/LegacySkin.cs | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/osu.Game/Skinning/LegacySkin.cs b/osu.Game/Skinning/LegacySkin.cs index d1acc51bed..4e470e13b5 100644 --- a/osu.Game/Skinning/LegacySkin.cs +++ b/osu.Game/Skinning/LegacySkin.cs @@ -134,13 +134,7 @@ namespace osu.Game.Skinning break; case LegacySkinConfiguration.LegacySetting legacy: - switch (legacy) - { - case LegacySkinConfiguration.LegacySetting.Version: - return SkinUtils.As(new Bindable(Configuration.LegacyVersion ?? LegacySkinConfiguration.LATEST_VERSION)); - } - - goto default; + return legacySettingLookup(legacy); default: return genericLookup(lookup); @@ -266,6 +260,19 @@ namespace osu.Game.Skinning private IBindable getManiaImage(LegacyManiaSkinConfiguration source, string lookup) => source.ImageLookups.TryGetValue(lookup, out var image) ? new Bindable(image) : null; + [CanBeNull] + private IBindable legacySettingLookup(LegacySkinConfiguration.LegacySetting legacySetting) + { + switch (legacySetting) + { + case LegacySkinConfiguration.LegacySetting.Version: + return SkinUtils.As(new Bindable(Configuration.LegacyVersion ?? LegacySkinConfiguration.LATEST_VERSION)); + + default: + return genericLookup(legacySetting); + } + } + [CanBeNull] private IBindable genericLookup(TLookup lookup) { From ca57c70961e51cceed04404706c59a8601fa29b9 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sun, 2 Aug 2020 21:33:14 +0300 Subject: [PATCH 053/434] Naming adjustments --- .../Dashboard/Dashboard/DashboardBeatmapListing.cs | 8 ++++---- .../Overlays/Dashboard/Dashboard/DashboardBeatmapPanel.cs | 8 ++++---- .../{DrawableBeatmapsList.cs => DrawableBeatmapList.cs} | 4 ++-- ...awableNewBeatmapsList.cs => DrawableNewBeatmapList.cs} | 4 ++-- ...pularBeatmapsList.cs => DrawablePopularBeatmapList.cs} | 4 ++-- 5 files changed, 14 insertions(+), 14 deletions(-) rename osu.Game/Overlays/Dashboard/Dashboard/{DrawableBeatmapsList.cs => DrawableBeatmapList.cs} (92%) rename osu.Game/Overlays/Dashboard/Dashboard/{DrawableNewBeatmapsList.cs => DrawableNewBeatmapList.cs} (80%) rename osu.Game/Overlays/Dashboard/Dashboard/{DrawablePopularBeatmapsList.cs => DrawablePopularBeatmapList.cs} (79%) diff --git a/osu.Game/Overlays/Dashboard/Dashboard/DashboardBeatmapListing.cs b/osu.Game/Overlays/Dashboard/Dashboard/DashboardBeatmapListing.cs index 26c892174d..a8c6ab7ba2 100644 --- a/osu.Game/Overlays/Dashboard/Dashboard/DashboardBeatmapListing.cs +++ b/osu.Game/Overlays/Dashboard/Dashboard/DashboardBeatmapListing.cs @@ -26,16 +26,16 @@ namespace osu.Game.Overlays.Dashboard.Dashboard { RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; - InternalChild = new FillFlowContainer + InternalChild = new FillFlowContainer { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, Direction = FillDirection.Vertical, Spacing = new Vector2(0, 10), - Children = new DrawableBeatmapsList[] + Children = new DrawableBeatmapList[] { - new DrawableNewBeatmapsList(newBeatmaps), - new DrawablePopularBeatmapsList(popularBeatmaps) + new DrawableNewBeatmapList(newBeatmaps), + new DrawablePopularBeatmapList(popularBeatmaps) } }; } diff --git a/osu.Game/Overlays/Dashboard/Dashboard/DashboardBeatmapPanel.cs b/osu.Game/Overlays/Dashboard/Dashboard/DashboardBeatmapPanel.cs index 61324fdc7f..45fa56a177 100644 --- a/osu.Game/Overlays/Dashboard/Dashboard/DashboardBeatmapPanel.cs +++ b/osu.Game/Overlays/Dashboard/Dashboard/DashboardBeatmapPanel.cs @@ -26,7 +26,7 @@ namespace osu.Game.Overlays.Dashboard.Dashboard protected readonly BeatmapSetInfo SetInfo; - private Box background; + private Box hoverBackground; private SpriteIcon chevron; protected DashboardBeatmapPanel(BeatmapSetInfo setInfo) @@ -41,7 +41,7 @@ namespace osu.Game.Overlays.Dashboard.Dashboard Height = 60; Children = new Drawable[] { - background = new Box + hoverBackground = new Box { RelativeSizeAxes = Axes.Both, Colour = ColourProvider.Background3, @@ -149,7 +149,7 @@ namespace osu.Game.Overlays.Dashboard.Dashboard protected override bool OnHover(HoverEvent e) { base.OnHover(e); - background.FadeIn(200, Easing.OutQuint); + hoverBackground.FadeIn(200, Easing.OutQuint); chevron.FadeColour(ColourProvider.Light1, 200, Easing.OutQuint); return true; } @@ -157,7 +157,7 @@ namespace osu.Game.Overlays.Dashboard.Dashboard protected override void OnHoverLost(HoverLostEvent e) { base.OnHoverLost(e); - background.FadeOut(200, Easing.OutQuint); + hoverBackground.FadeOut(200, Easing.OutQuint); chevron.FadeColour(ColourProvider.Foreground1, 200, Easing.OutQuint); } } diff --git a/osu.Game/Overlays/Dashboard/Dashboard/DrawableBeatmapsList.cs b/osu.Game/Overlays/Dashboard/Dashboard/DrawableBeatmapList.cs similarity index 92% rename from osu.Game/Overlays/Dashboard/Dashboard/DrawableBeatmapsList.cs rename to osu.Game/Overlays/Dashboard/Dashboard/DrawableBeatmapList.cs index dfe483a962..7dd969863a 100644 --- a/osu.Game/Overlays/Dashboard/Dashboard/DrawableBeatmapsList.cs +++ b/osu.Game/Overlays/Dashboard/Dashboard/DrawableBeatmapList.cs @@ -13,11 +13,11 @@ using osuTK; namespace osu.Game.Overlays.Dashboard.Dashboard { - public abstract class DrawableBeatmapsList : CompositeDrawable + public abstract class DrawableBeatmapList : CompositeDrawable { private readonly List beatmaps; - protected DrawableBeatmapsList(List beatmaps) + protected DrawableBeatmapList(List beatmaps) { this.beatmaps = beatmaps; } diff --git a/osu.Game/Overlays/Dashboard/Dashboard/DrawableNewBeatmapsList.cs b/osu.Game/Overlays/Dashboard/Dashboard/DrawableNewBeatmapList.cs similarity index 80% rename from osu.Game/Overlays/Dashboard/Dashboard/DrawableNewBeatmapsList.cs rename to osu.Game/Overlays/Dashboard/Dashboard/DrawableNewBeatmapList.cs index e89495dc99..3ed42cc4bb 100644 --- a/osu.Game/Overlays/Dashboard/Dashboard/DrawableNewBeatmapsList.cs +++ b/osu.Game/Overlays/Dashboard/Dashboard/DrawableNewBeatmapList.cs @@ -6,9 +6,9 @@ using osu.Game.Beatmaps; namespace osu.Game.Overlays.Dashboard.Dashboard { - public class DrawableNewBeatmapsList : DrawableBeatmapsList + public class DrawableNewBeatmapList : DrawableBeatmapList { - public DrawableNewBeatmapsList(List beatmaps) + public DrawableNewBeatmapList(List beatmaps) : base(beatmaps) { } diff --git a/osu.Game/Overlays/Dashboard/Dashboard/DrawablePopularBeatmapsList.cs b/osu.Game/Overlays/Dashboard/Dashboard/DrawablePopularBeatmapList.cs similarity index 79% rename from osu.Game/Overlays/Dashboard/Dashboard/DrawablePopularBeatmapsList.cs rename to osu.Game/Overlays/Dashboard/Dashboard/DrawablePopularBeatmapList.cs index 8076e86ed0..ee6c3e6d77 100644 --- a/osu.Game/Overlays/Dashboard/Dashboard/DrawablePopularBeatmapsList.cs +++ b/osu.Game/Overlays/Dashboard/Dashboard/DrawablePopularBeatmapList.cs @@ -6,9 +6,9 @@ using osu.Game.Beatmaps; namespace osu.Game.Overlays.Dashboard.Dashboard { - public class DrawablePopularBeatmapsList : DrawableBeatmapsList + public class DrawablePopularBeatmapList : DrawableBeatmapList { - public DrawablePopularBeatmapsList(List beatmaps) + public DrawablePopularBeatmapList(List beatmaps) : base(beatmaps) { } From 7d83cdbf1c18fdaa9d25d866ac62a3d292a5e795 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sun, 2 Aug 2020 21:35:24 +0300 Subject: [PATCH 054/434] Make title in DrawableBeatmapList a property --- osu.Game/Overlays/Dashboard/Dashboard/DrawableBeatmapList.cs | 4 ++-- .../Overlays/Dashboard/Dashboard/DrawableNewBeatmapList.cs | 2 +- .../Dashboard/Dashboard/DrawablePopularBeatmapList.cs | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game/Overlays/Dashboard/Dashboard/DrawableBeatmapList.cs b/osu.Game/Overlays/Dashboard/Dashboard/DrawableBeatmapList.cs index 7dd969863a..4837d587fd 100644 --- a/osu.Game/Overlays/Dashboard/Dashboard/DrawableBeatmapList.cs +++ b/osu.Game/Overlays/Dashboard/Dashboard/DrawableBeatmapList.cs @@ -41,7 +41,7 @@ namespace osu.Game.Overlays.Dashboard.Dashboard { Font = OsuFont.GetFont(size: 16, weight: FontWeight.Bold), Colour = colourProvider.Light1, - Text = CreateTitle(), + Text = Title, Padding = new MarginPadding { Left = 10 } } } @@ -50,7 +50,7 @@ namespace osu.Game.Overlays.Dashboard.Dashboard flow.AddRange(beatmaps.Select(CreateBeatmapPanel)); } - protected abstract string CreateTitle(); + protected abstract string Title { get; } protected abstract DashboardBeatmapPanel CreateBeatmapPanel(BeatmapSetInfo setInfo); } diff --git a/osu.Game/Overlays/Dashboard/Dashboard/DrawableNewBeatmapList.cs b/osu.Game/Overlays/Dashboard/Dashboard/DrawableNewBeatmapList.cs index 3ed42cc4bb..9856f6ae3e 100644 --- a/osu.Game/Overlays/Dashboard/Dashboard/DrawableNewBeatmapList.cs +++ b/osu.Game/Overlays/Dashboard/Dashboard/DrawableNewBeatmapList.cs @@ -15,6 +15,6 @@ namespace osu.Game.Overlays.Dashboard.Dashboard protected override DashboardBeatmapPanel CreateBeatmapPanel(BeatmapSetInfo setInfo) => new DashboardNewBeatmapPanel(setInfo); - protected override string CreateTitle() => "New Ranked Beatmaps"; + protected override string Title => "New Ranked Beatmaps"; } } diff --git a/osu.Game/Overlays/Dashboard/Dashboard/DrawablePopularBeatmapList.cs b/osu.Game/Overlays/Dashboard/Dashboard/DrawablePopularBeatmapList.cs index ee6c3e6d77..294a75c48a 100644 --- a/osu.Game/Overlays/Dashboard/Dashboard/DrawablePopularBeatmapList.cs +++ b/osu.Game/Overlays/Dashboard/Dashboard/DrawablePopularBeatmapList.cs @@ -15,6 +15,6 @@ namespace osu.Game.Overlays.Dashboard.Dashboard protected override DashboardBeatmapPanel CreateBeatmapPanel(BeatmapSetInfo setInfo) => new DashboardPopularBeatmapPanel(setInfo); - protected override string CreateTitle() => "Popular Beatmaps"; + protected override string Title => "Popular Beatmaps"; } } From bddc61756a3a40f5885b449cd72178b4fd8c2c7b Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sun, 2 Aug 2020 21:44:34 +0300 Subject: [PATCH 055/434] Rework padding --- .../TestSceneDashboardBeatmapListing.cs | 8 +++++++- .../Dashboard/Dashboard/DashboardBeatmapPanel.cs | 12 ++++++++---- .../Dashboard/Dashboard/DrawableBeatmapList.cs | 3 +-- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneDashboardBeatmapListing.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneDashboardBeatmapListing.cs index be0cc5187e..c5714dae46 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneDashboardBeatmapListing.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneDashboardBeatmapListing.cs @@ -36,7 +36,13 @@ namespace osu.Game.Tests.Visual.UserInterface RelativeSizeAxes = Axes.Both, Colour = colourProvider.Background4 }, - new DashboardBeatmapListing(new_beatmaps, popular_beatmaps) + new Container + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Padding = new MarginPadding { Horizontal = 10 }, + Child = new DashboardBeatmapListing(new_beatmaps, popular_beatmaps) + } } }); } diff --git a/osu.Game/Overlays/Dashboard/Dashboard/DashboardBeatmapPanel.cs b/osu.Game/Overlays/Dashboard/Dashboard/DashboardBeatmapPanel.cs index 45fa56a177..d74cdf4414 100644 --- a/osu.Game/Overlays/Dashboard/Dashboard/DashboardBeatmapPanel.cs +++ b/osu.Game/Overlays/Dashboard/Dashboard/DashboardBeatmapPanel.cs @@ -41,16 +41,20 @@ namespace osu.Game.Overlays.Dashboard.Dashboard Height = 60; Children = new Drawable[] { - hoverBackground = new Box + new Container { RelativeSizeAxes = Axes.Both, - Colour = ColourProvider.Background3, - Alpha = 0 + Padding = new MarginPadding { Horizontal = -10 }, + Child = hoverBackground = new Box + { + RelativeSizeAxes = Axes.Both, + Colour = ColourProvider.Background3, + Alpha = 0 + } }, new Container { RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding { Horizontal = 10 }, Child = new GridContainer { RelativeSizeAxes = Axes.Both, diff --git a/osu.Game/Overlays/Dashboard/Dashboard/DrawableBeatmapList.cs b/osu.Game/Overlays/Dashboard/Dashboard/DrawableBeatmapList.cs index 4837d587fd..6e42881de7 100644 --- a/osu.Game/Overlays/Dashboard/Dashboard/DrawableBeatmapList.cs +++ b/osu.Game/Overlays/Dashboard/Dashboard/DrawableBeatmapList.cs @@ -41,8 +41,7 @@ namespace osu.Game.Overlays.Dashboard.Dashboard { Font = OsuFont.GetFont(size: 16, weight: FontWeight.Bold), Colour = colourProvider.Light1, - Text = Title, - Padding = new MarginPadding { Left = 10 } + Text = Title } } }; From dc559093cdc519e600d7304e6f14bdcc06ea91aa Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sun, 2 Aug 2020 21:47:09 +0300 Subject: [PATCH 056/434] Rename namespace from Dashboard to Home --- .../Visual/UserInterface/TestSceneDashboardBeatmapListing.cs | 2 +- .../Dashboard/{Dashboard => Home}/DashboardBeatmapListing.cs | 2 +- .../Dashboard/{Dashboard => Home}/DashboardBeatmapPanel.cs | 2 +- .../Dashboard/{Dashboard => Home}/DashboardNewBeatmapPanel.cs | 2 +- .../{Dashboard => Home}/DashboardPopularBeatmapPanel.cs | 2 +- .../Dashboard/{Dashboard => Home}/DrawableBeatmapList.cs | 2 +- .../Dashboard/{Dashboard => Home}/DrawableNewBeatmapList.cs | 2 +- .../Dashboard/{Dashboard => Home}/DrawablePopularBeatmapList.cs | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) rename osu.Game/Overlays/Dashboard/{Dashboard => Home}/DashboardBeatmapListing.cs (96%) rename osu.Game/Overlays/Dashboard/{Dashboard => Home}/DashboardBeatmapPanel.cs (99%) rename osu.Game/Overlays/Dashboard/{Dashboard => Home}/DashboardNewBeatmapPanel.cs (93%) rename osu.Game/Overlays/Dashboard/{Dashboard => Home}/DashboardPopularBeatmapPanel.cs (96%) rename osu.Game/Overlays/Dashboard/{Dashboard => Home}/DrawableBeatmapList.cs (97%) rename osu.Game/Overlays/Dashboard/{Dashboard => Home}/DrawableNewBeatmapList.cs (92%) rename osu.Game/Overlays/Dashboard/{Dashboard => Home}/DrawablePopularBeatmapList.cs (92%) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneDashboardBeatmapListing.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneDashboardBeatmapListing.cs index c5714dae46..c51204eaba 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneDashboardBeatmapListing.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneDashboardBeatmapListing.cs @@ -3,7 +3,7 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics; -using osu.Game.Overlays.Dashboard.Dashboard; +using osu.Game.Overlays.Dashboard.Home; using osu.Game.Beatmaps; using osu.Game.Overlays; using osu.Framework.Allocation; diff --git a/osu.Game/Overlays/Dashboard/Dashboard/DashboardBeatmapListing.cs b/osu.Game/Overlays/Dashboard/Home/DashboardBeatmapListing.cs similarity index 96% rename from osu.Game/Overlays/Dashboard/Dashboard/DashboardBeatmapListing.cs rename to osu.Game/Overlays/Dashboard/Home/DashboardBeatmapListing.cs index a8c6ab7ba2..4d96825353 100644 --- a/osu.Game/Overlays/Dashboard/Dashboard/DashboardBeatmapListing.cs +++ b/osu.Game/Overlays/Dashboard/Home/DashboardBeatmapListing.cs @@ -8,7 +8,7 @@ using osu.Framework.Graphics.Containers; using osu.Game.Beatmaps; using osuTK; -namespace osu.Game.Overlays.Dashboard.Dashboard +namespace osu.Game.Overlays.Dashboard.Home { public class DashboardBeatmapListing : CompositeDrawable { diff --git a/osu.Game/Overlays/Dashboard/Dashboard/DashboardBeatmapPanel.cs b/osu.Game/Overlays/Dashboard/Home/DashboardBeatmapPanel.cs similarity index 99% rename from osu.Game/Overlays/Dashboard/Dashboard/DashboardBeatmapPanel.cs rename to osu.Game/Overlays/Dashboard/Home/DashboardBeatmapPanel.cs index d74cdf4414..0b660c16af 100644 --- a/osu.Game/Overlays/Dashboard/Dashboard/DashboardBeatmapPanel.cs +++ b/osu.Game/Overlays/Dashboard/Home/DashboardBeatmapPanel.cs @@ -14,7 +14,7 @@ using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; using osuTK; -namespace osu.Game.Overlays.Dashboard.Dashboard +namespace osu.Game.Overlays.Dashboard.Home { public abstract class DashboardBeatmapPanel : OsuClickableContainer { diff --git a/osu.Game/Overlays/Dashboard/Dashboard/DashboardNewBeatmapPanel.cs b/osu.Game/Overlays/Dashboard/Home/DashboardNewBeatmapPanel.cs similarity index 93% rename from osu.Game/Overlays/Dashboard/Dashboard/DashboardNewBeatmapPanel.cs rename to osu.Game/Overlays/Dashboard/Home/DashboardNewBeatmapPanel.cs index c4782b733d..b212eaf20a 100644 --- a/osu.Game/Overlays/Dashboard/Dashboard/DashboardNewBeatmapPanel.cs +++ b/osu.Game/Overlays/Dashboard/Home/DashboardNewBeatmapPanel.cs @@ -6,7 +6,7 @@ using osu.Framework.Graphics; using osu.Game.Beatmaps; using osu.Game.Graphics; -namespace osu.Game.Overlays.Dashboard.Dashboard +namespace osu.Game.Overlays.Dashboard.Home { public class DashboardNewBeatmapPanel : DashboardBeatmapPanel { diff --git a/osu.Game/Overlays/Dashboard/Dashboard/DashboardPopularBeatmapPanel.cs b/osu.Game/Overlays/Dashboard/Home/DashboardPopularBeatmapPanel.cs similarity index 96% rename from osu.Game/Overlays/Dashboard/Dashboard/DashboardPopularBeatmapPanel.cs rename to osu.Game/Overlays/Dashboard/Home/DashboardPopularBeatmapPanel.cs index 04bb261dce..2fb5617796 100644 --- a/osu.Game/Overlays/Dashboard/Dashboard/DashboardPopularBeatmapPanel.cs +++ b/osu.Game/Overlays/Dashboard/Home/DashboardPopularBeatmapPanel.cs @@ -9,7 +9,7 @@ using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osuTK; -namespace osu.Game.Overlays.Dashboard.Dashboard +namespace osu.Game.Overlays.Dashboard.Home { public class DashboardPopularBeatmapPanel : DashboardBeatmapPanel { diff --git a/osu.Game/Overlays/Dashboard/Dashboard/DrawableBeatmapList.cs b/osu.Game/Overlays/Dashboard/Home/DrawableBeatmapList.cs similarity index 97% rename from osu.Game/Overlays/Dashboard/Dashboard/DrawableBeatmapList.cs rename to osu.Game/Overlays/Dashboard/Home/DrawableBeatmapList.cs index 6e42881de7..f6535b7db3 100644 --- a/osu.Game/Overlays/Dashboard/Dashboard/DrawableBeatmapList.cs +++ b/osu.Game/Overlays/Dashboard/Home/DrawableBeatmapList.cs @@ -11,7 +11,7 @@ using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osuTK; -namespace osu.Game.Overlays.Dashboard.Dashboard +namespace osu.Game.Overlays.Dashboard.Home { public abstract class DrawableBeatmapList : CompositeDrawable { diff --git a/osu.Game/Overlays/Dashboard/Dashboard/DrawableNewBeatmapList.cs b/osu.Game/Overlays/Dashboard/Home/DrawableNewBeatmapList.cs similarity index 92% rename from osu.Game/Overlays/Dashboard/Dashboard/DrawableNewBeatmapList.cs rename to osu.Game/Overlays/Dashboard/Home/DrawableNewBeatmapList.cs index 9856f6ae3e..75e8ca336d 100644 --- a/osu.Game/Overlays/Dashboard/Dashboard/DrawableNewBeatmapList.cs +++ b/osu.Game/Overlays/Dashboard/Home/DrawableNewBeatmapList.cs @@ -4,7 +4,7 @@ using System.Collections.Generic; using osu.Game.Beatmaps; -namespace osu.Game.Overlays.Dashboard.Dashboard +namespace osu.Game.Overlays.Dashboard.Home { public class DrawableNewBeatmapList : DrawableBeatmapList { diff --git a/osu.Game/Overlays/Dashboard/Dashboard/DrawablePopularBeatmapList.cs b/osu.Game/Overlays/Dashboard/Home/DrawablePopularBeatmapList.cs similarity index 92% rename from osu.Game/Overlays/Dashboard/Dashboard/DrawablePopularBeatmapList.cs rename to osu.Game/Overlays/Dashboard/Home/DrawablePopularBeatmapList.cs index 294a75c48a..90bd00008c 100644 --- a/osu.Game/Overlays/Dashboard/Dashboard/DrawablePopularBeatmapList.cs +++ b/osu.Game/Overlays/Dashboard/Home/DrawablePopularBeatmapList.cs @@ -4,7 +4,7 @@ using System.Collections.Generic; using osu.Game.Beatmaps; -namespace osu.Game.Overlays.Dashboard.Dashboard +namespace osu.Game.Overlays.Dashboard.Home { public class DrawablePopularBeatmapList : DrawableBeatmapList { From b96e32b0bbd741373689ad7755b54d576d87dd56 Mon Sep 17 00:00:00 2001 From: Joehu Date: Sun, 2 Aug 2020 12:26:09 -0700 Subject: [PATCH 057/434] Add xmldoc for updateBindTarget --- osu.Game/Overlays/KeyBinding/KeyBindingRow.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs index d58acc1ac4..e5b246807c 100644 --- a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs +++ b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs @@ -320,6 +320,9 @@ namespace osu.Game.Overlays.KeyBinding base.OnFocusLost(e); } + /// + /// Updates the bind target to the currently hovered key button or the first if clicked anywhere else. + /// private void updateBindTarget() { if (bindTarget != null) bindTarget.IsBinding = false; From ba77fa2945475ab3d6eb8092f384c4500f1a6f51 Mon Sep 17 00:00:00 2001 From: Joehu Date: Sun, 2 Aug 2020 12:41:35 -0700 Subject: [PATCH 058/434] Add test for clear button --- .../Settings/TestSceneKeyBindingPanel.cs | 40 +++++++++++++++++++ osu.Game/Overlays/KeyBinding/KeyBindingRow.cs | 14 +++---- 2 files changed, 47 insertions(+), 7 deletions(-) diff --git a/osu.Game.Tests/Visual/Settings/TestSceneKeyBindingPanel.cs b/osu.Game.Tests/Visual/Settings/TestSceneKeyBindingPanel.cs index 3d335995ac..e7a1cab8eb 100644 --- a/osu.Game.Tests/Visual/Settings/TestSceneKeyBindingPanel.cs +++ b/osu.Game.Tests/Visual/Settings/TestSceneKeyBindingPanel.cs @@ -64,5 +64,45 @@ namespace osu.Game.Tests.Visual.Settings }, 0, true); }); } + + [Test] + public void TestClearButtonOnBindings() + { + KeyBindingRow backBindingRow = null; + + AddStep("click back binding row", () => + { + backBindingRow = panel.ChildrenOfType().ElementAt(10); + InputManager.MoveMouseTo(backBindingRow); + InputManager.Click(MouseButton.Left); + }); + + clickClearButton(); + + AddAssert("first binding cleared", () => string.IsNullOrEmpty(backBindingRow.Buttons.First().Text.Text)); + + AddStep("click second binding", () => + { + var target = backBindingRow.Buttons.ElementAt(1); + + InputManager.MoveMouseTo(target); + InputManager.Click(MouseButton.Left); + }); + + clickClearButton(); + + AddAssert("second binding cleared", () => string.IsNullOrEmpty(backBindingRow.Buttons.ElementAt(1).Text.Text)); + + void clickClearButton() + { + AddStep("click clear button", () => + { + var clearButton = backBindingRow.ChildrenOfType().Single(); + + InputManager.MoveMouseTo(clearButton); + InputManager.Click(MouseButton.Left); + }); + } + } } } diff --git a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs index e5b246807c..44b5fe09f4 100644 --- a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs +++ b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs @@ -50,7 +50,7 @@ namespace osu.Game.Overlays.KeyBinding private OsuSpriteText text; private Drawable pressAKey; - private FillFlowContainer buttons; + public FillFlowContainer Buttons; public IEnumerable FilterTerms => bindings.Select(b => b.KeyCombination.ReadableString()).Prepend((string)text.Text); @@ -93,7 +93,7 @@ namespace osu.Game.Overlays.KeyBinding Text = action.GetDescription(), Margin = new MarginPadding(padding), }, - buttons = new FillFlowContainer + Buttons = new FillFlowContainer { AutoSizeAxes = Axes.Both, Anchor = Anchor.TopRight, @@ -116,7 +116,7 @@ namespace osu.Game.Overlays.KeyBinding }; foreach (var b in bindings) - buttons.Add(new KeyButton(b)); + Buttons.Add(new KeyButton(b)); } public void RestoreDefaults() @@ -125,7 +125,7 @@ namespace osu.Game.Overlays.KeyBinding foreach (var d in Defaults) { - var button = buttons[i++]; + var button = Buttons[i++]; button.UpdateKeyCombination(d); store.Update(button.KeyBinding); } @@ -187,7 +187,7 @@ namespace osu.Game.Overlays.KeyBinding if (bindTarget.IsHovered) finalise(); - else if (buttons.Any(b => b.IsHovered)) + else if (Buttons.Any(b => b.IsHovered)) updateBindTarget(); } @@ -326,7 +326,7 @@ namespace osu.Game.Overlays.KeyBinding private void updateBindTarget() { if (bindTarget != null) bindTarget.IsBinding = false; - bindTarget = buttons.FirstOrDefault(b => b.IsHovered) ?? buttons.FirstOrDefault(); + bindTarget = Buttons.FirstOrDefault(b => b.IsHovered) ?? Buttons.FirstOrDefault(); if (bindTarget != null) bindTarget.IsBinding = true; } @@ -357,7 +357,7 @@ namespace osu.Game.Overlays.KeyBinding } } - private class KeyButton : Container + public class KeyButton : Container { public readonly Framework.Input.Bindings.KeyBinding KeyBinding; From d49e54deb60b3cfee754697c446b9b4ea21cfb2a Mon Sep 17 00:00:00 2001 From: Joehu Date: Sun, 2 Aug 2020 12:47:23 -0700 Subject: [PATCH 059/434] Add failing test for another regressing behavior --- .../Settings/TestSceneKeyBindingPanel.cs | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/osu.Game.Tests/Visual/Settings/TestSceneKeyBindingPanel.cs b/osu.Game.Tests/Visual/Settings/TestSceneKeyBindingPanel.cs index e7a1cab8eb..96075d56d1 100644 --- a/osu.Game.Tests/Visual/Settings/TestSceneKeyBindingPanel.cs +++ b/osu.Game.Tests/Visual/Settings/TestSceneKeyBindingPanel.cs @@ -104,5 +104,37 @@ namespace osu.Game.Tests.Visual.Settings }); } } + + [Test] + public void TestClickRowSelectsFirstBinding() + { + KeyBindingRow backBindingRow = null; + + AddStep("click back binding row", () => + { + backBindingRow = panel.ChildrenOfType().ElementAt(10); + InputManager.MoveMouseTo(backBindingRow); + InputManager.Click(MouseButton.Left); + }); + + AddAssert("first binding selected", () => backBindingRow.Buttons.First().IsBinding); + + AddStep("click second binding", () => + { + var target = backBindingRow.Buttons.ElementAt(1); + + InputManager.MoveMouseTo(target); + InputManager.Click(MouseButton.Left); + }); + + AddStep("click back binding row", () => + { + backBindingRow = panel.ChildrenOfType().ElementAt(10); + InputManager.MoveMouseTo(backBindingRow); + InputManager.Click(MouseButton.Left); + }); + + AddAssert("first binding selected", () => backBindingRow.Buttons.First().IsBinding); + } } } From 7aafc018ad384f5e1d10437519df539a93f4a91b Mon Sep 17 00:00:00 2001 From: Joehu Date: Sun, 2 Aug 2020 12:52:12 -0700 Subject: [PATCH 060/434] Prevent updating bind target when hovering cancel and clear buttons instead --- osu.Game/Overlays/KeyBinding/KeyBindingRow.cs | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs index 44b5fe09f4..a7394579bd 100644 --- a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs +++ b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs @@ -48,7 +48,7 @@ namespace osu.Game.Overlays.KeyBinding public bool FilteringActive { get; set; } private OsuSpriteText text; - private Drawable pressAKey; + private FillFlowContainer cancelAndClearButtons; public FillFlowContainer Buttons; @@ -80,7 +80,7 @@ namespace osu.Game.Overlays.KeyBinding Hollow = true, }; - Children = new[] + Children = new Drawable[] { new Box { @@ -99,7 +99,7 @@ namespace osu.Game.Overlays.KeyBinding Anchor = Anchor.TopRight, Origin = Anchor.TopRight }, - pressAKey = new FillFlowContainer + cancelAndClearButtons = new FillFlowContainer { AutoSizeAxes = Axes.Both, Padding = new MarginPadding(padding) { Top = height + padding * 2 }, @@ -187,7 +187,8 @@ namespace osu.Game.Overlays.KeyBinding if (bindTarget.IsHovered) finalise(); - else if (Buttons.Any(b => b.IsHovered)) + // prevent updating bind target before clear button's action + else if (!cancelAndClearButtons.Any(b => b.IsHovered)) updateBindTarget(); } @@ -298,8 +299,8 @@ namespace osu.Game.Overlays.KeyBinding if (HasFocus) GetContainingInputManager().ChangeFocus(null); - pressAKey.FadeOut(300, Easing.OutQuint); - pressAKey.BypassAutoSizeAxes |= Axes.Y; + cancelAndClearButtons.FadeOut(300, Easing.OutQuint); + cancelAndClearButtons.BypassAutoSizeAxes |= Axes.Y; } protected override void OnFocus(FocusEvent e) @@ -307,8 +308,8 @@ namespace osu.Game.Overlays.KeyBinding AutoSizeDuration = 500; AutoSizeEasing = Easing.OutQuint; - pressAKey.FadeIn(300, Easing.OutQuint); - pressAKey.BypassAutoSizeAxes &= ~Axes.Y; + cancelAndClearButtons.FadeIn(300, Easing.OutQuint); + cancelAndClearButtons.BypassAutoSizeAxes &= ~Axes.Y; updateBindTarget(); base.OnFocus(e); From 435c9de8b9d500890fb649809f38d6263fca2a89 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 3 Aug 2020 15:25:23 +0900 Subject: [PATCH 061/434] Re-privatise buttons --- .../Visual/Settings/TestSceneKeyBindingPanel.cs | 12 ++++++------ osu.Game/Overlays/KeyBinding/KeyBindingRow.cs | 11 +++++------ 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/osu.Game.Tests/Visual/Settings/TestSceneKeyBindingPanel.cs b/osu.Game.Tests/Visual/Settings/TestSceneKeyBindingPanel.cs index 96075d56d1..e06b3a8a7e 100644 --- a/osu.Game.Tests/Visual/Settings/TestSceneKeyBindingPanel.cs +++ b/osu.Game.Tests/Visual/Settings/TestSceneKeyBindingPanel.cs @@ -79,11 +79,11 @@ namespace osu.Game.Tests.Visual.Settings clickClearButton(); - AddAssert("first binding cleared", () => string.IsNullOrEmpty(backBindingRow.Buttons.First().Text.Text)); + AddAssert("first binding cleared", () => string.IsNullOrEmpty(backBindingRow.ChildrenOfType().First().Text.Text)); AddStep("click second binding", () => { - var target = backBindingRow.Buttons.ElementAt(1); + var target = backBindingRow.ChildrenOfType().ElementAt(1); InputManager.MoveMouseTo(target); InputManager.Click(MouseButton.Left); @@ -91,7 +91,7 @@ namespace osu.Game.Tests.Visual.Settings clickClearButton(); - AddAssert("second binding cleared", () => string.IsNullOrEmpty(backBindingRow.Buttons.ElementAt(1).Text.Text)); + AddAssert("second binding cleared", () => string.IsNullOrEmpty(backBindingRow.ChildrenOfType().ElementAt(1).Text.Text)); void clickClearButton() { @@ -117,11 +117,11 @@ namespace osu.Game.Tests.Visual.Settings InputManager.Click(MouseButton.Left); }); - AddAssert("first binding selected", () => backBindingRow.Buttons.First().IsBinding); + AddAssert("first binding selected", () => backBindingRow.ChildrenOfType().First().IsBinding); AddStep("click second binding", () => { - var target = backBindingRow.Buttons.ElementAt(1); + var target = backBindingRow.ChildrenOfType().ElementAt(1); InputManager.MoveMouseTo(target); InputManager.Click(MouseButton.Left); @@ -134,7 +134,7 @@ namespace osu.Game.Tests.Visual.Settings InputManager.Click(MouseButton.Left); }); - AddAssert("first binding selected", () => backBindingRow.Buttons.First().IsBinding); + AddAssert("first binding selected", () => backBindingRow.ChildrenOfType().First().IsBinding); } } } diff --git a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs index a7394579bd..b808d49fa2 100644 --- a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs +++ b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs @@ -49,8 +49,7 @@ namespace osu.Game.Overlays.KeyBinding private OsuSpriteText text; private FillFlowContainer cancelAndClearButtons; - - public FillFlowContainer Buttons; + private FillFlowContainer buttons; public IEnumerable FilterTerms => bindings.Select(b => b.KeyCombination.ReadableString()).Prepend((string)text.Text); @@ -93,7 +92,7 @@ namespace osu.Game.Overlays.KeyBinding Text = action.GetDescription(), Margin = new MarginPadding(padding), }, - Buttons = new FillFlowContainer + buttons = new FillFlowContainer { AutoSizeAxes = Axes.Both, Anchor = Anchor.TopRight, @@ -116,7 +115,7 @@ namespace osu.Game.Overlays.KeyBinding }; foreach (var b in bindings) - Buttons.Add(new KeyButton(b)); + buttons.Add(new KeyButton(b)); } public void RestoreDefaults() @@ -125,7 +124,7 @@ namespace osu.Game.Overlays.KeyBinding foreach (var d in Defaults) { - var button = Buttons[i++]; + var button = buttons[i++]; button.UpdateKeyCombination(d); store.Update(button.KeyBinding); } @@ -327,7 +326,7 @@ namespace osu.Game.Overlays.KeyBinding private void updateBindTarget() { if (bindTarget != null) bindTarget.IsBinding = false; - bindTarget = Buttons.FirstOrDefault(b => b.IsHovered) ?? Buttons.FirstOrDefault(); + bindTarget = buttons.FirstOrDefault(b => b.IsHovered) ?? buttons.FirstOrDefault(); if (bindTarget != null) bindTarget.IsBinding = true; } From 630322ff85a5c08a1b71e2a35404386fabd483e7 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Mon, 3 Aug 2020 09:55:06 +0300 Subject: [PATCH 062/434] Adjust font weights in line with web --- osu.Game/Overlays/Dashboard/Home/DashboardBeatmapPanel.cs | 6 +++--- .../Overlays/Dashboard/Home/DashboardPopularBeatmapPanel.cs | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game/Overlays/Dashboard/Home/DashboardBeatmapPanel.cs b/osu.Game/Overlays/Dashboard/Home/DashboardBeatmapPanel.cs index 0b660c16af..3badea155d 100644 --- a/osu.Game/Overlays/Dashboard/Home/DashboardBeatmapPanel.cs +++ b/osu.Game/Overlays/Dashboard/Home/DashboardBeatmapPanel.cs @@ -102,17 +102,17 @@ namespace osu.Game.Overlays.Dashboard.Home { RelativeSizeAxes = Axes.X, Truncate = true, - Font = OsuFont.GetFont(weight: FontWeight.SemiBold), + Font = OsuFont.GetFont(weight: FontWeight.Regular), Text = SetInfo.Metadata.Title }, new OsuSpriteText { RelativeSizeAxes = Axes.X, Truncate = true, - Font = OsuFont.GetFont(size: 12, weight: FontWeight.SemiBold), + Font = OsuFont.GetFont(size: 12, weight: FontWeight.Regular), Text = SetInfo.Metadata.Artist }, - new LinkFlowContainer(f => f.Font = OsuFont.GetFont(size: 10, weight: FontWeight.SemiBold)) + new LinkFlowContainer(f => f.Font = OsuFont.GetFont(size: 10, weight: FontWeight.Regular)) { AutoSizeAxes = Axes.Y, RelativeSizeAxes = Axes.X, diff --git a/osu.Game/Overlays/Dashboard/Home/DashboardPopularBeatmapPanel.cs b/osu.Game/Overlays/Dashboard/Home/DashboardPopularBeatmapPanel.cs index 2fb5617796..e9066c0657 100644 --- a/osu.Game/Overlays/Dashboard/Home/DashboardPopularBeatmapPanel.cs +++ b/osu.Game/Overlays/Dashboard/Home/DashboardPopularBeatmapPanel.cs @@ -33,7 +33,7 @@ namespace osu.Game.Overlays.Dashboard.Home }, new OsuSpriteText { - Font = OsuFont.GetFont(size: 10), + Font = OsuFont.GetFont(size: 10, weight: FontWeight.Regular), Text = SetInfo.OnlineInfo.FavouriteCount.ToString() } } From af320e4a619784cd979c1eba9af93a9e29ee97d8 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Mon, 3 Aug 2020 10:03:42 +0300 Subject: [PATCH 063/434] Fix NewsOverlay running request on startup --- osu.Game/Overlays/NewsOverlay.cs | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/NewsOverlay.cs b/osu.Game/Overlays/NewsOverlay.cs index a5687b77e2..f8666e22c5 100644 --- a/osu.Game/Overlays/NewsOverlay.cs +++ b/osu.Game/Overlays/NewsOverlay.cs @@ -67,7 +67,26 @@ namespace osu.Game.Overlays protected override void LoadComplete() { base.LoadComplete(); - article.BindValueChanged(onArticleChanged, true); + article.BindValueChanged(onArticleChanged); + } + + private bool displayUpdateRequired = true; + + protected override void PopIn() + { + base.PopIn(); + + if (displayUpdateRequired) + { + article.TriggerChange(); + displayUpdateRequired = false; + } + } + + protected override void PopOutComplete() + { + base.PopOutComplete(); + displayUpdateRequired = true; } public void ShowFrontPage() From f812767c95428a679d6e5646fc9c6cc5b608ed17 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 3 Aug 2020 18:48:10 +0900 Subject: [PATCH 064/434] Add fallback hash generation to fix android startup crash --- osu.Game/OsuGameBase.cs | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index 278f2d849f..98f60d52d3 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -36,6 +36,7 @@ using osu.Game.Rulesets.Mods; using osu.Game.Scoring; using osu.Game.Skinning; using osuTK.Input; +using RuntimeInfo = osu.Framework.RuntimeInfo; namespace osu.Game { @@ -134,8 +135,17 @@ namespace osu.Game [BackgroundDependencyLoader] private void load() { - using (var str = File.OpenRead(typeof(OsuGameBase).Assembly.Location)) - VersionHash = str.ComputeMD5Hash(); + try + { + using (var str = File.OpenRead(typeof(OsuGameBase).Assembly.Location)) + VersionHash = str.ComputeMD5Hash(); + } + catch + { + // special case for android builds, which can't read DLLs from a packed apk. + // should eventually be handled in a better way. + VersionHash = $"{Version}-{RuntimeInfo.OS}".ComputeMD5Hash(); + } Resources.AddStore(new DllResourceStore(OsuResources.ResourceAssembly)); From c48648ea2ac014f40281f7b0f313949b7d454fda Mon Sep 17 00:00:00 2001 From: Sebastian Krajewski Date: Mon, 3 Aug 2020 12:59:15 +0200 Subject: [PATCH 065/434] Add playfield shift like in osu-stable --- osu.Game.Rulesets.Osu/UI/OsuPlayfieldAdjustmentContainer.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game.Rulesets.Osu/UI/OsuPlayfieldAdjustmentContainer.cs b/osu.Game.Rulesets.Osu/UI/OsuPlayfieldAdjustmentContainer.cs index 9c8be868b0..93d88f3690 100644 --- a/osu.Game.Rulesets.Osu/UI/OsuPlayfieldAdjustmentContainer.cs +++ b/osu.Game.Rulesets.Osu/UI/OsuPlayfieldAdjustmentContainer.cs @@ -55,6 +55,7 @@ namespace osu.Game.Rulesets.Osu.UI // Scale = 819.2 / 512 // Scale = 1.6 Scale = new Vector2(Parent.ChildSize.X / OsuPlayfield.BASE_SIZE.X); + Position = new Vector2(0, 8 * Parent.ChildSize.Y / OsuPlayfield.BASE_SIZE.Y); // Size = 0.625 Size = Vector2.Divide(Vector2.One, Scale); } From 675f618b288cc1e75fed0a152c7908e61e77e9d4 Mon Sep 17 00:00:00 2001 From: Sebastian Krajewski Date: Mon, 3 Aug 2020 14:18:45 +0200 Subject: [PATCH 066/434] Apply playfield's offset only in play mode --- osu.Game.Rulesets.Osu/UI/DrawableOsuRuleset.cs | 2 +- .../UI/OsuPlayfieldAdjustmentContainer.cs | 12 +++++++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Osu/UI/DrawableOsuRuleset.cs b/osu.Game.Rulesets.Osu/UI/DrawableOsuRuleset.cs index b4d51d11c9..e6e37fd58e 100644 --- a/osu.Game.Rulesets.Osu/UI/DrawableOsuRuleset.cs +++ b/osu.Game.Rulesets.Osu/UI/DrawableOsuRuleset.cs @@ -35,7 +35,7 @@ namespace osu.Game.Rulesets.Osu.UI protected override PassThroughInputManager CreateInputManager() => new OsuInputManager(Ruleset.RulesetInfo); - public override PlayfieldAdjustmentContainer CreatePlayfieldAdjustmentContainer() => new OsuPlayfieldAdjustmentContainer(); + public override PlayfieldAdjustmentContainer CreatePlayfieldAdjustmentContainer() => new OsuPlayfieldAdjustmentContainer { PlayfieldShift = true }; protected override ResumeOverlay CreateResumeOverlay() => new OsuResumeOverlay(); diff --git a/osu.Game.Rulesets.Osu/UI/OsuPlayfieldAdjustmentContainer.cs b/osu.Game.Rulesets.Osu/UI/OsuPlayfieldAdjustmentContainer.cs index 93d88f3690..700601dbfd 100644 --- a/osu.Game.Rulesets.Osu/UI/OsuPlayfieldAdjustmentContainer.cs +++ b/osu.Game.Rulesets.Osu/UI/OsuPlayfieldAdjustmentContainer.cs @@ -15,6 +15,14 @@ namespace osu.Game.Rulesets.Osu.UI private const float playfield_size_adjust = 0.8f; + /// + /// Whether an osu-stable playfield offset should be applied (8 osu!pixels) + /// + public bool PlayfieldShift + { + set => ((ScalingContainer)content).PlayfieldShift = value; + } + public OsuPlayfieldAdjustmentContainer() { Anchor = Anchor.Centre; @@ -39,6 +47,8 @@ namespace osu.Game.Rulesets.Osu.UI /// private class ScalingContainer : Container { + internal bool PlayfieldShift { get; set; } + protected override void Update() { base.Update(); @@ -55,7 +65,7 @@ namespace osu.Game.Rulesets.Osu.UI // Scale = 819.2 / 512 // Scale = 1.6 Scale = new Vector2(Parent.ChildSize.X / OsuPlayfield.BASE_SIZE.X); - Position = new Vector2(0, 8 * Parent.ChildSize.Y / OsuPlayfield.BASE_SIZE.Y); + Position = new Vector2(0, (PlayfieldShift ? 8f : 0f) * Parent.ChildSize.Y / OsuPlayfield.BASE_SIZE.Y); // Size = 0.625 Size = Vector2.Divide(Vector2.One, Scale); } From 4d6f60edaf8b49a95ede7b5a97fdcca16dfd13ff Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 3 Aug 2020 22:41:22 +0900 Subject: [PATCH 067/434] Fix multiplayer match select forcing playback even when user paused --- osu.Game/Screens/Multi/Multiplayer.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Multi/Multiplayer.cs b/osu.Game/Screens/Multi/Multiplayer.cs index 269eab5772..4912df17b1 100644 --- a/osu.Game/Screens/Multi/Multiplayer.cs +++ b/osu.Game/Screens/Multi/Multiplayer.cs @@ -17,6 +17,7 @@ using osu.Game.Graphics.UserInterface; using osu.Game.Input; using osu.Game.Online.API; using osu.Game.Online.Multiplayer; +using osu.Game.Overlays; using osu.Game.Screens.Menu; using osu.Game.Screens.Multi.Components; using osu.Game.Screens.Multi.Lounge; @@ -50,6 +51,9 @@ namespace osu.Game.Screens.Multi [Cached] private readonly Bindable currentFilter = new Bindable(new FilterCriteria()); + [Resolved] + private MusicController music { get; set; } + [Cached(Type = typeof(IRoomManager))] private RoomManager roomManager; @@ -346,8 +350,7 @@ namespace osu.Game.Screens.Multi track.RestartPoint = Beatmap.Value.Metadata.PreviewTime; track.Looping = true; - if (!track.IsRunning) - track.Restart(); + music.EnsurePlayingSomething(); } } else From 9d10658e3c8cd5d5f0b7d24018401c30fdbec246 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Mon, 3 Aug 2020 20:14:17 +0300 Subject: [PATCH 068/434] Allow providing custom sprite text for RollingCounter --- .../Gameplay/Components/MatchScoreDisplay.cs | 18 ++++-- .../UserInterface/PercentageCounter.cs | 9 ++- .../Graphics/UserInterface/RollingCounter.cs | 61 +++++++++++++------ .../Graphics/UserInterface/ScoreCounter.cs | 9 ++- .../Expanded/Statistics/AccuracyStatistic.cs | 15 +++-- .../Expanded/Statistics/CounterStatistic.cs | 9 ++- .../Ranking/Expanded/TotalScoreCounter.cs | 17 ++++-- 7 files changed, 97 insertions(+), 41 deletions(-) diff --git a/osu.Game.Tournament/Screens/Gameplay/Components/MatchScoreDisplay.cs b/osu.Game.Tournament/Screens/Gameplay/Components/MatchScoreDisplay.cs index 2e7484542a..25417921bc 100644 --- a/osu.Game.Tournament/Screens/Gameplay/Components/MatchScoreDisplay.cs +++ b/osu.Game.Tournament/Screens/Gameplay/Components/MatchScoreDisplay.cs @@ -8,6 +8,7 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; using osu.Game.Tournament.IPC; using osu.Game.Tournament.Models; @@ -127,21 +128,28 @@ namespace osu.Game.Tournament.Screens.Gameplay.Components private class MatchScoreCounter : ScoreCounter { + private OsuSpriteText displayedSpriteText; + public MatchScoreCounter() { Margin = new MarginPadding { Top = bar_height, Horizontal = 10 }; - - Winning = false; - - DisplayedCountSpriteText.Spacing = new Vector2(-6); } public bool Winning { - set => DisplayedCountSpriteText.Font = value + set => displayedSpriteText.Font = value ? OsuFont.Torus.With(weight: FontWeight.Bold, size: 50, fixedWidth: true) : OsuFont.Torus.With(weight: FontWeight.Regular, size: 40, fixedWidth: true); } + + protected override OsuSpriteText CreateSpriteText() + { + displayedSpriteText = base.CreateSpriteText(); + displayedSpriteText.Spacing = new Vector2(-6); + Winning = false; + + return displayedSpriteText; + } } } } diff --git a/osu.Game/Graphics/UserInterface/PercentageCounter.cs b/osu.Game/Graphics/UserInterface/PercentageCounter.cs index 940c9808ce..9b31935eee 100644 --- a/osu.Game/Graphics/UserInterface/PercentageCounter.cs +++ b/osu.Game/Graphics/UserInterface/PercentageCounter.cs @@ -3,6 +3,7 @@ using System; using osu.Framework.Allocation; +using osu.Game.Graphics.Sprites; using osu.Game.Utils; namespace osu.Game.Graphics.UserInterface @@ -23,7 +24,6 @@ namespace osu.Game.Graphics.UserInterface public PercentageCounter() { - DisplayedCountSpriteText.Font = DisplayedCountSpriteText.Font.With(fixedWidth: true); Current.Value = DisplayedCount = 1.0f; } @@ -37,6 +37,13 @@ namespace osu.Game.Graphics.UserInterface return Math.Abs(currentValue - newValue) * RollingDuration * 100.0f; } + protected override OsuSpriteText CreateSpriteText() + { + var spriteText = base.CreateSpriteText(); + spriteText.Font = spriteText.Font.With(fixedWidth: true); + return spriteText; + } + public override void Increment(double amount) { Current.Value += amount; diff --git a/osu.Game/Graphics/UserInterface/RollingCounter.cs b/osu.Game/Graphics/UserInterface/RollingCounter.cs index cd244ed7e6..76bb4bf69d 100644 --- a/osu.Game/Graphics/UserInterface/RollingCounter.cs +++ b/osu.Game/Graphics/UserInterface/RollingCounter.cs @@ -7,6 +7,7 @@ using osu.Framework.Graphics.Sprites; using osu.Game.Graphics.Sprites; using System; using System.Collections.Generic; +using osu.Framework.Allocation; using osu.Framework.Bindables; using osuTK.Graphics; @@ -20,7 +21,7 @@ namespace osu.Game.Graphics.UserInterface /// public Bindable Current = new Bindable(); - protected SpriteText DisplayedCountSpriteText; + private SpriteText displayedCountSpriteText; /// /// If true, the roll-up duration will be proportional to change in value. @@ -46,29 +47,49 @@ namespace osu.Game.Graphics.UserInterface public virtual T DisplayedCount { get => displayedCount; - set { if (EqualityComparer.Default.Equals(displayedCount, value)) return; displayedCount = value; - DisplayedCountSpriteText.Text = FormatCount(value); + if (displayedCountSpriteText != null) + displayedCountSpriteText.Text = FormatCount(value); } } public abstract void Increment(T amount); + private float textSize = 40f; + public float TextSize { - get => DisplayedCountSpriteText.Font.Size; - set => DisplayedCountSpriteText.Font = DisplayedCountSpriteText.Font.With(size: value); + get => displayedCountSpriteText?.Font.Size ?? textSize; + set + { + if (TextSize == value) + return; + + textSize = value; + if (displayedCountSpriteText != null) + displayedCountSpriteText.Font = displayedCountSpriteText.Font.With(size: value); + } } + private Color4 accentColour; + public Color4 AccentColour { - get => DisplayedCountSpriteText.Colour; - set => DisplayedCountSpriteText.Colour = value; + get => displayedCountSpriteText?.Colour ?? accentColour; + set + { + if (AccentColour == value) + return; + + accentColour = value; + if (displayedCountSpriteText != null) + displayedCountSpriteText.Colour = value; + } } /// @@ -76,27 +97,21 @@ namespace osu.Game.Graphics.UserInterface /// protected RollingCounter() { - Children = new Drawable[] - { - DisplayedCountSpriteText = new OsuSpriteText { Font = OsuFont.Numeric } - }; - - TextSize = 40; AutoSizeAxes = Axes.Both; - DisplayedCount = Current.Value; - Current.ValueChanged += val => { - if (IsLoaded) TransformCount(displayedCount, val.NewValue); + if (IsLoaded) + TransformCount(DisplayedCount, val.NewValue); }; } - protected override void LoadComplete() + [BackgroundDependencyLoader] + private void load() { - base.LoadComplete(); - - DisplayedCountSpriteText.Text = FormatCount(Current.Value); + displayedCountSpriteText = CreateSpriteText(); + displayedCountSpriteText.Text = FormatCount(displayedCount); + Child = displayedCountSpriteText; } /// @@ -167,5 +182,11 @@ namespace osu.Game.Graphics.UserInterface this.TransformTo(nameof(DisplayedCount), newValue, rollingTotalDuration, RollingEasing); } + + protected virtual OsuSpriteText CreateSpriteText() => new OsuSpriteText + { + Font = OsuFont.Numeric.With(size: textSize), + Colour = accentColour, + }; } } diff --git a/osu.Game/Graphics/UserInterface/ScoreCounter.cs b/osu.Game/Graphics/UserInterface/ScoreCounter.cs index 01d8edaecf..438fe6c13b 100644 --- a/osu.Game/Graphics/UserInterface/ScoreCounter.cs +++ b/osu.Game/Graphics/UserInterface/ScoreCounter.cs @@ -3,6 +3,7 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; +using osu.Game.Graphics.Sprites; namespace osu.Game.Graphics.UserInterface { @@ -24,7 +25,6 @@ namespace osu.Game.Graphics.UserInterface /// How many leading zeroes the counter will have. public ScoreCounter(uint leading = 0) { - DisplayedCountSpriteText.Font = DisplayedCountSpriteText.Font.With(fixedWidth: true); LeadingZeroes = leading; } @@ -49,6 +49,13 @@ namespace osu.Game.Graphics.UserInterface return ((long)count).ToString(format); } + protected override OsuSpriteText CreateSpriteText() + { + var spriteText = base.CreateSpriteText(); + spriteText.Font = spriteText.Font.With(fixedWidth: true); + return spriteText; + } + public override void Increment(double amount) { Current.Value += amount; diff --git a/osu.Game/Screens/Ranking/Expanded/Statistics/AccuracyStatistic.cs b/osu.Game/Screens/Ranking/Expanded/Statistics/AccuracyStatistic.cs index 2a0e33aab7..921ad80976 100644 --- a/osu.Game/Screens/Ranking/Expanded/Statistics/AccuracyStatistic.cs +++ b/osu.Game/Screens/Ranking/Expanded/Statistics/AccuracyStatistic.cs @@ -3,6 +3,7 @@ using osu.Framework.Graphics; using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; using osu.Game.Screens.Ranking.Expanded.Accuracy; using osu.Game.Utils; @@ -43,16 +44,18 @@ namespace osu.Game.Screens.Ranking.Expanded.Statistics protected override Easing RollingEasing => AccuracyCircle.ACCURACY_TRANSFORM_EASING; - public Counter() - { - DisplayedCountSpriteText.Font = OsuFont.Torus.With(size: 20, fixedWidth: true); - DisplayedCountSpriteText.Spacing = new Vector2(-2, 0); - } - protected override string FormatCount(double count) => count.FormatAccuracy(); public override void Increment(double amount) => Current.Value += amount; + + protected override OsuSpriteText CreateSpriteText() + { + var spriteText = base.CreateSpriteText(); + spriteText.Font = OsuFont.Torus.With(size: 20, fixedWidth: true); + spriteText.Spacing = new Vector2(-2, 0); + return spriteText; + } } } } diff --git a/osu.Game/Screens/Ranking/Expanded/Statistics/CounterStatistic.cs b/osu.Game/Screens/Ranking/Expanded/Statistics/CounterStatistic.cs index 817cc9b8c2..cc0f49c968 100644 --- a/osu.Game/Screens/Ranking/Expanded/Statistics/CounterStatistic.cs +++ b/osu.Game/Screens/Ranking/Expanded/Statistics/CounterStatistic.cs @@ -3,6 +3,7 @@ using osu.Framework.Graphics; using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; using osu.Game.Screens.Ranking.Expanded.Accuracy; using osuTK; @@ -43,10 +44,12 @@ namespace osu.Game.Screens.Ranking.Expanded.Statistics protected override Easing RollingEasing => AccuracyCircle.ACCURACY_TRANSFORM_EASING; - public Counter() + protected override OsuSpriteText CreateSpriteText() { - DisplayedCountSpriteText.Font = OsuFont.Torus.With(size: 20, fixedWidth: true); - DisplayedCountSpriteText.Spacing = new Vector2(-2, 0); + var spriteText = base.CreateSpriteText(); + spriteText.Font = OsuFont.Torus.With(size: 20, fixedWidth: true); + spriteText.Spacing = new Vector2(-2, 0); + return spriteText; } public override void Increment(int amount) diff --git a/osu.Game/Screens/Ranking/Expanded/TotalScoreCounter.cs b/osu.Game/Screens/Ranking/Expanded/TotalScoreCounter.cs index cab04edb8b..b0060d19ac 100644 --- a/osu.Game/Screens/Ranking/Expanded/TotalScoreCounter.cs +++ b/osu.Game/Screens/Ranking/Expanded/TotalScoreCounter.cs @@ -3,6 +3,7 @@ using osu.Framework.Graphics; using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; using osu.Game.Screens.Ranking.Expanded.Accuracy; using osuTK; @@ -23,15 +24,21 @@ namespace osu.Game.Screens.Ranking.Expanded // Todo: AutoSize X removed here due to https://github.com/ppy/osu-framework/issues/3369 AutoSizeAxes = Axes.Y; RelativeSizeAxes = Axes.X; - DisplayedCountSpriteText.Anchor = Anchor.TopCentre; - DisplayedCountSpriteText.Origin = Anchor.TopCentre; - - DisplayedCountSpriteText.Font = OsuFont.Torus.With(size: 60, weight: FontWeight.Light, fixedWidth: true); - DisplayedCountSpriteText.Spacing = new Vector2(-5, 0); } protected override string FormatCount(long count) => count.ToString("N0"); + protected override OsuSpriteText CreateSpriteText() + { + var spriteText = base.CreateSpriteText(); + spriteText.Anchor = Anchor.TopCentre; + spriteText.Origin = Anchor.TopCentre; + + spriteText.Font = OsuFont.Torus.With(size: 60, weight: FontWeight.Light, fixedWidth: true); + spriteText.Spacing = new Vector2(-5, 0); + return spriteText; + } + public override void Increment(long amount) => Current.Value += amount; } From 22b52d63c7767f4cc9d75c4ff249cf5d5e6828c0 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 4 Aug 2020 20:51:59 +0900 Subject: [PATCH 069/434] Update framework --- osu.Android.props | 2 +- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index 13b4b6ebbb..924e9c4a16 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -52,6 +52,6 @@ - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 745555e0e2..627c2f3d33 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -24,7 +24,7 @@ - + diff --git a/osu.iOS.props b/osu.iOS.props index f1080f0c8b..f443937017 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -70,7 +70,7 @@ - + @@ -80,7 +80,7 @@ - + From d7e82efb671016649e13a1afcaec640691567392 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 4 Aug 2020 21:16:59 +0900 Subject: [PATCH 070/434] Fix tests --- .../Visual/UserInterface/TestSceneLogoTrackingContainer.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneLogoTrackingContainer.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneLogoTrackingContainer.cs index 010e4330d7..5582cc6826 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneLogoTrackingContainer.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneLogoTrackingContainer.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System; +using System.Linq; using NUnit.Framework; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -263,7 +264,7 @@ namespace osu.Game.Tests.Visual.UserInterface private void moveLogoFacade() { - if (logoFacade?.Transforms.Count == 0 && transferContainer?.Transforms.Count == 0) + if (!(logoFacade?.Transforms).Any() && !(transferContainer?.Transforms).Any()) { Random random = new Random(); trackingContainer.Delay(500).MoveTo(new Vector2(random.Next(0, (int)logo.Parent.DrawWidth), random.Next(0, (int)logo.Parent.DrawHeight)), 300); From 9fb7b8f3d8b6e1c83c0de13c3d4eb1af8d4dc7dd Mon Sep 17 00:00:00 2001 From: Sebastian Krajewski Date: Tue, 4 Aug 2020 15:43:33 +0200 Subject: [PATCH 071/434] Rename the property to "AlignWithStoryboard" --- osu.Game.Rulesets.Osu/UI/DrawableOsuRuleset.cs | 2 +- .../UI/OsuPlayfieldAdjustmentContainer.cs | 11 ++++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/osu.Game.Rulesets.Osu/UI/DrawableOsuRuleset.cs b/osu.Game.Rulesets.Osu/UI/DrawableOsuRuleset.cs index e6e37fd58e..b2299398e1 100644 --- a/osu.Game.Rulesets.Osu/UI/DrawableOsuRuleset.cs +++ b/osu.Game.Rulesets.Osu/UI/DrawableOsuRuleset.cs @@ -35,7 +35,7 @@ namespace osu.Game.Rulesets.Osu.UI protected override PassThroughInputManager CreateInputManager() => new OsuInputManager(Ruleset.RulesetInfo); - public override PlayfieldAdjustmentContainer CreatePlayfieldAdjustmentContainer() => new OsuPlayfieldAdjustmentContainer { PlayfieldShift = true }; + public override PlayfieldAdjustmentContainer CreatePlayfieldAdjustmentContainer() => new OsuPlayfieldAdjustmentContainer { AlignWithStoryboard = true }; protected override ResumeOverlay CreateResumeOverlay() => new OsuResumeOverlay(); diff --git a/osu.Game.Rulesets.Osu/UI/OsuPlayfieldAdjustmentContainer.cs b/osu.Game.Rulesets.Osu/UI/OsuPlayfieldAdjustmentContainer.cs index 700601dbfd..0d1a5a8304 100644 --- a/osu.Game.Rulesets.Osu/UI/OsuPlayfieldAdjustmentContainer.cs +++ b/osu.Game.Rulesets.Osu/UI/OsuPlayfieldAdjustmentContainer.cs @@ -11,16 +11,17 @@ namespace osu.Game.Rulesets.Osu.UI public class OsuPlayfieldAdjustmentContainer : PlayfieldAdjustmentContainer { protected override Container Content => content; - private readonly Container content; + private readonly ScalingContainer content; private const float playfield_size_adjust = 0.8f; /// - /// Whether an osu-stable playfield offset should be applied (8 osu!pixels) + /// When true, an offset is applied to allow alignment with historical storyboards displayed in the same parent space. + /// This will shift the playfield downwards slightly. /// - public bool PlayfieldShift + public bool AlignWithStoryboard { - set => ((ScalingContainer)content).PlayfieldShift = value; + set => content.PlayfieldShift = value; } public OsuPlayfieldAdjustmentContainer() @@ -65,7 +66,7 @@ namespace osu.Game.Rulesets.Osu.UI // Scale = 819.2 / 512 // Scale = 1.6 Scale = new Vector2(Parent.ChildSize.X / OsuPlayfield.BASE_SIZE.X); - Position = new Vector2(0, (PlayfieldShift ? 8f : 0f) * Parent.ChildSize.Y / OsuPlayfield.BASE_SIZE.Y); + Position = new Vector2(0, (PlayfieldShift ? 8f : 0f) * Scale.X); // Size = 0.625 Size = Vector2.Divide(Vector2.One, Scale); } From 24bc9b33b1437cf845834743c7019a5429773b46 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 5 Aug 2020 15:40:45 +0900 Subject: [PATCH 072/434] Always place spinners behind hitcircles/sliders --- osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs b/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs index 600efefca3..4ef9bbe091 100644 --- a/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs +++ b/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs @@ -23,7 +23,8 @@ namespace osu.Game.Rulesets.Osu.UI { public class OsuPlayfield : Playfield { - private readonly ApproachCircleProxyContainer approachCircles; + private readonly ProxyContainer approachCircles; + private readonly ProxyContainer spinnerProxies; private readonly JudgementContainer judgementLayer; private readonly FollowPointRenderer followPoints; private readonly OrderedHitPolicy hitPolicy; @@ -38,6 +39,10 @@ namespace osu.Game.Rulesets.Osu.UI { InternalChildren = new Drawable[] { + spinnerProxies = new ProxyContainer + { + RelativeSizeAxes = Axes.Both + }, followPoints = new FollowPointRenderer { RelativeSizeAxes = Axes.Both, @@ -54,7 +59,7 @@ namespace osu.Game.Rulesets.Osu.UI { Child = HitObjectContainer, }, - approachCircles = new ApproachCircleProxyContainer + approachCircles = new ProxyContainer { RelativeSizeAxes = Axes.Both, Depth = -1, @@ -76,6 +81,9 @@ namespace osu.Game.Rulesets.Osu.UI h.OnNewResult += onNewResult; h.OnLoadComplete += d => { + if (d is DrawableSpinner) + spinnerProxies.Add(d.CreateProxy()); + if (d is IDrawableHitObjectWithProxiedApproach c) approachCircles.Add(c.ProxiedLayer.CreateProxy()); }; @@ -113,9 +121,9 @@ namespace osu.Game.Rulesets.Osu.UI public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => HitObjectContainer.ReceivePositionalInputAt(screenSpacePos); - private class ApproachCircleProxyContainer : LifetimeManagementContainer + private class ProxyContainer : LifetimeManagementContainer { - public void Add(Drawable approachCircleProxy) => AddInternal(approachCircleProxy); + public void Add(Drawable proxy) => AddInternal(proxy); } private class DrawableJudgementPool : DrawablePool From bb73489ae5947c4be39ecaca7a3634f4b49c6db1 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 5 Aug 2020 18:44:34 +0900 Subject: [PATCH 073/434] Fix very short spinners being impossible to complete --- .../TestSceneSpinner.cs | 40 ++++++++++++++----- .../Objects/Drawables/DrawableSpinner.cs | 13 +++++- osu.Game.Rulesets.Osu/Objects/Spinner.cs | 3 +- 3 files changed, 44 insertions(+), 12 deletions(-) diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSpinner.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSpinner.cs index b57561f3e1..be92a25dbe 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSpinner.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSpinner.cs @@ -17,32 +17,54 @@ namespace osu.Game.Rulesets.Osu.Tests { private int depthIndex; - public TestSceneSpinner() + private TestDrawableSpinner drawableSpinner; + + [TestCase(false)] + [TestCase(true)] + public void TestVariousSpinners(bool autoplay) { AddStep("Miss Big", () => SetContents(() => testSingle(2))); AddStep("Miss Medium", () => SetContents(() => testSingle(5))); AddStep("Miss Small", () => SetContents(() => testSingle(7))); - AddStep("Hit Big", () => SetContents(() => testSingle(2, true))); - AddStep("Hit Medium", () => SetContents(() => testSingle(5, true))); - AddStep("Hit Small", () => SetContents(() => testSingle(7, true))); + AddStep("Hit Big", () => SetContents(() => testSingle(2, autoplay))); + AddStep("Hit Medium", () => SetContents(() => testSingle(5, autoplay))); + AddStep("Hit Small", () => SetContents(() => testSingle(7, autoplay))); } - private Drawable testSingle(float circleSize, bool auto = false) + [TestCase(false)] + [TestCase(true)] + public void TestLongSpinner(bool autoplay) { - var spinner = new Spinner { StartTime = Time.Current + 2000, EndTime = Time.Current + 5000 }; + AddStep("Very short spinner", () => SetContents(() => testSingle(5, autoplay, 2000))); + AddUntilStep("Wait for completion", () => drawableSpinner.Result.HasResult); + AddUntilStep("Check correct progress", () => drawableSpinner.Progress == (autoplay ? 1 : 0)); + } + + [TestCase(false)] + [TestCase(true)] + public void TestSuperShortSpinner(bool autoplay) + { + AddStep("Very short spinner", () => SetContents(() => testSingle(5, autoplay, 200))); + AddUntilStep("Wait for completion", () => drawableSpinner.Result.HasResult); + AddUntilStep("Short spinner implicitly completes", () => drawableSpinner.Progress == 1); + } + + private Drawable testSingle(float circleSize, bool auto = false, double length = 3000) + { + var spinner = new Spinner { StartTime = Time.Current + 2000, EndTime = Time.Current + +2000 + length }; spinner.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty { CircleSize = circleSize }); - var drawable = new TestDrawableSpinner(spinner, auto) + drawableSpinner = new TestDrawableSpinner(spinner, auto) { Anchor = Anchor.Centre, Depth = depthIndex++ }; foreach (var mod in SelectedMods.Value.OfType()) - mod.ApplyToDrawableHitObjects(new[] { drawable }); + mod.ApplyToDrawableHitObjects(new[] { drawableSpinner }); - return drawable; + return drawableSpinner; } private class TestDrawableSpinner : DrawableSpinner diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs index 68516bedf8..7363da0de8 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs @@ -175,7 +175,18 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables /// /// The completion progress of this spinner from 0..1 (clamped). /// - public float Progress => Math.Clamp(RotationTracker.CumulativeRotation / 360 / Spinner.SpinsRequired, 0, 1); + public float Progress + { + get + { + if (Spinner.SpinsRequired == 0) + // some spinners are so short they can't require an integer spin count. + // these become implicitly hit. + return 1; + + return Math.Clamp(RotationTracker.CumulativeRotation / 360 / Spinner.SpinsRequired, 0, 1); + } + } protected override void CheckForResult(bool userTriggered, double timeOffset) { diff --git a/osu.Game.Rulesets.Osu/Objects/Spinner.cs b/osu.Game.Rulesets.Osu/Objects/Spinner.cs index 619b49926e..1658a4e7c2 100644 --- a/osu.Game.Rulesets.Osu/Objects/Spinner.cs +++ b/osu.Game.Rulesets.Osu/Objects/Spinner.cs @@ -1,7 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System; using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Rulesets.Judgements; @@ -45,7 +44,7 @@ namespace osu.Game.Rulesets.Osu.Objects double minimumRotationsPerSecond = stable_matching_fudge * BeatmapDifficulty.DifficultyRange(difficulty.OverallDifficulty, 3, 5, 7.5); - SpinsRequired = (int)Math.Max(1, (secondsDuration * minimumRotationsPerSecond)); + SpinsRequired = (int)(secondsDuration * minimumRotationsPerSecond); MaximumBonusSpins = (int)((maximum_rotations_per_second - minimumRotationsPerSecond) * secondsDuration); } From 3916d98e5292db1546b4b9ced3bcea8c27ae887f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 5 Aug 2020 18:50:37 +0900 Subject: [PATCH 074/434] Add comment for clarity --- osu.Game/Overlays/NewsOverlay.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Overlays/NewsOverlay.cs b/osu.Game/Overlays/NewsOverlay.cs index f8666e22c5..09fb445b1f 100644 --- a/osu.Game/Overlays/NewsOverlay.cs +++ b/osu.Game/Overlays/NewsOverlay.cs @@ -67,6 +67,8 @@ namespace osu.Game.Overlays protected override void LoadComplete() { base.LoadComplete(); + + // should not be run until first pop-in to avoid requesting data before user views. article.BindValueChanged(onArticleChanged); } From bf1bb3267420e64400d8991c34bb2b65f026c9c5 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 5 Aug 2020 19:06:58 +0900 Subject: [PATCH 075/434] Add missing toolbar tooltips for right-hand icons --- osu.Game/Overlays/Toolbar/ToolbarBeatmapListingButton.cs | 2 ++ osu.Game/Overlays/Toolbar/ToolbarChangelogButton.cs | 2 ++ osu.Game/Overlays/Toolbar/ToolbarChatButton.cs | 2 ++ osu.Game/Overlays/Toolbar/ToolbarMusicButton.cs | 2 ++ osu.Game/Overlays/Toolbar/ToolbarNewsButton.cs | 2 ++ osu.Game/Overlays/Toolbar/ToolbarRankingsButton.cs | 2 ++ osu.Game/Overlays/Toolbar/ToolbarSocialButton.cs | 2 ++ 7 files changed, 14 insertions(+) diff --git a/osu.Game/Overlays/Toolbar/ToolbarBeatmapListingButton.cs b/osu.Game/Overlays/Toolbar/ToolbarBeatmapListingButton.cs index eecb368ee9..3c38fdd207 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarBeatmapListingButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarBeatmapListingButton.cs @@ -11,6 +11,8 @@ namespace osu.Game.Overlays.Toolbar public ToolbarBeatmapListingButton() { SetIcon(OsuIcon.ChevronDownCircle); + TooltipMain = "Beatmap Listing"; + TooltipSub = "Browse for new beatmaps"; } [BackgroundDependencyLoader(true)] diff --git a/osu.Game/Overlays/Toolbar/ToolbarChangelogButton.cs b/osu.Game/Overlays/Toolbar/ToolbarChangelogButton.cs index 84210e27a4..c88b418853 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarChangelogButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarChangelogButton.cs @@ -11,6 +11,8 @@ namespace osu.Game.Overlays.Toolbar public ToolbarChangelogButton() { SetIcon(FontAwesome.Solid.Bullhorn); + TooltipMain = "Changelog"; + TooltipSub = "Track recent dev updates in the osu! ecosystem"; } [BackgroundDependencyLoader(true)] diff --git a/osu.Game/Overlays/Toolbar/ToolbarChatButton.cs b/osu.Game/Overlays/Toolbar/ToolbarChatButton.cs index ad0e5be551..ec7da54571 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarChatButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarChatButton.cs @@ -11,6 +11,8 @@ namespace osu.Game.Overlays.Toolbar public ToolbarChatButton() { SetIcon(FontAwesome.Solid.Comments); + TooltipMain = "Chat"; + TooltipSub = "Join the real-time discussion"; } [BackgroundDependencyLoader(true)] diff --git a/osu.Game/Overlays/Toolbar/ToolbarMusicButton.cs b/osu.Game/Overlays/Toolbar/ToolbarMusicButton.cs index b29aec5842..712da12208 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarMusicButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarMusicButton.cs @@ -11,6 +11,8 @@ namespace osu.Game.Overlays.Toolbar public ToolbarMusicButton() { Icon = FontAwesome.Solid.Music; + TooltipMain = "Now playing"; + TooltipSub = "Manage the currently playing track"; } [BackgroundDependencyLoader(true)] diff --git a/osu.Game/Overlays/Toolbar/ToolbarNewsButton.cs b/osu.Game/Overlays/Toolbar/ToolbarNewsButton.cs index e813a3f4cb..106c67a041 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarNewsButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarNewsButton.cs @@ -11,6 +11,8 @@ namespace osu.Game.Overlays.Toolbar public ToolbarNewsButton() { Icon = FontAwesome.Solid.Newspaper; + TooltipMain = "News"; + TooltipSub = "Get up-to-date on community happenings"; } [BackgroundDependencyLoader(true)] diff --git a/osu.Game/Overlays/Toolbar/ToolbarRankingsButton.cs b/osu.Game/Overlays/Toolbar/ToolbarRankingsButton.cs index cbd097696d..c026ce99fe 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarRankingsButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarRankingsButton.cs @@ -11,6 +11,8 @@ namespace osu.Game.Overlays.Toolbar public ToolbarRankingsButton() { SetIcon(FontAwesome.Regular.ChartBar); + TooltipMain = "Ranking"; + TooltipSub = "Find out who's the best right now"; } [BackgroundDependencyLoader(true)] diff --git a/osu.Game/Overlays/Toolbar/ToolbarSocialButton.cs b/osu.Game/Overlays/Toolbar/ToolbarSocialButton.cs index f6646eb81d..0dbb552c15 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarSocialButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarSocialButton.cs @@ -11,6 +11,8 @@ namespace osu.Game.Overlays.Toolbar public ToolbarSocialButton() { Icon = FontAwesome.Solid.Users; + TooltipMain = "Friends"; + TooltipSub = "Interact with those close to you"; } [BackgroundDependencyLoader(true)] From 84f6b7608cf83a76db915d148d6c7f2090290742 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Wed, 5 Aug 2020 20:05:53 +0300 Subject: [PATCH 076/434] Remove misleading ExpandNumberPiece lookup --- osu.Game.Rulesets.Osu/Skinning/OsuLegacySkinTransformer.cs | 5 ----- osu.Game.Rulesets.Osu/Skinning/OsuSkinConfiguration.cs | 1 - 2 files changed, 6 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Skinning/OsuLegacySkinTransformer.cs b/osu.Game.Rulesets.Osu/Skinning/OsuLegacySkinTransformer.cs index 80602dfa40..81d1d05b66 100644 --- a/osu.Game.Rulesets.Osu/Skinning/OsuLegacySkinTransformer.cs +++ b/osu.Game.Rulesets.Osu/Skinning/OsuLegacySkinTransformer.cs @@ -6,7 +6,6 @@ using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Game.Skinning; using osuTK; -using static osu.Game.Skinning.LegacySkinConfiguration; namespace osu.Game.Rulesets.Osu.Skinning { @@ -139,10 +138,6 @@ namespace osu.Game.Rulesets.Osu.Skinning // HitCircleOverlayAboveNumer (with typo) should still be supported for now. return Source.GetConfig(OsuSkinConfiguration.HitCircleOverlayAboveNumber) ?? Source.GetConfig(OsuSkinConfiguration.HitCircleOverlayAboveNumer); - - case OsuSkinConfiguration.ExpandNumberPiece: - bool expand = !(source.GetConfig(LegacySetting.Version)?.Value >= 2.0m); - return SkinUtils.As(new BindableBool(expand)); } break; diff --git a/osu.Game.Rulesets.Osu/Skinning/OsuSkinConfiguration.cs b/osu.Game.Rulesets.Osu/Skinning/OsuSkinConfiguration.cs index c04312a2c3..154160fdb5 100644 --- a/osu.Game.Rulesets.Osu/Skinning/OsuSkinConfiguration.cs +++ b/osu.Game.Rulesets.Osu/Skinning/OsuSkinConfiguration.cs @@ -7,7 +7,6 @@ namespace osu.Game.Rulesets.Osu.Skinning { HitCirclePrefix, HitCircleOverlap, - ExpandNumberPiece, SliderBorderSize, SliderPathRadius, AllowSliderBallTint, From 1ab6110c05e7fc4e0bbc18ec3847636e847780b2 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Wed, 5 Aug 2020 20:07:05 +0300 Subject: [PATCH 077/434] Apply fade out to the number piece with quarter the pieces duration --- .../Skinning/LegacyMainCirclePiece.cs | 67 ++++++++++++------- 1 file changed, 43 insertions(+), 24 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Skinning/LegacyMainCirclePiece.cs b/osu.Game.Rulesets.Osu/Skinning/LegacyMainCirclePiece.cs index fe28e69ff2..41fe170ae0 100644 --- a/osu.Game.Rulesets.Osu/Skinning/LegacyMainCirclePiece.cs +++ b/osu.Game.Rulesets.Osu/Skinning/LegacyMainCirclePiece.cs @@ -14,6 +14,7 @@ using osu.Game.Rulesets.Osu.Objects; using osu.Game.Skinning; using osuTK; using osuTK.Graphics; +using static osu.Game.Skinning.LegacySkinConfiguration; namespace osu.Game.Rulesets.Osu.Skinning { @@ -28,7 +29,9 @@ namespace osu.Game.Rulesets.Osu.Skinning Size = new Vector2(OsuHitObject.OBJECT_RADIUS * 2); } + private Container circlePieces; private Sprite hitCircleSprite, hitCircleOverlay; + private SkinnableSpriteText hitCircleText; private readonly IBindable state = new Bindable(); @@ -45,12 +48,27 @@ namespace osu.Game.Rulesets.Osu.Skinning InternalChildren = new Drawable[] { - hitCircleSprite = new Sprite + circlePieces = new Container { - Texture = getTextureWithFallback(string.Empty), - Colour = drawableObject.AccentColour.Value, Anchor = Anchor.Centre, Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + Children = new[] + { + hitCircleSprite = new Sprite + { + Texture = getTextureWithFallback(string.Empty), + Colour = drawableObject.AccentColour.Value, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + }, + hitCircleOverlay = new Sprite + { + Texture = getTextureWithFallback("overlay"), + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + } + } }, hitCircleText = new SkinnableSpriteText(new OsuSkinComponent(OsuSkinComponents.HitCircleText), _ => new OsuSpriteText { @@ -61,31 +79,16 @@ namespace osu.Game.Rulesets.Osu.Skinning Anchor = Anchor.Centre, Origin = Anchor.Centre, }, - hitCircleOverlay = new Sprite - { - Texture = getTextureWithFallback("overlay"), - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - } }; bool overlayAboveNumber = skin.GetConfig(OsuSkinConfiguration.HitCircleOverlayAboveNumber)?.Value ?? true; - if (!overlayAboveNumber) - ChangeInternalChildDepth(hitCircleText, -float.MaxValue); + if (overlayAboveNumber) + AddInternal(hitCircleOverlay.CreateProxy()); state.BindTo(drawableObject.State); accentColour.BindTo(drawableObject.AccentColour); indexInCurrentCombo.BindTo(osuObject.IndexInCurrentComboBindable); - } - - protected override void LoadComplete() - { - base.LoadComplete(); - - state.BindValueChanged(updateState, true); - accentColour.BindValueChanged(colour => hitCircleSprite.Colour = colour.NewValue, true); - indexInCurrentCombo.BindValueChanged(index => hitCircleText.Text = (index.NewValue + 1).ToString(), true); Texture getTextureWithFallback(string name) { @@ -98,6 +101,15 @@ namespace osu.Game.Rulesets.Osu.Skinning } } + protected override void LoadComplete() + { + base.LoadComplete(); + + state.BindValueChanged(updateState, true); + accentColour.BindValueChanged(colour => hitCircleSprite.Colour = colour.NewValue, true); + indexInCurrentCombo.BindValueChanged(index => hitCircleText.Text = (index.NewValue + 1).ToString(), true); + } + private void updateState(ValueChangedEvent state) { const double legacy_fade_duration = 240; @@ -105,13 +117,20 @@ namespace osu.Game.Rulesets.Osu.Skinning switch (state.NewValue) { case ArmedState.Hit: - this.FadeOut(legacy_fade_duration, Easing.Out); + circlePieces.FadeOut(legacy_fade_duration, Easing.Out); + circlePieces.ScaleTo(1.4f, legacy_fade_duration, Easing.Out); - hitCircleSprite.ScaleTo(1.4f, legacy_fade_duration, Easing.Out); - hitCircleOverlay.ScaleTo(1.4f, legacy_fade_duration, Easing.Out); + var legacyVersion = skin.GetConfig(LegacySetting.Version)?.Value; - if (skin.GetConfig(OsuSkinConfiguration.ExpandNumberPiece)?.Value ?? true) + if (legacyVersion >= 2.0m) + // legacy skins of version 2.0 and newer apply immediate fade out to the number piece and only that. + hitCircleText.FadeOut(legacy_fade_duration / 4, Easing.Out); + else + { + // old skins scale and fade it normally along other pieces. + hitCircleText.FadeOut(legacy_fade_duration, Easing.Out); hitCircleText.ScaleTo(1.4f, legacy_fade_duration, Easing.Out); + } break; } From 43161697f88983bc271715e792c7a89eed9631d0 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Wed, 5 Aug 2020 23:41:57 +0300 Subject: [PATCH 078/434] Fix wrong english --- osu.Game.Rulesets.Osu/Skinning/LegacyMainCirclePiece.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Skinning/LegacyMainCirclePiece.cs b/osu.Game.Rulesets.Osu/Skinning/LegacyMainCirclePiece.cs index 41fe170ae0..74a2cb7dc5 100644 --- a/osu.Game.Rulesets.Osu/Skinning/LegacyMainCirclePiece.cs +++ b/osu.Game.Rulesets.Osu/Skinning/LegacyMainCirclePiece.cs @@ -123,7 +123,7 @@ namespace osu.Game.Rulesets.Osu.Skinning var legacyVersion = skin.GetConfig(LegacySetting.Version)?.Value; if (legacyVersion >= 2.0m) - // legacy skins of version 2.0 and newer apply immediate fade out to the number piece and only that. + // legacy skins of version 2.0 and newer only apply very short fade out to the number piece. hitCircleText.FadeOut(legacy_fade_duration / 4, Easing.Out); else { From 9465e7abe10e22482d598f9529d43a9b7468706f Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Wed, 5 Aug 2020 23:45:00 +0300 Subject: [PATCH 079/434] Rename sprites container to "circleSprites" --- osu.Game.Rulesets.Osu/Skinning/LegacyMainCirclePiece.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Skinning/LegacyMainCirclePiece.cs b/osu.Game.Rulesets.Osu/Skinning/LegacyMainCirclePiece.cs index 74a2cb7dc5..9fbd9f50b4 100644 --- a/osu.Game.Rulesets.Osu/Skinning/LegacyMainCirclePiece.cs +++ b/osu.Game.Rulesets.Osu/Skinning/LegacyMainCirclePiece.cs @@ -29,7 +29,7 @@ namespace osu.Game.Rulesets.Osu.Skinning Size = new Vector2(OsuHitObject.OBJECT_RADIUS * 2); } - private Container circlePieces; + private Container circleSprites; private Sprite hitCircleSprite, hitCircleOverlay; private SkinnableSpriteText hitCircleText; @@ -48,7 +48,7 @@ namespace osu.Game.Rulesets.Osu.Skinning InternalChildren = new Drawable[] { - circlePieces = new Container + circleSprites = new Container { Anchor = Anchor.Centre, Origin = Anchor.Centre, @@ -117,8 +117,8 @@ namespace osu.Game.Rulesets.Osu.Skinning switch (state.NewValue) { case ArmedState.Hit: - circlePieces.FadeOut(legacy_fade_duration, Easing.Out); - circlePieces.ScaleTo(1.4f, legacy_fade_duration, Easing.Out); + circleSprites.FadeOut(legacy_fade_duration, Easing.Out); + circleSprites.ScaleTo(1.4f, legacy_fade_duration, Easing.Out); var legacyVersion = skin.GetConfig(LegacySetting.Version)?.Value; From e3f314349abc74ebc3ef6e1774045325fd763a75 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 6 Aug 2020 12:27:30 +0900 Subject: [PATCH 080/434] Don't use title case Co-authored-by: Joseph Madamba --- osu.Game/Overlays/Toolbar/ToolbarBeatmapListingButton.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Toolbar/ToolbarBeatmapListingButton.cs b/osu.Game/Overlays/Toolbar/ToolbarBeatmapListingButton.cs index 3c38fdd207..64430c77ac 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarBeatmapListingButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarBeatmapListingButton.cs @@ -11,7 +11,7 @@ namespace osu.Game.Overlays.Toolbar public ToolbarBeatmapListingButton() { SetIcon(OsuIcon.ChevronDownCircle); - TooltipMain = "Beatmap Listing"; + TooltipMain = "Beatmap listing"; TooltipSub = "Browse for new beatmaps"; } From d5324be07d00ff9276831f2263ac326efa020f35 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 6 Aug 2020 12:33:40 +0900 Subject: [PATCH 081/434] Fix malformed testcase --- osu.Game.Rulesets.Osu.Tests/TestSceneSpinner.cs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSpinner.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSpinner.cs index be92a25dbe..ed89a4c991 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSpinner.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSpinner.cs @@ -23,12 +23,10 @@ namespace osu.Game.Rulesets.Osu.Tests [TestCase(true)] public void TestVariousSpinners(bool autoplay) { - AddStep("Miss Big", () => SetContents(() => testSingle(2))); - AddStep("Miss Medium", () => SetContents(() => testSingle(5))); - AddStep("Miss Small", () => SetContents(() => testSingle(7))); - AddStep("Hit Big", () => SetContents(() => testSingle(2, autoplay))); - AddStep("Hit Medium", () => SetContents(() => testSingle(5, autoplay))); - AddStep("Hit Small", () => SetContents(() => testSingle(7, autoplay))); + string term = autoplay ? "Hit" : "Miss"; + AddStep($"{term} Big", () => SetContents(() => testSingle(2, autoplay))); + AddStep($"{term} Medium", () => SetContents(() => testSingle(5, autoplay))); + AddStep($"{term} Small", () => SetContents(() => testSingle(7, autoplay))); } [TestCase(false)] From 3b15a50f0d343fbf985abc0167d86f04972958df Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 6 Aug 2020 12:34:42 +0900 Subject: [PATCH 082/434] Fix unnecessary + character --- osu.Game.Rulesets.Osu.Tests/TestSceneSpinner.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSpinner.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSpinner.cs index ed89a4c991..47b3926ceb 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSpinner.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSpinner.cs @@ -49,7 +49,13 @@ namespace osu.Game.Rulesets.Osu.Tests private Drawable testSingle(float circleSize, bool auto = false, double length = 3000) { - var spinner = new Spinner { StartTime = Time.Current + 2000, EndTime = Time.Current + +2000 + length }; + const double delay = 2000; + + var spinner = new Spinner + { + StartTime = Time.Current + delay, + EndTime = Time.Current + delay + length + }; spinner.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty { CircleSize = circleSize }); From 9a00ad48c617a4d490ab5420698b2656c3679a45 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 6 Aug 2020 14:43:39 +0900 Subject: [PATCH 083/434] Update components to use extension methods --- osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs | 1 + osu.Game/Rulesets/UI/DrawableRulesetDependencies.cs | 2 ++ osu.Game/Screens/Play/PauseOverlay.cs | 1 + 3 files changed, 4 insertions(+) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs index 7363da0de8..a2a49b5c42 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs @@ -4,6 +4,7 @@ using System; using System.Linq; using osu.Framework.Allocation; +using osu.Framework.Audio; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; diff --git a/osu.Game/Rulesets/UI/DrawableRulesetDependencies.cs b/osu.Game/Rulesets/UI/DrawableRulesetDependencies.cs index 168e937256..3f7dc957fb 100644 --- a/osu.Game/Rulesets/UI/DrawableRulesetDependencies.cs +++ b/osu.Game/Rulesets/UI/DrawableRulesetDependencies.cs @@ -117,6 +117,8 @@ namespace osu.Game.Rulesets.UI public void RemoveAdjustment(AdjustableProperty type, BindableNumber adjustBindable) => throw new NotSupportedException(); + public void RemoveAllAdjustments(AdjustableProperty type) => throw new NotImplementedException(); + public BindableNumber Volume => throw new NotSupportedException(); public BindableNumber Balance => throw new NotSupportedException(); diff --git a/osu.Game/Screens/Play/PauseOverlay.cs b/osu.Game/Screens/Play/PauseOverlay.cs index fa917cda32..97f1d1c91d 100644 --- a/osu.Game/Screens/Play/PauseOverlay.cs +++ b/osu.Game/Screens/Play/PauseOverlay.cs @@ -4,6 +4,7 @@ using System; using System.Linq; using osu.Framework.Allocation; +using osu.Framework.Audio; using osu.Framework.Graphics; using osu.Game.Audio; using osu.Game.Graphics; From 641279ec3e8397f23b2f21c200cf99af313d9253 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 6 Aug 2020 14:43:48 +0900 Subject: [PATCH 084/434] Make SkinnableSound an IAdjustableAudioComponent --- osu.Game/Skinning/SkinnableSound.cs | 42 ++++++++--------------------- 1 file changed, 11 insertions(+), 31 deletions(-) diff --git a/osu.Game/Skinning/SkinnableSound.cs b/osu.Game/Skinning/SkinnableSound.cs index 27f6c37895..11856fa581 100644 --- a/osu.Game/Skinning/SkinnableSound.cs +++ b/osu.Game/Skinning/SkinnableSound.cs @@ -4,19 +4,18 @@ using System.Collections.Generic; using System.Linq; using osu.Framework.Allocation; +using osu.Framework.Audio; using osu.Framework.Audio.Track; using osu.Framework.Bindables; using osu.Framework.Extensions.IEnumerableExtensions; -using osu.Framework.Graphics; using osu.Framework.Graphics.Audio; using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Transforms; using osu.Game.Audio; using osu.Game.Screens.Play; namespace osu.Game.Skinning { - public class SkinnableSound : SkinReloadableDrawable + public class SkinnableSound : SkinReloadableDrawable, IAdjustableAudioComponent { private readonly ISampleInfo[] hitSamples; @@ -143,36 +142,17 @@ namespace osu.Game.Skinning public BindableNumber Tempo => samplesContainer.Tempo; + public void AddAdjustment(AdjustableProperty type, BindableNumber adjustBindable) + => samplesContainer.AddAdjustment(type, adjustBindable); + + public void RemoveAdjustment(AdjustableProperty type, BindableNumber adjustBindable) + => samplesContainer.RemoveAdjustment(type, adjustBindable); + + public void RemoveAllAdjustments(AdjustableProperty type) + => samplesContainer.RemoveAllAdjustments(type); + public bool IsPlaying => samplesContainer.Any(s => s.Playing); - /// - /// Smoothly adjusts over time. - /// - /// A to which further transforms can be added. - public TransformSequence VolumeTo(double newVolume, double duration = 0, Easing easing = Easing.None) => - samplesContainer.VolumeTo(newVolume, duration, easing); - - /// - /// Smoothly adjusts over time. - /// - /// A to which further transforms can be added. - public TransformSequence BalanceTo(double newBalance, double duration = 0, Easing easing = Easing.None) => - samplesContainer.BalanceTo(newBalance, duration, easing); - - /// - /// Smoothly adjusts over time. - /// - /// A to which further transforms can be added. - public TransformSequence FrequencyTo(double newFrequency, double duration = 0, Easing easing = Easing.None) => - samplesContainer.FrequencyTo(newFrequency, duration, easing); - - /// - /// Smoothly adjusts over time. - /// - /// A to which further transforms can be added. - public TransformSequence TempoTo(double newTempo, double duration = 0, Easing easing = Easing.None) => - samplesContainer.TempoTo(newTempo, duration, easing); - #endregion } } From 6e42b8219c4510b856923aa08712c50dbf37fa87 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 4 Aug 2020 21:53:00 +0900 Subject: [PATCH 085/434] Move track to MusicController, compiles --- .../TestSceneHoldNoteInput.cs | 2 +- .../TestSceneOutOfOrderHits.cs | 2 +- .../TestSceneSliderInput.cs | 2 +- .../TestSceneSliderSnaking.cs | 15 +- .../TestSceneSpinnerRotation.cs | 13 +- .../Skinning/TestSceneDrawableTaikoMascot.cs | 4 +- .../Skinning/TestSceneTaikoPlayfield.cs | 2 +- .../Skins/TestSceneBeatmapSkinResources.cs | 3 +- .../Visual/Editing/TimelineTestScene.cs | 11 +- .../TestSceneCompletionCancellation.cs | 15 +- .../Gameplay/TestSceneGameplayRewinding.cs | 15 +- .../TestSceneNightcoreBeatContainer.cs | 4 +- .../Visual/Gameplay/TestScenePause.cs | 2 +- .../Visual/Gameplay/TestScenePlayerLoader.cs | 6 +- .../Visual/Gameplay/TestSceneStoryboard.cs | 10 +- .../Visual/Menus/TestSceneIntroWelcome.cs | 7 +- .../Navigation/TestSceneScreenNavigation.cs | 23 +- .../TestSceneBeatSyncedContainer.cs | 5 +- .../TestSceneNowPlayingOverlay.cs | 4 +- osu.Game/Beatmaps/BeatmapManager.cs | 2 +- .../Beatmaps/BeatmapManager_WorkingBeatmap.cs | 16 -- osu.Game/Beatmaps/IWorkingBeatmap.cs | 5 - osu.Game/Beatmaps/WorkingBeatmap.cs | 22 +- .../Containers/BeatSyncedContainer.cs | 16 +- osu.Game/OsuGame.cs | 23 +- osu.Game/OsuGameBase.cs | 10 - osu.Game/Overlays/Music/PlaylistOverlay.cs | 10 +- osu.Game/Overlays/MusicController.cs | 221 ++++++++++++++++-- osu.Game/Overlays/NowPlayingOverlay.cs | 10 +- osu.Game/Rulesets/Mods/IApplicableToTrack.cs | 2 +- osu.Game/Rulesets/Mods/ModDaycore.cs | 6 +- osu.Game/Rulesets/Mods/ModNightcore.cs | 6 +- osu.Game/Rulesets/Mods/ModRateAdjust.cs | 4 +- osu.Game/Rulesets/Mods/ModTimeRamp.cs | 4 +- .../Edit/Components/BottomBarContainer.cs | 2 - .../Edit/Components/PlaybackControl.cs | 8 +- .../Timelines/Summary/Parts/MarkerPart.cs | 5 +- .../Timelines/Summary/Parts/TimelinePart.cs | 8 +- .../Compose/Components/Timeline/Timeline.cs | 34 +-- .../Timeline/TimelineTickDisplay.cs | 7 +- osu.Game/Screens/Edit/Editor.cs | 8 +- osu.Game/Screens/Edit/EditorClock.cs | 22 +- osu.Game/Screens/Menu/IntroScreen.cs | 8 +- osu.Game/Screens/Menu/IntroTriangles.cs | 2 +- osu.Game/Screens/Menu/IntroWelcome.cs | 6 +- osu.Game/Screens/Menu/LogoVisualisation.cs | 12 +- osu.Game/Screens/Menu/MainMenu.cs | 16 +- osu.Game/Screens/Menu/OsuLogo.cs | 9 +- .../Multi/Match/Components/ReadyButton.cs | 6 +- osu.Game/Screens/Multi/Multiplayer.cs | 23 +- osu.Game/Screens/Play/FailAnimation.cs | 12 +- .../Screens/Play/GameplayClockContainer.cs | 46 +--- osu.Game/Screens/Select/SongSelect.cs | 34 ++- osu.Game/Tests/Beatmaps/TestWorkingBeatmap.cs | 2 - osu.Game/Tests/Visual/EditorClockTestScene.cs | 2 +- osu.Game/Tests/Visual/OsuTestScene.cs | 8 +- .../Visual/RateAdjustedBeatmapTestScene.cs | 2 +- 57 files changed, 438 insertions(+), 346 deletions(-) diff --git a/osu.Game.Rulesets.Mania.Tests/TestSceneHoldNoteInput.cs b/osu.Game.Rulesets.Mania.Tests/TestSceneHoldNoteInput.cs index 95072cf4f8..c3e0c277a0 100644 --- a/osu.Game.Rulesets.Mania.Tests/TestSceneHoldNoteInput.cs +++ b/osu.Game.Rulesets.Mania.Tests/TestSceneHoldNoteInput.cs @@ -343,7 +343,7 @@ namespace osu.Game.Rulesets.Mania.Tests judgementResults = new List(); }); - AddUntilStep("Beatmap at 0", () => Beatmap.Value.Track.CurrentTime == 0); + AddUntilStep("Beatmap at 0", () => MusicController.CurrentTrackTime == 0); AddUntilStep("Wait until player is loaded", () => currentPlayer.IsCurrentScreen()); AddUntilStep("Wait for completion", () => currentPlayer.ScoreProcessor.HasCompleted.Value); } diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneOutOfOrderHits.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneOutOfOrderHits.cs index 854626d362..dc7e59b40d 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneOutOfOrderHits.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneOutOfOrderHits.cs @@ -385,7 +385,7 @@ namespace osu.Game.Rulesets.Osu.Tests judgementResults = new List(); }); - AddUntilStep("Beatmap at 0", () => Beatmap.Value.Track.CurrentTime == 0); + AddUntilStep("Beatmap at 0", () => MusicController.CurrentTrackTime == 0); AddUntilStep("Wait until player is loaded", () => currentPlayer.IsCurrentScreen()); AddUntilStep("Wait for completion", () => currentPlayer.ScoreProcessor.HasCompleted.Value); } diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs index b543b6fa94..2dffcfeabb 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs @@ -366,7 +366,7 @@ namespace osu.Game.Rulesets.Osu.Tests judgementResults = new List(); }); - AddUntilStep("Beatmap at 0", () => Beatmap.Value.Track.CurrentTime == 0); + AddUntilStep("Beatmap at 0", () => MusicController.CurrentTrackTime == 0); AddUntilStep("Wait until player is loaded", () => currentPlayer.IsCurrentScreen()); AddUntilStep("Wait for completion", () => currentPlayer.ScoreProcessor.HasCompleted.Value); } diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderSnaking.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderSnaking.cs index a69646507a..cd46e8c545 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderSnaking.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderSnaking.cs @@ -22,7 +22,6 @@ using osu.Game.Rulesets.Osu.Objects.Drawables; using osu.Game.Rulesets.Osu.Objects.Drawables.Pieces; using osu.Game.Storyboards; using osuTK; -using static osu.Game.Tests.Visual.OsuTestScene.ClockBackedTestWorkingBeatmap; namespace osu.Game.Rulesets.Osu.Tests { @@ -32,8 +31,6 @@ namespace osu.Game.Rulesets.Osu.Tests [Resolved] private AudioManager audioManager { get; set; } - private TrackVirtualManual track; - protected override bool Autoplay => autoplay; private bool autoplay; @@ -44,11 +41,7 @@ namespace osu.Game.Rulesets.Osu.Tests private const double fade_in_modifier = -1200; protected override WorkingBeatmap CreateWorkingBeatmap(IBeatmap beatmap, Storyboard storyboard = null) - { - var working = new ClockBackedTestWorkingBeatmap(beatmap, storyboard, new FramedClock(new ManualClock { Rate = 1 }), audioManager); - track = (TrackVirtualManual)working.Track; - return working; - } + => new ClockBackedTestWorkingBeatmap(beatmap, storyboard, new FramedClock(new ManualClock { Rate = 1 }), audioManager); [BackgroundDependencyLoader] private void load(RulesetConfigCache configCache) @@ -72,7 +65,7 @@ namespace osu.Game.Rulesets.Osu.Tests { AddStep("enable autoplay", () => autoplay = true); base.SetUpSteps(); - AddUntilStep("wait for track to start running", () => track.IsRunning); + AddUntilStep("wait for track to start running", () => MusicController.IsPlaying); double startTime = hitObjects[sliderIndex].StartTime; retrieveDrawableSlider(sliderIndex); @@ -97,7 +90,7 @@ namespace osu.Game.Rulesets.Osu.Tests { AddStep("have autoplay", () => autoplay = true); base.SetUpSteps(); - AddUntilStep("wait for track to start running", () => track.IsRunning); + AddUntilStep("wait for track to start running", () => MusicController.IsPlaying); double startTime = hitObjects[sliderIndex].StartTime; retrieveDrawableSlider(sliderIndex); @@ -201,7 +194,7 @@ namespace osu.Game.Rulesets.Osu.Tests private void addSeekStep(double time) { - AddStep($"seek to {time}", () => track.Seek(time)); + AddStep($"seek to {time}", () => MusicController.SeekTo(time)); AddUntilStep("wait for seek to finish", () => Precision.AlmostEquals(time, Player.DrawableRuleset.FrameStableClock.CurrentTime, 100)); } diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerRotation.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerRotation.cs index b46964e8b7..105e19a73c 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerRotation.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerRotation.cs @@ -24,7 +24,6 @@ using osu.Game.Scoring; using osu.Game.Storyboards; using osu.Game.Tests.Visual; using osuTK; -using static osu.Game.Tests.Visual.OsuTestScene.ClockBackedTestWorkingBeatmap; namespace osu.Game.Rulesets.Osu.Tests { @@ -33,18 +32,12 @@ namespace osu.Game.Rulesets.Osu.Tests [Resolved] private AudioManager audioManager { get; set; } - private TrackVirtualManual track; - protected override bool Autoplay => true; protected override TestPlayer CreatePlayer(Ruleset ruleset) => new ScoreExposedPlayer(); protected override WorkingBeatmap CreateWorkingBeatmap(IBeatmap beatmap, Storyboard storyboard = null) - { - var working = new ClockBackedTestWorkingBeatmap(beatmap, storyboard, new FramedClock(new ManualClock { Rate = 1 }), audioManager); - track = (TrackVirtualManual)working.Track; - return working; - } + => new ClockBackedTestWorkingBeatmap(beatmap, storyboard, new FramedClock(new ManualClock { Rate = 1 }), audioManager); private DrawableSpinner drawableSpinner; private SpriteIcon spinnerSymbol => drawableSpinner.ChildrenOfType().Single(); @@ -54,7 +47,7 @@ namespace osu.Game.Rulesets.Osu.Tests { base.SetUpSteps(); - AddUntilStep("wait for track to start running", () => track.IsRunning); + AddUntilStep("wait for track to start running", () => MusicController.IsPlaying); AddStep("retrieve spinner", () => drawableSpinner = (DrawableSpinner)Player.DrawableRuleset.Playfield.AllHitObjects.First()); } @@ -198,7 +191,7 @@ namespace osu.Game.Rulesets.Osu.Tests private void addSeekStep(double time) { - AddStep($"seek to {time}", () => track.Seek(time)); + AddStep($"seek to {time}", () => MusicController.SeekTo(time)); AddUntilStep("wait for seek to finish", () => Precision.AlmostEquals(time, Player.DrawableRuleset.FrameStableClock.CurrentTime, 100)); } diff --git a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableTaikoMascot.cs b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableTaikoMascot.cs index 47d8a5c012..ba5aef5968 100644 --- a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableTaikoMascot.cs +++ b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableTaikoMascot.cs @@ -175,11 +175,11 @@ namespace osu.Game.Rulesets.Taiko.Tests.Skinning private void createDrawableRuleset() { - AddUntilStep("wait for beatmap to be loaded", () => Beatmap.Value.Track.IsLoaded); + AddUntilStep("wait for beatmap to be loaded", () => MusicController.TrackLoaded); AddStep("create drawable ruleset", () => { - Beatmap.Value.Track.Start(); + MusicController.Play(true); SetContents(() => { diff --git a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneTaikoPlayfield.cs b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneTaikoPlayfield.cs index 7b7e2c43d1..5c54393fb8 100644 --- a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneTaikoPlayfield.cs +++ b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneTaikoPlayfield.cs @@ -34,7 +34,7 @@ namespace osu.Game.Rulesets.Taiko.Tests.Skinning beatmap.ControlPointInfo.Add(0, new TimingControlPoint { BeatLength = 1000 }); - Beatmap.Value.Track.Start(); + MusicController.Play(true); }); AddStep("Load playfield", () => SetContents(() => new TaikoPlayfield(new ControlPointInfo()) diff --git a/osu.Game.Tests/Skins/TestSceneBeatmapSkinResources.cs b/osu.Game.Tests/Skins/TestSceneBeatmapSkinResources.cs index 4d3b73fb32..1a19326ac4 100644 --- a/osu.Game.Tests/Skins/TestSceneBeatmapSkinResources.cs +++ b/osu.Game.Tests/Skins/TestSceneBeatmapSkinResources.cs @@ -3,7 +3,6 @@ using NUnit.Framework; using osu.Framework.Allocation; -using osu.Framework.Audio.Track; using osu.Framework.Testing; using osu.Game.Audio; using osu.Game.Beatmaps; @@ -32,6 +31,6 @@ namespace osu.Game.Tests.Skins public void TestRetrieveOggSample() => AddAssert("sample is non-null", () => beatmap.Skin.GetSample(new SampleInfo("sample")) != null); [Test] - public void TestRetrieveOggTrack() => AddAssert("track is non-null", () => !(beatmap.Track is TrackVirtual)); + public void TestRetrieveOggTrack() => AddAssert("track is non-null", () => !MusicController.IsDummyDevice); } } diff --git a/osu.Game.Tests/Visual/Editing/TimelineTestScene.cs b/osu.Game.Tests/Visual/Editing/TimelineTestScene.cs index fdb8781563..5d6136d9fb 100644 --- a/osu.Game.Tests/Visual/Editing/TimelineTestScene.cs +++ b/osu.Game.Tests/Visual/Editing/TimelineTestScene.cs @@ -3,12 +3,11 @@ using osu.Framework.Allocation; using osu.Framework.Audio; -using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; -using osu.Game.Beatmaps; using osu.Game.Graphics.UserInterface; +using osu.Game.Overlays; using osu.Game.Rulesets.Edit; using osu.Game.Screens.Edit; using osu.Game.Screens.Edit.Compose.Components.Timeline; @@ -65,10 +64,10 @@ namespace osu.Game.Tests.Visual.Editing private readonly Drawable marker; [Resolved] - private IBindable beatmap { get; set; } + private EditorClock editorClock { get; set; } [Resolved] - private EditorClock editorClock { get; set; } + private MusicController musicController { get; set; } public AudioVisualiser() { @@ -94,8 +93,8 @@ namespace osu.Game.Tests.Visual.Editing { base.Update(); - if (beatmap.Value.Track.IsLoaded) - marker.X = (float)(editorClock.CurrentTime / beatmap.Value.Track.Length); + if (musicController.TrackLoaded) + marker.X = (float)(editorClock.CurrentTime / musicController.TrackLength); } } diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneCompletionCancellation.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneCompletionCancellation.cs index 79275d70a7..b39cfc3699 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneCompletionCancellation.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneCompletionCancellation.cs @@ -4,7 +4,6 @@ using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Audio; -using osu.Framework.Audio.Track; using osu.Framework.Screens; using osu.Framework.Testing; using osu.Framework.Timing; @@ -18,8 +17,6 @@ namespace osu.Game.Tests.Visual.Gameplay { public class TestSceneCompletionCancellation : OsuPlayerTestScene { - private Track track; - [Resolved] private AudioManager audio { get; set; } @@ -34,7 +31,7 @@ namespace osu.Game.Tests.Visual.Gameplay base.SetUpSteps(); // Ensure track has actually running before attempting to seek - AddUntilStep("wait for track to start running", () => track.IsRunning); + AddUntilStep("wait for track to start running", () => MusicController.IsPlaying); } [Test] @@ -73,13 +70,13 @@ namespace osu.Game.Tests.Visual.Gameplay private void complete() { - AddStep("seek to completion", () => track.Seek(5000)); + AddStep("seek to completion", () => MusicController.SeekTo(5000)); AddUntilStep("completion set by processor", () => Player.ScoreProcessor.HasCompleted.Value); } private void cancel() { - AddStep("rewind to cancel", () => track.Seek(4000)); + AddStep("rewind to cancel", () => MusicController.SeekTo(4000)); AddUntilStep("completion cleared by processor", () => !Player.ScoreProcessor.HasCompleted.Value); } @@ -91,11 +88,7 @@ namespace osu.Game.Tests.Visual.Gameplay } protected override WorkingBeatmap CreateWorkingBeatmap(IBeatmap beatmap, Storyboard storyboard = null) - { - var working = new ClockBackedTestWorkingBeatmap(beatmap, storyboard, new FramedClock(new ManualClock { Rate = 1 }), audio); - track = working.Track; - return working; - } + => new ClockBackedTestWorkingBeatmap(beatmap, storyboard, new FramedClock(new ManualClock { Rate = 1 }), audio); protected override IBeatmap CreateBeatmap(RulesetInfo ruleset) { diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneGameplayRewinding.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneGameplayRewinding.cs index 2a119f5199..6bdc65078a 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneGameplayRewinding.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneGameplayRewinding.cs @@ -5,10 +5,10 @@ using System.Linq; using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Audio; -using osu.Framework.Audio.Track; using osu.Framework.Utils; using osu.Framework.Timing; using osu.Game.Beatmaps; +using osu.Game.Overlays; using osu.Game.Rulesets; using osu.Game.Rulesets.Osu.Objects; using osu.Game.Storyboards; @@ -21,19 +21,16 @@ namespace osu.Game.Tests.Visual.Gameplay [Resolved] private AudioManager audioManager { get; set; } - private Track track; + [Resolved] + private MusicController musicController { get; set; } protected override WorkingBeatmap CreateWorkingBeatmap(IBeatmap beatmap, Storyboard storyboard = null) - { - var working = new ClockBackedTestWorkingBeatmap(beatmap, storyboard, new FramedClock(new ManualClock { Rate = 1 }), audioManager); - track = working.Track; - return working; - } + => new ClockBackedTestWorkingBeatmap(beatmap, storyboard, new FramedClock(new ManualClock { Rate = 1 }), audioManager); [Test] public void TestNoJudgementsOnRewind() { - AddUntilStep("wait for track to start running", () => track.IsRunning); + AddUntilStep("wait for track to start running", () => MusicController.IsPlaying); addSeekStep(3000); AddAssert("all judged", () => Player.DrawableRuleset.Playfield.AllHitObjects.All(h => h.Judged)); AddUntilStep("key counter counted keys", () => Player.HUDOverlay.KeyCounter.Children.All(kc => kc.CountPresses >= 7)); @@ -46,7 +43,7 @@ namespace osu.Game.Tests.Visual.Gameplay private void addSeekStep(double time) { - AddStep($"seek to {time}", () => track.Seek(time)); + AddStep($"seek to {time}", () => MusicController.SeekTo(time)); // Allow a few frames of lenience AddUntilStep("wait for seek to finish", () => Precision.AlmostEquals(time, Player.DrawableRuleset.FrameStableClock.CurrentTime, 100)); diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneNightcoreBeatContainer.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneNightcoreBeatContainer.cs index 951ee1489d..ce99d85e92 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneNightcoreBeatContainer.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneNightcoreBeatContainer.cs @@ -19,8 +19,8 @@ namespace osu.Game.Tests.Visual.Gameplay Beatmap.Value = CreateWorkingBeatmap(new OsuRuleset().RulesetInfo); - Beatmap.Value.Track.Start(); - Beatmap.Value.Track.Seek(Beatmap.Value.Beatmap.HitObjects.First().StartTime - 1000); + MusicController.Play(true); + MusicController.SeekTo(Beatmap.Value.Beatmap.HitObjects.First().StartTime - 1000); Add(new ModNightcore.NightcoreBeatContainer()); diff --git a/osu.Game.Tests/Visual/Gameplay/TestScenePause.cs b/osu.Game.Tests/Visual/Gameplay/TestScenePause.cs index 420bf29429..8f14de1578 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestScenePause.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestScenePause.cs @@ -288,7 +288,7 @@ namespace osu.Game.Tests.Visual.Gameplay private void confirmNoTrackAdjustments() { - AddAssert("track has no adjustments", () => Beatmap.Value.Track.AggregateFrequency.Value == 1); + AddAssert("track has no adjustments", () => MusicController.AggregateFrequency.Value == 1); } private void restart() => AddStep("restart", () => Player.Restart()); diff --git a/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs b/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs index 4c73065087..2f86db1b25 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs @@ -57,7 +57,7 @@ namespace osu.Game.Tests.Visual.Gameplay Beatmap.Value = CreateWorkingBeatmap(new OsuRuleset().RulesetInfo); foreach (var mod in SelectedMods.Value.OfType()) - mod.ApplyToTrack(Beatmap.Value.Track); + mod.ApplyToTrack(MusicController); InputManager.Child = container = new TestPlayerLoaderContainer( loader = new TestPlayerLoader(() => @@ -77,12 +77,12 @@ namespace osu.Game.Tests.Visual.Gameplay { AddStep("load dummy beatmap", () => ResetPlayer(false, () => SelectedMods.Value = new[] { new OsuModNightcore() })); AddUntilStep("wait for current", () => loader.IsCurrentScreen()); - AddAssert("mod rate applied", () => Beatmap.Value.Track.Rate != 1); + AddAssert("mod rate applied", () => MusicController.Rate != 1); AddStep("exit loader", () => loader.Exit()); AddUntilStep("wait for not current", () => !loader.IsCurrentScreen()); AddAssert("player did not load", () => !player.IsLoaded); AddUntilStep("player disposed", () => loader.DisposalTask?.IsCompleted == true); - AddAssert("mod rate still applied", () => Beatmap.Value.Track.Rate != 1); + AddAssert("mod rate still applied", () => MusicController.Rate != 1); } [Test] diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboard.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboard.cs index 9f1492a25f..a4b558fce2 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboard.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboard.cs @@ -87,11 +87,9 @@ namespace osu.Game.Tests.Visual.Gameplay private void restart() { - var track = Beatmap.Value.Track; - - track.Reset(); + MusicController.Reset(); loadStoryboard(Beatmap.Value); - track.Start(); + MusicController.Play(true); } private void loadStoryboard(WorkingBeatmap working) @@ -106,7 +104,7 @@ namespace osu.Game.Tests.Visual.Gameplay storyboard.Passing = false; storyboardContainer.Add(storyboard); - decoupledClock.ChangeSource(working.Track); + decoupledClock.ChangeSource(musicController.GetTrackClock()); } private void loadStoryboardNoVideo() @@ -129,7 +127,7 @@ namespace osu.Game.Tests.Visual.Gameplay storyboard = sb.CreateDrawable(Beatmap.Value); storyboardContainer.Add(storyboard); - decoupledClock.ChangeSource(Beatmap.Value.Track); + decoupledClock.ChangeSource(musicController.GetTrackClock()); } } } diff --git a/osu.Game.Tests/Visual/Menus/TestSceneIntroWelcome.cs b/osu.Game.Tests/Visual/Menus/TestSceneIntroWelcome.cs index 8f20e38494..36f98b7a0c 100644 --- a/osu.Game.Tests/Visual/Menus/TestSceneIntroWelcome.cs +++ b/osu.Game.Tests/Visual/Menus/TestSceneIntroWelcome.cs @@ -2,7 +2,6 @@ // See the LICENCE file in the repository root for full licence text. using NUnit.Framework; -using osu.Framework.Audio.Track; using osu.Framework.Screens; using osu.Game.Screens.Menu; @@ -15,11 +14,9 @@ namespace osu.Game.Tests.Visual.Menus public TestSceneIntroWelcome() { - AddUntilStep("wait for load", () => getTrack() != null); + AddUntilStep("wait for load", () => MusicController.TrackLoaded); - AddAssert("check if menu music loops", () => getTrack().Looping); + AddAssert("check if menu music loops", () => MusicController.Looping); } - - private Track getTrack() => (IntroStack?.CurrentScreen as MainMenu)?.Track; } } diff --git a/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs b/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs index 8ccaca8630..455b7e56e6 100644 --- a/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs +++ b/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs @@ -4,7 +4,6 @@ using System.Linq; using NUnit.Framework; using osu.Framework.Allocation; -using osu.Framework.Audio.Track; using osu.Framework.Graphics.Containers; using osu.Framework.Screens; using osu.Game.Beatmaps; @@ -46,7 +45,6 @@ namespace osu.Game.Tests.Visual.Navigation Player player = null; WorkingBeatmap beatmap() => Game.Beatmap.Value; - Track track() => beatmap().Track; PushAndConfirm(() => new TestSongSelect()); @@ -62,30 +60,27 @@ namespace osu.Game.Tests.Visual.Navigation AddUntilStep("wait for player", () => (player = Game.ScreenStack.CurrentScreen as Player) != null); AddUntilStep("wait for fail", () => player.HasFailed); - AddUntilStep("wait for track stop", () => !track().IsRunning); - AddAssert("Ensure time before preview point", () => track().CurrentTime < beatmap().Metadata.PreviewTime); + AddUntilStep("wait for track stop", () => !MusicController.IsPlaying); + AddAssert("Ensure time before preview point", () => MusicController.CurrentTrackTime < beatmap().Metadata.PreviewTime); pushEscape(); - AddUntilStep("wait for track playing", () => track().IsRunning); - AddAssert("Ensure time wasn't reset to preview point", () => track().CurrentTime < beatmap().Metadata.PreviewTime); + AddUntilStep("wait for track playing", () => MusicController.IsPlaying); + AddAssert("Ensure time wasn't reset to preview point", () => MusicController.CurrentTrackTime < beatmap().Metadata.PreviewTime); } [Test] public void TestMenuMakesMusic() { - WorkingBeatmap beatmap() => Game.Beatmap.Value; - Track track() => beatmap().Track; - TestSongSelect songSelect = null; PushAndConfirm(() => songSelect = new TestSongSelect()); - AddUntilStep("wait for no track", () => track() is TrackVirtual); + AddUntilStep("wait for no track", () => MusicController.IsDummyDevice); AddStep("return to menu", () => songSelect.Exit()); - AddUntilStep("wait for track", () => !(track() is TrackVirtual) && track().IsRunning); + AddUntilStep("wait for track", () => !MusicController.IsDummyDevice && MusicController.IsPlaying); } [Test] @@ -140,12 +135,12 @@ namespace osu.Game.Tests.Visual.Navigation AddUntilStep("Wait for music controller", () => Game.MusicController.IsLoaded); AddStep("Seek close to end", () => { - Game.MusicController.SeekTo(Game.Beatmap.Value.Track.Length - 1000); - Game.Beatmap.Value.Track.Completed += () => trackCompleted = true; + Game.MusicController.SeekTo(MusicController.TrackLength - 1000); + // MusicController.Completed += () => trackCompleted = true; }); AddUntilStep("Track was completed", () => trackCompleted); - AddUntilStep("Track was restarted", () => Game.Beatmap.Value.Track.IsRunning); + AddUntilStep("Track was restarted", () => MusicController.IsPlaying); } private void pushEscape() => diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneBeatSyncedContainer.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneBeatSyncedContainer.cs index dd5ceec739..f3fef8c355 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneBeatSyncedContainer.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneBeatSyncedContainer.cs @@ -71,6 +71,9 @@ namespace osu.Game.Tests.Visual.UserInterface private readonly Box flashLayer; + [Resolved] + private MusicController musicController { get; set; } + public BeatContainer() { RelativeSizeAxes = Axes.X; @@ -165,7 +168,7 @@ namespace osu.Game.Tests.Visual.UserInterface if (timingPoints.Count == 0) return 0; if (timingPoints[^1] == current) - return (int)Math.Ceiling((Beatmap.Value.Track.Length - current.Time) / current.BeatLength); + return (int)Math.Ceiling((musicController.TrackLength - current.Time) / current.BeatLength); return (int)Math.Ceiling((getNextTimingPoint(current).Time - current.Time) / current.BeatLength); } diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneNowPlayingOverlay.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneNowPlayingOverlay.cs index 532744a0fc..3ecd8ab550 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneNowPlayingOverlay.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneNowPlayingOverlay.cs @@ -80,12 +80,12 @@ namespace osu.Game.Tests.Visual.UserInterface AddStep("Store track", () => currentBeatmap = Beatmap.Value); AddStep(@"Seek track to 6 second", () => musicController.SeekTo(6000)); - AddUntilStep(@"Wait for current time to update", () => currentBeatmap.Track.CurrentTime > 5000); + AddUntilStep(@"Wait for current time to update", () => musicController.CurrentTrackTime > 5000); AddStep(@"Set previous", () => musicController.PreviousTrack()); AddAssert(@"Check beatmap didn't change", () => currentBeatmap == Beatmap.Value); - AddUntilStep("Wait for current time to update", () => currentBeatmap.Track.CurrentTime < 5000); + AddUntilStep("Wait for current time to update", () => musicController.CurrentTrackTime < 5000); AddStep(@"Set previous", () => musicController.PreviousTrack()); AddAssert(@"Check beatmap did change", () => currentBeatmap != Beatmap.Value); diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index b4b341634c..b2329f58ad 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -255,7 +255,7 @@ namespace osu.Game.Beatmaps new LargeTextureStore(host?.CreateTextureLoaderStore(Files.Store)), beatmapInfo, audioManager)); } - previous?.TransferTo(working); + // previous?.TransferTo(working); return working; } } diff --git a/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs b/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs index 39c5ccab27..33945a9eb1 100644 --- a/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs @@ -79,22 +79,6 @@ namespace osu.Game.Beatmaps } } - public override void RecycleTrack() - { - base.RecycleTrack(); - - trackStore?.Dispose(); - trackStore = null; - } - - public override void TransferTo(WorkingBeatmap other) - { - base.TransferTo(other); - - if (other is BeatmapManagerWorkingBeatmap owb && textureStore != null && BeatmapInfo.BackgroundEquals(other.BeatmapInfo)) - owb.textureStore = textureStore; - } - protected override Waveform GetWaveform() { try diff --git a/osu.Game/Beatmaps/IWorkingBeatmap.cs b/osu.Game/Beatmaps/IWorkingBeatmap.cs index 31975157a0..086b7502a2 100644 --- a/osu.Game/Beatmaps/IWorkingBeatmap.cs +++ b/osu.Game/Beatmaps/IWorkingBeatmap.cs @@ -26,11 +26,6 @@ namespace osu.Game.Beatmaps /// Texture Background { get; } - /// - /// Retrieves the audio track for this . - /// - Track Track { get; } - /// /// Retrieves the for the of this . /// diff --git a/osu.Game/Beatmaps/WorkingBeatmap.cs b/osu.Game/Beatmaps/WorkingBeatmap.cs index ac399e37c4..171201ca68 100644 --- a/osu.Game/Beatmaps/WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/WorkingBeatmap.cs @@ -40,7 +40,6 @@ namespace osu.Game.Beatmaps BeatmapSetInfo = beatmapInfo.BeatmapSet; Metadata = beatmapInfo.Metadata ?? BeatmapSetInfo?.Metadata ?? new BeatmapMetadata(); - track = new RecyclableLazy(() => GetTrack() ?? GetVirtualTrack(1000)); background = new RecyclableLazy(GetBackground, BackgroundStillValid); waveform = new RecyclableLazy(GetWaveform); storyboard = new RecyclableLazy(GetStoryboard); @@ -250,10 +249,9 @@ namespace osu.Game.Beatmaps protected abstract Texture GetBackground(); private readonly RecyclableLazy background; - public virtual bool TrackLoaded => track.IsResultAvailable; - public Track Track => track.Value; + public Track GetRealTrack() => GetTrack() ?? GetVirtualTrack(1000); + protected abstract Track GetTrack(); - private RecyclableLazy track; public bool WaveformLoaded => waveform.IsResultAvailable; public Waveform Waveform => waveform.Value; @@ -271,22 +269,6 @@ namespace osu.Game.Beatmaps protected virtual ISkin GetSkin() => new DefaultSkin(); private readonly RecyclableLazy skin; - /// - /// Transfer pieces of a beatmap to a new one, where possible, to save on loading. - /// - /// The new beatmap which is being switched to. - public virtual void TransferTo(WorkingBeatmap other) - { - if (track.IsResultAvailable && Track != null && BeatmapInfo.AudioEquals(other.BeatmapInfo)) - other.track = track; - } - - /// - /// Eagerly dispose of the audio track associated with this (if any). - /// Accessing track again will load a fresh instance. - /// - public virtual void RecycleTrack() => track.Recycle(); - ~WorkingBeatmap() { total_count.Value--; diff --git a/osu.Game/Graphics/Containers/BeatSyncedContainer.cs b/osu.Game/Graphics/Containers/BeatSyncedContainer.cs index df063f57d5..2dd28a01dc 100644 --- a/osu.Game/Graphics/Containers/BeatSyncedContainer.cs +++ b/osu.Game/Graphics/Containers/BeatSyncedContainer.cs @@ -7,6 +7,7 @@ using osu.Framework.Bindables; using osu.Framework.Graphics.Containers; using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; +using osu.Game.Overlays; namespace osu.Game.Graphics.Containers { @@ -14,6 +15,9 @@ namespace osu.Game.Graphics.Containers { protected readonly IBindable Beatmap = new Bindable(); + [Resolved] + private MusicController musicController { get; set; } + private int lastBeat; private TimingControlPoint lastTimingPoint; @@ -47,22 +51,18 @@ namespace osu.Game.Graphics.Containers protected override void Update() { - Track track = null; IBeatmap beatmap = null; double currentTrackTime = 0; TimingControlPoint timingPoint = null; EffectControlPoint effectPoint = null; - if (Beatmap.Value.TrackLoaded && Beatmap.Value.BeatmapLoaded) - { - track = Beatmap.Value.Track; + if (musicController.TrackLoaded && Beatmap.Value.BeatmapLoaded) beatmap = Beatmap.Value.Beatmap; - } - if (track != null && beatmap != null && track.IsRunning && track.Length > 0) + if (beatmap != null && musicController.IsPlaying && musicController.TrackLength > 0) { - currentTrackTime = track.CurrentTime + EarlyActivationMilliseconds; + currentTrackTime = musicController.CurrentTrackTime + EarlyActivationMilliseconds; timingPoint = beatmap.ControlPointInfo.TimingPointAt(currentTrackTime); effectPoint = beatmap.ControlPointInfo.EffectPointAt(currentTrackTime); @@ -98,7 +98,7 @@ namespace osu.Game.Graphics.Containers return; using (BeginDelayedSequence(-TimeSinceLastBeat, true)) - OnNewBeat(beatIndex, timingPoint, effectPoint, track?.CurrentAmplitudes ?? ChannelAmplitudes.Empty); + OnNewBeat(beatIndex, timingPoint, effectPoint, musicController.CurrentAmplitudes); lastBeat = beatIndex; lastTimingPoint = timingPoint; diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 26f7c3b93b..929254e8ad 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -431,19 +431,19 @@ namespace osu.Game if (newBeatmap != null) { - newBeatmap.Track.Completed += () => Scheduler.AddOnce(() => trackCompleted(newBeatmap)); + // MusicController.Completed += () => Scheduler.AddOnce(() => trackCompleted(newBeatmap)); newBeatmap.BeginAsyncLoad(); } - void trackCompleted(WorkingBeatmap b) - { - // the source of track completion is the audio thread, so the beatmap may have changed before firing. - if (Beatmap.Value != b) - return; - - if (!Beatmap.Value.Track.Looping && !Beatmap.Disabled) - MusicController.NextTrack(); - } + // void trackCompleted(WorkingBeatmap b) + // { + // // the source of track completion is the audio thread, so the beatmap may have changed before firing. + // if (Beatmap.Value != b) + // return; + // + // if (!MusicController.Looping && !Beatmap.Disabled) + // MusicController.NextTrack(); + // } } private void modsChanged(ValueChangedEvent> mods) @@ -555,6 +555,7 @@ namespace osu.Game BackButton.Receptor receptor; dependencies.CacheAs(idleTracker = new GameIdleTracker(6000)); + dependencies.CacheAs(MusicController = new MusicController()); AddRange(new Drawable[] { @@ -617,7 +618,7 @@ namespace osu.Game loadComponentSingleFile(new OnScreenDisplay(), Add, true); - loadComponentSingleFile(MusicController = new MusicController(), Add, true); + loadComponentSingleFile(MusicController, Add); loadComponentSingleFile(notifications.With(d => { diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index 98f60d52d3..24c1f7849c 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -238,16 +238,6 @@ namespace osu.Game Beatmap = new NonNullableBindable(defaultBeatmap); - // ScheduleAfterChildren is safety against something in the current frame accessing the previous beatmap's track - // and potentially causing a reload of it after just unloading. - // Note that the reason for this being added *has* been resolved, so it may be feasible to removed this if required. - Beatmap.BindValueChanged(b => ScheduleAfterChildren(() => - { - // compare to last beatmap as sometimes the two may share a track representation (optimisation, see WorkingBeatmap.TransferTo) - if (b.OldValue?.TrackLoaded == true && b.OldValue?.Track != b.NewValue?.Track) - b.OldValue.RecycleTrack(); - })); - dependencies.CacheAs>(Beatmap); dependencies.CacheAs(Beatmap); diff --git a/osu.Game/Overlays/Music/PlaylistOverlay.cs b/osu.Game/Overlays/Music/PlaylistOverlay.cs index b878aba489..c089158c01 100644 --- a/osu.Game/Overlays/Music/PlaylistOverlay.cs +++ b/osu.Game/Overlays/Music/PlaylistOverlay.cs @@ -30,6 +30,9 @@ namespace osu.Game.Overlays.Music [Resolved] private BeatmapManager beatmaps { get; set; } + [Resolved] + private MusicController musicController { get; set; } + private FilterControl filter; private Playlist list; @@ -80,10 +83,7 @@ namespace osu.Game.Overlays.Music BeatmapInfo toSelect = list.FirstVisibleSet?.Beatmaps?.FirstOrDefault(); if (toSelect != null) - { beatmap.Value = beatmaps.GetWorkingBeatmap(toSelect); - beatmap.Value.Track.Restart(); - } }; } @@ -116,12 +116,12 @@ namespace osu.Game.Overlays.Music { if (set.ID == (beatmap.Value?.BeatmapSetInfo?.ID ?? -1)) { - beatmap.Value?.Track?.Seek(0); + musicController.SeekTo(0); return; } beatmap.Value = beatmaps.GetWorkingBeatmap(set.Beatmaps.First()); - beatmap.Value.Track.Restart(); + musicController.Play(true); } } diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index a990f9a6ab..f5ca5a3a49 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -4,13 +4,18 @@ using System; using System.Collections.Generic; using System.Linq; +using JetBrains.Annotations; using osu.Framework.Allocation; +using osu.Framework.Audio; using osu.Framework.Audio.Track; using osu.Framework.Bindables; using osu.Framework.Graphics; +using osu.Framework.Graphics.Audio; +using osu.Framework.Graphics.Containers; using osu.Framework.Input.Bindings; using osu.Framework.Utils; using osu.Framework.Threading; +using osu.Framework.Timing; using osu.Game.Beatmaps; using osu.Game.Input.Bindings; using osu.Game.Overlays.OSD; @@ -21,7 +26,7 @@ namespace osu.Game.Overlays /// /// Handles playback of the global music track. /// - public class MusicController : Component, IKeyBindingHandler + public class MusicController : CompositeDrawable, IKeyBindingHandler, ITrack { [Resolved] private BeatmapManager beatmaps { get; set; } @@ -61,9 +66,23 @@ namespace osu.Game.Overlays [Resolved(canBeNull: true)] private OnScreenDisplay onScreenDisplay { get; set; } + [NotNull] + private readonly TrackContainer trackContainer; + + [CanBeNull] + private DrawableTrack drawableTrack; + + [CanBeNull] + private Track track; + private IBindable> managerUpdated; private IBindable> managerRemoved; + public MusicController() + { + InternalChild = trackContainer = new TrackContainer { RelativeSizeAxes = Axes.Both }; + } + [BackgroundDependencyLoader] private void load() { @@ -95,9 +114,35 @@ namespace osu.Game.Overlays } /// - /// Returns whether the current beatmap track is playing. + /// Returns whether the beatmap track is playing. /// - public bool IsPlaying => current?.Track.IsRunning ?? false; + public bool IsPlaying => drawableTrack?.IsRunning ?? false; + + /// + /// Returns whether the beatmap track is loaded. + /// + public bool TrackLoaded => drawableTrack?.IsLoaded == true; + + /// + /// Returns the current time of the beatmap track. + /// + public double CurrentTrackTime => drawableTrack?.CurrentTime ?? 0; + + /// + /// Returns the length of the beatmap track. + /// + public double TrackLength => drawableTrack?.Length ?? 0; + + public void AddAdjustment(AdjustableProperty type, BindableNumber adjustBindable) + => trackContainer.AddAdjustment(type, adjustBindable); + + public void RemoveAdjustment(AdjustableProperty type, BindableNumber adjustBindable) + => trackContainer.RemoveAdjustment(type, adjustBindable); + + public void Reset() => drawableTrack?.Reset(); + + [CanBeNull] + public IAdjustableClock GetTrackClock() => track; private void beatmapUpdated(ValueChangedEvent> weakSet) { @@ -130,7 +175,7 @@ namespace osu.Game.Overlays seekDelegate = Schedule(() => { if (!beatmap.Disabled) - current?.Track.Seek(position); + drawableTrack?.Seek(position); }); } @@ -142,9 +187,7 @@ namespace osu.Game.Overlays { if (IsUserPaused) return; - var track = current?.Track; - - if (track == null || track is TrackVirtual) + if (drawableTrack == null || drawableTrack.IsDummyDevice) { if (beatmap.Disabled) return; @@ -163,17 +206,15 @@ namespace osu.Game.Overlays /// Whether the operation was successful. public bool Play(bool restart = false) { - var track = current?.Track; - IsUserPaused = false; - if (track == null) + if (drawableTrack == null) return false; if (restart) - track.Restart(); + drawableTrack.Restart(); else if (!IsPlaying) - track.Start(); + drawableTrack.Start(); return true; } @@ -183,11 +224,9 @@ namespace osu.Game.Overlays /// public void Stop() { - var track = current?.Track; - IsUserPaused = true; - if (track?.IsRunning == true) - track.Stop(); + if (drawableTrack?.IsRunning == true) + drawableTrack.Stop(); } /// @@ -196,9 +235,7 @@ namespace osu.Game.Overlays /// Whether the operation was successful. public bool TogglePause() { - var track = current?.Track; - - if (track?.IsRunning == true) + if (drawableTrack?.IsRunning == true) Stop(); else Play(); @@ -220,7 +257,7 @@ namespace osu.Game.Overlays if (beatmap.Disabled) return PreviousTrackResult.None; - var currentTrackPosition = current?.Track.CurrentTime; + var currentTrackPosition = drawableTrack?.CurrentTime; if (currentTrackPosition >= restart_cutoff_point) { @@ -274,7 +311,7 @@ namespace osu.Game.Overlays { // if not scheduled, the previously track will be stopped one frame later (see ScheduleAfterChildren logic in GameBase). // we probably want to move this to a central method for switching to a new working beatmap in the future. - Schedule(() => beatmap.Value.Track.Restart()); + Schedule(() => drawableTrack?.Restart()); } private WorkingBeatmap current; @@ -307,6 +344,14 @@ namespace osu.Game.Overlays } current = beatmap.NewValue; + + drawableTrack?.Expire(); + drawableTrack = null; + track = null; + + if (current != null) + trackContainer.Add(drawableTrack = new DrawableTrack(track = current.GetRealTrack())); + TrackChanged?.Invoke(current, direction); ResetTrackAdjustments(); @@ -334,16 +379,15 @@ namespace osu.Game.Overlays public void ResetTrackAdjustments() { - var track = current?.Track; - if (track == null) + if (drawableTrack == null) return; - track.ResetSpeedAdjustments(); + drawableTrack.ResetSpeedAdjustments(); if (allowRateAdjustments) { foreach (var mod in mods.Value.OfType()) - mod.ApplyToTrack(track); + mod.ApplyToTrack(drawableTrack); } } @@ -394,6 +438,133 @@ namespace osu.Game.Overlays { } } + + private class TrackContainer : AudioContainer + { + } + + #region ITrack + + /// + /// The volume of this component. + /// + public BindableNumber Volume => drawableTrack?.Volume; // Todo: Bad + + /// + /// The playback balance of this sample (-1 .. 1 where 0 is centered) + /// + public BindableNumber Balance => drawableTrack?.Balance; // Todo: Bad + + /// + /// Rate at which the component is played back (affects pitch). 1 is 100% playback speed, or default frequency. + /// + public BindableNumber Frequency => drawableTrack?.Frequency; // Todo: Bad + + /// + /// Rate at which the component is played back (does not affect pitch). 1 is 100% playback speed. + /// + public BindableNumber Tempo => drawableTrack?.Tempo; // Todo: Bad + + public IBindable AggregateVolume => drawableTrack?.AggregateVolume; // Todo: Bad + + public IBindable AggregateBalance => drawableTrack?.AggregateBalance; // Todo: Bad + + public IBindable AggregateFrequency => drawableTrack?.AggregateFrequency; // Todo: Bad + + public IBindable AggregateTempo => drawableTrack?.AggregateTempo; // Todo: Bad + + /// + /// Overall playback rate (1 is 100%, -1 is reversed at 100%). + /// + public double Rate => AggregateFrequency.Value * AggregateTempo.Value; + + event Action ITrack.Completed + { + add + { + if (drawableTrack != null) + drawableTrack.Completed += value; + } + remove + { + if (drawableTrack != null) + drawableTrack.Completed -= value; + } + } + + event Action ITrack.Failed + { + add + { + if (drawableTrack != null) + drawableTrack.Failed += value; + } + remove + { + if (drawableTrack != null) + drawableTrack.Failed -= value; + } + } + + public bool Looping + { + get => drawableTrack?.Looping ?? false; + set + { + if (drawableTrack != null) + drawableTrack.Looping = value; + } + } + + public bool IsDummyDevice => drawableTrack?.IsDummyDevice ?? true; + + public double RestartPoint + { + get => drawableTrack?.RestartPoint ?? 0; + set + { + if (drawableTrack != null) + drawableTrack.RestartPoint = value; + } + } + + double ITrack.CurrentTime => CurrentTrackTime; + + double ITrack.Length + { + get => TrackLength; + set + { + if (drawableTrack != null) + drawableTrack.Length = value; + } + } + + public int? Bitrate => drawableTrack?.Bitrate; + + bool ITrack.IsRunning => IsPlaying; + + public bool IsReversed => drawableTrack?.IsReversed ?? false; + + public bool HasCompleted => drawableTrack?.HasCompleted ?? false; + + void ITrack.Reset() => drawableTrack?.Reset(); + + void ITrack.Restart() => Play(true); + + void ITrack.ResetSpeedAdjustments() => ResetTrackAdjustments(); + + bool ITrack.Seek(double seek) + { + SeekTo(seek); + return true; + } + + void ITrack.Start() => Play(); + + public ChannelAmplitudes CurrentAmplitudes => drawableTrack?.CurrentAmplitudes ?? ChannelAmplitudes.Empty; + + #endregion } public enum TrackChangeDirection diff --git a/osu.Game/Overlays/NowPlayingOverlay.cs b/osu.Game/Overlays/NowPlayingOverlay.cs index ebb4a96d14..fde6a52fee 100644 --- a/osu.Game/Overlays/NowPlayingOverlay.cs +++ b/osu.Game/Overlays/NowPlayingOverlay.cs @@ -234,14 +234,12 @@ namespace osu.Game.Overlays pendingBeatmapSwitch = null; } - var track = beatmap.Value?.TrackLoaded ?? false ? beatmap.Value.Track : null; - - if (track?.IsDummyDevice == false) + if (musicController.IsDummyDevice == false) { - progressBar.EndTime = track.Length; - progressBar.CurrentTime = track.CurrentTime; + progressBar.EndTime = musicController.TrackLength; + progressBar.CurrentTime = musicController.CurrentTrackTime; - playButton.Icon = track.IsRunning ? FontAwesome.Regular.PauseCircle : FontAwesome.Regular.PlayCircle; + playButton.Icon = musicController.IsPlaying ? FontAwesome.Regular.PauseCircle : FontAwesome.Regular.PlayCircle; } else { diff --git a/osu.Game/Rulesets/Mods/IApplicableToTrack.cs b/osu.Game/Rulesets/Mods/IApplicableToTrack.cs index 4d6d958e82..9b840cea08 100644 --- a/osu.Game/Rulesets/Mods/IApplicableToTrack.cs +++ b/osu.Game/Rulesets/Mods/IApplicableToTrack.cs @@ -10,6 +10,6 @@ namespace osu.Game.Rulesets.Mods /// public interface IApplicableToTrack : IApplicableMod { - void ApplyToTrack(Track track); + void ApplyToTrack(ITrack track); } } diff --git a/osu.Game/Rulesets/Mods/ModDaycore.cs b/osu.Game/Rulesets/Mods/ModDaycore.cs index bd98e735e5..9cefeb3340 100644 --- a/osu.Game/Rulesets/Mods/ModDaycore.cs +++ b/osu.Game/Rulesets/Mods/ModDaycore.cs @@ -27,11 +27,11 @@ namespace osu.Game.Rulesets.Mods }, true); } - public override void ApplyToTrack(Track track) + public override void ApplyToTrack(ITrack track) { // base.ApplyToTrack() intentionally not called (different tempo adjustment is applied) - track.AddAdjustment(AdjustableProperty.Frequency, freqAdjust); - track.AddAdjustment(AdjustableProperty.Tempo, tempoAdjust); + (track as Track)?.AddAdjustment(AdjustableProperty.Frequency, freqAdjust); + (track as Track)?.AddAdjustment(AdjustableProperty.Tempo, tempoAdjust); } } } diff --git a/osu.Game/Rulesets/Mods/ModNightcore.cs b/osu.Game/Rulesets/Mods/ModNightcore.cs index ed8eb2fb66..b34affa77f 100644 --- a/osu.Game/Rulesets/Mods/ModNightcore.cs +++ b/osu.Game/Rulesets/Mods/ModNightcore.cs @@ -38,11 +38,11 @@ namespace osu.Game.Rulesets.Mods }, true); } - public override void ApplyToTrack(Track track) + public override void ApplyToTrack(ITrack track) { // base.ApplyToTrack() intentionally not called (different tempo adjustment is applied) - track.AddAdjustment(AdjustableProperty.Frequency, freqAdjust); - track.AddAdjustment(AdjustableProperty.Tempo, tempoAdjust); + (track as Track)?.AddAdjustment(AdjustableProperty.Frequency, freqAdjust); + (track as Track)?.AddAdjustment(AdjustableProperty.Tempo, tempoAdjust); } public void ApplyToDrawableRuleset(DrawableRuleset drawableRuleset) diff --git a/osu.Game/Rulesets/Mods/ModRateAdjust.cs b/osu.Game/Rulesets/Mods/ModRateAdjust.cs index 874384686f..ee1280da39 100644 --- a/osu.Game/Rulesets/Mods/ModRateAdjust.cs +++ b/osu.Game/Rulesets/Mods/ModRateAdjust.cs @@ -12,9 +12,9 @@ namespace osu.Game.Rulesets.Mods { public abstract BindableNumber SpeedChange { get; } - public virtual void ApplyToTrack(Track track) + public virtual void ApplyToTrack(ITrack track) { - track.AddAdjustment(AdjustableProperty.Tempo, SpeedChange); + (track as Track)?.AddAdjustment(AdjustableProperty.Tempo, SpeedChange); } public virtual void ApplyToSample(SampleChannel sample) diff --git a/osu.Game/Rulesets/Mods/ModTimeRamp.cs b/osu.Game/Rulesets/Mods/ModTimeRamp.cs index 839d97f04e..0257e241b8 100644 --- a/osu.Game/Rulesets/Mods/ModTimeRamp.cs +++ b/osu.Game/Rulesets/Mods/ModTimeRamp.cs @@ -51,9 +51,9 @@ namespace osu.Game.Rulesets.Mods AdjustPitch.BindValueChanged(applyPitchAdjustment); } - public void ApplyToTrack(Track track) + public void ApplyToTrack(ITrack track) { - this.track = track; + this.track = track as Track; FinalRate.TriggerChange(); AdjustPitch.TriggerChange(); diff --git a/osu.Game/Screens/Edit/Components/BottomBarContainer.cs b/osu.Game/Screens/Edit/Components/BottomBarContainer.cs index cb5078a479..8d8c59b2ee 100644 --- a/osu.Game/Screens/Edit/Components/BottomBarContainer.cs +++ b/osu.Game/Screens/Edit/Components/BottomBarContainer.cs @@ -2,7 +2,6 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Allocation; -using osu.Framework.Audio.Track; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -18,7 +17,6 @@ namespace osu.Game.Screens.Edit.Components private const float contents_padding = 15; protected readonly IBindable Beatmap = new Bindable(); - protected Track Track => Beatmap.Value.Track; private readonly Drawable background; private readonly Container content; diff --git a/osu.Game/Screens/Edit/Components/PlaybackControl.cs b/osu.Game/Screens/Edit/Components/PlaybackControl.cs index 59b3d1c565..0a9b4f06a7 100644 --- a/osu.Game/Screens/Edit/Components/PlaybackControl.cs +++ b/osu.Game/Screens/Edit/Components/PlaybackControl.cs @@ -16,6 +16,7 @@ using osu.Framework.Input.Events; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; +using osu.Game.Overlays; using osuTK.Input; namespace osu.Game.Screens.Edit.Components @@ -27,6 +28,9 @@ namespace osu.Game.Screens.Edit.Components [Resolved] private EditorClock editorClock { get; set; } + [Resolved] + private MusicController musicController { get; set; } + private readonly BindableNumber tempo = new BindableDouble(1); [BackgroundDependencyLoader] @@ -62,12 +66,12 @@ namespace osu.Game.Screens.Edit.Components } }; - Track?.AddAdjustment(AdjustableProperty.Tempo, tempo); + musicController.AddAdjustment(AdjustableProperty.Tempo, tempo); } protected override void Dispose(bool isDisposing) { - Track?.RemoveAdjustment(AdjustableProperty.Tempo, tempo); + musicController?.RemoveAdjustment(AdjustableProperty.Tempo, tempo); base.Dispose(isDisposing); } diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/MarkerPart.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/MarkerPart.cs index 9e9ac93d23..a353f79ef4 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/MarkerPart.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/MarkerPart.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System; +using System.Diagnostics; using osuTK; using osu.Framework.Allocation; using osu.Framework.Graphics; @@ -58,7 +59,9 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts return; float markerPos = Math.Clamp(ToLocalSpace(screenPosition).X, 0, DrawWidth); - editorClock.SeekTo(markerPos / DrawWidth * editorClock.TrackLength); + + Debug.Assert(editorClock.TrackLength != null); + editorClock.SeekTo(markerPos / DrawWidth * editorClock.TrackLength.Value); }); } diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs index 4a7c3f26bc..446f7fdf88 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs @@ -8,6 +8,7 @@ using osuTK; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Beatmaps; +using osu.Game.Overlays; namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts { @@ -26,6 +27,9 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts protected override Container Content => content; + [Resolved] + private MusicController musicController { get; set; } + public TimelinePart(Container content = null) { AddInternal(this.content = content ?? new Container { RelativeSizeAxes = Axes.Both }); @@ -46,14 +50,14 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts private void updateRelativeChildSize() { // the track may not be loaded completely (only has a length once it is). - if (!Beatmap.Value.Track.IsLoaded) + if (!musicController.TrackLoaded) { content.RelativeChildSize = Vector2.One; Schedule(updateRelativeChildSize); return; } - content.RelativeChildSize = new Vector2((float)Math.Max(1, Beatmap.Value.Track.Length), 1); + content.RelativeChildSize = new Vector2((float)Math.Max(1, musicController.TrackLength), 1); } protected virtual void LoadBeatmap(WorkingBeatmap beatmap) diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs index 717d60b4f3..f35e5defd8 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs @@ -3,7 +3,6 @@ using System; using osu.Framework.Allocation; -using osu.Framework.Audio.Track; using osu.Framework.Bindables; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; @@ -11,6 +10,7 @@ using osu.Framework.Graphics.Audio; using osu.Framework.Input.Events; using osu.Game.Beatmaps; using osu.Game.Graphics; +using osu.Game.Overlays; using osu.Game.Rulesets.Edit; using osuTK; @@ -26,6 +26,9 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline [Resolved] private EditorClock editorClock { get; set; } + [Resolved] + private MusicController musicController { get; set; } + public Timeline() { ZoomDuration = 200; @@ -57,18 +60,21 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline Beatmap.BindValueChanged(b => { waveform.Waveform = b.NewValue.Waveform; - track = b.NewValue.Track; - if (track.Length > 0) + // Todo: Wrong. + Schedule(() => { - MaxZoom = getZoomLevelForVisibleMilliseconds(500); - MinZoom = getZoomLevelForVisibleMilliseconds(10000); - Zoom = getZoomLevelForVisibleMilliseconds(2000); - } + if (musicController.TrackLength > 0) + { + MaxZoom = getZoomLevelForVisibleMilliseconds(500); + MinZoom = getZoomLevelForVisibleMilliseconds(10000); + Zoom = getZoomLevelForVisibleMilliseconds(2000); + } + }); }, true); } - private float getZoomLevelForVisibleMilliseconds(double milliseconds) => (float)(track.Length / milliseconds); + private float getZoomLevelForVisibleMilliseconds(double milliseconds) => (float)(musicController.TrackLength / milliseconds); /// /// The timeline's scroll position in the last frame. @@ -90,8 +96,6 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline /// private bool trackWasPlaying; - private Track track; - protected override void Update() { base.Update(); @@ -129,18 +133,18 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline private void seekTrackToCurrent() { - if (!track.IsLoaded) + if (!musicController.TrackLoaded) return; - editorClock.Seek(Current / Content.DrawWidth * track.Length); + editorClock.Seek(Current / Content.DrawWidth * musicController.TrackLength); } private void scrollToTrackTime() { - if (!track.IsLoaded || track.Length == 0) + if (!musicController.TrackLoaded || musicController.TrackLength == 0) return; - ScrollTo((float)(editorClock.CurrentTime / track.Length) * Content.DrawWidth, false); + ScrollTo((float)(editorClock.CurrentTime / musicController.TrackLength) * Content.DrawWidth, false); } protected override bool OnMouseDown(MouseDownEvent e) @@ -184,7 +188,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline new SnapResult(screenSpacePosition, beatSnapProvider.SnapTime(getTimeFromPosition(Content.ToLocalSpace(screenSpacePosition)))); private double getTimeFromPosition(Vector2 localPosition) => - (localPosition.X / Content.DrawWidth) * track.Length; + (localPosition.X / Content.DrawWidth) * musicController.TrackLength; public float GetBeatSnapDistanceAt(double referenceTime) => throw new NotImplementedException(); diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineTickDisplay.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineTickDisplay.cs index 36ee976bf7..a833b354ed 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineTickDisplay.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineTickDisplay.cs @@ -3,10 +3,9 @@ using System.Linq; using osu.Framework.Allocation; -using osu.Framework.Bindables; using osu.Framework.Graphics; -using osu.Game.Beatmaps; using osu.Game.Graphics; +using osu.Game.Overlays; using osu.Game.Screens.Edit.Components.Timelines.Summary.Parts; using osu.Game.Screens.Edit.Components.Timelines.Summary.Visualisations; @@ -18,7 +17,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline private EditorBeatmap beatmap { get; set; } [Resolved] - private Bindable working { get; set; } + private MusicController musicController { get; set; } [Resolved] private BindableBeatDivisor beatDivisor { get; set; } @@ -44,7 +43,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline for (var i = 0; i < beatmap.ControlPointInfo.TimingPoints.Count; i++) { var point = beatmap.ControlPointInfo.TimingPoints[i]; - var until = i + 1 < beatmap.ControlPointInfo.TimingPoints.Count ? beatmap.ControlPointInfo.TimingPoints[i + 1].Time : working.Value.Track.Length; + var until = i + 1 < beatmap.ControlPointInfo.TimingPoints.Count ? beatmap.ControlPointInfo.TimingPoints[i + 1].Time : musicController.TrackLength; int beat = 0; diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index d92f3922c3..756b03d049 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -28,6 +28,7 @@ using osu.Framework.Logging; using osu.Game.Beatmaps; using osu.Game.Graphics.Cursor; using osu.Game.Input.Bindings; +using osu.Game.Overlays; using osu.Game.Rulesets.Edit; using osu.Game.Screens.Edit.Compose; using osu.Game.Screens.Edit.Setup; @@ -53,6 +54,9 @@ namespace osu.Game.Screens.Edit [Resolved] private BeatmapManager beatmapManager { get; set; } + [Resolved] + private MusicController musicController { get; set; } + private Box bottomBackground; private Container screenContainer; @@ -79,7 +83,7 @@ namespace osu.Game.Screens.Edit beatDivisor.BindValueChanged(divisor => Beatmap.Value.BeatmapInfo.BeatDivisor = divisor.NewValue); // Todo: should probably be done at a DrawableRuleset level to share logic with Player. - var sourceClock = (IAdjustableClock)Beatmap.Value.Track ?? new StopwatchClock(); + var sourceClock = musicController.GetTrackClock() ?? new StopwatchClock(); clock = new EditorClock(Beatmap.Value, beatDivisor) { IsCoupled = false }; clock.ChangeSource(sourceClock); @@ -346,7 +350,7 @@ namespace osu.Game.Screens.Edit private void resetTrack(bool seekToStart = false) { - Beatmap.Value.Track?.Stop(); + musicController.Stop(); if (seekToStart) { diff --git a/osu.Game/Screens/Edit/EditorClock.cs b/osu.Game/Screens/Edit/EditorClock.cs index d4d0feb813..4cb24f90a6 100644 --- a/osu.Game/Screens/Edit/EditorClock.cs +++ b/osu.Game/Screens/Edit/EditorClock.cs @@ -2,13 +2,16 @@ // See the LICENCE file in the repository root for full licence text. using System; +using System.Diagnostics; using System.Linq; +using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Transforms; using osu.Framework.Utils; using osu.Framework.Timing; using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; +using osu.Game.Overlays; namespace osu.Game.Screens.Edit { @@ -17,7 +20,7 @@ namespace osu.Game.Screens.Edit /// public class EditorClock : Component, IFrameBasedClock, IAdjustableClock, ISourceChangeableClock { - public readonly double TrackLength; + public double? TrackLength { get; private set; } public ControlPointInfo ControlPointInfo; @@ -25,12 +28,15 @@ namespace osu.Game.Screens.Edit private readonly DecoupleableInterpolatingFramedClock underlyingClock; + [Resolved] + private MusicController musicController { get; set; } + public EditorClock(WorkingBeatmap beatmap, BindableBeatDivisor beatDivisor) - : this(beatmap.Beatmap.ControlPointInfo, beatmap.Track.Length, beatDivisor) + : this(beatmap.Beatmap.ControlPointInfo, null, beatDivisor) { } - public EditorClock(ControlPointInfo controlPointInfo, double trackLength, BindableBeatDivisor beatDivisor) + public EditorClock(ControlPointInfo controlPointInfo, double? trackLength, BindableBeatDivisor beatDivisor) { this.beatDivisor = beatDivisor; @@ -45,6 +51,13 @@ namespace osu.Game.Screens.Edit { } + [BackgroundDependencyLoader] + private void load() + { + // Todo: What. + TrackLength ??= musicController.TrackLength; + } + /// /// Seek to the closest snappable beat from a time. /// @@ -135,7 +148,8 @@ namespace osu.Game.Screens.Edit seekTime = timingPoint.Time; // Ensure the sought point is within the boundaries - seekTime = Math.Clamp(seekTime, 0, TrackLength); + Debug.Assert(TrackLength != null); + seekTime = Math.Clamp(seekTime, 0, TrackLength.Value); SeekTo(seekTime); } diff --git a/osu.Game/Screens/Menu/IntroScreen.cs b/osu.Game/Screens/Menu/IntroScreen.cs index 5f91aaad15..7da5df2723 100644 --- a/osu.Game/Screens/Menu/IntroScreen.cs +++ b/osu.Game/Screens/Menu/IntroScreen.cs @@ -12,6 +12,7 @@ using osu.Framework.Screens; using osu.Game.Beatmaps; using osu.Game.Configuration; using osu.Game.IO.Archives; +using osu.Game.Overlays; using osu.Game.Screens.Backgrounds; using osu.Game.Skinning; using osuTK; @@ -43,7 +44,8 @@ namespace osu.Game.Screens.Menu private WorkingBeatmap initialBeatmap; - protected Track Track => initialBeatmap?.Track; + [Resolved] + protected MusicController MusicController { get; private set; } private readonly BindableDouble exitingVolumeFade = new BindableDouble(1); @@ -111,7 +113,7 @@ namespace osu.Game.Screens.Menu if (setInfo != null) { initialBeatmap = beatmaps.GetWorkingBeatmap(setInfo.Beatmaps[0]); - UsingThemedIntro = !(Track is TrackVirtual); + UsingThemedIntro = !MusicController.IsDummyDevice; } return UsingThemedIntro; @@ -150,7 +152,7 @@ namespace osu.Game.Screens.Menu { // Only start the current track if it is the menu music. A beatmap's track is started when entering the Main Menu. if (UsingThemedIntro) - Track.Restart(); + MusicController.Play(true); } protected override void LogoArriving(OsuLogo logo, bool resuming) diff --git a/osu.Game/Screens/Menu/IntroTriangles.cs b/osu.Game/Screens/Menu/IntroTriangles.cs index a9ef20436f..86a6fa3802 100644 --- a/osu.Game/Screens/Menu/IntroTriangles.cs +++ b/osu.Game/Screens/Menu/IntroTriangles.cs @@ -59,7 +59,7 @@ namespace osu.Game.Screens.Menu LoadComponentAsync(new TrianglesIntroSequence(logo, background) { RelativeSizeAxes = Axes.Both, - Clock = new FramedClock(UsingThemedIntro ? Track : null), + Clock = new FramedClock(UsingThemedIntro ? MusicController.GetTrackClock() : null), LoadMenu = LoadMenu }, t => { diff --git a/osu.Game/Screens/Menu/IntroWelcome.cs b/osu.Game/Screens/Menu/IntroWelcome.cs index bf42e36e8c..62cada577d 100644 --- a/osu.Game/Screens/Menu/IntroWelcome.cs +++ b/osu.Game/Screens/Menu/IntroWelcome.cs @@ -11,6 +11,7 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Textures; +using osu.Game.Overlays; using osu.Game.Screens.Backgrounds; using osuTK.Graphics; @@ -30,6 +31,9 @@ namespace osu.Game.Screens.Menu Alpha = 0, }; + [Resolved] + private MusicController musicController { get; set; } + private BackgroundScreenDefault background; [BackgroundDependencyLoader] @@ -40,7 +44,7 @@ namespace osu.Game.Screens.Menu pianoReverb = audio.Samples.Get(@"Intro/Welcome/welcome_piano"); - Track.Looping = true; + musicController.Looping = true; } protected override void LogoArriving(OsuLogo logo, bool resuming) diff --git a/osu.Game/Screens/Menu/LogoVisualisation.cs b/osu.Game/Screens/Menu/LogoVisualisation.cs index ebbb19636c..349654165f 100644 --- a/osu.Game/Screens/Menu/LogoVisualisation.cs +++ b/osu.Game/Screens/Menu/LogoVisualisation.cs @@ -20,6 +20,7 @@ using osu.Framework.Audio; using osu.Framework.Audio.Track; using osu.Framework.Bindables; using osu.Framework.Utils; +using osu.Game.Overlays; namespace osu.Game.Screens.Menu { @@ -74,6 +75,9 @@ namespace osu.Game.Screens.Menu /// public float Magnitude { get; set; } = 1; + [Resolved] + private MusicController musicController { get; set; } + private readonly float[] frequencyAmplitudes = new float[256]; private IShader shader; @@ -103,15 +107,15 @@ namespace osu.Game.Screens.Menu private void updateAmplitudes() { - var effect = beatmap.Value.BeatmapLoaded && beatmap.Value.TrackLoaded - ? beatmap.Value.Beatmap?.ControlPointInfo.EffectPointAt(beatmap.Value.Track.CurrentTime) + var effect = beatmap.Value.BeatmapLoaded && musicController.TrackLoaded + ? beatmap.Value.Beatmap?.ControlPointInfo.EffectPointAt(musicController.CurrentTrackTime) : null; for (int i = 0; i < temporalAmplitudes.Length; i++) temporalAmplitudes[i] = 0; - if (beatmap.Value.TrackLoaded) - addAmplitudesFromSource(beatmap.Value.Track); + if (musicController.TrackLoaded) + addAmplitudesFromSource(musicController); foreach (var source in amplitudeSources) addAmplitudesFromSource(source); diff --git a/osu.Game/Screens/Menu/MainMenu.cs b/osu.Game/Screens/Menu/MainMenu.cs index 57252d557e..c422f57332 100644 --- a/osu.Game/Screens/Menu/MainMenu.cs +++ b/osu.Game/Screens/Menu/MainMenu.cs @@ -5,7 +5,6 @@ using System.Linq; using osuTK; using osuTK.Graphics; using osu.Framework.Allocation; -using osu.Framework.Audio.Track; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Platform; @@ -62,8 +61,6 @@ namespace osu.Game.Screens.Menu protected override BackgroundScreen CreateBackground() => background; - internal Track Track { get; private set; } - private Bindable holdDelay; private Bindable loginDisplayed; @@ -172,20 +169,23 @@ namespace osu.Game.Screens.Menu [Resolved] private Storage storage { get; set; } + [Resolved] + private MusicController musicController { get; set; } + public override void OnEntering(IScreen last) { base.OnEntering(last); buttons.FadeInFromZero(500); - Track = Beatmap.Value.Track; var metadata = Beatmap.Value.Metadata; - if (last is IntroScreen && Track != null) + if (last is IntroScreen && musicController.TrackLoaded) { - if (!Track.IsRunning) + // Todo: Wrong. + if (!musicController.IsPlaying) { - Track.Seek(metadata.PreviewTime != -1 ? metadata.PreviewTime : 0.4f * Track.Length); - Track.Start(); + musicController.SeekTo(metadata.PreviewTime != -1 ? metadata.PreviewTime : 0.4f * musicController.TrackLength); + musicController.Play(); } } diff --git a/osu.Game/Screens/Menu/OsuLogo.cs b/osu.Game/Screens/Menu/OsuLogo.cs index f5e4b078da..1feb2481c3 100644 --- a/osu.Game/Screens/Menu/OsuLogo.cs +++ b/osu.Game/Screens/Menu/OsuLogo.cs @@ -17,6 +17,7 @@ using osu.Framework.Utils; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Graphics.Backgrounds; using osu.Game.Graphics.Containers; +using osu.Game.Overlays; using osuTK; using osuTK.Graphics; using osuTK.Input; @@ -46,7 +47,6 @@ namespace osu.Game.Screens.Menu private SampleChannel sampleBeat; private readonly Container colourAndTriangles; - private readonly Triangles triangles; /// @@ -319,6 +319,9 @@ namespace osu.Game.Screens.Menu intro.Delay(length + fade).FadeOut(); } + [Resolved] + private MusicController musicController { get; set; } + protected override void Update() { base.Update(); @@ -327,9 +330,9 @@ namespace osu.Game.Screens.Menu const float velocity_adjust_cutoff = 0.98f; const float paused_velocity = 0.5f; - if (Beatmap.Value.Track.IsRunning) + if (musicController.IsPlaying) { - var maxAmplitude = lastBeatIndex >= 0 ? Beatmap.Value.Track.CurrentAmplitudes.Maximum : 0; + var maxAmplitude = lastBeatIndex >= 0 ? musicController.CurrentAmplitudes.Maximum : 0; logoAmplitudeContainer.Scale = new Vector2((float)Interpolation.Damp(logoAmplitudeContainer.Scale.X, 1 - Math.Max(0, maxAmplitude - scale_adjust_cutoff) * 0.04f, 0.9f, Time.Elapsed)); if (maxAmplitude > velocity_adjust_cutoff) diff --git a/osu.Game/Screens/Multi/Match/Components/ReadyButton.cs b/osu.Game/Screens/Multi/Match/Components/ReadyButton.cs index a64f24dd7e..032c8d5ca9 100644 --- a/osu.Game/Screens/Multi/Match/Components/ReadyButton.cs +++ b/osu.Game/Screens/Multi/Match/Components/ReadyButton.cs @@ -10,6 +10,7 @@ using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Graphics.UserInterface; using osu.Game.Online.Multiplayer; +using osu.Game.Overlays; namespace osu.Game.Screens.Multi.Match.Components { @@ -26,6 +27,9 @@ namespace osu.Game.Screens.Multi.Match.Components [Resolved] private BeatmapManager beatmaps { get; set; } + [Resolved] + private MusicController musicController { get; set; } + private bool hasBeatmap; public ReadyButton() @@ -100,7 +104,7 @@ namespace osu.Game.Screens.Multi.Match.Components return; } - bool hasEnoughTime = DateTimeOffset.UtcNow.AddSeconds(30).AddMilliseconds(gameBeatmap.Value.Track.Length) < endDate.Value; + bool hasEnoughTime = DateTimeOffset.UtcNow.AddSeconds(30).AddMilliseconds(musicController.TrackLength) < endDate.Value; Enabled.Value = hasBeatmap && hasEnoughTime; } diff --git a/osu.Game/Screens/Multi/Multiplayer.cs b/osu.Game/Screens/Multi/Multiplayer.cs index 4912df17b1..2d74434c76 100644 --- a/osu.Game/Screens/Multi/Multiplayer.cs +++ b/osu.Game/Screens/Multi/Multiplayer.cs @@ -52,7 +52,7 @@ namespace osu.Game.Screens.Multi private readonly Bindable currentFilter = new Bindable(new FilterCriteria()); [Resolved] - private MusicController music { get; set; } + private MusicController musicController { get; set; } [Cached(Type = typeof(IRoomManager))] private RoomManager roomManager; @@ -343,15 +343,9 @@ namespace osu.Game.Screens.Multi { if (screenStack.CurrentScreen is MatchSubScreen) { - var track = Beatmap.Value?.Track; - - if (track != null) - { - track.RestartPoint = Beatmap.Value.Metadata.PreviewTime; - track.Looping = true; - - music.EnsurePlayingSomething(); - } + musicController.RestartPoint = Beatmap.Value.Metadata.PreviewTime; + musicController.Looping = true; + musicController.EnsurePlayingSomething(); } else { @@ -361,13 +355,8 @@ namespace osu.Game.Screens.Multi private void cancelLooping() { - var track = Beatmap?.Value?.Track; - - if (track != null) - { - track.Looping = false; - track.RestartPoint = 0; - } + musicController.Looping = false; + musicController.RestartPoint = 0; } protected override void Dispose(bool isDisposing) diff --git a/osu.Game/Screens/Play/FailAnimation.cs b/osu.Game/Screens/Play/FailAnimation.cs index 54c644c999..0e0ef8c675 100644 --- a/osu.Game/Screens/Play/FailAnimation.cs +++ b/osu.Game/Screens/Play/FailAnimation.cs @@ -8,10 +8,10 @@ using System; using System.Collections.Generic; using osu.Framework.Allocation; using osu.Framework.Audio.Sample; -using osu.Framework.Audio.Track; using osu.Framework.Graphics; using osu.Framework.Utils; using osu.Game.Beatmaps; +using osu.Game.Overlays; using osu.Game.Rulesets.Objects.Drawables; using osuTK; using osuTK.Graphics; @@ -30,12 +30,13 @@ namespace osu.Game.Screens.Play private readonly BindableDouble trackFreq = new BindableDouble(1); - private Track track; - private const float duration = 2500; private SampleChannel failSample; + [Resolved] + private MusicController musicController { get; set; } + public FailAnimation(DrawableRuleset drawableRuleset) { this.drawableRuleset = drawableRuleset; @@ -44,7 +45,6 @@ namespace osu.Game.Screens.Play [BackgroundDependencyLoader] private void load(AudioManager audio, IBindable beatmap) { - track = beatmap.Value.Track; failSample = audio.Samples.Get(@"Gameplay/failsound"); } @@ -68,7 +68,7 @@ namespace osu.Game.Screens.Play Expire(); }); - track.AddAdjustment(AdjustableProperty.Frequency, trackFreq); + musicController.AddAdjustment(AdjustableProperty.Frequency, trackFreq); applyToPlayfield(drawableRuleset.Playfield); drawableRuleset.Playfield.HitObjectContainer.FlashColour(Color4.Red, 500); @@ -107,7 +107,7 @@ namespace osu.Game.Screens.Play protected override void Dispose(bool isDisposing) { base.Dispose(isDisposing); - track?.RemoveAdjustment(AdjustableProperty.Frequency, trackFreq); + musicController?.RemoveAdjustment(AdjustableProperty.Frequency, trackFreq); } } } diff --git a/osu.Game/Screens/Play/GameplayClockContainer.cs b/osu.Game/Screens/Play/GameplayClockContainer.cs index 0653373c91..cf4678ab29 100644 --- a/osu.Game/Screens/Play/GameplayClockContainer.cs +++ b/osu.Game/Screens/Play/GameplayClockContainer.cs @@ -8,13 +8,13 @@ using System.Threading.Tasks; using osu.Framework; using osu.Framework.Allocation; using osu.Framework.Audio; -using osu.Framework.Audio.Track; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Timing; using osu.Game.Beatmaps; using osu.Game.Configuration; +using osu.Game.Overlays; using osu.Game.Rulesets.Mods; namespace osu.Game.Screens.Play @@ -27,10 +27,8 @@ namespace osu.Game.Screens.Play private readonly WorkingBeatmap beatmap; private readonly IReadOnlyList mods; - /// - /// The 's track. - /// - private Track track; + [Resolved] + private MusicController musicController { get; set; } public readonly BindableBool IsPaused = new BindableBool(); @@ -72,8 +70,6 @@ namespace osu.Game.Screens.Play RelativeSizeAxes = Axes.Both; - track = beatmap.Track; - adjustableClock = new DecoupleableInterpolatingFramedClock { IsCoupled = false }; // Lazer's audio timings in general doesn't match stable. This is the result of user testing, albeit limited. @@ -125,15 +121,15 @@ namespace osu.Game.Screens.Play { // The Reset() call below causes speed adjustments to be reset in an async context, leading to deadlocks. // The deadlock can be prevented by resetting the track synchronously before entering the async context. - track.ResetSpeedAdjustments(); + musicController.Reset(); Task.Run(() => { - track.Reset(); + musicController.Reset(); Schedule(() => { - adjustableClock.ChangeSource(track); + adjustableClock.ChangeSource(musicController.GetTrackClock()); updateRate(); if (!IsPaused.Value) @@ -194,20 +190,6 @@ namespace osu.Game.Screens.Play IsPaused.Value = true; } - /// - /// Changes the backing clock to avoid using the originally provided beatmap's track. - /// - public void StopUsingBeatmapClock() - { - if (track != beatmap.Track) - return; - - removeSourceClockAdjustments(); - - track = new TrackVirtual(beatmap.Track.Length); - adjustableClock.ChangeSource(track); - } - protected override void Update() { if (!IsPaused.Value) @@ -220,31 +202,23 @@ namespace osu.Game.Screens.Play private void updateRate() { - if (track == null) return; - speedAdjustmentsApplied = true; - track.ResetSpeedAdjustments(); - - track.AddAdjustment(AdjustableProperty.Frequency, pauseFreqAdjust); - track.AddAdjustment(AdjustableProperty.Tempo, UserPlaybackRate); - - foreach (var mod in mods.OfType()) - mod.ApplyToTrack(track); + musicController.ResetTrackAdjustments(); + musicController.AddAdjustment(AdjustableProperty.Frequency, pauseFreqAdjust); + musicController.AddAdjustment(AdjustableProperty.Tempo, UserPlaybackRate); } protected override void Dispose(bool isDisposing) { base.Dispose(isDisposing); - removeSourceClockAdjustments(); - track = null; } private void removeSourceClockAdjustments() { if (speedAdjustmentsApplied) { - track.ResetSpeedAdjustments(); + musicController.ResetTrackAdjustments(); speedAdjustmentsApplied = false; } } diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 74a5ee8309..9ba2732920 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -4,7 +4,6 @@ using osu.Framework.Allocation; using osu.Framework.Audio; using osu.Framework.Audio.Sample; -using osu.Framework.Audio.Track; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -561,8 +560,11 @@ namespace osu.Game.Screens.Select BeatmapDetails.Refresh(); - Beatmap.Value.Track.Looping = true; - music?.ResetTrackAdjustments(); + if (music != null) + { + music.Looping = true; + music.ResetTrackAdjustments(); + } if (Beatmap != null && !Beatmap.Value.BeatmapSetInfo.DeletePending) { @@ -586,8 +588,8 @@ namespace osu.Game.Screens.Select BeatmapOptions.Hide(); - if (Beatmap.Value.Track != null) - Beatmap.Value.Track.Looping = false; + if (music != null) + music.Looping = false; this.ScaleTo(1.1f, 250, Easing.InSine); @@ -608,8 +610,8 @@ namespace osu.Game.Screens.Select FilterControl.Deactivate(); - if (Beatmap.Value.Track != null) - Beatmap.Value.Track.Looping = false; + if (music != null) + music.Looping = false; return false; } @@ -650,28 +652,18 @@ namespace osu.Game.Screens.Select BeatmapDetails.Beatmap = beatmap; - if (beatmap.Track != null) - beatmap.Track.Looping = true; + if (music != null) + music.Looping = false; } - private readonly WeakReference lastTrack = new WeakReference(null); - /// /// Ensures some music is playing for the current track. /// Will resume playback from a manual user pause if the track has changed. /// private void ensurePlayingSelected() { - Track track = Beatmap.Value.Track; - - bool isNewTrack = !lastTrack.TryGetTarget(out var last) || last != track; - - track.RestartPoint = Beatmap.Value.Metadata.PreviewTime; - - if (!track.IsRunning && (music?.IsUserPaused != true || isNewTrack)) - music?.Play(true); - - lastTrack.SetTarget(track); + music.RestartPoint = Beatmap.Value.Metadata.PreviewTime; + music.EnsurePlayingSomething(); } private void carouselBeatmapsLoaded() diff --git a/osu.Game/Tests/Beatmaps/TestWorkingBeatmap.cs b/osu.Game/Tests/Beatmaps/TestWorkingBeatmap.cs index cdf9170701..ee04142035 100644 --- a/osu.Game/Tests/Beatmaps/TestWorkingBeatmap.cs +++ b/osu.Game/Tests/Beatmaps/TestWorkingBeatmap.cs @@ -27,8 +27,6 @@ namespace osu.Game.Tests.Beatmaps this.storyboard = storyboard; } - public override bool TrackLoaded => true; - public override bool BeatmapLoaded => true; protected override IBeatmap GetBeatmap() => beatmap; diff --git a/osu.Game/Tests/Visual/EditorClockTestScene.cs b/osu.Game/Tests/Visual/EditorClockTestScene.cs index f0ec638fc9..5226a49def 100644 --- a/osu.Game/Tests/Visual/EditorClockTestScene.cs +++ b/osu.Game/Tests/Visual/EditorClockTestScene.cs @@ -44,7 +44,7 @@ namespace osu.Game.Tests.Visual private void beatmapChanged(ValueChangedEvent e) { Clock.ControlPointInfo = e.NewValue.Beatmap.ControlPointInfo; - Clock.ChangeSource((IAdjustableClock)e.NewValue.Track ?? new StopwatchClock()); + Clock.ChangeSource(MusicController.GetTrackClock() ?? new StopwatchClock()); Clock.ProcessFrame(); } diff --git a/osu.Game/Tests/Visual/OsuTestScene.cs b/osu.Game/Tests/Visual/OsuTestScene.cs index 866fc215d6..e968f7e675 100644 --- a/osu.Game/Tests/Visual/OsuTestScene.cs +++ b/osu.Game/Tests/Visual/OsuTestScene.cs @@ -20,6 +20,7 @@ using osu.Framework.Timing; using osu.Game.Beatmaps; using osu.Game.Database; using osu.Game.Online.API; +using osu.Game.Overlays; using osu.Game.Rulesets; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.UI; @@ -135,6 +136,9 @@ namespace osu.Game.Tests.Visual [Resolved] protected AudioManager Audio { get; private set; } + [Resolved] + protected MusicController MusicController { get; private set; } + /// /// Creates the ruleset to be used for this test scene. /// @@ -164,8 +168,8 @@ namespace osu.Game.Tests.Visual rulesetDependencies?.Dispose(); - if (Beatmap?.Value.TrackLoaded == true) - Beatmap.Value.Track.Stop(); + if (MusicController?.TrackLoaded == true) + MusicController.Stop(); if (contextFactory.IsValueCreated) contextFactory.Value.ResetDatabase(); diff --git a/osu.Game/Tests/Visual/RateAdjustedBeatmapTestScene.cs b/osu.Game/Tests/Visual/RateAdjustedBeatmapTestScene.cs index ad24ffc7b8..e7cb461d7b 100644 --- a/osu.Game/Tests/Visual/RateAdjustedBeatmapTestScene.cs +++ b/osu.Game/Tests/Visual/RateAdjustedBeatmapTestScene.cs @@ -13,7 +13,7 @@ namespace osu.Game.Tests.Visual base.Update(); // note that this will override any mod rate application - Beatmap.Value.Track.Tempo.Value = Clock.Rate; + MusicController.Tempo.Value = Clock.Rate; } } } From 5c05fe3988ad5ba9c92e908628f2d11def1c9376 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 5 Aug 2020 21:10:38 +0900 Subject: [PATCH 086/434] Expose track from MusicController --- .../TestSceneHoldNoteInput.cs | 2 +- .../TestSceneOutOfOrderHits.cs | 2 +- .../TestSceneSliderInput.cs | 2 +- .../Skins/TestSceneBeatmapSkinResources.cs | 2 +- .../Visual/Editing/TimelineTestScene.cs | 6 +- .../Visual/Gameplay/TestScenePause.cs | 2 +- .../Visual/Gameplay/TestScenePlayerLoader.cs | 6 +- .../Visual/Gameplay/TestSceneStoryboard.cs | 8 +- .../Visual/Menus/TestSceneIntroWelcome.cs | 2 +- .../Navigation/TestSceneScreenNavigation.cs | 13 +- .../TestSceneBeatSyncedContainer.cs | 3 +- .../TestSceneNowPlayingOverlay.cs | 4 +- .../Containers/BeatSyncedContainer.cs | 14 +- osu.Game/Overlays/MusicController.cs | 190 ++---------------- osu.Game/Overlays/NowPlayingOverlay.cs | 12 +- osu.Game/Rulesets/Mods/IApplicableToTrack.cs | 3 +- osu.Game/Rulesets/Mods/ModDaycore.cs | 7 +- osu.Game/Rulesets/Mods/ModNightcore.cs | 6 +- osu.Game/Rulesets/Mods/ModRateAdjust.cs | 4 +- osu.Game/Rulesets/Mods/ModTimeRamp.cs | 10 +- .../Edit/Components/PlaybackControl.cs | 4 +- .../Timelines/Summary/Parts/TimelinePart.cs | 4 +- .../Compose/Components/Timeline/Timeline.cs | 31 +-- .../Timeline/TimelineTickDisplay.cs | 3 +- osu.Game/Screens/Edit/Editor.cs | 2 +- osu.Game/Screens/Edit/EditorClock.cs | 2 +- osu.Game/Screens/Menu/IntroScreen.cs | 4 +- osu.Game/Screens/Menu/IntroTriangles.cs | 2 +- osu.Game/Screens/Menu/IntroWelcome.cs | 3 +- osu.Game/Screens/Menu/LogoVisualisation.cs | 5 +- osu.Game/Screens/Menu/MainMenu.cs | 10 +- osu.Game/Screens/Menu/OsuLogo.cs | 4 +- .../Multi/Match/Components/ReadyButton.cs | 2 +- osu.Game/Screens/Multi/Multiplayer.cs | 17 +- osu.Game/Screens/Play/FailAnimation.cs | 13 +- .../Screens/Play/GameplayClockContainer.cs | 44 +++- osu.Game/Screens/Select/SongSelect.cs | 33 ++- osu.Game/Tests/Visual/EditorClockTestScene.cs | 2 +- .../Visual/RateAdjustedBeatmapTestScene.cs | 4 +- 39 files changed, 204 insertions(+), 283 deletions(-) diff --git a/osu.Game.Rulesets.Mania.Tests/TestSceneHoldNoteInput.cs b/osu.Game.Rulesets.Mania.Tests/TestSceneHoldNoteInput.cs index c3e0c277a0..98669efb10 100644 --- a/osu.Game.Rulesets.Mania.Tests/TestSceneHoldNoteInput.cs +++ b/osu.Game.Rulesets.Mania.Tests/TestSceneHoldNoteInput.cs @@ -343,7 +343,7 @@ namespace osu.Game.Rulesets.Mania.Tests judgementResults = new List(); }); - AddUntilStep("Beatmap at 0", () => MusicController.CurrentTrackTime == 0); + AddUntilStep("Beatmap at 0", () => MusicController.CurrentTrack?.CurrentTime == 0); AddUntilStep("Wait until player is loaded", () => currentPlayer.IsCurrentScreen()); AddUntilStep("Wait for completion", () => currentPlayer.ScoreProcessor.HasCompleted.Value); } diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneOutOfOrderHits.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneOutOfOrderHits.cs index dc7e59b40d..e5be778527 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneOutOfOrderHits.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneOutOfOrderHits.cs @@ -385,7 +385,7 @@ namespace osu.Game.Rulesets.Osu.Tests judgementResults = new List(); }); - AddUntilStep("Beatmap at 0", () => MusicController.CurrentTrackTime == 0); + AddUntilStep("Beatmap at 0", () => MusicController.CurrentTrack?.CurrentTime == 0); AddUntilStep("Wait until player is loaded", () => currentPlayer.IsCurrentScreen()); AddUntilStep("Wait for completion", () => currentPlayer.ScoreProcessor.HasCompleted.Value); } diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs index 2dffcfeabb..c9d13d3976 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs @@ -366,7 +366,7 @@ namespace osu.Game.Rulesets.Osu.Tests judgementResults = new List(); }); - AddUntilStep("Beatmap at 0", () => MusicController.CurrentTrackTime == 0); + AddUntilStep("Beatmap at 0", () => MusicController.CurrentTrack?.CurrentTime == 0); AddUntilStep("Wait until player is loaded", () => currentPlayer.IsCurrentScreen()); AddUntilStep("Wait for completion", () => currentPlayer.ScoreProcessor.HasCompleted.Value); } diff --git a/osu.Game.Tests/Skins/TestSceneBeatmapSkinResources.cs b/osu.Game.Tests/Skins/TestSceneBeatmapSkinResources.cs index 1a19326ac4..08a4e27ff7 100644 --- a/osu.Game.Tests/Skins/TestSceneBeatmapSkinResources.cs +++ b/osu.Game.Tests/Skins/TestSceneBeatmapSkinResources.cs @@ -31,6 +31,6 @@ namespace osu.Game.Tests.Skins public void TestRetrieveOggSample() => AddAssert("sample is non-null", () => beatmap.Skin.GetSample(new SampleInfo("sample")) != null); [Test] - public void TestRetrieveOggTrack() => AddAssert("track is non-null", () => !MusicController.IsDummyDevice); + public void TestRetrieveOggTrack() => AddAssert("track is non-null", () => MusicController.CurrentTrack?.IsDummyDevice == false); } } diff --git a/osu.Game.Tests/Visual/Editing/TimelineTestScene.cs b/osu.Game.Tests/Visual/Editing/TimelineTestScene.cs index 5d6136d9fb..4113bdddf8 100644 --- a/osu.Game.Tests/Visual/Editing/TimelineTestScene.cs +++ b/osu.Game.Tests/Visual/Editing/TimelineTestScene.cs @@ -1,6 +1,7 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System.Diagnostics; using osu.Framework.Allocation; using osu.Framework.Audio; using osu.Framework.Graphics; @@ -94,7 +95,10 @@ namespace osu.Game.Tests.Visual.Editing base.Update(); if (musicController.TrackLoaded) - marker.X = (float)(editorClock.CurrentTime / musicController.TrackLength); + { + Debug.Assert(musicController.CurrentTrack != null); + marker.X = (float)(editorClock.CurrentTime / musicController.CurrentTrack.Length); + } } } diff --git a/osu.Game.Tests/Visual/Gameplay/TestScenePause.cs b/osu.Game.Tests/Visual/Gameplay/TestScenePause.cs index 8f14de1578..e500b451f0 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestScenePause.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestScenePause.cs @@ -288,7 +288,7 @@ namespace osu.Game.Tests.Visual.Gameplay private void confirmNoTrackAdjustments() { - AddAssert("track has no adjustments", () => MusicController.AggregateFrequency.Value == 1); + AddAssert("track has no adjustments", () => MusicController.CurrentTrack?.AggregateFrequency.Value == 1); } private void restart() => AddStep("restart", () => Player.Restart()); diff --git a/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs b/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs index 2f86db1b25..c72ab7d3d1 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs @@ -57,7 +57,7 @@ namespace osu.Game.Tests.Visual.Gameplay Beatmap.Value = CreateWorkingBeatmap(new OsuRuleset().RulesetInfo); foreach (var mod in SelectedMods.Value.OfType()) - mod.ApplyToTrack(MusicController); + mod.ApplyToTrack(MusicController.CurrentTrack); InputManager.Child = container = new TestPlayerLoaderContainer( loader = new TestPlayerLoader(() => @@ -77,12 +77,12 @@ namespace osu.Game.Tests.Visual.Gameplay { AddStep("load dummy beatmap", () => ResetPlayer(false, () => SelectedMods.Value = new[] { new OsuModNightcore() })); AddUntilStep("wait for current", () => loader.IsCurrentScreen()); - AddAssert("mod rate applied", () => MusicController.Rate != 1); + AddAssert("mod rate applied", () => MusicController.CurrentTrack?.Rate != 1); AddStep("exit loader", () => loader.Exit()); AddUntilStep("wait for not current", () => !loader.IsCurrentScreen()); AddAssert("player did not load", () => !player.IsLoaded); AddUntilStep("player disposed", () => loader.DisposalTask?.IsCompleted == true); - AddAssert("mod rate still applied", () => MusicController.Rate != 1); + AddAssert("mod rate still applied", () => MusicController.CurrentTrack?.Rate != 1); } [Test] diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboard.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboard.cs index a4b558fce2..c7a012a03f 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboard.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboard.cs @@ -87,9 +87,9 @@ namespace osu.Game.Tests.Visual.Gameplay private void restart() { - MusicController.Reset(); + MusicController.CurrentTrack?.Reset(); loadStoryboard(Beatmap.Value); - MusicController.Play(true); + MusicController.CurrentTrack?.Start(); } private void loadStoryboard(WorkingBeatmap working) @@ -104,7 +104,7 @@ namespace osu.Game.Tests.Visual.Gameplay storyboard.Passing = false; storyboardContainer.Add(storyboard); - decoupledClock.ChangeSource(musicController.GetTrackClock()); + decoupledClock.ChangeSource(musicController.CurrentTrack); } private void loadStoryboardNoVideo() @@ -127,7 +127,7 @@ namespace osu.Game.Tests.Visual.Gameplay storyboard = sb.CreateDrawable(Beatmap.Value); storyboardContainer.Add(storyboard); - decoupledClock.ChangeSource(musicController.GetTrackClock()); + decoupledClock.ChangeSource(musicController.CurrentTrack); } } } diff --git a/osu.Game.Tests/Visual/Menus/TestSceneIntroWelcome.cs b/osu.Game.Tests/Visual/Menus/TestSceneIntroWelcome.cs index 36f98b7a0c..a88704c831 100644 --- a/osu.Game.Tests/Visual/Menus/TestSceneIntroWelcome.cs +++ b/osu.Game.Tests/Visual/Menus/TestSceneIntroWelcome.cs @@ -16,7 +16,7 @@ namespace osu.Game.Tests.Visual.Menus { AddUntilStep("wait for load", () => MusicController.TrackLoaded); - AddAssert("check if menu music loops", () => MusicController.Looping); + AddAssert("check if menu music loops", () => MusicController.CurrentTrack?.Looping == true); } } } diff --git a/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs b/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs index 455b7e56e6..946bc2a175 100644 --- a/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs +++ b/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs @@ -4,6 +4,7 @@ using System.Linq; using NUnit.Framework; using osu.Framework.Allocation; +using osu.Framework.Extensions.ObjectExtensions; using osu.Framework.Graphics.Containers; using osu.Framework.Screens; using osu.Game.Beatmaps; @@ -61,12 +62,12 @@ namespace osu.Game.Tests.Visual.Navigation AddUntilStep("wait for fail", () => player.HasFailed); AddUntilStep("wait for track stop", () => !MusicController.IsPlaying); - AddAssert("Ensure time before preview point", () => MusicController.CurrentTrackTime < beatmap().Metadata.PreviewTime); + AddAssert("Ensure time before preview point", () => MusicController.CurrentTrack?.CurrentTime < beatmap().Metadata.PreviewTime); pushEscape(); AddUntilStep("wait for track playing", () => MusicController.IsPlaying); - AddAssert("Ensure time wasn't reset to preview point", () => MusicController.CurrentTrackTime < beatmap().Metadata.PreviewTime); + AddAssert("Ensure time wasn't reset to preview point", () => MusicController.CurrentTrack?.CurrentTime < beatmap().Metadata.PreviewTime); } [Test] @@ -76,11 +77,11 @@ namespace osu.Game.Tests.Visual.Navigation PushAndConfirm(() => songSelect = new TestSongSelect()); - AddUntilStep("wait for no track", () => MusicController.IsDummyDevice); + AddUntilStep("wait for no track", () => MusicController.CurrentTrack?.IsDummyDevice == true); AddStep("return to menu", () => songSelect.Exit()); - AddUntilStep("wait for track", () => !MusicController.IsDummyDevice && MusicController.IsPlaying); + AddUntilStep("wait for track", () => MusicController.CurrentTrack?.IsDummyDevice == false && MusicController.IsPlaying); } [Test] @@ -135,8 +136,8 @@ namespace osu.Game.Tests.Visual.Navigation AddUntilStep("Wait for music controller", () => Game.MusicController.IsLoaded); AddStep("Seek close to end", () => { - Game.MusicController.SeekTo(MusicController.TrackLength - 1000); - // MusicController.Completed += () => trackCompleted = true; + Game.MusicController.SeekTo(MusicController.CurrentTrack.AsNonNull().Length - 1000); + MusicController.CurrentTrack.AsNonNull().Completed += () => trackCompleted = true; }); AddUntilStep("Track was completed", () => trackCompleted); diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneBeatSyncedContainer.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneBeatSyncedContainer.cs index f3fef8c355..ac743d76df 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneBeatSyncedContainer.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneBeatSyncedContainer.cs @@ -8,6 +8,7 @@ using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Audio.Track; using osu.Framework.Extensions.Color4Extensions; +using osu.Framework.Extensions.ObjectExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; @@ -168,7 +169,7 @@ namespace osu.Game.Tests.Visual.UserInterface if (timingPoints.Count == 0) return 0; if (timingPoints[^1] == current) - return (int)Math.Ceiling((musicController.TrackLength - current.Time) / current.BeatLength); + return (int)Math.Ceiling((musicController.CurrentTrack.AsNonNull().Length - current.Time) / current.BeatLength); return (int)Math.Ceiling((getNextTimingPoint(current).Time - current.Time) / current.BeatLength); } diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneNowPlayingOverlay.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneNowPlayingOverlay.cs index 3ecd8ab550..0161ec0c56 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneNowPlayingOverlay.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneNowPlayingOverlay.cs @@ -80,12 +80,12 @@ namespace osu.Game.Tests.Visual.UserInterface AddStep("Store track", () => currentBeatmap = Beatmap.Value); AddStep(@"Seek track to 6 second", () => musicController.SeekTo(6000)); - AddUntilStep(@"Wait for current time to update", () => musicController.CurrentTrackTime > 5000); + AddUntilStep(@"Wait for current time to update", () => musicController.CurrentTrack?.CurrentTime > 5000); AddStep(@"Set previous", () => musicController.PreviousTrack()); AddAssert(@"Check beatmap didn't change", () => currentBeatmap == Beatmap.Value); - AddUntilStep("Wait for current time to update", () => musicController.CurrentTrackTime < 5000); + AddUntilStep("Wait for current time to update", () => musicController.CurrentTrack?.CurrentTime < 5000); AddStep(@"Set previous", () => musicController.PreviousTrack()); AddAssert(@"Check beatmap did change", () => currentBeatmap != Beatmap.Value); diff --git a/osu.Game/Graphics/Containers/BeatSyncedContainer.cs b/osu.Game/Graphics/Containers/BeatSyncedContainer.cs index 2dd28a01dc..92a9ed0566 100644 --- a/osu.Game/Graphics/Containers/BeatSyncedContainer.cs +++ b/osu.Game/Graphics/Containers/BeatSyncedContainer.cs @@ -51,6 +51,7 @@ namespace osu.Game.Graphics.Containers protected override void Update() { + ITrack track = null; IBeatmap beatmap = null; double currentTrackTime = 0; @@ -58,11 +59,14 @@ namespace osu.Game.Graphics.Containers EffectControlPoint effectPoint = null; if (musicController.TrackLoaded && Beatmap.Value.BeatmapLoaded) - beatmap = Beatmap.Value.Beatmap; - - if (beatmap != null && musicController.IsPlaying && musicController.TrackLength > 0) { - currentTrackTime = musicController.CurrentTrackTime + EarlyActivationMilliseconds; + track = musicController.CurrentTrack; + beatmap = Beatmap.Value.Beatmap; + } + + if (track != null && beatmap != null && musicController.IsPlaying && track.Length > 0) + { + currentTrackTime = track.CurrentTime + EarlyActivationMilliseconds; timingPoint = beatmap.ControlPointInfo.TimingPointAt(currentTrackTime); effectPoint = beatmap.ControlPointInfo.EffectPointAt(currentTrackTime); @@ -98,7 +102,7 @@ namespace osu.Game.Graphics.Containers return; using (BeginDelayedSequence(-TimeSinceLastBeat, true)) - OnNewBeat(beatIndex, timingPoint, effectPoint, musicController.CurrentAmplitudes); + OnNewBeat(beatIndex, timingPoint, effectPoint, track?.CurrentAmplitudes ?? ChannelAmplitudes.Empty); lastBeat = beatIndex; lastTimingPoint = timingPoint; diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index f5ca5a3a49..c22849b7d6 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -6,7 +6,6 @@ using System.Collections.Generic; using System.Linq; using JetBrains.Annotations; using osu.Framework.Allocation; -using osu.Framework.Audio; using osu.Framework.Audio.Track; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -15,7 +14,6 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Input.Bindings; using osu.Framework.Utils; using osu.Framework.Threading; -using osu.Framework.Timing; using osu.Game.Beatmaps; using osu.Game.Input.Bindings; using osu.Game.Overlays.OSD; @@ -26,7 +24,7 @@ namespace osu.Game.Overlays /// /// Handles playback of the global music track. /// - public class MusicController : CompositeDrawable, IKeyBindingHandler, ITrack + public class MusicController : CompositeDrawable, IKeyBindingHandler { [Resolved] private BeatmapManager beatmaps { get; set; } @@ -70,10 +68,7 @@ namespace osu.Game.Overlays private readonly TrackContainer trackContainer; [CanBeNull] - private DrawableTrack drawableTrack; - - [CanBeNull] - private Track track; + public DrawableTrack CurrentTrack { get; private set; } private IBindable> managerUpdated; private IBindable> managerRemoved; @@ -116,33 +111,12 @@ namespace osu.Game.Overlays /// /// Returns whether the beatmap track is playing. /// - public bool IsPlaying => drawableTrack?.IsRunning ?? false; + public bool IsPlaying => CurrentTrack?.IsRunning ?? false; /// /// Returns whether the beatmap track is loaded. /// - public bool TrackLoaded => drawableTrack?.IsLoaded == true; - - /// - /// Returns the current time of the beatmap track. - /// - public double CurrentTrackTime => drawableTrack?.CurrentTime ?? 0; - - /// - /// Returns the length of the beatmap track. - /// - public double TrackLength => drawableTrack?.Length ?? 0; - - public void AddAdjustment(AdjustableProperty type, BindableNumber adjustBindable) - => trackContainer.AddAdjustment(type, adjustBindable); - - public void RemoveAdjustment(AdjustableProperty type, BindableNumber adjustBindable) - => trackContainer.RemoveAdjustment(type, adjustBindable); - - public void Reset() => drawableTrack?.Reset(); - - [CanBeNull] - public IAdjustableClock GetTrackClock() => track; + public bool TrackLoaded => CurrentTrack?.IsLoaded == true; private void beatmapUpdated(ValueChangedEvent> weakSet) { @@ -175,7 +149,7 @@ namespace osu.Game.Overlays seekDelegate = Schedule(() => { if (!beatmap.Disabled) - drawableTrack?.Seek(position); + CurrentTrack?.Seek(position); }); } @@ -187,7 +161,7 @@ namespace osu.Game.Overlays { if (IsUserPaused) return; - if (drawableTrack == null || drawableTrack.IsDummyDevice) + if (CurrentTrack == null || CurrentTrack.IsDummyDevice) { if (beatmap.Disabled) return; @@ -208,13 +182,13 @@ namespace osu.Game.Overlays { IsUserPaused = false; - if (drawableTrack == null) + if (CurrentTrack == null) return false; if (restart) - drawableTrack.Restart(); + CurrentTrack.Restart(); else if (!IsPlaying) - drawableTrack.Start(); + CurrentTrack.Start(); return true; } @@ -225,8 +199,8 @@ namespace osu.Game.Overlays public void Stop() { IsUserPaused = true; - if (drawableTrack?.IsRunning == true) - drawableTrack.Stop(); + if (CurrentTrack?.IsRunning == true) + CurrentTrack.Stop(); } /// @@ -235,7 +209,7 @@ namespace osu.Game.Overlays /// Whether the operation was successful. public bool TogglePause() { - if (drawableTrack?.IsRunning == true) + if (CurrentTrack?.IsRunning == true) Stop(); else Play(); @@ -257,7 +231,7 @@ namespace osu.Game.Overlays if (beatmap.Disabled) return PreviousTrackResult.None; - var currentTrackPosition = drawableTrack?.CurrentTime; + var currentTrackPosition = CurrentTrack?.CurrentTime; if (currentTrackPosition >= restart_cutoff_point) { @@ -311,7 +285,7 @@ namespace osu.Game.Overlays { // if not scheduled, the previously track will be stopped one frame later (see ScheduleAfterChildren logic in GameBase). // we probably want to move this to a central method for switching to a new working beatmap in the future. - Schedule(() => drawableTrack?.Restart()); + Schedule(() => CurrentTrack?.Restart()); } private WorkingBeatmap current; @@ -345,12 +319,11 @@ namespace osu.Game.Overlays current = beatmap.NewValue; - drawableTrack?.Expire(); - drawableTrack = null; - track = null; + CurrentTrack?.Expire(); + CurrentTrack = null; if (current != null) - trackContainer.Add(drawableTrack = new DrawableTrack(track = current.GetRealTrack())); + trackContainer.Add(CurrentTrack = new DrawableTrack(current.GetRealTrack())); TrackChanged?.Invoke(current, direction); @@ -379,15 +352,15 @@ namespace osu.Game.Overlays public void ResetTrackAdjustments() { - if (drawableTrack == null) + if (CurrentTrack == null) return; - drawableTrack.ResetSpeedAdjustments(); + CurrentTrack.ResetSpeedAdjustments(); if (allowRateAdjustments) { foreach (var mod in mods.Value.OfType()) - mod.ApplyToTrack(drawableTrack); + mod.ApplyToTrack(CurrentTrack); } } @@ -442,129 +415,6 @@ namespace osu.Game.Overlays private class TrackContainer : AudioContainer { } - - #region ITrack - - /// - /// The volume of this component. - /// - public BindableNumber Volume => drawableTrack?.Volume; // Todo: Bad - - /// - /// The playback balance of this sample (-1 .. 1 where 0 is centered) - /// - public BindableNumber Balance => drawableTrack?.Balance; // Todo: Bad - - /// - /// Rate at which the component is played back (affects pitch). 1 is 100% playback speed, or default frequency. - /// - public BindableNumber Frequency => drawableTrack?.Frequency; // Todo: Bad - - /// - /// Rate at which the component is played back (does not affect pitch). 1 is 100% playback speed. - /// - public BindableNumber Tempo => drawableTrack?.Tempo; // Todo: Bad - - public IBindable AggregateVolume => drawableTrack?.AggregateVolume; // Todo: Bad - - public IBindable AggregateBalance => drawableTrack?.AggregateBalance; // Todo: Bad - - public IBindable AggregateFrequency => drawableTrack?.AggregateFrequency; // Todo: Bad - - public IBindable AggregateTempo => drawableTrack?.AggregateTempo; // Todo: Bad - - /// - /// Overall playback rate (1 is 100%, -1 is reversed at 100%). - /// - public double Rate => AggregateFrequency.Value * AggregateTempo.Value; - - event Action ITrack.Completed - { - add - { - if (drawableTrack != null) - drawableTrack.Completed += value; - } - remove - { - if (drawableTrack != null) - drawableTrack.Completed -= value; - } - } - - event Action ITrack.Failed - { - add - { - if (drawableTrack != null) - drawableTrack.Failed += value; - } - remove - { - if (drawableTrack != null) - drawableTrack.Failed -= value; - } - } - - public bool Looping - { - get => drawableTrack?.Looping ?? false; - set - { - if (drawableTrack != null) - drawableTrack.Looping = value; - } - } - - public bool IsDummyDevice => drawableTrack?.IsDummyDevice ?? true; - - public double RestartPoint - { - get => drawableTrack?.RestartPoint ?? 0; - set - { - if (drawableTrack != null) - drawableTrack.RestartPoint = value; - } - } - - double ITrack.CurrentTime => CurrentTrackTime; - - double ITrack.Length - { - get => TrackLength; - set - { - if (drawableTrack != null) - drawableTrack.Length = value; - } - } - - public int? Bitrate => drawableTrack?.Bitrate; - - bool ITrack.IsRunning => IsPlaying; - - public bool IsReversed => drawableTrack?.IsReversed ?? false; - - public bool HasCompleted => drawableTrack?.HasCompleted ?? false; - - void ITrack.Reset() => drawableTrack?.Reset(); - - void ITrack.Restart() => Play(true); - - void ITrack.ResetSpeedAdjustments() => ResetTrackAdjustments(); - - bool ITrack.Seek(double seek) - { - SeekTo(seek); - return true; - } - - void ITrack.Start() => Play(); - - public ChannelAmplitudes CurrentAmplitudes => drawableTrack?.CurrentAmplitudes ?? ChannelAmplitudes.Empty; - - #endregion } public enum TrackChangeDirection diff --git a/osu.Game/Overlays/NowPlayingOverlay.cs b/osu.Game/Overlays/NowPlayingOverlay.cs index fde6a52fee..15b189ead6 100644 --- a/osu.Game/Overlays/NowPlayingOverlay.cs +++ b/osu.Game/Overlays/NowPlayingOverlay.cs @@ -234,12 +234,14 @@ namespace osu.Game.Overlays pendingBeatmapSwitch = null; } - if (musicController.IsDummyDevice == false) - { - progressBar.EndTime = musicController.TrackLength; - progressBar.CurrentTime = musicController.CurrentTrackTime; + var track = musicController.TrackLoaded ? musicController.CurrentTrack : null; - playButton.Icon = musicController.IsPlaying ? FontAwesome.Regular.PauseCircle : FontAwesome.Regular.PlayCircle; + if (track?.IsDummyDevice == false) + { + progressBar.EndTime = track.Length; + progressBar.CurrentTime = track.CurrentTime; + + playButton.Icon = track.IsRunning ? FontAwesome.Regular.PauseCircle : FontAwesome.Regular.PlayCircle; } else { diff --git a/osu.Game/Rulesets/Mods/IApplicableToTrack.cs b/osu.Game/Rulesets/Mods/IApplicableToTrack.cs index 9b840cea08..5ae41fe09c 100644 --- a/osu.Game/Rulesets/Mods/IApplicableToTrack.cs +++ b/osu.Game/Rulesets/Mods/IApplicableToTrack.cs @@ -1,6 +1,7 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using osu.Framework.Audio; using osu.Framework.Audio.Track; namespace osu.Game.Rulesets.Mods @@ -10,6 +11,6 @@ namespace osu.Game.Rulesets.Mods /// public interface IApplicableToTrack : IApplicableMod { - void ApplyToTrack(ITrack track); + void ApplyToTrack(T track) where T : ITrack, IAdjustableAudioComponent; } } diff --git a/osu.Game/Rulesets/Mods/ModDaycore.cs b/osu.Game/Rulesets/Mods/ModDaycore.cs index 9cefeb3340..989978eb35 100644 --- a/osu.Game/Rulesets/Mods/ModDaycore.cs +++ b/osu.Game/Rulesets/Mods/ModDaycore.cs @@ -2,7 +2,6 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Audio; -using osu.Framework.Audio.Track; using osu.Framework.Bindables; using osu.Framework.Graphics.Sprites; @@ -27,11 +26,11 @@ namespace osu.Game.Rulesets.Mods }, true); } - public override void ApplyToTrack(ITrack track) + public override void ApplyToTrack(T track) { // base.ApplyToTrack() intentionally not called (different tempo adjustment is applied) - (track as Track)?.AddAdjustment(AdjustableProperty.Frequency, freqAdjust); - (track as Track)?.AddAdjustment(AdjustableProperty.Tempo, tempoAdjust); + track.AddAdjustment(AdjustableProperty.Frequency, freqAdjust); + track.AddAdjustment(AdjustableProperty.Tempo, tempoAdjust); } } } diff --git a/osu.Game/Rulesets/Mods/ModNightcore.cs b/osu.Game/Rulesets/Mods/ModNightcore.cs index b34affa77f..70cdaa6345 100644 --- a/osu.Game/Rulesets/Mods/ModNightcore.cs +++ b/osu.Game/Rulesets/Mods/ModNightcore.cs @@ -38,11 +38,11 @@ namespace osu.Game.Rulesets.Mods }, true); } - public override void ApplyToTrack(ITrack track) + public override void ApplyToTrack(T track) { // base.ApplyToTrack() intentionally not called (different tempo adjustment is applied) - (track as Track)?.AddAdjustment(AdjustableProperty.Frequency, freqAdjust); - (track as Track)?.AddAdjustment(AdjustableProperty.Tempo, tempoAdjust); + track.AddAdjustment(AdjustableProperty.Frequency, freqAdjust); + track.AddAdjustment(AdjustableProperty.Tempo, tempoAdjust); } public void ApplyToDrawableRuleset(DrawableRuleset drawableRuleset) diff --git a/osu.Game/Rulesets/Mods/ModRateAdjust.cs b/osu.Game/Rulesets/Mods/ModRateAdjust.cs index ee1280da39..e2c8ac64d9 100644 --- a/osu.Game/Rulesets/Mods/ModRateAdjust.cs +++ b/osu.Game/Rulesets/Mods/ModRateAdjust.cs @@ -12,9 +12,9 @@ namespace osu.Game.Rulesets.Mods { public abstract BindableNumber SpeedChange { get; } - public virtual void ApplyToTrack(ITrack track) + public virtual void ApplyToTrack(T track) where T : ITrack, IAdjustableAudioComponent { - (track as Track)?.AddAdjustment(AdjustableProperty.Tempo, SpeedChange); + track.AddAdjustment(AdjustableProperty.Tempo, SpeedChange); } public virtual void ApplyToSample(SampleChannel sample) diff --git a/osu.Game/Rulesets/Mods/ModTimeRamp.cs b/osu.Game/Rulesets/Mods/ModTimeRamp.cs index 0257e241b8..b6cbe72971 100644 --- a/osu.Game/Rulesets/Mods/ModTimeRamp.cs +++ b/osu.Game/Rulesets/Mods/ModTimeRamp.cs @@ -42,7 +42,7 @@ namespace osu.Game.Rulesets.Mods Precision = 0.01, }; - private Track track; + private ITrack track; protected ModTimeRamp() { @@ -51,9 +51,9 @@ namespace osu.Game.Rulesets.Mods AdjustPitch.BindValueChanged(applyPitchAdjustment); } - public void ApplyToTrack(ITrack track) + public void ApplyToTrack(T track) where T : ITrack, IAdjustableAudioComponent { - this.track = track as Track; + this.track = track; FinalRate.TriggerChange(); AdjustPitch.TriggerChange(); @@ -89,9 +89,9 @@ namespace osu.Game.Rulesets.Mods private void applyPitchAdjustment(ValueChangedEvent adjustPitchSetting) { // remove existing old adjustment - track?.RemoveAdjustment(adjustmentForPitchSetting(adjustPitchSetting.OldValue), SpeedChange); + (track as IAdjustableAudioComponent)?.RemoveAdjustment(adjustmentForPitchSetting(adjustPitchSetting.OldValue), SpeedChange); - track?.AddAdjustment(adjustmentForPitchSetting(adjustPitchSetting.NewValue), SpeedChange); + (track as IAdjustableAudioComponent)?.AddAdjustment(adjustmentForPitchSetting(adjustPitchSetting.NewValue), SpeedChange); } private AdjustableProperty adjustmentForPitchSetting(bool adjustPitchSettingValue) diff --git a/osu.Game/Screens/Edit/Components/PlaybackControl.cs b/osu.Game/Screens/Edit/Components/PlaybackControl.cs index 0a9b4f06a7..412efe266c 100644 --- a/osu.Game/Screens/Edit/Components/PlaybackControl.cs +++ b/osu.Game/Screens/Edit/Components/PlaybackControl.cs @@ -66,12 +66,12 @@ namespace osu.Game.Screens.Edit.Components } }; - musicController.AddAdjustment(AdjustableProperty.Tempo, tempo); + musicController.CurrentTrack?.AddAdjustment(AdjustableProperty.Tempo, tempo); } protected override void Dispose(bool isDisposing) { - musicController?.RemoveAdjustment(AdjustableProperty.Tempo, tempo); + musicController?.CurrentTrack?.RemoveAdjustment(AdjustableProperty.Tempo, tempo); base.Dispose(isDisposing); } diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs index 446f7fdf88..24fb855009 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System; +using System.Diagnostics; using osu.Framework.Allocation; using osu.Framework.Bindables; using osuTK; @@ -57,7 +58,8 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts return; } - content.RelativeChildSize = new Vector2((float)Math.Max(1, musicController.TrackLength), 1); + Debug.Assert(musicController.CurrentTrack != null); + content.RelativeChildSize = new Vector2((float)Math.Max(1, musicController.CurrentTrack.Length), 1); } protected virtual void LoadBeatmap(WorkingBeatmap beatmap) diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs index f35e5defd8..d556d948f6 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs @@ -2,7 +2,9 @@ // See the LICENCE file in the repository root for full licence text. using System; +using System.Diagnostics; using osu.Framework.Allocation; +using osu.Framework.Audio.Track; using osu.Framework.Bindables; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; @@ -60,21 +62,20 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline Beatmap.BindValueChanged(b => { waveform.Waveform = b.NewValue.Waveform; + track = musicController.CurrentTrack; - // Todo: Wrong. - Schedule(() => + Debug.Assert(track != null); + + if (track.Length > 0) { - if (musicController.TrackLength > 0) - { - MaxZoom = getZoomLevelForVisibleMilliseconds(500); - MinZoom = getZoomLevelForVisibleMilliseconds(10000); - Zoom = getZoomLevelForVisibleMilliseconds(2000); - } - }); + MaxZoom = getZoomLevelForVisibleMilliseconds(500); + MinZoom = getZoomLevelForVisibleMilliseconds(10000); + Zoom = getZoomLevelForVisibleMilliseconds(2000); + } }, true); } - private float getZoomLevelForVisibleMilliseconds(double milliseconds) => (float)(musicController.TrackLength / milliseconds); + private float getZoomLevelForVisibleMilliseconds(double milliseconds) => (float)(track.Length / milliseconds); /// /// The timeline's scroll position in the last frame. @@ -96,6 +97,8 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline /// private bool trackWasPlaying; + private ITrack track; + protected override void Update() { base.Update(); @@ -136,15 +139,15 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline if (!musicController.TrackLoaded) return; - editorClock.Seek(Current / Content.DrawWidth * musicController.TrackLength); + editorClock.Seek(Current / Content.DrawWidth * track.Length); } private void scrollToTrackTime() { - if (!musicController.TrackLoaded || musicController.TrackLength == 0) + if (!musicController.TrackLoaded || track.Length == 0) return; - ScrollTo((float)(editorClock.CurrentTime / musicController.TrackLength) * Content.DrawWidth, false); + ScrollTo((float)(editorClock.CurrentTime / track.Length) * Content.DrawWidth, false); } protected override bool OnMouseDown(MouseDownEvent e) @@ -188,7 +191,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline new SnapResult(screenSpacePosition, beatSnapProvider.SnapTime(getTimeFromPosition(Content.ToLocalSpace(screenSpacePosition)))); private double getTimeFromPosition(Vector2 localPosition) => - (localPosition.X / Content.DrawWidth) * musicController.TrackLength; + (localPosition.X / Content.DrawWidth) * track.Length; public float GetBeatSnapDistanceAt(double referenceTime) => throw new NotImplementedException(); diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineTickDisplay.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineTickDisplay.cs index a833b354ed..ceb0275a13 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineTickDisplay.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineTickDisplay.cs @@ -3,6 +3,7 @@ using System.Linq; using osu.Framework.Allocation; +using osu.Framework.Extensions.ObjectExtensions; using osu.Framework.Graphics; using osu.Game.Graphics; using osu.Game.Overlays; @@ -43,7 +44,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline for (var i = 0; i < beatmap.ControlPointInfo.TimingPoints.Count; i++) { var point = beatmap.ControlPointInfo.TimingPoints[i]; - var until = i + 1 < beatmap.ControlPointInfo.TimingPoints.Count ? beatmap.ControlPointInfo.TimingPoints[i + 1].Time : musicController.TrackLength; + var until = i + 1 < beatmap.ControlPointInfo.TimingPoints.Count ? beatmap.ControlPointInfo.TimingPoints[i + 1].Time : musicController.CurrentTrack.AsNonNull().Length; int beat = 0; diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index 756b03d049..b02aabc24d 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -83,7 +83,7 @@ namespace osu.Game.Screens.Edit beatDivisor.BindValueChanged(divisor => Beatmap.Value.BeatmapInfo.BeatDivisor = divisor.NewValue); // Todo: should probably be done at a DrawableRuleset level to share logic with Player. - var sourceClock = musicController.GetTrackClock() ?? new StopwatchClock(); + var sourceClock = (IAdjustableClock)musicController.CurrentTrack ?? new StopwatchClock(); clock = new EditorClock(Beatmap.Value, beatDivisor) { IsCoupled = false }; clock.ChangeSource(sourceClock); diff --git a/osu.Game/Screens/Edit/EditorClock.cs b/osu.Game/Screens/Edit/EditorClock.cs index 4cb24f90a6..4e589aeeef 100644 --- a/osu.Game/Screens/Edit/EditorClock.cs +++ b/osu.Game/Screens/Edit/EditorClock.cs @@ -55,7 +55,7 @@ namespace osu.Game.Screens.Edit private void load() { // Todo: What. - TrackLength ??= musicController.TrackLength; + TrackLength ??= musicController.CurrentTrack?.Length ?? 0; } /// diff --git a/osu.Game/Screens/Menu/IntroScreen.cs b/osu.Game/Screens/Menu/IntroScreen.cs index 7da5df2723..030923c228 100644 --- a/osu.Game/Screens/Menu/IntroScreen.cs +++ b/osu.Game/Screens/Menu/IntroScreen.cs @@ -113,7 +113,9 @@ namespace osu.Game.Screens.Menu if (setInfo != null) { initialBeatmap = beatmaps.GetWorkingBeatmap(setInfo.Beatmaps[0]); - UsingThemedIntro = !MusicController.IsDummyDevice; + + // Todo: Wrong. + UsingThemedIntro = MusicController.CurrentTrack?.IsDummyDevice == false; } return UsingThemedIntro; diff --git a/osu.Game/Screens/Menu/IntroTriangles.cs b/osu.Game/Screens/Menu/IntroTriangles.cs index 86a6fa3802..e29ea6e743 100644 --- a/osu.Game/Screens/Menu/IntroTriangles.cs +++ b/osu.Game/Screens/Menu/IntroTriangles.cs @@ -59,7 +59,7 @@ namespace osu.Game.Screens.Menu LoadComponentAsync(new TrianglesIntroSequence(logo, background) { RelativeSizeAxes = Axes.Both, - Clock = new FramedClock(UsingThemedIntro ? MusicController.GetTrackClock() : null), + Clock = new FramedClock(UsingThemedIntro ? MusicController.CurrentTrack : null), LoadMenu = LoadMenu }, t => { diff --git a/osu.Game/Screens/Menu/IntroWelcome.cs b/osu.Game/Screens/Menu/IntroWelcome.cs index 62cada577d..85f11eb244 100644 --- a/osu.Game/Screens/Menu/IntroWelcome.cs +++ b/osu.Game/Screens/Menu/IntroWelcome.cs @@ -44,7 +44,8 @@ namespace osu.Game.Screens.Menu pianoReverb = audio.Samples.Get(@"Intro/Welcome/welcome_piano"); - musicController.Looping = true; + if (musicController.CurrentTrack != null) + musicController.CurrentTrack.Looping = true; } protected override void LogoArriving(OsuLogo logo, bool resuming) diff --git a/osu.Game/Screens/Menu/LogoVisualisation.cs b/osu.Game/Screens/Menu/LogoVisualisation.cs index 349654165f..7a1ff4fa06 100644 --- a/osu.Game/Screens/Menu/LogoVisualisation.cs +++ b/osu.Game/Screens/Menu/LogoVisualisation.cs @@ -19,6 +19,7 @@ using osu.Framework.Allocation; using osu.Framework.Audio; using osu.Framework.Audio.Track; using osu.Framework.Bindables; +using osu.Framework.Extensions.ObjectExtensions; using osu.Framework.Utils; using osu.Game.Overlays; @@ -108,14 +109,14 @@ namespace osu.Game.Screens.Menu private void updateAmplitudes() { var effect = beatmap.Value.BeatmapLoaded && musicController.TrackLoaded - ? beatmap.Value.Beatmap?.ControlPointInfo.EffectPointAt(musicController.CurrentTrackTime) + ? beatmap.Value.Beatmap?.ControlPointInfo.EffectPointAt(musicController.CurrentTrack.AsNonNull().CurrentTime) : null; for (int i = 0; i < temporalAmplitudes.Length; i++) temporalAmplitudes[i] = 0; if (musicController.TrackLoaded) - addAmplitudesFromSource(musicController); + addAmplitudesFromSource(musicController.CurrentTrack.AsNonNull()); foreach (var source in amplitudeSources) addAmplitudesFromSource(source); diff --git a/osu.Game/Screens/Menu/MainMenu.cs b/osu.Game/Screens/Menu/MainMenu.cs index c422f57332..ce48777ce1 100644 --- a/osu.Game/Screens/Menu/MainMenu.cs +++ b/osu.Game/Screens/Menu/MainMenu.cs @@ -1,6 +1,7 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System.Diagnostics; using System.Linq; using osuTK; using osuTK.Graphics; @@ -181,11 +182,12 @@ namespace osu.Game.Screens.Menu if (last is IntroScreen && musicController.TrackLoaded) { - // Todo: Wrong. - if (!musicController.IsPlaying) + Debug.Assert(musicController.CurrentTrack != null); + + if (!musicController.CurrentTrack.IsRunning) { - musicController.SeekTo(metadata.PreviewTime != -1 ? metadata.PreviewTime : 0.4f * musicController.TrackLength); - musicController.Play(); + musicController.CurrentTrack.Seek(metadata.PreviewTime != -1 ? metadata.PreviewTime : 0.4f * musicController.CurrentTrack.Length); + musicController.CurrentTrack.Start(); } } diff --git a/osu.Game/Screens/Menu/OsuLogo.cs b/osu.Game/Screens/Menu/OsuLogo.cs index 1feb2481c3..f028f9b229 100644 --- a/osu.Game/Screens/Menu/OsuLogo.cs +++ b/osu.Game/Screens/Menu/OsuLogo.cs @@ -330,9 +330,9 @@ namespace osu.Game.Screens.Menu const float velocity_adjust_cutoff = 0.98f; const float paused_velocity = 0.5f; - if (musicController.IsPlaying) + if (musicController.CurrentTrack?.IsRunning == true) { - var maxAmplitude = lastBeatIndex >= 0 ? musicController.CurrentAmplitudes.Maximum : 0; + var maxAmplitude = lastBeatIndex >= 0 ? musicController.CurrentTrack.CurrentAmplitudes.Maximum : 0; logoAmplitudeContainer.Scale = new Vector2((float)Interpolation.Damp(logoAmplitudeContainer.Scale.X, 1 - Math.Max(0, maxAmplitude - scale_adjust_cutoff) * 0.04f, 0.9f, Time.Elapsed)); if (maxAmplitude > velocity_adjust_cutoff) diff --git a/osu.Game/Screens/Multi/Match/Components/ReadyButton.cs b/osu.Game/Screens/Multi/Match/Components/ReadyButton.cs index 032c8d5ca9..c7dc20ff23 100644 --- a/osu.Game/Screens/Multi/Match/Components/ReadyButton.cs +++ b/osu.Game/Screens/Multi/Match/Components/ReadyButton.cs @@ -104,7 +104,7 @@ namespace osu.Game.Screens.Multi.Match.Components return; } - bool hasEnoughTime = DateTimeOffset.UtcNow.AddSeconds(30).AddMilliseconds(musicController.TrackLength) < endDate.Value; + bool hasEnoughTime = musicController.CurrentTrack != null && DateTimeOffset.UtcNow.AddSeconds(30).AddMilliseconds(musicController.CurrentTrack.Length) < endDate.Value; Enabled.Value = hasBeatmap && hasEnoughTime; } diff --git a/osu.Game/Screens/Multi/Multiplayer.cs b/osu.Game/Screens/Multi/Multiplayer.cs index 2d74434c76..e068899c7b 100644 --- a/osu.Game/Screens/Multi/Multiplayer.cs +++ b/osu.Game/Screens/Multi/Multiplayer.cs @@ -343,9 +343,13 @@ namespace osu.Game.Screens.Multi { if (screenStack.CurrentScreen is MatchSubScreen) { - musicController.RestartPoint = Beatmap.Value.Metadata.PreviewTime; - musicController.Looping = true; - musicController.EnsurePlayingSomething(); + if (musicController.CurrentTrack != null) + { + musicController.CurrentTrack.RestartPoint = Beatmap.Value.Metadata.PreviewTime; + musicController.CurrentTrack.Looping = true; + + musicController.EnsurePlayingSomething(); + } } else { @@ -355,8 +359,11 @@ namespace osu.Game.Screens.Multi private void cancelLooping() { - musicController.Looping = false; - musicController.RestartPoint = 0; + if (musicController.CurrentTrack != null) + { + musicController.CurrentTrack.Looping = false; + musicController.CurrentTrack.RestartPoint = 0; + } } protected override void Dispose(bool isDisposing) diff --git a/osu.Game/Screens/Play/FailAnimation.cs b/osu.Game/Screens/Play/FailAnimation.cs index 0e0ef8c675..1171d8c3b0 100644 --- a/osu.Game/Screens/Play/FailAnimation.cs +++ b/osu.Game/Screens/Play/FailAnimation.cs @@ -9,6 +9,7 @@ using System.Collections.Generic; using osu.Framework.Allocation; using osu.Framework.Audio.Sample; using osu.Framework.Graphics; +using osu.Framework.Graphics.Audio; using osu.Framework.Utils; using osu.Game.Beatmaps; using osu.Game.Overlays; @@ -30,21 +31,21 @@ namespace osu.Game.Screens.Play private readonly BindableDouble trackFreq = new BindableDouble(1); + private DrawableTrack track; + private const float duration = 2500; private SampleChannel failSample; - [Resolved] - private MusicController musicController { get; set; } - public FailAnimation(DrawableRuleset drawableRuleset) { this.drawableRuleset = drawableRuleset; } [BackgroundDependencyLoader] - private void load(AudioManager audio, IBindable beatmap) + private void load(AudioManager audio, IBindable beatmap, MusicController musicController) { + track = musicController.CurrentTrack; failSample = audio.Samples.Get(@"Gameplay/failsound"); } @@ -68,7 +69,7 @@ namespace osu.Game.Screens.Play Expire(); }); - musicController.AddAdjustment(AdjustableProperty.Frequency, trackFreq); + track.AddAdjustment(AdjustableProperty.Frequency, trackFreq); applyToPlayfield(drawableRuleset.Playfield); drawableRuleset.Playfield.HitObjectContainer.FlashColour(Color4.Red, 500); @@ -107,7 +108,7 @@ namespace osu.Game.Screens.Play protected override void Dispose(bool isDisposing) { base.Dispose(isDisposing); - musicController?.RemoveAdjustment(AdjustableProperty.Frequency, trackFreq); + track?.RemoveAdjustment(AdjustableProperty.Frequency, trackFreq); } } } diff --git a/osu.Game/Screens/Play/GameplayClockContainer.cs b/osu.Game/Screens/Play/GameplayClockContainer.cs index cf4678ab29..61272f56ad 100644 --- a/osu.Game/Screens/Play/GameplayClockContainer.cs +++ b/osu.Game/Screens/Play/GameplayClockContainer.cs @@ -8,8 +8,10 @@ using System.Threading.Tasks; using osu.Framework; using osu.Framework.Allocation; using osu.Framework.Audio; +using osu.Framework.Audio.Track; using osu.Framework.Bindables; using osu.Framework.Graphics; +using osu.Framework.Graphics.Audio; using osu.Framework.Graphics.Containers; using osu.Framework.Timing; using osu.Game.Beatmaps; @@ -27,8 +29,7 @@ namespace osu.Game.Screens.Play private readonly WorkingBeatmap beatmap; private readonly IReadOnlyList mods; - [Resolved] - private MusicController musicController { get; set; } + private DrawableTrack track; public readonly BindableBool IsPaused = new BindableBool(); @@ -95,8 +96,10 @@ namespace osu.Game.Screens.Play private readonly BindableDouble pauseFreqAdjust = new BindableDouble(1); [BackgroundDependencyLoader] - private void load(OsuConfigManager config) + private void load(OsuConfigManager config, MusicController musicController) { + track = musicController.CurrentTrack; + userAudioOffset = config.GetBindable(OsuSetting.AudioOffset); userAudioOffset.BindValueChanged(offset => userOffsetClock.Offset = offset.NewValue, true); @@ -121,15 +124,15 @@ namespace osu.Game.Screens.Play { // The Reset() call below causes speed adjustments to be reset in an async context, leading to deadlocks. // The deadlock can be prevented by resetting the track synchronously before entering the async context. - musicController.Reset(); + track.ResetSpeedAdjustments(); Task.Run(() => { - musicController.Reset(); + track.Reset(); Schedule(() => { - adjustableClock.ChangeSource(musicController.GetTrackClock()); + adjustableClock.ChangeSource(track); updateRate(); if (!IsPaused.Value) @@ -190,6 +193,20 @@ namespace osu.Game.Screens.Play IsPaused.Value = true; } + /// + /// Changes the backing clock to avoid using the originally provided track. + /// + public void StopUsingBeatmapClock() + { + if (track == null) + return; + + removeSourceClockAdjustments(); + + track = new DrawableTrack(new TrackVirtual(track.Length)); + adjustableClock.ChangeSource(track); + } + protected override void Update() { if (!IsPaused.Value) @@ -202,23 +219,30 @@ namespace osu.Game.Screens.Play private void updateRate() { + if (track == null) return; + speedAdjustmentsApplied = true; - musicController.ResetTrackAdjustments(); - musicController.AddAdjustment(AdjustableProperty.Frequency, pauseFreqAdjust); - musicController.AddAdjustment(AdjustableProperty.Tempo, UserPlaybackRate); + track.ResetSpeedAdjustments(); + + track.AddAdjustment(AdjustableProperty.Frequency, pauseFreqAdjust); + track.AddAdjustment(AdjustableProperty.Tempo, UserPlaybackRate); + + foreach (var mod in mods.OfType()) + mod.ApplyToTrack(track); } protected override void Dispose(bool isDisposing) { base.Dispose(isDisposing); removeSourceClockAdjustments(); + track = null; } private void removeSourceClockAdjustments() { if (speedAdjustmentsApplied) { - musicController.ResetTrackAdjustments(); + track.ResetSpeedAdjustments(); speedAdjustmentsApplied = false; } } diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 9ba2732920..ea04d82e67 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -31,6 +31,7 @@ using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using osu.Framework.Audio.Track; using osu.Framework.Graphics.Sprites; using osu.Framework.Input.Bindings; using osu.Game.Graphics.UserInterface; @@ -560,9 +561,9 @@ namespace osu.Game.Screens.Select BeatmapDetails.Refresh(); - if (music != null) + if (music?.CurrentTrack != null) { - music.Looping = true; + music.CurrentTrack.Looping = true; music.ResetTrackAdjustments(); } @@ -588,8 +589,8 @@ namespace osu.Game.Screens.Select BeatmapOptions.Hide(); - if (music != null) - music.Looping = false; + if (music?.CurrentTrack != null) + music.CurrentTrack.Looping = false; this.ScaleTo(1.1f, 250, Easing.InSine); @@ -610,8 +611,8 @@ namespace osu.Game.Screens.Select FilterControl.Deactivate(); - if (music != null) - music.Looping = false; + if (music?.CurrentTrack != null) + music.CurrentTrack.Looping = false; return false; } @@ -652,18 +653,30 @@ namespace osu.Game.Screens.Select BeatmapDetails.Beatmap = beatmap; - if (music != null) - music.Looping = false; + if (music?.CurrentTrack != null) + music.CurrentTrack.Looping = false; } + private readonly WeakReference lastTrack = new WeakReference(null); + /// /// Ensures some music is playing for the current track. /// Will resume playback from a manual user pause if the track has changed. /// private void ensurePlayingSelected() { - music.RestartPoint = Beatmap.Value.Metadata.PreviewTime; - music.EnsurePlayingSomething(); + ITrack track = music?.CurrentTrack; + if (track == null) + return; + + bool isNewTrack = !lastTrack.TryGetTarget(out var last) || last != track; + + track.RestartPoint = Beatmap.Value.Metadata.PreviewTime; + + if (!track.IsRunning && (music?.IsUserPaused != true || isNewTrack)) + music?.Play(true); + + lastTrack.SetTarget(track); } private void carouselBeatmapsLoaded() diff --git a/osu.Game/Tests/Visual/EditorClockTestScene.cs b/osu.Game/Tests/Visual/EditorClockTestScene.cs index 5226a49def..780b4f1b3a 100644 --- a/osu.Game/Tests/Visual/EditorClockTestScene.cs +++ b/osu.Game/Tests/Visual/EditorClockTestScene.cs @@ -44,7 +44,7 @@ namespace osu.Game.Tests.Visual private void beatmapChanged(ValueChangedEvent e) { Clock.ControlPointInfo = e.NewValue.Beatmap.ControlPointInfo; - Clock.ChangeSource(MusicController.GetTrackClock() ?? new StopwatchClock()); + Clock.ChangeSource((IAdjustableClock)MusicController.CurrentTrack ?? new StopwatchClock()); Clock.ProcessFrame(); } diff --git a/osu.Game/Tests/Visual/RateAdjustedBeatmapTestScene.cs b/osu.Game/Tests/Visual/RateAdjustedBeatmapTestScene.cs index e7cb461d7b..ae4b0ef84a 100644 --- a/osu.Game/Tests/Visual/RateAdjustedBeatmapTestScene.cs +++ b/osu.Game/Tests/Visual/RateAdjustedBeatmapTestScene.cs @@ -1,6 +1,8 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using osu.Framework.Extensions.ObjectExtensions; + namespace osu.Game.Tests.Visual { /// @@ -13,7 +15,7 @@ namespace osu.Game.Tests.Visual base.Update(); // note that this will override any mod rate application - MusicController.Tempo.Value = Clock.Rate; + MusicController.CurrentTrack.AsNonNull().Tempo.Value = Clock.Rate; } } } From 58660c70a3c9cad61e78ef854d238e8f569ee08e Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 5 Aug 2020 21:20:41 +0900 Subject: [PATCH 087/434] Cache before idle tracker --- osu.Game/OsuGame.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 929254e8ad..3e41be2028 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -554,8 +554,8 @@ namespace osu.Game Container logoContainer; BackButton.Receptor receptor; - dependencies.CacheAs(idleTracker = new GameIdleTracker(6000)); dependencies.CacheAs(MusicController = new MusicController()); + dependencies.CacheAs(idleTracker = new GameIdleTracker(6000)); AddRange(new Drawable[] { From e9fc783b1d75f31ec8291fa8a11f254f28cb1860 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 5 Aug 2020 21:21:08 +0900 Subject: [PATCH 088/434] Add back loop-on-completion --- osu.Game/OsuGame.cs | 18 +----------------- osu.Game/Overlays/MusicController.cs | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 3e41be2028..a41c7b28a5 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -427,23 +427,7 @@ namespace osu.Game updateModDefaults(); - var newBeatmap = beatmap.NewValue; - - if (newBeatmap != null) - { - // MusicController.Completed += () => Scheduler.AddOnce(() => trackCompleted(newBeatmap)); - newBeatmap.BeginAsyncLoad(); - } - - // void trackCompleted(WorkingBeatmap b) - // { - // // the source of track completion is the audio thread, so the beatmap may have changed before firing. - // if (Beatmap.Value != b) - // return; - // - // if (!MusicController.Looping && !Beatmap.Disabled) - // MusicController.NextTrack(); - // } + beatmap.NewValue?.BeginAsyncLoad(); } private void modsChanged(ValueChangedEvent> mods) diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index c22849b7d6..50ad97be7c 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; using JetBrains.Annotations; using osu.Framework.Allocation; @@ -323,7 +324,10 @@ namespace osu.Game.Overlays CurrentTrack = null; if (current != null) + { trackContainer.Add(CurrentTrack = new DrawableTrack(current.GetRealTrack())); + CurrentTrack.Completed += () => onTrackCompleted(current); + } TrackChanged?.Invoke(current, direction); @@ -332,6 +336,18 @@ namespace osu.Game.Overlays queuedDirection = null; } + private void onTrackCompleted(WorkingBeatmap workingBeatmap) + { + // the source of track completion is the audio thread, so the beatmap may have changed before firing. + if (current != workingBeatmap) + return; + + Debug.Assert(CurrentTrack != null); + + if (!CurrentTrack.Looping && !beatmap.Disabled) + NextTrack(); + } + private bool allowRateAdjustments; /// From 11a6c9bdccc65e89575a0e138512ccc379b1a15f Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 5 Aug 2020 21:21:14 +0900 Subject: [PATCH 089/434] Revert unnecessary change --- osu.Game/Graphics/Containers/BeatSyncedContainer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Graphics/Containers/BeatSyncedContainer.cs b/osu.Game/Graphics/Containers/BeatSyncedContainer.cs index 92a9ed0566..69021e1634 100644 --- a/osu.Game/Graphics/Containers/BeatSyncedContainer.cs +++ b/osu.Game/Graphics/Containers/BeatSyncedContainer.cs @@ -64,7 +64,7 @@ namespace osu.Game.Graphics.Containers beatmap = Beatmap.Value.Beatmap; } - if (track != null && beatmap != null && musicController.IsPlaying && track.Length > 0) + if (track != null && beatmap != null && track.IsRunning && track.Length > 0) { currentTrackTime = track.CurrentTime + EarlyActivationMilliseconds; From f058f5e977bbfb532b2711e0101c76868022b808 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 5 Aug 2020 21:29:53 +0900 Subject: [PATCH 090/434] Fix incorrect value being set --- osu.Game/Screens/Select/SongSelect.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index ea04d82e67..80ed894233 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -654,7 +654,7 @@ namespace osu.Game.Screens.Select BeatmapDetails.Beatmap = beatmap; if (music?.CurrentTrack != null) - music.CurrentTrack.Looping = false; + music.CurrentTrack.Looping = true; } private readonly WeakReference lastTrack = new WeakReference(null); From 0edd50939783f86909c3e024d47100259417c42e Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 5 Aug 2020 21:30:11 +0900 Subject: [PATCH 091/434] Only change track when audio doesn't equal --- osu.Game/Overlays/MusicController.cs | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index 50ad97be7c..47d1bef177 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -320,6 +320,18 @@ namespace osu.Game.Overlays current = beatmap.NewValue; + if (!beatmap.OldValue.BeatmapInfo.AudioEquals(current?.BeatmapInfo)) + changeTrack(); + + TrackChanged?.Invoke(current, direction); + + ResetTrackAdjustments(); + + queuedDirection = null; + } + + private void changeTrack() + { CurrentTrack?.Expire(); CurrentTrack = null; @@ -328,12 +340,6 @@ namespace osu.Game.Overlays trackContainer.Add(CurrentTrack = new DrawableTrack(current.GetRealTrack())); CurrentTrack.Completed += () => onTrackCompleted(current); } - - TrackChanged?.Invoke(current, direction); - - ResetTrackAdjustments(); - - queuedDirection = null; } private void onTrackCompleted(WorkingBeatmap workingBeatmap) From 86ae61c6b79aec0febbe8220781cc7ad3aefb9de Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 5 Aug 2020 22:09:47 +0900 Subject: [PATCH 092/434] Re-implement store transferral in BeatmapManager --- osu.Game/Beatmaps/BeatmapManager.cs | 19 +++++++++++-------- .../Beatmaps/BeatmapManager_WorkingBeatmap.cs | 17 +++++++++-------- 2 files changed, 20 insertions(+), 16 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index b2329f58ad..6a7d0b053f 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -218,7 +218,7 @@ namespace osu.Game.Beatmaps removeWorkingCache(info); } - private readonly WeakList workingCache = new WeakList(); + private readonly WeakList workingCache = new WeakList(); /// /// Retrieve a instance for the provided @@ -246,16 +246,19 @@ namespace osu.Game.Beatmaps lock (workingCache) { var working = workingCache.FirstOrDefault(w => w.BeatmapInfo?.ID == beatmapInfo.ID); + if (working != null) + return working; - if (working == null) - { - beatmapInfo.Metadata ??= beatmapInfo.BeatmapSet.Metadata; + beatmapInfo.Metadata ??= beatmapInfo.BeatmapSet.Metadata; - workingCache.Add(working = new BeatmapManagerWorkingBeatmap(Files.Store, - new LargeTextureStore(host?.CreateTextureLoaderStore(Files.Store)), beatmapInfo, audioManager)); - } + ITrackStore trackStore = workingCache.FirstOrDefault(b => b.BeatmapInfo.AudioEquals(beatmapInfo))?.TrackStore; + TextureStore textureStore = workingCache.FirstOrDefault(b => b.BeatmapInfo.BackgroundEquals(beatmapInfo))?.TextureStore; + + textureStore ??= new LargeTextureStore(host?.CreateTextureLoaderStore(Files.Store)); + trackStore ??= audioManager.GetTrackStore(Files.Store); + + workingCache.Add(working = new BeatmapManagerWorkingBeatmap(Files.Store, textureStore, trackStore, beatmapInfo, audioManager)); - // previous?.TransferTo(working); return working; } } diff --git a/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs b/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs index 33945a9eb1..ceefef5d7e 100644 --- a/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs @@ -19,13 +19,18 @@ namespace osu.Game.Beatmaps { protected class BeatmapManagerWorkingBeatmap : WorkingBeatmap { + public readonly TextureStore TextureStore; + public readonly ITrackStore TrackStore; + private readonly IResourceStore store; - public BeatmapManagerWorkingBeatmap(IResourceStore store, TextureStore textureStore, BeatmapInfo beatmapInfo, AudioManager audioManager) + public BeatmapManagerWorkingBeatmap(IResourceStore store, TextureStore textureStore, ITrackStore trackStore, BeatmapInfo beatmapInfo, AudioManager audioManager) : base(beatmapInfo, audioManager) { this.store = store; - this.textureStore = textureStore; + + TextureStore = textureStore; + TrackStore = trackStore; } protected override IBeatmap GetBeatmap() @@ -44,10 +49,6 @@ namespace osu.Game.Beatmaps private string getPathForFile(string filename) => BeatmapSetInfo.Files.SingleOrDefault(f => string.Equals(f.Filename, filename, StringComparison.OrdinalIgnoreCase))?.FileInfo.StoragePath; - private TextureStore textureStore; - - private ITrackStore trackStore; - protected override bool BackgroundStillValid(Texture b) => false; // bypass lazy logic. we want to return a new background each time for refcounting purposes. protected override Texture GetBackground() @@ -57,7 +58,7 @@ namespace osu.Game.Beatmaps try { - return textureStore.Get(getPathForFile(Metadata.BackgroundFile)); + return TextureStore.Get(getPathForFile(Metadata.BackgroundFile)); } catch (Exception e) { @@ -70,7 +71,7 @@ namespace osu.Game.Beatmaps { try { - return (trackStore ??= AudioManager.GetTrackStore(store)).Get(getPathForFile(Metadata.AudioFile)); + return TrackStore.Get(getPathForFile(Metadata.AudioFile)); } catch (Exception e) { From 0f7fde5d2cd5db7eb8e621bfe221ea28cc252da8 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 5 Aug 2020 22:32:44 +0900 Subject: [PATCH 093/434] Revert unnecessary change --- osu.Game/Overlays/Music/PlaylistOverlay.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Music/PlaylistOverlay.cs b/osu.Game/Overlays/Music/PlaylistOverlay.cs index c089158c01..b9a58c37cb 100644 --- a/osu.Game/Overlays/Music/PlaylistOverlay.cs +++ b/osu.Game/Overlays/Music/PlaylistOverlay.cs @@ -83,7 +83,10 @@ namespace osu.Game.Overlays.Music BeatmapInfo toSelect = list.FirstVisibleSet?.Beatmaps?.FirstOrDefault(); if (toSelect != null) + { beatmap.Value = beatmaps.GetWorkingBeatmap(toSelect); + musicController.CurrentTrack?.Restart(); + } }; } @@ -116,12 +119,12 @@ namespace osu.Game.Overlays.Music { if (set.ID == (beatmap.Value?.BeatmapSetInfo?.ID ?? -1)) { - musicController.SeekTo(0); + musicController.CurrentTrack?.Seek(0); return; } beatmap.Value = beatmaps.GetWorkingBeatmap(set.Beatmaps.First()); - musicController.Play(true); + musicController.CurrentTrack?.Restart(); } } From fe8c462498ad18a842544202bc4e6a14d3e217ed Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 6 Aug 2020 17:00:17 +0900 Subject: [PATCH 094/434] Remove intermediate container --- osu.Game/Overlays/MusicController.cs | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index 47d1bef177..6adfa1817e 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -65,20 +65,12 @@ namespace osu.Game.Overlays [Resolved(canBeNull: true)] private OnScreenDisplay onScreenDisplay { get; set; } - [NotNull] - private readonly TrackContainer trackContainer; - [CanBeNull] public DrawableTrack CurrentTrack { get; private set; } private IBindable> managerUpdated; private IBindable> managerRemoved; - public MusicController() - { - InternalChild = trackContainer = new TrackContainer { RelativeSizeAxes = Axes.Both }; - } - [BackgroundDependencyLoader] private void load() { @@ -337,8 +329,10 @@ namespace osu.Game.Overlays if (current != null) { - trackContainer.Add(CurrentTrack = new DrawableTrack(current.GetRealTrack())); + CurrentTrack = new DrawableTrack(current.GetRealTrack()); CurrentTrack.Completed += () => onTrackCompleted(current); + + AddInternal(CurrentTrack); } } @@ -433,10 +427,6 @@ namespace osu.Game.Overlays { } } - - private class TrackContainer : AudioContainer - { - } } public enum TrackChangeDirection From e8ab3cff3c38c5dad046b0c69f0f34b7478a08ce Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 6 Aug 2020 17:02:42 +0900 Subject: [PATCH 095/434] Add class constraint --- osu.Game/Rulesets/Mods/IApplicableToTrack.cs | 2 +- osu.Game/Rulesets/Mods/ModRateAdjust.cs | 3 ++- osu.Game/Rulesets/Mods/ModTimeRamp.cs | 3 ++- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/osu.Game/Rulesets/Mods/IApplicableToTrack.cs b/osu.Game/Rulesets/Mods/IApplicableToTrack.cs index 5ae41fe09c..b29ba55942 100644 --- a/osu.Game/Rulesets/Mods/IApplicableToTrack.cs +++ b/osu.Game/Rulesets/Mods/IApplicableToTrack.cs @@ -11,6 +11,6 @@ namespace osu.Game.Rulesets.Mods /// public interface IApplicableToTrack : IApplicableMod { - void ApplyToTrack(T track) where T : ITrack, IAdjustableAudioComponent; + void ApplyToTrack(T track) where T : class, ITrack, IAdjustableAudioComponent; } } diff --git a/osu.Game/Rulesets/Mods/ModRateAdjust.cs b/osu.Game/Rulesets/Mods/ModRateAdjust.cs index e2c8ac64d9..4aee5affe9 100644 --- a/osu.Game/Rulesets/Mods/ModRateAdjust.cs +++ b/osu.Game/Rulesets/Mods/ModRateAdjust.cs @@ -12,7 +12,8 @@ namespace osu.Game.Rulesets.Mods { public abstract BindableNumber SpeedChange { get; } - public virtual void ApplyToTrack(T track) where T : ITrack, IAdjustableAudioComponent + public virtual void ApplyToTrack(T track) + where T : class, ITrack, IAdjustableAudioComponent { track.AddAdjustment(AdjustableProperty.Tempo, SpeedChange); } diff --git a/osu.Game/Rulesets/Mods/ModTimeRamp.cs b/osu.Game/Rulesets/Mods/ModTimeRamp.cs index b6cbe72971..4b5241488f 100644 --- a/osu.Game/Rulesets/Mods/ModTimeRamp.cs +++ b/osu.Game/Rulesets/Mods/ModTimeRamp.cs @@ -51,7 +51,8 @@ namespace osu.Game.Rulesets.Mods AdjustPitch.BindValueChanged(applyPitchAdjustment); } - public void ApplyToTrack(T track) where T : ITrack, IAdjustableAudioComponent + public void ApplyToTrack(T track) + where T : class, ITrack, IAdjustableAudioComponent { this.track = track; From ad959ce5238dbd8ca4465305d703efac065a3dab Mon Sep 17 00:00:00 2001 From: Joehu Date: Thu, 6 Aug 2020 01:06:51 -0700 Subject: [PATCH 096/434] Make toolbar button abstract --- osu.Game/Overlays/Toolbar/ToolbarButton.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Toolbar/ToolbarButton.cs b/osu.Game/Overlays/Toolbar/ToolbarButton.cs index 86a3f5d8aa..a03ea64eb2 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarButton.cs @@ -18,7 +18,7 @@ using osu.Game.Graphics.UserInterface; namespace osu.Game.Overlays.Toolbar { - public class ToolbarButton : OsuClickableContainer + public abstract class ToolbarButton : OsuClickableContainer { public const float WIDTH = Toolbar.HEIGHT * 1.4f; @@ -68,7 +68,7 @@ namespace osu.Game.Overlays.Toolbar private readonly SpriteText tooltip2; protected FillFlowContainer Flow; - public ToolbarButton() + protected ToolbarButton() : base(HoverSampleSet.Loud) { Width = WIDTH; From c72ab9047e3ea00dbc6eb176a797d20dfd5c95d3 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 6 Aug 2020 17:15:33 +0900 Subject: [PATCH 097/434] Cleanup test scene disposal --- osu.Game/Tests/Visual/OsuTestScene.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/osu.Game/Tests/Visual/OsuTestScene.cs b/osu.Game/Tests/Visual/OsuTestScene.cs index e968f7e675..f2b9388fdc 100644 --- a/osu.Game/Tests/Visual/OsuTestScene.cs +++ b/osu.Game/Tests/Visual/OsuTestScene.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.IO; using System.Linq; using System.Threading.Tasks; @@ -169,7 +170,10 @@ namespace osu.Game.Tests.Visual rulesetDependencies?.Dispose(); if (MusicController?.TrackLoaded == true) - MusicController.Stop(); + { + Debug.Assert(MusicController.CurrentTrack != null); + MusicController.CurrentTrack.Stop(); + } if (contextFactory.IsValueCreated) contextFactory.Value.ResetDatabase(); From 7bcb68ffacd76d2f7b5d743781598b733f2c2731 Mon Sep 17 00:00:00 2001 From: Joehu Date: Thu, 6 Aug 2020 01:17:24 -0700 Subject: [PATCH 098/434] Handle overlay toggling with toolbar buttons instead --- osu.Game/OsuGame.cs | 28 +----------------- .../Toolbar/ToolbarBeatmapListingButton.cs | 3 ++ osu.Game/Overlays/Toolbar/ToolbarButton.cs | 29 +++++++++++++++---- .../Overlays/Toolbar/ToolbarChatButton.cs | 3 ++ .../Overlays/Toolbar/ToolbarHomeButton.cs | 18 ++---------- .../Overlays/Toolbar/ToolbarMusicButton.cs | 3 ++ .../Toolbar/ToolbarNotificationButton.cs | 3 ++ .../Overlays/Toolbar/ToolbarSettingsButton.cs | 3 ++ .../Overlays/Toolbar/ToolbarSocialButton.cs | 3 ++ 9 files changed, 45 insertions(+), 48 deletions(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 26f7c3b93b..b5752214bd 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -67,8 +67,6 @@ namespace osu.Game [NotNull] private readonly NotificationOverlay notifications = new NotificationOverlay(); - private NowPlayingOverlay nowPlaying; - private BeatmapListingOverlay beatmapListing; private DashboardOverlay dashboard; @@ -650,7 +648,7 @@ namespace osu.Game Origin = Anchor.TopRight, }, rightFloatingOverlayContent.Add, true); - loadComponentSingleFile(nowPlaying = new NowPlayingOverlay + loadComponentSingleFile(new NowPlayingOverlay { GetToolbarHeight = () => ToolbarOffset, Anchor = Anchor.TopRight, @@ -862,18 +860,6 @@ namespace osu.Game switch (action) { - case GlobalAction.ToggleNowPlaying: - nowPlaying.ToggleVisibility(); - return true; - - case GlobalAction.ToggleChat: - chatOverlay.ToggleVisibility(); - return true; - - case GlobalAction.ToggleSocial: - dashboard.ToggleVisibility(); - return true; - case GlobalAction.ResetInputSettings: var sensitivity = frameworkConfig.GetBindable(FrameworkSetting.CursorSensitivity); @@ -889,18 +875,6 @@ namespace osu.Game Toolbar.ToggleVisibility(); return true; - case GlobalAction.ToggleSettings: - Settings.ToggleVisibility(); - return true; - - case GlobalAction.ToggleDirect: - beatmapListing.ToggleVisibility(); - return true; - - case GlobalAction.ToggleNotifications: - notifications.ToggleVisibility(); - return true; - case GlobalAction.ToggleGameplayMouseButtons: LocalConfig.Set(OsuSetting.MouseDisableButtons, !LocalConfig.Get(OsuSetting.MouseDisableButtons)); return true; diff --git a/osu.Game/Overlays/Toolbar/ToolbarBeatmapListingButton.cs b/osu.Game/Overlays/Toolbar/ToolbarBeatmapListingButton.cs index 64430c77ac..cde305fffd 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarBeatmapListingButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarBeatmapListingButton.cs @@ -3,6 +3,7 @@ using osu.Framework.Allocation; using osu.Game.Graphics; +using osu.Game.Input.Bindings; namespace osu.Game.Overlays.Toolbar { @@ -13,6 +14,8 @@ namespace osu.Game.Overlays.Toolbar SetIcon(OsuIcon.ChevronDownCircle); TooltipMain = "Beatmap listing"; TooltipSub = "Browse for new beatmaps"; + + Hotkey = GlobalAction.ToggleDirect; } [BackgroundDependencyLoader(true)] diff --git a/osu.Game/Overlays/Toolbar/ToolbarButton.cs b/osu.Game/Overlays/Toolbar/ToolbarButton.cs index a03ea64eb2..3f1dccc45a 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarButton.cs @@ -5,23 +5,27 @@ using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Effects; +using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Sprites; +using osu.Framework.Input.Bindings; +using osu.Framework.Input.Events; using osu.Game.Graphics; using osu.Game.Graphics.Backgrounds; +using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; +using osu.Game.Graphics.UserInterface; +using osu.Game.Input.Bindings; using osuTK; using osuTK.Graphics; -using osu.Framework.Graphics.Shapes; -using osu.Framework.Input.Events; -using osu.Game.Graphics.Containers; -using osu.Game.Graphics.UserInterface; namespace osu.Game.Overlays.Toolbar { - public abstract class ToolbarButton : OsuClickableContainer + public abstract class ToolbarButton : OsuClickableContainer, IKeyBindingHandler { public const float WIDTH = Toolbar.HEIGHT * 1.4f; + protected GlobalAction? Hotkey { get; set; } + public void SetIcon(Drawable icon) { IconContainer.Icon = icon; @@ -164,6 +168,21 @@ namespace osu.Game.Overlays.Toolbar HoverBackground.FadeOut(200); tooltipContainer.FadeOut(100); } + + public bool OnPressed(GlobalAction action) + { + if (action == Hotkey) + { + Click(); + return true; + } + + return false; + } + + public void OnReleased(GlobalAction action) + { + } } public class OpaqueBackground : Container diff --git a/osu.Game/Overlays/Toolbar/ToolbarChatButton.cs b/osu.Game/Overlays/Toolbar/ToolbarChatButton.cs index ec7da54571..dee4be0c1f 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarChatButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarChatButton.cs @@ -3,6 +3,7 @@ using osu.Framework.Allocation; using osu.Framework.Graphics.Sprites; +using osu.Game.Input.Bindings; namespace osu.Game.Overlays.Toolbar { @@ -13,6 +14,8 @@ namespace osu.Game.Overlays.Toolbar SetIcon(FontAwesome.Solid.Comments); TooltipMain = "Chat"; TooltipSub = "Join the real-time discussion"; + + Hotkey = GlobalAction.ToggleChat; } [BackgroundDependencyLoader(true)] diff --git a/osu.Game/Overlays/Toolbar/ToolbarHomeButton.cs b/osu.Game/Overlays/Toolbar/ToolbarHomeButton.cs index e642f0c453..4845c9a99f 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarHomeButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarHomeButton.cs @@ -2,33 +2,19 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Graphics.Sprites; -using osu.Framework.Input.Bindings; using osu.Game.Input.Bindings; namespace osu.Game.Overlays.Toolbar { - public class ToolbarHomeButton : ToolbarButton, IKeyBindingHandler + public class ToolbarHomeButton : ToolbarButton { public ToolbarHomeButton() { Icon = FontAwesome.Solid.Home; TooltipMain = "Home"; TooltipSub = "Return to the main menu"; - } - public bool OnPressed(GlobalAction action) - { - if (action == GlobalAction.Home) - { - Click(); - return true; - } - - return false; - } - - public void OnReleased(GlobalAction action) - { + Hotkey = GlobalAction.Home; } } } diff --git a/osu.Game/Overlays/Toolbar/ToolbarMusicButton.cs b/osu.Game/Overlays/Toolbar/ToolbarMusicButton.cs index 712da12208..59276a5943 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarMusicButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarMusicButton.cs @@ -3,6 +3,7 @@ using osu.Framework.Allocation; using osu.Framework.Graphics.Sprites; +using osu.Game.Input.Bindings; namespace osu.Game.Overlays.Toolbar { @@ -13,6 +14,8 @@ namespace osu.Game.Overlays.Toolbar Icon = FontAwesome.Solid.Music; TooltipMain = "Now playing"; TooltipSub = "Manage the currently playing track"; + + Hotkey = GlobalAction.ToggleNowPlaying; } [BackgroundDependencyLoader(true)] diff --git a/osu.Game/Overlays/Toolbar/ToolbarNotificationButton.cs b/osu.Game/Overlays/Toolbar/ToolbarNotificationButton.cs index dbd6c557d3..a699fd907f 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarNotificationButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarNotificationButton.cs @@ -9,6 +9,7 @@ using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Sprites; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; +using osu.Game.Input.Bindings; using osuTK; using osuTK.Graphics; @@ -28,6 +29,8 @@ namespace osu.Game.Overlays.Toolbar TooltipMain = "Notifications"; TooltipSub = "Waiting for 'ya"; + Hotkey = GlobalAction.ToggleNotifications; + Add(countDisplay = new CountCircle { Alpha = 0, diff --git a/osu.Game/Overlays/Toolbar/ToolbarSettingsButton.cs b/osu.Game/Overlays/Toolbar/ToolbarSettingsButton.cs index 79942012f9..ed2a23ec2a 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarSettingsButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarSettingsButton.cs @@ -3,6 +3,7 @@ using osu.Framework.Allocation; using osu.Framework.Graphics.Sprites; +using osu.Game.Input.Bindings; namespace osu.Game.Overlays.Toolbar { @@ -13,6 +14,8 @@ namespace osu.Game.Overlays.Toolbar Icon = FontAwesome.Solid.Cog; TooltipMain = "Settings"; TooltipSub = "Change your settings"; + + Hotkey = GlobalAction.ToggleSettings; } [BackgroundDependencyLoader(true)] diff --git a/osu.Game/Overlays/Toolbar/ToolbarSocialButton.cs b/osu.Game/Overlays/Toolbar/ToolbarSocialButton.cs index 0dbb552c15..6faa58c559 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarSocialButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarSocialButton.cs @@ -3,6 +3,7 @@ using osu.Framework.Allocation; using osu.Framework.Graphics.Sprites; +using osu.Game.Input.Bindings; namespace osu.Game.Overlays.Toolbar { @@ -13,6 +14,8 @@ namespace osu.Game.Overlays.Toolbar Icon = FontAwesome.Solid.Users; TooltipMain = "Friends"; TooltipSub = "Interact with those close to you"; + + Hotkey = GlobalAction.ToggleSocial; } [BackgroundDependencyLoader(true)] From d574cac702612dc4c36748588cebf4991d3ab64f Mon Sep 17 00:00:00 2001 From: Joehu Date: Thu, 6 Aug 2020 01:18:45 -0700 Subject: [PATCH 099/434] Add keybinding to toolbar button's tooltip --- osu.Game/Overlays/Toolbar/ToolbarButton.cs | 35 ++++++++++++++++++++-- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/osu.Game/Overlays/Toolbar/ToolbarButton.cs b/osu.Game/Overlays/Toolbar/ToolbarButton.cs index 3f1dccc45a..9fd47fd150 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarButton.cs @@ -1,6 +1,7 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using osu.Framework.Allocation; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -14,6 +15,7 @@ using osu.Game.Graphics.Backgrounds; using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; +using osu.Game.Input; using osu.Game.Input.Bindings; using osuTK; using osuTK.Graphics; @@ -70,8 +72,12 @@ namespace osu.Game.Overlays.Toolbar private readonly FillFlowContainer tooltipContainer; private readonly SpriteText tooltip1; private readonly SpriteText tooltip2; + private readonly SpriteText keyBindingTooltip; protected FillFlowContainer Flow; + [Resolved] + private KeyBindingStore store { get; set; } + protected ToolbarButton() : base(HoverSampleSet.Loud) { @@ -127,7 +133,7 @@ namespace osu.Game.Overlays.Toolbar Origin = TooltipAnchor, Position = new Vector2(TooltipAnchor.HasFlag(Anchor.x0) ? 5 : -5, 5), Alpha = 0, - Children = new[] + Children = new Drawable[] { tooltip1 = new OsuSpriteText { @@ -136,17 +142,40 @@ namespace osu.Game.Overlays.Toolbar Shadow = true, Font = OsuFont.GetFont(size: 22, weight: FontWeight.Bold), }, - tooltip2 = new OsuSpriteText + new FillFlowContainer { + AutoSizeAxes = Axes.Both, Anchor = TooltipAnchor, Origin = TooltipAnchor, - Shadow = true, + Direction = FillDirection.Horizontal, + Children = new[] + { + tooltip2 = new OsuSpriteText { Shadow = true }, + keyBindingTooltip = new OsuSpriteText { Shadow = true } + } } } } }; } + [BackgroundDependencyLoader] + private void load() + { + updateTooltip(); + + store.KeyBindingChanged += updateTooltip; + } + + private void updateTooltip() + { + var binding = store.Query().Find(b => (GlobalAction)b.Action == Hotkey); + + var keyBindingString = binding?.KeyCombination.ReadableString(); + + keyBindingTooltip.Text = !string.IsNullOrEmpty(keyBindingString) ? $" ({keyBindingString})" : string.Empty; + } + protected override bool OnMouseDown(MouseDownEvent e) => true; protected override bool OnClick(ClickEvent e) From f9c369b23cff9b0bdc1b8b7907ed74d8919bf123 Mon Sep 17 00:00:00 2001 From: Joehu Date: Thu, 6 Aug 2020 01:20:03 -0700 Subject: [PATCH 100/434] Fix toolbar music button tooltip overflowing off-screen --- osu.Game/Overlays/Toolbar/ToolbarMusicButton.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/osu.Game/Overlays/Toolbar/ToolbarMusicButton.cs b/osu.Game/Overlays/Toolbar/ToolbarMusicButton.cs index 59276a5943..f9aa2de497 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarMusicButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarMusicButton.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Allocation; +using osu.Framework.Graphics; using osu.Framework.Graphics.Sprites; using osu.Game.Input.Bindings; @@ -9,6 +10,8 @@ namespace osu.Game.Overlays.Toolbar { public class ToolbarMusicButton : ToolbarOverlayToggleButton { + protected override Anchor TooltipAnchor => Anchor.TopRight; + public ToolbarMusicButton() { Icon = FontAwesome.Solid.Music; From f53672193eb6ccd1d14c7900603aa5269e7468c9 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 6 Aug 2020 17:48:07 +0900 Subject: [PATCH 101/434] Fix track stores being kept alive --- osu.Game/Beatmaps/BeatmapManager.cs | 16 +++++++++++++++- .../Beatmaps/BeatmapManager_WorkingBeatmap.cs | 10 +++++++++- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index 6a7d0b053f..f22f41531a 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -219,6 +219,7 @@ namespace osu.Game.Beatmaps } private readonly WeakList workingCache = new WeakList(); + private readonly Dictionary referencedTrackStores = new Dictionary(); /// /// Retrieve a instance for the provided @@ -257,12 +258,25 @@ namespace osu.Game.Beatmaps textureStore ??= new LargeTextureStore(host?.CreateTextureLoaderStore(Files.Store)); trackStore ??= audioManager.GetTrackStore(Files.Store); - workingCache.Add(working = new BeatmapManagerWorkingBeatmap(Files.Store, textureStore, trackStore, beatmapInfo, audioManager)); + workingCache.Add(working = new BeatmapManagerWorkingBeatmap(Files.Store, textureStore, trackStore, beatmapInfo, audioManager, dereferenceTrackStore)); + referencedTrackStores[trackStore] = referencedTrackStores.GetOrDefault(trackStore) + 1; return working; } } + private void dereferenceTrackStore(ITrackStore trackStore) + { + lock (workingCache) + { + if (--referencedTrackStores[trackStore] == 0) + { + referencedTrackStores.Remove(trackStore); + trackStore.Dispose(); + } + } + } + /// /// Perform a lookup query on available s. /// diff --git a/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs b/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs index ceefef5d7e..a54d46c1b1 100644 --- a/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs @@ -23,11 +23,14 @@ namespace osu.Game.Beatmaps public readonly ITrackStore TrackStore; private readonly IResourceStore store; + private readonly Action dereferenceAction; - public BeatmapManagerWorkingBeatmap(IResourceStore store, TextureStore textureStore, ITrackStore trackStore, BeatmapInfo beatmapInfo, AudioManager audioManager) + public BeatmapManagerWorkingBeatmap(IResourceStore store, TextureStore textureStore, ITrackStore trackStore, BeatmapInfo beatmapInfo, AudioManager audioManager, + Action dereferenceAction) : base(beatmapInfo, audioManager) { this.store = store; + this.dereferenceAction = dereferenceAction; TextureStore = textureStore; TrackStore = trackStore; @@ -137,6 +140,11 @@ namespace osu.Game.Beatmaps return null; } } + + ~BeatmapManagerWorkingBeatmap() + { + dereferenceAction?.Invoke(TrackStore); + } } } } From c8ebbc8594b79423825614268feb88f2f20a32e6 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 6 Aug 2020 18:19:55 +0900 Subject: [PATCH 102/434] Remove MusicController from EditorClock --- .../Timelines/Summary/Parts/MarkerPart.cs | 5 +-- osu.Game/Screens/Edit/Editor.cs | 2 +- osu.Game/Screens/Edit/EditorClock.cs | 36 ++++++------------- 3 files changed, 13 insertions(+), 30 deletions(-) diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/MarkerPart.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/MarkerPart.cs index a353f79ef4..9e9ac93d23 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/MarkerPart.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/MarkerPart.cs @@ -2,7 +2,6 @@ // See the LICENCE file in the repository root for full licence text. using System; -using System.Diagnostics; using osuTK; using osu.Framework.Allocation; using osu.Framework.Graphics; @@ -59,9 +58,7 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts return; float markerPos = Math.Clamp(ToLocalSpace(screenPosition).X, 0, DrawWidth); - - Debug.Assert(editorClock.TrackLength != null); - editorClock.SeekTo(markerPos / DrawWidth * editorClock.TrackLength.Value); + editorClock.SeekTo(markerPos / DrawWidth * editorClock.TrackLength); }); } diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index b02aabc24d..79b13a7eac 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -84,7 +84,7 @@ namespace osu.Game.Screens.Edit // Todo: should probably be done at a DrawableRuleset level to share logic with Player. var sourceClock = (IAdjustableClock)musicController.CurrentTrack ?? new StopwatchClock(); - clock = new EditorClock(Beatmap.Value, beatDivisor) { IsCoupled = false }; + clock = new EditorClock(Beatmap.Value, musicController.CurrentTrack?.Length ?? 0, beatDivisor) { IsCoupled = false }; clock.ChangeSource(sourceClock); dependencies.CacheAs(clock); diff --git a/osu.Game/Screens/Edit/EditorClock.cs b/osu.Game/Screens/Edit/EditorClock.cs index 4e589aeeef..fbfa397795 100644 --- a/osu.Game/Screens/Edit/EditorClock.cs +++ b/osu.Game/Screens/Edit/EditorClock.cs @@ -2,16 +2,13 @@ // See the LICENCE file in the repository root for full licence text. using System; -using System.Diagnostics; using System.Linq; -using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Transforms; using osu.Framework.Utils; using osu.Framework.Timing; using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; -using osu.Game.Overlays; namespace osu.Game.Screens.Edit { @@ -20,7 +17,7 @@ namespace osu.Game.Screens.Edit /// public class EditorClock : Component, IFrameBasedClock, IAdjustableClock, ISourceChangeableClock { - public double? TrackLength { get; private set; } + public readonly double TrackLength; public ControlPointInfo ControlPointInfo; @@ -28,34 +25,24 @@ namespace osu.Game.Screens.Edit private readonly DecoupleableInterpolatingFramedClock underlyingClock; - [Resolved] - private MusicController musicController { get; set; } - - public EditorClock(WorkingBeatmap beatmap, BindableBeatDivisor beatDivisor) - : this(beatmap.Beatmap.ControlPointInfo, null, beatDivisor) + public EditorClock(WorkingBeatmap beatmap, double trackLength, BindableBeatDivisor beatDivisor) + : this(beatmap.Beatmap.ControlPointInfo, trackLength, beatDivisor) { } - public EditorClock(ControlPointInfo controlPointInfo, double? trackLength, BindableBeatDivisor beatDivisor) - { - this.beatDivisor = beatDivisor; - - ControlPointInfo = controlPointInfo; - TrackLength = trackLength; - - underlyingClock = new DecoupleableInterpolatingFramedClock(); - } - public EditorClock() : this(new ControlPointInfo(), 1000, new BindableBeatDivisor()) { } - [BackgroundDependencyLoader] - private void load() + public EditorClock(ControlPointInfo controlPointInfo, double trackLength, BindableBeatDivisor beatDivisor) { - // Todo: What. - TrackLength ??= musicController.CurrentTrack?.Length ?? 0; + this.beatDivisor = beatDivisor; + + ControlPointInfo = controlPointInfo; + TrackLength = trackLength; + + underlyingClock = new DecoupleableInterpolatingFramedClock(); } /// @@ -148,8 +135,7 @@ namespace osu.Game.Screens.Edit seekTime = timingPoint.Time; // Ensure the sought point is within the boundaries - Debug.Assert(TrackLength != null); - seekTime = Math.Clamp(seekTime, 0, TrackLength.Value); + seekTime = Math.Clamp(seekTime, 0, TrackLength); SeekTo(seekTime); } From 9685df0ecac3c264b6379a240c073473c4d410ac Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 6 Aug 2020 18:22:17 +0900 Subject: [PATCH 103/434] Only update key binding on next usage to avoid large blocking calls --- osu.Game/Overlays/Toolbar/ToolbarButton.cs | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/osu.Game/Overlays/Toolbar/ToolbarButton.cs b/osu.Game/Overlays/Toolbar/ToolbarButton.cs index 9fd47fd150..0afc6642b2 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarButton.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Allocation; +using osu.Framework.Caching; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -76,7 +77,7 @@ namespace osu.Game.Overlays.Toolbar protected FillFlowContainer Flow; [Resolved] - private KeyBindingStore store { get; set; } + private KeyBindingStore keyBindings { get; set; } protected ToolbarButton() : base(HoverSampleSet.Loud) @@ -159,21 +160,25 @@ namespace osu.Game.Overlays.Toolbar }; } + private readonly Cached tooltipKeyBinding = new Cached(); + [BackgroundDependencyLoader] private void load() { - updateTooltip(); - - store.KeyBindingChanged += updateTooltip; + keyBindings.KeyBindingChanged += () => tooltipKeyBinding.Invalidate(); + updateKeyBindingTooltip(); } - private void updateTooltip() + private void updateKeyBindingTooltip() { - var binding = store.Query().Find(b => (GlobalAction)b.Action == Hotkey); + if (tooltipKeyBinding.IsValid) + return; + var binding = keyBindings.Query().Find(b => (GlobalAction)b.Action == Hotkey); var keyBindingString = binding?.KeyCombination.ReadableString(); - keyBindingTooltip.Text = !string.IsNullOrEmpty(keyBindingString) ? $" ({keyBindingString})" : string.Empty; + + tooltipKeyBinding.Validate(); } protected override bool OnMouseDown(MouseDownEvent e) => true; @@ -187,6 +192,8 @@ namespace osu.Game.Overlays.Toolbar protected override bool OnHover(HoverEvent e) { + updateKeyBindingTooltip(); + HoverBackground.FadeIn(200); tooltipContainer.FadeIn(100); return base.OnHover(e); From 7c3ae4ed4291eeb86f704344956dedfef75e8735 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 6 Aug 2020 18:25:34 +0900 Subject: [PATCH 104/434] Remove generics from IApplicableToTrack --- osu.Game/Rulesets/Mods/IApplicableToTrack.cs | 3 +-- osu.Game/Rulesets/Mods/ModDaycore.cs | 7 ++++--- osu.Game/Rulesets/Mods/ModNightcore.cs | 6 +++--- osu.Game/Rulesets/Mods/ModRateAdjust.cs | 5 ++--- osu.Game/Rulesets/Mods/ModTimeRamp.cs | 3 +-- 5 files changed, 11 insertions(+), 13 deletions(-) diff --git a/osu.Game/Rulesets/Mods/IApplicableToTrack.cs b/osu.Game/Rulesets/Mods/IApplicableToTrack.cs index b29ba55942..9b840cea08 100644 --- a/osu.Game/Rulesets/Mods/IApplicableToTrack.cs +++ b/osu.Game/Rulesets/Mods/IApplicableToTrack.cs @@ -1,7 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using osu.Framework.Audio; using osu.Framework.Audio.Track; namespace osu.Game.Rulesets.Mods @@ -11,6 +10,6 @@ namespace osu.Game.Rulesets.Mods /// public interface IApplicableToTrack : IApplicableMod { - void ApplyToTrack(T track) where T : class, ITrack, IAdjustableAudioComponent; + void ApplyToTrack(ITrack track); } } diff --git a/osu.Game/Rulesets/Mods/ModDaycore.cs b/osu.Game/Rulesets/Mods/ModDaycore.cs index 989978eb35..800312d047 100644 --- a/osu.Game/Rulesets/Mods/ModDaycore.cs +++ b/osu.Game/Rulesets/Mods/ModDaycore.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Audio; +using osu.Framework.Audio.Track; using osu.Framework.Bindables; using osu.Framework.Graphics.Sprites; @@ -26,11 +27,11 @@ namespace osu.Game.Rulesets.Mods }, true); } - public override void ApplyToTrack(T track) + public override void ApplyToTrack(ITrack track) { // base.ApplyToTrack() intentionally not called (different tempo adjustment is applied) - track.AddAdjustment(AdjustableProperty.Frequency, freqAdjust); - track.AddAdjustment(AdjustableProperty.Tempo, tempoAdjust); + (track as IAdjustableAudioComponent)?.AddAdjustment(AdjustableProperty.Frequency, freqAdjust); + (track as IAdjustableAudioComponent)?.AddAdjustment(AdjustableProperty.Tempo, tempoAdjust); } } } diff --git a/osu.Game/Rulesets/Mods/ModNightcore.cs b/osu.Game/Rulesets/Mods/ModNightcore.cs index 70cdaa6345..4932df08f1 100644 --- a/osu.Game/Rulesets/Mods/ModNightcore.cs +++ b/osu.Game/Rulesets/Mods/ModNightcore.cs @@ -38,11 +38,11 @@ namespace osu.Game.Rulesets.Mods }, true); } - public override void ApplyToTrack(T track) + public override void ApplyToTrack(ITrack track) { // base.ApplyToTrack() intentionally not called (different tempo adjustment is applied) - track.AddAdjustment(AdjustableProperty.Frequency, freqAdjust); - track.AddAdjustment(AdjustableProperty.Tempo, tempoAdjust); + (track as IAdjustableAudioComponent)?.AddAdjustment(AdjustableProperty.Frequency, freqAdjust); + (track as IAdjustableAudioComponent)?.AddAdjustment(AdjustableProperty.Tempo, tempoAdjust); } public void ApplyToDrawableRuleset(DrawableRuleset drawableRuleset) diff --git a/osu.Game/Rulesets/Mods/ModRateAdjust.cs b/osu.Game/Rulesets/Mods/ModRateAdjust.cs index 4aee5affe9..ae7077c67b 100644 --- a/osu.Game/Rulesets/Mods/ModRateAdjust.cs +++ b/osu.Game/Rulesets/Mods/ModRateAdjust.cs @@ -12,10 +12,9 @@ namespace osu.Game.Rulesets.Mods { public abstract BindableNumber SpeedChange { get; } - public virtual void ApplyToTrack(T track) - where T : class, ITrack, IAdjustableAudioComponent + public virtual void ApplyToTrack(ITrack track) { - track.AddAdjustment(AdjustableProperty.Tempo, SpeedChange); + (track as IAdjustableAudioComponent)?.AddAdjustment(AdjustableProperty.Tempo, SpeedChange); } public virtual void ApplyToSample(SampleChannel sample) diff --git a/osu.Game/Rulesets/Mods/ModTimeRamp.cs b/osu.Game/Rulesets/Mods/ModTimeRamp.cs index 4b5241488f..b904cf007b 100644 --- a/osu.Game/Rulesets/Mods/ModTimeRamp.cs +++ b/osu.Game/Rulesets/Mods/ModTimeRamp.cs @@ -51,8 +51,7 @@ namespace osu.Game.Rulesets.Mods AdjustPitch.BindValueChanged(applyPitchAdjustment); } - public void ApplyToTrack(T track) - where T : class, ITrack, IAdjustableAudioComponent + public void ApplyToTrack(ITrack track) { this.track = track; From 2e3ecf71c70c035db37621df04cc289a4b7d7489 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 6 Aug 2020 18:31:08 +0900 Subject: [PATCH 105/434] Pass track from Player to components --- .../TestSceneGameplayClockContainer.cs | 7 +++++- .../Gameplay/TestSceneStoryboardSamples.cs | 6 +++-- .../Visual/Gameplay/TestSceneSkipOverlay.cs | 4 +++- osu.Game/Screens/Play/FailAnimation.cs | 16 ++++++-------- .../Screens/Play/GameplayClockContainer.cs | 22 +++++++++---------- osu.Game/Screens/Play/Player.cs | 11 +++++----- 6 files changed, 36 insertions(+), 30 deletions(-) diff --git a/osu.Game.Tests/Gameplay/TestSceneGameplayClockContainer.cs b/osu.Game.Tests/Gameplay/TestSceneGameplayClockContainer.cs index cd3669f160..40f6cecd9a 100644 --- a/osu.Game.Tests/Gameplay/TestSceneGameplayClockContainer.cs +++ b/osu.Game.Tests/Gameplay/TestSceneGameplayClockContainer.cs @@ -19,7 +19,12 @@ namespace osu.Game.Tests.Gameplay { GameplayClockContainer gcc = null; - AddStep("create container", () => Add(gcc = new GameplayClockContainer(CreateWorkingBeatmap(new OsuRuleset().RulesetInfo), Array.Empty(), 0))); + AddStep("create container", () => + { + var working = CreateWorkingBeatmap(new OsuRuleset().RulesetInfo); + Add(gcc = new GameplayClockContainer(working.GetRealTrack(), working, Array.Empty(), 0)); + }); + AddStep("start track", () => gcc.Start()); AddUntilStep("elapsed greater than zero", () => gcc.GameplayClock.ElapsedFrameTime > 0); } diff --git a/osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs b/osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs index b30870d057..720436fae4 100644 --- a/osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs +++ b/osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs @@ -59,7 +59,9 @@ namespace osu.Game.Tests.Gameplay AddStep("create container", () => { - Add(gameplayContainer = new GameplayClockContainer(CreateWorkingBeatmap(new OsuRuleset().RulesetInfo), Array.Empty(), 0)); + var working = CreateWorkingBeatmap(new OsuRuleset().RulesetInfo); + + Add(gameplayContainer = new GameplayClockContainer(working.GetRealTrack(), working, Array.Empty(), 0)); gameplayContainer.Add(sample = new DrawableStoryboardSample(new StoryboardSampleInfo(string.Empty, 0, 1)) { @@ -103,7 +105,7 @@ namespace osu.Game.Tests.Gameplay Beatmap.Value = new TestCustomSkinWorkingBeatmap(new OsuRuleset().RulesetInfo, Audio); SelectedMods.Value = new[] { testedMod }; - Add(gameplayContainer = new GameplayClockContainer(Beatmap.Value, SelectedMods.Value, 0)); + Add(gameplayContainer = new GameplayClockContainer(MusicController.CurrentTrack, Beatmap.Value, SelectedMods.Value, 0)); gameplayContainer.Add(sample = new TestDrawableStoryboardSample(new StoryboardSampleInfo("test-sample", 1, 1)) { diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSkipOverlay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSkipOverlay.cs index 7ed7a116b4..68110d759c 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSkipOverlay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSkipOverlay.cs @@ -32,7 +32,9 @@ namespace osu.Game.Tests.Visual.Gameplay requestCount = 0; increment = skip_time; - Child = gameplayClockContainer = new GameplayClockContainer(CreateWorkingBeatmap(CreateBeatmap(new OsuRuleset().RulesetInfo)), Array.Empty(), 0) + var working = CreateWorkingBeatmap(CreateBeatmap(new OsuRuleset().RulesetInfo)); + + Child = gameplayClockContainer = new GameplayClockContainer(working.GetRealTrack(), working, Array.Empty(), 0) { RelativeSizeAxes = Axes.Both, Children = new Drawable[] diff --git a/osu.Game/Screens/Play/FailAnimation.cs b/osu.Game/Screens/Play/FailAnimation.cs index 1171d8c3b0..a7bfca612e 100644 --- a/osu.Game/Screens/Play/FailAnimation.cs +++ b/osu.Game/Screens/Play/FailAnimation.cs @@ -8,11 +8,10 @@ using System; using System.Collections.Generic; using osu.Framework.Allocation; using osu.Framework.Audio.Sample; +using osu.Framework.Audio.Track; using osu.Framework.Graphics; -using osu.Framework.Graphics.Audio; using osu.Framework.Utils; using osu.Game.Beatmaps; -using osu.Game.Overlays; using osu.Game.Rulesets.Objects.Drawables; using osuTK; using osuTK.Graphics; @@ -28,24 +27,23 @@ namespace osu.Game.Screens.Play public Action OnComplete; private readonly DrawableRuleset drawableRuleset; + private readonly ITrack track; private readonly BindableDouble trackFreq = new BindableDouble(1); - private DrawableTrack track; - private const float duration = 2500; private SampleChannel failSample; - public FailAnimation(DrawableRuleset drawableRuleset) + public FailAnimation(DrawableRuleset drawableRuleset, ITrack track) { this.drawableRuleset = drawableRuleset; + this.track = track; } [BackgroundDependencyLoader] - private void load(AudioManager audio, IBindable beatmap, MusicController musicController) + private void load(AudioManager audio, IBindable beatmap) { - track = musicController.CurrentTrack; failSample = audio.Samples.Get(@"Gameplay/failsound"); } @@ -69,7 +67,7 @@ namespace osu.Game.Screens.Play Expire(); }); - track.AddAdjustment(AdjustableProperty.Frequency, trackFreq); + (track as IAdjustableAudioComponent)?.AddAdjustment(AdjustableProperty.Frequency, trackFreq); applyToPlayfield(drawableRuleset.Playfield); drawableRuleset.Playfield.HitObjectContainer.FlashColour(Color4.Red, 500); @@ -108,7 +106,7 @@ namespace osu.Game.Screens.Play protected override void Dispose(bool isDisposing) { base.Dispose(isDisposing); - track?.RemoveAdjustment(AdjustableProperty.Frequency, trackFreq); + (track as IAdjustableAudioComponent)?.RemoveAdjustment(AdjustableProperty.Frequency, trackFreq); } } } diff --git a/osu.Game/Screens/Play/GameplayClockContainer.cs b/osu.Game/Screens/Play/GameplayClockContainer.cs index 61272f56ad..c4f368e1f5 100644 --- a/osu.Game/Screens/Play/GameplayClockContainer.cs +++ b/osu.Game/Screens/Play/GameplayClockContainer.cs @@ -11,12 +11,10 @@ using osu.Framework.Audio; using osu.Framework.Audio.Track; using osu.Framework.Bindables; using osu.Framework.Graphics; -using osu.Framework.Graphics.Audio; using osu.Framework.Graphics.Containers; using osu.Framework.Timing; using osu.Game.Beatmaps; using osu.Game.Configuration; -using osu.Game.Overlays; using osu.Game.Rulesets.Mods; namespace osu.Game.Screens.Play @@ -29,7 +27,7 @@ namespace osu.Game.Screens.Play private readonly WorkingBeatmap beatmap; private readonly IReadOnlyList mods; - private DrawableTrack track; + private ITrack track; public readonly BindableBool IsPaused = new BindableBool(); @@ -62,11 +60,13 @@ namespace osu.Game.Screens.Play private readonly FramedOffsetClock platformOffsetClock; - public GameplayClockContainer(WorkingBeatmap beatmap, IReadOnlyList mods, double gameplayStartTime) + public GameplayClockContainer(ITrack track, WorkingBeatmap beatmap, IReadOnlyList mods, double gameplayStartTime) { this.beatmap = beatmap; this.mods = mods; this.gameplayStartTime = gameplayStartTime; + this.track = track; + firstHitObjectTime = beatmap.Beatmap.HitObjects.First().StartTime; RelativeSizeAxes = Axes.Both; @@ -96,10 +96,8 @@ namespace osu.Game.Screens.Play private readonly BindableDouble pauseFreqAdjust = new BindableDouble(1); [BackgroundDependencyLoader] - private void load(OsuConfigManager config, MusicController musicController) + private void load(OsuConfigManager config) { - track = musicController.CurrentTrack; - userAudioOffset = config.GetBindable(OsuSetting.AudioOffset); userAudioOffset.BindValueChanged(offset => userOffsetClock.Offset = offset.NewValue, true); @@ -132,7 +130,7 @@ namespace osu.Game.Screens.Play Schedule(() => { - adjustableClock.ChangeSource(track); + adjustableClock.ChangeSource((IAdjustableClock)track); updateRate(); if (!IsPaused.Value) @@ -203,8 +201,8 @@ namespace osu.Game.Screens.Play removeSourceClockAdjustments(); - track = new DrawableTrack(new TrackVirtual(track.Length)); - adjustableClock.ChangeSource(track); + track = new TrackVirtual(track.Length); + adjustableClock.ChangeSource((IAdjustableClock)track); } protected override void Update() @@ -224,8 +222,8 @@ namespace osu.Game.Screens.Play speedAdjustmentsApplied = true; track.ResetSpeedAdjustments(); - track.AddAdjustment(AdjustableProperty.Frequency, pauseFreqAdjust); - track.AddAdjustment(AdjustableProperty.Tempo, UserPlaybackRate); + (track as IAdjustableAudioComponent)?.AddAdjustment(AdjustableProperty.Frequency, pauseFreqAdjust); + (track as IAdjustableAudioComponent)?.AddAdjustment(AdjustableProperty.Tempo, UserPlaybackRate); foreach (var mod in mods.OfType()) mod.ApplyToTrack(track); diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 541275cf55..e92164de7c 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -8,6 +8,7 @@ using System.Linq; using osu.Framework.Allocation; using osu.Framework.Audio; using osu.Framework.Audio.Sample; +using osu.Framework.Audio.Track; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -150,7 +151,7 @@ namespace osu.Game.Screens.Play } [BackgroundDependencyLoader] - private void load(AudioManager audio, OsuConfigManager config) + private void load(AudioManager audio, OsuConfigManager config, MusicController musicController) { Mods.Value = base.Mods.Value.Select(m => m.CreateCopy()).ToArray(); @@ -178,7 +179,7 @@ namespace osu.Game.Screens.Play if (!ScoreProcessor.Mode.Disabled) config.BindWith(OsuSetting.ScoreDisplayMode, ScoreProcessor.Mode); - InternalChild = GameplayClockContainer = new GameplayClockContainer(Beatmap.Value, Mods.Value, DrawableRuleset.GameplayStartTime); + InternalChild = GameplayClockContainer = new GameplayClockContainer(musicController.CurrentTrack, Beatmap.Value, Mods.Value, DrawableRuleset.GameplayStartTime); AddInternal(gameplayBeatmap = new GameplayBeatmap(playableBeatmap)); AddInternal(screenSuspension = new ScreenSuspensionHandler(GameplayClockContainer)); @@ -187,7 +188,7 @@ namespace osu.Game.Screens.Play addUnderlayComponents(GameplayClockContainer); addGameplayComponents(GameplayClockContainer, Beatmap.Value, playableBeatmap); - addOverlayComponents(GameplayClockContainer, Beatmap.Value); + addOverlayComponents(GameplayClockContainer, Beatmap.Value, musicController.CurrentTrack); if (!DrawableRuleset.AllowGameplayOverlays) { @@ -264,7 +265,7 @@ namespace osu.Game.Screens.Play }); } - private void addOverlayComponents(Container target, WorkingBeatmap working) + private void addOverlayComponents(Container target, WorkingBeatmap working, ITrack track) { target.AddRange(new[] { @@ -331,7 +332,7 @@ namespace osu.Game.Screens.Play performImmediateExit(); }, }, - failAnimation = new FailAnimation(DrawableRuleset) { OnComplete = onFailComplete, }, + failAnimation = new FailAnimation(DrawableRuleset, track) { OnComplete = onFailComplete, }, }); } From ef689d943aafc413dac909da50d96532816abd6c Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 6 Aug 2020 18:54:08 +0900 Subject: [PATCH 106/434] Fix intros playing incorrectly --- osu.Game/OsuGame.cs | 4 ++-- osu.Game/Screens/Menu/IntroScreen.cs | 13 +++++++------ osu.Game/Screens/Menu/IntroTriangles.cs | 2 +- osu.Game/Screens/Menu/IntroWelcome.cs | 9 ++------- 4 files changed, 12 insertions(+), 16 deletions(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index a41c7b28a5..0049e5a520 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -581,6 +581,8 @@ namespace osu.Game ScreenStack.ScreenPushed += screenPushed; ScreenStack.ScreenExited += screenExited; + loadComponentSingleFile(MusicController, Add); + loadComponentSingleFile(osuLogo, logo => { logoContainer.Add(logo); @@ -602,8 +604,6 @@ namespace osu.Game loadComponentSingleFile(new OnScreenDisplay(), Add, true); - loadComponentSingleFile(MusicController, Add); - loadComponentSingleFile(notifications.With(d => { d.GetToolbarHeight = () => ToolbarOffset; diff --git a/osu.Game/Screens/Menu/IntroScreen.cs b/osu.Game/Screens/Menu/IntroScreen.cs index 030923c228..7e327261ab 100644 --- a/osu.Game/Screens/Menu/IntroScreen.cs +++ b/osu.Game/Screens/Menu/IntroScreen.cs @@ -44,8 +44,7 @@ namespace osu.Game.Screens.Menu private WorkingBeatmap initialBeatmap; - [Resolved] - protected MusicController MusicController { get; private set; } + protected ITrack Track { get; private set; } private readonly BindableDouble exitingVolumeFade = new BindableDouble(1); @@ -62,6 +61,9 @@ namespace osu.Game.Screens.Menu [Resolved] private AudioManager audio { get; set; } + [Resolved] + private MusicController musicController { get; set; } + /// /// Whether the is provided by osu! resources, rather than a user beatmap. /// @@ -113,9 +115,7 @@ namespace osu.Game.Screens.Menu if (setInfo != null) { initialBeatmap = beatmaps.GetWorkingBeatmap(setInfo.Beatmaps[0]); - - // Todo: Wrong. - UsingThemedIntro = MusicController.CurrentTrack?.IsDummyDevice == false; + UsingThemedIntro = initialBeatmap.GetRealTrack().IsDummyDevice == false; } return UsingThemedIntro; @@ -154,7 +154,7 @@ namespace osu.Game.Screens.Menu { // Only start the current track if it is the menu music. A beatmap's track is started when entering the Main Menu. if (UsingThemedIntro) - MusicController.Play(true); + Track.Restart(); } protected override void LogoArriving(OsuLogo logo, bool resuming) @@ -168,6 +168,7 @@ namespace osu.Game.Screens.Menu if (!resuming) { beatmap.Value = initialBeatmap; + Track = musicController.CurrentTrack; logo.MoveTo(new Vector2(0.5f)); logo.ScaleTo(Vector2.One); diff --git a/osu.Game/Screens/Menu/IntroTriangles.cs b/osu.Game/Screens/Menu/IntroTriangles.cs index e29ea6e743..86f7dbdd6f 100644 --- a/osu.Game/Screens/Menu/IntroTriangles.cs +++ b/osu.Game/Screens/Menu/IntroTriangles.cs @@ -59,7 +59,7 @@ namespace osu.Game.Screens.Menu LoadComponentAsync(new TrianglesIntroSequence(logo, background) { RelativeSizeAxes = Axes.Both, - Clock = new FramedClock(UsingThemedIntro ? MusicController.CurrentTrack : null), + Clock = new FramedClock(UsingThemedIntro ? (IAdjustableClock)Track : null), LoadMenu = LoadMenu }, t => { diff --git a/osu.Game/Screens/Menu/IntroWelcome.cs b/osu.Game/Screens/Menu/IntroWelcome.cs index 85f11eb244..e81646456f 100644 --- a/osu.Game/Screens/Menu/IntroWelcome.cs +++ b/osu.Game/Screens/Menu/IntroWelcome.cs @@ -11,7 +11,6 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Textures; -using osu.Game.Overlays; using osu.Game.Screens.Backgrounds; using osuTK.Graphics; @@ -31,9 +30,6 @@ namespace osu.Game.Screens.Menu Alpha = 0, }; - [Resolved] - private MusicController musicController { get; set; } - private BackgroundScreenDefault background; [BackgroundDependencyLoader] @@ -43,9 +39,6 @@ namespace osu.Game.Screens.Menu welcome = audio.Samples.Get(@"Intro/Welcome/welcome"); pianoReverb = audio.Samples.Get(@"Intro/Welcome/welcome_piano"); - - if (musicController.CurrentTrack != null) - musicController.CurrentTrack.Looping = true; } protected override void LogoArriving(OsuLogo logo, bool resuming) @@ -54,6 +47,8 @@ namespace osu.Game.Screens.Menu if (!resuming) { + Track.Looping = true; + LoadComponentAsync(new WelcomeIntroSequence { RelativeSizeAxes = Axes.Both From f8279dab328d758f2a590924de44a8a8921ca595 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 6 Aug 2020 18:54:14 +0900 Subject: [PATCH 107/434] Refactor MainMenu --- osu.Game/Screens/Menu/MainMenu.cs | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/osu.Game/Screens/Menu/MainMenu.cs b/osu.Game/Screens/Menu/MainMenu.cs index ce48777ce1..ea4347a285 100644 --- a/osu.Game/Screens/Menu/MainMenu.cs +++ b/osu.Game/Screens/Menu/MainMenu.cs @@ -170,9 +170,6 @@ namespace osu.Game.Screens.Menu [Resolved] private Storage storage { get; set; } - [Resolved] - private MusicController musicController { get; set; } - public override void OnEntering(IScreen last) { base.OnEntering(last); @@ -180,14 +177,14 @@ namespace osu.Game.Screens.Menu var metadata = Beatmap.Value.Metadata; - if (last is IntroScreen && musicController.TrackLoaded) + if (last is IntroScreen && music.TrackLoaded) { - Debug.Assert(musicController.CurrentTrack != null); + Debug.Assert(music.CurrentTrack != null); - if (!musicController.CurrentTrack.IsRunning) + if (!music.CurrentTrack.IsRunning) { - musicController.CurrentTrack.Seek(metadata.PreviewTime != -1 ? metadata.PreviewTime : 0.4f * musicController.CurrentTrack.Length); - musicController.CurrentTrack.Start(); + music.CurrentTrack.Seek(metadata.PreviewTime != -1 ? metadata.PreviewTime : 0.4f * music.CurrentTrack.Length); + music.CurrentTrack.Start(); } } From adf4f56dce1871816e29bde01e51fe78a77397ab Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 6 Aug 2020 19:01:23 +0900 Subject: [PATCH 108/434] Move MusicController to OsuGameBase --- osu.Game/OsuGame.cs | 5 ----- osu.Game/OsuGameBase.cs | 6 ++++++ 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 0049e5a520..cf4610793c 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -538,7 +538,6 @@ namespace osu.Game Container logoContainer; BackButton.Receptor receptor; - dependencies.CacheAs(MusicController = new MusicController()); dependencies.CacheAs(idleTracker = new GameIdleTracker(6000)); AddRange(new Drawable[] @@ -581,8 +580,6 @@ namespace osu.Game ScreenStack.ScreenPushed += screenPushed; ScreenStack.ScreenExited += screenExited; - loadComponentSingleFile(MusicController, Add); - loadComponentSingleFile(osuLogo, logo => { logoContainer.Add(logo); @@ -925,8 +922,6 @@ namespace osu.Game private ScalingContainer screenContainer; - protected MusicController MusicController { get; private set; } - protected override bool OnExiting() { if (ScreenStack.CurrentScreen is Loader) diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index 24c1f7849c..51b9b7278d 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -30,6 +30,7 @@ using osu.Game.Database; using osu.Game.Input; using osu.Game.Input.Bindings; using osu.Game.IO; +using osu.Game.Overlays; using osu.Game.Resources; using osu.Game.Rulesets; using osu.Game.Rulesets.Mods; @@ -73,6 +74,8 @@ namespace osu.Game protected MenuCursorContainer MenuCursorContainer; + protected MusicController MusicController; + private Container content; protected override Container Content => content; @@ -265,6 +268,9 @@ namespace osu.Game dependencies.Cache(previewTrackManager = new PreviewTrackManager()); Add(previewTrackManager); + AddInternal(MusicController = new MusicController()); + dependencies.CacheAs(MusicController); + Ruleset.BindValueChanged(onRulesetChanged); } From 4cfca71d080822734e7f29de27b5273f3304460a Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 6 Aug 2020 19:05:15 +0900 Subject: [PATCH 109/434] Fix a few test scenes --- osu.Game/Tests/Visual/RateAdjustedBeatmapTestScene.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/osu.Game/Tests/Visual/RateAdjustedBeatmapTestScene.cs b/osu.Game/Tests/Visual/RateAdjustedBeatmapTestScene.cs index ae4b0ef84a..a6266d210c 100644 --- a/osu.Game/Tests/Visual/RateAdjustedBeatmapTestScene.cs +++ b/osu.Game/Tests/Visual/RateAdjustedBeatmapTestScene.cs @@ -1,6 +1,7 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System.Diagnostics; using osu.Framework.Extensions.ObjectExtensions; namespace osu.Game.Tests.Visual @@ -15,7 +16,11 @@ namespace osu.Game.Tests.Visual base.Update(); // note that this will override any mod rate application - MusicController.CurrentTrack.AsNonNull().Tempo.Value = Clock.Rate; + if (MusicController.TrackLoaded) + { + Debug.Assert(MusicController.CurrentTrack != null); + MusicController.CurrentTrack.Tempo.Value = Clock.Rate; + } } } } From d1af1429b3dd8d79ba36bc5d41ac02a75ad86bac Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 6 Aug 2020 19:08:45 +0900 Subject: [PATCH 110/434] Fix inspection --- osu.Game/Tests/Visual/RateAdjustedBeatmapTestScene.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Tests/Visual/RateAdjustedBeatmapTestScene.cs b/osu.Game/Tests/Visual/RateAdjustedBeatmapTestScene.cs index a6266d210c..54458716b1 100644 --- a/osu.Game/Tests/Visual/RateAdjustedBeatmapTestScene.cs +++ b/osu.Game/Tests/Visual/RateAdjustedBeatmapTestScene.cs @@ -2,7 +2,6 @@ // See the LICENCE file in the repository root for full licence text. using System.Diagnostics; -using osu.Framework.Extensions.ObjectExtensions; namespace osu.Game.Tests.Visual { From e3105fd4c80caec86c086e66b5bad55d2f5d29c5 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 6 Aug 2020 19:16:26 +0900 Subject: [PATCH 111/434] Add more resilient logic for whether to avoid playing SkinnableSound on no volume --- .../Objects/Drawables/DrawableSpinner.cs | 6 ++---- osu.Game/Screens/Play/PauseOverlay.cs | 8 ++------ osu.Game/Skinning/SkinnableSound.cs | 12 +++++++++++- 3 files changed, 15 insertions(+), 11 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs index 7363da0de8..b74a9c7197 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs @@ -82,8 +82,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables private SkinnableSound spinningSample; - private const float minimum_volume = 0.0001f; - protected override void LoadSamples() { base.LoadSamples(); @@ -100,7 +98,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables AddInternal(spinningSample = new SkinnableSound(clone) { - Volume = { Value = minimum_volume }, + Volume = { Value = 0 }, Looping = true, }); } @@ -118,7 +116,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables } else { - spinningSample?.VolumeTo(minimum_volume, 200).Finally(_ => spinningSample.Stop()); + spinningSample?.VolumeTo(0, 200).Finally(_ => spinningSample.Stop()); } } diff --git a/osu.Game/Screens/Play/PauseOverlay.cs b/osu.Game/Screens/Play/PauseOverlay.cs index fa917cda32..3cdc558951 100644 --- a/osu.Game/Screens/Play/PauseOverlay.cs +++ b/osu.Game/Screens/Play/PauseOverlay.cs @@ -25,8 +25,6 @@ namespace osu.Game.Screens.Play protected override Action BackAction => () => InternalButtons.Children.First().Click(); - private const float minimum_volume = 0.0001f; - [BackgroundDependencyLoader] private void load(OsuColour colours) { @@ -37,10 +35,8 @@ namespace osu.Game.Screens.Play AddInternal(pauseLoop = new SkinnableSound(new SampleInfo("pause-loop")) { Looping = true, + Volume = { Value = 0 } }); - - // SkinnableSound only plays a sound if its aggregate volume is > 0, so the volume must be turned up before playing it - pauseLoop.VolumeTo(minimum_volume); } protected override void PopIn() @@ -55,7 +51,7 @@ namespace osu.Game.Screens.Play { base.PopOut(); - pauseLoop.VolumeTo(minimum_volume, TRANSITION_DURATION, Easing.OutQuad).Finally(_ => pauseLoop.Stop()); + pauseLoop.VolumeTo(0, TRANSITION_DURATION, Easing.OutQuad).Finally(_ => pauseLoop.Stop()); } } } diff --git a/osu.Game/Skinning/SkinnableSound.cs b/osu.Game/Skinning/SkinnableSound.cs index 27f6c37895..8c18e83e92 100644 --- a/osu.Game/Skinning/SkinnableSound.cs +++ b/osu.Game/Skinning/SkinnableSound.cs @@ -28,6 +28,16 @@ namespace osu.Game.Skinning public override bool RemoveWhenNotAlive => false; public override bool RemoveCompletedTransforms => false; + /// + /// Whether to play the underlying sample when aggregate volume is zero. + /// Note that this is checked at the point of calling ; changing the volume post-play will not begin playback. + /// Defaults to false unless . + /// + /// + /// Can serve as an optimisation if it is known ahead-of-time that this behaviour will not negatively affect behaviour. + /// + protected bool SkipPlayWhenZeroVolume => !Looping; + private readonly AudioContainer samplesContainer; public SkinnableSound(ISampleInfo hitSamples) @@ -87,7 +97,7 @@ namespace osu.Game.Skinning { samplesContainer.ForEach(c => { - if (c.AggregateVolume.Value > 0) + if (!SkipPlayWhenZeroVolume || c.AggregateVolume.Value > 0) c.Play(); }); } From f994bf28884b66d7efc4654c50ebbb961640ecb0 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 6 Aug 2020 21:34:48 +0900 Subject: [PATCH 112/434] Update framework --- osu.Android.props | 2 +- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index 924e9c4a16..e5fed09c07 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -52,6 +52,6 @@ - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 627c2f3d33..18c3052ca3 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -24,7 +24,7 @@ - + diff --git a/osu.iOS.props b/osu.iOS.props index f443937017..b034253d88 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -70,7 +70,7 @@ - + @@ -80,7 +80,7 @@ - + From c84452cfbfdb8e72424702ee1e25cea82aa39606 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 6 Aug 2020 21:53:20 +0900 Subject: [PATCH 113/434] Update usages --- osu.Game/Rulesets/UI/DrawableRulesetDependencies.cs | 2 ++ osu.Game/Skinning/SkinnableSound.cs | 9 +++++---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/osu.Game/Rulesets/UI/DrawableRulesetDependencies.cs b/osu.Game/Rulesets/UI/DrawableRulesetDependencies.cs index 168e937256..83a1077d70 100644 --- a/osu.Game/Rulesets/UI/DrawableRulesetDependencies.cs +++ b/osu.Game/Rulesets/UI/DrawableRulesetDependencies.cs @@ -117,6 +117,8 @@ namespace osu.Game.Rulesets.UI public void RemoveAdjustment(AdjustableProperty type, BindableNumber adjustBindable) => throw new NotSupportedException(); + public void RemoveAllAdjustments(AdjustableProperty type) => throw new NotSupportedException(); + public BindableNumber Volume => throw new NotSupportedException(); public BindableNumber Balance => throw new NotSupportedException(); diff --git a/osu.Game/Skinning/SkinnableSound.cs b/osu.Game/Skinning/SkinnableSound.cs index 27f6c37895..f19aaee821 100644 --- a/osu.Game/Skinning/SkinnableSound.cs +++ b/osu.Game/Skinning/SkinnableSound.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Linq; using osu.Framework.Allocation; +using osu.Framework.Audio; using osu.Framework.Audio.Track; using osu.Framework.Bindables; using osu.Framework.Extensions.IEnumerableExtensions; @@ -149,28 +150,28 @@ namespace osu.Game.Skinning /// Smoothly adjusts over time. /// /// A to which further transforms can be added. - public TransformSequence VolumeTo(double newVolume, double duration = 0, Easing easing = Easing.None) => + public TransformSequence> VolumeTo(double newVolume, double duration = 0, Easing easing = Easing.None) => samplesContainer.VolumeTo(newVolume, duration, easing); /// /// Smoothly adjusts over time. /// /// A to which further transforms can be added. - public TransformSequence BalanceTo(double newBalance, double duration = 0, Easing easing = Easing.None) => + public TransformSequence> BalanceTo(double newBalance, double duration = 0, Easing easing = Easing.None) => samplesContainer.BalanceTo(newBalance, duration, easing); /// /// Smoothly adjusts over time. /// /// A to which further transforms can be added. - public TransformSequence FrequencyTo(double newFrequency, double duration = 0, Easing easing = Easing.None) => + public TransformSequence> FrequencyTo(double newFrequency, double duration = 0, Easing easing = Easing.None) => samplesContainer.FrequencyTo(newFrequency, duration, easing); /// /// Smoothly adjusts over time. /// /// A to which further transforms can be added. - public TransformSequence TempoTo(double newTempo, double duration = 0, Easing easing = Easing.None) => + public TransformSequence> TempoTo(double newTempo, double duration = 0, Easing easing = Easing.None) => samplesContainer.TempoTo(newTempo, duration, easing); #endregion From bce3f3952fbc1154b74d190b2947624b1558c574 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 7 Aug 2020 16:36:40 +0900 Subject: [PATCH 114/434] Split out variable declaration --- osu.Game.Rulesets.Osu/Skinning/LegacyMainCirclePiece.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Skinning/LegacyMainCirclePiece.cs b/osu.Game.Rulesets.Osu/Skinning/LegacyMainCirclePiece.cs index 9fbd9f50b4..0ab3e8825b 100644 --- a/osu.Game.Rulesets.Osu/Skinning/LegacyMainCirclePiece.cs +++ b/osu.Game.Rulesets.Osu/Skinning/LegacyMainCirclePiece.cs @@ -30,7 +30,8 @@ namespace osu.Game.Rulesets.Osu.Skinning } private Container circleSprites; - private Sprite hitCircleSprite, hitCircleOverlay; + private Sprite hitCircleSprite; + private Sprite hitCircleOverlay; private SkinnableSpriteText hitCircleText; From 2e0f567d5def9ce469170c00f4d1c7caa4c0f43f Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Fri, 7 Aug 2020 11:33:02 +0300 Subject: [PATCH 115/434] Implement HomeNewsPanel component --- .../Visual/Online/TestSceneHomeNewsPanel.cs | 38 +++ osu.Game/Overlays/Dashboard/Home/HomePanel.cs | 58 +++++ .../Dashboard/Home/News/HomeNewsPanel.cs | 240 ++++++++++++++++++ osu.Game/Overlays/News/NewsCard.cs | 34 +-- osu.Game/Overlays/News/NewsPostBackground.cs | 37 +++ 5 files changed, 375 insertions(+), 32 deletions(-) create mode 100644 osu.Game.Tests/Visual/Online/TestSceneHomeNewsPanel.cs create mode 100644 osu.Game/Overlays/Dashboard/Home/HomePanel.cs create mode 100644 osu.Game/Overlays/Dashboard/Home/News/HomeNewsPanel.cs create mode 100644 osu.Game/Overlays/News/NewsPostBackground.cs diff --git a/osu.Game.Tests/Visual/Online/TestSceneHomeNewsPanel.cs b/osu.Game.Tests/Visual/Online/TestSceneHomeNewsPanel.cs new file mode 100644 index 0000000000..262bc51cd8 --- /dev/null +++ b/osu.Game.Tests/Visual/Online/TestSceneHomeNewsPanel.cs @@ -0,0 +1,38 @@ +// 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.Framework.Graphics; +using osu.Game.Online.API.Requests.Responses; +using osu.Framework.Allocation; +using osu.Game.Overlays; +using System; +using osu.Game.Overlays.Dashboard.Home.News; + +namespace osu.Game.Tests.Visual.Online +{ + public class TestSceneHomeNewsPanel : OsuTestScene + { + [Cached] + private readonly OverlayColourProvider overlayColour = new OverlayColourProvider(OverlayColourScheme.Purple); + + public TestSceneHomeNewsPanel() + { + Add(new Container + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + AutoSizeAxes = Axes.Y, + Width = 500, + Child = new HomeNewsPanel(new APINewsPost + { + Title = "This post has an image which starts with \"/\" and has many authors!", + Preview = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.", + FirstImage = "/help/wiki/shared/news/banners/monthly-beatmapping-contest.png", + PublishedAt = DateTimeOffset.Now, + Slug = "2020-07-16-summer-theme-park-2020-voting-open" + }) + }); + } + } +} diff --git a/osu.Game/Overlays/Dashboard/Home/HomePanel.cs b/osu.Game/Overlays/Dashboard/Home/HomePanel.cs new file mode 100644 index 0000000000..bbe7e411fd --- /dev/null +++ b/osu.Game/Overlays/Dashboard/Home/HomePanel.cs @@ -0,0 +1,58 @@ +// 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.Extensions.Color4Extensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Effects; +using osu.Framework.Graphics.Shapes; +using osuTK; +using osuTK.Graphics; + +namespace osu.Game.Overlays.Dashboard.Home +{ + public class HomePanel : Container + { + protected override Container Content => content; + + [Resolved] + protected OverlayColourProvider ColourProvider { get; private set; } + + private readonly Container content; + private readonly Box background; + + public HomePanel() + { + RelativeSizeAxes = Axes.X; + AutoSizeAxes = Axes.Y; + Masking = true; + EdgeEffect = new EdgeEffectParameters + { + Colour = Color4.Black.Opacity(0.25f), + Type = EdgeEffectType.Shadow, + Radius = 3, + Offset = new Vector2(0, 1) + }; + + AddRangeInternal(new Drawable[] + { + background = new Box + { + RelativeSizeAxes = Axes.Both + }, + content = new Container + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y + } + }); + } + + [BackgroundDependencyLoader] + private void load() + { + background.Colour = ColourProvider.Background4; + } + } +} diff --git a/osu.Game/Overlays/Dashboard/Home/News/HomeNewsPanel.cs b/osu.Game/Overlays/Dashboard/Home/News/HomeNewsPanel.cs new file mode 100644 index 0000000000..85e31b3034 --- /dev/null +++ b/osu.Game/Overlays/Dashboard/Home/News/HomeNewsPanel.cs @@ -0,0 +1,240 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System; +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Cursor; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Platform; +using osu.Game.Graphics; +using osu.Game.Graphics.Containers; +using osu.Game.Graphics.Sprites; +using osu.Game.Online.API.Requests.Responses; +using osu.Game.Overlays.News; +using osuTK; +using osuTK.Graphics; + +namespace osu.Game.Overlays.Dashboard.Home.News +{ + public class HomeNewsPanel : HomePanel + { + private readonly APINewsPost post; + + public HomeNewsPanel(APINewsPost post) + { + this.post = post; + } + + [BackgroundDependencyLoader] + private void load() + { + Children = new Drawable[] + { + new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Vertical, + Children = new Drawable[] + { + new ClickableNewsBackground(post), + new GridContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + ColumnDimensions = new[] + { + new Dimension(GridSizeMode.AutoSize), + new Dimension() + }, + RowDimensions = new[] + { + new Dimension(GridSizeMode.AutoSize) + }, + Content = new[] + { + new Drawable[] + { + new Container + { + RelativeSizeAxes = Axes.Y, + Width = 80, + Padding = new MarginPadding(10), + Children = new Drawable[] + { + new Box + { + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, + RelativeSizeAxes = Axes.Y, + Width = 1, + Colour = ColourProvider.Light1 + }, + new Container + { + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, + AutoSizeAxes = Axes.Both, + Padding = new MarginPadding { Right = 11 }, + Child = new DateContainer(post.PublishedAt) + } + } + }, + new Container + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Padding = new MarginPadding { Right = 10 }, + Children = new Drawable[] + { + new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Margin = new MarginPadding { Top = 5, Bottom = 10 }, + Spacing = new Vector2(0, 10), + Direction = FillDirection.Vertical, + Children = new Drawable[] + { + new TitleLink(post), + new TextFlowContainer(f => + { + f.Font = OsuFont.GetFont(size: 12, weight: FontWeight.Regular); + }) + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Text = post.Preview + } + } + } + } + } + } + } + } + } + } + }; + } + + private class ClickableNewsBackground : OsuHoverContainer + { + private readonly APINewsPost post; + + public ClickableNewsBackground(APINewsPost post) + { + this.post = post; + + RelativeSizeAxes = Axes.X; + Height = 130; + } + + [BackgroundDependencyLoader] + private void load(GameHost host) + { + NewsPostBackground bg; + + Child = new DelayedLoadWrapper(bg = new NewsPostBackground(post.FirstImage) + { + RelativeSizeAxes = Axes.Both, + FillMode = FillMode.Fill, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Alpha = 0 + }) + { + RelativeSizeAxes = Axes.Both + }; + + bg.OnLoadComplete += d => d.FadeIn(250, Easing.In); + + TooltipText = "view in browser"; + Action = () => host.OpenUrlExternally("https://osu.ppy.sh/home/news/" + post.Slug); + + HoverColour = Color4.White; + } + } + + private class TitleLink : OsuHoverContainer + { + private readonly APINewsPost post; + + public TitleLink(APINewsPost post) + { + this.post = post; + + RelativeSizeAxes = Axes.X; + AutoSizeAxes = Axes.Y; + } + + [BackgroundDependencyLoader] + private void load(GameHost host) + { + Child = new TextFlowContainer(t => + { + t.Font = OsuFont.GetFont(weight: FontWeight.Bold); + }) + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Text = post.Title + }; + + TooltipText = "view in browser"; + Action = () => host.OpenUrlExternally("https://osu.ppy.sh/home/news/" + post.Slug); + } + } + + private class DateContainer : CompositeDrawable, IHasCustomTooltip + { + public ITooltip GetCustomTooltip() => new DateTooltip(); + + public object TooltipContent => date; + + private readonly DateTimeOffset date; + + public DateContainer(DateTimeOffset date) + { + this.date = date; + } + + [BackgroundDependencyLoader] + private void load(OverlayColourProvider colourProvider) + { + AutoSizeAxes = Axes.Both; + InternalChild = new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Vertical, + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, + Children = new Drawable[] + { + new OsuSpriteText + { + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, + Font = OsuFont.GetFont(weight: FontWeight.Bold), // using Bold since there is no 800 weight alternative + Colour = colourProvider.Light1, + Text = date.Day.ToString() + }, + new TextFlowContainer(f => + { + f.Font = OsuFont.GetFont(size: 11, weight: FontWeight.Regular); + f.Colour = colourProvider.Light1; + }) + { + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, + AutoSizeAxes = Axes.Both, + Text = $"{date:MMM yyyy}" + } + } + }; + } + } + } +} diff --git a/osu.Game/Overlays/News/NewsCard.cs b/osu.Game/Overlays/News/NewsCard.cs index 201c3ce826..599b45fa78 100644 --- a/osu.Game/Overlays/News/NewsCard.cs +++ b/osu.Game/Overlays/News/NewsCard.cs @@ -9,8 +9,6 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Cursor; using osu.Framework.Graphics.Shapes; -using osu.Framework.Graphics.Sprites; -using osu.Framework.Graphics.Textures; using osu.Framework.Input.Events; using osu.Framework.Platform; using osu.Game.Graphics; @@ -48,7 +46,7 @@ namespace osu.Game.Overlays.News Action = () => host.OpenUrlExternally("https://osu.ppy.sh/home/news/" + post.Slug); } - NewsBackground bg; + NewsPostBackground bg; AddRange(new Drawable[] { background = new Box @@ -70,7 +68,7 @@ namespace osu.Game.Overlays.News CornerRadius = 6, Children = new Drawable[] { - new DelayedLoadWrapper(bg = new NewsBackground(post.FirstImage) + new DelayedLoadWrapper(bg = new NewsPostBackground(post.FirstImage) { RelativeSizeAxes = Axes.Both, FillMode = FillMode.Fill, @@ -123,34 +121,6 @@ namespace osu.Game.Overlays.News main.AddText(post.Author, t => t.Font = OsuFont.GetFont(size: 12, weight: FontWeight.SemiBold)); } - [LongRunningLoad] - private class NewsBackground : Sprite - { - private readonly string sourceUrl; - - public NewsBackground(string sourceUrl) - { - this.sourceUrl = sourceUrl; - } - - [BackgroundDependencyLoader] - private void load(LargeTextureStore store) - { - Texture = store.Get(createUrl(sourceUrl)); - } - - private string createUrl(string source) - { - if (string.IsNullOrEmpty(source)) - return "Headers/news"; - - if (source.StartsWith('/')) - return "https://osu.ppy.sh" + source; - - return source; - } - } - private class DateContainer : CircularContainer, IHasCustomTooltip { public ITooltip GetCustomTooltip() => new DateTooltip(); diff --git a/osu.Game/Overlays/News/NewsPostBackground.cs b/osu.Game/Overlays/News/NewsPostBackground.cs new file mode 100644 index 0000000000..386ef7f669 --- /dev/null +++ b/osu.Game/Overlays/News/NewsPostBackground.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.Graphics.Sprites; +using osu.Framework.Graphics.Textures; + +namespace osu.Game.Overlays.News +{ + [LongRunningLoad] + public class NewsPostBackground : Sprite + { + private readonly string sourceUrl; + + public NewsPostBackground(string sourceUrl) + { + this.sourceUrl = sourceUrl; + } + + [BackgroundDependencyLoader] + private void load(LargeTextureStore store) + { + Texture = store.Get(createUrl(sourceUrl)); + } + + private string createUrl(string source) + { + if (string.IsNullOrEmpty(source)) + return "Headers/news"; + + if (source.StartsWith('/')) + return "https://osu.ppy.sh" + source; + + return source; + } + } +} From 76d35a7667eb082d6917e1e032ab3d9f418b905d Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Fri, 7 Aug 2020 12:59:45 +0300 Subject: [PATCH 116/434] Implement HomeNewsGroupPanel --- .../Visual/Online/TestSceneHomeNewsPanel.cs | 38 ++++- osu.Game/Overlays/Dashboard/Home/HomePanel.cs | 7 +- .../Dashboard/Home/News/HomeNewsGroupPanel.cs | 85 ++++++++++ .../Dashboard/Home/News/HomeNewsPanel.cs | 152 ++++-------------- .../Home/News/HomeNewsPanelFooter.cs | 79 +++++++++ .../Home/News/NewsPostDrawableDate.cs | 37 +++++ .../Dashboard/Home/News/NewsTitleLink.cs | 43 +++++ 7 files changed, 311 insertions(+), 130 deletions(-) create mode 100644 osu.Game/Overlays/Dashboard/Home/News/HomeNewsGroupPanel.cs create mode 100644 osu.Game/Overlays/Dashboard/Home/News/HomeNewsPanelFooter.cs create mode 100644 osu.Game/Overlays/Dashboard/Home/News/NewsPostDrawableDate.cs create mode 100644 osu.Game/Overlays/Dashboard/Home/News/NewsTitleLink.cs diff --git a/osu.Game.Tests/Visual/Online/TestSceneHomeNewsPanel.cs b/osu.Game.Tests/Visual/Online/TestSceneHomeNewsPanel.cs index 262bc51cd8..78d77c9e97 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneHomeNewsPanel.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneHomeNewsPanel.cs @@ -8,6 +8,8 @@ using osu.Framework.Allocation; using osu.Game.Overlays; using System; using osu.Game.Overlays.Dashboard.Home.News; +using osuTK; +using System.Collections.Generic; namespace osu.Game.Tests.Visual.Online { @@ -18,20 +20,40 @@ namespace osu.Game.Tests.Visual.Online public TestSceneHomeNewsPanel() { - Add(new Container + Add(new FillFlowContainer { Anchor = Anchor.Centre, Origin = Anchor.Centre, AutoSizeAxes = Axes.Y, Width = 500, - Child = new HomeNewsPanel(new APINewsPost + Direction = FillDirection.Vertical, + Spacing = new Vector2(0, 5), + Children = new Drawable[] { - Title = "This post has an image which starts with \"/\" and has many authors!", - Preview = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.", - FirstImage = "/help/wiki/shared/news/banners/monthly-beatmapping-contest.png", - PublishedAt = DateTimeOffset.Now, - Slug = "2020-07-16-summer-theme-park-2020-voting-open" - }) + new HomeNewsPanel(new APINewsPost + { + Title = "This post has an image which starts with \"/\" and has many authors!", + Preview = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.", + FirstImage = "/help/wiki/shared/news/banners/monthly-beatmapping-contest.png", + PublishedAt = DateTimeOffset.Now, + Slug = "2020-07-16-summer-theme-park-2020-voting-open" + }), + new HomeNewsGroupPanel(new List + { + new APINewsPost + { + Title = "Title 1", + Slug = "2020-07-16-summer-theme-park-2020-voting-open", + PublishedAt = DateTimeOffset.Now, + }, + new APINewsPost + { + Title = "Title of this post is Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.", + Slug = "2020-07-16-summer-theme-park-2020-voting-open", + PublishedAt = DateTimeOffset.Now, + } + }) + } }); } } diff --git a/osu.Game/Overlays/Dashboard/Home/HomePanel.cs b/osu.Game/Overlays/Dashboard/Home/HomePanel.cs index bbe7e411fd..ce053cd4ec 100644 --- a/osu.Game/Overlays/Dashboard/Home/HomePanel.cs +++ b/osu.Game/Overlays/Dashboard/Home/HomePanel.cs @@ -16,9 +16,6 @@ namespace osu.Game.Overlays.Dashboard.Home { protected override Container Content => content; - [Resolved] - protected OverlayColourProvider ColourProvider { get; private set; } - private readonly Container content; private readonly Box background; @@ -50,9 +47,9 @@ namespace osu.Game.Overlays.Dashboard.Home } [BackgroundDependencyLoader] - private void load() + private void load(OverlayColourProvider colourProvider) { - background.Colour = ColourProvider.Background4; + background.Colour = colourProvider.Background4; } } } diff --git a/osu.Game/Overlays/Dashboard/Home/News/HomeNewsGroupPanel.cs b/osu.Game/Overlays/Dashboard/Home/News/HomeNewsGroupPanel.cs new file mode 100644 index 0000000000..cd1c5393c5 --- /dev/null +++ b/osu.Game/Overlays/Dashboard/Home/News/HomeNewsGroupPanel.cs @@ -0,0 +1,85 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System; +using System.Collections.Generic; +using System.Linq; +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Game.Graphics; +using osu.Game.Online.API.Requests.Responses; + +namespace osu.Game.Overlays.Dashboard.Home.News +{ + public class HomeNewsGroupPanel : HomePanel + { + private readonly List posts; + + public HomeNewsGroupPanel(List posts) + { + this.posts = posts; + } + + [BackgroundDependencyLoader] + private void load() + { + Content.Padding = new MarginPadding { Vertical = 5 }; + + Child = new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Vertical, + Children = posts.Select(p => new CollapsedNewsPanel(p)).ToArray() + }; + } + + private class CollapsedNewsPanel : HomeNewsPanelFooter + { + public CollapsedNewsPanel(APINewsPost post) + : base(post) + { + } + + protected override Drawable CreateContent(APINewsPost post) => new NewsTitleLink(post); + + protected override NewsPostDrawableDate CreateDate(DateTimeOffset date) => new Date(date); + + private class Date : NewsPostDrawableDate + { + public Date(DateTimeOffset date) + : base(date) + { + } + + protected override Drawable CreateDate(DateTimeOffset date, OverlayColourProvider colourProvider) + { + var drawableDate = new TextFlowContainer(t => + { + t.Colour = colourProvider.Light1; + }) + { + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Margin = new MarginPadding { Vertical = 5 } + }; + + drawableDate.AddText($"{date:dd} ", t => + { + t.Font = OsuFont.GetFont(size: 14, weight: FontWeight.Bold); + }); + + drawableDate.AddText($"{date:MMM}", t => + { + t.Font = OsuFont.GetFont(size: 14, weight: FontWeight.Regular); + }); + + return drawableDate; + } + } + } + } +} diff --git a/osu.Game/Overlays/Dashboard/Home/News/HomeNewsPanel.cs b/osu.Game/Overlays/Dashboard/Home/News/HomeNewsPanel.cs index 85e31b3034..3548b7c88d 100644 --- a/osu.Game/Overlays/Dashboard/Home/News/HomeNewsPanel.cs +++ b/osu.Game/Overlays/Dashboard/Home/News/HomeNewsPanel.cs @@ -5,8 +5,6 @@ using System; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Cursor; -using osu.Framework.Graphics.Shapes; using osu.Framework.Platform; using osu.Game.Graphics; using osu.Game.Graphics.Containers; @@ -40,81 +38,7 @@ namespace osu.Game.Overlays.Dashboard.Home.News Children = new Drawable[] { new ClickableNewsBackground(post), - new GridContainer - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - ColumnDimensions = new[] - { - new Dimension(GridSizeMode.AutoSize), - new Dimension() - }, - RowDimensions = new[] - { - new Dimension(GridSizeMode.AutoSize) - }, - Content = new[] - { - new Drawable[] - { - new Container - { - RelativeSizeAxes = Axes.Y, - Width = 80, - Padding = new MarginPadding(10), - Children = new Drawable[] - { - new Box - { - Anchor = Anchor.TopRight, - Origin = Anchor.TopRight, - RelativeSizeAxes = Axes.Y, - Width = 1, - Colour = ColourProvider.Light1 - }, - new Container - { - Anchor = Anchor.TopRight, - Origin = Anchor.TopRight, - AutoSizeAxes = Axes.Both, - Padding = new MarginPadding { Right = 11 }, - Child = new DateContainer(post.PublishedAt) - } - } - }, - new Container - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Padding = new MarginPadding { Right = 10 }, - Children = new Drawable[] - { - new FillFlowContainer - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Margin = new MarginPadding { Top = 5, Bottom = 10 }, - Spacing = new Vector2(0, 10), - Direction = FillDirection.Vertical, - Children = new Drawable[] - { - new TitleLink(post), - new TextFlowContainer(f => - { - f.Font = OsuFont.GetFont(size: 12, weight: FontWeight.Regular); - }) - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Text = post.Preview - } - } - } - } - } - } - } - } + new Footer(post) } } }; @@ -158,54 +82,48 @@ namespace osu.Game.Overlays.Dashboard.Home.News } } - private class TitleLink : OsuHoverContainer + private class Footer : HomeNewsPanelFooter { - private readonly APINewsPost post; + protected override float BarPading => 10; - public TitleLink(APINewsPost post) + public Footer(APINewsPost post) + : base(post) { - this.post = post; - - RelativeSizeAxes = Axes.X; - AutoSizeAxes = Axes.Y; } - [BackgroundDependencyLoader] - private void load(GameHost host) + protected override NewsPostDrawableDate CreateDate(DateTimeOffset date) => new Date(date); + + protected override Drawable CreateContent(APINewsPost post) => new FillFlowContainer { - Child = new TextFlowContainer(t => + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Margin = new MarginPadding { Top = 5, Bottom = 10 }, + Spacing = new Vector2(0, 10), + Direction = FillDirection.Vertical, + Children = new Drawable[] { - t.Font = OsuFont.GetFont(weight: FontWeight.Bold); - }) + new NewsTitleLink(post), + new TextFlowContainer(f => + { + f.Font = OsuFont.GetFont(size: 12, weight: FontWeight.Regular); + }) + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Text = post.Preview + } + } + }; + + private class Date : NewsPostDrawableDate + { + public Date(DateTimeOffset date) + : base(date) { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Text = post.Title - }; + Margin = new MarginPadding { Top = 10 }; + } - TooltipText = "view in browser"; - Action = () => host.OpenUrlExternally("https://osu.ppy.sh/home/news/" + post.Slug); - } - } - - private class DateContainer : CompositeDrawable, IHasCustomTooltip - { - public ITooltip GetCustomTooltip() => new DateTooltip(); - - public object TooltipContent => date; - - private readonly DateTimeOffset date; - - public DateContainer(DateTimeOffset date) - { - this.date = date; - } - - [BackgroundDependencyLoader] - private void load(OverlayColourProvider colourProvider) - { - AutoSizeAxes = Axes.Both; - InternalChild = new FillFlowContainer + protected override Drawable CreateDate(DateTimeOffset date, OverlayColourProvider colourProvider) => new FillFlowContainer { AutoSizeAxes = Axes.Both, Direction = FillDirection.Vertical, @@ -219,7 +137,7 @@ namespace osu.Game.Overlays.Dashboard.Home.News Origin = Anchor.TopRight, Font = OsuFont.GetFont(weight: FontWeight.Bold), // using Bold since there is no 800 weight alternative Colour = colourProvider.Light1, - Text = date.Day.ToString() + Text = $"{date: dd}" }, new TextFlowContainer(f => { diff --git a/osu.Game/Overlays/Dashboard/Home/News/HomeNewsPanelFooter.cs b/osu.Game/Overlays/Dashboard/Home/News/HomeNewsPanelFooter.cs new file mode 100644 index 0000000000..591f53ac4a --- /dev/null +++ b/osu.Game/Overlays/Dashboard/Home/News/HomeNewsPanelFooter.cs @@ -0,0 +1,79 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System; +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Game.Online.API.Requests.Responses; + +namespace osu.Game.Overlays.Dashboard.Home.News +{ + public abstract class HomeNewsPanelFooter : CompositeDrawable + { + protected virtual float BarPading { get; } = 0; + + private readonly APINewsPost post; + + protected HomeNewsPanelFooter(APINewsPost post) + { + this.post = post; + } + + [BackgroundDependencyLoader] + private void load(OverlayColourProvider colourProvider) + { + RelativeSizeAxes = Axes.X; + AutoSizeAxes = Axes.Y; + InternalChild = new GridContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + RowDimensions = new[] + { + new Dimension(GridSizeMode.AutoSize) + }, + ColumnDimensions = new[] + { + new Dimension(GridSizeMode.Absolute, size: 60), + new Dimension(GridSizeMode.Absolute, size: 20), + new Dimension() + }, + Content = new[] + { + new Drawable[] + { + CreateDate(post.PublishedAt), + new Container + { + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding { Vertical = BarPading }, + Child = new Box + { + Anchor = Anchor.TopCentre, + Origin = Anchor.TopRight, + Width = 1, + RelativeSizeAxes = Axes.Y, + Colour = colourProvider.Light1 + } + }, + new Container + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Padding = new MarginPadding { Right = 10 }, + Child = CreateContent(post) + } + } + } + }; + } + + protected abstract NewsPostDrawableDate CreateDate(DateTimeOffset date); + + protected abstract Drawable CreateContent(APINewsPost post); + } +} diff --git a/osu.Game/Overlays/Dashboard/Home/News/NewsPostDrawableDate.cs b/osu.Game/Overlays/Dashboard/Home/News/NewsPostDrawableDate.cs new file mode 100644 index 0000000000..8ba58e27a7 --- /dev/null +++ b/osu.Game/Overlays/Dashboard/Home/News/NewsPostDrawableDate.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 System; +using osu.Framework.Allocation; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Cursor; +using osu.Game.Graphics; +using osu.Framework.Graphics; + +namespace osu.Game.Overlays.Dashboard.Home.News +{ + public abstract class NewsPostDrawableDate : CompositeDrawable, IHasCustomTooltip + { + public ITooltip GetCustomTooltip() => new DateTooltip(); + + public object TooltipContent => date; + + private readonly DateTimeOffset date; + + protected NewsPostDrawableDate(DateTimeOffset date) + { + this.date = date; + } + + [BackgroundDependencyLoader] + private void load(OverlayColourProvider colourProvider) + { + AutoSizeAxes = Axes.Both; + Anchor = Anchor.TopRight; + Origin = Anchor.TopRight; + InternalChild = CreateDate(date, colourProvider); + } + + protected abstract Drawable CreateDate(DateTimeOffset date, OverlayColourProvider colourProvider); + } +} diff --git a/osu.Game/Overlays/Dashboard/Home/News/NewsTitleLink.cs b/osu.Game/Overlays/Dashboard/Home/News/NewsTitleLink.cs new file mode 100644 index 0000000000..da98c92bbe --- /dev/null +++ b/osu.Game/Overlays/Dashboard/Home/News/NewsTitleLink.cs @@ -0,0 +1,43 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Platform; +using osu.Game.Graphics; +using osu.Game.Graphics.Containers; +using osu.Game.Online.API.Requests.Responses; + +namespace osu.Game.Overlays.Dashboard.Home.News +{ + public class NewsTitleLink : OsuHoverContainer + { + private readonly APINewsPost post; + + public NewsTitleLink(APINewsPost post) + { + this.post = post; + + RelativeSizeAxes = Axes.X; + AutoSizeAxes = Axes.Y; + } + + [BackgroundDependencyLoader] + private void load(GameHost host) + { + Child = new TextFlowContainer(t => + { + t.Font = OsuFont.GetFont(weight: FontWeight.Bold); + }) + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Text = post.Title + }; + + TooltipText = "view in browser"; + Action = () => host.OpenUrlExternally("https://osu.ppy.sh/home/news/" + post.Slug); + } + } +} From cddd4f0a97842eefd68ba1ddda18f81ec5ca09b3 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Fri, 7 Aug 2020 13:18:31 +0300 Subject: [PATCH 117/434] Implement HomeShowMoreNewsPanel --- .../Visual/Online/TestSceneHomeNewsPanel.cs | 3 +- .../Home/News/HomeShowMoreNewsPanel.cs | 51 +++++++++++++++++++ 2 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 osu.Game/Overlays/Dashboard/Home/News/HomeShowMoreNewsPanel.cs diff --git a/osu.Game.Tests/Visual/Online/TestSceneHomeNewsPanel.cs b/osu.Game.Tests/Visual/Online/TestSceneHomeNewsPanel.cs index 78d77c9e97..b1c0c5adcd 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneHomeNewsPanel.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneHomeNewsPanel.cs @@ -52,7 +52,8 @@ namespace osu.Game.Tests.Visual.Online Slug = "2020-07-16-summer-theme-park-2020-voting-open", PublishedAt = DateTimeOffset.Now, } - }) + }), + new HomeShowMoreNewsPanel() } }); } diff --git a/osu.Game/Overlays/Dashboard/Home/News/HomeShowMoreNewsPanel.cs b/osu.Game/Overlays/Dashboard/Home/News/HomeShowMoreNewsPanel.cs new file mode 100644 index 0000000000..abb4bd7969 --- /dev/null +++ b/osu.Game/Overlays/Dashboard/Home/News/HomeShowMoreNewsPanel.cs @@ -0,0 +1,51 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Collections.Generic; +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Game.Graphics.Containers; +using osu.Game.Graphics.Sprites; +using osuTK.Graphics; + +namespace osu.Game.Overlays.Dashboard.Home.News +{ + public class HomeShowMoreNewsPanel : OsuHoverContainer + { + protected override IEnumerable EffectTargets => new[] { text }; + + [Resolved(canBeNull: true)] + private NewsOverlay overlay { get; set; } + + private OsuSpriteText text; + + public HomeShowMoreNewsPanel() + { + RelativeSizeAxes = Axes.X; + AutoSizeAxes = Axes.Y; + } + + [BackgroundDependencyLoader] + private void load(OverlayColourProvider colourProvider) + { + Child = new HomePanel + { + Child = text = new OsuSpriteText + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Margin = new MarginPadding { Vertical = 20 }, + Text = "see more" + } + }; + + IdleColour = colourProvider.Light1; + HoverColour = Color4.White; + + Action = () => + { + overlay?.ShowFrontPage(); + }; + } + } +} From 61b632516eb73c43918697a9e408b5d75d04ab4d Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 7 Aug 2020 19:43:16 +0900 Subject: [PATCH 118/434] Ensure CurrentTrack is never null --- osu.Game.Tests/Visual/Editing/TimelineTestScene.cs | 3 --- .../Visual/Navigation/TestSceneScreenNavigation.cs | 4 ++-- .../Visual/UserInterface/TestSceneBeatSyncedContainer.cs | 2 +- osu.Game/Overlays/MusicController.cs | 6 ++---- .../Edit/Components/Timelines/Summary/Parts/TimelinePart.cs | 1 - .../Edit/Compose/Components/Timeline/TimelineTickDisplay.cs | 2 +- osu.Game/Screens/Menu/LogoVisualisation.cs | 4 ++-- osu.Game/Screens/Menu/MainMenu.cs | 2 -- osu.Game/Tests/Visual/OsuTestScene.cs | 3 --- osu.Game/Tests/Visual/RateAdjustedBeatmapTestScene.cs | 3 --- 10 files changed, 8 insertions(+), 22 deletions(-) diff --git a/osu.Game.Tests/Visual/Editing/TimelineTestScene.cs b/osu.Game.Tests/Visual/Editing/TimelineTestScene.cs index 4113bdddf8..347b5757c8 100644 --- a/osu.Game.Tests/Visual/Editing/TimelineTestScene.cs +++ b/osu.Game.Tests/Visual/Editing/TimelineTestScene.cs @@ -95,10 +95,7 @@ namespace osu.Game.Tests.Visual.Editing base.Update(); if (musicController.TrackLoaded) - { - Debug.Assert(musicController.CurrentTrack != null); marker.X = (float)(editorClock.CurrentTime / musicController.CurrentTrack.Length); - } } } diff --git a/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs b/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs index 946bc2a175..e5d862cfc7 100644 --- a/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs +++ b/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs @@ -136,8 +136,8 @@ namespace osu.Game.Tests.Visual.Navigation AddUntilStep("Wait for music controller", () => Game.MusicController.IsLoaded); AddStep("Seek close to end", () => { - Game.MusicController.SeekTo(MusicController.CurrentTrack.AsNonNull().Length - 1000); - MusicController.CurrentTrack.AsNonNull().Completed += () => trackCompleted = true; + Game.MusicController.SeekTo(MusicController.CurrentTrack.Length - 1000); + MusicController.CurrentTrack.Completed += () => trackCompleted = true; }); AddUntilStep("Track was completed", () => trackCompleted); diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneBeatSyncedContainer.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneBeatSyncedContainer.cs index ac743d76df..3cccfa992e 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneBeatSyncedContainer.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneBeatSyncedContainer.cs @@ -169,7 +169,7 @@ namespace osu.Game.Tests.Visual.UserInterface if (timingPoints.Count == 0) return 0; if (timingPoints[^1] == current) - return (int)Math.Ceiling((musicController.CurrentTrack.AsNonNull().Length - current.Time) / current.BeatLength); + return (int)Math.Ceiling((musicController.CurrentTrack.Length - current.Time) / current.BeatLength); return (int)Math.Ceiling((getNextTimingPoint(current).Time - current.Time) / current.BeatLength); } diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index 6adfa1817e..7e3bb1ce89 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -5,7 +5,6 @@ using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; -using JetBrains.Annotations; using osu.Framework.Allocation; using osu.Framework.Audio.Track; using osu.Framework.Bindables; @@ -65,8 +64,7 @@ namespace osu.Game.Overlays [Resolved(canBeNull: true)] private OnScreenDisplay onScreenDisplay { get; set; } - [CanBeNull] - public DrawableTrack CurrentTrack { get; private set; } + public DrawableTrack CurrentTrack { get; private set; } = new DrawableTrack(new TrackVirtual(1000)); private IBindable> managerUpdated; private IBindable> managerRemoved; @@ -312,7 +310,7 @@ namespace osu.Game.Overlays current = beatmap.NewValue; - if (!beatmap.OldValue.BeatmapInfo.AudioEquals(current?.BeatmapInfo)) + if (CurrentTrack == null || !beatmap.OldValue.BeatmapInfo.AudioEquals(current?.BeatmapInfo)) changeTrack(); TrackChanged?.Invoke(current, direction); diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs index 24fb855009..7085c8b020 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs @@ -58,7 +58,6 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts return; } - Debug.Assert(musicController.CurrentTrack != null); content.RelativeChildSize = new Vector2((float)Math.Max(1, musicController.CurrentTrack.Length), 1); } diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineTickDisplay.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineTickDisplay.cs index ceb0275a13..1ce33f221a 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineTickDisplay.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineTickDisplay.cs @@ -44,7 +44,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline for (var i = 0; i < beatmap.ControlPointInfo.TimingPoints.Count; i++) { var point = beatmap.ControlPointInfo.TimingPoints[i]; - var until = i + 1 < beatmap.ControlPointInfo.TimingPoints.Count ? beatmap.ControlPointInfo.TimingPoints[i + 1].Time : musicController.CurrentTrack.AsNonNull().Length; + var until = i + 1 < beatmap.ControlPointInfo.TimingPoints.Count ? beatmap.ControlPointInfo.TimingPoints[i + 1].Time : musicController.CurrentTrack.Length; int beat = 0; diff --git a/osu.Game/Screens/Menu/LogoVisualisation.cs b/osu.Game/Screens/Menu/LogoVisualisation.cs index 7a1ff4fa06..974b704200 100644 --- a/osu.Game/Screens/Menu/LogoVisualisation.cs +++ b/osu.Game/Screens/Menu/LogoVisualisation.cs @@ -109,14 +109,14 @@ namespace osu.Game.Screens.Menu private void updateAmplitudes() { var effect = beatmap.Value.BeatmapLoaded && musicController.TrackLoaded - ? beatmap.Value.Beatmap?.ControlPointInfo.EffectPointAt(musicController.CurrentTrack.AsNonNull().CurrentTime) + ? beatmap.Value.Beatmap?.ControlPointInfo.EffectPointAt(musicController.CurrentTrack.CurrentTime) : null; for (int i = 0; i < temporalAmplitudes.Length; i++) temporalAmplitudes[i] = 0; if (musicController.TrackLoaded) - addAmplitudesFromSource(musicController.CurrentTrack.AsNonNull()); + addAmplitudesFromSource(musicController.CurrentTrack); foreach (var source in amplitudeSources) addAmplitudesFromSource(source); diff --git a/osu.Game/Screens/Menu/MainMenu.cs b/osu.Game/Screens/Menu/MainMenu.cs index ea4347a285..518277bce3 100644 --- a/osu.Game/Screens/Menu/MainMenu.cs +++ b/osu.Game/Screens/Menu/MainMenu.cs @@ -179,8 +179,6 @@ namespace osu.Game.Screens.Menu if (last is IntroScreen && music.TrackLoaded) { - Debug.Assert(music.CurrentTrack != null); - if (!music.CurrentTrack.IsRunning) { music.CurrentTrack.Seek(metadata.PreviewTime != -1 ? metadata.PreviewTime : 0.4f * music.CurrentTrack.Length); diff --git a/osu.Game/Tests/Visual/OsuTestScene.cs b/osu.Game/Tests/Visual/OsuTestScene.cs index f2b9388fdc..af7579aafb 100644 --- a/osu.Game/Tests/Visual/OsuTestScene.cs +++ b/osu.Game/Tests/Visual/OsuTestScene.cs @@ -170,10 +170,7 @@ namespace osu.Game.Tests.Visual rulesetDependencies?.Dispose(); if (MusicController?.TrackLoaded == true) - { - Debug.Assert(MusicController.CurrentTrack != null); MusicController.CurrentTrack.Stop(); - } if (contextFactory.IsValueCreated) contextFactory.Value.ResetDatabase(); diff --git a/osu.Game/Tests/Visual/RateAdjustedBeatmapTestScene.cs b/osu.Game/Tests/Visual/RateAdjustedBeatmapTestScene.cs index 54458716b1..027259d4f0 100644 --- a/osu.Game/Tests/Visual/RateAdjustedBeatmapTestScene.cs +++ b/osu.Game/Tests/Visual/RateAdjustedBeatmapTestScene.cs @@ -16,10 +16,7 @@ namespace osu.Game.Tests.Visual // note that this will override any mod rate application if (MusicController.TrackLoaded) - { - Debug.Assert(MusicController.CurrentTrack != null); MusicController.CurrentTrack.Tempo.Value = Clock.Rate; - } } } } From 5002d69f6973ab9753997dd28255c90a90de270a Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 7 Aug 2020 20:51:56 +0900 Subject: [PATCH 119/434] Update inspections --- .../TestSceneHoldNoteInput.cs | 2 +- .../TestSceneOutOfOrderHits.cs | 2 +- .../TestSceneSliderInput.cs | 2 +- .../Skins/TestSceneBeatmapSkinResources.cs | 2 +- .../Visual/Editing/TimelineTestScene.cs | 1 - .../Visual/Gameplay/TestScenePause.cs | 2 +- .../Visual/Gameplay/TestScenePlayerLoader.cs | 4 +-- .../Visual/Gameplay/TestSceneStoryboard.cs | 4 +-- .../Visual/Menus/TestSceneIntroWelcome.cs | 2 +- .../Navigation/TestSceneScreenNavigation.cs | 9 +++--- .../TestSceneBeatSyncedContainer.cs | 1 - .../TestSceneNowPlayingOverlay.cs | 4 +-- osu.Game/Audio/PreviewTrackManager.cs | 2 +- osu.Game/Overlays/Music/PlaylistOverlay.cs | 6 ++-- osu.Game/Overlays/MusicController.cs | 31 +++++++------------ .../Edit/Components/PlaybackControl.cs | 4 +-- .../Timelines/Summary/Parts/TimelinePart.cs | 1 - .../Timeline/TimelineTickDisplay.cs | 1 - osu.Game/Screens/Edit/Editor.cs | 2 +- osu.Game/Screens/Menu/LogoVisualisation.cs | 1 - osu.Game/Screens/Menu/MainMenu.cs | 1 - osu.Game/Screens/Menu/OsuLogo.cs | 2 +- .../Multi/Match/Components/ReadyButton.cs | 2 +- osu.Game/Screens/Multi/Multiplayer.cs | 16 +++------- osu.Game/Tests/Visual/OsuTestScene.cs | 1 - .../Visual/RateAdjustedBeatmapTestScene.cs | 2 -- 26 files changed, 42 insertions(+), 65 deletions(-) diff --git a/osu.Game.Rulesets.Mania.Tests/TestSceneHoldNoteInput.cs b/osu.Game.Rulesets.Mania.Tests/TestSceneHoldNoteInput.cs index 98669efb10..19b69bac6d 100644 --- a/osu.Game.Rulesets.Mania.Tests/TestSceneHoldNoteInput.cs +++ b/osu.Game.Rulesets.Mania.Tests/TestSceneHoldNoteInput.cs @@ -343,7 +343,7 @@ namespace osu.Game.Rulesets.Mania.Tests judgementResults = new List(); }); - AddUntilStep("Beatmap at 0", () => MusicController.CurrentTrack?.CurrentTime == 0); + AddUntilStep("Beatmap at 0", () => MusicController.CurrentTrack.CurrentTime == 0); AddUntilStep("Wait until player is loaded", () => currentPlayer.IsCurrentScreen()); AddUntilStep("Wait for completion", () => currentPlayer.ScoreProcessor.HasCompleted.Value); } diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneOutOfOrderHits.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneOutOfOrderHits.cs index e5be778527..744ad46c28 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneOutOfOrderHits.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneOutOfOrderHits.cs @@ -385,7 +385,7 @@ namespace osu.Game.Rulesets.Osu.Tests judgementResults = new List(); }); - AddUntilStep("Beatmap at 0", () => MusicController.CurrentTrack?.CurrentTime == 0); + AddUntilStep("Beatmap at 0", () => MusicController.CurrentTrack.CurrentTime == 0); AddUntilStep("Wait until player is loaded", () => currentPlayer.IsCurrentScreen()); AddUntilStep("Wait for completion", () => currentPlayer.ScoreProcessor.HasCompleted.Value); } diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs index c9d13d3976..1690f648f9 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs @@ -366,7 +366,7 @@ namespace osu.Game.Rulesets.Osu.Tests judgementResults = new List(); }); - AddUntilStep("Beatmap at 0", () => MusicController.CurrentTrack?.CurrentTime == 0); + AddUntilStep("Beatmap at 0", () => MusicController.CurrentTrack.CurrentTime == 0); AddUntilStep("Wait until player is loaded", () => currentPlayer.IsCurrentScreen()); AddUntilStep("Wait for completion", () => currentPlayer.ScoreProcessor.HasCompleted.Value); } diff --git a/osu.Game.Tests/Skins/TestSceneBeatmapSkinResources.cs b/osu.Game.Tests/Skins/TestSceneBeatmapSkinResources.cs index 08a4e27ff7..2866692be4 100644 --- a/osu.Game.Tests/Skins/TestSceneBeatmapSkinResources.cs +++ b/osu.Game.Tests/Skins/TestSceneBeatmapSkinResources.cs @@ -31,6 +31,6 @@ namespace osu.Game.Tests.Skins public void TestRetrieveOggSample() => AddAssert("sample is non-null", () => beatmap.Skin.GetSample(new SampleInfo("sample")) != null); [Test] - public void TestRetrieveOggTrack() => AddAssert("track is non-null", () => MusicController.CurrentTrack?.IsDummyDevice == false); + public void TestRetrieveOggTrack() => AddAssert("track is non-null", () => MusicController.CurrentTrack.IsDummyDevice == false); } } diff --git a/osu.Game.Tests/Visual/Editing/TimelineTestScene.cs b/osu.Game.Tests/Visual/Editing/TimelineTestScene.cs index 347b5757c8..4988a09650 100644 --- a/osu.Game.Tests/Visual/Editing/TimelineTestScene.cs +++ b/osu.Game.Tests/Visual/Editing/TimelineTestScene.cs @@ -1,7 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System.Diagnostics; using osu.Framework.Allocation; using osu.Framework.Audio; using osu.Framework.Graphics; diff --git a/osu.Game.Tests/Visual/Gameplay/TestScenePause.cs b/osu.Game.Tests/Visual/Gameplay/TestScenePause.cs index e500b451f0..e7dd586f4e 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestScenePause.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestScenePause.cs @@ -288,7 +288,7 @@ namespace osu.Game.Tests.Visual.Gameplay private void confirmNoTrackAdjustments() { - AddAssert("track has no adjustments", () => MusicController.CurrentTrack?.AggregateFrequency.Value == 1); + AddAssert("track has no adjustments", () => MusicController.CurrentTrack.AggregateFrequency.Value == 1); } private void restart() => AddStep("restart", () => Player.Restart()); diff --git a/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs b/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs index c72ab7d3d1..c4882046de 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs @@ -77,12 +77,12 @@ namespace osu.Game.Tests.Visual.Gameplay { AddStep("load dummy beatmap", () => ResetPlayer(false, () => SelectedMods.Value = new[] { new OsuModNightcore() })); AddUntilStep("wait for current", () => loader.IsCurrentScreen()); - AddAssert("mod rate applied", () => MusicController.CurrentTrack?.Rate != 1); + AddAssert("mod rate applied", () => MusicController.CurrentTrack.Rate != 1); AddStep("exit loader", () => loader.Exit()); AddUntilStep("wait for not current", () => !loader.IsCurrentScreen()); AddAssert("player did not load", () => !player.IsLoaded); AddUntilStep("player disposed", () => loader.DisposalTask?.IsCompleted == true); - AddAssert("mod rate still applied", () => MusicController.CurrentTrack?.Rate != 1); + AddAssert("mod rate still applied", () => MusicController.CurrentTrack.Rate != 1); } [Test] diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboard.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboard.cs index c7a012a03f..3d2dd8a0c5 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboard.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboard.cs @@ -87,9 +87,9 @@ namespace osu.Game.Tests.Visual.Gameplay private void restart() { - MusicController.CurrentTrack?.Reset(); + MusicController.CurrentTrack.Reset(); loadStoryboard(Beatmap.Value); - MusicController.CurrentTrack?.Start(); + MusicController.CurrentTrack.Start(); } private void loadStoryboard(WorkingBeatmap working) diff --git a/osu.Game.Tests/Visual/Menus/TestSceneIntroWelcome.cs b/osu.Game.Tests/Visual/Menus/TestSceneIntroWelcome.cs index a88704c831..29be250b12 100644 --- a/osu.Game.Tests/Visual/Menus/TestSceneIntroWelcome.cs +++ b/osu.Game.Tests/Visual/Menus/TestSceneIntroWelcome.cs @@ -16,7 +16,7 @@ namespace osu.Game.Tests.Visual.Menus { AddUntilStep("wait for load", () => MusicController.TrackLoaded); - AddAssert("check if menu music loops", () => MusicController.CurrentTrack?.Looping == true); + AddAssert("check if menu music loops", () => MusicController.CurrentTrack.Looping); } } } diff --git a/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs b/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs index e5d862cfc7..d2c71c1d17 100644 --- a/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs +++ b/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs @@ -4,7 +4,6 @@ using System.Linq; using NUnit.Framework; using osu.Framework.Allocation; -using osu.Framework.Extensions.ObjectExtensions; using osu.Framework.Graphics.Containers; using osu.Framework.Screens; using osu.Game.Beatmaps; @@ -62,12 +61,12 @@ namespace osu.Game.Tests.Visual.Navigation AddUntilStep("wait for fail", () => player.HasFailed); AddUntilStep("wait for track stop", () => !MusicController.IsPlaying); - AddAssert("Ensure time before preview point", () => MusicController.CurrentTrack?.CurrentTime < beatmap().Metadata.PreviewTime); + AddAssert("Ensure time before preview point", () => MusicController.CurrentTrack.CurrentTime < beatmap().Metadata.PreviewTime); pushEscape(); AddUntilStep("wait for track playing", () => MusicController.IsPlaying); - AddAssert("Ensure time wasn't reset to preview point", () => MusicController.CurrentTrack?.CurrentTime < beatmap().Metadata.PreviewTime); + AddAssert("Ensure time wasn't reset to preview point", () => MusicController.CurrentTrack.CurrentTime < beatmap().Metadata.PreviewTime); } [Test] @@ -77,11 +76,11 @@ namespace osu.Game.Tests.Visual.Navigation PushAndConfirm(() => songSelect = new TestSongSelect()); - AddUntilStep("wait for no track", () => MusicController.CurrentTrack?.IsDummyDevice == true); + AddUntilStep("wait for no track", () => MusicController.CurrentTrack.IsDummyDevice); AddStep("return to menu", () => songSelect.Exit()); - AddUntilStep("wait for track", () => MusicController.CurrentTrack?.IsDummyDevice == false && MusicController.IsPlaying); + AddUntilStep("wait for track", () => MusicController.CurrentTrack.IsDummyDevice == false && MusicController.IsPlaying); } [Test] diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneBeatSyncedContainer.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneBeatSyncedContainer.cs index 3cccfa992e..127915c6c6 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneBeatSyncedContainer.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneBeatSyncedContainer.cs @@ -8,7 +8,6 @@ using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Audio.Track; using osu.Framework.Extensions.Color4Extensions; -using osu.Framework.Extensions.ObjectExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneNowPlayingOverlay.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneNowPlayingOverlay.cs index 0161ec0c56..cadecbbef0 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneNowPlayingOverlay.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneNowPlayingOverlay.cs @@ -80,12 +80,12 @@ namespace osu.Game.Tests.Visual.UserInterface AddStep("Store track", () => currentBeatmap = Beatmap.Value); AddStep(@"Seek track to 6 second", () => musicController.SeekTo(6000)); - AddUntilStep(@"Wait for current time to update", () => musicController.CurrentTrack?.CurrentTime > 5000); + AddUntilStep(@"Wait for current time to update", () => musicController.CurrentTrack.CurrentTime > 5000); AddStep(@"Set previous", () => musicController.PreviousTrack()); AddAssert(@"Check beatmap didn't change", () => currentBeatmap == Beatmap.Value); - AddUntilStep("Wait for current time to update", () => musicController.CurrentTrack?.CurrentTime < 5000); + AddUntilStep("Wait for current time to update", () => musicController.CurrentTrack.CurrentTime < 5000); AddStep(@"Set previous", () => musicController.PreviousTrack()); AddAssert(@"Check beatmap did change", () => currentBeatmap != Beatmap.Value); diff --git a/osu.Game/Audio/PreviewTrackManager.cs b/osu.Game/Audio/PreviewTrackManager.cs index 862be41c1a..1c68ce71d4 100644 --- a/osu.Game/Audio/PreviewTrackManager.cs +++ b/osu.Game/Audio/PreviewTrackManager.cs @@ -48,7 +48,7 @@ namespace osu.Game.Audio track.Started += () => Schedule(() => { - CurrentTrack?.Stop(); + CurrentTrack.Stop(); CurrentTrack = track; audio.Tracks.AddAdjustment(AdjustableProperty.Volume, muteBindable); }); diff --git a/osu.Game/Overlays/Music/PlaylistOverlay.cs b/osu.Game/Overlays/Music/PlaylistOverlay.cs index b9a58c37cb..7471e31923 100644 --- a/osu.Game/Overlays/Music/PlaylistOverlay.cs +++ b/osu.Game/Overlays/Music/PlaylistOverlay.cs @@ -85,7 +85,7 @@ namespace osu.Game.Overlays.Music if (toSelect != null) { beatmap.Value = beatmaps.GetWorkingBeatmap(toSelect); - musicController.CurrentTrack?.Restart(); + musicController.CurrentTrack.Restart(); } }; } @@ -119,12 +119,12 @@ namespace osu.Game.Overlays.Music { if (set.ID == (beatmap.Value?.BeatmapSetInfo?.ID ?? -1)) { - musicController.CurrentTrack?.Seek(0); + musicController.CurrentTrack.Seek(0); return; } beatmap.Value = beatmaps.GetWorkingBeatmap(set.Beatmaps.First()); - musicController.CurrentTrack?.Restart(); + musicController.CurrentTrack.Restart(); } } diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index 7e3bb1ce89..3e93ae2ccd 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -3,8 +3,8 @@ using System; using System.Collections.Generic; -using System.Diagnostics; using System.Linq; +using JetBrains.Annotations; using osu.Framework.Allocation; using osu.Framework.Audio.Track; using osu.Framework.Bindables; @@ -64,6 +64,7 @@ namespace osu.Game.Overlays [Resolved(canBeNull: true)] private OnScreenDisplay onScreenDisplay { get; set; } + [NotNull] public DrawableTrack CurrentTrack { get; private set; } = new DrawableTrack(new TrackVirtual(1000)); private IBindable> managerUpdated; @@ -102,12 +103,12 @@ namespace osu.Game.Overlays /// /// Returns whether the beatmap track is playing. /// - public bool IsPlaying => CurrentTrack?.IsRunning ?? false; + public bool IsPlaying => CurrentTrack.IsRunning; /// /// Returns whether the beatmap track is loaded. /// - public bool TrackLoaded => CurrentTrack?.IsLoaded == true; + public bool TrackLoaded => CurrentTrack.IsLoaded; private void beatmapUpdated(ValueChangedEvent> weakSet) { @@ -140,7 +141,7 @@ namespace osu.Game.Overlays seekDelegate = Schedule(() => { if (!beatmap.Disabled) - CurrentTrack?.Seek(position); + CurrentTrack.Seek(position); }); } @@ -152,7 +153,7 @@ namespace osu.Game.Overlays { if (IsUserPaused) return; - if (CurrentTrack == null || CurrentTrack.IsDummyDevice) + if (CurrentTrack.IsDummyDevice) { if (beatmap.Disabled) return; @@ -173,9 +174,6 @@ namespace osu.Game.Overlays { IsUserPaused = false; - if (CurrentTrack == null) - return false; - if (restart) CurrentTrack.Restart(); else if (!IsPlaying) @@ -190,7 +188,7 @@ namespace osu.Game.Overlays public void Stop() { IsUserPaused = true; - if (CurrentTrack?.IsRunning == true) + if (CurrentTrack.IsRunning) CurrentTrack.Stop(); } @@ -200,7 +198,7 @@ namespace osu.Game.Overlays /// Whether the operation was successful. public bool TogglePause() { - if (CurrentTrack?.IsRunning == true) + if (CurrentTrack.IsRunning) Stop(); else Play(); @@ -222,7 +220,7 @@ namespace osu.Game.Overlays if (beatmap.Disabled) return PreviousTrackResult.None; - var currentTrackPosition = CurrentTrack?.CurrentTime; + var currentTrackPosition = CurrentTrack.CurrentTime; if (currentTrackPosition >= restart_cutoff_point) { @@ -276,7 +274,7 @@ namespace osu.Game.Overlays { // if not scheduled, the previously track will be stopped one frame later (see ScheduleAfterChildren logic in GameBase). // we probably want to move this to a central method for switching to a new working beatmap in the future. - Schedule(() => CurrentTrack?.Restart()); + Schedule(() => CurrentTrack.Restart()); } private WorkingBeatmap current; @@ -310,7 +308,7 @@ namespace osu.Game.Overlays current = beatmap.NewValue; - if (CurrentTrack == null || !beatmap.OldValue.BeatmapInfo.AudioEquals(current?.BeatmapInfo)) + if (CurrentTrack.IsDummyDevice || !beatmap.OldValue.BeatmapInfo.AudioEquals(current?.BeatmapInfo)) changeTrack(); TrackChanged?.Invoke(current, direction); @@ -322,7 +320,7 @@ namespace osu.Game.Overlays private void changeTrack() { - CurrentTrack?.Expire(); + CurrentTrack.Expire(); CurrentTrack = null; if (current != null) @@ -340,8 +338,6 @@ namespace osu.Game.Overlays if (current != workingBeatmap) return; - Debug.Assert(CurrentTrack != null); - if (!CurrentTrack.Looping && !beatmap.Disabled) NextTrack(); } @@ -366,9 +362,6 @@ namespace osu.Game.Overlays public void ResetTrackAdjustments() { - if (CurrentTrack == null) - return; - CurrentTrack.ResetSpeedAdjustments(); if (allowRateAdjustments) diff --git a/osu.Game/Screens/Edit/Components/PlaybackControl.cs b/osu.Game/Screens/Edit/Components/PlaybackControl.cs index 412efe266c..5bafc120af 100644 --- a/osu.Game/Screens/Edit/Components/PlaybackControl.cs +++ b/osu.Game/Screens/Edit/Components/PlaybackControl.cs @@ -66,12 +66,12 @@ namespace osu.Game.Screens.Edit.Components } }; - musicController.CurrentTrack?.AddAdjustment(AdjustableProperty.Tempo, tempo); + musicController.CurrentTrack.AddAdjustment(AdjustableProperty.Tempo, tempo); } protected override void Dispose(bool isDisposing) { - musicController?.CurrentTrack?.RemoveAdjustment(AdjustableProperty.Tempo, tempo); + musicController?.CurrentTrack.RemoveAdjustment(AdjustableProperty.Tempo, tempo); base.Dispose(isDisposing); } diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs index 7085c8b020..c8a470c58a 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs @@ -2,7 +2,6 @@ // See the LICENCE file in the repository root for full licence text. using System; -using System.Diagnostics; using osu.Framework.Allocation; using osu.Framework.Bindables; using osuTK; diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineTickDisplay.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineTickDisplay.cs index 1ce33f221a..cb122c590e 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineTickDisplay.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineTickDisplay.cs @@ -3,7 +3,6 @@ using System.Linq; using osu.Framework.Allocation; -using osu.Framework.Extensions.ObjectExtensions; using osu.Framework.Graphics; using osu.Game.Graphics; using osu.Game.Overlays; diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index 79b13a7eac..9f2009b415 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -84,7 +84,7 @@ namespace osu.Game.Screens.Edit // Todo: should probably be done at a DrawableRuleset level to share logic with Player. var sourceClock = (IAdjustableClock)musicController.CurrentTrack ?? new StopwatchClock(); - clock = new EditorClock(Beatmap.Value, musicController.CurrentTrack?.Length ?? 0, beatDivisor) { IsCoupled = false }; + clock = new EditorClock(Beatmap.Value, musicController.CurrentTrack.Length, beatDivisor) { IsCoupled = false }; clock.ChangeSource(sourceClock); dependencies.CacheAs(clock); diff --git a/osu.Game/Screens/Menu/LogoVisualisation.cs b/osu.Game/Screens/Menu/LogoVisualisation.cs index 974b704200..4d95ee9b7b 100644 --- a/osu.Game/Screens/Menu/LogoVisualisation.cs +++ b/osu.Game/Screens/Menu/LogoVisualisation.cs @@ -19,7 +19,6 @@ using osu.Framework.Allocation; using osu.Framework.Audio; using osu.Framework.Audio.Track; using osu.Framework.Bindables; -using osu.Framework.Extensions.ObjectExtensions; using osu.Framework.Utils; using osu.Game.Overlays; diff --git a/osu.Game/Screens/Menu/MainMenu.cs b/osu.Game/Screens/Menu/MainMenu.cs index 518277bce3..8837a49772 100644 --- a/osu.Game/Screens/Menu/MainMenu.cs +++ b/osu.Game/Screens/Menu/MainMenu.cs @@ -1,7 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System.Diagnostics; using System.Linq; using osuTK; using osuTK.Graphics; diff --git a/osu.Game/Screens/Menu/OsuLogo.cs b/osu.Game/Screens/Menu/OsuLogo.cs index f028f9b229..4515ee8ed0 100644 --- a/osu.Game/Screens/Menu/OsuLogo.cs +++ b/osu.Game/Screens/Menu/OsuLogo.cs @@ -330,7 +330,7 @@ namespace osu.Game.Screens.Menu const float velocity_adjust_cutoff = 0.98f; const float paused_velocity = 0.5f; - if (musicController.CurrentTrack?.IsRunning == true) + if (musicController.CurrentTrack.IsRunning) { var maxAmplitude = lastBeatIndex >= 0 ? musicController.CurrentTrack.CurrentAmplitudes.Maximum : 0; logoAmplitudeContainer.Scale = new Vector2((float)Interpolation.Damp(logoAmplitudeContainer.Scale.X, 1 - Math.Max(0, maxAmplitude - scale_adjust_cutoff) * 0.04f, 0.9f, Time.Elapsed)); diff --git a/osu.Game/Screens/Multi/Match/Components/ReadyButton.cs b/osu.Game/Screens/Multi/Match/Components/ReadyButton.cs index c7dc20ff23..384d3bd5a5 100644 --- a/osu.Game/Screens/Multi/Match/Components/ReadyButton.cs +++ b/osu.Game/Screens/Multi/Match/Components/ReadyButton.cs @@ -104,7 +104,7 @@ namespace osu.Game.Screens.Multi.Match.Components return; } - bool hasEnoughTime = musicController.CurrentTrack != null && DateTimeOffset.UtcNow.AddSeconds(30).AddMilliseconds(musicController.CurrentTrack.Length) < endDate.Value; + bool hasEnoughTime = DateTimeOffset.UtcNow.AddSeconds(30).AddMilliseconds(musicController.CurrentTrack.Length) < endDate.Value; Enabled.Value = hasBeatmap && hasEnoughTime; } diff --git a/osu.Game/Screens/Multi/Multiplayer.cs b/osu.Game/Screens/Multi/Multiplayer.cs index e068899c7b..1a39d80f8d 100644 --- a/osu.Game/Screens/Multi/Multiplayer.cs +++ b/osu.Game/Screens/Multi/Multiplayer.cs @@ -343,13 +343,10 @@ namespace osu.Game.Screens.Multi { if (screenStack.CurrentScreen is MatchSubScreen) { - if (musicController.CurrentTrack != null) - { - musicController.CurrentTrack.RestartPoint = Beatmap.Value.Metadata.PreviewTime; - musicController.CurrentTrack.Looping = true; + musicController.CurrentTrack.RestartPoint = Beatmap.Value.Metadata.PreviewTime; + musicController.CurrentTrack.Looping = true; - musicController.EnsurePlayingSomething(); - } + musicController.EnsurePlayingSomething(); } else { @@ -359,11 +356,8 @@ namespace osu.Game.Screens.Multi private void cancelLooping() { - if (musicController.CurrentTrack != null) - { - musicController.CurrentTrack.Looping = false; - musicController.CurrentTrack.RestartPoint = 0; - } + musicController.CurrentTrack.Looping = false; + musicController.CurrentTrack.RestartPoint = 0; } protected override void Dispose(bool isDisposing) diff --git a/osu.Game/Tests/Visual/OsuTestScene.cs b/osu.Game/Tests/Visual/OsuTestScene.cs index af7579aafb..b0d15bf442 100644 --- a/osu.Game/Tests/Visual/OsuTestScene.cs +++ b/osu.Game/Tests/Visual/OsuTestScene.cs @@ -3,7 +3,6 @@ using System; using System.Collections.Generic; -using System.Diagnostics; using System.IO; using System.Linq; using System.Threading.Tasks; diff --git a/osu.Game/Tests/Visual/RateAdjustedBeatmapTestScene.cs b/osu.Game/Tests/Visual/RateAdjustedBeatmapTestScene.cs index 027259d4f0..7651285970 100644 --- a/osu.Game/Tests/Visual/RateAdjustedBeatmapTestScene.cs +++ b/osu.Game/Tests/Visual/RateAdjustedBeatmapTestScene.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System.Diagnostics; - namespace osu.Game.Tests.Visual { /// From 028040344a9c2bfcc1cd25d3efad2e8dcf651207 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 7 Aug 2020 21:07:59 +0900 Subject: [PATCH 120/434] Fix test scene using local beatmap --- osu.Game.Tests/Skins/TestSceneBeatmapSkinResources.cs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/osu.Game.Tests/Skins/TestSceneBeatmapSkinResources.cs b/osu.Game.Tests/Skins/TestSceneBeatmapSkinResources.cs index 2866692be4..03faee9ad2 100644 --- a/osu.Game.Tests/Skins/TestSceneBeatmapSkinResources.cs +++ b/osu.Game.Tests/Skins/TestSceneBeatmapSkinResources.cs @@ -18,17 +18,15 @@ namespace osu.Game.Tests.Skins [Resolved] private BeatmapManager beatmaps { get; set; } - private WorkingBeatmap beatmap; - [BackgroundDependencyLoader] private void load() { var imported = beatmaps.Import(new ZipArchiveReader(TestResources.OpenResource("Archives/ogg-beatmap.osz"))).Result; - beatmap = beatmaps.GetWorkingBeatmap(imported.Beatmaps[0]); + Beatmap.Value = beatmaps.GetWorkingBeatmap(imported.Beatmaps[0]); } [Test] - public void TestRetrieveOggSample() => AddAssert("sample is non-null", () => beatmap.Skin.GetSample(new SampleInfo("sample")) != null); + public void TestRetrieveOggSample() => AddAssert("sample is non-null", () => Beatmap.Value.Skin.GetSample(new SampleInfo("sample")) != null); [Test] public void TestRetrieveOggTrack() => AddAssert("track is non-null", () => MusicController.CurrentTrack.IsDummyDevice == false); From 961c6dab541c379e30cd4afe837f5bbfb265096b Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 7 Aug 2020 21:08:03 +0900 Subject: [PATCH 121/434] Fix more inspections --- osu.Game/Screens/Edit/Editor.cs | 2 +- osu.Game/Tests/Visual/EditorClockTestScene.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index 9f2009b415..1a7d76ba8f 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -83,7 +83,7 @@ namespace osu.Game.Screens.Edit beatDivisor.BindValueChanged(divisor => Beatmap.Value.BeatmapInfo.BeatDivisor = divisor.NewValue); // Todo: should probably be done at a DrawableRuleset level to share logic with Player. - var sourceClock = (IAdjustableClock)musicController.CurrentTrack ?? new StopwatchClock(); + var sourceClock = (IAdjustableClock)musicController.CurrentTrack; clock = new EditorClock(Beatmap.Value, musicController.CurrentTrack.Length, beatDivisor) { IsCoupled = false }; clock.ChangeSource(sourceClock); diff --git a/osu.Game/Tests/Visual/EditorClockTestScene.cs b/osu.Game/Tests/Visual/EditorClockTestScene.cs index 780b4f1b3a..1009151ac4 100644 --- a/osu.Game/Tests/Visual/EditorClockTestScene.cs +++ b/osu.Game/Tests/Visual/EditorClockTestScene.cs @@ -44,7 +44,7 @@ namespace osu.Game.Tests.Visual private void beatmapChanged(ValueChangedEvent e) { Clock.ControlPointInfo = e.NewValue.Beatmap.ControlPointInfo; - Clock.ChangeSource((IAdjustableClock)MusicController.CurrentTrack ?? new StopwatchClock()); + Clock.ChangeSource((IAdjustableClock)MusicController.CurrentTrack); Clock.ProcessFrame(); } From b08ebe6f81f9d596920ba602e04a1df9cb90798a Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 7 Aug 2020 21:14:45 +0900 Subject: [PATCH 122/434] More inspections (rider is broken) --- osu.Game/Screens/Edit/Editor.cs | 4 +--- osu.Game/Tests/Visual/EditorClockTestScene.cs | 3 +-- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index 1a7d76ba8f..78fa6c74b0 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -14,7 +14,6 @@ using osu.Framework.Bindables; using osu.Framework.Graphics.UserInterface; using osu.Framework.Input.Events; using osu.Framework.Platform; -using osu.Framework.Timing; using osu.Game.Graphics.UserInterface; using osu.Game.Screens.Edit.Components; using osu.Game.Screens.Edit.Components.Menus; @@ -83,9 +82,8 @@ namespace osu.Game.Screens.Edit beatDivisor.BindValueChanged(divisor => Beatmap.Value.BeatmapInfo.BeatDivisor = divisor.NewValue); // Todo: should probably be done at a DrawableRuleset level to share logic with Player. - var sourceClock = (IAdjustableClock)musicController.CurrentTrack; clock = new EditorClock(Beatmap.Value, musicController.CurrentTrack.Length, beatDivisor) { IsCoupled = false }; - clock.ChangeSource(sourceClock); + clock.ChangeSource(musicController.CurrentTrack); dependencies.CacheAs(clock); AddInternal(clock); diff --git a/osu.Game/Tests/Visual/EditorClockTestScene.cs b/osu.Game/Tests/Visual/EditorClockTestScene.cs index 1009151ac4..59c9329d37 100644 --- a/osu.Game/Tests/Visual/EditorClockTestScene.cs +++ b/osu.Game/Tests/Visual/EditorClockTestScene.cs @@ -4,7 +4,6 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Input.Events; -using osu.Framework.Timing; using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Screens.Edit; @@ -44,7 +43,7 @@ namespace osu.Game.Tests.Visual private void beatmapChanged(ValueChangedEvent e) { Clock.ControlPointInfo = e.NewValue.Beatmap.ControlPointInfo; - Clock.ChangeSource((IAdjustableClock)MusicController.CurrentTrack); + Clock.ChangeSource(MusicController.CurrentTrack); Clock.ProcessFrame(); } From 08820c62ec6ab6121b60c59ad8e89f3dfbcef3f5 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 7 Aug 2020 21:36:02 +0900 Subject: [PATCH 123/434] Add back removed nullcheck --- osu.Game/Audio/PreviewTrackManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Audio/PreviewTrackManager.cs b/osu.Game/Audio/PreviewTrackManager.cs index 1c68ce71d4..862be41c1a 100644 --- a/osu.Game/Audio/PreviewTrackManager.cs +++ b/osu.Game/Audio/PreviewTrackManager.cs @@ -48,7 +48,7 @@ namespace osu.Game.Audio track.Started += () => Schedule(() => { - CurrentTrack.Stop(); + CurrentTrack?.Stop(); CurrentTrack = track; audio.Tracks.AddAdjustment(AdjustableProperty.Volume, muteBindable); }); From b6fb7a0d39e6a5667be3fa45d90a3f2a5072d5ed Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 7 Aug 2020 22:05:58 +0900 Subject: [PATCH 124/434] Fix possibly setting null track --- .../Visual/Online/TestSceneNowPlayingCommand.cs | 2 +- osu.Game/Beatmaps/DummyWorkingBeatmap.cs | 3 ++- osu.Game/Overlays/MusicController.cs | 8 +++----- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneNowPlayingCommand.cs b/osu.Game.Tests/Visual/Online/TestSceneNowPlayingCommand.cs index 103308d34d..9662bd65b4 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneNowPlayingCommand.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneNowPlayingCommand.cs @@ -59,7 +59,7 @@ namespace osu.Game.Tests.Visual.Online { AddStep("Set activity", () => API.Activity.Value = new UserActivity.InLobby()); - AddStep("Set beatmap", () => Beatmap.Value = new DummyWorkingBeatmap(null, null) + AddStep("Set beatmap", () => Beatmap.Value = new DummyWorkingBeatmap(Audio, null) { BeatmapInfo = { OnlineBeatmapID = hasOnlineId ? 1234 : (int?)null } }); diff --git a/osu.Game/Beatmaps/DummyWorkingBeatmap.cs b/osu.Game/Beatmaps/DummyWorkingBeatmap.cs index 8080e94075..ca801cf745 100644 --- a/osu.Game/Beatmaps/DummyWorkingBeatmap.cs +++ b/osu.Game/Beatmaps/DummyWorkingBeatmap.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using JetBrains.Annotations; using osu.Framework.Audio; using osu.Framework.Audio.Track; using osu.Framework.Extensions.IEnumerableExtensions; @@ -19,7 +20,7 @@ namespace osu.Game.Beatmaps { private readonly TextureStore textures; - public DummyWorkingBeatmap(AudioManager audio, TextureStore textures) + public DummyWorkingBeatmap([NotNull] AudioManager audio, TextureStore textures) : base(new BeatmapInfo { Metadata = new BeatmapMetadata diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index 3e93ae2ccd..2aed46a1d0 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -321,15 +321,13 @@ namespace osu.Game.Overlays private void changeTrack() { CurrentTrack.Expire(); - CurrentTrack = null; + CurrentTrack = new DrawableTrack(new TrackVirtual(1000)); if (current != null) - { CurrentTrack = new DrawableTrack(current.GetRealTrack()); - CurrentTrack.Completed += () => onTrackCompleted(current); - AddInternal(CurrentTrack); - } + CurrentTrack.Completed += () => onTrackCompleted(current); + AddInternal(CurrentTrack); } private void onTrackCompleted(WorkingBeatmap workingBeatmap) From d1765c8a45e3940974c35ec2c75366c14a96a4e1 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 7 Aug 2020 22:06:04 +0900 Subject: [PATCH 125/434] Fix using the wrong music controller instance --- .../Navigation/TestSceneScreenNavigation.cs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs b/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs index d2c71c1d17..0f06010a6a 100644 --- a/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs +++ b/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs @@ -60,13 +60,13 @@ namespace osu.Game.Tests.Visual.Navigation AddUntilStep("wait for player", () => (player = Game.ScreenStack.CurrentScreen as Player) != null); AddUntilStep("wait for fail", () => player.HasFailed); - AddUntilStep("wait for track stop", () => !MusicController.IsPlaying); - AddAssert("Ensure time before preview point", () => MusicController.CurrentTrack.CurrentTime < beatmap().Metadata.PreviewTime); + AddUntilStep("wait for track stop", () => !Game.MusicController.IsPlaying); + AddAssert("Ensure time before preview point", () => Game.MusicController.CurrentTrack.CurrentTime < beatmap().Metadata.PreviewTime); pushEscape(); - AddUntilStep("wait for track playing", () => MusicController.IsPlaying); - AddAssert("Ensure time wasn't reset to preview point", () => MusicController.CurrentTrack.CurrentTime < beatmap().Metadata.PreviewTime); + AddUntilStep("wait for track playing", () => Game.MusicController.IsPlaying); + AddAssert("Ensure time wasn't reset to preview point", () => Game.MusicController.CurrentTrack.CurrentTime < beatmap().Metadata.PreviewTime); } [Test] @@ -76,11 +76,11 @@ namespace osu.Game.Tests.Visual.Navigation PushAndConfirm(() => songSelect = new TestSongSelect()); - AddUntilStep("wait for no track", () => MusicController.CurrentTrack.IsDummyDevice); + AddUntilStep("wait for no track", () => Game.MusicController.CurrentTrack.IsDummyDevice); AddStep("return to menu", () => songSelect.Exit()); - AddUntilStep("wait for track", () => MusicController.CurrentTrack.IsDummyDevice == false && MusicController.IsPlaying); + AddUntilStep("wait for track", () => Game.MusicController.CurrentTrack.IsDummyDevice == false && Game.MusicController.IsPlaying); } [Test] @@ -135,12 +135,12 @@ namespace osu.Game.Tests.Visual.Navigation AddUntilStep("Wait for music controller", () => Game.MusicController.IsLoaded); AddStep("Seek close to end", () => { - Game.MusicController.SeekTo(MusicController.CurrentTrack.Length - 1000); - MusicController.CurrentTrack.Completed += () => trackCompleted = true; + Game.MusicController.SeekTo(Game.MusicController.CurrentTrack.Length - 1000); + Game.MusicController.CurrentTrack.Completed += () => trackCompleted = true; }); AddUntilStep("Track was completed", () => trackCompleted); - AddUntilStep("Track was restarted", () => MusicController.IsPlaying); + AddUntilStep("Track was restarted", () => Game.MusicController.IsPlaying); } private void pushEscape() => From e87f50f74f28ca8d5b5c6a0189b3ec2be21a1360 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 7 Aug 2020 22:31:41 +0900 Subject: [PATCH 126/434] Rename method --- osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs | 2 +- osu.Game.Tests/Gameplay/TestSceneGameplayClockContainer.cs | 2 +- osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs | 2 +- osu.Game.Tests/Visual/Gameplay/TestSceneSkipOverlay.cs | 2 +- osu.Game.Tests/WaveformTestBeatmap.cs | 2 +- osu.Game/Beatmaps/BeatmapManager.cs | 2 +- osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs | 2 +- osu.Game/Beatmaps/DummyWorkingBeatmap.cs | 2 +- osu.Game/Beatmaps/IWorkingBeatmap.cs | 5 +++++ osu.Game/Beatmaps/WorkingBeatmap.cs | 4 ++-- osu.Game/Overlays/MusicController.cs | 2 +- osu.Game/Screens/Edit/LegacyEditorBeatmapPatcher.cs | 2 +- osu.Game/Screens/Menu/IntroScreen.cs | 2 +- osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs | 2 +- osu.Game/Tests/Beatmaps/TestWorkingBeatmap.cs | 2 +- osu.Game/Tests/Visual/OsuTestScene.cs | 2 +- 16 files changed, 21 insertions(+), 16 deletions(-) diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs index 30331e98d2..4a11e1785b 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs @@ -106,7 +106,7 @@ namespace osu.Game.Tests.Beatmaps.Formats protected override Texture GetBackground() => throw new NotImplementedException(); - protected override Track GetTrack() => throw new NotImplementedException(); + protected override Track GetBeatmapTrack() => throw new NotImplementedException(); } } } diff --git a/osu.Game.Tests/Gameplay/TestSceneGameplayClockContainer.cs b/osu.Game.Tests/Gameplay/TestSceneGameplayClockContainer.cs index 40f6cecd9a..bb60ae73db 100644 --- a/osu.Game.Tests/Gameplay/TestSceneGameplayClockContainer.cs +++ b/osu.Game.Tests/Gameplay/TestSceneGameplayClockContainer.cs @@ -22,7 +22,7 @@ namespace osu.Game.Tests.Gameplay AddStep("create container", () => { var working = CreateWorkingBeatmap(new OsuRuleset().RulesetInfo); - Add(gcc = new GameplayClockContainer(working.GetRealTrack(), working, Array.Empty(), 0)); + Add(gcc = new GameplayClockContainer(working.GetTrack(), working, Array.Empty(), 0)); }); AddStep("start track", () => gcc.Start()); diff --git a/osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs b/osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs index 720436fae4..360e7eccdc 100644 --- a/osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs +++ b/osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs @@ -61,7 +61,7 @@ namespace osu.Game.Tests.Gameplay { var working = CreateWorkingBeatmap(new OsuRuleset().RulesetInfo); - Add(gameplayContainer = new GameplayClockContainer(working.GetRealTrack(), working, Array.Empty(), 0)); + Add(gameplayContainer = new GameplayClockContainer(working.GetTrack(), working, Array.Empty(), 0)); gameplayContainer.Add(sample = new DrawableStoryboardSample(new StoryboardSampleInfo(string.Empty, 0, 1)) { diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSkipOverlay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSkipOverlay.cs index 68110d759c..58fd760fc3 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSkipOverlay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSkipOverlay.cs @@ -34,7 +34,7 @@ namespace osu.Game.Tests.Visual.Gameplay var working = CreateWorkingBeatmap(CreateBeatmap(new OsuRuleset().RulesetInfo)); - Child = gameplayClockContainer = new GameplayClockContainer(working.GetRealTrack(), working, Array.Empty(), 0) + Child = gameplayClockContainer = new GameplayClockContainer(working.GetTrack(), working, Array.Empty(), 0) { RelativeSizeAxes = Axes.Both, Children = new Drawable[] diff --git a/osu.Game.Tests/WaveformTestBeatmap.cs b/osu.Game.Tests/WaveformTestBeatmap.cs index 90c91eb007..7dc5ce1d7f 100644 --- a/osu.Game.Tests/WaveformTestBeatmap.cs +++ b/osu.Game.Tests/WaveformTestBeatmap.cs @@ -52,7 +52,7 @@ namespace osu.Game.Tests protected override Waveform GetWaveform() => new Waveform(trackStore.GetStream(firstAudioFile)); - protected override Track GetTrack() => trackStore.Get(firstAudioFile); + protected override Track GetBeatmapTrack() => trackStore.Get(firstAudioFile); private string firstAudioFile { diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index f22f41531a..e001185da9 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -476,7 +476,7 @@ namespace osu.Game.Beatmaps protected override IBeatmap GetBeatmap() => beatmap; protected override Texture GetBackground() => null; - protected override Track GetTrack() => null; + protected override Track GetBeatmapTrack() => null; } } diff --git a/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs b/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs index a54d46c1b1..f1289cd3aa 100644 --- a/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs @@ -70,7 +70,7 @@ namespace osu.Game.Beatmaps } } - protected override Track GetTrack() + protected override Track GetBeatmapTrack() { try { diff --git a/osu.Game/Beatmaps/DummyWorkingBeatmap.cs b/osu.Game/Beatmaps/DummyWorkingBeatmap.cs index ca801cf745..af2a2ac250 100644 --- a/osu.Game/Beatmaps/DummyWorkingBeatmap.cs +++ b/osu.Game/Beatmaps/DummyWorkingBeatmap.cs @@ -45,7 +45,7 @@ namespace osu.Game.Beatmaps protected override Texture GetBackground() => textures?.Get(@"Backgrounds/bg4"); - protected override Track GetTrack() => GetVirtualTrack(); + protected override Track GetBeatmapTrack() => GetVirtualTrack(); private class DummyRulesetInfo : RulesetInfo { diff --git a/osu.Game/Beatmaps/IWorkingBeatmap.cs b/osu.Game/Beatmaps/IWorkingBeatmap.cs index 086b7502a2..e020625b99 100644 --- a/osu.Game/Beatmaps/IWorkingBeatmap.cs +++ b/osu.Game/Beatmaps/IWorkingBeatmap.cs @@ -54,5 +54,10 @@ namespace osu.Game.Beatmaps /// The converted . /// If could not be converted to . IBeatmap GetPlayableBeatmap(RulesetInfo ruleset, IReadOnlyList mods = null, TimeSpan? timeout = null); + + /// + /// Retrieves the which this provides. + /// + Track GetTrack(); } } diff --git a/osu.Game/Beatmaps/WorkingBeatmap.cs b/osu.Game/Beatmaps/WorkingBeatmap.cs index 171201ca68..af6a67ad3f 100644 --- a/osu.Game/Beatmaps/WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/WorkingBeatmap.cs @@ -249,9 +249,9 @@ namespace osu.Game.Beatmaps protected abstract Texture GetBackground(); private readonly RecyclableLazy background; - public Track GetRealTrack() => GetTrack() ?? GetVirtualTrack(1000); + public Track GetTrack() => GetBeatmapTrack() ?? GetVirtualTrack(1000); - protected abstract Track GetTrack(); + protected abstract Track GetBeatmapTrack(); public bool WaveformLoaded => waveform.IsResultAvailable; public Waveform Waveform => waveform.Value; diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index 2aed46a1d0..cf420c3b91 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -324,7 +324,7 @@ namespace osu.Game.Overlays CurrentTrack = new DrawableTrack(new TrackVirtual(1000)); if (current != null) - CurrentTrack = new DrawableTrack(current.GetRealTrack()); + CurrentTrack = new DrawableTrack(current.GetTrack()); CurrentTrack.Completed += () => onTrackCompleted(current); AddInternal(CurrentTrack); diff --git a/osu.Game/Screens/Edit/LegacyEditorBeatmapPatcher.cs b/osu.Game/Screens/Edit/LegacyEditorBeatmapPatcher.cs index fc3dd4c105..57b7ce6940 100644 --- a/osu.Game/Screens/Edit/LegacyEditorBeatmapPatcher.cs +++ b/osu.Game/Screens/Edit/LegacyEditorBeatmapPatcher.cs @@ -107,7 +107,7 @@ namespace osu.Game.Screens.Edit protected override Texture GetBackground() => throw new NotImplementedException(); - protected override Track GetTrack() => throw new NotImplementedException(); + protected override Track GetBeatmapTrack() => throw new NotImplementedException(); } } } diff --git a/osu.Game/Screens/Menu/IntroScreen.cs b/osu.Game/Screens/Menu/IntroScreen.cs index 7e327261ab..6e85abf7dc 100644 --- a/osu.Game/Screens/Menu/IntroScreen.cs +++ b/osu.Game/Screens/Menu/IntroScreen.cs @@ -115,7 +115,7 @@ namespace osu.Game.Screens.Menu if (setInfo != null) { initialBeatmap = beatmaps.GetWorkingBeatmap(setInfo.Beatmaps[0]); - UsingThemedIntro = initialBeatmap.GetRealTrack().IsDummyDevice == false; + UsingThemedIntro = initialBeatmap.GetTrack().IsDummyDevice == false; } return UsingThemedIntro; diff --git a/osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs b/osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs index 6ada632850..e492069c5e 100644 --- a/osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs +++ b/osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs @@ -208,7 +208,7 @@ namespace osu.Game.Tests.Beatmaps protected override Texture GetBackground() => throw new NotImplementedException(); - protected override Track GetTrack() => throw new NotImplementedException(); + protected override Track GetBeatmapTrack() => throw new NotImplementedException(); protected override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap, Ruleset ruleset) { diff --git a/osu.Game/Tests/Beatmaps/TestWorkingBeatmap.cs b/osu.Game/Tests/Beatmaps/TestWorkingBeatmap.cs index ee04142035..d091da3206 100644 --- a/osu.Game/Tests/Beatmaps/TestWorkingBeatmap.cs +++ b/osu.Game/Tests/Beatmaps/TestWorkingBeatmap.cs @@ -35,6 +35,6 @@ namespace osu.Game.Tests.Beatmaps protected override Texture GetBackground() => null; - protected override Track GetTrack() => null; + protected override Track GetBeatmapTrack() => null; } } diff --git a/osu.Game/Tests/Visual/OsuTestScene.cs b/osu.Game/Tests/Visual/OsuTestScene.cs index b0d15bf442..756074c0b3 100644 --- a/osu.Game/Tests/Visual/OsuTestScene.cs +++ b/osu.Game/Tests/Visual/OsuTestScene.cs @@ -223,7 +223,7 @@ namespace osu.Game.Tests.Visual store?.Dispose(); } - protected override Track GetTrack() => track; + protected override Track GetBeatmapTrack() => track; public class TrackVirtualStore : AudioCollectionManager, ITrackStore { From b8373e89b7e30e0370170f10bf16c1d7bb36b835 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 7 Aug 2020 23:05:59 +0900 Subject: [PATCH 127/434] Move beatmap bind to BDL load() --- osu.Game/Overlays/MusicController.cs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index cf420c3b91..26df48171e 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -79,12 +79,9 @@ namespace osu.Game.Overlays managerRemoved.BindValueChanged(beatmapRemoved); beatmapSets.AddRange(beatmaps.GetAllUsableBeatmapSets(IncludedDetails.Minimal, true).OrderBy(_ => RNG.Next())); - } - - protected override void LoadComplete() - { - base.LoadComplete(); + // Todo: These binds really shouldn't be here, but are unlikely to cause any issues for now. + // They are placed here for now since some tests rely on setting the beatmap _and_ their hierarchies inside their load(), which runs before the MusicController's load(). beatmap.BindValueChanged(beatmapChanged, true); mods.BindValueChanged(_ => ResetTrackAdjustments(), true); } From 2351701ade19e518b2d07f308af5237df2e7eedd Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 7 Aug 2020 23:08:51 +0900 Subject: [PATCH 128/434] Fix test not having a long enough track --- .../UserInterface/TestSceneNowPlayingOverlay.cs | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneNowPlayingOverlay.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneNowPlayingOverlay.cs index cadecbbef0..c14a1ddbf2 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneNowPlayingOverlay.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneNowPlayingOverlay.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System.Collections.Generic; +using System.Linq; using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Audio; @@ -11,6 +12,7 @@ using osu.Game.Beatmaps; using osu.Game.Overlays; using osu.Game.Rulesets; using osu.Game.Rulesets.Osu; +using osu.Game.Tests.Resources; namespace osu.Game.Tests.Visual.UserInterface { @@ -20,8 +22,6 @@ namespace osu.Game.Tests.Visual.UserInterface [Cached] private MusicController musicController = new MusicController(); - private WorkingBeatmap currentBeatmap; - private NowPlayingOverlay nowPlayingOverlay; private RulesetStore rulesets; @@ -76,8 +76,13 @@ namespace osu.Game.Tests.Visual.UserInterface } }).Wait(), 5); - AddStep(@"Next track", () => musicController.NextTrack()); - AddStep("Store track", () => currentBeatmap = Beatmap.Value); + WorkingBeatmap currentBeatmap = null; + + AddStep("import beatmap with track", () => + { + var setWithTrack = manager.Import(TestResources.GetTestBeatmapForImport()).Result; + Beatmap.Value = currentBeatmap = manager.GetWorkingBeatmap(setWithTrack.Beatmaps.First()); + }); AddStep(@"Seek track to 6 second", () => musicController.SeekTo(6000)); AddUntilStep(@"Wait for current time to update", () => musicController.CurrentTrack.CurrentTime > 5000); From 87ce1e3558d598388c38cd078840d7148c95f0fd Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Sat, 8 Aug 2020 00:58:04 +0900 Subject: [PATCH 129/434] Remove impossible null case (DummyWorkingBeatmap) --- osu.Game/Overlays/MusicController.cs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index 26df48171e..c5ba82288c 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -318,12 +318,9 @@ namespace osu.Game.Overlays private void changeTrack() { CurrentTrack.Expire(); - CurrentTrack = new DrawableTrack(new TrackVirtual(1000)); - - if (current != null) - CurrentTrack = new DrawableTrack(current.GetTrack()); - + CurrentTrack = new DrawableTrack(current.GetTrack()); CurrentTrack.Completed += () => onTrackCompleted(current); + AddInternal(CurrentTrack); } From 1090137da3d46e76f2be85d26dc14a6696393a84 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 8 Aug 2020 23:23:02 +0900 Subject: [PATCH 130/434] Adjust comment to read better MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bartłomiej Dach --- osu.Game/Skinning/SkinnableSound.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Skinning/SkinnableSound.cs b/osu.Game/Skinning/SkinnableSound.cs index 8c18e83e92..7ee0b474de 100644 --- a/osu.Game/Skinning/SkinnableSound.cs +++ b/osu.Game/Skinning/SkinnableSound.cs @@ -34,7 +34,7 @@ namespace osu.Game.Skinning /// Defaults to false unless . /// /// - /// Can serve as an optimisation if it is known ahead-of-time that this behaviour will not negatively affect behaviour. + /// Can serve as an optimisation if it is known ahead-of-time that this behaviour is allowed in a given use case. /// protected bool SkipPlayWhenZeroVolume => !Looping; From ffb2e56a8d31e6b62c3715380967e5b63711b672 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 8 Aug 2020 23:25:52 +0900 Subject: [PATCH 131/434] Reverse direction of bool to make mental parsing easier --- osu.Game/Skinning/SkinnableSound.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Skinning/SkinnableSound.cs b/osu.Game/Skinning/SkinnableSound.cs index 7739be693d..32f49367f0 100644 --- a/osu.Game/Skinning/SkinnableSound.cs +++ b/osu.Game/Skinning/SkinnableSound.cs @@ -37,7 +37,7 @@ namespace osu.Game.Skinning /// /// Can serve as an optimisation if it is known ahead-of-time that this behaviour is allowed in a given use case. /// - protected bool SkipPlayWhenZeroVolume => !Looping; + protected bool PlayWhenZeroVolume => Looping; private readonly AudioContainer samplesContainer; @@ -98,7 +98,7 @@ namespace osu.Game.Skinning { samplesContainer.ForEach(c => { - if (!SkipPlayWhenZeroVolume || c.AggregateVolume.Value > 0) + if (PlayWhenZeroVolume || c.AggregateVolume.Value > 0) c.Play(); }); } From a72a48624d82fb1f07264403e31f8744d0ae5ef8 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sun, 9 Aug 2020 05:16:08 +0300 Subject: [PATCH 132/434] Remove NewsPostDrawableDate --- .../Dashboard/Home/News/HomeNewsGroupPanel.cs | 69 +++++++++++-------- .../Dashboard/Home/News/HomeNewsPanel.cs | 34 ++++++--- .../Home/News/HomeNewsPanelFooter.cs | 6 +- .../Home/News/NewsPostDrawableDate.cs | 37 ---------- 4 files changed, 67 insertions(+), 79 deletions(-) delete mode 100644 osu.Game/Overlays/Dashboard/Home/News/NewsPostDrawableDate.cs diff --git a/osu.Game/Overlays/Dashboard/Home/News/HomeNewsGroupPanel.cs b/osu.Game/Overlays/Dashboard/Home/News/HomeNewsGroupPanel.cs index cd1c5393c5..48ecaf57dc 100644 --- a/osu.Game/Overlays/Dashboard/Home/News/HomeNewsGroupPanel.cs +++ b/osu.Game/Overlays/Dashboard/Home/News/HomeNewsGroupPanel.cs @@ -7,6 +7,7 @@ using System.Linq; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Cursor; using osu.Game.Graphics; using osu.Game.Online.API.Requests.Responses; @@ -44,41 +45,51 @@ namespace osu.Game.Overlays.Dashboard.Home.News protected override Drawable CreateContent(APINewsPost post) => new NewsTitleLink(post); - protected override NewsPostDrawableDate CreateDate(DateTimeOffset date) => new Date(date); + protected override Drawable CreateDate(DateTimeOffset date) => new Date(date); + } - private class Date : NewsPostDrawableDate + private class Date : CompositeDrawable, IHasCustomTooltip + { + public ITooltip GetCustomTooltip() => new DateTooltip(); + + public object TooltipContent => date; + + private readonly DateTimeOffset date; + + public Date(DateTimeOffset date) { - public Date(DateTimeOffset date) - : base(date) + this.date = date; + } + + [BackgroundDependencyLoader] + private void load(OverlayColourProvider colourProvider) + { + TextFlowContainer textFlow; + + AutoSizeAxes = Axes.Both; + Anchor = Anchor.TopRight; + Origin = Anchor.TopRight; + InternalChild = textFlow = new TextFlowContainer(t => { - } - - protected override Drawable CreateDate(DateTimeOffset date, OverlayColourProvider colourProvider) + t.Colour = colourProvider.Light1; + }) { - var drawableDate = new TextFlowContainer(t => - { - t.Colour = colourProvider.Light1; - }) - { - Anchor = Anchor.TopRight, - Origin = Anchor.TopRight, - AutoSizeAxes = Axes.Both, - Direction = FillDirection.Horizontal, - Margin = new MarginPadding { Vertical = 5 } - }; + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Margin = new MarginPadding { Vertical = 5 } + }; - drawableDate.AddText($"{date:dd} ", t => - { - t.Font = OsuFont.GetFont(size: 14, weight: FontWeight.Bold); - }); + textFlow.AddText($"{date:dd}", t => + { + t.Font = OsuFont.GetFont(size: 14, weight: FontWeight.Bold); + }); - drawableDate.AddText($"{date:MMM}", t => - { - t.Font = OsuFont.GetFont(size: 14, weight: FontWeight.Regular); - }); - - return drawableDate; - } + textFlow.AddText($"{date: MMM}", t => + { + t.Font = OsuFont.GetFont(size: 14, weight: FontWeight.Regular); + }); } } } diff --git a/osu.Game/Overlays/Dashboard/Home/News/HomeNewsPanel.cs b/osu.Game/Overlays/Dashboard/Home/News/HomeNewsPanel.cs index 3548b7c88d..786c376fc9 100644 --- a/osu.Game/Overlays/Dashboard/Home/News/HomeNewsPanel.cs +++ b/osu.Game/Overlays/Dashboard/Home/News/HomeNewsPanel.cs @@ -5,6 +5,7 @@ using System; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Cursor; using osu.Framework.Platform; using osu.Game.Graphics; using osu.Game.Graphics.Containers; @@ -84,14 +85,14 @@ namespace osu.Game.Overlays.Dashboard.Home.News private class Footer : HomeNewsPanelFooter { - protected override float BarPading => 10; + protected override float BarPadding => 10; public Footer(APINewsPost post) : base(post) { } - protected override NewsPostDrawableDate CreateDate(DateTimeOffset date) => new Date(date); + protected override Drawable CreateDate(DateTimeOffset date) => new Date(date); protected override Drawable CreateContent(APINewsPost post) => new FillFlowContainer { @@ -114,16 +115,29 @@ namespace osu.Game.Overlays.Dashboard.Home.News } } }; + } - private class Date : NewsPostDrawableDate + private class Date : CompositeDrawable, IHasCustomTooltip + { + public ITooltip GetCustomTooltip() => new DateTooltip(); + + public object TooltipContent => date; + + private readonly DateTimeOffset date; + + public Date(DateTimeOffset date) { - public Date(DateTimeOffset date) - : base(date) - { - Margin = new MarginPadding { Top = 10 }; - } + this.date = date; + } - protected override Drawable CreateDate(DateTimeOffset date, OverlayColourProvider colourProvider) => new FillFlowContainer + [BackgroundDependencyLoader] + private void load(OverlayColourProvider colourProvider) + { + AutoSizeAxes = Axes.Both; + Anchor = Anchor.TopRight; + Origin = Anchor.TopRight; + Margin = new MarginPadding { Top = 10 }; + InternalChild = new FillFlowContainer { AutoSizeAxes = Axes.Both, Direction = FillDirection.Vertical, @@ -137,7 +151,7 @@ namespace osu.Game.Overlays.Dashboard.Home.News Origin = Anchor.TopRight, Font = OsuFont.GetFont(weight: FontWeight.Bold), // using Bold since there is no 800 weight alternative Colour = colourProvider.Light1, - Text = $"{date: dd}" + Text = $"{date:dd}" }, new TextFlowContainer(f => { diff --git a/osu.Game/Overlays/Dashboard/Home/News/HomeNewsPanelFooter.cs b/osu.Game/Overlays/Dashboard/Home/News/HomeNewsPanelFooter.cs index 591f53ac4a..3e3301b603 100644 --- a/osu.Game/Overlays/Dashboard/Home/News/HomeNewsPanelFooter.cs +++ b/osu.Game/Overlays/Dashboard/Home/News/HomeNewsPanelFooter.cs @@ -12,7 +12,7 @@ namespace osu.Game.Overlays.Dashboard.Home.News { public abstract class HomeNewsPanelFooter : CompositeDrawable { - protected virtual float BarPading { get; } = 0; + protected virtual float BarPadding { get; } = 0; private readonly APINewsPost post; @@ -48,7 +48,7 @@ namespace osu.Game.Overlays.Dashboard.Home.News new Container { RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding { Vertical = BarPading }, + Padding = new MarginPadding { Vertical = BarPadding }, Child = new Box { Anchor = Anchor.TopCentre, @@ -72,7 +72,7 @@ namespace osu.Game.Overlays.Dashboard.Home.News }; } - protected abstract NewsPostDrawableDate CreateDate(DateTimeOffset date); + protected abstract Drawable CreateDate(DateTimeOffset date); protected abstract Drawable CreateContent(APINewsPost post); } diff --git a/osu.Game/Overlays/Dashboard/Home/News/NewsPostDrawableDate.cs b/osu.Game/Overlays/Dashboard/Home/News/NewsPostDrawableDate.cs deleted file mode 100644 index 8ba58e27a7..0000000000 --- a/osu.Game/Overlays/Dashboard/Home/News/NewsPostDrawableDate.cs +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using System; -using osu.Framework.Allocation; -using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Cursor; -using osu.Game.Graphics; -using osu.Framework.Graphics; - -namespace osu.Game.Overlays.Dashboard.Home.News -{ - public abstract class NewsPostDrawableDate : CompositeDrawable, IHasCustomTooltip - { - public ITooltip GetCustomTooltip() => new DateTooltip(); - - public object TooltipContent => date; - - private readonly DateTimeOffset date; - - protected NewsPostDrawableDate(DateTimeOffset date) - { - this.date = date; - } - - [BackgroundDependencyLoader] - private void load(OverlayColourProvider colourProvider) - { - AutoSizeAxes = Axes.Both; - Anchor = Anchor.TopRight; - Origin = Anchor.TopRight; - InternalChild = CreateDate(date, colourProvider); - } - - protected abstract Drawable CreateDate(DateTimeOffset date, OverlayColourProvider colourProvider); - } -} From d8f89306917a66833db4d1587f03efb295aab3de Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sun, 9 Aug 2020 05:28:43 +0300 Subject: [PATCH 133/434] Remove HomeNewsPanelFooter --- .../Dashboard/Home/News/CollapsedNewsPanel.cs | 115 ++++++++++++++++++ .../Dashboard/Home/News/HomeNewsGroupPanel.cs | 60 --------- .../Dashboard/Home/News/HomeNewsPanel.cs | 95 +++++++++------ .../Home/News/HomeNewsPanelFooter.cs | 79 ------------ 4 files changed, 174 insertions(+), 175 deletions(-) create mode 100644 osu.Game/Overlays/Dashboard/Home/News/CollapsedNewsPanel.cs delete mode 100644 osu.Game/Overlays/Dashboard/Home/News/HomeNewsPanelFooter.cs diff --git a/osu.Game/Overlays/Dashboard/Home/News/CollapsedNewsPanel.cs b/osu.Game/Overlays/Dashboard/Home/News/CollapsedNewsPanel.cs new file mode 100644 index 0000000000..7dbc6a8f87 --- /dev/null +++ b/osu.Game/Overlays/Dashboard/Home/News/CollapsedNewsPanel.cs @@ -0,0 +1,115 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System; +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Cursor; +using osu.Framework.Graphics.Shapes; +using osu.Game.Graphics; +using osu.Game.Online.API.Requests.Responses; + +namespace osu.Game.Overlays.Dashboard.Home.News +{ + public class CollapsedNewsPanel : CompositeDrawable + { + private readonly APINewsPost post; + + public CollapsedNewsPanel(APINewsPost post) + { + this.post = post; + } + + [BackgroundDependencyLoader] + private void load(OverlayColourProvider colourProvider) + { + RelativeSizeAxes = Axes.X; + AutoSizeAxes = Axes.Y; + InternalChild = new GridContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + RowDimensions = new[] + { + new Dimension(GridSizeMode.AutoSize) + }, + ColumnDimensions = new[] + { + new Dimension(GridSizeMode.Absolute, size: 60), + new Dimension(GridSizeMode.Absolute, size: 20), + new Dimension() + }, + Content = new[] + { + new Drawable[] + { + new Date(post.PublishedAt), + new Box + { + Anchor = Anchor.TopCentre, + Origin = Anchor.TopRight, + Width = 1, + RelativeSizeAxes = Axes.Y, + Colour = colourProvider.Light1 + }, + new Container + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Padding = new MarginPadding { Right = 10 }, + Child = new NewsTitleLink(post) + } + } + } + }; + } + + private class Date : CompositeDrawable, IHasCustomTooltip + { + public ITooltip GetCustomTooltip() => new DateTooltip(); + + public object TooltipContent => date; + + private readonly DateTimeOffset date; + + public Date(DateTimeOffset date) + { + this.date = date; + } + + [BackgroundDependencyLoader] + private void load(OverlayColourProvider colourProvider) + { + TextFlowContainer textFlow; + + AutoSizeAxes = Axes.Both; + Anchor = Anchor.TopRight; + Origin = Anchor.TopRight; + InternalChild = textFlow = new TextFlowContainer(t => + { + t.Colour = colourProvider.Light1; + }) + { + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Margin = new MarginPadding { Vertical = 5 } + }; + + textFlow.AddText($"{date:dd}", t => + { + t.Font = OsuFont.GetFont(size: 14, weight: FontWeight.Bold); + }); + + textFlow.AddText($"{date: MMM}", t => + { + t.Font = OsuFont.GetFont(size: 14, weight: FontWeight.Regular); + }); + } + } + } +} diff --git a/osu.Game/Overlays/Dashboard/Home/News/HomeNewsGroupPanel.cs b/osu.Game/Overlays/Dashboard/Home/News/HomeNewsGroupPanel.cs index 48ecaf57dc..6007f1408b 100644 --- a/osu.Game/Overlays/Dashboard/Home/News/HomeNewsGroupPanel.cs +++ b/osu.Game/Overlays/Dashboard/Home/News/HomeNewsGroupPanel.cs @@ -1,14 +1,11 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System; using System.Collections.Generic; using System.Linq; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Cursor; -using osu.Game.Graphics; using osu.Game.Online.API.Requests.Responses; namespace osu.Game.Overlays.Dashboard.Home.News @@ -35,62 +32,5 @@ namespace osu.Game.Overlays.Dashboard.Home.News Children = posts.Select(p => new CollapsedNewsPanel(p)).ToArray() }; } - - private class CollapsedNewsPanel : HomeNewsPanelFooter - { - public CollapsedNewsPanel(APINewsPost post) - : base(post) - { - } - - protected override Drawable CreateContent(APINewsPost post) => new NewsTitleLink(post); - - protected override Drawable CreateDate(DateTimeOffset date) => new Date(date); - } - - private class Date : CompositeDrawable, IHasCustomTooltip - { - public ITooltip GetCustomTooltip() => new DateTooltip(); - - public object TooltipContent => date; - - private readonly DateTimeOffset date; - - public Date(DateTimeOffset date) - { - this.date = date; - } - - [BackgroundDependencyLoader] - private void load(OverlayColourProvider colourProvider) - { - TextFlowContainer textFlow; - - AutoSizeAxes = Axes.Both; - Anchor = Anchor.TopRight; - Origin = Anchor.TopRight; - InternalChild = textFlow = new TextFlowContainer(t => - { - t.Colour = colourProvider.Light1; - }) - { - Anchor = Anchor.TopRight, - Origin = Anchor.TopRight, - AutoSizeAxes = Axes.Both, - Direction = FillDirection.Horizontal, - Margin = new MarginPadding { Vertical = 5 } - }; - - textFlow.AddText($"{date:dd}", t => - { - t.Font = OsuFont.GetFont(size: 14, weight: FontWeight.Bold); - }); - - textFlow.AddText($"{date: MMM}", t => - { - t.Font = OsuFont.GetFont(size: 14, weight: FontWeight.Regular); - }); - } - } } } diff --git a/osu.Game/Overlays/Dashboard/Home/News/HomeNewsPanel.cs b/osu.Game/Overlays/Dashboard/Home/News/HomeNewsPanel.cs index 786c376fc9..ca56c33315 100644 --- a/osu.Game/Overlays/Dashboard/Home/News/HomeNewsPanel.cs +++ b/osu.Game/Overlays/Dashboard/Home/News/HomeNewsPanel.cs @@ -6,6 +6,7 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Cursor; +using osu.Framework.Graphics.Shapes; using osu.Framework.Platform; using osu.Game.Graphics; using osu.Game.Graphics.Containers; @@ -27,7 +28,7 @@ namespace osu.Game.Overlays.Dashboard.Home.News } [BackgroundDependencyLoader] - private void load() + private void load(OverlayColourProvider colourProvider) { Children = new Drawable[] { @@ -39,7 +40,63 @@ namespace osu.Game.Overlays.Dashboard.Home.News Children = new Drawable[] { new ClickableNewsBackground(post), - new Footer(post) + new GridContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + RowDimensions = new[] + { + new Dimension(GridSizeMode.AutoSize) + }, + ColumnDimensions = new[] + { + new Dimension(GridSizeMode.Absolute, size: 60), + new Dimension(GridSizeMode.Absolute, size: 20), + new Dimension() + }, + Content = new[] + { + new Drawable[] + { + new Date(post.PublishedAt), + new Container + { + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding { Vertical = 10 }, + Child = new Box + { + Anchor = Anchor.TopCentre, + Origin = Anchor.TopRight, + Width = 1, + RelativeSizeAxes = Axes.Y, + Colour = colourProvider.Light1 + } + }, + new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Margin = new MarginPadding { Top = 5, Bottom = 10 }, + Padding = new MarginPadding { Right = 10 }, + Spacing = new Vector2(0, 10), + Direction = FillDirection.Vertical, + Children = new Drawable[] + { + new NewsTitleLink(post), + new TextFlowContainer(f => + { + f.Font = OsuFont.GetFont(size: 12, weight: FontWeight.Regular); + }) + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Text = post.Preview + } + } + } + } + } + } } } }; @@ -83,40 +140,6 @@ namespace osu.Game.Overlays.Dashboard.Home.News } } - private class Footer : HomeNewsPanelFooter - { - protected override float BarPadding => 10; - - public Footer(APINewsPost post) - : base(post) - { - } - - protected override Drawable CreateDate(DateTimeOffset date) => new Date(date); - - protected override Drawable CreateContent(APINewsPost post) => new FillFlowContainer - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Margin = new MarginPadding { Top = 5, Bottom = 10 }, - Spacing = new Vector2(0, 10), - Direction = FillDirection.Vertical, - Children = new Drawable[] - { - new NewsTitleLink(post), - new TextFlowContainer(f => - { - f.Font = OsuFont.GetFont(size: 12, weight: FontWeight.Regular); - }) - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Text = post.Preview - } - } - }; - } - private class Date : CompositeDrawable, IHasCustomTooltip { public ITooltip GetCustomTooltip() => new DateTooltip(); diff --git a/osu.Game/Overlays/Dashboard/Home/News/HomeNewsPanelFooter.cs b/osu.Game/Overlays/Dashboard/Home/News/HomeNewsPanelFooter.cs deleted file mode 100644 index 3e3301b603..0000000000 --- a/osu.Game/Overlays/Dashboard/Home/News/HomeNewsPanelFooter.cs +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using System; -using osu.Framework.Allocation; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Shapes; -using osu.Game.Online.API.Requests.Responses; - -namespace osu.Game.Overlays.Dashboard.Home.News -{ - public abstract class HomeNewsPanelFooter : CompositeDrawable - { - protected virtual float BarPadding { get; } = 0; - - private readonly APINewsPost post; - - protected HomeNewsPanelFooter(APINewsPost post) - { - this.post = post; - } - - [BackgroundDependencyLoader] - private void load(OverlayColourProvider colourProvider) - { - RelativeSizeAxes = Axes.X; - AutoSizeAxes = Axes.Y; - InternalChild = new GridContainer - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - RowDimensions = new[] - { - new Dimension(GridSizeMode.AutoSize) - }, - ColumnDimensions = new[] - { - new Dimension(GridSizeMode.Absolute, size: 60), - new Dimension(GridSizeMode.Absolute, size: 20), - new Dimension() - }, - Content = new[] - { - new Drawable[] - { - CreateDate(post.PublishedAt), - new Container - { - RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding { Vertical = BarPadding }, - Child = new Box - { - Anchor = Anchor.TopCentre, - Origin = Anchor.TopRight, - Width = 1, - RelativeSizeAxes = Axes.Y, - Colour = colourProvider.Light1 - } - }, - new Container - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - Padding = new MarginPadding { Right = 10 }, - Child = CreateContent(post) - } - } - } - }; - } - - protected abstract Drawable CreateDate(DateTimeOffset date); - - protected abstract Drawable CreateContent(APINewsPost post); - } -} From 1f84e541518a29d0b514f99b9ce8830b68daf68e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 10 Aug 2020 20:16:16 +0900 Subject: [PATCH 134/434] Improve messaging when timeshift token retrieval fails Obviously not a final solution, but should better help self-compiling (or unofficial package) users better understand why this is happening. --- osu.Game/Screens/Multi/Play/TimeshiftPlayer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Multi/Play/TimeshiftPlayer.cs b/osu.Game/Screens/Multi/Play/TimeshiftPlayer.cs index da082692d7..79b4b04722 100644 --- a/osu.Game/Screens/Multi/Play/TimeshiftPlayer.cs +++ b/osu.Game/Screens/Multi/Play/TimeshiftPlayer.cs @@ -64,7 +64,7 @@ namespace osu.Game.Screens.Multi.Play { failed = true; - Logger.Error(e, "Failed to retrieve a score submission token."); + Logger.Error(e, "Failed to retrieve a score submission token.\n\nThis may happen if you are not running an official release of osu! (ie. you are self-compiling)."); Schedule(() => { From 730d13fda6f08a6976c30139ab32d908b78eadc8 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 10 Aug 2020 20:48:04 +0900 Subject: [PATCH 135/434] Always show newly presented overlay at front This feels much better. Does not change order if the overlay to be shown is not yet completely hidden. - Closes #9815. --- osu.Game/OsuGame.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index b5752214bd..623c677991 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -702,6 +702,9 @@ namespace osu.Game if (state.NewValue == Visibility.Hidden) return; singleDisplayOverlays.Where(o => o != overlay).ForEach(o => o.Hide()); + + if (!overlay.IsPresent) + overlayContent.ChangeChildDepth(overlay, (float)-Clock.CurrentTime); }; } From d7de8b2916af35ebd843b08c6f2a3c0d8ad788a6 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 10 Aug 2020 17:17:07 +0000 Subject: [PATCH 136/434] Bump Microsoft.NET.Test.Sdk from 16.6.1 to 16.7.0 Bumps [Microsoft.NET.Test.Sdk](https://github.com/microsoft/vstest) from 16.6.1 to 16.7.0. - [Release notes](https://github.com/microsoft/vstest/releases) - [Commits](https://github.com/microsoft/vstest/compare/v16.6.1...v16.7.0) Signed-off-by: dependabot-preview[bot] --- .../osu.Game.Rulesets.Catch.Tests.csproj | 2 +- .../osu.Game.Rulesets.Mania.Tests.csproj | 2 +- osu.Game.Rulesets.Osu.Tests/osu.Game.Rulesets.Osu.Tests.csproj | 2 +- .../osu.Game.Rulesets.Taiko.Tests.csproj | 2 +- osu.Game.Tests/osu.Game.Tests.csproj | 2 +- osu.Game.Tournament.Tests/osu.Game.Tournament.Tests.csproj | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/osu.Game.Rulesets.Catch.Tests/osu.Game.Rulesets.Catch.Tests.csproj b/osu.Game.Rulesets.Catch.Tests/osu.Game.Rulesets.Catch.Tests.csproj index 7c0b73e8c3..f9d56dfa78 100644 --- a/osu.Game.Rulesets.Catch.Tests/osu.Game.Rulesets.Catch.Tests.csproj +++ b/osu.Game.Rulesets.Catch.Tests/osu.Game.Rulesets.Catch.Tests.csproj @@ -2,7 +2,7 @@ - + diff --git a/osu.Game.Rulesets.Mania.Tests/osu.Game.Rulesets.Mania.Tests.csproj b/osu.Game.Rulesets.Mania.Tests/osu.Game.Rulesets.Mania.Tests.csproj index 972cbec4a2..ed00ed0b4c 100644 --- a/osu.Game.Rulesets.Mania.Tests/osu.Game.Rulesets.Mania.Tests.csproj +++ b/osu.Game.Rulesets.Mania.Tests/osu.Game.Rulesets.Mania.Tests.csproj @@ -2,7 +2,7 @@ - + diff --git a/osu.Game.Rulesets.Osu.Tests/osu.Game.Rulesets.Osu.Tests.csproj b/osu.Game.Rulesets.Osu.Tests/osu.Game.Rulesets.Osu.Tests.csproj index d6a68abaf2..f3837ea6b1 100644 --- a/osu.Game.Rulesets.Osu.Tests/osu.Game.Rulesets.Osu.Tests.csproj +++ b/osu.Game.Rulesets.Osu.Tests/osu.Game.Rulesets.Osu.Tests.csproj @@ -2,7 +2,7 @@ - + diff --git a/osu.Game.Rulesets.Taiko.Tests/osu.Game.Rulesets.Taiko.Tests.csproj b/osu.Game.Rulesets.Taiko.Tests/osu.Game.Rulesets.Taiko.Tests.csproj index ada7ac5d74..e896606ee8 100644 --- a/osu.Game.Rulesets.Taiko.Tests/osu.Game.Rulesets.Taiko.Tests.csproj +++ b/osu.Game.Rulesets.Taiko.Tests/osu.Game.Rulesets.Taiko.Tests.csproj @@ -2,7 +2,7 @@ - + diff --git a/osu.Game.Tests/osu.Game.Tests.csproj b/osu.Game.Tests/osu.Game.Tests.csproj index 4b0506d818..d767973528 100644 --- a/osu.Game.Tests/osu.Game.Tests.csproj +++ b/osu.Game.Tests/osu.Game.Tests.csproj @@ -3,7 +3,7 @@ - + diff --git a/osu.Game.Tournament.Tests/osu.Game.Tournament.Tests.csproj b/osu.Game.Tournament.Tests/osu.Game.Tournament.Tests.csproj index f256b8e4e9..95f5deb2cc 100644 --- a/osu.Game.Tournament.Tests/osu.Game.Tournament.Tests.csproj +++ b/osu.Game.Tournament.Tests/osu.Game.Tournament.Tests.csproj @@ -5,7 +5,7 @@ - + From 61f1c4fe62d5d4c52fa98ee2895af00229c9748d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Mon, 10 Aug 2020 19:51:00 +0200 Subject: [PATCH 137/434] Extract replay-transforming helper test method --- .../TestSceneSpinnerRotation.cs | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerRotation.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerRotation.cs index b46964e8b7..816c0c38d9 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerRotation.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerRotation.cs @@ -121,19 +121,7 @@ namespace osu.Game.Rulesets.Osu.Tests public void TestRotationDirection([Values(true, false)] bool clockwise) { if (clockwise) - { - AddStep("flip replay", () => - { - var drawableRuleset = this.ChildrenOfType().Single(); - var score = drawableRuleset.ReplayScore; - var scoreWithFlippedReplay = new Score - { - ScoreInfo = score.ScoreInfo, - Replay = flipReplay(score.Replay) - }; - drawableRuleset.SetReplayScore(scoreWithFlippedReplay); - }); - } + transformReplay(flip); addSeekStep(5000); @@ -141,7 +129,7 @@ namespace osu.Game.Rulesets.Osu.Tests AddAssert("spinner symbol direction correct", () => clockwise ? spinnerSymbol.Rotation > 0 : spinnerSymbol.Rotation < 0); } - private Replay flipReplay(Replay scoreReplay) => new Replay + private Replay flip(Replay scoreReplay) => new Replay { Frames = scoreReplay .Frames @@ -203,6 +191,18 @@ namespace osu.Game.Rulesets.Osu.Tests AddUntilStep("wait for seek to finish", () => Precision.AlmostEquals(time, Player.DrawableRuleset.FrameStableClock.CurrentTime, 100)); } + private void transformReplay(Func replayTransformation) => AddStep("set replay", () => + { + var drawableRuleset = this.ChildrenOfType().Single(); + var score = drawableRuleset.ReplayScore; + var transformedScore = new Score + { + ScoreInfo = score.ScoreInfo, + Replay = replayTransformation.Invoke(score.Replay) + }; + drawableRuleset.SetReplayScore(transformedScore); + }); + protected override IBeatmap CreateBeatmap(RulesetInfo ruleset) => new Beatmap { HitObjects = new List From 5d63b5f6a5be7657a75024448b44c6ed214bf7b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Mon, 10 Aug 2020 20:04:14 +0200 Subject: [PATCH 138/434] Add failing test cases --- .../TestSceneSpinnerRotation.cs | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerRotation.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerRotation.cs index 816c0c38d9..b6f4efc24c 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerRotation.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerRotation.cs @@ -7,6 +7,7 @@ using System.Linq; using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Audio; +using osu.Framework.Bindables; using osu.Framework.Graphics.Sprites; using osu.Framework.Testing; using osu.Framework.Timing; @@ -184,6 +185,49 @@ namespace osu.Game.Rulesets.Osu.Tests AddAssert("spm still valid", () => Precision.AlmostEquals(drawableSpinner.SpmCounter.SpinsPerMinute, estimatedSpm, 1.0)); } + [TestCase(0.5)] + [TestCase(2.0)] + public void TestSpinUnaffectedByClockRate(double rate) + { + double expectedProgress = 0; + double expectedSpm = 0; + + addSeekStep(1000); + AddStep("retrieve spinner state", () => + { + expectedProgress = drawableSpinner.Progress; + expectedSpm = drawableSpinner.SpmCounter.SpinsPerMinute; + }); + + addSeekStep(0); + + AddStep("adjust track rate", () => track.AddAdjustment(AdjustableProperty.Tempo, new BindableDouble(rate))); + // autoplay replay frames use track time; + // if a spin takes 1000ms in track time and we're playing with a 2x rate adjustment, the spin will take 500ms of *real* time. + // therefore we need to apply the rate adjustment to the replay itself to change from track time to real time, + // as real time is what we care about for spinners + // (so we're making the spin take 1000ms in real time *always*, regardless of the track clock's rate). + transformReplay(replay => applyRateAdjustment(replay, rate)); + + addSeekStep(1000); + AddAssert("progress almost same", () => Precision.AlmostEquals(expectedProgress, drawableSpinner.Progress, 0.05)); + AddAssert("spm almost same", () => Precision.AlmostEquals(expectedSpm, drawableSpinner.SpmCounter.SpinsPerMinute, 2.0)); + } + + private Replay applyRateAdjustment(Replay scoreReplay, double rate) => new Replay + { + Frames = scoreReplay + .Frames + .Cast() + .Select(replayFrame => + { + var adjustedTime = replayFrame.Time * rate; + return new OsuReplayFrame(adjustedTime, replayFrame.Position, replayFrame.Actions.ToArray()); + }) + .Cast() + .ToList() + }; + private void addSeekStep(double time) { AddStep($"seek to {time}", () => track.Seek(time)); From cca78235d5e9c0028852563329802f1d026da6c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Mon, 10 Aug 2020 22:17:47 +0200 Subject: [PATCH 139/434] Replace CumulativeRotation with RateAdjustedRotation --- .../TestSceneSpinnerRotation.cs | 12 +++++------ .../Objects/Drawables/DrawableSpinner.cs | 6 +++--- .../Drawables/Pieces/DefaultSpinnerDisc.cs | 2 +- .../Pieces/SpinnerRotationTracker.cs | 21 +++++++++++++++---- 4 files changed, 27 insertions(+), 14 deletions(-) diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerRotation.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerRotation.cs index b6f4efc24c..69857f8ef9 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerRotation.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerRotation.cs @@ -70,11 +70,11 @@ namespace osu.Game.Rulesets.Osu.Tests trackerRotationTolerance = Math.Abs(drawableSpinner.RotationTracker.Rotation * 0.1f); }); AddAssert("is disc rotation not almost 0", () => !Precision.AlmostEquals(drawableSpinner.RotationTracker.Rotation, 0, 100)); - AddAssert("is disc rotation absolute not almost 0", () => !Precision.AlmostEquals(drawableSpinner.RotationTracker.CumulativeRotation, 0, 100)); + AddAssert("is disc rotation absolute not almost 0", () => !Precision.AlmostEquals(drawableSpinner.RotationTracker.RateAdjustedRotation, 0, 100)); addSeekStep(0); AddAssert("is disc rotation almost 0", () => Precision.AlmostEquals(drawableSpinner.RotationTracker.Rotation, 0, trackerRotationTolerance)); - AddAssert("is disc rotation absolute almost 0", () => Precision.AlmostEquals(drawableSpinner.RotationTracker.CumulativeRotation, 0, 100)); + AddAssert("is disc rotation absolute almost 0", () => Precision.AlmostEquals(drawableSpinner.RotationTracker.RateAdjustedRotation, 0, 100)); } [Test] @@ -95,7 +95,7 @@ namespace osu.Game.Rulesets.Osu.Tests finalSpinnerSymbolRotation = spinnerSymbol.Rotation; spinnerSymbolRotationTolerance = Math.Abs(finalSpinnerSymbolRotation * 0.05f); }); - AddStep("retrieve cumulative disc rotation", () => finalCumulativeTrackerRotation = drawableSpinner.RotationTracker.CumulativeRotation); + AddStep("retrieve cumulative disc rotation", () => finalCumulativeTrackerRotation = drawableSpinner.RotationTracker.RateAdjustedRotation); addSeekStep(2500); AddAssert("disc rotation rewound", @@ -107,7 +107,7 @@ namespace osu.Game.Rulesets.Osu.Tests () => Precision.AlmostEquals(spinnerSymbol.Rotation, finalSpinnerSymbolRotation / 2, spinnerSymbolRotationTolerance)); AddAssert("is cumulative rotation rewound", // cumulative rotation is not damped, so we're treating it as the "ground truth" and allowing a comparatively smaller margin of error. - () => Precision.AlmostEquals(drawableSpinner.RotationTracker.CumulativeRotation, finalCumulativeTrackerRotation / 2, 100)); + () => Precision.AlmostEquals(drawableSpinner.RotationTracker.RateAdjustedRotation, finalCumulativeTrackerRotation / 2, 100)); addSeekStep(5000); AddAssert("is disc rotation almost same", @@ -115,7 +115,7 @@ namespace osu.Game.Rulesets.Osu.Tests AddAssert("is symbol rotation almost same", () => Precision.AlmostEquals(spinnerSymbol.Rotation, finalSpinnerSymbolRotation, spinnerSymbolRotationTolerance)); AddAssert("is cumulative rotation almost same", - () => Precision.AlmostEquals(drawableSpinner.RotationTracker.CumulativeRotation, finalCumulativeTrackerRotation, 100)); + () => Precision.AlmostEquals(drawableSpinner.RotationTracker.RateAdjustedRotation, finalCumulativeTrackerRotation, 100)); } [Test] @@ -153,7 +153,7 @@ namespace osu.Game.Rulesets.Osu.Tests { // multipled by 2 to nullify the score multiplier. (autoplay mod selected) var totalScore = ((ScoreExposedPlayer)Player).ScoreProcessor.TotalScore.Value * 2; - return totalScore == (int)(drawableSpinner.RotationTracker.CumulativeRotation / 360) * SpinnerTick.SCORE_PER_TICK; + return totalScore == (int)(drawableSpinner.RotationTracker.RateAdjustedRotation / 360) * SpinnerTick.SCORE_PER_TICK; }); addSeekStep(0); diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs index a2a49b5c42..f10d11827b 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs @@ -185,7 +185,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables // these become implicitly hit. return 1; - return Math.Clamp(RotationTracker.CumulativeRotation / 360 / Spinner.SpinsRequired, 0, 1); + return Math.Clamp(RotationTracker.RateAdjustedRotation / 360 / Spinner.SpinsRequired, 0, 1); } } @@ -233,7 +233,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables if (!SpmCounter.IsPresent && RotationTracker.Tracking) SpmCounter.FadeIn(HitObject.TimeFadeIn); - SpmCounter.SetRotation(RotationTracker.CumulativeRotation); + SpmCounter.SetRotation(RotationTracker.RateAdjustedRotation); updateBonusScore(); } @@ -245,7 +245,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables if (ticks.Count == 0) return; - int spins = (int)(RotationTracker.CumulativeRotation / 360); + int spins = (int)(RotationTracker.RateAdjustedRotation / 360); if (spins < wholeSpins) { diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/DefaultSpinnerDisc.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/DefaultSpinnerDisc.cs index dfb692eba9..1476fe6010 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/DefaultSpinnerDisc.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/DefaultSpinnerDisc.cs @@ -177,7 +177,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces { get { - int rotations = (int)(drawableSpinner.RotationTracker.CumulativeRotation / 360); + int rotations = (int)(drawableSpinner.RotationTracker.RateAdjustedRotation / 360); if (wholeRotationCount == rotations) return false; diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerRotationTracker.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerRotationTracker.cs index 0cc6c842f4..f1a782cbb5 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerRotationTracker.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerRotationTracker.cs @@ -31,17 +31,28 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces public readonly BindableBool Complete = new BindableBool(); /// - /// The total rotation performed on the spinner disc, disregarding the spin direction. + /// The total rotation performed on the spinner disc, disregarding the spin direction, + /// adjusted for the track's playback rate. /// /// + /// /// This value is always non-negative and is monotonically increasing with time /// (i.e. will only increase if time is passing forward, but can decrease during rewind). + /// + /// + /// The rotation from each frame is multiplied by the clock's current playback rate. + /// The reason this is done is to ensure that spinners give the same score and require the same number of spins + /// regardless of whether speed-modifying mods are applied. + /// /// /// - /// If the spinner is spun 360 degrees clockwise and then 360 degrees counter-clockwise, + /// Assuming no speed-modifying mods are active, + /// if the spinner is spun 360 degrees clockwise and then 360 degrees counter-clockwise, /// this property will return the value of 720 (as opposed to 0 for ). + /// If Double Time is active instead (with a speed multiplier of 1.5x), + /// in the same scenario the property will return 720 * 1.5 = 1080. /// - public float CumulativeRotation { get; private set; } + public float RateAdjustedRotation { get; private set; } /// /// Whether the spinning is spinning at a reasonable speed to be considered visually spinning. @@ -113,7 +124,9 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces } currentRotation += angle; - CumulativeRotation += Math.Abs(angle) * Math.Sign(Clock.ElapsedFrameTime); + // rate has to be applied each frame, because it's not guaranteed to be constant throughout playback + // (see: ModTimeRamp) + RateAdjustedRotation += (float)(Math.Abs(angle) * Clock.Rate); } } } From ecb4826e1974ce4752020732d78d6631863d9e9f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 11 Aug 2020 06:54:26 +0900 Subject: [PATCH 140/434] Update framework --- osu.Android.props | 2 +- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index e5fed09c07..a384ad4c34 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -52,6 +52,6 @@ - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 18c3052ca3..b38ef38ec2 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -24,7 +24,7 @@ - + diff --git a/osu.iOS.props b/osu.iOS.props index b034253d88..00ddd94d53 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -70,7 +70,7 @@ - + @@ -80,7 +80,7 @@ - + From d1b106a3b557c0c8dd13746679a7e68193863eff Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 11 Aug 2020 10:59:28 +0900 Subject: [PATCH 141/434] Include mention of old releases in error message --- osu.Game/Screens/Multi/Play/TimeshiftPlayer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Multi/Play/TimeshiftPlayer.cs b/osu.Game/Screens/Multi/Play/TimeshiftPlayer.cs index 79b4b04722..04da943a10 100644 --- a/osu.Game/Screens/Multi/Play/TimeshiftPlayer.cs +++ b/osu.Game/Screens/Multi/Play/TimeshiftPlayer.cs @@ -64,7 +64,7 @@ namespace osu.Game.Screens.Multi.Play { failed = true; - Logger.Error(e, "Failed to retrieve a score submission token.\n\nThis may happen if you are not running an official release of osu! (ie. you are self-compiling)."); + Logger.Error(e, "Failed to retrieve a score submission token.\n\nThis may happen if you are running an old or non-official release of osu! (ie. you are self-compiling)."); Schedule(() => { From 471ed968e3d7a81b566a137078b5e3bef9e35d10 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 11 Aug 2020 11:09:02 +0900 Subject: [PATCH 142/434] Fix crash when same ruleset loaded more than once If the same ruleset assembly was present more than once in the current AppDomain, the game would crash. We recently saw this in Rider EAP9. While this behaviour may change going forward, this is a good safety measure regardless. --- osu.Game/Rulesets/RulesetStore.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/osu.Game/Rulesets/RulesetStore.cs b/osu.Game/Rulesets/RulesetStore.cs index dd43092c0d..5d93f5186b 100644 --- a/osu.Game/Rulesets/RulesetStore.cs +++ b/osu.Game/Rulesets/RulesetStore.cs @@ -191,6 +191,11 @@ namespace osu.Game.Rulesets if (loadedAssemblies.ContainsKey(assembly)) return; + // the same assembly may be loaded twice in the same AppDomain (currently a thing in certain Rider versions https://youtrack.jetbrains.com/issue/RIDER-48799). + // as a failsafe, also compare by FullName. + if (loadedAssemblies.Any(a => a.Key.FullName == assembly.FullName)) + return; + try { loadedAssemblies[assembly] = assembly.GetTypes().First(t => t.IsPublic && t.IsSubclassOf(typeof(Ruleset))); From 20197e276861128b96dec6fcf7f9fd148a763e8d Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 11 Aug 2020 12:27:32 +0900 Subject: [PATCH 143/434] Remove locally-cached music controller --- osu.Game.Tests/Visual/Gameplay/TestSceneStoryboard.cs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboard.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboard.cs index 3d2dd8a0c5..c11a47d62b 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboard.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboard.cs @@ -25,16 +25,12 @@ namespace osu.Game.Tests.Visual.Gameplay private readonly Container storyboardContainer; private DrawableStoryboard storyboard; - [Cached] - private MusicController musicController = new MusicController(); - public TestSceneStoryboard() { Clock = new FramedClock(); AddRange(new Drawable[] { - musicController, new Container { RelativeSizeAxes = Axes.Both, @@ -104,7 +100,7 @@ namespace osu.Game.Tests.Visual.Gameplay storyboard.Passing = false; storyboardContainer.Add(storyboard); - decoupledClock.ChangeSource(musicController.CurrentTrack); + decoupledClock.ChangeSource(MusicController.CurrentTrack); } private void loadStoryboardNoVideo() @@ -127,7 +123,7 @@ namespace osu.Game.Tests.Visual.Gameplay storyboard = sb.CreateDrawable(Beatmap.Value); storyboardContainer.Add(storyboard); - decoupledClock.ChangeSource(musicController.CurrentTrack); + decoupledClock.ChangeSource(MusicController.CurrentTrack); } } } From b64142dff9d04deb9295eeb9c5b3e52623c63cdf Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 11 Aug 2020 12:37:00 +0900 Subject: [PATCH 144/434] Fix incorrect load state being used --- osu.Game/Overlays/MusicController.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index c5ba82288c..813ad26ae4 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -105,7 +105,7 @@ namespace osu.Game.Overlays /// /// Returns whether the beatmap track is loaded. /// - public bool TrackLoaded => CurrentTrack.IsLoaded; + public bool TrackLoaded => CurrentTrack.TrackLoaded; private void beatmapUpdated(ValueChangedEvent> weakSet) { From c66a14e9c5d160def0fdcdabcf39772e72cdd0dc Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 11 Aug 2020 12:37:48 +0900 Subject: [PATCH 145/434] Remove beatmap from FailAnimation --- osu.Game/Screens/Play/FailAnimation.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/osu.Game/Screens/Play/FailAnimation.cs b/osu.Game/Screens/Play/FailAnimation.cs index a7bfca612e..122ae505ca 100644 --- a/osu.Game/Screens/Play/FailAnimation.cs +++ b/osu.Game/Screens/Play/FailAnimation.cs @@ -11,7 +11,6 @@ using osu.Framework.Audio.Sample; using osu.Framework.Audio.Track; using osu.Framework.Graphics; using osu.Framework.Utils; -using osu.Game.Beatmaps; using osu.Game.Rulesets.Objects.Drawables; using osuTK; using osuTK.Graphics; @@ -42,7 +41,7 @@ namespace osu.Game.Screens.Play } [BackgroundDependencyLoader] - private void load(AudioManager audio, IBindable beatmap) + private void load(AudioManager audio) { failSample = audio.Samples.Get(@"Gameplay/failsound"); } From 7d35893ecd2bf8b277c2e6ac9632592dbf313f6f Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 11 Aug 2020 12:40:58 +0900 Subject: [PATCH 146/434] Make MusicController non-nullable --- osu.Game/Screens/Menu/MainMenu.cs | 2 +- .../Screens/Multi/Lounge/LoungeSubScreen.cs | 2 +- osu.Game/Screens/Select/SongSelect.cs | 28 +++++++------------ 3 files changed, 12 insertions(+), 20 deletions(-) diff --git a/osu.Game/Screens/Menu/MainMenu.cs b/osu.Game/Screens/Menu/MainMenu.cs index 8837a49772..470e8ca9a6 100644 --- a/osu.Game/Screens/Menu/MainMenu.cs +++ b/osu.Game/Screens/Menu/MainMenu.cs @@ -45,7 +45,7 @@ namespace osu.Game.Screens.Menu [Resolved] private GameHost host { get; set; } - [Resolved(canBeNull: true)] + [Resolved] private MusicController music { get; set; } [Resolved(canBeNull: true)] diff --git a/osu.Game/Screens/Multi/Lounge/LoungeSubScreen.cs b/osu.Game/Screens/Multi/Lounge/LoungeSubScreen.cs index ff7d56a95b..f9c5fd13a4 100644 --- a/osu.Game/Screens/Multi/Lounge/LoungeSubScreen.cs +++ b/osu.Game/Screens/Multi/Lounge/LoungeSubScreen.cs @@ -32,7 +32,7 @@ namespace osu.Game.Screens.Multi.Lounge [Resolved] private Bindable selectedRoom { get; set; } - [Resolved(canBeNull: true)] + [Resolved] private MusicController music { get; set; } private bool joiningRoom; diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 80ed894233..ddbb021054 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -99,7 +99,7 @@ namespace osu.Game.Screens.Select private readonly Bindable decoupledRuleset = new Bindable(); - [Resolved(canBeNull: true)] + [Resolved] private MusicController music { get; set; } [BackgroundDependencyLoader(true)] @@ -561,18 +561,15 @@ namespace osu.Game.Screens.Select BeatmapDetails.Refresh(); - if (music?.CurrentTrack != null) - { - music.CurrentTrack.Looping = true; - music.ResetTrackAdjustments(); - } + music.CurrentTrack.Looping = true; + music.ResetTrackAdjustments(); if (Beatmap != null && !Beatmap.Value.BeatmapSetInfo.DeletePending) { updateComponentFromBeatmap(Beatmap.Value); // restart playback on returning to song select, regardless. - music?.Play(); + music.Play(); } this.FadeIn(250); @@ -589,8 +586,7 @@ namespace osu.Game.Screens.Select BeatmapOptions.Hide(); - if (music?.CurrentTrack != null) - music.CurrentTrack.Looping = false; + music.CurrentTrack.Looping = false; this.ScaleTo(1.1f, 250, Easing.InSine); @@ -611,8 +607,7 @@ namespace osu.Game.Screens.Select FilterControl.Deactivate(); - if (music?.CurrentTrack != null) - music.CurrentTrack.Looping = false; + music.CurrentTrack.Looping = false; return false; } @@ -653,8 +648,7 @@ namespace osu.Game.Screens.Select BeatmapDetails.Beatmap = beatmap; - if (music?.CurrentTrack != null) - music.CurrentTrack.Looping = true; + music.CurrentTrack.Looping = true; } private readonly WeakReference lastTrack = new WeakReference(null); @@ -665,16 +659,14 @@ namespace osu.Game.Screens.Select /// private void ensurePlayingSelected() { - ITrack track = music?.CurrentTrack; - if (track == null) - return; + ITrack track = music.CurrentTrack; bool isNewTrack = !lastTrack.TryGetTarget(out var last) || last != track; track.RestartPoint = Beatmap.Value.Metadata.PreviewTime; - if (!track.IsRunning && (music?.IsUserPaused != true || isNewTrack)) - music?.Play(true); + if (!track.IsRunning && (music.IsUserPaused != true || isNewTrack)) + music.Play(true); lastTrack.SetTarget(track); } From 322d08af1bfe25f45f90fcd8bc395219ce85c108 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 11 Aug 2020 13:11:59 +0900 Subject: [PATCH 147/434] Remove more local music controller caches --- osu.Game.Tests/Visual/Menus/TestSceneSongTicker.cs | 5 ----- .../Visual/UserInterface/TestSceneBeatSyncedContainer.cs | 4 ---- 2 files changed, 9 deletions(-) diff --git a/osu.Game.Tests/Visual/Menus/TestSceneSongTicker.cs b/osu.Game.Tests/Visual/Menus/TestSceneSongTicker.cs index d7f23f5cc0..4b22af38c5 100644 --- a/osu.Game.Tests/Visual/Menus/TestSceneSongTicker.cs +++ b/osu.Game.Tests/Visual/Menus/TestSceneSongTicker.cs @@ -1,7 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Overlays; @@ -11,14 +10,10 @@ namespace osu.Game.Tests.Visual.Menus { public class TestSceneSongTicker : OsuTestScene { - [Cached] - private MusicController musicController = new MusicController(); - public TestSceneSongTicker() { AddRange(new Drawable[] { - musicController, new SongTicker { Anchor = Anchor.Centre, diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneBeatSyncedContainer.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneBeatSyncedContainer.cs index 127915c6c6..82b7e65c4f 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneBeatSyncedContainer.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneBeatSyncedContainer.cs @@ -26,9 +26,6 @@ namespace osu.Game.Tests.Visual.UserInterface { private readonly NowPlayingOverlay np; - [Cached] - private MusicController musicController = new MusicController(); - public TestSceneBeatSyncedContainer() { Clock = new FramedClock(); @@ -36,7 +33,6 @@ namespace osu.Game.Tests.Visual.UserInterface AddRange(new Drawable[] { - musicController, new BeatContainer { Anchor = Anchor.BottomCentre, From 6aafb3d2710174fe4bf302300ecf2cd1edd52988 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 11 Aug 2020 13:14:20 +0900 Subject: [PATCH 148/434] Cleanup TestSceneScreenNavigation --- osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs b/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs index 0f06010a6a..73a833c15d 100644 --- a/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs +++ b/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs @@ -80,7 +80,7 @@ namespace osu.Game.Tests.Visual.Navigation AddStep("return to menu", () => songSelect.Exit()); - AddUntilStep("wait for track", () => Game.MusicController.CurrentTrack.IsDummyDevice == false && Game.MusicController.IsPlaying); + AddUntilStep("wait for track", () => !Game.MusicController.CurrentTrack.IsDummyDevice && Game.MusicController.IsPlaying); } [Test] From 338c01fa43657beb3f1476aab90db227605deed2 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 11 Aug 2020 13:16:06 +0900 Subject: [PATCH 149/434] Remove track store reference counting, use single instance stores --- osu.Game/Beatmaps/BeatmapManager.cs | 29 ++++--------------- .../Beatmaps/BeatmapManager_WorkingBeatmap.cs | 24 +++++---------- 2 files changed, 13 insertions(+), 40 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index e001185da9..6f01580998 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -63,8 +63,9 @@ namespace osu.Game.Beatmaps private readonly RulesetStore rulesets; private readonly BeatmapStore beatmaps; private readonly AudioManager audioManager; - private readonly GameHost host; private readonly BeatmapOnlineLookupQueue onlineLookupQueue; + private readonly TextureStore textureStore; + private readonly ITrackStore trackStore; public BeatmapManager(Storage storage, IDatabaseContextFactory contextFactory, RulesetStore rulesets, IAPIProvider api, AudioManager audioManager, GameHost host = null, WorkingBeatmap defaultBeatmap = null) @@ -72,7 +73,6 @@ namespace osu.Game.Beatmaps { this.rulesets = rulesets; this.audioManager = audioManager; - this.host = host; DefaultBeatmap = defaultBeatmap; @@ -83,6 +83,9 @@ namespace osu.Game.Beatmaps beatmaps.ItemUpdated += removeWorkingCache; onlineLookupQueue = new BeatmapOnlineLookupQueue(api, storage); + + textureStore = new LargeTextureStore(host?.CreateTextureLoaderStore(Files.Store)); + trackStore = audioManager.GetTrackStore(Files.Store); } protected override ArchiveDownloadRequest CreateDownloadRequest(BeatmapSetInfo set, bool minimiseDownloadSize) => @@ -219,7 +222,6 @@ namespace osu.Game.Beatmaps } private readonly WeakList workingCache = new WeakList(); - private readonly Dictionary referencedTrackStores = new Dictionary(); /// /// Retrieve a instance for the provided @@ -252,31 +254,12 @@ namespace osu.Game.Beatmaps beatmapInfo.Metadata ??= beatmapInfo.BeatmapSet.Metadata; - ITrackStore trackStore = workingCache.FirstOrDefault(b => b.BeatmapInfo.AudioEquals(beatmapInfo))?.TrackStore; - TextureStore textureStore = workingCache.FirstOrDefault(b => b.BeatmapInfo.BackgroundEquals(beatmapInfo))?.TextureStore; - - textureStore ??= new LargeTextureStore(host?.CreateTextureLoaderStore(Files.Store)); - trackStore ??= audioManager.GetTrackStore(Files.Store); - - workingCache.Add(working = new BeatmapManagerWorkingBeatmap(Files.Store, textureStore, trackStore, beatmapInfo, audioManager, dereferenceTrackStore)); - referencedTrackStores[trackStore] = referencedTrackStores.GetOrDefault(trackStore) + 1; + workingCache.Add(working = new BeatmapManagerWorkingBeatmap(Files.Store, textureStore, trackStore, beatmapInfo, audioManager)); return working; } } - private void dereferenceTrackStore(ITrackStore trackStore) - { - lock (workingCache) - { - if (--referencedTrackStores[trackStore] == 0) - { - referencedTrackStores.Remove(trackStore); - trackStore.Dispose(); - } - } - } - /// /// Perform a lookup query on available s. /// diff --git a/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs b/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs index f1289cd3aa..aa93833f33 100644 --- a/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs @@ -19,21 +19,16 @@ namespace osu.Game.Beatmaps { protected class BeatmapManagerWorkingBeatmap : WorkingBeatmap { - public readonly TextureStore TextureStore; - public readonly ITrackStore TrackStore; - private readonly IResourceStore store; - private readonly Action dereferenceAction; + private readonly TextureStore textureStore; + private readonly ITrackStore trackStore; - public BeatmapManagerWorkingBeatmap(IResourceStore store, TextureStore textureStore, ITrackStore trackStore, BeatmapInfo beatmapInfo, AudioManager audioManager, - Action dereferenceAction) + public BeatmapManagerWorkingBeatmap(IResourceStore store, TextureStore textureStore, ITrackStore trackStore, BeatmapInfo beatmapInfo, AudioManager audioManager) : base(beatmapInfo, audioManager) { this.store = store; - this.dereferenceAction = dereferenceAction; - - TextureStore = textureStore; - TrackStore = trackStore; + this.textureStore = textureStore; + this.trackStore = trackStore; } protected override IBeatmap GetBeatmap() @@ -61,7 +56,7 @@ namespace osu.Game.Beatmaps try { - return TextureStore.Get(getPathForFile(Metadata.BackgroundFile)); + return textureStore.Get(getPathForFile(Metadata.BackgroundFile)); } catch (Exception e) { @@ -74,7 +69,7 @@ namespace osu.Game.Beatmaps { try { - return TrackStore.Get(getPathForFile(Metadata.AudioFile)); + return trackStore.Get(getPathForFile(Metadata.AudioFile)); } catch (Exception e) { @@ -140,11 +135,6 @@ namespace osu.Game.Beatmaps return null; } } - - ~BeatmapManagerWorkingBeatmap() - { - dereferenceAction?.Invoke(TrackStore); - } } } } From faff0a70c49734841f6c1dd36c8df2775d1b867e Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 11 Aug 2020 13:48:57 +0900 Subject: [PATCH 150/434] Privatise BMWB --- osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs b/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs index aa93833f33..92199789ec 100644 --- a/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs @@ -17,7 +17,7 @@ namespace osu.Game.Beatmaps { public partial class BeatmapManager { - protected class BeatmapManagerWorkingBeatmap : WorkingBeatmap + private class BeatmapManagerWorkingBeatmap : WorkingBeatmap { private readonly IResourceStore store; private readonly TextureStore textureStore; From 031d29ac34bd6684340f51aab051b84db42c4644 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 11 Aug 2020 13:53:23 +0900 Subject: [PATCH 151/434] Inspect current track directly --- osu.Game/Overlays/NowPlayingOverlay.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/NowPlayingOverlay.cs b/osu.Game/Overlays/NowPlayingOverlay.cs index 15b189ead6..dc52300cdb 100644 --- a/osu.Game/Overlays/NowPlayingOverlay.cs +++ b/osu.Game/Overlays/NowPlayingOverlay.cs @@ -234,9 +234,9 @@ namespace osu.Game.Overlays pendingBeatmapSwitch = null; } - var track = musicController.TrackLoaded ? musicController.CurrentTrack : null; + var track = musicController.CurrentTrack; - if (track?.IsDummyDevice == false) + if (track.IsDummyDevice == false) { progressBar.EndTime = track.Length; progressBar.CurrentTime = track.CurrentTime; From 8bfe6ba27c275208f665e6c125b73fade6c6fdd7 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 11 Aug 2020 23:04:00 +0900 Subject: [PATCH 152/434] Fix informational overlays not hiding each other correctly --- osu.Game/OsuGame.cs | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 623c677991..053eb01dcd 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -683,9 +683,8 @@ namespace osu.Game { overlay.State.ValueChanged += state => { - if (state.NewValue == Visibility.Hidden) return; - - informationalOverlays.Where(o => o != overlay).ForEach(o => o.Hide()); + if (state.NewValue != Visibility.Hidden) + showOverlayAboveOthers(overlay, informationalOverlays); }; } @@ -699,12 +698,8 @@ namespace osu.Game // informational overlays should be dismissed on a show or hide of a full overlay. informationalOverlays.ForEach(o => o.Hide()); - if (state.NewValue == Visibility.Hidden) return; - - singleDisplayOverlays.Where(o => o != overlay).ForEach(o => o.Hide()); - - if (!overlay.IsPresent) - overlayContent.ChangeChildDepth(overlay, (float)-Clock.CurrentTime); + if (state.NewValue != Visibility.Hidden) + showOverlayAboveOthers(overlay, singleDisplayOverlays); }; } @@ -729,6 +724,15 @@ namespace osu.Game notifications.State.ValueChanged += _ => updateScreenOffset(); } + private void showOverlayAboveOthers(OverlayContainer overlay, OverlayContainer[] otherOverlays) + { + otherOverlays.Where(o => o != overlay).ForEach(o => o.Hide()); + + // show above others if not visible at all, else leave at current depth. + if (!overlay.IsPresent) + overlayContent.ChangeChildDepth(overlay, (float)-Clock.CurrentTime); + } + public class GameIdleTracker : IdleTracker { private InputManager inputManager; From 070d71ec27fa74eec6d27fa551dd5162ab628d4e Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 12 Aug 2020 00:48:38 +0900 Subject: [PATCH 153/434] More cleanups --- .../Skinning/TestSceneDrawableTaikoMascot.cs | 4 ++-- .../Skinning/TestSceneTaikoPlayfield.cs | 2 +- osu.Game.Tests/Skins/TestSceneBeatmapSkinResources.cs | 2 +- .../Visual/Gameplay/TestSceneNightcoreBeatContainer.cs | 4 ++-- osu.Game/Overlays/NowPlayingOverlay.cs | 2 +- osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs | 3 --- osu.Game/Screens/Edit/Editor.cs | 4 ++-- osu.Game/Screens/Edit/EditorClock.cs | 4 ++-- osu.Game/Screens/Menu/IntroScreen.cs | 2 +- 9 files changed, 12 insertions(+), 15 deletions(-) diff --git a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableTaikoMascot.cs b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableTaikoMascot.cs index ba5aef5968..6141bf062e 100644 --- a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableTaikoMascot.cs +++ b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableTaikoMascot.cs @@ -175,11 +175,11 @@ namespace osu.Game.Rulesets.Taiko.Tests.Skinning private void createDrawableRuleset() { - AddUntilStep("wait for beatmap to be loaded", () => MusicController.TrackLoaded); + AddUntilStep("wait for beatmap to be loaded", () => MusicController.CurrentTrack.TrackLoaded); AddStep("create drawable ruleset", () => { - MusicController.Play(true); + MusicController.CurrentTrack.Start(); SetContents(() => { diff --git a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneTaikoPlayfield.cs b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneTaikoPlayfield.cs index 5c54393fb8..a3d3bc81c4 100644 --- a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneTaikoPlayfield.cs +++ b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneTaikoPlayfield.cs @@ -34,7 +34,7 @@ namespace osu.Game.Rulesets.Taiko.Tests.Skinning beatmap.ControlPointInfo.Add(0, new TimingControlPoint { BeatLength = 1000 }); - MusicController.Play(true); + MusicController.CurrentTrack.Start(); }); AddStep("Load playfield", () => SetContents(() => new TaikoPlayfield(new ControlPointInfo()) diff --git a/osu.Game.Tests/Skins/TestSceneBeatmapSkinResources.cs b/osu.Game.Tests/Skins/TestSceneBeatmapSkinResources.cs index 03faee9ad2..49b40daf99 100644 --- a/osu.Game.Tests/Skins/TestSceneBeatmapSkinResources.cs +++ b/osu.Game.Tests/Skins/TestSceneBeatmapSkinResources.cs @@ -29,6 +29,6 @@ namespace osu.Game.Tests.Skins public void TestRetrieveOggSample() => AddAssert("sample is non-null", () => Beatmap.Value.Skin.GetSample(new SampleInfo("sample")) != null); [Test] - public void TestRetrieveOggTrack() => AddAssert("track is non-null", () => MusicController.CurrentTrack.IsDummyDevice == false); + public void TestRetrieveOggTrack() => AddAssert("track is non-null", () => !MusicController.CurrentTrack.IsDummyDevice); } } diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneNightcoreBeatContainer.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneNightcoreBeatContainer.cs index ce99d85e92..53e06a632e 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneNightcoreBeatContainer.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneNightcoreBeatContainer.cs @@ -19,8 +19,8 @@ namespace osu.Game.Tests.Visual.Gameplay Beatmap.Value = CreateWorkingBeatmap(new OsuRuleset().RulesetInfo); - MusicController.Play(true); - MusicController.SeekTo(Beatmap.Value.Beatmap.HitObjects.First().StartTime - 1000); + MusicController.CurrentTrack.Start(); + MusicController.CurrentTrack.Seek(Beatmap.Value.Beatmap.HitObjects.First().StartTime - 1000); Add(new ModNightcore.NightcoreBeatContainer()); diff --git a/osu.Game/Overlays/NowPlayingOverlay.cs b/osu.Game/Overlays/NowPlayingOverlay.cs index dc52300cdb..af692486b7 100644 --- a/osu.Game/Overlays/NowPlayingOverlay.cs +++ b/osu.Game/Overlays/NowPlayingOverlay.cs @@ -236,7 +236,7 @@ namespace osu.Game.Overlays var track = musicController.CurrentTrack; - if (track.IsDummyDevice == false) + if (!track.IsDummyDevice) { progressBar.EndTime = track.Length; progressBar.CurrentTime = track.CurrentTime; diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs index d556d948f6..e1702d3eff 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs @@ -2,7 +2,6 @@ // See the LICENCE file in the repository root for full licence text. using System; -using System.Diagnostics; using osu.Framework.Allocation; using osu.Framework.Audio.Track; using osu.Framework.Bindables; @@ -64,8 +63,6 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline waveform.Waveform = b.NewValue.Waveform; track = musicController.CurrentTrack; - Debug.Assert(track != null); - if (track.Length > 0) { MaxZoom = getZoomLevelForVisibleMilliseconds(500); diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index 78fa6c74b0..6722d9179c 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -82,7 +82,7 @@ namespace osu.Game.Screens.Edit beatDivisor.BindValueChanged(divisor => Beatmap.Value.BeatmapInfo.BeatDivisor = divisor.NewValue); // Todo: should probably be done at a DrawableRuleset level to share logic with Player. - clock = new EditorClock(Beatmap.Value, musicController.CurrentTrack.Length, beatDivisor) { IsCoupled = false }; + clock = new EditorClock(Beatmap.Value, beatDivisor) { IsCoupled = false }; clock.ChangeSource(musicController.CurrentTrack); dependencies.CacheAs(clock); @@ -348,7 +348,7 @@ namespace osu.Game.Screens.Edit private void resetTrack(bool seekToStart = false) { - musicController.Stop(); + musicController.CurrentTrack.Stop(); if (seekToStart) { diff --git a/osu.Game/Screens/Edit/EditorClock.cs b/osu.Game/Screens/Edit/EditorClock.cs index fbfa397795..d0e265adb0 100644 --- a/osu.Game/Screens/Edit/EditorClock.cs +++ b/osu.Game/Screens/Edit/EditorClock.cs @@ -25,8 +25,8 @@ namespace osu.Game.Screens.Edit private readonly DecoupleableInterpolatingFramedClock underlyingClock; - public EditorClock(WorkingBeatmap beatmap, double trackLength, BindableBeatDivisor beatDivisor) - : this(beatmap.Beatmap.ControlPointInfo, trackLength, beatDivisor) + public EditorClock(WorkingBeatmap beatmap, BindableBeatDivisor beatDivisor) + : this(beatmap.Beatmap.ControlPointInfo, beatmap.GetTrack().Length, beatDivisor) { } diff --git a/osu.Game/Screens/Menu/IntroScreen.cs b/osu.Game/Screens/Menu/IntroScreen.cs index 6e85abf7dc..389629445c 100644 --- a/osu.Game/Screens/Menu/IntroScreen.cs +++ b/osu.Game/Screens/Menu/IntroScreen.cs @@ -115,7 +115,7 @@ namespace osu.Game.Screens.Menu if (setInfo != null) { initialBeatmap = beatmaps.GetWorkingBeatmap(setInfo.Beatmaps[0]); - UsingThemedIntro = initialBeatmap.GetTrack().IsDummyDevice == false; + UsingThemedIntro = !initialBeatmap.GetTrack().IsDummyDevice; } return UsingThemedIntro; From b66f303e71cf9083c2f764964cf3424bb4433f64 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 12 Aug 2020 00:48:45 +0900 Subject: [PATCH 154/434] Add annotation --- osu.Game/Beatmaps/WorkingBeatmap.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Beatmaps/WorkingBeatmap.cs b/osu.Game/Beatmaps/WorkingBeatmap.cs index af6a67ad3f..bec2679103 100644 --- a/osu.Game/Beatmaps/WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/WorkingBeatmap.cs @@ -7,6 +7,7 @@ using System.Diagnostics; using System.Linq; using System.Threading; using System.Threading.Tasks; +using JetBrains.Annotations; using osu.Framework.Audio; using osu.Framework.Audio.Track; using osu.Framework.Graphics.Textures; @@ -249,6 +250,7 @@ namespace osu.Game.Beatmaps protected abstract Texture GetBackground(); private readonly RecyclableLazy background; + [NotNull] public Track GetTrack() => GetBeatmapTrack() ?? GetVirtualTrack(1000); protected abstract Track GetBeatmapTrack(); From eec94e1f535e1a5f9d3a17561bfd1ca6d2e5ccab Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 12 Aug 2020 00:50:56 +0900 Subject: [PATCH 155/434] Make track not-null in GameplayClockContainer/FailAnimation --- osu.Game/Screens/Play/FailAnimation.cs | 5 ++++- osu.Game/Screens/Play/GameplayClockContainer.cs | 10 +++------- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/osu.Game/Screens/Play/FailAnimation.cs b/osu.Game/Screens/Play/FailAnimation.cs index 122ae505ca..6ebee209e2 100644 --- a/osu.Game/Screens/Play/FailAnimation.cs +++ b/osu.Game/Screens/Play/FailAnimation.cs @@ -6,6 +6,7 @@ using osu.Framework.Bindables; using osu.Game.Rulesets.UI; using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using osu.Framework.Allocation; using osu.Framework.Audio.Sample; using osu.Framework.Audio.Track; @@ -26,6 +27,8 @@ namespace osu.Game.Screens.Play public Action OnComplete; private readonly DrawableRuleset drawableRuleset; + + [NotNull] private readonly ITrack track; private readonly BindableDouble trackFreq = new BindableDouble(1); @@ -34,7 +37,7 @@ namespace osu.Game.Screens.Play private SampleChannel failSample; - public FailAnimation(DrawableRuleset drawableRuleset, ITrack track) + public FailAnimation(DrawableRuleset drawableRuleset, [NotNull] ITrack track) { this.drawableRuleset = drawableRuleset; this.track = track; diff --git a/osu.Game/Screens/Play/GameplayClockContainer.cs b/osu.Game/Screens/Play/GameplayClockContainer.cs index c4f368e1f5..f3466a562e 100644 --- a/osu.Game/Screens/Play/GameplayClockContainer.cs +++ b/osu.Game/Screens/Play/GameplayClockContainer.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Threading.Tasks; using osu.Framework; @@ -27,6 +28,7 @@ namespace osu.Game.Screens.Play private readonly WorkingBeatmap beatmap; private readonly IReadOnlyList mods; + [NotNull] private ITrack track; public readonly BindableBool IsPaused = new BindableBool(); @@ -60,7 +62,7 @@ namespace osu.Game.Screens.Play private readonly FramedOffsetClock platformOffsetClock; - public GameplayClockContainer(ITrack track, WorkingBeatmap beatmap, IReadOnlyList mods, double gameplayStartTime) + public GameplayClockContainer([NotNull] ITrack track, WorkingBeatmap beatmap, IReadOnlyList mods, double gameplayStartTime) { this.beatmap = beatmap; this.mods = mods; @@ -196,9 +198,6 @@ namespace osu.Game.Screens.Play /// public void StopUsingBeatmapClock() { - if (track == null) - return; - removeSourceClockAdjustments(); track = new TrackVirtual(track.Length); @@ -217,8 +216,6 @@ namespace osu.Game.Screens.Play private void updateRate() { - if (track == null) return; - speedAdjustmentsApplied = true; track.ResetSpeedAdjustments(); @@ -233,7 +230,6 @@ namespace osu.Game.Screens.Play { base.Dispose(isDisposing); removeSourceClockAdjustments(); - track = null; } private void removeSourceClockAdjustments() From 688e4479506645bdacee7cdc7ae9ee9deaa5f1b4 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 12 Aug 2020 01:33:06 +0900 Subject: [PATCH 156/434] Fix potential hierarchy mutation from async context --- osu.Game/Overlays/MusicController.cs | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index 813ad26ae4..c18b564b4f 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -317,11 +317,28 @@ namespace osu.Game.Overlays private void changeTrack() { - CurrentTrack.Expire(); - CurrentTrack = new DrawableTrack(current.GetTrack()); - CurrentTrack.Completed += () => onTrackCompleted(current); + var lastTrack = CurrentTrack; - AddInternal(CurrentTrack); + var newTrack = new DrawableTrack(current.GetTrack()); + newTrack.Completed += () => onTrackCompleted(current); + + CurrentTrack = newTrack; + + // At this point we may potentially be in an async context from tests. This is extremely dangerous but we have to make do for now. + // CurrentTrack is immediately updated above for situations where a immediate knowledge about the new track is required, + // but the mutation of the hierarchy is scheduled to avoid exceptions. + Schedule(() => + { + lastTrack.Expire(); + + if (newTrack == CurrentTrack) + AddInternal(newTrack); + else + { + // If the track has changed via changeTrack() being called multiple times in a single update, force disposal on the old track. + newTrack.Dispose(); + } + }); } private void onTrackCompleted(WorkingBeatmap workingBeatmap) From e47a1eb313f86d9c0f635e58545644139d5cbf34 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 12 Aug 2020 01:41:21 +0900 Subject: [PATCH 157/434] Use adjustable ITrack --- osu.Game/Rulesets/Mods/ModDaycore.cs | 4 ++-- osu.Game/Rulesets/Mods/ModNightcore.cs | 4 ++-- osu.Game/Rulesets/Mods/ModRateAdjust.cs | 2 +- osu.Game/Rulesets/Mods/ModTimeRamp.cs | 4 ++-- osu.Game/Screens/Play/FailAnimation.cs | 4 ++-- osu.Game/Screens/Play/GameplayClockContainer.cs | 4 ++-- 6 files changed, 11 insertions(+), 11 deletions(-) diff --git a/osu.Game/Rulesets/Mods/ModDaycore.cs b/osu.Game/Rulesets/Mods/ModDaycore.cs index 800312d047..61ad7db706 100644 --- a/osu.Game/Rulesets/Mods/ModDaycore.cs +++ b/osu.Game/Rulesets/Mods/ModDaycore.cs @@ -30,8 +30,8 @@ namespace osu.Game.Rulesets.Mods public override void ApplyToTrack(ITrack track) { // base.ApplyToTrack() intentionally not called (different tempo adjustment is applied) - (track as IAdjustableAudioComponent)?.AddAdjustment(AdjustableProperty.Frequency, freqAdjust); - (track as IAdjustableAudioComponent)?.AddAdjustment(AdjustableProperty.Tempo, tempoAdjust); + track.AddAdjustment(AdjustableProperty.Frequency, freqAdjust); + track.AddAdjustment(AdjustableProperty.Tempo, tempoAdjust); } } } diff --git a/osu.Game/Rulesets/Mods/ModNightcore.cs b/osu.Game/Rulesets/Mods/ModNightcore.cs index 4932df08f1..4004953cd1 100644 --- a/osu.Game/Rulesets/Mods/ModNightcore.cs +++ b/osu.Game/Rulesets/Mods/ModNightcore.cs @@ -41,8 +41,8 @@ namespace osu.Game.Rulesets.Mods public override void ApplyToTrack(ITrack track) { // base.ApplyToTrack() intentionally not called (different tempo adjustment is applied) - (track as IAdjustableAudioComponent)?.AddAdjustment(AdjustableProperty.Frequency, freqAdjust); - (track as IAdjustableAudioComponent)?.AddAdjustment(AdjustableProperty.Tempo, tempoAdjust); + track.AddAdjustment(AdjustableProperty.Frequency, freqAdjust); + track.AddAdjustment(AdjustableProperty.Tempo, tempoAdjust); } public void ApplyToDrawableRuleset(DrawableRuleset drawableRuleset) diff --git a/osu.Game/Rulesets/Mods/ModRateAdjust.cs b/osu.Game/Rulesets/Mods/ModRateAdjust.cs index ae7077c67b..fec21764b0 100644 --- a/osu.Game/Rulesets/Mods/ModRateAdjust.cs +++ b/osu.Game/Rulesets/Mods/ModRateAdjust.cs @@ -14,7 +14,7 @@ namespace osu.Game.Rulesets.Mods public virtual void ApplyToTrack(ITrack track) { - (track as IAdjustableAudioComponent)?.AddAdjustment(AdjustableProperty.Tempo, SpeedChange); + track.AddAdjustment(AdjustableProperty.Tempo, SpeedChange); } public virtual void ApplyToSample(SampleChannel sample) diff --git a/osu.Game/Rulesets/Mods/ModTimeRamp.cs b/osu.Game/Rulesets/Mods/ModTimeRamp.cs index b904cf007b..20c8d0f3e7 100644 --- a/osu.Game/Rulesets/Mods/ModTimeRamp.cs +++ b/osu.Game/Rulesets/Mods/ModTimeRamp.cs @@ -89,9 +89,9 @@ namespace osu.Game.Rulesets.Mods private void applyPitchAdjustment(ValueChangedEvent adjustPitchSetting) { // remove existing old adjustment - (track as IAdjustableAudioComponent)?.RemoveAdjustment(adjustmentForPitchSetting(adjustPitchSetting.OldValue), SpeedChange); + track?.RemoveAdjustment(adjustmentForPitchSetting(adjustPitchSetting.OldValue), SpeedChange); - (track as IAdjustableAudioComponent)?.AddAdjustment(adjustmentForPitchSetting(adjustPitchSetting.NewValue), SpeedChange); + track?.AddAdjustment(adjustmentForPitchSetting(adjustPitchSetting.NewValue), SpeedChange); } private AdjustableProperty adjustmentForPitchSetting(bool adjustPitchSettingValue) diff --git a/osu.Game/Screens/Play/FailAnimation.cs b/osu.Game/Screens/Play/FailAnimation.cs index 6ebee209e2..dade904180 100644 --- a/osu.Game/Screens/Play/FailAnimation.cs +++ b/osu.Game/Screens/Play/FailAnimation.cs @@ -69,7 +69,7 @@ namespace osu.Game.Screens.Play Expire(); }); - (track as IAdjustableAudioComponent)?.AddAdjustment(AdjustableProperty.Frequency, trackFreq); + track.AddAdjustment(AdjustableProperty.Frequency, trackFreq); applyToPlayfield(drawableRuleset.Playfield); drawableRuleset.Playfield.HitObjectContainer.FlashColour(Color4.Red, 500); @@ -108,7 +108,7 @@ namespace osu.Game.Screens.Play protected override void Dispose(bool isDisposing) { base.Dispose(isDisposing); - (track as IAdjustableAudioComponent)?.RemoveAdjustment(AdjustableProperty.Frequency, trackFreq); + track?.RemoveAdjustment(AdjustableProperty.Frequency, trackFreq); } } } diff --git a/osu.Game/Screens/Play/GameplayClockContainer.cs b/osu.Game/Screens/Play/GameplayClockContainer.cs index f3466a562e..59e26cdf55 100644 --- a/osu.Game/Screens/Play/GameplayClockContainer.cs +++ b/osu.Game/Screens/Play/GameplayClockContainer.cs @@ -219,8 +219,8 @@ namespace osu.Game.Screens.Play speedAdjustmentsApplied = true; track.ResetSpeedAdjustments(); - (track as IAdjustableAudioComponent)?.AddAdjustment(AdjustableProperty.Frequency, pauseFreqAdjust); - (track as IAdjustableAudioComponent)?.AddAdjustment(AdjustableProperty.Tempo, UserPlaybackRate); + track.AddAdjustment(AdjustableProperty.Frequency, pauseFreqAdjust); + track.AddAdjustment(AdjustableProperty.Tempo, UserPlaybackRate); foreach (var mod in mods.OfType()) mod.ApplyToTrack(track); From c0031955c9ed6c0b74fd655366f988b33ba34ae6 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 12 Aug 2020 01:50:18 +0900 Subject: [PATCH 158/434] Update with further framework changes --- osu.Game/Screens/Menu/IntroTriangles.cs | 2 +- osu.Game/Screens/Play/GameplayClockContainer.cs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Menu/IntroTriangles.cs b/osu.Game/Screens/Menu/IntroTriangles.cs index 86f7dbdd6f..a9ef20436f 100644 --- a/osu.Game/Screens/Menu/IntroTriangles.cs +++ b/osu.Game/Screens/Menu/IntroTriangles.cs @@ -59,7 +59,7 @@ namespace osu.Game.Screens.Menu LoadComponentAsync(new TrianglesIntroSequence(logo, background) { RelativeSizeAxes = Axes.Both, - Clock = new FramedClock(UsingThemedIntro ? (IAdjustableClock)Track : null), + Clock = new FramedClock(UsingThemedIntro ? Track : null), LoadMenu = LoadMenu }, t => { diff --git a/osu.Game/Screens/Play/GameplayClockContainer.cs b/osu.Game/Screens/Play/GameplayClockContainer.cs index 59e26cdf55..f0bbcf957a 100644 --- a/osu.Game/Screens/Play/GameplayClockContainer.cs +++ b/osu.Game/Screens/Play/GameplayClockContainer.cs @@ -132,7 +132,7 @@ namespace osu.Game.Screens.Play Schedule(() => { - adjustableClock.ChangeSource((IAdjustableClock)track); + adjustableClock.ChangeSource(track); updateRate(); if (!IsPaused.Value) @@ -201,7 +201,7 @@ namespace osu.Game.Screens.Play removeSourceClockAdjustments(); track = new TrackVirtual(track.Length); - adjustableClock.ChangeSource((IAdjustableClock)track); + adjustableClock.ChangeSource(track); } protected override void Update() From 84655b0798d16f462ec24bb9727c91c2edcde55e Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 11 Aug 2020 20:17:29 +0300 Subject: [PATCH 159/434] Change hover colour for news title --- osu.Game/Overlays/Dashboard/Home/News/NewsTitleLink.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Dashboard/Home/News/NewsTitleLink.cs b/osu.Game/Overlays/Dashboard/Home/News/NewsTitleLink.cs index da98c92bbe..d6a3a69fe0 100644 --- a/osu.Game/Overlays/Dashboard/Home/News/NewsTitleLink.cs +++ b/osu.Game/Overlays/Dashboard/Home/News/NewsTitleLink.cs @@ -24,7 +24,7 @@ namespace osu.Game.Overlays.Dashboard.Home.News } [BackgroundDependencyLoader] - private void load(GameHost host) + private void load(GameHost host, OverlayColourProvider colourProvider) { Child = new TextFlowContainer(t => { @@ -36,6 +36,8 @@ namespace osu.Game.Overlays.Dashboard.Home.News Text = post.Title }; + HoverColour = colourProvider.Light1; + TooltipText = "view in browser"; Action = () => host.OpenUrlExternally("https://osu.ppy.sh/home/news/" + post.Slug); } From b78ccf8a347ca3995712c4424f8d72f580a929de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Tue, 11 Aug 2020 21:28:00 +0200 Subject: [PATCH 160/434] Rewrite Spun Out test scene --- .../Mods/TestSceneOsuModSpunOut.cs | 39 ++++++++++++ .../TestSceneSpinnerSpunOut.cs | 59 ------------------- 2 files changed, 39 insertions(+), 59 deletions(-) create mode 100644 osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModSpunOut.cs delete mode 100644 osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerSpunOut.cs diff --git a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModSpunOut.cs b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModSpunOut.cs new file mode 100644 index 0000000000..1b052600ca --- /dev/null +++ b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModSpunOut.cs @@ -0,0 +1,39 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Collections.Generic; +using System.Linq; +using NUnit.Framework; +using osu.Framework.Testing; +using osu.Game.Beatmaps; +using osu.Game.Rulesets.Objects; +using osu.Game.Rulesets.Osu.Mods; +using osu.Game.Rulesets.Osu.Objects; +using osu.Game.Rulesets.Osu.Objects.Drawables; +using osuTK; + +namespace osu.Game.Rulesets.Osu.Tests.Mods +{ + public class TestSceneOsuModSpunOut : OsuModTestScene + { + [Test] + public void TestSpinnerAutoCompleted() => CreateModTest(new ModTestData + { + Mod = new OsuModSpunOut(), + Autoplay = false, + Beatmap = new Beatmap + { + HitObjects = new List + { + new Spinner + { + Position = new Vector2(256, 192), + StartTime = 500, + Duration = 2000 + } + } + }, + PassCondition = () => Player.ChildrenOfType().Single().Progress >= 1 + }); + } +} diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerSpunOut.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerSpunOut.cs deleted file mode 100644 index d1210db6b1..0000000000 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerSpunOut.cs +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using System.Linq; -using NUnit.Framework; -using osu.Framework.Graphics; -using osu.Game.Beatmaps; -using osu.Game.Beatmaps.ControlPoints; -using osu.Game.Rulesets.Mods; -using osu.Game.Rulesets.Osu.Mods; -using osu.Game.Rulesets.Osu.Objects; -using osu.Game.Rulesets.Osu.Objects.Drawables; -using osu.Game.Tests.Visual; - -namespace osu.Game.Rulesets.Osu.Tests -{ - [TestFixture] - public class TestSceneSpinnerSpunOut : OsuTestScene - { - [SetUp] - public void SetUp() => Schedule(() => - { - SelectedMods.Value = new[] { new OsuModSpunOut() }; - }); - - [Test] - public void TestSpunOut() - { - DrawableSpinner spinner = null; - - AddStep("create spinner", () => spinner = createSpinner()); - - AddUntilStep("wait for end", () => Time.Current > spinner.LifetimeEnd); - - AddAssert("spinner is completed", () => spinner.Progress >= 1); - } - - private DrawableSpinner createSpinner() - { - var spinner = new Spinner - { - StartTime = Time.Current + 500, - EndTime = Time.Current + 2500 - }; - spinner.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty()); - - var drawableSpinner = new DrawableSpinner(spinner) - { - Anchor = Anchor.Centre - }; - - foreach (var mod in SelectedMods.Value.OfType()) - mod.ApplyToDrawableHitObjects(new[] { drawableSpinner }); - - Add(drawableSpinner); - return drawableSpinner; - } - } -} From 8fe5775ecb82be2a6d52149a4f0393150316ec58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Tue, 11 Aug 2020 21:55:20 +0200 Subject: [PATCH 161/434] Allow testing mod combinations in ModTestScenes --- osu.Game/Tests/Visual/ModTestScene.cs | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/osu.Game/Tests/Visual/ModTestScene.cs b/osu.Game/Tests/Visual/ModTestScene.cs index 23b5ad0bd8..a71d008eb9 100644 --- a/osu.Game/Tests/Visual/ModTestScene.cs +++ b/osu.Game/Tests/Visual/ModTestScene.cs @@ -40,8 +40,8 @@ namespace osu.Game.Tests.Visual { var mods = new List(SelectedMods.Value); - if (currentTestData.Mod != null) - mods.Add(currentTestData.Mod); + if (currentTestData.Mods != null) + mods.AddRange(currentTestData.Mods); if (currentTestData.Autoplay) mods.Add(ruleset.GetAutoplayMod()); @@ -85,9 +85,18 @@ namespace osu.Game.Tests.Visual public Func PassCondition; /// - /// The this test case tests. + /// The s this test case tests. /// - public Mod Mod; + public IReadOnlyList Mods; + + /// + /// Convenience property for setting if only + /// a single mod is to be tested. + /// + public Mod Mod + { + set => Mods = new[] { value }; + } } } } From 25f59e0489a292b825f60af57d6a8ac9df7e1692 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Tue, 11 Aug 2020 21:55:50 +0200 Subject: [PATCH 162/434] Add failing test cases --- .../Mods/TestSceneOsuModSpunOut.cs | 50 ++++++++++++++----- 1 file changed, 38 insertions(+), 12 deletions(-) diff --git a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModSpunOut.cs b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModSpunOut.cs index 1b052600ca..d8064d36ea 100644 --- a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModSpunOut.cs +++ b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModSpunOut.cs @@ -1,39 +1,65 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System; using System.Collections.Generic; using System.Linq; using NUnit.Framework; using osu.Framework.Testing; +using osu.Framework.Utils; using osu.Game.Beatmaps; +using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Osu.Mods; using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Osu.Objects.Drawables; +using osu.Game.Rulesets.Osu.Objects.Drawables.Pieces; using osuTK; namespace osu.Game.Rulesets.Osu.Tests.Mods { public class TestSceneOsuModSpunOut : OsuModTestScene { + protected override bool AllowFail => true; + [Test] public void TestSpinnerAutoCompleted() => CreateModTest(new ModTestData { Mod = new OsuModSpunOut(), Autoplay = false, - Beatmap = new Beatmap - { - HitObjects = new List - { - new Spinner - { - Position = new Vector2(256, 192), - StartTime = 500, - Duration = 2000 - } - } - }, + Beatmap = singleSpinnerBeatmap, PassCondition = () => Player.ChildrenOfType().Single().Progress >= 1 }); + + [TestCase(null)] + [TestCase(typeof(OsuModDoubleTime))] + [TestCase(typeof(OsuModHalfTime))] + public void TestSpinRateUnaffectedByMods(Type additionalModType) + { + var mods = new List { new OsuModSpunOut() }; + if (additionalModType != null) + mods.Add((Mod)Activator.CreateInstance(additionalModType)); + + CreateModTest(new ModTestData + { + Mods = mods, + Autoplay = false, + Beatmap = singleSpinnerBeatmap, + PassCondition = () => Precision.AlmostEquals(Player.ChildrenOfType().Single().SpinsPerMinute, 286, 1) + }); + } + + private Beatmap singleSpinnerBeatmap => new Beatmap + { + HitObjects = new List + { + new Spinner + { + Position = new Vector2(256, 192), + StartTime = 500, + Duration = 2000 + } + } + }; } } From bcaaf2527892e3ac2a02fc64e8226f5664a4a5f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Tue, 11 Aug 2020 22:04:18 +0200 Subject: [PATCH 163/434] Fix Spun Out mod being affected by rate-changing mods --- osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs b/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs index 47d765fecd..2816073e8c 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs @@ -41,7 +41,12 @@ namespace osu.Game.Rulesets.Osu.Mods var spinner = (DrawableSpinner)drawable; spinner.RotationTracker.Tracking = true; - spinner.RotationTracker.AddRotation(MathUtils.RadiansToDegrees((float)spinner.Clock.ElapsedFrameTime * 0.03f)); + + // because the spinner is under the gameplay clock, it is affected by rate adjustments on the track; + // for that reason using ElapsedFrameTime directly leads to fewer SPM with Half Time and more SPM with Double Time. + // for spinners we want the real (wall clock) elapsed time; to achieve that, unapply the clock rate locally here. + var rateIndependentElapsedTime = spinner.Clock.ElapsedFrameTime / spinner.Clock.Rate; + spinner.RotationTracker.AddRotation(MathUtils.RadiansToDegrees((float)rateIndependentElapsedTime * 0.03f)); } } } From 4f3f95540be8836006ce2bffee47f51efa987617 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Tue, 11 Aug 2020 22:34:46 +0200 Subject: [PATCH 164/434] Check for zero rate to prevent crashes on unpause --- osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs b/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs index 2816073e8c..f080e11933 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs @@ -42,6 +42,10 @@ namespace osu.Game.Rulesets.Osu.Mods spinner.RotationTracker.Tracking = true; + // early-return if we were paused to avoid division-by-zero in the subsequent calculations. + if (Precision.AlmostEquals(spinner.Clock.Rate, 0)) + return; + // because the spinner is under the gameplay clock, it is affected by rate adjustments on the track; // for that reason using ElapsedFrameTime directly leads to fewer SPM with Half Time and more SPM with Double Time. // for spinners we want the real (wall clock) elapsed time; to achieve that, unapply the clock rate locally here. From f3202fb123807ed3ef1b1a693e88f80f9ff42296 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 12 Aug 2020 11:24:26 +0300 Subject: [PATCH 165/434] Naming adjustments --- osu.Game.Tests/Visual/Online/TestSceneHomeNewsPanel.cs | 6 +++--- .../News/{HomeNewsPanel.cs => FeaturedNewsItemPanel.cs} | 4 ++-- .../Home/News/{CollapsedNewsPanel.cs => NewsGroupItem.cs} | 4 ++-- .../News/{HomeNewsGroupPanel.cs => NewsItemGroupPanel.cs} | 8 ++++---- .../{HomeShowMoreNewsPanel.cs => ShowMoreNewsPanel.cs} | 4 ++-- 5 files changed, 13 insertions(+), 13 deletions(-) rename osu.Game/Overlays/Dashboard/Home/News/{HomeNewsPanel.cs => FeaturedNewsItemPanel.cs} (98%) rename osu.Game/Overlays/Dashboard/Home/News/{CollapsedNewsPanel.cs => NewsGroupItem.cs} (97%) rename osu.Game/Overlays/Dashboard/Home/News/{HomeNewsGroupPanel.cs => NewsItemGroupPanel.cs} (76%) rename osu.Game/Overlays/Dashboard/Home/News/{HomeShowMoreNewsPanel.cs => ShowMoreNewsPanel.cs} (93%) diff --git a/osu.Game.Tests/Visual/Online/TestSceneHomeNewsPanel.cs b/osu.Game.Tests/Visual/Online/TestSceneHomeNewsPanel.cs index b1c0c5adcd..a1251ca793 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneHomeNewsPanel.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneHomeNewsPanel.cs @@ -30,7 +30,7 @@ namespace osu.Game.Tests.Visual.Online Spacing = new Vector2(0, 5), Children = new Drawable[] { - new HomeNewsPanel(new APINewsPost + new FeaturedNewsItemPanel(new APINewsPost { Title = "This post has an image which starts with \"/\" and has many authors!", Preview = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.", @@ -38,7 +38,7 @@ namespace osu.Game.Tests.Visual.Online PublishedAt = DateTimeOffset.Now, Slug = "2020-07-16-summer-theme-park-2020-voting-open" }), - new HomeNewsGroupPanel(new List + new NewsItemGroupPanel(new List { new APINewsPost { @@ -53,7 +53,7 @@ namespace osu.Game.Tests.Visual.Online PublishedAt = DateTimeOffset.Now, } }), - new HomeShowMoreNewsPanel() + new ShowMoreNewsPanel() } }); } diff --git a/osu.Game/Overlays/Dashboard/Home/News/HomeNewsPanel.cs b/osu.Game/Overlays/Dashboard/Home/News/FeaturedNewsItemPanel.cs similarity index 98% rename from osu.Game/Overlays/Dashboard/Home/News/HomeNewsPanel.cs rename to osu.Game/Overlays/Dashboard/Home/News/FeaturedNewsItemPanel.cs index ca56c33315..ee88469e2f 100644 --- a/osu.Game/Overlays/Dashboard/Home/News/HomeNewsPanel.cs +++ b/osu.Game/Overlays/Dashboard/Home/News/FeaturedNewsItemPanel.cs @@ -18,11 +18,11 @@ using osuTK.Graphics; namespace osu.Game.Overlays.Dashboard.Home.News { - public class HomeNewsPanel : HomePanel + public class FeaturedNewsItemPanel : HomePanel { private readonly APINewsPost post; - public HomeNewsPanel(APINewsPost post) + public FeaturedNewsItemPanel(APINewsPost post) { this.post = post; } diff --git a/osu.Game/Overlays/Dashboard/Home/News/CollapsedNewsPanel.cs b/osu.Game/Overlays/Dashboard/Home/News/NewsGroupItem.cs similarity index 97% rename from osu.Game/Overlays/Dashboard/Home/News/CollapsedNewsPanel.cs rename to osu.Game/Overlays/Dashboard/Home/News/NewsGroupItem.cs index 7dbc6a8f87..dc4f3f8c92 100644 --- a/osu.Game/Overlays/Dashboard/Home/News/CollapsedNewsPanel.cs +++ b/osu.Game/Overlays/Dashboard/Home/News/NewsGroupItem.cs @@ -12,11 +12,11 @@ using osu.Game.Online.API.Requests.Responses; namespace osu.Game.Overlays.Dashboard.Home.News { - public class CollapsedNewsPanel : CompositeDrawable + public class NewsGroupItem : CompositeDrawable { private readonly APINewsPost post; - public CollapsedNewsPanel(APINewsPost post) + public NewsGroupItem(APINewsPost post) { this.post = post; } diff --git a/osu.Game/Overlays/Dashboard/Home/News/HomeNewsGroupPanel.cs b/osu.Game/Overlays/Dashboard/Home/News/NewsItemGroupPanel.cs similarity index 76% rename from osu.Game/Overlays/Dashboard/Home/News/HomeNewsGroupPanel.cs rename to osu.Game/Overlays/Dashboard/Home/News/NewsItemGroupPanel.cs index 6007f1408b..c1d5a87ef5 100644 --- a/osu.Game/Overlays/Dashboard/Home/News/HomeNewsGroupPanel.cs +++ b/osu.Game/Overlays/Dashboard/Home/News/NewsItemGroupPanel.cs @@ -10,11 +10,11 @@ using osu.Game.Online.API.Requests.Responses; namespace osu.Game.Overlays.Dashboard.Home.News { - public class HomeNewsGroupPanel : HomePanel + public class NewsItemGroupPanel : HomePanel { private readonly List posts; - public HomeNewsGroupPanel(List posts) + public NewsItemGroupPanel(List posts) { this.posts = posts; } @@ -24,12 +24,12 @@ namespace osu.Game.Overlays.Dashboard.Home.News { Content.Padding = new MarginPadding { Vertical = 5 }; - Child = new FillFlowContainer + Child = new FillFlowContainer { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, Direction = FillDirection.Vertical, - Children = posts.Select(p => new CollapsedNewsPanel(p)).ToArray() + Children = posts.Select(p => new NewsGroupItem(p)).ToArray() }; } } diff --git a/osu.Game/Overlays/Dashboard/Home/News/HomeShowMoreNewsPanel.cs b/osu.Game/Overlays/Dashboard/Home/News/ShowMoreNewsPanel.cs similarity index 93% rename from osu.Game/Overlays/Dashboard/Home/News/HomeShowMoreNewsPanel.cs rename to osu.Game/Overlays/Dashboard/Home/News/ShowMoreNewsPanel.cs index abb4bd7969..d25df6f189 100644 --- a/osu.Game/Overlays/Dashboard/Home/News/HomeShowMoreNewsPanel.cs +++ b/osu.Game/Overlays/Dashboard/Home/News/ShowMoreNewsPanel.cs @@ -10,7 +10,7 @@ using osuTK.Graphics; namespace osu.Game.Overlays.Dashboard.Home.News { - public class HomeShowMoreNewsPanel : OsuHoverContainer + public class ShowMoreNewsPanel : OsuHoverContainer { protected override IEnumerable EffectTargets => new[] { text }; @@ -19,7 +19,7 @@ namespace osu.Game.Overlays.Dashboard.Home.News private OsuSpriteText text; - public HomeShowMoreNewsPanel() + public ShowMoreNewsPanel() { RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; From b10cddf625c9a51bfeac4e22a9871818486cd1f9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 12 Aug 2020 23:28:08 +0900 Subject: [PATCH 166/434] Update framework --- osu.Android.props | 2 +- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index a384ad4c34..7c0cb9271e 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -52,6 +52,6 @@ - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index b38ef38ec2..bb89492e8b 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -24,7 +24,7 @@ - + diff --git a/osu.iOS.props b/osu.iOS.props index 00ddd94d53..8364caa42f 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -70,7 +70,7 @@ - + @@ -80,7 +80,7 @@ - + From 00f8bb7c3e36ccb09de2b1634a9f5161b3a8cd67 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 12 Aug 2020 23:28:45 +0900 Subject: [PATCH 167/434] Update resources --- osu.Android.props | 2 +- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index 7c0cb9271e..241b836aac 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -51,7 +51,7 @@ - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index bb89492e8b..63267e1494 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -25,7 +25,7 @@ - + diff --git a/osu.iOS.props b/osu.iOS.props index 8364caa42f..3500eb75dc 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -71,7 +71,7 @@ - + From 45876bc55aca3d28034c8ba7d6b3ea5322708c23 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 12 Aug 2020 23:50:33 +0900 Subject: [PATCH 168/434] Fix reference to non-existent variable --- osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerRotation.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerRotation.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerRotation.cs index ab6cf60a79..3c559765d4 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerRotation.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerRotation.cs @@ -194,7 +194,7 @@ namespace osu.Game.Rulesets.Osu.Tests addSeekStep(0); - AddStep("adjust track rate", () => track.AddAdjustment(AdjustableProperty.Tempo, new BindableDouble(rate))); + AddStep("adjust track rate", () => MusicController.CurrentTrack.AddAdjustment(AdjustableProperty.Tempo, new BindableDouble(rate))); // autoplay replay frames use track time; // if a spin takes 1000ms in track time and we're playing with a 2x rate adjustment, the spin will take 500ms of *real* time. // therefore we need to apply the rate adjustment to the replay itself to change from track time to real time, From 91e28b849de0ed31402536b63069b8b2d5383f4b Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 13 Aug 2020 00:29:23 +0900 Subject: [PATCH 169/434] Fix incorrect BeatmapManager construction --- .../Visual/UserInterface/TestSceneDeleteLocalScore.cs | 3 ++- osu.Game/Beatmaps/BeatmapManager.cs | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneDeleteLocalScore.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneDeleteLocalScore.cs index eb4750a597..e54292f7cc 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneDeleteLocalScore.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneDeleteLocalScore.cs @@ -6,6 +6,7 @@ using System.Linq; using NUnit.Framework; using osu.Framework.Graphics; using osu.Framework.Allocation; +using osu.Framework.Audio; using osu.Framework.Graphics.Cursor; using osu.Framework.Platform; using osu.Framework.Testing; @@ -79,7 +80,7 @@ namespace osu.Game.Tests.Visual.UserInterface var dependencies = new DependencyContainer(base.CreateChildDependencies(parent)); dependencies.Cache(rulesetStore = new RulesetStore(ContextFactory)); - dependencies.Cache(beatmapManager = new BeatmapManager(LocalStorage, ContextFactory, rulesetStore, null, Audio, dependencies.Get(), Beatmap.Default)); + dependencies.Cache(beatmapManager = new BeatmapManager(LocalStorage, ContextFactory, rulesetStore, null, dependencies.Get(), dependencies.Get(), Beatmap.Default)); dependencies.Cache(scoreManager = new ScoreManager(rulesetStore, () => beatmapManager, LocalStorage, null, ContextFactory)); beatmap = beatmapManager.Import(TestResources.GetTestBeatmapForImport()).Result.Beatmaps[0]; diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index 6f01580998..0cadcf5947 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -9,6 +9,7 @@ using System.Linq.Expressions; using System.Text; using System.Threading; using System.Threading.Tasks; +using JetBrains.Annotations; using Microsoft.EntityFrameworkCore; using osu.Framework.Audio; using osu.Framework.Audio.Track; @@ -67,7 +68,7 @@ namespace osu.Game.Beatmaps private readonly TextureStore textureStore; private readonly ITrackStore trackStore; - public BeatmapManager(Storage storage, IDatabaseContextFactory contextFactory, RulesetStore rulesets, IAPIProvider api, AudioManager audioManager, GameHost host = null, + public BeatmapManager(Storage storage, IDatabaseContextFactory contextFactory, RulesetStore rulesets, IAPIProvider api, [NotNull] AudioManager audioManager, GameHost host = null, WorkingBeatmap defaultBeatmap = null) : base(storage, contextFactory, api, new BeatmapStore(contextFactory), host) { From 27cd9e119aa27be6ce39ee7989f30c5ead5437db Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 13 Aug 2020 12:04:32 +0900 Subject: [PATCH 170/434] Delay beatmap load until after transition has finished Previously the beatmap would begin loading at the same time the `PlayerLoader` class was. This can cause a horribly visible series of stutters, especially when a storyboard is involved. Obviously we should be aiming to reduce the stutters via changes to the beatmap load process (such as incremental storyboard loading, `DrawableHitObject` pooling, etc.) but this improves user experience tenfold in the mean time. --- osu.Game/Screens/Play/PlayerLoader.cs | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/osu.Game/Screens/Play/PlayerLoader.cs b/osu.Game/Screens/Play/PlayerLoader.cs index 93a734589c..d32fae1b90 100644 --- a/osu.Game/Screens/Play/PlayerLoader.cs +++ b/osu.Game/Screens/Play/PlayerLoader.cs @@ -153,8 +153,6 @@ namespace osu.Game.Screens.Play { base.OnEntering(last); - prepareNewPlayer(); - content.ScaleTo(0.7f); Background?.FadeColour(Color4.White, 800, Easing.OutQuint); @@ -172,11 +170,6 @@ namespace osu.Game.Screens.Play contentIn(); - MetadataInfo.Loading = true; - - // we will only be resumed if the player has requested a re-run (see restartRequested). - prepareNewPlayer(); - this.Delay(400).Schedule(pushWhenLoaded); } @@ -257,6 +250,9 @@ namespace osu.Game.Screens.Play private void prepareNewPlayer() { + if (!this.IsCurrentScreen()) + return; + var restartCount = player?.RestartCount + 1 ?? 0; player = createPlayer(); @@ -274,8 +270,10 @@ namespace osu.Game.Screens.Play private void contentIn() { - content.ScaleTo(1, 650, Easing.OutQuint); + MetadataInfo.Loading = true; + content.FadeInFromZero(400); + content.ScaleTo(1, 650, Easing.OutQuint).Then().Schedule(prepareNewPlayer); } private void contentOut() From 99bea6b8e9e5d5a586179c385d7a14c246c522f4 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 13 Aug 2020 12:52:35 +0900 Subject: [PATCH 171/434] Add missing null check (player construction is potentially delayed now) --- osu.Game/Screens/Play/PlayerLoader.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Play/PlayerLoader.cs b/osu.Game/Screens/Play/PlayerLoader.cs index d32fae1b90..dcf84a8821 100644 --- a/osu.Game/Screens/Play/PlayerLoader.cs +++ b/osu.Game/Screens/Play/PlayerLoader.cs @@ -68,7 +68,7 @@ namespace osu.Game.Screens.Play private bool readyForPush => // don't push unless the player is completely loaded - player.LoadState == LoadState.Ready + player?.LoadState == LoadState.Ready // don't push if the user is hovering one of the panes, unless they are idle. && (IsHovered || idleTracker.IsIdle.Value) // don't push if the user is dragging a slider or otherwise. From 5b536aebe71a49f2c4eab4edd508985d00bdcdf3 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 13 Aug 2020 12:53:37 +0900 Subject: [PATCH 172/434] Add missing null checks and avoid cross-test pollution --- osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs b/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs index 4c73065087..c34b523c97 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs @@ -49,6 +49,8 @@ namespace osu.Game.Tests.Visual.Gameplay /// An action to run after container load. public void ResetPlayer(bool interactive, Action beforeLoadAction = null, Action afterLoadAction = null) { + player = null; + audioManager.Volume.SetDefault(); InputManager.Clear(); @@ -80,7 +82,7 @@ namespace osu.Game.Tests.Visual.Gameplay AddAssert("mod rate applied", () => Beatmap.Value.Track.Rate != 1); AddStep("exit loader", () => loader.Exit()); AddUntilStep("wait for not current", () => !loader.IsCurrentScreen()); - AddAssert("player did not load", () => !player.IsLoaded); + AddAssert("player did not load", () => player?.IsLoaded != true); AddUntilStep("player disposed", () => loader.DisposalTask?.IsCompleted == true); AddAssert("mod rate still applied", () => Beatmap.Value.Track.Rate != 1); } @@ -94,7 +96,7 @@ namespace osu.Game.Tests.Visual.Gameplay AddUntilStep("wait for load ready", () => { moveMouse(); - return player.LoadState == LoadState.Ready; + return player?.LoadState == LoadState.Ready; }); AddRepeatStep("move mouse", moveMouse, 20); @@ -222,7 +224,7 @@ namespace osu.Game.Tests.Visual.Gameplay AddStep("reset notification lock", () => sessionStatics.GetBindable(Static.MutedAudioNotificationShownOnce).Value = false); AddStep("load player", () => ResetPlayer(false, beforeLoad, afterLoad)); - AddUntilStep("wait for player", () => player.LoadState == LoadState.Ready); + AddUntilStep("wait for player", () => player?.LoadState == LoadState.Ready); AddAssert("check for notification", () => container.NotificationOverlay.UnreadCount.Value == 1); AddStep("click notification", () => From fd7bf70b7d4302c1536a6b0e1489ac0c9ff5a1ff Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 13 Aug 2020 12:59:00 +0900 Subject: [PATCH 173/434] Remove weird "after load" action This was pretty pointless anyway and from its usages, doesn't look to need to exist. --- .../Visual/Gameplay/TestScenePlayerLoader.cs | 24 ++++++++----------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs b/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs index c34b523c97..d6742a27c2 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs @@ -46,8 +46,7 @@ namespace osu.Game.Tests.Visual.Gameplay /// /// If the test player should behave like the production one. /// An action to run before player load but after bindable leases are returned. - /// An action to run after container load. - public void ResetPlayer(bool interactive, Action beforeLoadAction = null, Action afterLoadAction = null) + public void ResetPlayer(bool interactive, Action beforeLoadAction = null) { player = null; @@ -55,18 +54,16 @@ namespace osu.Game.Tests.Visual.Gameplay InputManager.Clear(); + container = new TestPlayerLoaderContainer(loader = new TestPlayerLoader(() => player = new TestPlayer(interactive, interactive))); + beforeLoadAction?.Invoke(); + Beatmap.Value = CreateWorkingBeatmap(new OsuRuleset().RulesetInfo); foreach (var mod in SelectedMods.Value.OfType()) mod.ApplyToTrack(Beatmap.Value.Track); - InputManager.Child = container = new TestPlayerLoaderContainer( - loader = new TestPlayerLoader(() => - { - afterLoadAction?.Invoke(); - return player = new TestPlayer(interactive, interactive); - })); + InputManager.Child = container; } /// @@ -197,19 +194,19 @@ namespace osu.Game.Tests.Visual.Gameplay [Test] public void TestMutedNotificationMasterVolume() { - addVolumeSteps("master volume", () => audioManager.Volume.Value = 0, null, () => audioManager.Volume.IsDefault); + addVolumeSteps("master volume", () => audioManager.Volume.Value = 0, () => audioManager.Volume.IsDefault); } [Test] public void TestMutedNotificationTrackVolume() { - addVolumeSteps("music volume", () => audioManager.VolumeTrack.Value = 0, null, () => audioManager.VolumeTrack.IsDefault); + addVolumeSteps("music volume", () => audioManager.VolumeTrack.Value = 0, () => audioManager.VolumeTrack.IsDefault); } [Test] public void TestMutedNotificationMuteButton() { - addVolumeSteps("mute button", null, () => container.VolumeOverlay.IsMuted.Value = true, () => !container.VolumeOverlay.IsMuted.Value); + addVolumeSteps("mute button", () => container.VolumeOverlay.IsMuted.Value = true, () => !container.VolumeOverlay.IsMuted.Value); } /// @@ -217,13 +214,12 @@ namespace osu.Game.Tests.Visual.Gameplay /// /// What part of the volume system is checked /// The action to be invoked to set the volume before loading - /// The action to be invoked to set the volume after loading /// The function to be invoked and checked - private void addVolumeSteps(string volumeName, Action beforeLoad, Action afterLoad, Func assert) + private void addVolumeSteps(string volumeName, Action beforeLoad, Func assert) { AddStep("reset notification lock", () => sessionStatics.GetBindable(Static.MutedAudioNotificationShownOnce).Value = false); - AddStep("load player", () => ResetPlayer(false, beforeLoad, afterLoad)); + AddStep("load player", () => ResetPlayer(false, beforeLoad)); AddUntilStep("wait for player", () => player?.LoadState == LoadState.Ready); AddAssert("check for notification", () => container.NotificationOverlay.UnreadCount.Value == 1); From cf9bda6c199bddcbf957033191285814c531b04a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 13 Aug 2020 13:05:00 +0900 Subject: [PATCH 174/434] Add coverage of early exit with null and non-null player --- .../Visual/Gameplay/TestScenePlayerLoader.cs | 28 ++++++++++++++----- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs b/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs index d6742a27c2..e698d31176 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs @@ -66,20 +66,34 @@ namespace osu.Game.Tests.Visual.Gameplay InputManager.Child = container; } - /// - /// When exits early, it has to wait for the player load task - /// to complete before running disposal on player. This previously caused an issue where mod - /// speed adjustments were undone too late, causing cross-screen pollution. - /// [Test] - public void TestEarlyExit() + public void TestEarlyExitBeforePlayerConstruction() { AddStep("load dummy beatmap", () => ResetPlayer(false, () => SelectedMods.Value = new[] { new OsuModNightcore() })); AddUntilStep("wait for current", () => loader.IsCurrentScreen()); AddAssert("mod rate applied", () => Beatmap.Value.Track.Rate != 1); AddStep("exit loader", () => loader.Exit()); AddUntilStep("wait for not current", () => !loader.IsCurrentScreen()); - AddAssert("player did not load", () => player?.IsLoaded != true); + AddAssert("player did not load", () => player == null); + AddUntilStep("player disposed", () => loader.DisposalTask == null); + AddAssert("mod rate still applied", () => Beatmap.Value.Track.Rate != 1); + } + + /// + /// When exits early, it has to wait for the player load task + /// to complete before running disposal on player. This previously caused an issue where mod + /// speed adjustments were undone too late, causing cross-screen pollution. + /// + [Test] + public void TestEarlyExitAfterPlayerConstruction() + { + AddStep("load dummy beatmap", () => ResetPlayer(false, () => SelectedMods.Value = new[] { new OsuModNightcore() })); + AddUntilStep("wait for current", () => loader.IsCurrentScreen()); + AddAssert("mod rate applied", () => Beatmap.Value.Track.Rate != 1); + AddUntilStep("wait for non-null player", () => player != null); + AddStep("exit loader", () => loader.Exit()); + AddUntilStep("wait for not current", () => !loader.IsCurrentScreen()); + AddAssert("player did not load", () => !player.IsLoaded); AddUntilStep("player disposed", () => loader.DisposalTask?.IsCompleted == true); AddAssert("mod rate still applied", () => Beatmap.Value.Track.Rate != 1); } From c71ee0877ff0ad2d5b161a6923a51281c513b76a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 13 Aug 2020 14:07:07 +0900 Subject: [PATCH 175/434] Update fastlane and plugins --- Gemfile.lock | 73 ++++++++++++++++++++++++++-------------------------- 1 file changed, 36 insertions(+), 37 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index bf971d2c22..a4b49af7e4 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -6,35 +6,36 @@ GEM public_suffix (>= 2.0.2, < 5.0) atomos (0.1.3) aws-eventstream (1.1.0) - aws-partitions (1.329.0) - aws-sdk-core (3.99.2) + aws-partitions (1.354.0) + aws-sdk-core (3.104.3) aws-eventstream (~> 1, >= 1.0.2) aws-partitions (~> 1, >= 1.239.0) aws-sigv4 (~> 1.1) jmespath (~> 1.0) - aws-sdk-kms (1.34.1) + aws-sdk-kms (1.36.0) aws-sdk-core (~> 3, >= 3.99.0) aws-sigv4 (~> 1.1) - aws-sdk-s3 (1.68.1) - aws-sdk-core (~> 3, >= 3.99.0) + aws-sdk-s3 (1.78.0) + aws-sdk-core (~> 3, >= 3.104.3) aws-sdk-kms (~> 1) aws-sigv4 (~> 1.1) - aws-sigv4 (1.1.4) - aws-eventstream (~> 1.0, >= 1.0.2) + aws-sigv4 (1.2.1) + aws-eventstream (~> 1, >= 1.0.2) babosa (1.0.3) claide (1.0.3) colored (1.2) colored2 (3.1.2) commander-fastlane (4.4.6) highline (~> 1.7.2) - declarative (0.0.10) + declarative (0.0.20) declarative-option (0.1.0) - digest-crc (0.5.1) + digest-crc (0.6.1) + rake (~> 13.0) domain_name (0.5.20190701) unf (>= 0.0.5, < 1.0.0) - dotenv (2.7.5) - emoji_regex (1.0.1) - excon (0.74.0) + dotenv (2.7.6) + emoji_regex (3.0.0) + excon (0.76.0) faraday (1.0.1) multipart-post (>= 1.2, < 3) faraday-cookie_jar (0.0.6) @@ -42,34 +43,32 @@ GEM http-cookie (~> 1.0.0) faraday_middleware (1.0.0) faraday (~> 1.0) - fastimage (2.1.7) - fastlane (2.149.1) + fastimage (2.2.0) + fastlane (2.156.0) CFPropertyList (>= 2.3, < 4.0.0) addressable (>= 2.3, < 3.0.0) aws-sdk-s3 (~> 1.0) - babosa (>= 1.0.2, < 2.0.0) + babosa (>= 1.0.3, < 2.0.0) bundler (>= 1.12.0, < 3.0.0) colored commander-fastlane (>= 4.4.6, < 5.0.0) dotenv (>= 2.1.1, < 3.0.0) - emoji_regex (>= 0.1, < 2.0) + emoji_regex (>= 0.1, < 4.0) excon (>= 0.71.0, < 1.0.0) - faraday (>= 0.17, < 2.0) + faraday (~> 1.0) faraday-cookie_jar (~> 0.0.6) - faraday_middleware (>= 0.13.1, < 2.0) + faraday_middleware (~> 1.0) fastimage (>= 2.1.0, < 3.0.0) gh_inspector (>= 1.1.2, < 2.0.0) google-api-client (>= 0.37.0, < 0.39.0) google-cloud-storage (>= 1.15.0, < 2.0.0) highline (>= 1.7.2, < 2.0.0) json (< 3.0.0) - jwt (~> 2.1.0) + jwt (>= 2.1.0, < 3) mini_magick (>= 4.9.4, < 5.0.0) - multi_xml (~> 0.5) multipart-post (~> 2.0.0) plist (>= 3.1.0, < 4.0.0) - public_suffix (~> 2.0.0) - rubyzip (>= 1.3.0, < 2.0.0) + rubyzip (>= 2.0.0, < 3.0.0) security (= 0.1.3) simctl (~> 1.6.3) slack-notifier (>= 2.0.0, < 3.0.0) @@ -97,17 +96,17 @@ GEM google-cloud-core (1.5.0) google-cloud-env (~> 1.0) google-cloud-errors (~> 1.0) - google-cloud-env (1.3.2) + google-cloud-env (1.3.3) faraday (>= 0.17.3, < 2.0) google-cloud-errors (1.0.1) - google-cloud-storage (1.26.2) + google-cloud-storage (1.27.0) addressable (~> 2.5) digest-crc (~> 0.4) google-api-client (~> 0.33) google-cloud-core (~> 1.2) googleauth (~> 0.9) mini_mime (~> 1.0) - googleauth (0.12.0) + googleauth (0.13.1) faraday (>= 0.17.3, < 2.0) jwt (>= 1.4, < 3.0) memoist (~> 0.16) @@ -119,29 +118,29 @@ GEM domain_name (~> 0.5) httpclient (2.8.3) jmespath (1.4.0) - json (2.3.0) - jwt (2.1.0) + json (2.3.1) + jwt (2.2.1) memoist (0.16.2) mini_magick (4.10.1) mini_mime (1.0.2) mini_portile2 (2.4.0) - multi_json (1.14.1) - multi_xml (0.6.0) + multi_json (1.15.0) multipart-post (2.0.0) - nanaimo (0.2.6) + nanaimo (0.3.0) naturally (2.2.0) - nokogiri (1.10.7) + nokogiri (1.10.10) mini_portile2 (~> 2.4.0) - os (1.1.0) + os (1.1.1) plist (3.5.0) - public_suffix (2.0.5) + public_suffix (4.0.5) + rake (13.0.1) representable (3.0.4) declarative (< 0.1.0) declarative-option (< 0.2.0) uber (< 0.2.0) retriable (3.1.2) rouge (2.0.7) - rubyzip (1.3.0) + rubyzip (2.3.0) security (0.1.3) signet (0.14.0) addressable (~> 2.3) @@ -160,7 +159,7 @@ GEM terminal-table (1.8.0) unicode-display_width (~> 1.1, >= 1.1.1) tty-cursor (0.7.1) - tty-screen (0.8.0) + tty-screen (0.8.1) tty-spinner (0.9.3) tty-cursor (~> 0.7) uber (0.1.0) @@ -169,12 +168,12 @@ GEM unf_ext (0.0.7.7) unicode-display_width (1.7.0) word_wrap (1.0.0) - xcodeproj (1.16.0) + xcodeproj (1.18.0) CFPropertyList (>= 2.3.3, < 4.0) atomos (~> 0.1.3) claide (>= 1.0.2, < 2.0) colored2 (~> 3.1) - nanaimo (~> 0.2.6) + nanaimo (~> 0.3.0) xcpretty (0.3.0) rouge (~> 2.0.7) xcpretty-travis-formatter (1.0.0) From 662281d727561b70572f76d40174a1bc75d67604 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 13 Aug 2020 18:20:45 +0900 Subject: [PATCH 176/434] Adjust legacy spinners to fade in later Matches stable 1:1 for legacy skins. I've left lazer default as it is because changing to use the shorter apperance looks bad. This will probably change as we proceed with the redesign of the default skin. --- osu.Game.Rulesets.Osu/Skinning/LegacyNewStyleSpinner.cs | 4 ++-- osu.Game.Rulesets.Osu/Skinning/LegacyOldStyleSpinner.cs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Skinning/LegacyNewStyleSpinner.cs b/osu.Game.Rulesets.Osu/Skinning/LegacyNewStyleSpinner.cs index 72bc3ddc9a..739c87e037 100644 --- a/osu.Game.Rulesets.Osu/Skinning/LegacyNewStyleSpinner.cs +++ b/osu.Game.Rulesets.Osu/Skinning/LegacyNewStyleSpinner.cs @@ -79,8 +79,8 @@ namespace osu.Game.Rulesets.Osu.Skinning { var spinner = (Spinner)drawableSpinner.HitObject; - using (BeginAbsoluteSequence(spinner.StartTime - spinner.TimePreempt / 2, true)) - this.FadeInFromZero(spinner.TimePreempt / 2); + using (BeginAbsoluteSequence(spinner.StartTime - spinner.TimeFadeIn / 2, true)) + this.FadeInFromZero(spinner.TimeFadeIn / 2); fixedMiddle.FadeColour(Color4.White); using (BeginAbsoluteSequence(spinner.StartTime, true)) diff --git a/osu.Game.Rulesets.Osu/Skinning/LegacyOldStyleSpinner.cs b/osu.Game.Rulesets.Osu/Skinning/LegacyOldStyleSpinner.cs index 0ae1d8f683..81a0df5ea5 100644 --- a/osu.Game.Rulesets.Osu/Skinning/LegacyOldStyleSpinner.cs +++ b/osu.Game.Rulesets.Osu/Skinning/LegacyOldStyleSpinner.cs @@ -85,8 +85,8 @@ namespace osu.Game.Rulesets.Osu.Skinning { var spinner = drawableSpinner.HitObject; - using (BeginAbsoluteSequence(spinner.StartTime - spinner.TimePreempt / 2, true)) - this.FadeInFromZero(spinner.TimePreempt / 2); + using (BeginAbsoluteSequence(spinner.StartTime - spinner.TimeFadeIn / 2, true)) + this.FadeInFromZero(spinner.TimeFadeIn / 2); } protected override void Update() From 3cb22fad82d6d1f3b0bc07f8bb025acabb090cd5 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 13 Aug 2020 19:48:31 +0900 Subject: [PATCH 177/434] Fix mods sharing bindable instances --- .../UserInterface/TestSceneModSettings.cs | 20 ++++++++++++++++++ osu.Game/Rulesets/Mods/Mod.cs | 21 ++++++++++++++++++- 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneModSettings.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneModSettings.cs index 7ff463361a..c5ce3751ef 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneModSettings.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneModSettings.cs @@ -8,6 +8,7 @@ using NUnit.Framework; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Utils; using osu.Game.Beatmaps; using osu.Game.Configuration; using osu.Game.Graphics.UserInterface; @@ -15,6 +16,7 @@ using osu.Game.Overlays.Mods; using osu.Game.Rulesets; using osu.Game.Rulesets.Difficulty; using osu.Game.Rulesets.Mods; +using osu.Game.Rulesets.Osu.Mods; using osu.Game.Rulesets.UI; namespace osu.Game.Tests.Visual.UserInterface @@ -75,6 +77,24 @@ namespace osu.Game.Tests.Visual.UserInterface AddAssert("Customisation closed", () => modSelect.ModSettingsContainer.Alpha == 0); } + [Test] + public void TestModSettingsUnboundWhenCopied() + { + OsuModDoubleTime original = null; + OsuModDoubleTime copy = null; + + AddStep("create mods", () => + { + original = new OsuModDoubleTime(); + copy = (OsuModDoubleTime)original.CreateCopy(); + }); + + AddStep("change property", () => original.SpeedChange.Value = 2); + + AddAssert("original has new value", () => Precision.AlmostEquals(2.0, original.SpeedChange.Value)); + AddAssert("copy has original value", () => Precision.AlmostEquals(1.5, copy.SpeedChange.Value)); + } + private void createModSelect() { AddStep("create mod select", () => diff --git a/osu.Game/Rulesets/Mods/Mod.cs b/osu.Game/Rulesets/Mods/Mod.cs index 0e5fe3fc9c..52ffa0ad2a 100644 --- a/osu.Game/Rulesets/Mods/Mod.cs +++ b/osu.Game/Rulesets/Mods/Mod.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; using System.Reflection; using Newtonsoft.Json; @@ -126,7 +127,25 @@ namespace osu.Game.Rulesets.Mods /// /// Creates a copy of this initialised to a default state. /// - public virtual Mod CreateCopy() => (Mod)MemberwiseClone(); + public virtual Mod CreateCopy() + { + var copy = (Mod)Activator.CreateInstance(GetType()); + + // Copy bindable values across + foreach (var (_, prop) in this.GetSettingsSourceProperties()) + { + var origBindable = prop.GetValue(this); + var copyBindable = prop.GetValue(copy); + + // The bindables themselves are readonly, so the value must be transferred through the Bindable.Value property. + var valueProperty = origBindable.GetType().GetProperty(nameof(Bindable.Value), BindingFlags.Public | BindingFlags.Instance); + Debug.Assert(valueProperty != null); + + valueProperty.SetValue(copyBindable, valueProperty.GetValue(origBindable)); + } + + return copy; + } public bool Equals(IMod other) => GetType() == other?.GetType(); } From 0500d82b5bed73153b1bcee54374c557a4408ab4 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 13 Aug 2020 19:48:41 +0900 Subject: [PATCH 178/434] Fix playlist items sharing mod instances --- .../Multiplayer/TestSceneMatchSongSelect.cs | 17 +++++++++++++++++ osu.Game/Screens/Select/MatchSongSelect.cs | 2 ++ 2 files changed, 19 insertions(+) diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchSongSelect.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchSongSelect.cs index c62479faa0..3d225aa0a9 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchSongSelect.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchSongSelect.cs @@ -16,7 +16,9 @@ using osu.Framework.Utils; using osu.Game.Beatmaps; using osu.Game.Online.Multiplayer; using osu.Game.Rulesets; +using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Osu; +using osu.Game.Rulesets.Osu.Mods; using osu.Game.Screens.Multi.Components; using osu.Game.Screens.Select; @@ -145,6 +147,21 @@ namespace osu.Game.Tests.Visual.Multiplayer AddAssert("new item has id 2", () => Room.Playlist.Last().ID == 2); } + /// + /// Tests that the same instances are not shared between two playlist items. + /// + [Test] + public void TestNewItemHasNewModInstances() + { + AddStep("set dt mod", () => SelectedMods.Value = new[] { new OsuModDoubleTime() }); + AddStep("create item", () => songSelect.BeatmapDetails.CreateNewItem()); + AddStep("change mod rate", () => ((OsuModDoubleTime)SelectedMods.Value[0]).SpeedChange.Value = 2); + AddStep("create item", () => songSelect.BeatmapDetails.CreateNewItem()); + + AddAssert("item 1 has rate 1.5", () => Precision.AlmostEquals(1.5, ((OsuModDoubleTime)Room.Playlist.First().RequiredMods[0]).SpeedChange.Value)); + AddAssert("item 2 has rate 2", () => Precision.AlmostEquals(2, ((OsuModDoubleTime)Room.Playlist.Last().RequiredMods[0]).SpeedChange.Value)); + } + private class TestMatchSongSelect : MatchSongSelect { public new MatchBeatmapDetailArea BeatmapDetails => (MatchBeatmapDetailArea)base.BeatmapDetails; diff --git a/osu.Game/Screens/Select/MatchSongSelect.cs b/osu.Game/Screens/Select/MatchSongSelect.cs index 2f3674642e..96a48fa3ac 100644 --- a/osu.Game/Screens/Select/MatchSongSelect.cs +++ b/osu.Game/Screens/Select/MatchSongSelect.cs @@ -77,6 +77,8 @@ namespace osu.Game.Screens.Select item.RequiredMods.Clear(); item.RequiredMods.AddRange(Mods.Value); + + Mods.Value = Mods.Value.Select(m => m.CreateCopy()).ToArray(); } } } From 671141ec61e1eaf8b0daeea84c1bb03c498dc997 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 14 Aug 2020 18:05:05 +0900 Subject: [PATCH 179/434] Load menu backgrounds via LargeTextureStore to reduce memory usage --- osu.Game/Graphics/Backgrounds/BeatmapBackground.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Graphics/Backgrounds/BeatmapBackground.cs b/osu.Game/Graphics/Backgrounds/BeatmapBackground.cs index 387e189dc4..058d2ed0f9 100644 --- a/osu.Game/Graphics/Backgrounds/BeatmapBackground.cs +++ b/osu.Game/Graphics/Backgrounds/BeatmapBackground.cs @@ -20,7 +20,7 @@ namespace osu.Game.Graphics.Backgrounds } [BackgroundDependencyLoader] - private void load(TextureStore textures) + private void load(LargeTextureStore textures) { Sprite.Texture = Beatmap?.Background ?? textures.Get(fallbackTextureName); } From c3757a4660f1b1f1633e9b16af75d2960b343006 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 14 Aug 2020 19:22:23 +0900 Subject: [PATCH 180/434] Fix beatmap covers not being unloaded in most overlays Eventually we'll probably want something smarter than this, but for the time being this helps stop runaway memory usage. --- .../Drawables/UpdateableBeatmapSetCover.cs | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/osu.Game/Beatmaps/Drawables/UpdateableBeatmapSetCover.cs b/osu.Game/Beatmaps/Drawables/UpdateableBeatmapSetCover.cs index c60bd0286e..6c229755e7 100644 --- a/osu.Game/Beatmaps/Drawables/UpdateableBeatmapSetCover.cs +++ b/osu.Game/Beatmaps/Drawables/UpdateableBeatmapSetCover.cs @@ -67,19 +67,18 @@ namespace osu.Game.Beatmaps.Drawables if (beatmapSet != null) { - BeatmapSetCover cover; - - Add(displayedCover = new DelayedLoadWrapper( - cover = new BeatmapSetCover(beatmapSet, coverType) + Add(displayedCover = new DelayedLoadUnloadWrapper(() => + { + var cover = new BeatmapSetCover(beatmapSet, coverType) { Anchor = Anchor.Centre, Origin = Anchor.Centre, RelativeSizeAxes = Axes.Both, FillMode = FillMode.Fill, - }) - ); - - cover.OnLoadComplete += d => d.FadeInFromZero(400, Easing.Out); + }; + cover.OnLoadComplete += d => d.FadeInFromZero(400, Easing.Out); + return cover; + })); } } } From e39b2e7218acf876cea7c7efcaa6ae9a4faf7818 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 14 Aug 2020 21:53:18 +0900 Subject: [PATCH 181/434] Update framework --- osu.Android.props | 2 +- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index 241b836aac..f3fb949f76 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -52,6 +52,6 @@ - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 63267e1494..a12ce138bd 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -24,7 +24,7 @@ - + diff --git a/osu.iOS.props b/osu.iOS.props index 3500eb75dc..0170e94140 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -70,7 +70,7 @@ - + @@ -80,7 +80,7 @@ - + From c1a9bf507af61e2737c6c81dc06efcda3dac91c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 15 Aug 2020 13:06:53 +0200 Subject: [PATCH 182/434] Add failing test case --- .../Gameplay/TestSceneGameplayMenuOverlay.cs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneGameplayMenuOverlay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneGameplayMenuOverlay.cs index e8b8c7c8e9..fc9cbb073e 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneGameplayMenuOverlay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneGameplayMenuOverlay.cs @@ -272,7 +272,21 @@ namespace osu.Game.Tests.Visual.Gameplay AddAssert("Overlay is closed", () => pauseOverlay.State.Value == Visibility.Hidden); } + [Test] + public void TestSelectionResetOnVisibilityChange() + { + showOverlay(); + AddStep("Select last button", () => InputManager.Key(Key.Up)); + + hideOverlay(); + showOverlay(); + + AddAssert("No button selected", + () => pauseOverlay.Buttons.All(button => !button.Selected.Value)); + } + private void showOverlay() => AddStep("Show overlay", () => pauseOverlay.Show()); + private void hideOverlay() => AddStep("Hide overlay", () => pauseOverlay.Hide()); private DialogButton getButton(int index) => pauseOverlay.Buttons.Skip(index).First(); From a426ff1d5b26e158c868cb49ec51f21a6f265971 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 15 Aug 2020 13:36:00 +0200 Subject: [PATCH 183/434] Refactor gameplay menu overlay to fix regression --- osu.Game/Screens/Play/GameplayMenuOverlay.cs | 78 ++++++++++++-------- 1 file changed, 47 insertions(+), 31 deletions(-) diff --git a/osu.Game/Screens/Play/GameplayMenuOverlay.cs b/osu.Game/Screens/Play/GameplayMenuOverlay.cs index 57403a0987..f938839be3 100644 --- a/osu.Game/Screens/Play/GameplayMenuOverlay.cs +++ b/osu.Game/Screens/Play/GameplayMenuOverlay.cs @@ -50,7 +50,7 @@ namespace osu.Game.Screens.Play public abstract string Description { get; } - protected internal FillFlowContainer InternalButtons; + protected ButtonContainer InternalButtons; public IReadOnlyList Buttons => InternalButtons; private FillFlowContainer retryCounterContainer; @@ -59,7 +59,7 @@ namespace osu.Game.Screens.Play { RelativeSizeAxes = Axes.Both; - State.ValueChanged += s => selectionIndex = -1; + State.ValueChanged += s => InternalButtons.Deselect(); } [BackgroundDependencyLoader] @@ -114,7 +114,7 @@ namespace osu.Game.Screens.Play } } }, - InternalButtons = new FillFlowContainer + InternalButtons = new ButtonContainer { Origin = Anchor.TopCentre, Anchor = Anchor.TopCentre, @@ -186,40 +186,16 @@ namespace osu.Game.Screens.Play InternalButtons.Add(button); } - private int selectionIndex = -1; - - private void setSelected(int value) - { - if (selectionIndex == value) - return; - - // Deselect the previously-selected button - if (selectionIndex != -1) - InternalButtons[selectionIndex].Selected.Value = false; - - selectionIndex = value; - - // Select the newly-selected button - if (selectionIndex != -1) - InternalButtons[selectionIndex].Selected.Value = true; - } - public bool OnPressed(GlobalAction action) { switch (action) { case GlobalAction.SelectPrevious: - if (selectionIndex == -1 || selectionIndex == 0) - setSelected(InternalButtons.Count - 1); - else - setSelected(selectionIndex - 1); + InternalButtons.SelectPrevious(); return true; case GlobalAction.SelectNext: - if (selectionIndex == -1 || selectionIndex == InternalButtons.Count - 1) - setSelected(0); - else - setSelected(selectionIndex + 1); + InternalButtons.SelectNext(); return true; case GlobalAction.Back: @@ -241,9 +217,9 @@ namespace osu.Game.Screens.Play private void buttonSelectionChanged(DialogButton button, bool isSelected) { if (!isSelected) - setSelected(-1); + InternalButtons.Deselect(); else - setSelected(InternalButtons.IndexOf(button)); + InternalButtons.Select(button); } private void updateRetryCount() @@ -277,6 +253,46 @@ namespace osu.Game.Screens.Play }; } + protected class ButtonContainer : FillFlowContainer + { + private int selectedIndex = -1; + + private void setSelected(int value) + { + if (selectedIndex == value) + return; + + // Deselect the previously-selected button + if (selectedIndex != -1) + this[selectedIndex].Selected.Value = false; + + selectedIndex = value; + + // Select the newly-selected button + if (selectedIndex != -1) + this[selectedIndex].Selected.Value = true; + } + + public void SelectNext() + { + if (selectedIndex == -1 || selectedIndex == Count - 1) + setSelected(0); + else + setSelected(selectedIndex + 1); + } + + public void SelectPrevious() + { + if (selectedIndex == -1 || selectedIndex == 0) + setSelected(Count - 1); + else + setSelected(selectedIndex - 1); + } + + public void Deselect() => setSelected(-1); + public void Select(DialogButton button) => setSelected(IndexOf(button)); + } + private class Button : DialogButton { // required to ensure keyboard navigation always starts from an extremity (unless the cursor is moved) From 5c11270b988f7e8f85eddafe329d048d14228ad6 Mon Sep 17 00:00:00 2001 From: Ron B Date: Sat, 15 Aug 2020 20:12:06 +0300 Subject: [PATCH 184/434] Add SpinnerFrequencyModulate skin config option --- .../Objects/Drawables/DrawableSpinner.cs | 9 ++++++--- osu.Game.Rulesets.Osu/Skinning/OsuSkinConfiguration.cs | 3 ++- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs index d1a6463d72..273a9fda84 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs @@ -12,6 +12,7 @@ using osu.Game.Graphics; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Osu.Objects.Drawables.Pieces; +using osu.Game.Rulesets.Osu.Skinning; using osu.Game.Rulesets.Scoring; using osu.Game.Screens.Ranking; using osu.Game.Skinning; @@ -31,6 +32,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables private readonly IBindable positionBindable = new Bindable(); + private bool spinnerFrequencyModulate; + public DrawableSpinner(Spinner s) : base(s) { @@ -165,10 +168,11 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables } [BackgroundDependencyLoader] - private void load(OsuColour colours) + private void load(OsuColour colours, ISkinSource skin) { positionBindable.BindValueChanged(pos => Position = pos.NewValue); positionBindable.BindTo(HitObject.PositionBindable); + spinnerFrequencyModulate = skin.GetConfig(OsuSkinConfiguration.SpinnerFrequencyModulate)?.Value ?? true; } /// @@ -221,8 +225,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables RotationTracker.Tracking = !Result.HasResult && (OsuActionInputManager?.PressedActions.Any(x => x == OsuAction.LeftButton || x == OsuAction.RightButton) ?? false); if (spinningSample != null) - // todo: implement SpinnerFrequencyModulate - spinningSample.Frequency.Value = 0.5f + Progress; + spinningSample.Frequency.Value = spinnerFrequencyModulate ? 0.5f + Progress : 0.5f; } protected override void UpdateAfterChildren() diff --git a/osu.Game.Rulesets.Osu/Skinning/OsuSkinConfiguration.cs b/osu.Game.Rulesets.Osu/Skinning/OsuSkinConfiguration.cs index 154160fdb5..54755bd9d5 100644 --- a/osu.Game.Rulesets.Osu/Skinning/OsuSkinConfiguration.cs +++ b/osu.Game.Rulesets.Osu/Skinning/OsuSkinConfiguration.cs @@ -13,6 +13,7 @@ namespace osu.Game.Rulesets.Osu.Skinning CursorExpand, CursorRotate, HitCircleOverlayAboveNumber, - HitCircleOverlayAboveNumer // Some old skins will have this typo + HitCircleOverlayAboveNumer, // Some old skins will have this typo + SpinnerFrequencyModulate } } From 896a87e62921bfef2281a822eb20c784e3612fd2 Mon Sep 17 00:00:00 2001 From: Ron B Date: Sat, 15 Aug 2020 20:14:36 +0300 Subject: [PATCH 185/434] Replace accidental tab with spaces --- osu.Game.Rulesets.Osu/Skinning/OsuSkinConfiguration.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Skinning/OsuSkinConfiguration.cs b/osu.Game.Rulesets.Osu/Skinning/OsuSkinConfiguration.cs index 54755bd9d5..1d34727c04 100644 --- a/osu.Game.Rulesets.Osu/Skinning/OsuSkinConfiguration.cs +++ b/osu.Game.Rulesets.Osu/Skinning/OsuSkinConfiguration.cs @@ -13,7 +13,7 @@ namespace osu.Game.Rulesets.Osu.Skinning CursorExpand, CursorRotate, HitCircleOverlayAboveNumber, - HitCircleOverlayAboveNumer, // Some old skins will have this typo + HitCircleOverlayAboveNumer, // Some old skins will have this typo SpinnerFrequencyModulate } } From 61de3c75402f55704c07da9128778f35b374a52f Mon Sep 17 00:00:00 2001 From: Ron B Date: Sat, 15 Aug 2020 20:16:28 +0300 Subject: [PATCH 186/434] Replace accidental tab with spaces --- osu.Game.Rulesets.Osu/Skinning/OsuSkinConfiguration.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Skinning/OsuSkinConfiguration.cs b/osu.Game.Rulesets.Osu/Skinning/OsuSkinConfiguration.cs index 1d34727c04..e034e14eb0 100644 --- a/osu.Game.Rulesets.Osu/Skinning/OsuSkinConfiguration.cs +++ b/osu.Game.Rulesets.Osu/Skinning/OsuSkinConfiguration.cs @@ -13,7 +13,7 @@ namespace osu.Game.Rulesets.Osu.Skinning CursorExpand, CursorRotate, HitCircleOverlayAboveNumber, - HitCircleOverlayAboveNumer, // Some old skins will have this typo - SpinnerFrequencyModulate + HitCircleOverlayAboveNumer, // Some old skins will have this typo + SpinnerFrequencyModulate } } From 07c25d5a78d2df33e3d54d3922da6723c3622f2f Mon Sep 17 00:00:00 2001 From: Ron B Date: Sat, 15 Aug 2020 20:51:33 +0300 Subject: [PATCH 187/434] Move spinnerFrequencyModulate set to ApplySkin --- osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs index 273a9fda84..5bf87ba16b 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs @@ -172,6 +172,10 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables { positionBindable.BindValueChanged(pos => Position = pos.NewValue); positionBindable.BindTo(HitObject.PositionBindable); + } + + protected override void ApplySkin(ISkinSource skin, bool allowFallback) + { spinnerFrequencyModulate = skin.GetConfig(OsuSkinConfiguration.SpinnerFrequencyModulate)?.Value ?? true; } From 40445d0005fe33943baf6350e8e2b35869e08643 Mon Sep 17 00:00:00 2001 From: Ron B Date: Sat, 15 Aug 2020 21:07:44 +0300 Subject: [PATCH 188/434] replicate osu-stable behaviour for spinningSample frequency --- osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs index 5bf87ba16b..dfe10eeaab 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs @@ -104,6 +104,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables { Volume = { Value = 0 }, Looping = true, + Frequency = { Value = 1.0f } }); } } @@ -228,8 +229,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables if (HandleUserInput) RotationTracker.Tracking = !Result.HasResult && (OsuActionInputManager?.PressedActions.Any(x => x == OsuAction.LeftButton || x == OsuAction.RightButton) ?? false); - if (spinningSample != null) - spinningSample.Frequency.Value = spinnerFrequencyModulate ? 0.5f + Progress : 0.5f; + if (spinningSample != null && spinnerFrequencyModulate) + spinningSample.Frequency.Value = 0.5f + Progress; } protected override void UpdateAfterChildren() From a1079bac3234f53f39e894dbd888321e21561907 Mon Sep 17 00:00:00 2001 From: Ron B Date: Sat, 15 Aug 2020 21:19:47 +0300 Subject: [PATCH 189/434] Move frequency values into consts --- osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs index dfe10eeaab..c44553a1c5 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs @@ -85,6 +85,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables } private SkinnableSound spinningSample; + private const float SPINNING_SAMPLE_INITAL_FREQUENCY = 1.0f; + private const float SPINNING_SAMPLE_MODULATED_BASE_FREQUENCY = 0.5f; protected override void LoadSamples() { @@ -104,7 +106,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables { Volume = { Value = 0 }, Looping = true, - Frequency = { Value = 1.0f } + Frequency = { Value = SPINNING_SAMPLE_INITAL_FREQUENCY } }); } } @@ -230,7 +232,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables RotationTracker.Tracking = !Result.HasResult && (OsuActionInputManager?.PressedActions.Any(x => x == OsuAction.LeftButton || x == OsuAction.RightButton) ?? false); if (spinningSample != null && spinnerFrequencyModulate) - spinningSample.Frequency.Value = 0.5f + Progress; + spinningSample.Frequency.Value = SPINNING_SAMPLE_MODULATED_BASE_FREQUENCY + Progress; } protected override void UpdateAfterChildren() From 390e87273065aef35335d3d1e617dc62c9ea90eb Mon Sep 17 00:00:00 2001 From: Ron B Date: Sat, 15 Aug 2020 21:34:17 +0300 Subject: [PATCH 190/434] Fix acoording to review --- osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs index c44553a1c5..a4636050bb 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs @@ -85,7 +85,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables } private SkinnableSound spinningSample; - private const float SPINNING_SAMPLE_INITAL_FREQUENCY = 1.0f; + private const float SPINNING_SAMPLE_INITIAL_FREQUENCY = 1.0f; private const float SPINNING_SAMPLE_MODULATED_BASE_FREQUENCY = 0.5f; protected override void LoadSamples() @@ -106,7 +106,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables { Volume = { Value = 0 }, Looping = true, - Frequency = { Value = SPINNING_SAMPLE_INITAL_FREQUENCY } + Frequency = { Value = SPINNING_SAMPLE_INITIAL_FREQUENCY } }); } } @@ -171,7 +171,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables } [BackgroundDependencyLoader] - private void load(OsuColour colours, ISkinSource skin) + private void load(OsuColour colours) { positionBindable.BindValueChanged(pos => Position = pos.NewValue); positionBindable.BindTo(HitObject.PositionBindable); @@ -179,6 +179,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables protected override void ApplySkin(ISkinSource skin, bool allowFallback) { + base.ApplySkin(skin, allowFallback); spinnerFrequencyModulate = skin.GetConfig(OsuSkinConfiguration.SpinnerFrequencyModulate)?.Value ?? true; } From 5f35b3ebb98821e2f8870964302e9c60dab84d8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 15 Aug 2020 20:44:02 +0200 Subject: [PATCH 191/434] Fix constant casing --- .../Objects/Drawables/DrawableSpinner.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs index a4636050bb..a57bb466c7 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs @@ -85,8 +85,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables } private SkinnableSound spinningSample; - private const float SPINNING_SAMPLE_INITIAL_FREQUENCY = 1.0f; - private const float SPINNING_SAMPLE_MODULATED_BASE_FREQUENCY = 0.5f; + private const float spinning_sample_initial_frequency = 1.0f; + private const float spinning_sample_modulated_base_frequency = 0.5f; protected override void LoadSamples() { @@ -106,7 +106,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables { Volume = { Value = 0 }, Looping = true, - Frequency = { Value = SPINNING_SAMPLE_INITIAL_FREQUENCY } + Frequency = { Value = spinning_sample_initial_frequency } }); } } @@ -233,7 +233,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables RotationTracker.Tracking = !Result.HasResult && (OsuActionInputManager?.PressedActions.Any(x => x == OsuAction.LeftButton || x == OsuAction.RightButton) ?? false); if (spinningSample != null && spinnerFrequencyModulate) - spinningSample.Frequency.Value = SPINNING_SAMPLE_MODULATED_BASE_FREQUENCY + Progress; + spinningSample.Frequency.Value = spinning_sample_modulated_base_frequency + Progress; } protected override void UpdateAfterChildren() From 3d6d22f70fbdc37b960d3cbc1bd90f78ba0fcb6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sun, 16 Aug 2020 12:39:41 +0200 Subject: [PATCH 192/434] Adjust README.md to read better --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index dc3ee63844..d3e9ca5121 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,9 @@ [![CodeFactor](https://www.codefactor.io/repository/github/ppy/osu/badge)](https://www.codefactor.io/repository/github/ppy/osu) [![dev chat](https://discordapp.com/api/guilds/188630481301012481/widget.png?style=shield)](https://discord.gg/ppy) -Rhythm is just a *click* away. The future of [osu!](https://osu.ppy.sh) and the beginning of an open era! Commonly known by the codename *osu!lazer*. Pew pew. +A free-to-win rhythm game. Rhythm is just a *click* away! + +The future of [osu!](https://osu.ppy.sh) and the beginning of an open era! Commonly known by the codename *osu!lazer*. Pew pew. ## Status From 6c44513115ec085bcdc181b3dd04a369130b6e51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sun, 16 Aug 2020 12:53:31 +0200 Subject: [PATCH 193/434] Update .csproj descriptions to match --- osu.Desktop/osu.Desktop.csproj | 2 +- osu.Desktop/osu.nuspec | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/osu.Desktop/osu.Desktop.csproj b/osu.Desktop/osu.Desktop.csproj index 7a99c70999..62e8f7c518 100644 --- a/osu.Desktop/osu.Desktop.csproj +++ b/osu.Desktop/osu.Desktop.csproj @@ -3,7 +3,7 @@ netcoreapp3.1 WinExe true - click the circles. to the beat. + A free-to-win rhythm game. Rhythm is just a *click* away! osu! osu!lazer osu!lazer diff --git a/osu.Desktop/osu.nuspec b/osu.Desktop/osu.nuspec index a919d54f38..2fc6009183 100644 --- a/osu.Desktop/osu.nuspec +++ b/osu.Desktop/osu.nuspec @@ -9,8 +9,7 @@ https://osu.ppy.sh/ https://puu.sh/tYyXZ/9a01a5d1b0.ico false - click the circles. to the beat. - click the circles. + A free-to-win rhythm game. Rhythm is just a *click* away! testing Copyright (c) 2020 ppy Pty Ltd en-AU From a6708c4286d3973c8ed68be43176228da1137237 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 16 Aug 2020 23:04:49 +0900 Subject: [PATCH 194/434] Rename resolved variable in MainMenu --- osu.Game/Screens/Menu/MainMenu.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/osu.Game/Screens/Menu/MainMenu.cs b/osu.Game/Screens/Menu/MainMenu.cs index 470e8ca9a6..fac9e9eb49 100644 --- a/osu.Game/Screens/Menu/MainMenu.cs +++ b/osu.Game/Screens/Menu/MainMenu.cs @@ -46,7 +46,7 @@ namespace osu.Game.Screens.Menu private GameHost host { get; set; } [Resolved] - private MusicController music { get; set; } + private MusicController musicController { get; set; } [Resolved(canBeNull: true)] private LoginOverlay login { get; set; } @@ -176,12 +176,12 @@ namespace osu.Game.Screens.Menu var metadata = Beatmap.Value.Metadata; - if (last is IntroScreen && music.TrackLoaded) + if (last is IntroScreen && musicController.TrackLoaded) { - if (!music.CurrentTrack.IsRunning) + if (!musicController.CurrentTrack.IsRunning) { - music.CurrentTrack.Seek(metadata.PreviewTime != -1 ? metadata.PreviewTime : 0.4f * music.CurrentTrack.Length); - music.CurrentTrack.Start(); + musicController.CurrentTrack.Seek(metadata.PreviewTime != -1 ? metadata.PreviewTime : 0.4f * musicController.CurrentTrack.Length); + musicController.CurrentTrack.Start(); } } @@ -256,7 +256,7 @@ namespace osu.Game.Screens.Menu // we may have consumed our preloaded instance, so let's make another. preloadSongSelect(); - music.EnsurePlayingSomething(); + musicController.EnsurePlayingSomething(); } public override bool OnExiting(IScreen next) From 5d433c0b055d3c284b1737df65856f5e118a817f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 16 Aug 2020 23:11:29 +0900 Subject: [PATCH 195/434] Fix a couple of new Resharper inspections --- osu.Game/Screens/Menu/ButtonSystem.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Menu/ButtonSystem.cs b/osu.Game/Screens/Menu/ButtonSystem.cs index 30e5e9702e..5ba7a8ddc3 100644 --- a/osu.Game/Screens/Menu/ButtonSystem.cs +++ b/osu.Game/Screens/Menu/ButtonSystem.cs @@ -324,10 +324,9 @@ namespace osu.Game.Screens.Menu bool impact = logo.Scale.X > 0.6f; - if (lastState == ButtonSystemState.Initial) - logo.ScaleTo(0.5f, 200, Easing.In); + logo.ScaleTo(0.5f, 200, Easing.In); - logoTrackingContainer.StartTracking(logo, lastState == ButtonSystemState.EnteringMode ? 0 : 200, Easing.In); + logoTrackingContainer.StartTracking(logo, 200, Easing.In); logoDelayedAction?.Cancel(); logoDelayedAction = Scheduler.AddDelayed(() => From 948c3cfbf1fe65a5974b13f555e84f2fd3566db1 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 17 Aug 2020 14:56:05 +0900 Subject: [PATCH 196/434] Improve visibility of toolbar tooltips against bright backgrounds --- osu.Game/Overlays/Toolbar/Toolbar.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Toolbar/Toolbar.cs b/osu.Game/Overlays/Toolbar/Toolbar.cs index 5bdd86c671..beac6adc59 100644 --- a/osu.Game/Overlays/Toolbar/Toolbar.cs +++ b/osu.Game/Overlays/Toolbar/Toolbar.cs @@ -118,9 +118,9 @@ namespace osu.Game.Overlays.Toolbar RelativeSizeAxes = Axes.X, Anchor = Anchor.BottomLeft, Alpha = 0, - Height = 90, + Height = 100, Colour = ColourInfo.GradientVertical( - OsuColour.Gray(0.1f).Opacity(0.5f), OsuColour.Gray(0.1f).Opacity(0)), + OsuColour.Gray(0).Opacity(0.9f), OsuColour.Gray(0).Opacity(0)), }, }; } From d9debef1568a393f0da721759d09206ffe5c3701 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 17 Aug 2020 15:38:16 +0900 Subject: [PATCH 197/434] Add explicit LoadTrack method --- .../TestSceneGameplayClockContainer.cs | 4 +++- .../Gameplay/TestSceneStoryboardSamples.cs | 5 ++-- .../Visual/Gameplay/TestSceneSkipOverlay.cs | 3 ++- osu.Game/Beatmaps/IWorkingBeatmap.cs | 2 +- osu.Game/Beatmaps/WorkingBeatmap.cs | 23 ++++++++++++++++++- osu.Game/Overlays/MusicController.cs | 2 +- osu.Game/Screens/Edit/EditorClock.cs | 2 +- osu.Game/Screens/Menu/IntroScreen.cs | 2 +- .../Screens/Play/GameplayClockContainer.cs | 4 ++-- osu.Game/Screens/Play/Player.cs | 2 +- 10 files changed, 37 insertions(+), 12 deletions(-) diff --git a/osu.Game.Tests/Gameplay/TestSceneGameplayClockContainer.cs b/osu.Game.Tests/Gameplay/TestSceneGameplayClockContainer.cs index bb60ae73db..dc9f540907 100644 --- a/osu.Game.Tests/Gameplay/TestSceneGameplayClockContainer.cs +++ b/osu.Game.Tests/Gameplay/TestSceneGameplayClockContainer.cs @@ -22,7 +22,9 @@ namespace osu.Game.Tests.Gameplay AddStep("create container", () => { var working = CreateWorkingBeatmap(new OsuRuleset().RulesetInfo); - Add(gcc = new GameplayClockContainer(working.GetTrack(), working, Array.Empty(), 0)); + working.LoadTrack(); + + Add(gcc = new GameplayClockContainer(working, Array.Empty(), 0)); }); AddStep("start track", () => gcc.Start()); diff --git a/osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs b/osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs index 360e7eccdc..6f788a070e 100644 --- a/osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs +++ b/osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs @@ -60,8 +60,9 @@ namespace osu.Game.Tests.Gameplay AddStep("create container", () => { var working = CreateWorkingBeatmap(new OsuRuleset().RulesetInfo); + working.LoadTrack(); - Add(gameplayContainer = new GameplayClockContainer(working.GetTrack(), working, Array.Empty(), 0)); + Add(gameplayContainer = new GameplayClockContainer(working, Array.Empty(), 0)); gameplayContainer.Add(sample = new DrawableStoryboardSample(new StoryboardSampleInfo(string.Empty, 0, 1)) { @@ -105,7 +106,7 @@ namespace osu.Game.Tests.Gameplay Beatmap.Value = new TestCustomSkinWorkingBeatmap(new OsuRuleset().RulesetInfo, Audio); SelectedMods.Value = new[] { testedMod }; - Add(gameplayContainer = new GameplayClockContainer(MusicController.CurrentTrack, Beatmap.Value, SelectedMods.Value, 0)); + Add(gameplayContainer = new GameplayClockContainer(Beatmap.Value, SelectedMods.Value, 0)); gameplayContainer.Add(sample = new TestDrawableStoryboardSample(new StoryboardSampleInfo("test-sample", 1, 1)) { diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSkipOverlay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSkipOverlay.cs index 58fd760fc3..c7e5e2a7ec 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSkipOverlay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSkipOverlay.cs @@ -33,8 +33,9 @@ namespace osu.Game.Tests.Visual.Gameplay increment = skip_time; var working = CreateWorkingBeatmap(CreateBeatmap(new OsuRuleset().RulesetInfo)); + working.LoadTrack(); - Child = gameplayClockContainer = new GameplayClockContainer(working.GetTrack(), working, Array.Empty(), 0) + Child = gameplayClockContainer = new GameplayClockContainer(working, Array.Empty(), 0) { RelativeSizeAxes = Axes.Both, Children = new Drawable[] diff --git a/osu.Game/Beatmaps/IWorkingBeatmap.cs b/osu.Game/Beatmaps/IWorkingBeatmap.cs index e020625b99..88d73fd7c4 100644 --- a/osu.Game/Beatmaps/IWorkingBeatmap.cs +++ b/osu.Game/Beatmaps/IWorkingBeatmap.cs @@ -58,6 +58,6 @@ namespace osu.Game.Beatmaps /// /// Retrieves the which this provides. /// - Track GetTrack(); + Track LoadTrack(); } } diff --git a/osu.Game/Beatmaps/WorkingBeatmap.cs b/osu.Game/Beatmaps/WorkingBeatmap.cs index bec2679103..b4046a4e95 100644 --- a/osu.Game/Beatmaps/WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/WorkingBeatmap.cs @@ -250,8 +250,29 @@ namespace osu.Game.Beatmaps protected abstract Texture GetBackground(); private readonly RecyclableLazy background; + private Track loadedTrack; + + /// + /// Load a new audio track instance for this beatmap. + /// + /// A fresh track instance, which will also be available via . [NotNull] - public Track GetTrack() => GetBeatmapTrack() ?? GetVirtualTrack(1000); + public Track LoadTrack() => loadedTrack = GetBeatmapTrack() ?? GetVirtualTrack(1000); + + /// + /// Get the loaded audio track instance. must have first been called. + /// This generally happens via MusicController when changing the global beatmap. + /// + public Track Track + { + get + { + if (loadedTrack == null) + throw new InvalidOperationException($"Cannot access {nameof(Track)} without first calling {nameof(LoadTrack)}."); + + return loadedTrack; + } + } protected abstract Track GetBeatmapTrack(); diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index c18b564b4f..8bbae33811 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -319,7 +319,7 @@ namespace osu.Game.Overlays { var lastTrack = CurrentTrack; - var newTrack = new DrawableTrack(current.GetTrack()); + var newTrack = new DrawableTrack(current.LoadTrack()); newTrack.Completed += () => onTrackCompleted(current); CurrentTrack = newTrack; diff --git a/osu.Game/Screens/Edit/EditorClock.cs b/osu.Game/Screens/Edit/EditorClock.cs index d0e265adb0..634a6f7e25 100644 --- a/osu.Game/Screens/Edit/EditorClock.cs +++ b/osu.Game/Screens/Edit/EditorClock.cs @@ -26,7 +26,7 @@ namespace osu.Game.Screens.Edit private readonly DecoupleableInterpolatingFramedClock underlyingClock; public EditorClock(WorkingBeatmap beatmap, BindableBeatDivisor beatDivisor) - : this(beatmap.Beatmap.ControlPointInfo, beatmap.GetTrack().Length, beatDivisor) + : this(beatmap.Beatmap.ControlPointInfo, beatmap.Track.Length, beatDivisor) { } diff --git a/osu.Game/Screens/Menu/IntroScreen.cs b/osu.Game/Screens/Menu/IntroScreen.cs index 389629445c..3e4320ae44 100644 --- a/osu.Game/Screens/Menu/IntroScreen.cs +++ b/osu.Game/Screens/Menu/IntroScreen.cs @@ -115,7 +115,7 @@ namespace osu.Game.Screens.Menu if (setInfo != null) { initialBeatmap = beatmaps.GetWorkingBeatmap(setInfo.Beatmaps[0]); - UsingThemedIntro = !initialBeatmap.GetTrack().IsDummyDevice; + UsingThemedIntro = !initialBeatmap.LoadTrack().IsDummyDevice; } return UsingThemedIntro; diff --git a/osu.Game/Screens/Play/GameplayClockContainer.cs b/osu.Game/Screens/Play/GameplayClockContainer.cs index f0bbcf957a..50a7331e4f 100644 --- a/osu.Game/Screens/Play/GameplayClockContainer.cs +++ b/osu.Game/Screens/Play/GameplayClockContainer.cs @@ -62,12 +62,12 @@ namespace osu.Game.Screens.Play private readonly FramedOffsetClock platformOffsetClock; - public GameplayClockContainer([NotNull] ITrack track, WorkingBeatmap beatmap, IReadOnlyList mods, double gameplayStartTime) + public GameplayClockContainer(WorkingBeatmap beatmap, IReadOnlyList mods, double gameplayStartTime) { this.beatmap = beatmap; this.mods = mods; this.gameplayStartTime = gameplayStartTime; - this.track = track; + track = beatmap.Track; firstHitObjectTime = beatmap.Beatmap.HitObjects.First().StartTime; diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index e92164de7c..ccdd4ea8a4 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -179,7 +179,7 @@ namespace osu.Game.Screens.Play if (!ScoreProcessor.Mode.Disabled) config.BindWith(OsuSetting.ScoreDisplayMode, ScoreProcessor.Mode); - InternalChild = GameplayClockContainer = new GameplayClockContainer(musicController.CurrentTrack, Beatmap.Value, Mods.Value, DrawableRuleset.GameplayStartTime); + InternalChild = GameplayClockContainer = new GameplayClockContainer(Beatmap.Value, Mods.Value, DrawableRuleset.GameplayStartTime); AddInternal(gameplayBeatmap = new GameplayBeatmap(playableBeatmap)); AddInternal(screenSuspension = new ScreenSuspensionHandler(GameplayClockContainer)); From 93a8bc3d5aa330cb6ef008ac8858ae4d005434aa Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 17 Aug 2020 22:36:03 +0900 Subject: [PATCH 198/434] Remove local reset method in GameplayClockContainer --- .../TestSceneGameplayClockContainer.cs | 4 +-- .../Gameplay/TestSceneStoryboardSamples.cs | 4 +-- .../Visual/Gameplay/TestSceneSkipOverlay.cs | 4 +-- .../Screens/Play/GameplayClockContainer.cs | 31 +++++++------------ osu.Game/Screens/Play/Player.cs | 2 +- osu.Game/Tests/Visual/PlayerTestScene.cs | 2 ++ 6 files changed, 19 insertions(+), 28 deletions(-) diff --git a/osu.Game.Tests/Gameplay/TestSceneGameplayClockContainer.cs b/osu.Game.Tests/Gameplay/TestSceneGameplayClockContainer.cs index dc9f540907..891537c4ad 100644 --- a/osu.Game.Tests/Gameplay/TestSceneGameplayClockContainer.cs +++ b/osu.Game.Tests/Gameplay/TestSceneGameplayClockContainer.cs @@ -1,10 +1,8 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System; using NUnit.Framework; using osu.Framework.Testing; -using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Osu; using osu.Game.Screens.Play; using osu.Game.Tests.Visual; @@ -24,7 +22,7 @@ namespace osu.Game.Tests.Gameplay var working = CreateWorkingBeatmap(new OsuRuleset().RulesetInfo); working.LoadTrack(); - Add(gcc = new GameplayClockContainer(working, Array.Empty(), 0)); + Add(gcc = new GameplayClockContainer(working, 0)); }); AddStep("start track", () => gcc.Start()); diff --git a/osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs b/osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs index 6f788a070e..a690eb3b59 100644 --- a/osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs +++ b/osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs @@ -62,7 +62,7 @@ namespace osu.Game.Tests.Gameplay var working = CreateWorkingBeatmap(new OsuRuleset().RulesetInfo); working.LoadTrack(); - Add(gameplayContainer = new GameplayClockContainer(working, Array.Empty(), 0)); + Add(gameplayContainer = new GameplayClockContainer(working, 0)); gameplayContainer.Add(sample = new DrawableStoryboardSample(new StoryboardSampleInfo(string.Empty, 0, 1)) { @@ -106,7 +106,7 @@ namespace osu.Game.Tests.Gameplay Beatmap.Value = new TestCustomSkinWorkingBeatmap(new OsuRuleset().RulesetInfo, Audio); SelectedMods.Value = new[] { testedMod }; - Add(gameplayContainer = new GameplayClockContainer(Beatmap.Value, SelectedMods.Value, 0)); + Add(gameplayContainer = new GameplayClockContainer(Beatmap.Value, 0)); gameplayContainer.Add(sample = new TestDrawableStoryboardSample(new StoryboardSampleInfo("test-sample", 1, 1)) { diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSkipOverlay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSkipOverlay.cs index c7e5e2a7ec..841722a8f1 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSkipOverlay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSkipOverlay.cs @@ -1,11 +1,9 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System; using NUnit.Framework; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Osu; using osu.Game.Screens.Play; using osuTK; @@ -35,7 +33,7 @@ namespace osu.Game.Tests.Visual.Gameplay var working = CreateWorkingBeatmap(CreateBeatmap(new OsuRuleset().RulesetInfo)); working.LoadTrack(); - Child = gameplayClockContainer = new GameplayClockContainer(working, Array.Empty(), 0) + Child = gameplayClockContainer = new GameplayClockContainer(working, 0) { RelativeSizeAxes = Axes.Both, Children = new Drawable[] diff --git a/osu.Game/Screens/Play/GameplayClockContainer.cs b/osu.Game/Screens/Play/GameplayClockContainer.cs index 50a7331e4f..7a9cb3dddd 100644 --- a/osu.Game/Screens/Play/GameplayClockContainer.cs +++ b/osu.Game/Screens/Play/GameplayClockContainer.cs @@ -2,7 +2,6 @@ // See the LICENCE file in the repository root for full licence text. using System; -using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Threading.Tasks; @@ -16,7 +15,6 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Timing; using osu.Game.Beatmaps; using osu.Game.Configuration; -using osu.Game.Rulesets.Mods; namespace osu.Game.Screens.Play { @@ -26,7 +24,6 @@ namespace osu.Game.Screens.Play public class GameplayClockContainer : Container { private readonly WorkingBeatmap beatmap; - private readonly IReadOnlyList mods; [NotNull] private ITrack track; @@ -62,10 +59,9 @@ namespace osu.Game.Screens.Play private readonly FramedOffsetClock platformOffsetClock; - public GameplayClockContainer(WorkingBeatmap beatmap, IReadOnlyList mods, double gameplayStartTime) + public GameplayClockContainer(WorkingBeatmap beatmap, double gameplayStartTime) { this.beatmap = beatmap; - this.mods = mods; this.gameplayStartTime = gameplayStartTime; track = beatmap.Track; @@ -122,13 +118,10 @@ namespace osu.Game.Screens.Play public void Restart() { - // The Reset() call below causes speed adjustments to be reset in an async context, leading to deadlocks. - // The deadlock can be prevented by resetting the track synchronously before entering the async context. - track.ResetSpeedAdjustments(); - Task.Run(() => { - track.Reset(); + track.Seek(0); + track.Stop(); Schedule(() => { @@ -216,14 +209,13 @@ namespace osu.Game.Screens.Play private void updateRate() { - speedAdjustmentsApplied = true; - track.ResetSpeedAdjustments(); + if (speedAdjustmentsApplied) + return; track.AddAdjustment(AdjustableProperty.Frequency, pauseFreqAdjust); track.AddAdjustment(AdjustableProperty.Tempo, UserPlaybackRate); - foreach (var mod in mods.OfType()) - mod.ApplyToTrack(track); + speedAdjustmentsApplied = true; } protected override void Dispose(bool isDisposing) @@ -234,11 +226,12 @@ namespace osu.Game.Screens.Play private void removeSourceClockAdjustments() { - if (speedAdjustmentsApplied) - { - track.ResetSpeedAdjustments(); - speedAdjustmentsApplied = false; - } + if (!speedAdjustmentsApplied) return; + + track.RemoveAdjustment(AdjustableProperty.Frequency, pauseFreqAdjust); + track.RemoveAdjustment(AdjustableProperty.Tempo, UserPlaybackRate); + + speedAdjustmentsApplied = false; } private class HardwareCorrectionOffsetClock : FramedOffsetClock diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index ccdd4ea8a4..cc70995b26 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -179,7 +179,7 @@ namespace osu.Game.Screens.Play if (!ScoreProcessor.Mode.Disabled) config.BindWith(OsuSetting.ScoreDisplayMode, ScoreProcessor.Mode); - InternalChild = GameplayClockContainer = new GameplayClockContainer(Beatmap.Value, Mods.Value, DrawableRuleset.GameplayStartTime); + InternalChild = GameplayClockContainer = new GameplayClockContainer(Beatmap.Value, DrawableRuleset.GameplayStartTime); AddInternal(gameplayBeatmap = new GameplayBeatmap(playableBeatmap)); AddInternal(screenSuspension = new ScreenSuspensionHandler(GameplayClockContainer)); diff --git a/osu.Game/Tests/Visual/PlayerTestScene.cs b/osu.Game/Tests/Visual/PlayerTestScene.cs index 2c46e7f6d3..7d06c99133 100644 --- a/osu.Game/Tests/Visual/PlayerTestScene.cs +++ b/osu.Game/Tests/Visual/PlayerTestScene.cs @@ -29,6 +29,8 @@ namespace osu.Game.Tests.Visual { Dependencies.Cache(LocalConfig = new OsuConfigManager(LocalStorage)); LocalConfig.GetBindable(OsuSetting.DimLevel).Value = 1.0; + + MusicController.AllowRateAdjustments = true; } [SetUpSteps] From 548ccc1a50694b931924d7cc0b8d0e49803f3037 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 18 Aug 2020 00:29:00 +0900 Subject: [PATCH 199/434] Initial implementation of hold note freezing --- .../Objects/Drawables/DrawableHoldNote.cs | 36 ++++++++++++++----- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs index 0c5289efe1..39b1771643 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs @@ -1,6 +1,7 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Game.Rulesets.Mania.Objects.Drawables.Pieces; @@ -11,6 +12,7 @@ using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.UI.Scrolling; using osu.Game.Skinning; +using osuTK; namespace osu.Game.Rulesets.Mania.Objects.Drawables { @@ -32,6 +34,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables private readonly Container tailContainer; private readonly Container tickContainer; + private readonly Container bodyPieceContainer; private readonly Drawable bodyPiece; /// @@ -44,19 +47,25 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables /// public bool HasBroken { get; private set; } + /// + /// Whether the hold note has been released potentially without having caused a break. + /// + private bool hasReleased; + public DrawableHoldNote(HoldNote hitObject) : base(hitObject) { RelativeSizeAxes = Axes.X; - AddRangeInternal(new[] + AddRangeInternal(new Drawable[] { - bodyPiece = new SkinnableDrawable(new ManiaSkinComponent(ManiaSkinComponents.HoldNoteBody, hitObject.Column), _ => new DefaultBodyPiece + bodyPieceContainer = new Container { - RelativeSizeAxes = Axes.Both - }) - { - RelativeSizeAxes = Axes.X + RelativeSizeAxes = Axes.X, + Child = bodyPiece = new SkinnableDrawable(new ManiaSkinComponent(ManiaSkinComponents.HoldNoteBody, hitObject.Column), _ => new DefaultBodyPiece + { + RelativeSizeAxes = Axes.Both + }) }, tickContainer = new Container { RelativeSizeAxes = Axes.Both }, headContainer = new Container { RelativeSizeAxes = Axes.Both }, @@ -127,7 +136,8 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables { base.OnDirectionChanged(e); - bodyPiece.Anchor = bodyPiece.Origin = e.NewValue == ScrollingDirection.Up ? Anchor.TopLeft : Anchor.BottomLeft; + bodyPieceContainer.Anchor = bodyPieceContainer.Origin = e.NewValue == ScrollingDirection.Up ? Anchor.TopLeft : Anchor.BottomLeft; + bodyPieceContainer.Anchor = bodyPieceContainer.Origin = e.NewValue == ScrollingDirection.Up ? Anchor.BottomLeft : Anchor.TopLeft; } public override void PlaySamples() @@ -140,8 +150,14 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables base.Update(); // Make the body piece not lie under the head note - bodyPiece.Y = (Direction.Value == ScrollingDirection.Up ? 1 : -1) * Head.Height / 2; - bodyPiece.Height = DrawHeight - Head.Height / 2 + Tail.Height / 2; + bodyPieceContainer.Y = (Direction.Value == ScrollingDirection.Up ? 1 : -1) * Head.Height / 2; + bodyPieceContainer.Height = DrawHeight - Head.Height / 2 + Tail.Height / 2; + + if (Head.IsHit && !hasReleased) + { + float heightDecrease = (float)(Math.Max(0, Time.Current - HitObject.StartTime) / HitObject.Duration); + bodyPiece.Height = MathHelper.Clamp(1 - heightDecrease, 0, 1); + } } protected override void UpdateStateTransforms(ArmedState state) @@ -206,6 +222,8 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables // If the key has been released too early, the user should not receive full score for the release if (!Tail.IsHit) HasBroken = true; + + hasReleased = true; } private void endHold() From b969bc03e0d48b91c1c17eec744b948945dec70a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 18 Aug 2020 00:47:32 +0900 Subject: [PATCH 200/434] Add loading spinner while editor screen loads --- osu.Game/Screens/Edit/EditorScreenWithTimeline.cs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/EditorScreenWithTimeline.cs b/osu.Game/Screens/Edit/EditorScreenWithTimeline.cs index e9ff0b5598..67442aa55e 100644 --- a/osu.Game/Screens/Edit/EditorScreenWithTimeline.cs +++ b/osu.Game/Screens/Edit/EditorScreenWithTimeline.cs @@ -7,6 +7,7 @@ using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; +using osu.Game.Graphics.UserInterface; using osu.Game.Screens.Edit.Compose.Components; using osu.Game.Screens.Edit.Compose.Components.Timeline; using osuTK.Graphics; @@ -32,6 +33,8 @@ namespace osu.Game.Screens.Edit Container mainContent; + LoadingSpinner spinner; + Children = new Drawable[] { mainContent = new Container @@ -44,6 +47,10 @@ namespace osu.Game.Screens.Edit Top = vertical_margins + timeline_height, Bottom = vertical_margins }, + Child = spinner = new LoadingSpinner(true) + { + State = { Value = Visibility.Visible }, + }, }, new Container { @@ -87,9 +94,10 @@ namespace osu.Game.Screens.Edit } }, }; - LoadComponentAsync(CreateMainContent(), content => { + spinner.State.Value = Visibility.Hidden; + mainContent.Add(content); content.FadeInFromZero(300, Easing.OutQuint); From 583760100a633b037c5194cf8b2e0cae3820af40 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 18 Aug 2020 01:40:55 +0900 Subject: [PATCH 201/434] Implement mania invert mod --- .../Mods/TestSceneManiaModInvert.cs | 21 ++++++ osu.Game.Rulesets.Mania/ManiaRuleset.cs | 1 + .../Mods/ManiaModInvert.cs | 68 +++++++++++++++++++ osu.Game.Rulesets.Mania/Objects/HoldNote.cs | 6 +- osu.Game/Beatmaps/WorkingBeatmap.cs | 9 +++ .../Mods/IApplicableAfterBeatmapConversion.cs | 19 ++++++ 6 files changed, 121 insertions(+), 3 deletions(-) create mode 100644 osu.Game.Rulesets.Mania.Tests/Mods/TestSceneManiaModInvert.cs create mode 100644 osu.Game.Rulesets.Mania/Mods/ManiaModInvert.cs create mode 100644 osu.Game/Rulesets/Mods/IApplicableAfterBeatmapConversion.cs diff --git a/osu.Game.Rulesets.Mania.Tests/Mods/TestSceneManiaModInvert.cs b/osu.Game.Rulesets.Mania.Tests/Mods/TestSceneManiaModInvert.cs new file mode 100644 index 0000000000..f2cc254e38 --- /dev/null +++ b/osu.Game.Rulesets.Mania.Tests/Mods/TestSceneManiaModInvert.cs @@ -0,0 +1,21 @@ +// 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.Rulesets.Mania.Mods; +using osu.Game.Tests.Visual; + +namespace osu.Game.Rulesets.Mania.Tests.Mods +{ + public class TestSceneManiaModInvert : ModTestScene + { + protected override Ruleset CreatePlayerRuleset() => new ManiaRuleset(); + + [Test] + public void TestInversion() => CreateModTest(new ModTestData + { + Mod = new ManiaModInvert(), + PassCondition = () => Player.ScoreProcessor.JudgedHits >= 2 + }); + } +} diff --git a/osu.Game.Rulesets.Mania/ManiaRuleset.cs b/osu.Game.Rulesets.Mania/ManiaRuleset.cs index 68dce8b139..2795868c97 100644 --- a/osu.Game.Rulesets.Mania/ManiaRuleset.cs +++ b/osu.Game.Rulesets.Mania/ManiaRuleset.cs @@ -220,6 +220,7 @@ namespace osu.Game.Rulesets.Mania new ManiaModDualStages(), new ManiaModMirror(), new ManiaModDifficultyAdjust(), + new ManiaModInvert(), }; case ModType.Automation: diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModInvert.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModInvert.cs new file mode 100644 index 0000000000..2fb7a75141 --- /dev/null +++ b/osu.Game.Rulesets.Mania/Mods/ManiaModInvert.cs @@ -0,0 +1,68 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Collections.Generic; +using System.Linq; +using osu.Game.Audio; +using osu.Game.Beatmaps; +using osu.Game.Rulesets.Mania.Beatmaps; +using osu.Game.Rulesets.Mania.Objects; +using osu.Game.Rulesets.Mods; + +namespace osu.Game.Rulesets.Mania.Mods +{ + public class ManiaModInvert : Mod, IApplicableAfterBeatmapConversion + { + public override string Name => "Invert"; + + public override string Acronym => "IN"; + public override double ScoreMultiplier => 1; + + public override string Description => "Hold the keys. To the beat."; + + public override ModType Type => ModType.Conversion; + + public void ApplyToBeatmap(IBeatmap beatmap) + { + var maniaBeatmap = (ManiaBeatmap)beatmap; + + var newObjects = new List(); + + foreach (var column in maniaBeatmap.HitObjects.GroupBy(h => h.Column)) + { + var newColumnObjects = new List(); + + var locations = column.OfType().Select(n => (startTime: n.StartTime, samples: n.Samples)) + .Concat(column.OfType().SelectMany(h => new[] + { + (startTime: h.StartTime, samples: h.GetNodeSamples(0)), + (startTime: h.EndTime, samples: h.GetNodeSamples(1)) + })) + .OrderBy(h => h.startTime).ToList(); + + for (int i = 0; i < locations.Count - 1; i += 2) + { + newColumnObjects.Add(new HoldNote + { + Column = column.Key, + StartTime = locations[i].startTime, + Duration = locations[i + 1].startTime - locations[i].startTime, + Samples = locations[i].samples, + NodeSamples = new List> + { + locations[i].samples, + locations[i + 1].samples + } + }); + } + + newObjects.AddRange(newColumnObjects); + } + + maniaBeatmap.HitObjects = newObjects.OrderBy(h => h.StartTime).ToList(); + + // No breaks + maniaBeatmap.Breaks.Clear(); + } + } +} diff --git a/osu.Game.Rulesets.Mania/Objects/HoldNote.cs b/osu.Game.Rulesets.Mania/Objects/HoldNote.cs index a100c9a58e..6cc7ff92d3 100644 --- a/osu.Game.Rulesets.Mania/Objects/HoldNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/HoldNote.cs @@ -102,14 +102,14 @@ namespace osu.Game.Rulesets.Mania.Objects { StartTime = StartTime, Column = Column, - Samples = getNodeSamples(0), + Samples = GetNodeSamples(0), }); AddNested(Tail = new TailNote { StartTime = EndTime, Column = Column, - Samples = getNodeSamples((NodeSamples?.Count - 1) ?? 1), + Samples = GetNodeSamples((NodeSamples?.Count - 1) ?? 1), }); } @@ -134,7 +134,7 @@ namespace osu.Game.Rulesets.Mania.Objects protected override HitWindows CreateHitWindows() => HitWindows.Empty; - private IList getNodeSamples(int nodeIndex) => + public IList GetNodeSamples(int nodeIndex) => nodeIndex < NodeSamples?.Count ? NodeSamples[nodeIndex] : Samples; } } diff --git a/osu.Game/Beatmaps/WorkingBeatmap.cs b/osu.Game/Beatmaps/WorkingBeatmap.cs index ac399e37c4..b4bcf285b9 100644 --- a/osu.Game/Beatmaps/WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/WorkingBeatmap.cs @@ -109,6 +109,15 @@ namespace osu.Game.Beatmaps // Convert IBeatmap converted = converter.Convert(); + // Apply conversion mods to the result + foreach (var mod in mods.OfType()) + { + if (cancellationSource.IsCancellationRequested) + throw new BeatmapLoadTimeoutException(BeatmapInfo); + + mod.ApplyToBeatmap(converted); + } + // Apply difficulty mods if (mods.Any(m => m is IApplicableToDifficulty)) { diff --git a/osu.Game/Rulesets/Mods/IApplicableAfterBeatmapConversion.cs b/osu.Game/Rulesets/Mods/IApplicableAfterBeatmapConversion.cs new file mode 100644 index 0000000000..d45311675d --- /dev/null +++ b/osu.Game/Rulesets/Mods/IApplicableAfterBeatmapConversion.cs @@ -0,0 +1,19 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Game.Beatmaps; + +namespace osu.Game.Rulesets.Mods +{ + /// + /// Interface for a that applies changes to the generated by the . + /// + public interface IApplicableAfterBeatmapConversion : IApplicableMod + { + /// + /// Applies this to the after conversion has taken place. + /// + /// The converted . + void ApplyToBeatmap(IBeatmap beatmap); + } +} From 9e8192e31d0237043743792ddb3cd75cddd86804 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 17 Aug 2020 17:14:51 +0000 Subject: [PATCH 202/434] Bump Microsoft.CodeAnalysis.BannedApiAnalyzers from 3.0.0 to 3.3.0 Bumps [Microsoft.CodeAnalysis.BannedApiAnalyzers](https://github.com/dotnet/roslyn-analyzers) from 3.0.0 to 3.3.0. - [Release notes](https://github.com/dotnet/roslyn-analyzers/releases) - [Changelog](https://github.com/dotnet/roslyn-analyzers/blob/master/PostReleaseActivities.md) - [Commits](https://github.com/dotnet/roslyn-analyzers/compare/v3.0.0...v3.3.0) Signed-off-by: dependabot-preview[bot] --- Directory.Build.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Build.props b/Directory.Build.props index 2cd40c8675..2d3478f256 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -16,7 +16,7 @@ - + From e4303d79436113148cbe505655e5e0f151a6cbc8 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 18 Aug 2020 12:35:23 +0900 Subject: [PATCH 203/434] Fix PlayerLoader test failures due to too many steps --- osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs b/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs index e698d31176..4fac7bb45f 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs @@ -71,7 +71,6 @@ namespace osu.Game.Tests.Visual.Gameplay { AddStep("load dummy beatmap", () => ResetPlayer(false, () => SelectedMods.Value = new[] { new OsuModNightcore() })); AddUntilStep("wait for current", () => loader.IsCurrentScreen()); - AddAssert("mod rate applied", () => Beatmap.Value.Track.Rate != 1); AddStep("exit loader", () => loader.Exit()); AddUntilStep("wait for not current", () => !loader.IsCurrentScreen()); AddAssert("player did not load", () => player == null); From 083bcde3cf260147304b110d4a0956285690e4ba Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 18 Aug 2020 13:01:35 +0900 Subject: [PATCH 204/434] Fix beatmap transfer not working --- osu.Game/Beatmaps/WorkingBeatmap.cs | 7 +++++++ osu.Game/Overlays/MusicController.cs | 13 ++++++++++--- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/osu.Game/Beatmaps/WorkingBeatmap.cs b/osu.Game/Beatmaps/WorkingBeatmap.cs index b4046a4e95..c9a60d7948 100644 --- a/osu.Game/Beatmaps/WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/WorkingBeatmap.cs @@ -259,6 +259,13 @@ namespace osu.Game.Beatmaps [NotNull] public Track LoadTrack() => loadedTrack = GetBeatmapTrack() ?? GetVirtualTrack(1000); + /// + /// Transfer a valid audio track into this working beatmap. Used as an optimisation to avoid reload / track swap + /// across difficulties in the same beatmap set. + /// + /// The track to transfer. + public void TransferTrack([NotNull] Track track) => loadedTrack = track ?? throw new ArgumentNullException(nameof(track)); + /// /// Get the loaded audio track instance. must have first been called. /// This generally happens via MusicController when changing the global beatmap. diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index 8bbae33811..c1116ff651 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -282,10 +282,10 @@ namespace osu.Game.Overlays { TrackChangeDirection direction = TrackChangeDirection.None; + bool audioEquals = beatmap.NewValue?.BeatmapInfo?.AudioEquals(current?.BeatmapInfo) ?? false; + if (current != null) { - bool audioEquals = beatmap.NewValue?.BeatmapInfo?.AudioEquals(current.BeatmapInfo) ?? false; - if (audioEquals) direction = TrackChangeDirection.None; else if (queuedDirection.HasValue) @@ -305,8 +305,15 @@ namespace osu.Game.Overlays current = beatmap.NewValue; - if (CurrentTrack.IsDummyDevice || !beatmap.OldValue.BeatmapInfo.AudioEquals(current?.BeatmapInfo)) + if (!audioEquals || CurrentTrack.IsDummyDevice) + { changeTrack(); + } + else + { + // transfer still valid track to new working beatmap + current.TransferTrack(beatmap.OldValue.Track); + } TrackChanged?.Invoke(current, direction); From 848f3bbf51b0b44d48f7424d4a48fc0bc3e369a7 Mon Sep 17 00:00:00 2001 From: Joehu Date: Mon, 17 Aug 2020 21:09:55 -0700 Subject: [PATCH 205/434] Show tooltip of leaderboard score rank when 1000 or higher --- .../Online/Leaderboards/LeaderboardScore.cs | 30 ++++++++++++------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/osu.Game/Online/Leaderboards/LeaderboardScore.cs b/osu.Game/Online/Leaderboards/LeaderboardScore.cs index b60d71cfe7..662c02df0e 100644 --- a/osu.Game/Online/Leaderboards/LeaderboardScore.cs +++ b/osu.Game/Online/Leaderboards/LeaderboardScore.cs @@ -82,20 +82,10 @@ namespace osu.Game.Online.Leaderboards Children = new Drawable[] { - new Container + new RankLabel(rank) { RelativeSizeAxes = Axes.Y, Width = rank_width, - Children = new[] - { - new OsuSpriteText - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Font = OsuFont.GetFont(size: 20, italics: true), - Text = rank == null ? "-" : rank.Value.ToMetric(decimals: rank < 100000 ? 1 : 0), - }, - }, }, content = new Container { @@ -356,6 +346,24 @@ namespace osu.Game.Online.Leaderboards } } + private class RankLabel : Container, IHasTooltip + { + public RankLabel(int? rank) + { + TooltipText = rank == null || rank < 1000 ? null : $"{rank}"; + + Child = new OsuSpriteText + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Font = OsuFont.GetFont(size: 20, italics: true), + Text = rank == null ? "-" : rank.Value.ToMetric(decimals: rank < 100000 ? 1 : 0), + }; + } + + public string TooltipText { get; } + } + public class LeaderboardScoreStatistic { public IconUsage Icon; From e0383f61008db34bbcc3317e9ad12ff94f56ec7b Mon Sep 17 00:00:00 2001 From: Joehu Date: Mon, 17 Aug 2020 22:07:04 -0700 Subject: [PATCH 206/434] Change format of rank tooltip --- osu.Game/Online/Leaderboards/LeaderboardScore.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Online/Leaderboards/LeaderboardScore.cs b/osu.Game/Online/Leaderboards/LeaderboardScore.cs index 662c02df0e..a4c20d1b9e 100644 --- a/osu.Game/Online/Leaderboards/LeaderboardScore.cs +++ b/osu.Game/Online/Leaderboards/LeaderboardScore.cs @@ -350,7 +350,7 @@ namespace osu.Game.Online.Leaderboards { public RankLabel(int? rank) { - TooltipText = rank == null || rank < 1000 ? null : $"{rank}"; + TooltipText = rank == null || rank < 1000 ? null : $"#{rank:N0}"; Child = new OsuSpriteText { From 4d6b52a0d6a9a9d8e3d847c8d610d978b80d7802 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Mon, 17 Aug 2020 23:08:51 -0700 Subject: [PATCH 207/434] Simply condition Co-authored-by: Dean Herbert --- osu.Game/Online/Leaderboards/LeaderboardScore.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Online/Leaderboards/LeaderboardScore.cs b/osu.Game/Online/Leaderboards/LeaderboardScore.cs index a4c20d1b9e..87b283f6b5 100644 --- a/osu.Game/Online/Leaderboards/LeaderboardScore.cs +++ b/osu.Game/Online/Leaderboards/LeaderboardScore.cs @@ -350,7 +350,8 @@ namespace osu.Game.Online.Leaderboards { public RankLabel(int? rank) { - TooltipText = rank == null || rank < 1000 ? null : $"#{rank:N0}"; + if (rank >= 1000) + TooltipText = $"#{rank:N0}"; Child = new OsuSpriteText { From f4f642fbcf5b5109727ca17776cb91fd53b49630 Mon Sep 17 00:00:00 2001 From: Joehu Date: Mon, 17 Aug 2020 23:21:44 -0700 Subject: [PATCH 208/434] Add ability to skip cutscene with forward mouse button --- osu.Game/Input/Bindings/GlobalActionContainer.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Input/Bindings/GlobalActionContainer.cs b/osu.Game/Input/Bindings/GlobalActionContainer.cs index 6ae420b162..45b07581ec 100644 --- a/osu.Game/Input/Bindings/GlobalActionContainer.cs +++ b/osu.Game/Input/Bindings/GlobalActionContainer.cs @@ -53,6 +53,7 @@ namespace osu.Game.Input.Bindings public IEnumerable InGameKeyBindings => new[] { new KeyBinding(InputKey.Space, GlobalAction.SkipCutscene), + new KeyBinding(InputKey.ExtraMouseButton2, GlobalAction.SkipCutscene), new KeyBinding(InputKey.Tilde, GlobalAction.QuickRetry), new KeyBinding(new[] { InputKey.Control, InputKey.Tilde }, GlobalAction.QuickExit), new KeyBinding(new[] { InputKey.Control, InputKey.Plus }, GlobalAction.IncreaseScrollSpeed), From e1ed8554a1805dcbe055518962a0cfd3fb7674a5 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 18 Aug 2020 17:23:11 +0900 Subject: [PATCH 209/434] Use yinyang icon --- osu.Game.Rulesets.Mania/Mods/ManiaModInvert.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModInvert.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModInvert.cs index 2fb7a75141..69f883cd3c 100644 --- a/osu.Game.Rulesets.Mania/Mods/ManiaModInvert.cs +++ b/osu.Game.Rulesets.Mania/Mods/ManiaModInvert.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; +using osu.Framework.Graphics.Sprites; using osu.Game.Audio; using osu.Game.Beatmaps; using osu.Game.Rulesets.Mania.Beatmaps; @@ -20,6 +21,8 @@ namespace osu.Game.Rulesets.Mania.Mods public override string Description => "Hold the keys. To the beat."; + public override IconUsage? Icon => FontAwesome.Solid.YinYang; + public override ModType Type => ModType.Conversion; public void ApplyToBeatmap(IBeatmap beatmap) From 628be66653e94ea692a717096a8b234f7f4b0a87 Mon Sep 17 00:00:00 2001 From: Jihoon Yang Date: Tue, 18 Aug 2020 01:24:56 -0700 Subject: [PATCH 210/434] Updated calculation of mania scroll speed --- .../Configuration/ManiaRulesetConfigManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Mania/Configuration/ManiaRulesetConfigManager.cs b/osu.Game.Rulesets.Mania/Configuration/ManiaRulesetConfigManager.cs index 7e84f17809..df453cf562 100644 --- a/osu.Game.Rulesets.Mania/Configuration/ManiaRulesetConfigManager.cs +++ b/osu.Game.Rulesets.Mania/Configuration/ManiaRulesetConfigManager.cs @@ -27,7 +27,7 @@ namespace osu.Game.Rulesets.Mania.Configuration public override TrackedSettings CreateTrackedSettings() => new TrackedSettings { new TrackedSetting(ManiaRulesetSetting.ScrollTime, - v => new SettingDescription(v, "Scroll Speed", $"{(int)Math.Round(DrawableManiaRuleset.MAX_TIME_RANGE / v)} ({v}ms)")) + v => new SettingDescription(v, "Scroll Speed", $"{(int)Math.Round(13720.0 / v)} ({v}ms)")) }; } From d157c42340224d340fe632f3da416f7c2bf60a61 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 18 Aug 2020 17:40:44 +0900 Subject: [PATCH 211/434] Increase density by not skipping objects --- osu.Game.Rulesets.Mania/Mods/ManiaModInvert.cs | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModInvert.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModInvert.cs index 69f883cd3c..56f6e389bf 100644 --- a/osu.Game.Rulesets.Mania/Mods/ManiaModInvert.cs +++ b/osu.Game.Rulesets.Mania/Mods/ManiaModInvert.cs @@ -1,6 +1,7 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System; using System.Collections.Generic; using System.Linq; using osu.Framework.Graphics.Sprites; @@ -43,13 +44,22 @@ namespace osu.Game.Rulesets.Mania.Mods })) .OrderBy(h => h.startTime).ToList(); - for (int i = 0; i < locations.Count - 1; i += 2) + for (int i = 0; i < locations.Count - 1; i++) { + // Full duration of the hold note. + double duration = locations[i + 1].startTime - locations[i].startTime; + + // Beat length at the end of the hold note. + double beatLength = beatmap.ControlPointInfo.TimingPointAt(locations[i + 1].startTime).BeatLength; + + // Decrease the duration by at most a 1/4 beat to ensure there's no instantaneous notes. + duration = Math.Max(duration / 2, duration - beatLength / 4); + newColumnObjects.Add(new HoldNote { Column = column.Key, StartTime = locations[i].startTime, - Duration = locations[i + 1].startTime - locations[i].startTime, + Duration = duration, Samples = locations[i].samples, NodeSamples = new List> { From 4ddc04793f5a8c61c9467c25f77fbbf860e34262 Mon Sep 17 00:00:00 2001 From: Jihoon Yang Date: Tue, 18 Aug 2020 01:44:30 -0700 Subject: [PATCH 212/434] Changed MAX_TIME_RANGE instead of the single instance --- .../Configuration/ManiaRulesetConfigManager.cs | 2 +- osu.Game.Rulesets.Mania/UI/DrawableManiaRuleset.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Configuration/ManiaRulesetConfigManager.cs b/osu.Game.Rulesets.Mania/Configuration/ManiaRulesetConfigManager.cs index df453cf562..7e84f17809 100644 --- a/osu.Game.Rulesets.Mania/Configuration/ManiaRulesetConfigManager.cs +++ b/osu.Game.Rulesets.Mania/Configuration/ManiaRulesetConfigManager.cs @@ -27,7 +27,7 @@ namespace osu.Game.Rulesets.Mania.Configuration public override TrackedSettings CreateTrackedSettings() => new TrackedSettings { new TrackedSetting(ManiaRulesetSetting.ScrollTime, - v => new SettingDescription(v, "Scroll Speed", $"{(int)Math.Round(13720.0 / v)} ({v}ms)")) + v => new SettingDescription(v, "Scroll Speed", $"{(int)Math.Round(DrawableManiaRuleset.MAX_TIME_RANGE / v)} ({v}ms)")) }; } diff --git a/osu.Game.Rulesets.Mania/UI/DrawableManiaRuleset.cs b/osu.Game.Rulesets.Mania/UI/DrawableManiaRuleset.cs index 94b5ee9486..5b46550333 100644 --- a/osu.Game.Rulesets.Mania/UI/DrawableManiaRuleset.cs +++ b/osu.Game.Rulesets.Mania/UI/DrawableManiaRuleset.cs @@ -36,7 +36,7 @@ namespace osu.Game.Rulesets.Mania.UI /// /// The maximum time range. This occurs at a of 1. /// - public const double MAX_TIME_RANGE = 6000; + public const double MAX_TIME_RANGE = 13720; protected new ManiaPlayfield Playfield => (ManiaPlayfield)base.Playfield; From 138dc5929e9b40e40fdba96097e831eea386098b Mon Sep 17 00:00:00 2001 From: Jihoon Yang Date: Tue, 18 Aug 2020 01:46:07 -0700 Subject: [PATCH 213/434] Changed MIN_TIME_RANGE as well --- osu.Game.Rulesets.Mania/UI/DrawableManiaRuleset.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Mania/UI/DrawableManiaRuleset.cs b/osu.Game.Rulesets.Mania/UI/DrawableManiaRuleset.cs index 5b46550333..7f5b9a6ee0 100644 --- a/osu.Game.Rulesets.Mania/UI/DrawableManiaRuleset.cs +++ b/osu.Game.Rulesets.Mania/UI/DrawableManiaRuleset.cs @@ -31,7 +31,7 @@ namespace osu.Game.Rulesets.Mania.UI /// /// The minimum time range. This occurs at a of 40. /// - public const double MIN_TIME_RANGE = 150; + public const double MIN_TIME_RANGE = 340; /// /// The maximum time range. This occurs at a of 1. From 385f7cf85d52c0d412f03b8706157ac686fea070 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 18 Aug 2020 17:56:48 +0900 Subject: [PATCH 214/434] Implement mania hold note body recycling --- .../Blueprints/Components/EditBodyPiece.cs | 4 +- .../Objects/Drawables/DrawableHoldNote.cs | 10 +- .../Drawables/Pieces/DefaultBodyPiece.cs | 157 +++++++++++------- .../Objects/Drawables/Pieces/IHoldNoteBody.cs | 16 ++ 4 files changed, 121 insertions(+), 66 deletions(-) create mode 100644 osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/IHoldNoteBody.cs diff --git a/osu.Game.Rulesets.Mania/Edit/Blueprints/Components/EditBodyPiece.cs b/osu.Game.Rulesets.Mania/Edit/Blueprints/Components/EditBodyPiece.cs index efcfe11dad..5fa687298a 100644 --- a/osu.Game.Rulesets.Mania/Edit/Blueprints/Components/EditBodyPiece.cs +++ b/osu.Game.Rulesets.Mania/Edit/Blueprints/Components/EditBodyPiece.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Allocation; +using osu.Framework.Graphics; using osu.Game.Graphics; using osu.Game.Rulesets.Mania.Objects.Drawables.Pieces; @@ -15,7 +16,8 @@ namespace osu.Game.Rulesets.Mania.Edit.Blueprints.Components AccentColour.Value = colours.Yellow; Background.Alpha = 0.5f; - Foreground.Alpha = 0; } + + protected override Drawable CreateForeground() => base.CreateForeground().With(d => d.Alpha = 0); } } diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs index 0c5289efe1..a44f8a8886 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs @@ -32,7 +32,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables private readonly Container tailContainer; private readonly Container tickContainer; - private readonly Drawable bodyPiece; + private readonly SkinnableDrawable bodyPiece; /// /// Time at which the user started holding this hold note. Null if the user is not holding this hold note. @@ -49,7 +49,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables { RelativeSizeAxes = Axes.X; - AddRangeInternal(new[] + AddRangeInternal(new Drawable[] { bodyPiece = new SkinnableDrawable(new ManiaSkinComponent(ManiaSkinComponents.HoldNoteBody, hitObject.Column), _ => new DefaultBodyPiece { @@ -135,6 +135,12 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables // Samples are played by the head/tail notes. } + public override void OnKilled() + { + base.OnKilled(); + (bodyPiece.Drawable as IHoldNoteBody)?.Recycle(); + } + protected override void Update() { base.Update(); diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/DefaultBodyPiece.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/DefaultBodyPiece.cs index bc4a095395..9999983af5 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/DefaultBodyPiece.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/DefaultBodyPiece.cs @@ -19,24 +19,17 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables.Pieces /// /// Represents length-wise portion of a hold note. /// - public class DefaultBodyPiece : CompositeDrawable + public class DefaultBodyPiece : CompositeDrawable, IHoldNoteBody { protected readonly Bindable AccentColour = new Bindable(); - - private readonly LayoutValue subtractionCache = new LayoutValue(Invalidation.DrawSize); - private readonly IBindable isHitting = new Bindable(); + protected readonly IBindable IsHitting = new Bindable(); protected Drawable Background { get; private set; } - protected BufferedContainer Foreground { get; private set; } - - private BufferedContainer subtractionContainer; - private Container subtractionLayer; + private Container foregroundContainer; public DefaultBodyPiece() { Blending = BlendingParameters.Additive; - - AddLayout(subtractionCache); } [BackgroundDependencyLoader(true)] @@ -45,7 +38,54 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables.Pieces InternalChildren = new[] { Background = new Box { RelativeSizeAxes = Axes.Both }, - Foreground = new BufferedContainer + foregroundContainer = new Container { RelativeSizeAxes = Axes.Both } + }; + + if (drawableObject != null) + { + var holdNote = (DrawableHoldNote)drawableObject; + + AccentColour.BindTo(drawableObject.AccentColour); + IsHitting.BindTo(holdNote.IsHitting); + } + + AccentColour.BindValueChanged(onAccentChanged, true); + + Recycle(); + } + + public void Recycle() => foregroundContainer.Child = CreateForeground(); + + protected virtual Drawable CreateForeground() => new ForegroundPiece + { + AccentColour = { BindTarget = AccentColour }, + IsHitting = { BindTarget = IsHitting } + }; + + private void onAccentChanged(ValueChangedEvent accent) => Background.Colour = accent.NewValue.Opacity(0.7f); + + private class ForegroundPiece : CompositeDrawable + { + public readonly Bindable AccentColour = new Bindable(); + public readonly IBindable IsHitting = new Bindable(); + + private readonly LayoutValue subtractionCache = new LayoutValue(Invalidation.DrawSize); + + private BufferedContainer foregroundBuffer; + private BufferedContainer subtractionBuffer; + private Container subtractionLayer; + + public ForegroundPiece() + { + RelativeSizeAxes = Axes.Both; + + AddLayout(subtractionCache); + } + + [BackgroundDependencyLoader] + private void load() + { + InternalChild = foregroundBuffer = new BufferedContainer { Blending = BlendingParameters.Additive, RelativeSizeAxes = Axes.Both, @@ -53,7 +93,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables.Pieces Children = new Drawable[] { new Box { RelativeSizeAxes = Axes.Both }, - subtractionContainer = new BufferedContainer + subtractionBuffer = new BufferedContainer { RelativeSizeAxes = Axes.Both, // This is needed because we're blending with another object @@ -77,60 +117,51 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables.Pieces } } } - } - }; - - if (drawableObject != null) - { - var holdNote = (DrawableHoldNote)drawableObject; - - AccentColour.BindTo(drawableObject.AccentColour); - isHitting.BindTo(holdNote.IsHitting); - } - - AccentColour.BindValueChanged(onAccentChanged, true); - isHitting.BindValueChanged(_ => onAccentChanged(new ValueChangedEvent(AccentColour.Value, AccentColour.Value)), true); - } - - private void onAccentChanged(ValueChangedEvent accent) - { - Foreground.Colour = accent.NewValue.Opacity(0.5f); - Background.Colour = accent.NewValue.Opacity(0.7f); - - const float animation_length = 50; - - Foreground.ClearTransforms(false, nameof(Foreground.Colour)); - - if (isHitting.Value) - { - // wait for the next sync point - double synchronisedOffset = animation_length * 2 - Time.Current % (animation_length * 2); - using (Foreground.BeginDelayedSequence(synchronisedOffset)) - Foreground.FadeColour(accent.NewValue.Lighten(0.2f), animation_length).Then().FadeColour(Foreground.Colour, animation_length).Loop(); - } - - subtractionCache.Invalidate(); - } - - protected override void Update() - { - base.Update(); - - if (!subtractionCache.IsValid) - { - subtractionLayer.Width = 5; - subtractionLayer.Height = Math.Max(0, DrawHeight - DrawWidth); - subtractionLayer.EdgeEffect = new EdgeEffectParameters - { - Colour = Color4.White, - Type = EdgeEffectType.Glow, - Radius = DrawWidth }; - Foreground.ForceRedraw(); - subtractionContainer.ForceRedraw(); + AccentColour.BindValueChanged(onAccentChanged, true); + IsHitting.BindValueChanged(_ => onAccentChanged(new ValueChangedEvent(AccentColour.Value, AccentColour.Value)), true); + } - subtractionCache.Validate(); + private void onAccentChanged(ValueChangedEvent accent) + { + foregroundBuffer.Colour = accent.NewValue.Opacity(0.5f); + + const float animation_length = 50; + + foregroundBuffer.ClearTransforms(false, nameof(foregroundBuffer.Colour)); + + if (IsHitting.Value) + { + // wait for the next sync point + double synchronisedOffset = animation_length * 2 - Time.Current % (animation_length * 2); + using (foregroundBuffer.BeginDelayedSequence(synchronisedOffset)) + foregroundBuffer.FadeColour(accent.NewValue.Lighten(0.2f), animation_length).Then().FadeColour(foregroundBuffer.Colour, animation_length).Loop(); + } + + subtractionCache.Invalidate(); + } + + protected override void Update() + { + base.Update(); + + if (!subtractionCache.IsValid) + { + subtractionLayer.Width = 5; + subtractionLayer.Height = Math.Max(0, DrawHeight - DrawWidth); + subtractionLayer.EdgeEffect = new EdgeEffectParameters + { + Colour = Color4.White, + Type = EdgeEffectType.Glow, + Radius = DrawWidth + }; + + foregroundBuffer.ForceRedraw(); + subtractionBuffer.ForceRedraw(); + + subtractionCache.Validate(); + } } } } diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/IHoldNoteBody.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/IHoldNoteBody.cs new file mode 100644 index 0000000000..ac3792c01d --- /dev/null +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/IHoldNoteBody.cs @@ -0,0 +1,16 @@ +// 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.Rulesets.Mania.Objects.Drawables.Pieces +{ + /// + /// Interface for mania hold note bodies. + /// + public interface IHoldNoteBody + { + /// + /// Recycles the contents of this to free used resources. + /// + void Recycle(); + } +} From da07354f050d15f94a6291d9296cd1286885143c Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 18 Aug 2020 19:51:16 +0900 Subject: [PATCH 215/434] Fix some judgements potentially giving wrong score --- osu.Game.Rulesets.Mania/Judgements/HoldNoteTickJudgement.cs | 2 +- osu.Game.Rulesets.Osu/Objects/SpinnerBonusTick.cs | 2 +- osu.Game.Rulesets.Osu/Objects/SpinnerTick.cs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Judgements/HoldNoteTickJudgement.cs b/osu.Game.Rulesets.Mania/Judgements/HoldNoteTickJudgement.cs index 294aab1e4e..28e5d2cc1b 100644 --- a/osu.Game.Rulesets.Mania/Judgements/HoldNoteTickJudgement.cs +++ b/osu.Game.Rulesets.Mania/Judgements/HoldNoteTickJudgement.cs @@ -7,7 +7,7 @@ namespace osu.Game.Rulesets.Mania.Judgements { public class HoldNoteTickJudgement : ManiaJudgement { - protected override int NumericResultFor(HitResult result) => 20; + protected override int NumericResultFor(HitResult result) => result == MaxResult ? 20 : 0; protected override double HealthIncreaseFor(HitResult result) { diff --git a/osu.Game.Rulesets.Osu/Objects/SpinnerBonusTick.cs b/osu.Game.Rulesets.Osu/Objects/SpinnerBonusTick.cs index 9c4b6f774f..0b1232b8db 100644 --- a/osu.Game.Rulesets.Osu/Objects/SpinnerBonusTick.cs +++ b/osu.Game.Rulesets.Osu/Objects/SpinnerBonusTick.cs @@ -20,7 +20,7 @@ namespace osu.Game.Rulesets.Osu.Objects public class OsuSpinnerBonusTickJudgement : OsuSpinnerTickJudgement { - protected override int NumericResultFor(HitResult result) => SCORE_PER_TICK; + protected override int NumericResultFor(HitResult result) => result == MaxResult ? SCORE_PER_TICK : 0; protected override double HealthIncreaseFor(HitResult result) => base.HealthIncreaseFor(result) * 2; } diff --git a/osu.Game.Rulesets.Osu/Objects/SpinnerTick.cs b/osu.Game.Rulesets.Osu/Objects/SpinnerTick.cs index de3ae27e55..f54e7a9a15 100644 --- a/osu.Game.Rulesets.Osu/Objects/SpinnerTick.cs +++ b/osu.Game.Rulesets.Osu/Objects/SpinnerTick.cs @@ -19,7 +19,7 @@ namespace osu.Game.Rulesets.Osu.Objects { public override bool AffectsCombo => false; - protected override int NumericResultFor(HitResult result) => SCORE_PER_TICK; + protected override int NumericResultFor(HitResult result) => result == MaxResult ? SCORE_PER_TICK : 0; protected override double HealthIncreaseFor(HitResult result) => result == MaxResult ? 0.6 * base.HealthIncreaseFor(result) : 0; } From a4ad0bd1744a14207e0f39b5c363e24ace00005c Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 18 Aug 2020 19:51:26 +0900 Subject: [PATCH 216/434] Ensure 0 score from miss judgements, add test --- .../Gameplay/TestSceneScoreProcessor.cs | 41 +++++++++++++++++++ osu.Game/Rulesets/Scoring/ScoreProcessor.cs | 12 ++++-- 2 files changed, 49 insertions(+), 4 deletions(-) create mode 100644 osu.Game.Tests/Gameplay/TestSceneScoreProcessor.cs diff --git a/osu.Game.Tests/Gameplay/TestSceneScoreProcessor.cs b/osu.Game.Tests/Gameplay/TestSceneScoreProcessor.cs new file mode 100644 index 0000000000..b0baf0385e --- /dev/null +++ b/osu.Game.Tests/Gameplay/TestSceneScoreProcessor.cs @@ -0,0 +1,41 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using NUnit.Framework; +using osu.Framework.Testing; +using osu.Game.Beatmaps; +using osu.Game.Rulesets.Judgements; +using osu.Game.Rulesets.Objects; +using osu.Game.Rulesets.Scoring; +using osu.Game.Tests.Visual; + +namespace osu.Game.Tests.Gameplay +{ + [HeadlessTest] + public class TestSceneScoreProcessor : OsuTestScene + { + [Test] + public void TestNoScoreIncreaseFromMiss() + { + var beatmap = new Beatmap { HitObjects = { new TestHitObject() } }; + + var scoreProcessor = new ScoreProcessor(); + scoreProcessor.ApplyBeatmap(beatmap); + + // Apply a miss judgement + scoreProcessor.ApplyResult(new JudgementResult(new TestHitObject(), new TestJudgement()) { Type = HitResult.Miss }); + + Assert.That(scoreProcessor.TotalScore.Value, Is.EqualTo(0.0)); + } + + private class TestHitObject : HitObject + { + public override Judgement CreateJudgement() => new TestJudgement(); + } + + private class TestJudgement : Judgement + { + protected override int NumericResultFor(HitResult result) => 100; + } + } +} diff --git a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs index f1cdfd93c8..eac47aa089 100644 --- a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs +++ b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs @@ -133,17 +133,19 @@ namespace osu.Game.Rulesets.Scoring } } + double scoreIncrease = result.Type == HitResult.Miss ? 0 : result.Judgement.NumericResultFor(result); + if (result.Judgement.IsBonus) { if (result.IsHit) - bonusScore += result.Judgement.NumericResultFor(result); + bonusScore += scoreIncrease; } else { if (result.HasResult) scoreResultCounts[result.Type] = scoreResultCounts.GetOrDefault(result.Type) + 1; - baseScore += result.Judgement.NumericResultFor(result); + baseScore += scoreIncrease; rollingMaxBaseScore += result.Judgement.MaxNumericResult; } @@ -169,17 +171,19 @@ namespace osu.Game.Rulesets.Scoring if (result.FailedAtJudgement) return; + double scoreIncrease = result.Type == HitResult.Miss ? 0 : result.Judgement.NumericResultFor(result); + if (result.Judgement.IsBonus) { if (result.IsHit) - bonusScore -= result.Judgement.NumericResultFor(result); + bonusScore -= scoreIncrease; } else { if (result.HasResult) scoreResultCounts[result.Type] = scoreResultCounts.GetOrDefault(result.Type) - 1; - baseScore -= result.Judgement.NumericResultFor(result); + baseScore -= scoreIncrease; rollingMaxBaseScore -= result.Judgement.MaxNumericResult; } From 6aa31dffdb2b194eb0c593c8094e3d37f96f614e Mon Sep 17 00:00:00 2001 From: Lucas A Date: Tue, 18 Aug 2020 15:25:51 +0200 Subject: [PATCH 217/434] Fix toolbar not respecting current overlay activation mode. --- .../Visual/Menus/TestSceneToolbar.cs | 27 +++++++++++++++++-- osu.Game/Overlays/Toolbar/Toolbar.cs | 21 +++++++++------ 2 files changed, 38 insertions(+), 10 deletions(-) diff --git a/osu.Game.Tests/Visual/Menus/TestSceneToolbar.cs b/osu.Game.Tests/Visual/Menus/TestSceneToolbar.cs index b4985cad9f..5170058700 100644 --- a/osu.Game.Tests/Visual/Menus/TestSceneToolbar.cs +++ b/osu.Game.Tests/Visual/Menus/TestSceneToolbar.cs @@ -4,8 +4,10 @@ using System.Linq; using NUnit.Framework; using osu.Framework.Allocation; +using osu.Framework.Bindables; using osu.Framework.Graphics.Containers; using osu.Framework.Testing; +using osu.Game.Overlays; using osu.Game.Overlays.Toolbar; using osu.Game.Rulesets; using osuTK.Input; @@ -15,7 +17,7 @@ namespace osu.Game.Tests.Visual.Menus [TestFixture] public class TestSceneToolbar : OsuManualInputManagerTestScene { - private Toolbar toolbar; + private TestToolbar toolbar; [Resolved] private RulesetStore rulesets { get; set; } @@ -23,7 +25,7 @@ namespace osu.Game.Tests.Visual.Menus [SetUp] public void SetUp() => Schedule(() => { - Child = toolbar = new Toolbar { State = { Value = Visibility.Visible } }; + Child = toolbar = new TestToolbar { State = { Value = Visibility.Visible } }; }); [Test] @@ -72,5 +74,26 @@ namespace osu.Game.Tests.Visual.Menus AddUntilStep("ruleset switched", () => rulesetSelector.Current.Value.Equals(expected)); } } + + [TestCase(OverlayActivation.All)] + [TestCase(OverlayActivation.Disabled)] + public void TestRespectsOverlayActivation(OverlayActivation mode) + { + AddStep($"set activation mode to {mode}", () => toolbar.OverlayActivationMode.Value = mode); + AddStep("hide toolbar", () => toolbar.Hide()); + AddStep("try to show toolbar", () => toolbar.Show()); + + if (mode == OverlayActivation.Disabled) + AddUntilStep("toolbar still hidden", () => toolbar.Visibility == Visibility.Hidden); + else + AddAssert("toolbar is visible", () => toolbar.Visibility == Visibility.Visible); + } + + public class TestToolbar : Toolbar + { + public new Bindable OverlayActivationMode => base.OverlayActivationMode; + + public Visibility Visibility => State.Value; + } } } diff --git a/osu.Game/Overlays/Toolbar/Toolbar.cs b/osu.Game/Overlays/Toolbar/Toolbar.cs index beac6adc59..3bf9e85428 100644 --- a/osu.Game/Overlays/Toolbar/Toolbar.cs +++ b/osu.Game/Overlays/Toolbar/Toolbar.cs @@ -28,7 +28,7 @@ namespace osu.Game.Overlays.Toolbar private const double transition_time = 500; - private readonly Bindable overlayActivationMode = new Bindable(OverlayActivation.All); + protected readonly Bindable OverlayActivationMode = new Bindable(OverlayActivation.All); // Toolbar components like RulesetSelector should receive keyboard input events even when the toolbar is hidden. public override bool PropagateNonPositionalInputSubTree => true; @@ -89,14 +89,8 @@ namespace osu.Game.Overlays.Toolbar // 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 => - { - if (overlayActivationMode.Value == OverlayActivation.Disabled) - Hide(); - }; - if (osuGame != null) - overlayActivationMode.BindTo(osuGame.OverlayActivationMode); + OverlayActivationMode.BindTo(osuGame.OverlayActivationMode); } public class ToolbarBackground : Container @@ -137,6 +131,17 @@ namespace osu.Game.Overlays.Toolbar } } + protected override void UpdateState(ValueChangedEvent state) + { + if (state.NewValue == Visibility.Visible && OverlayActivationMode.Value == OverlayActivation.Disabled) + { + State.Value = Visibility.Hidden; + return; + } + + base.UpdateState(state); + } + protected override void PopIn() { this.MoveToY(0, transition_time, Easing.OutQuint); From 988ad378a7c7ccfe0e20c11b334e47a1cc368082 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 19 Aug 2020 00:05:05 +0900 Subject: [PATCH 218/434] Fix body size + freeze head piece --- .../Objects/Drawables/DrawableHoldNote.cs | 48 ++++++++++++------- .../Objects/Drawables/DrawableHoldNoteHead.cs | 8 ++++ 2 files changed, 40 insertions(+), 16 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs index 39b1771643..008cc3519e 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs @@ -34,8 +34,15 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables private readonly Container tailContainer; private readonly Container tickContainer; - private readonly Container bodyPieceContainer; - private readonly Drawable bodyPiece; + /// + /// Contains the maximum size/position of the body prior to any offset or size adjustments. + /// + private readonly Container bodyContainer; + + /// + /// Contains the offset size/position of the body such that the body extends half-way between the head and tail pieces. + /// + private readonly Container bodyOffsetContainer; /// /// Time at which the user started holding this hold note. Null if the user is not holding this hold note. @@ -57,18 +64,27 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables { RelativeSizeAxes = Axes.X; - AddRangeInternal(new Drawable[] + AddRangeInternal(new[] { - bodyPieceContainer = new Container + bodyContainer = new Container { - RelativeSizeAxes = Axes.X, - Child = bodyPiece = new SkinnableDrawable(new ManiaSkinComponent(ManiaSkinComponents.HoldNoteBody, hitObject.Column), _ => new DefaultBodyPiece + RelativeSizeAxes = Axes.Both, + Children = new Drawable[] { - RelativeSizeAxes = Axes.Both - }) + bodyOffsetContainer = new Container + { + RelativeSizeAxes = Axes.X, + Child = new SkinnableDrawable(new ManiaSkinComponent(ManiaSkinComponents.HoldNoteBody, hitObject.Column), _ => new DefaultBodyPiece + { + RelativeSizeAxes = Axes.Both + }) + }, + // The head needs to move along with changes in the size of the body. + headContainer = new Container { RelativeSizeAxes = Axes.Both } + } }, tickContainer = new Container { RelativeSizeAxes = Axes.Both }, - headContainer = new Container { RelativeSizeAxes = Axes.Both }, + headContainer.CreateProxy(), tailContainer = new Container { RelativeSizeAxes = Axes.Both }, }); } @@ -136,8 +152,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables { base.OnDirectionChanged(e); - bodyPieceContainer.Anchor = bodyPieceContainer.Origin = e.NewValue == ScrollingDirection.Up ? Anchor.TopLeft : Anchor.BottomLeft; - bodyPieceContainer.Anchor = bodyPieceContainer.Origin = e.NewValue == ScrollingDirection.Up ? Anchor.BottomLeft : Anchor.TopLeft; + bodyOffsetContainer.Anchor = bodyOffsetContainer.Origin = e.NewValue == ScrollingDirection.Up ? Anchor.TopLeft : Anchor.BottomLeft; } public override void PlaySamples() @@ -149,15 +164,16 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables { base.Update(); - // Make the body piece not lie under the head note - bodyPieceContainer.Y = (Direction.Value == ScrollingDirection.Up ? 1 : -1) * Head.Height / 2; - bodyPieceContainer.Height = DrawHeight - Head.Height / 2 + Tail.Height / 2; - + // Decrease the size of the body while the hold note is held and the head has been hit. if (Head.IsHit && !hasReleased) { float heightDecrease = (float)(Math.Max(0, Time.Current - HitObject.StartTime) / HitObject.Duration); - bodyPiece.Height = MathHelper.Clamp(1 - heightDecrease, 0, 1); + bodyContainer.Height = MathHelper.Clamp(1 - heightDecrease, 0, 1); } + + // Offset the body to extend half-way under the head and tail. + bodyOffsetContainer.Y = (Direction.Value == ScrollingDirection.Up ? 1 : -1) * Head.Height / 2; + bodyOffsetContainer.Height = bodyContainer.DrawHeight - Head.Height / 2 + Tail.Height / 2; } protected override void UpdateStateTransforms(ArmedState state) diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteHead.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteHead.cs index a73fe259e4..cd56b81e10 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteHead.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteHead.cs @@ -1,6 +1,8 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using osu.Game.Rulesets.Objects.Drawables; + namespace osu.Game.Rulesets.Mania.Objects.Drawables { /// @@ -17,6 +19,12 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables public void UpdateResult() => base.UpdateResult(true); + protected override void UpdateStateTransforms(ArmedState state) + { + // This hitobject should never expire, so this is just a safe maximum. + LifetimeEnd = LifetimeStart + 30000; + } + public override bool OnPressed(ManiaAction action) => false; // Handled by the hold note public override void OnReleased(ManiaAction action) From 99315a4aa74c434bb4938357d75b65543150ff59 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 19 Aug 2020 00:05:36 +0900 Subject: [PATCH 219/434] Fix incorrect anchors for up-scroll --- .../Objects/Drawables/DrawableHoldNote.cs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs index 008cc3519e..e120fab21b 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs @@ -152,7 +152,18 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables { base.OnDirectionChanged(e); - bodyOffsetContainer.Anchor = bodyOffsetContainer.Origin = e.NewValue == ScrollingDirection.Up ? Anchor.TopLeft : Anchor.BottomLeft; + // The body container is anchored from the position of the tail, since its height is changed when the hold note is being hit. + // The body offset container is anchored from the position of the head (inverse of the above). + if (e.NewValue == ScrollingDirection.Up) + { + bodyContainer.Anchor = bodyContainer.Origin = Anchor.BottomLeft; + bodyOffsetContainer.Anchor = bodyOffsetContainer.Origin = Anchor.TopLeft; + } + else + { + bodyContainer.Anchor = bodyContainer.Origin = Anchor.TopLeft; + bodyOffsetContainer.Anchor = bodyOffsetContainer.Origin = Anchor.BottomLeft; + } } public override void PlaySamples() From af8f727721cc227082ffc78d20b3b39dbf73fb3e Mon Sep 17 00:00:00 2001 From: Jihoon Yang Date: Tue, 18 Aug 2020 08:28:53 -0700 Subject: [PATCH 220/434] Disable LegacyHitExplosion for hold notes --- osu.Game.Rulesets.Mania/Skinning/LegacyHitExplosion.cs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Skinning/LegacyHitExplosion.cs b/osu.Game.Rulesets.Mania/Skinning/LegacyHitExplosion.cs index 12747924de..e80d968f37 100644 --- a/osu.Game.Rulesets.Mania/Skinning/LegacyHitExplosion.cs +++ b/osu.Game.Rulesets.Mania/Skinning/LegacyHitExplosion.cs @@ -7,6 +7,7 @@ using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Animations; using osu.Game.Rulesets.Judgements; +using osu.Game.Rulesets.Mania.Judgements; using osu.Game.Rulesets.Mania.UI; using osu.Game.Rulesets.UI.Scrolling; using osu.Game.Skinning; @@ -66,10 +67,13 @@ namespace osu.Game.Rulesets.Mania.Skinning public void Animate(JudgementResult result) { - (explosion as IFramedAnimation)?.GotoFrame(0); + if (!(result.Judgement is HoldNoteTickJudgement)) + { + (explosion as IFramedAnimation)?.GotoFrame(0); - explosion?.FadeInFromZero(80) - .Then().FadeOut(120); + explosion?.FadeInFromZero(80) + .Then().FadeOut(120); + } } } } From 474f2452226cf79b271813824c5bad9add33a177 Mon Sep 17 00:00:00 2001 From: Jihoon Yang Date: Tue, 18 Aug 2020 08:40:29 -0700 Subject: [PATCH 221/434] Replace nested loop with early return --- .../Skinning/LegacyHitExplosion.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Skinning/LegacyHitExplosion.cs b/osu.Game.Rulesets.Mania/Skinning/LegacyHitExplosion.cs index e80d968f37..41f3090afd 100644 --- a/osu.Game.Rulesets.Mania/Skinning/LegacyHitExplosion.cs +++ b/osu.Game.Rulesets.Mania/Skinning/LegacyHitExplosion.cs @@ -67,13 +67,13 @@ namespace osu.Game.Rulesets.Mania.Skinning public void Animate(JudgementResult result) { - if (!(result.Judgement is HoldNoteTickJudgement)) - { - (explosion as IFramedAnimation)?.GotoFrame(0); + if (result.Judgement is HoldNoteTickJudgement) + return; - explosion?.FadeInFromZero(80) - .Then().FadeOut(120); - } + (explosion as IFramedAnimation)?.GotoFrame(0); + + explosion?.FadeInFromZero(80) + .Then().FadeOut(120); } } } From 4d4d9b7356e1963b6d397bee2951a4b67a5bea25 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 19 Aug 2020 01:37:24 +0900 Subject: [PATCH 222/434] Add rewinding support --- .../Objects/Drawables/DrawableHoldNote.cs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs index e120fab21b..0e1e700702 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs @@ -57,7 +57,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables /// /// Whether the hold note has been released potentially without having caused a break. /// - private bool hasReleased; + private double? releaseTime; public DrawableHoldNote(HoldNote hitObject) : base(hitObject) @@ -175,8 +175,11 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables { base.Update(); - // Decrease the size of the body while the hold note is held and the head has been hit. - if (Head.IsHit && !hasReleased) + if (Time.Current < releaseTime) + releaseTime = null; + + // Decrease the size of the body while the hold note is held and the head has been hit. This stops at the very first release point. + if (Head.IsHit && releaseTime == null) { float heightDecrease = (float)(Math.Max(0, Time.Current - HitObject.StartTime) / HitObject.Duration); bodyContainer.Height = MathHelper.Clamp(1 - heightDecrease, 0, 1); @@ -250,7 +253,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables if (!Tail.IsHit) HasBroken = true; - hasReleased = true; + releaseTime = Time.Current; } private void endHold() From 1d9d885d27fbd22f1118944a99fc2889d3617ca3 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 19 Aug 2020 01:40:26 +0900 Subject: [PATCH 223/434] Mask the tail as the body gets shorter --- .../Objects/Drawables/DrawableHoldNote.cs | 38 +++++++++++++++++-- 1 file changed, 34 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs index 0e1e700702..d2412df7c3 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs @@ -44,6 +44,11 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables /// private readonly Container bodyOffsetContainer; + /// + /// Contains the masking area for the tail, which is resized along with . + /// + private readonly Container tailMaskingContainer; + /// /// Time at which the user started holding this hold note. Null if the user is not holding this hold note. /// @@ -84,8 +89,16 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables } }, tickContainer = new Container { RelativeSizeAxes = Axes.Both }, - headContainer.CreateProxy(), - tailContainer = new Container { RelativeSizeAxes = Axes.Both }, + tailMaskingContainer = new Container + { + RelativeSizeAxes = Axes.X, + Masking = true, + Child = tailContainer = new Container + { + RelativeSizeAxes = Axes.X, + } + }, + headContainer.CreateProxy() }); } @@ -154,15 +167,22 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables // The body container is anchored from the position of the tail, since its height is changed when the hold note is being hit. // The body offset container is anchored from the position of the head (inverse of the above). + // The tail containers are both anchored from the position of the tail. if (e.NewValue == ScrollingDirection.Up) { bodyContainer.Anchor = bodyContainer.Origin = Anchor.BottomLeft; bodyOffsetContainer.Anchor = bodyOffsetContainer.Origin = Anchor.TopLeft; + + tailMaskingContainer.Anchor = tailMaskingContainer.Origin = Anchor.BottomLeft; + tailContainer.Anchor = tailContainer.Origin = Anchor.BottomLeft; } else { bodyContainer.Anchor = bodyContainer.Origin = Anchor.TopLeft; bodyOffsetContainer.Anchor = bodyOffsetContainer.Origin = Anchor.BottomLeft; + + tailMaskingContainer.Anchor = tailMaskingContainer.Origin = Anchor.TopLeft; + tailContainer.Anchor = tailContainer.Origin = Anchor.TopLeft; } } @@ -185,9 +205,19 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables bodyContainer.Height = MathHelper.Clamp(1 - heightDecrease, 0, 1); } - // Offset the body to extend half-way under the head and tail. + // Re-position the body half-way up the head, and extend the height until it's half-way under the tail. bodyOffsetContainer.Y = (Direction.Value == ScrollingDirection.Up ? 1 : -1) * Head.Height / 2; - bodyOffsetContainer.Height = bodyContainer.DrawHeight - Head.Height / 2 + Tail.Height / 2; + bodyOffsetContainer.Height = bodyContainer.DrawHeight + Tail.Height / 2 - Head.Height / 2; + + // The tail is positioned to be "outside" the hold note, so re-position its masking container to fully cover the tail and extend the height until it's half-way under the head. + // The masking height is determined by the size of the body so that the head and tail don't overlap as the body becomes shorter via hitting (above). + tailMaskingContainer.Y = (Direction.Value == ScrollingDirection.Up ? 1 : -1) * Tail.Height; + tailMaskingContainer.Height = bodyContainer.DrawHeight + Tail.Height - Head.Height / 2; + + // The tail container needs the reverse of the above offset applied to bring the tail to its original position. + // It also needs the full original height of the hold note to maintain positioning even as the height of the masking container changes. + tailContainer.Y = -tailMaskingContainer.Y; + tailContainer.Height = DrawHeight; } protected override void UpdateStateTransforms(ArmedState state) From 8f1a71c6b1c563b7238c81c997b60df1dadd8440 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Wed, 19 Aug 2020 07:44:45 +0300 Subject: [PATCH 224/434] Remove counter sprite attributes for not being of any reasonable use --- .../Visual/Gameplay/TestSceneScoreCounter.cs | 2 - .../UserInterface/PercentageCounter.cs | 9 ++--- .../Graphics/UserInterface/RollingCounter.cs | 38 +------------------ .../Graphics/UserInterface/ScoreCounter.cs | 8 +--- .../UserInterface/SimpleComboCounter.cs | 7 +++- osu.Game/Screens/Play/HUDOverlay.cs | 3 -- 6 files changed, 13 insertions(+), 54 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneScoreCounter.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneScoreCounter.cs index 030d420ec0..09b4f9b761 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneScoreCounter.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneScoreCounter.cs @@ -20,7 +20,6 @@ namespace osu.Game.Tests.Visual.Gameplay { Origin = Anchor.TopRight, Anchor = Anchor.TopRight, - TextSize = 40, Margin = new MarginPadding(20), }; Add(score); @@ -30,7 +29,6 @@ namespace osu.Game.Tests.Visual.Gameplay Origin = Anchor.BottomLeft, Anchor = Anchor.BottomLeft, Margin = new MarginPadding(10), - TextSize = 40, }; Add(comboCounter); diff --git a/osu.Game/Graphics/UserInterface/PercentageCounter.cs b/osu.Game/Graphics/UserInterface/PercentageCounter.cs index 9b31935eee..3ea9c1053c 100644 --- a/osu.Game/Graphics/UserInterface/PercentageCounter.cs +++ b/osu.Game/Graphics/UserInterface/PercentageCounter.cs @@ -3,6 +3,7 @@ using System; using osu.Framework.Allocation; +using osu.Framework.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Utils; @@ -28,7 +29,7 @@ namespace osu.Game.Graphics.UserInterface } [BackgroundDependencyLoader] - private void load(OsuColour colours) => AccentColour = colours.BlueLighter; + private void load(OsuColour colours) => Colour = colours.BlueLighter; protected override string FormatCount(double count) => count.FormatAccuracy(); @@ -38,11 +39,7 @@ namespace osu.Game.Graphics.UserInterface } protected override OsuSpriteText CreateSpriteText() - { - var spriteText = base.CreateSpriteText(); - spriteText.Font = spriteText.Font.With(fixedWidth: true); - return spriteText; - } + => base.CreateSpriteText().With(s => s.Font = s.Font.With(size: 20f, fixedWidth: true)); public override void Increment(double amount) { diff --git a/osu.Game/Graphics/UserInterface/RollingCounter.cs b/osu.Game/Graphics/UserInterface/RollingCounter.cs index 76bb4bf69d..7c53d4fa0d 100644 --- a/osu.Game/Graphics/UserInterface/RollingCounter.cs +++ b/osu.Game/Graphics/UserInterface/RollingCounter.cs @@ -9,11 +9,10 @@ using System; using System.Collections.Generic; using osu.Framework.Allocation; using osu.Framework.Bindables; -using osuTK.Graphics; namespace osu.Game.Graphics.UserInterface { - public abstract class RollingCounter : Container, IHasAccentColour + public abstract class RollingCounter : Container where T : struct, IEquatable { /// @@ -60,38 +59,6 @@ namespace osu.Game.Graphics.UserInterface public abstract void Increment(T amount); - private float textSize = 40f; - - public float TextSize - { - get => displayedCountSpriteText?.Font.Size ?? textSize; - set - { - if (TextSize == value) - return; - - textSize = value; - if (displayedCountSpriteText != null) - displayedCountSpriteText.Font = displayedCountSpriteText.Font.With(size: value); - } - } - - private Color4 accentColour; - - public Color4 AccentColour - { - get => displayedCountSpriteText?.Colour ?? accentColour; - set - { - if (AccentColour == value) - return; - - accentColour = value; - if (displayedCountSpriteText != null) - displayedCountSpriteText.Colour = value; - } - } - /// /// Skeleton of a numeric counter which value rolls over time. /// @@ -185,8 +152,7 @@ namespace osu.Game.Graphics.UserInterface protected virtual OsuSpriteText CreateSpriteText() => new OsuSpriteText { - Font = OsuFont.Numeric.With(size: textSize), - Colour = accentColour, + Font = OsuFont.Numeric.With(size: 40f), }; } } diff --git a/osu.Game/Graphics/UserInterface/ScoreCounter.cs b/osu.Game/Graphics/UserInterface/ScoreCounter.cs index 438fe6c13b..faabe69f87 100644 --- a/osu.Game/Graphics/UserInterface/ScoreCounter.cs +++ b/osu.Game/Graphics/UserInterface/ScoreCounter.cs @@ -29,7 +29,7 @@ namespace osu.Game.Graphics.UserInterface } [BackgroundDependencyLoader] - private void load(OsuColour colours) => AccentColour = colours.BlueLighter; + private void load(OsuColour colours) => Colour = colours.BlueLighter; protected override double GetProportionalDuration(double currentValue, double newValue) { @@ -50,11 +50,7 @@ namespace osu.Game.Graphics.UserInterface } protected override OsuSpriteText CreateSpriteText() - { - var spriteText = base.CreateSpriteText(); - spriteText.Font = spriteText.Font.With(fixedWidth: true); - return spriteText; - } + => base.CreateSpriteText().With(s => s.Font = s.Font.With(fixedWidth: true)); public override void Increment(double amount) { diff --git a/osu.Game/Graphics/UserInterface/SimpleComboCounter.cs b/osu.Game/Graphics/UserInterface/SimpleComboCounter.cs index af03cbb63e..aac0166774 100644 --- a/osu.Game/Graphics/UserInterface/SimpleComboCounter.cs +++ b/osu.Game/Graphics/UserInterface/SimpleComboCounter.cs @@ -3,6 +3,8 @@ using System; using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Game.Graphics.Sprites; namespace osu.Game.Graphics.UserInterface { @@ -19,7 +21,7 @@ namespace osu.Game.Graphics.UserInterface } [BackgroundDependencyLoader] - private void load(OsuColour colours) => AccentColour = colours.BlueLighter; + private void load(OsuColour colours) => Colour = colours.BlueLighter; protected override string FormatCount(int count) { @@ -35,5 +37,8 @@ namespace osu.Game.Graphics.UserInterface { Current.Value += amount; } + + protected override OsuSpriteText CreateSpriteText() + => base.CreateSpriteText().With(s => s.Font = s.Font.With(size: 20f)); } } diff --git a/osu.Game/Screens/Play/HUDOverlay.cs b/osu.Game/Screens/Play/HUDOverlay.cs index f09745cf71..26aefa138b 100644 --- a/osu.Game/Screens/Play/HUDOverlay.cs +++ b/osu.Game/Screens/Play/HUDOverlay.cs @@ -232,7 +232,6 @@ namespace osu.Game.Screens.Play protected virtual RollingCounter CreateAccuracyCounter() => new PercentageCounter { - TextSize = 20, BypassAutoSizeAxes = Axes.X, Anchor = Anchor.TopLeft, Origin = Anchor.TopRight, @@ -241,14 +240,12 @@ namespace osu.Game.Screens.Play protected virtual ScoreCounter CreateScoreCounter() => new ScoreCounter(6) { - TextSize = 40, Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, }; protected virtual RollingCounter CreateComboCounter() => new SimpleComboCounter { - TextSize = 20, BypassAutoSizeAxes = Axes.X, Anchor = Anchor.TopRight, Origin = Anchor.TopLeft, From 5759ffff6fc8696dc7ca98ef507c5b39c6743334 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Wed, 19 Aug 2020 07:45:05 +0300 Subject: [PATCH 225/434] Use the property instead of the backing field --- osu.Game/Graphics/UserInterface/RollingCounter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Graphics/UserInterface/RollingCounter.cs b/osu.Game/Graphics/UserInterface/RollingCounter.cs index 7c53d4fa0d..6763198213 100644 --- a/osu.Game/Graphics/UserInterface/RollingCounter.cs +++ b/osu.Game/Graphics/UserInterface/RollingCounter.cs @@ -77,7 +77,7 @@ namespace osu.Game.Graphics.UserInterface private void load() { displayedCountSpriteText = CreateSpriteText(); - displayedCountSpriteText.Text = FormatCount(displayedCount); + displayedCountSpriteText.Text = FormatCount(DisplayedCount); Child = displayedCountSpriteText; } From ee9fa11d142ed4fe14ca3dc06bfcc9edb56c02f5 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Wed, 19 Aug 2020 07:47:02 +0300 Subject: [PATCH 226/434] Use `With(s => ...)` extension for better readability --- .../Gameplay/Components/MatchScoreDisplay.cs | 23 ++++++++++--------- .../Expanded/Statistics/AccuracyStatistic.cs | 10 ++++---- .../Expanded/Statistics/CounterStatistic.cs | 10 ++++---- .../Ranking/Expanded/TotalScoreCounter.cs | 14 +++++------ 4 files changed, 26 insertions(+), 31 deletions(-) diff --git a/osu.Game.Tournament/Screens/Gameplay/Components/MatchScoreDisplay.cs b/osu.Game.Tournament/Screens/Gameplay/Components/MatchScoreDisplay.cs index 25417921bc..695c6d6f3e 100644 --- a/osu.Game.Tournament/Screens/Gameplay/Components/MatchScoreDisplay.cs +++ b/osu.Game.Tournament/Screens/Gameplay/Components/MatchScoreDisplay.cs @@ -137,19 +137,20 @@ namespace osu.Game.Tournament.Screens.Gameplay.Components public bool Winning { - set => displayedSpriteText.Font = value + set => updateFont(value); + } + + protected override OsuSpriteText CreateSpriteText() => base.CreateSpriteText().With(s => + { + displayedSpriteText = s; + displayedSpriteText.Spacing = new Vector2(-6); + updateFont(false); + }); + + private void updateFont(bool winning) + => displayedSpriteText.Font = winning ? OsuFont.Torus.With(weight: FontWeight.Bold, size: 50, fixedWidth: true) : OsuFont.Torus.With(weight: FontWeight.Regular, size: 40, fixedWidth: true); - } - - protected override OsuSpriteText CreateSpriteText() - { - displayedSpriteText = base.CreateSpriteText(); - displayedSpriteText.Spacing = new Vector2(-6); - Winning = false; - - return displayedSpriteText; - } } } } diff --git a/osu.Game/Screens/Ranking/Expanded/Statistics/AccuracyStatistic.cs b/osu.Game/Screens/Ranking/Expanded/Statistics/AccuracyStatistic.cs index 921ad80976..6933456e7e 100644 --- a/osu.Game/Screens/Ranking/Expanded/Statistics/AccuracyStatistic.cs +++ b/osu.Game/Screens/Ranking/Expanded/Statistics/AccuracyStatistic.cs @@ -49,13 +49,11 @@ namespace osu.Game.Screens.Ranking.Expanded.Statistics public override void Increment(double amount) => Current.Value += amount; - protected override OsuSpriteText CreateSpriteText() + protected override OsuSpriteText CreateSpriteText() => base.CreateSpriteText().With(s => { - var spriteText = base.CreateSpriteText(); - spriteText.Font = OsuFont.Torus.With(size: 20, fixedWidth: true); - spriteText.Spacing = new Vector2(-2, 0); - return spriteText; - } + s.Font = OsuFont.Torus.With(size: 20, fixedWidth: true); + s.Spacing = new Vector2(-2, 0); + }); } } } diff --git a/osu.Game/Screens/Ranking/Expanded/Statistics/CounterStatistic.cs b/osu.Game/Screens/Ranking/Expanded/Statistics/CounterStatistic.cs index cc0f49c968..043a560d12 100644 --- a/osu.Game/Screens/Ranking/Expanded/Statistics/CounterStatistic.cs +++ b/osu.Game/Screens/Ranking/Expanded/Statistics/CounterStatistic.cs @@ -44,13 +44,11 @@ namespace osu.Game.Screens.Ranking.Expanded.Statistics protected override Easing RollingEasing => AccuracyCircle.ACCURACY_TRANSFORM_EASING; - protected override OsuSpriteText CreateSpriteText() + protected override OsuSpriteText CreateSpriteText() => base.CreateSpriteText().With(s => { - var spriteText = base.CreateSpriteText(); - spriteText.Font = OsuFont.Torus.With(size: 20, fixedWidth: true); - spriteText.Spacing = new Vector2(-2, 0); - return spriteText; - } + s.Font = OsuFont.Torus.With(size: 20, fixedWidth: true); + s.Spacing = new Vector2(-2, 0); + }); public override void Increment(int amount) => Current.Value += amount; diff --git a/osu.Game/Screens/Ranking/Expanded/TotalScoreCounter.cs b/osu.Game/Screens/Ranking/Expanded/TotalScoreCounter.cs index b0060d19ac..7f6fd1eabe 100644 --- a/osu.Game/Screens/Ranking/Expanded/TotalScoreCounter.cs +++ b/osu.Game/Screens/Ranking/Expanded/TotalScoreCounter.cs @@ -28,16 +28,14 @@ namespace osu.Game.Screens.Ranking.Expanded protected override string FormatCount(long count) => count.ToString("N0"); - protected override OsuSpriteText CreateSpriteText() + protected override OsuSpriteText CreateSpriteText() => base.CreateSpriteText().With(s => { - var spriteText = base.CreateSpriteText(); - spriteText.Anchor = Anchor.TopCentre; - spriteText.Origin = Anchor.TopCentre; + s.Anchor = Anchor.TopCentre; + s.Origin = Anchor.TopCentre; - spriteText.Font = OsuFont.Torus.With(size: 60, weight: FontWeight.Light, fixedWidth: true); - spriteText.Spacing = new Vector2(-5, 0); - return spriteText; - } + s.Font = OsuFont.Torus.With(size: 60, weight: FontWeight.Light, fixedWidth: true); + s.Spacing = new Vector2(-5, 0); + }); public override void Increment(long amount) => Current.Value += amount; From 06503597e00f8b784c0c712f97c17ff589b086f1 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 19 Aug 2020 19:09:35 +0900 Subject: [PATCH 227/434] Remove unnecessarily exposed visibility state --- osu.Game.Tests/Visual/Menus/TestSceneToolbar.cs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/osu.Game.Tests/Visual/Menus/TestSceneToolbar.cs b/osu.Game.Tests/Visual/Menus/TestSceneToolbar.cs index 5170058700..56c030df77 100644 --- a/osu.Game.Tests/Visual/Menus/TestSceneToolbar.cs +++ b/osu.Game.Tests/Visual/Menus/TestSceneToolbar.cs @@ -84,16 +84,14 @@ namespace osu.Game.Tests.Visual.Menus AddStep("try to show toolbar", () => toolbar.Show()); if (mode == OverlayActivation.Disabled) - AddUntilStep("toolbar still hidden", () => toolbar.Visibility == Visibility.Hidden); + AddUntilStep("toolbar still hidden", () => toolbar.State.Value == Visibility.Hidden); else - AddAssert("toolbar is visible", () => toolbar.Visibility == Visibility.Visible); + AddAssert("toolbar is visible", () => toolbar.State.Value == Visibility.Visible); } public class TestToolbar : Toolbar { public new Bindable OverlayActivationMode => base.OverlayActivationMode; - - public Visibility Visibility => State.Value; } } } From 3e4eae7fe4bcad660abf0bb6018e3f2f0d66bf3f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 19 Aug 2020 19:10:45 +0900 Subject: [PATCH 228/434] Remove unnecessary until step --- osu.Game.Tests/Visual/Menus/TestSceneToolbar.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Menus/TestSceneToolbar.cs b/osu.Game.Tests/Visual/Menus/TestSceneToolbar.cs index 56c030df77..f819ae4682 100644 --- a/osu.Game.Tests/Visual/Menus/TestSceneToolbar.cs +++ b/osu.Game.Tests/Visual/Menus/TestSceneToolbar.cs @@ -84,7 +84,7 @@ namespace osu.Game.Tests.Visual.Menus AddStep("try to show toolbar", () => toolbar.Show()); if (mode == OverlayActivation.Disabled) - AddUntilStep("toolbar still hidden", () => toolbar.State.Value == Visibility.Hidden); + AddAssert("toolbar still hidden", () => toolbar.State.Value == Visibility.Hidden); else AddAssert("toolbar is visible", () => toolbar.State.Value == Visibility.Visible); } From f6ca31688e73757dbf12a37381f52e6c91917f46 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 19 Aug 2020 21:39:55 +0900 Subject: [PATCH 229/434] Fix incorrect spacing --- osu.Game.Rulesets.Mania/Skinning/LegacyHitExplosion.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Mania/Skinning/LegacyHitExplosion.cs b/osu.Game.Rulesets.Mania/Skinning/LegacyHitExplosion.cs index 41f3090afd..7c5d41efcf 100644 --- a/osu.Game.Rulesets.Mania/Skinning/LegacyHitExplosion.cs +++ b/osu.Game.Rulesets.Mania/Skinning/LegacyHitExplosion.cs @@ -73,7 +73,7 @@ namespace osu.Game.Rulesets.Mania.Skinning (explosion as IFramedAnimation)?.GotoFrame(0); explosion?.FadeInFromZero(80) - .Then().FadeOut(120); + .Then().FadeOut(120); } } } From 4397be60e2a3bd249662437d9f6e1272b470bc0c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 19 Aug 2020 21:58:02 +0900 Subject: [PATCH 230/434] Update framework --- osu.Android.props | 2 +- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index f3fb949f76..1a76a24496 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -52,6 +52,6 @@ - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index a12ce138bd..d1e2033596 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -24,7 +24,7 @@ - + diff --git a/osu.iOS.props b/osu.iOS.props index 0170e94140..9b25eaab41 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -70,7 +70,7 @@ - + @@ -80,7 +80,7 @@ - + From 1badc584f6cc7920558fce900d6a275f62f55188 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 19 Aug 2020 22:10:58 +0900 Subject: [PATCH 231/434] Update textbox event names --- osu.Game/Graphics/UserInterface/OsuTextBox.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/OsuTextBox.cs b/osu.Game/Graphics/UserInterface/OsuTextBox.cs index 0d173e2d3e..1ec4dfc91a 100644 --- a/osu.Game/Graphics/UserInterface/OsuTextBox.cs +++ b/osu.Game/Graphics/UserInterface/OsuTextBox.cs @@ -74,9 +74,9 @@ namespace osu.Game.Graphics.UserInterface protected override Color4 SelectionColour => new Color4(249, 90, 255, 255); - protected override void OnTextAdded(string added) + protected override void OnUserTextAdded(string added) { - base.OnTextAdded(added); + base.OnUserTextAdded(added); if (added.Any(char.IsUpper) && AllowUniqueCharacterSamples) capsTextAddedSample?.Play(); @@ -84,9 +84,9 @@ namespace osu.Game.Graphics.UserInterface textAddedSamples[RNG.Next(0, 3)]?.Play(); } - protected override void OnTextRemoved(string removed) + protected override void OnUserTextRemoved(string removed) { - base.OnTextRemoved(removed); + base.OnUserTextRemoved(removed); textRemovedSample?.Play(); } From ff0dec3dd928aa0ab0467cadb1027414bfe1606e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 20 Aug 2020 12:23:39 +0900 Subject: [PATCH 232/434] Update plist path to work with newer fastlane version It seems they have fixed the working/current directory and the parent traversal is no longer required. --- fastlane/Fastfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fastlane/Fastfile b/fastlane/Fastfile index 4fd0e5e8c7..8c278604aa 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -113,7 +113,7 @@ platform :ios do souyuz( platform: "ios", - plist_path: "../osu.iOS/Info.plist" + plist_path: "osu.iOS/Info.plist" ) end @@ -127,7 +127,7 @@ platform :ios do end lane :update_version do |options| - options[:plist_path] = '../osu.iOS/Info.plist' + options[:plist_path] = 'osu.iOS/Info.plist' app_version(options) end From 6358f4a661f282719597d215a1129af97e63ae5b Mon Sep 17 00:00:00 2001 From: Shane Woolcock Date: Thu, 20 Aug 2020 17:33:08 +0930 Subject: [PATCH 233/434] Disable CA2225 warning regarding operator overloads --- .editorconfig | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.editorconfig b/.editorconfig index 67f98f94eb..a5f7795882 100644 --- a/.editorconfig +++ b/.editorconfig @@ -191,4 +191,7 @@ dotnet_diagnostic.IDE0052.severity = silent #Rules for disposable dotnet_diagnostic.IDE0067.severity = none dotnet_diagnostic.IDE0068.severity = none -dotnet_diagnostic.IDE0069.severity = none \ No newline at end of file +dotnet_diagnostic.IDE0069.severity = none + +#Disable operator overloads requiring alternate named methods +dotnet_diagnostic.CA2225.severity = none \ No newline at end of file From 1f14d9b690d39122cd89ef799429c12c7511e34e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 20 Aug 2020 18:15:06 +0900 Subject: [PATCH 234/434] Use correct width adjust for osu!catch playfield --- .../UI/CatchPlayfieldAdjustmentContainer.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Catch/UI/CatchPlayfieldAdjustmentContainer.cs b/osu.Game.Rulesets.Catch/UI/CatchPlayfieldAdjustmentContainer.cs index 8ee23461ba..040247a264 100644 --- a/osu.Game.Rulesets.Catch/UI/CatchPlayfieldAdjustmentContainer.cs +++ b/osu.Game.Rulesets.Catch/UI/CatchPlayfieldAdjustmentContainer.cs @@ -10,6 +10,8 @@ namespace osu.Game.Rulesets.Catch.UI { public class CatchPlayfieldAdjustmentContainer : PlayfieldAdjustmentContainer { + private const float playfield_size_adjust = 0.8f; + protected override Container Content => content; private readonly Container content; @@ -18,7 +20,7 @@ namespace osu.Game.Rulesets.Catch.UI Anchor = Anchor.TopCentre; Origin = Anchor.TopCentre; - Size = new Vector2(0.86f); // matches stable's vertical offset for catcher plate + Size = new Vector2(playfield_size_adjust); InternalChild = new Container { From a94a86178bcbbde7a7b1a96cf871be29c3e96b40 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 20 Aug 2020 19:12:37 +0900 Subject: [PATCH 235/434] Align osu!catch playfield with stable 1:1 --- .../UI/CatchPlayfieldAdjustmentContainer.cs | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Catch/UI/CatchPlayfieldAdjustmentContainer.cs b/osu.Game.Rulesets.Catch/UI/CatchPlayfieldAdjustmentContainer.cs index 040247a264..efc1b24ed5 100644 --- a/osu.Game.Rulesets.Catch/UI/CatchPlayfieldAdjustmentContainer.cs +++ b/osu.Game.Rulesets.Catch/UI/CatchPlayfieldAdjustmentContainer.cs @@ -17,8 +17,12 @@ namespace osu.Game.Rulesets.Catch.UI public CatchPlayfieldAdjustmentContainer() { - Anchor = Anchor.TopCentre; - Origin = Anchor.TopCentre; + // because we are using centre anchor/origin, we will need to limit visibility in the future + // to ensure tall windows do not get a readability advantage. + // it may be possible to bake the catch-specific offsets (-100..340 mentioned below) into new values + // which are compatible with TopCentre alignment. + Anchor = Anchor.Centre; + Origin = Anchor.Centre; Size = new Vector2(playfield_size_adjust); @@ -29,7 +33,7 @@ namespace osu.Game.Rulesets.Catch.UI RelativeSizeAxes = Axes.Both, FillMode = FillMode.Fit, FillAspectRatio = 4f / 3, - Child = content = new ScalingContainer { RelativeSizeAxes = Axes.Both } + Child = content = new ScalingContainer { RelativeSizeAxes = Axes.Both, } }; } @@ -42,8 +46,14 @@ namespace osu.Game.Rulesets.Catch.UI { base.Update(); + // in stable, fruit fall vertically from -100 to 340. + // to emulate this, we want to make our playfield 440 gameplay pixels high. + // we then offset it -100 vertically in the position set below. + const float stable_v_offset_ratio = 440 / 384f; + Scale = new Vector2(Parent.ChildSize.X / CatchPlayfield.WIDTH); - Size = Vector2.Divide(Vector2.One, Scale); + Position = new Vector2(0, -100 * stable_v_offset_ratio + Scale.X); + Size = Vector2.Divide(new Vector2(1, stable_v_offset_ratio), Scale); } } } From e6d13edafb8200de6122d685dd5cdffaf724d2c3 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 20 Aug 2020 19:41:27 +0900 Subject: [PATCH 236/434] Force tournament client to run in windowed mode We generally haven't tested in other modes, and it doesn't really make sense as you wouldn't be able to use it in a meaningful way otherwise. - [ ] Test on windows. --- osu.Game.Tournament/TournamentGame.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/osu.Game.Tournament/TournamentGame.cs b/osu.Game.Tournament/TournamentGame.cs index 7b1a174c1e..307ee1c773 100644 --- a/osu.Game.Tournament/TournamentGame.cs +++ b/osu.Game.Tournament/TournamentGame.cs @@ -31,6 +31,7 @@ namespace osu.Game.Tournament public static readonly Color4 TEXT_COLOUR = Color4Extensions.FromHex("#fff"); private Drawable heightWarning; private Bindable windowSize; + private Bindable windowMode; [BackgroundDependencyLoader] private void load(FrameworkConfigManager frameworkConfig) @@ -43,6 +44,12 @@ namespace osu.Game.Tournament heightWarning.Alpha = size.NewValue.Width < minWidth ? 1 : 0; }), true); + windowMode = frameworkConfig.GetBindable(FrameworkSetting.WindowMode); + windowMode.BindValueChanged(mode => ScheduleAfterChildren(() => + { + windowMode.Value = WindowMode.Windowed; + }), true); + AddRange(new[] { new Container From c89509aca01da1f461382a3851f72c32131fc54e Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 20 Aug 2020 20:25:40 +0900 Subject: [PATCH 237/434] Fix right bound not being applied correctly --- .../CatchBeatmapConversionTest.cs | 1 + .../Beatmaps/CatchBeatmapProcessor.cs | 2 +- ...t-bound-hr-offset-expected-conversion.json | 17 ++++++++++++++++ .../Beatmaps/right-bound-hr-offset.osu | 20 +++++++++++++++++++ 4 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 osu.Game.Rulesets.Catch/Resources/Testing/Beatmaps/right-bound-hr-offset-expected-conversion.json create mode 100644 osu.Game.Rulesets.Catch/Resources/Testing/Beatmaps/right-bound-hr-offset.osu diff --git a/osu.Game.Rulesets.Catch.Tests/CatchBeatmapConversionTest.cs b/osu.Game.Rulesets.Catch.Tests/CatchBeatmapConversionTest.cs index df54df7b01..8c48158acd 100644 --- a/osu.Game.Rulesets.Catch.Tests/CatchBeatmapConversionTest.cs +++ b/osu.Game.Rulesets.Catch.Tests/CatchBeatmapConversionTest.cs @@ -25,6 +25,7 @@ namespace osu.Game.Rulesets.Catch.Tests [TestCase("hardrock-stream", new[] { typeof(CatchModHardRock) })] [TestCase("hardrock-repeat-slider", new[] { typeof(CatchModHardRock) })] [TestCase("hardrock-spinner", new[] { typeof(CatchModHardRock) })] + [TestCase("right-bound-hr-offset", new[] { typeof(CatchModHardRock) })] public new void Test(string name, params Type[] mods) => base.Test(name, mods); protected override IEnumerable CreateConvertValue(HitObject hitObject) diff --git a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs index bb14988414..15e6e98f5a 100644 --- a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs +++ b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs @@ -179,7 +179,7 @@ namespace osu.Game.Rulesets.Catch.Beatmaps if (amount > 0) { // Clamp to the right bound - if (position + amount < 1) + if (position + amount < CatchPlayfield.WIDTH) position += amount; } else diff --git a/osu.Game.Rulesets.Catch/Resources/Testing/Beatmaps/right-bound-hr-offset-expected-conversion.json b/osu.Game.Rulesets.Catch/Resources/Testing/Beatmaps/right-bound-hr-offset-expected-conversion.json new file mode 100644 index 0000000000..3bde97070c --- /dev/null +++ b/osu.Game.Rulesets.Catch/Resources/Testing/Beatmaps/right-bound-hr-offset-expected-conversion.json @@ -0,0 +1,17 @@ +{ + "Mappings": [{ + "StartTime": 3368, + "Objects": [{ + "StartTime": 3368, + "Position": 374 + }] + }, + { + "StartTime": 3501, + "Objects": [{ + "StartTime": 3501, + "Position": 446 + }] + } + ] +} \ No newline at end of file diff --git a/osu.Game.Rulesets.Catch/Resources/Testing/Beatmaps/right-bound-hr-offset.osu b/osu.Game.Rulesets.Catch/Resources/Testing/Beatmaps/right-bound-hr-offset.osu new file mode 100644 index 0000000000..6630f369d5 --- /dev/null +++ b/osu.Game.Rulesets.Catch/Resources/Testing/Beatmaps/right-bound-hr-offset.osu @@ -0,0 +1,20 @@ +osu file format v14 + +[General] +StackLeniency: 0.7 +Mode: 2 + +[Difficulty] +HPDrainRate:6 +CircleSize:4 +OverallDifficulty:9.6 +ApproachRate:9.6 +SliderMultiplier:1.9 +SliderTickRate:1 + +[TimingPoints] +2169,266.666666666667,4,2,1,70,1,0 + +[HitObjects] +374,60,3368,1,0,0:0:0:0: +410,146,3501,1,2,0:1:0:0: \ No newline at end of file From f1e09466036ae60f50296dd22c700cc6e14e9522 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 20 Aug 2020 22:38:47 +0900 Subject: [PATCH 238/434] Remove release samples in invert mod --- osu.Game.Rulesets.Mania/Mods/ManiaModInvert.cs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModInvert.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModInvert.cs index 56f6e389bf..593b459e8a 100644 --- a/osu.Game.Rulesets.Mania/Mods/ManiaModInvert.cs +++ b/osu.Game.Rulesets.Mania/Mods/ManiaModInvert.cs @@ -60,12 +60,7 @@ namespace osu.Game.Rulesets.Mania.Mods Column = column.Key, StartTime = locations[i].startTime, Duration = duration, - Samples = locations[i].samples, - NodeSamples = new List> - { - locations[i].samples, - locations[i + 1].samples - } + NodeSamples = new List> { locations[i].samples, new List() } }); } From 54a2322090a7c1555e7c170ce28443c46f1b20cc Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 20 Aug 2020 22:51:52 +0900 Subject: [PATCH 239/434] Use Array.Empty<> --- osu.Game.Rulesets.Mania/Mods/ManiaModInvert.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModInvert.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModInvert.cs index 593b459e8a..1ea45c295c 100644 --- a/osu.Game.Rulesets.Mania/Mods/ManiaModInvert.cs +++ b/osu.Game.Rulesets.Mania/Mods/ManiaModInvert.cs @@ -60,7 +60,7 @@ namespace osu.Game.Rulesets.Mania.Mods Column = column.Key, StartTime = locations[i].startTime, Duration = duration, - NodeSamples = new List> { locations[i].samples, new List() } + NodeSamples = new List> { locations[i].samples, Array.Empty() } }); } From a193fb79071a6cbfb8ddf09b1b27e2b38987bcb1 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 20 Aug 2020 23:15:30 +0900 Subject: [PATCH 240/434] Fix test not working for droplets/tinydroplets --- .../TestSceneFruitObjects.cs | 22 +++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneFruitObjects.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneFruitObjects.cs index c07e4fdad3..6182faedd1 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneFruitObjects.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneFruitObjects.cs @@ -30,9 +30,8 @@ namespace osu.Game.Rulesets.Catch.Tests private Drawable createDrawableTinyDroplet() { - var droplet = new TinyDroplet + var droplet = new TestCatchTinyDroplet { - StartTime = Clock.CurrentTime, Scale = 1.5f, }; @@ -49,9 +48,8 @@ namespace osu.Game.Rulesets.Catch.Tests private Drawable createDrawableDroplet() { - var droplet = new Droplet + var droplet = new TestCatchDroplet { - StartTime = Clock.CurrentTime, Scale = 1.5f, }; @@ -95,5 +93,21 @@ namespace osu.Game.Rulesets.Catch.Tests public override FruitVisualRepresentation VisualRepresentation { get; } } + + public class TestCatchDroplet : Droplet + { + public TestCatchDroplet() + { + StartTime = 1000000000000; + } + } + + public class TestCatchTinyDroplet : TinyDroplet + { + public TestCatchTinyDroplet() + { + StartTime = 1000000000000; + } + } } } From 725caa9382128e5dedfec1a664e26dae89b7489e Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 20 Aug 2020 23:16:37 +0900 Subject: [PATCH 241/434] Add visual test for hyperdash droplets --- osu.Game.Rulesets.Catch.Tests/TestSceneFruitObjects.cs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneFruitObjects.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneFruitObjects.cs index 6182faedd1..385d8ed7fa 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneFruitObjects.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneFruitObjects.cs @@ -20,12 +20,13 @@ namespace osu.Game.Rulesets.Catch.Tests foreach (FruitVisualRepresentation rep in Enum.GetValues(typeof(FruitVisualRepresentation))) AddStep($"show {rep}", () => SetContents(() => createDrawable(rep))); - AddStep("show droplet", () => SetContents(createDrawableDroplet)); - + AddStep("show droplet", () => SetContents(() => createDrawableDroplet())); AddStep("show tiny droplet", () => SetContents(createDrawableTinyDroplet)); foreach (FruitVisualRepresentation rep in Enum.GetValues(typeof(FruitVisualRepresentation))) AddStep($"show hyperdash {rep}", () => SetContents(() => createDrawable(rep, true))); + + AddStep("show hyperdash droplet", () => SetContents(() => createDrawableDroplet(true))); } private Drawable createDrawableTinyDroplet() @@ -46,11 +47,12 @@ namespace osu.Game.Rulesets.Catch.Tests }; } - private Drawable createDrawableDroplet() + private Drawable createDrawableDroplet(bool hyperdash = false) { var droplet = new TestCatchDroplet { Scale = 1.5f, + HyperDashTarget = hyperdash ? new Banana() : null }; return new DrawableDroplet(droplet) From 40a456170b73754fd172c2cb3bf4bc697f5c3bcd Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 20 Aug 2020 23:34:40 +0900 Subject: [PATCH 242/434] Add default skin display for hyperdash droplets --- .../Objects/Drawables/DrawableDroplet.cs | 7 +- .../Objects/Drawables/DropletPiece.cs | 70 +++++++++++++++++++ .../Objects/Drawables/FruitPiece.cs | 6 -- 3 files changed, 71 insertions(+), 12 deletions(-) create mode 100644 osu.Game.Rulesets.Catch/Objects/Drawables/DropletPiece.cs diff --git a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableDroplet.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableDroplet.cs index cad8892283..592b69d963 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableDroplet.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableDroplet.cs @@ -4,7 +4,6 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Utils; -using osu.Game.Rulesets.Catch.Objects.Drawables.Pieces; using osu.Game.Skinning; namespace osu.Game.Rulesets.Catch.Objects.Drawables @@ -21,11 +20,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables [BackgroundDependencyLoader] private void load() { - ScaleContainer.Child = new SkinnableDrawable(new CatchSkinComponent(CatchSkinComponents.Droplet), _ => new Pulp - { - Size = Size / 4, - AccentColour = { BindTarget = AccentColour } - }); + ScaleContainer.Child = new SkinnableDrawable(new CatchSkinComponent(CatchSkinComponents.Droplet), _ => new DropletPiece()); } protected override void UpdateInitialTransforms() diff --git a/osu.Game.Rulesets.Catch/Objects/Drawables/DropletPiece.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/DropletPiece.cs new file mode 100644 index 0000000000..d6c9f4398f --- /dev/null +++ b/osu.Game.Rulesets.Catch/Objects/Drawables/DropletPiece.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 osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Game.Rulesets.Catch.Objects.Drawables.Pieces; +using osu.Game.Rulesets.Catch.UI; +using osu.Game.Rulesets.Objects.Drawables; +using osuTK; + +namespace osu.Game.Rulesets.Catch.Objects.Drawables +{ + public class DropletPiece : CompositeDrawable + { + public DropletPiece() + { + Size = new Vector2(CatchHitObject.OBJECT_RADIUS / 2); + } + + [BackgroundDependencyLoader] + private void load(DrawableHitObject drawableObject) + { + DrawableCatchHitObject drawableCatchObject = (DrawableCatchHitObject)drawableObject; + var hitObject = drawableCatchObject.HitObject; + + InternalChild = new Pulp + { + // RelativeSizeAxes is not used since the edge effect uses Size. + Size = Size, + AccentColour = { BindTarget = drawableObject.AccentColour } + }; + + if (hitObject.HyperDash) + { + AddInternal(new Container + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + Size = new Vector2(2f), + Depth = 1, + Children = new Drawable[] + { + new Circle + { + RelativeSizeAxes = Axes.Both, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + BorderColour = Catcher.DEFAULT_HYPER_DASH_COLOUR, + BorderThickness = 6, + Children = new Drawable[] + { + new Box + { + AlwaysPresent = true, + Alpha = 0.3f, + Blending = BlendingParameters.Additive, + RelativeSizeAxes = Axes.Both, + Colour = Catcher.DEFAULT_HYPER_DASH_COLOUR, + } + } + } + } + }); + } + } + } +} diff --git a/osu.Game.Rulesets.Catch/Objects/Drawables/FruitPiece.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/FruitPiece.cs index 7ac9f11ad6..4bffdab3d8 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawables/FruitPiece.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawables/FruitPiece.cs @@ -3,7 +3,6 @@ using System; using osu.Framework.Allocation; -using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; @@ -21,11 +20,8 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables public const float RADIUS_ADJUST = 1.1f; private Circle border; - private CatchHitObject hitObject; - private readonly IBindable accentColour = new Bindable(); - public FruitPiece() { RelativeSizeAxes = Axes.Both; @@ -37,8 +33,6 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables DrawableCatchHitObject drawableCatchObject = (DrawableCatchHitObject)drawableObject; hitObject = drawableCatchObject.HitObject; - accentColour.BindTo(drawableCatchObject.AccentColour); - AddRangeInternal(new[] { getFruitFor(drawableCatchObject.HitObject.VisualRepresentation), From 35ff25940b11437e8823b0b904c78c99ee101428 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Thu, 20 Aug 2020 18:16:32 +0200 Subject: [PATCH 243/434] Add sample playback to juice stream test scene --- osu.Game.Rulesets.Catch.Tests/TestSceneAutoJuiceStream.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneAutoJuiceStream.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneAutoJuiceStream.cs index d6bba3d55e..3c636a5b97 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneAutoJuiceStream.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneAutoJuiceStream.cs @@ -1,7 +1,9 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System.Collections.Generic; using System.Linq; +using osu.Game.Audio; using osu.Game.Beatmaps; using osu.Game.Rulesets.Catch.Objects; using osu.Game.Rulesets.Catch.UI; @@ -38,7 +40,11 @@ namespace osu.Game.Rulesets.Catch.Tests new Vector2(width, 0) }), StartTime = i * 2000, - NewCombo = i % 8 == 0 + NewCombo = i % 8 == 0, + Samples = new List(new[] + { + new HitSampleInfo { Bank = "normal", Name = "hitnormal", Volume = 100 } + }) }); } From 45e2ea71b4e28380fdcad4719271fa7438beab98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Thu, 20 Aug 2020 18:41:08 +0200 Subject: [PATCH 244/434] Rename Palpable{-> Drawable}CatchHitObject --- .../Objects/Drawables/DrawableCatchHitObject.cs | 4 ++-- osu.Game.Rulesets.Catch/Objects/Drawables/DrawableDroplet.cs | 2 +- osu.Game.Rulesets.Catch/Objects/Drawables/DrawableFruit.cs | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableCatchHitObject.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableCatchHitObject.cs index c6345a9df7..883d2048ed 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableCatchHitObject.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableCatchHitObject.cs @@ -15,14 +15,14 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Catch.Objects.Drawables { - public abstract class PalpableCatchHitObject : DrawableCatchHitObject + public abstract class PalpableDrawableCatchHitObject : DrawableCatchHitObject where TObject : CatchHitObject { public override bool CanBePlated => true; protected Container ScaleContainer { get; private set; } - protected PalpableCatchHitObject(TObject hitObject) + protected PalpableDrawableCatchHitObject(TObject hitObject) : base(hitObject) { Origin = Anchor.Centre; diff --git a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableDroplet.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableDroplet.cs index cad8892283..77ae7e9a54 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableDroplet.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableDroplet.cs @@ -9,7 +9,7 @@ using osu.Game.Skinning; namespace osu.Game.Rulesets.Catch.Objects.Drawables { - public class DrawableDroplet : PalpableCatchHitObject + public class DrawableDroplet : PalpableDrawableCatchHitObject { public override bool StaysOnPlate => false; diff --git a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableFruit.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableFruit.cs index fae5a10d04..c1c34e4157 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableFruit.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableFruit.cs @@ -8,7 +8,7 @@ using osu.Game.Skinning; namespace osu.Game.Rulesets.Catch.Objects.Drawables { - public class DrawableFruit : PalpableCatchHitObject + public class DrawableFruit : PalpableDrawableCatchHitObject { public DrawableFruit(Fruit h) : base(h) From f956c9fe37925edb9780f778b181b24a6a44dade Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 21 Aug 2020 02:01:29 +0900 Subject: [PATCH 245/434] Clobber in a gameplay test --- .../TestSceneHyperDash.cs | 19 +++++++++++++++++++ osu.Game.Rulesets.Catch/UI/Catcher.cs | 5 ++--- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneHyperDash.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneHyperDash.cs index ad24adf352..1aa333c401 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneHyperDash.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneHyperDash.cs @@ -6,6 +6,7 @@ using System.Linq; using NUnit.Framework; using osu.Framework.Testing; using osu.Game.Beatmaps; +using osu.Game.Beatmaps.ControlPoints; using osu.Game.Rulesets.Catch.Objects; using osu.Game.Rulesets.Catch.UI; using osu.Game.Rulesets.Objects; @@ -31,6 +32,8 @@ namespace osu.Game.Rulesets.Catch.Tests AddUntilStep("wait for right hyperdash", () => getCatcher().Scale.X > 0 && getCatcher().HyperDashing); AddUntilStep("wait for left hyperdash", () => getCatcher().Scale.X < 0 && getCatcher().HyperDashing); } + + AddUntilStep("wait for right hyperdash", () => getCatcher().Scale.X > 0 && getCatcher().HyperDashing); } private Catcher getCatcher() => Player.ChildrenOfType().First().MovableCatcher; @@ -46,6 +49,8 @@ namespace osu.Game.Rulesets.Catch.Tests } }; + beatmap.ControlPointInfo.Add(0, new TimingControlPoint()); + // Should produce a hyper-dash (edge case test) beatmap.HitObjects.Add(new Fruit { StartTime = 1816, X = 56, NewCombo = true }); beatmap.HitObjects.Add(new Fruit { StartTime = 2008, X = 308, NewCombo = true }); @@ -63,6 +68,20 @@ namespace osu.Game.Rulesets.Catch.Tests createObjects(() => new Fruit { X = right_x }); createObjects(() => new TestJuiceStream(left_x), 1); + beatmap.ControlPointInfo.Add(7900, new TimingControlPoint + { + BeatLength = 50 + }); + + createObjects(() => new TestJuiceStream(left_x) + { + Path = new SliderPath(new[] + { + new PathControlPoint(Vector2.Zero), + new PathControlPoint(new Vector2(512, 0)) + }) + }, 1); + return beatmap; void createObjects(Func createObject, int count = 3) diff --git a/osu.Game.Rulesets.Catch/UI/Catcher.cs b/osu.Game.Rulesets.Catch/UI/Catcher.cs index 8820dff730..0897ccf2d5 100644 --- a/osu.Game.Rulesets.Catch/UI/Catcher.cs +++ b/osu.Game.Rulesets.Catch/UI/Catcher.cs @@ -226,9 +226,8 @@ namespace osu.Game.Rulesets.Catch.UI catchObjectPosition >= catcherPosition - halfCatchWidth && catchObjectPosition <= catcherPosition + halfCatchWidth; - // only update hyperdash state if we are catching a fruit. - // exceptions are Droplets and JuiceStreams. - if (!(fruit is Fruit)) return validCatch; + // only update hyperdash state if we are catching a fruit or a droplet (and not a tiny droplet). + if (!(fruit is Fruit || fruit is Droplet) || fruit is TinyDroplet) return validCatch; if (validCatch && fruit.HyperDash) { From 28534c1599ed85f8b1a6a1a99fc3c78d7f21b131 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Thu, 20 Aug 2020 18:48:01 +0200 Subject: [PATCH 246/434] Reintroduce PalpableCatchHitObject at data level --- osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs | 13 +++++++++++++ .../Objects/Drawables/DrawableCatchHitObject.cs | 8 ++------ osu.Game.Rulesets.Catch/Objects/Droplet.cs | 2 +- osu.Game.Rulesets.Catch/Objects/Fruit.cs | 2 +- osu.Game.Rulesets.Catch/UI/CatcherArea.cs | 2 +- 5 files changed, 18 insertions(+), 9 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs b/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs index 04932ecdbb..5985ec9b68 100644 --- a/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs +++ b/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs @@ -27,6 +27,11 @@ namespace osu.Game.Rulesets.Catch.Objects set => x = value; } + /// + /// Whether this object can be placed on the catcher's plate. + /// + public virtual bool CanBePlated => false; + /// /// A random offset applied to , set by the . /// @@ -100,6 +105,14 @@ namespace osu.Game.Rulesets.Catch.Objects protected override HitWindows CreateHitWindows() => HitWindows.Empty; } + /// + /// Represents a single object that can be caught by the catcher. + /// + public abstract class PalpableCatchHitObject : CatchHitObject + { + public override bool CanBePlated => true; + } + public enum FruitVisualRepresentation { Pear, diff --git a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableCatchHitObject.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableCatchHitObject.cs index 883d2048ed..2fe017dc62 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableCatchHitObject.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableCatchHitObject.cs @@ -16,10 +16,8 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Catch.Objects.Drawables { public abstract class PalpableDrawableCatchHitObject : DrawableCatchHitObject - where TObject : CatchHitObject + where TObject : PalpableCatchHitObject { - public override bool CanBePlated => true; - protected Container ScaleContainer { get; private set; } protected PalpableDrawableCatchHitObject(TObject hitObject) @@ -65,9 +63,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables public abstract class DrawableCatchHitObject : DrawableHitObject { - public virtual bool CanBePlated => false; - - public virtual bool StaysOnPlate => CanBePlated; + public virtual bool StaysOnPlate => HitObject.CanBePlated; public float DisplayRadius => DrawSize.X / 2 * Scale.X * HitObject.Scale; diff --git a/osu.Game.Rulesets.Catch/Objects/Droplet.cs b/osu.Game.Rulesets.Catch/Objects/Droplet.cs index 7b0bb3f0ae..9c1004a04b 100644 --- a/osu.Game.Rulesets.Catch/Objects/Droplet.cs +++ b/osu.Game.Rulesets.Catch/Objects/Droplet.cs @@ -6,7 +6,7 @@ using osu.Game.Rulesets.Judgements; namespace osu.Game.Rulesets.Catch.Objects { - public class Droplet : CatchHitObject + public class Droplet : PalpableCatchHitObject { public override Judgement CreateJudgement() => new CatchDropletJudgement(); } diff --git a/osu.Game.Rulesets.Catch/Objects/Fruit.cs b/osu.Game.Rulesets.Catch/Objects/Fruit.cs index 6f0423b420..43486796ad 100644 --- a/osu.Game.Rulesets.Catch/Objects/Fruit.cs +++ b/osu.Game.Rulesets.Catch/Objects/Fruit.cs @@ -6,7 +6,7 @@ using osu.Game.Rulesets.Judgements; namespace osu.Game.Rulesets.Catch.Objects { - public class Fruit : CatchHitObject + public class Fruit : PalpableCatchHitObject { public override Judgement CreateJudgement() => new CatchJudgement(); } diff --git a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs index 4255c3b1af..03ebf01b9b 100644 --- a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs +++ b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs @@ -55,7 +55,7 @@ namespace osu.Game.Rulesets.Catch.UI lastPlateableFruit.OnLoadComplete += _ => action(); } - if (result.IsHit && fruit.CanBePlated) + if (result.IsHit && fruit.HitObject.CanBePlated) { // create a new (cloned) fruit to stay on the plate. the original is faded out immediately. var caughtFruit = (DrawableCatchHitObject)CreateDrawableRepresentation?.Invoke(fruit.HitObject); From 9546fbb64bf823392b92333238ed1cf560c6fcae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Thu, 20 Aug 2020 18:58:07 +0200 Subject: [PATCH 247/434] Prevent catcher from performing invalid catches --- osu.Game.Rulesets.Catch/UI/Catcher.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/osu.Game.Rulesets.Catch/UI/Catcher.cs b/osu.Game.Rulesets.Catch/UI/Catcher.cs index 8820dff730..e4a3c01dbc 100644 --- a/osu.Game.Rulesets.Catch/UI/Catcher.cs +++ b/osu.Game.Rulesets.Catch/UI/Catcher.cs @@ -216,6 +216,9 @@ namespace osu.Game.Rulesets.Catch.UI /// Whether the catch is possible. public bool AttemptCatch(CatchHitObject fruit) { + if (!fruit.CanBePlated) + return false; + var halfCatchWidth = catchWidth * 0.5f; // this stuff wil disappear once we move fruit to non-relative coordinate space in the future. From 738ff7ba217e1db02c5f9232076a61b8438a2229 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 21 Aug 2020 02:21:16 +0900 Subject: [PATCH 248/434] Use full catcher width for hyperdash calculation --- osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs | 6 ++++++ osu.Game.Rulesets.Catch/UI/Catcher.cs | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs index 15e6e98f5a..a08c5b6fb1 100644 --- a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs +++ b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs @@ -212,6 +212,12 @@ namespace osu.Game.Rulesets.Catch.Beatmaps objectWithDroplets.Sort((h1, h2) => h1.StartTime.CompareTo(h2.StartTime)); double halfCatcherWidth = Catcher.CalculateCatchWidth(beatmap.BeatmapInfo.BaseDifficulty) / 2; + + // Todo: This is wrong. osu!stable calculated hyperdashes using the full catcher size, excluding the margins. + // This should theoretically cause impossible scenarios, but practically, likely due to the size of the playfield, it doesn't seem possible. + // For now, to bring gameplay (and diffcalc!) completely in-line with stable, this code also uses the full catcher size. + halfCatcherWidth /= Catcher.ALLOWED_CATCH_RANGE; + int lastDirection = 0; double lastExcess = halfCatcherWidth; diff --git a/osu.Game.Rulesets.Catch/UI/Catcher.cs b/osu.Game.Rulesets.Catch/UI/Catcher.cs index 8820dff730..11e69678ca 100644 --- a/osu.Game.Rulesets.Catch/UI/Catcher.cs +++ b/osu.Game.Rulesets.Catch/UI/Catcher.cs @@ -64,7 +64,7 @@ namespace osu.Game.Rulesets.Catch.UI /// /// The width of the catcher which can receive fruit. Equivalent to "catchMargin" in osu-stable. /// - private const float allowed_catch_range = 0.8f; + public const float ALLOWED_CATCH_RANGE = 0.8f; /// /// The drawable catcher for . @@ -166,7 +166,7 @@ namespace osu.Game.Rulesets.Catch.UI /// /// The scale of the catcher. internal static float CalculateCatchWidth(Vector2 scale) - => CatcherArea.CATCHER_SIZE * Math.Abs(scale.X) * allowed_catch_range; + => CatcherArea.CATCHER_SIZE * Math.Abs(scale.X) * ALLOWED_CATCH_RANGE; /// /// Calculates the width of the area used for attempting catches in gameplay. From bd4acdce789776c1252c7f60604296b6ae63bd9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Thu, 20 Aug 2020 21:01:58 +0200 Subject: [PATCH 249/434] Add until step to ensure failure --- osu.Game.Tests/Visual/Multiplayer/TestSceneMultiScreen.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiScreen.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiScreen.cs index 61859c9da3..dbf5b98e52 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiScreen.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiScreen.cs @@ -14,7 +14,8 @@ namespace osu.Game.Tests.Visual.Multiplayer { Screens.Multi.Multiplayer multi = new Screens.Multi.Multiplayer(); - AddStep(@"show", () => LoadScreen(multi)); + AddStep("show", () => LoadScreen(multi)); + AddUntilStep("wait for loaded", () => multi.IsLoaded); } } } From dcce7a213052cc16b49196c3c3441c38ee4f9809 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Thu, 20 Aug 2020 21:03:27 +0200 Subject: [PATCH 250/434] Cache local music controller to resolve failure --- osu.Game.Tests/Visual/Multiplayer/TestSceneMultiScreen.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiScreen.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiScreen.cs index dbf5b98e52..3924b0333f 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiScreen.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiScreen.cs @@ -2,6 +2,8 @@ // See the LICENCE file in the repository root for full licence text. using NUnit.Framework; +using osu.Framework.Allocation; +using osu.Game.Overlays; namespace osu.Game.Tests.Visual.Multiplayer { @@ -10,6 +12,9 @@ namespace osu.Game.Tests.Visual.Multiplayer { protected override bool UseOnlineAPI => true; + [Cached] + private MusicController musicController { get; set; } = new MusicController(); + public TestSceneMultiScreen() { Screens.Multi.Multiplayer multi = new Screens.Multi.Multiplayer(); From f00bc67aaa0852e9ed77f83eced4bcaeb9ebd35a Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 21 Aug 2020 12:29:28 +0900 Subject: [PATCH 251/434] Fix pulp and use relative sizse --- osu.Game.Rulesets.Catch/Objects/Drawables/DropletPiece.cs | 3 +-- osu.Game.Rulesets.Catch/Objects/Drawables/Pieces/Pulp.cs | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Objects/Drawables/DropletPiece.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/DropletPiece.cs index d6c9f4398f..c2499446fa 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawables/DropletPiece.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawables/DropletPiece.cs @@ -27,8 +27,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables InternalChild = new Pulp { - // RelativeSizeAxes is not used since the edge effect uses Size. - Size = Size, + RelativeSizeAxes = Axes.Both, AccentColour = { BindTarget = drawableObject.AccentColour } }; diff --git a/osu.Game.Rulesets.Catch/Objects/Drawables/Pieces/Pulp.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/Pieces/Pulp.cs index 1e7506a257..d3e4945611 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawables/Pieces/Pulp.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawables/Pieces/Pulp.cs @@ -36,7 +36,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables.Pieces EdgeEffect = new EdgeEffectParameters { Type = EdgeEffectType.Glow, - Radius = Size.X / 2, + Radius = DrawWidth / 2, Colour = colour.NewValue.Darken(0.2f).Opacity(0.75f) }; } From dd1f2db1752be453e14964d6b47f87aa04e8a611 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 21 Aug 2020 12:30:33 +0900 Subject: [PATCH 252/434] Use startTime in test --- osu.Game.Rulesets.Catch.Tests/TestSceneHyperDash.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneHyperDash.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneHyperDash.cs index 1aa333c401..6dab2a0b56 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneHyperDash.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneHyperDash.cs @@ -68,7 +68,7 @@ namespace osu.Game.Rulesets.Catch.Tests createObjects(() => new Fruit { X = right_x }); createObjects(() => new TestJuiceStream(left_x), 1); - beatmap.ControlPointInfo.Add(7900, new TimingControlPoint + beatmap.ControlPointInfo.Add(startTime, new TimingControlPoint { BeatLength = 50 }); From 6ad7a3686b011c35cb17e6bfa8d0303e1cf9fc78 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 21 Aug 2020 13:13:08 +0900 Subject: [PATCH 253/434] Simplify condition --- osu.Game.Rulesets.Catch/UI/Catcher.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Catch/UI/Catcher.cs b/osu.Game.Rulesets.Catch/UI/Catcher.cs index 7fffa1fdc3..8e74437834 100644 --- a/osu.Game.Rulesets.Catch/UI/Catcher.cs +++ b/osu.Game.Rulesets.Catch/UI/Catcher.cs @@ -229,8 +229,8 @@ namespace osu.Game.Rulesets.Catch.UI catchObjectPosition >= catcherPosition - halfCatchWidth && catchObjectPosition <= catcherPosition + halfCatchWidth; - // only update hyperdash state if we are catching a fruit or a droplet (and not a tiny droplet). - if (!(fruit is Fruit || fruit is Droplet) || fruit is TinyDroplet) return validCatch; + // only update hyperdash state if we are catching not catching a tiny droplet. + if (fruit is TinyDroplet) return validCatch; if (validCatch && fruit.HyperDash) { From 62d833d63d93690d5a40162d09d2ee763858c4cd Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 21 Aug 2020 13:14:50 +0900 Subject: [PATCH 254/434] Fix comment --- osu.Game.Rulesets.Catch/UI/Catcher.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Catch/UI/Catcher.cs b/osu.Game.Rulesets.Catch/UI/Catcher.cs index 8e74437834..952ff6b0ce 100644 --- a/osu.Game.Rulesets.Catch/UI/Catcher.cs +++ b/osu.Game.Rulesets.Catch/UI/Catcher.cs @@ -229,7 +229,7 @@ namespace osu.Game.Rulesets.Catch.UI catchObjectPosition >= catcherPosition - halfCatchWidth && catchObjectPosition <= catcherPosition + halfCatchWidth; - // only update hyperdash state if we are catching not catching a tiny droplet. + // only update hyperdash state if we are not catching a tiny droplet. if (fruit is TinyDroplet) return validCatch; if (validCatch && fruit.HyperDash) From 526f06be4c714410061a732dfb041c84c3c45f0d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 21 Aug 2020 13:53:12 +0900 Subject: [PATCH 255/434] Add back track loaded bool in WorkingBeatmap --- osu.Game/Beatmaps/WorkingBeatmap.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/WorkingBeatmap.cs b/osu.Game/Beatmaps/WorkingBeatmap.cs index 051d66af7b..8d5543cadb 100644 --- a/osu.Game/Beatmaps/WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/WorkingBeatmap.cs @@ -275,6 +275,11 @@ namespace osu.Game.Beatmaps /// The track to transfer. public void TransferTrack([NotNull] Track track) => loadedTrack = track ?? throw new ArgumentNullException(nameof(track)); + /// + /// Whether this beatmap's track has been loaded via . + /// + public bool TrackLoaded => loadedTrack != null; + /// /// Get the loaded audio track instance. must have first been called. /// This generally happens via MusicController when changing the global beatmap. @@ -283,7 +288,7 @@ namespace osu.Game.Beatmaps { get { - if (loadedTrack == null) + if (!TrackLoaded) throw new InvalidOperationException($"Cannot access {nameof(Track)} without first calling {nameof(LoadTrack)}."); return loadedTrack; From 0b0ff626477a611a161ece951ffb9f0682dd8a44 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 21 Aug 2020 14:46:23 +0900 Subject: [PATCH 256/434] Switch timeline to use track directly from beatmap again --- .../Compose/Components/Timeline/Timeline.cs | 49 ++++++++++--------- 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs index e1702d3eff..96c48c0ddc 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs @@ -30,6 +30,28 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline [Resolved] private MusicController musicController { get; set; } + /// + /// The timeline's scroll position in the last frame. + /// + private float lastScrollPosition; + + /// + /// The track time in the last frame. + /// + private double lastTrackTime; + + /// + /// Whether the user is currently dragging the timeline. + /// + private bool handlingDragInput; + + /// + /// Whether the track was playing before a user drag event. + /// + private bool trackWasPlaying; + + private ITrack track; + public Timeline() { ZoomDuration = 200; @@ -61,9 +83,10 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline Beatmap.BindValueChanged(b => { waveform.Waveform = b.NewValue.Waveform; - track = musicController.CurrentTrack; + track = b.NewValue.Track; - if (track.Length > 0) + // todo: i don't think this is safe, the track may not be loaded yet. + if (b.NewValue.Track.Length > 0) { MaxZoom = getZoomLevelForVisibleMilliseconds(500); MinZoom = getZoomLevelForVisibleMilliseconds(10000); @@ -74,28 +97,6 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline private float getZoomLevelForVisibleMilliseconds(double milliseconds) => (float)(track.Length / milliseconds); - /// - /// The timeline's scroll position in the last frame. - /// - private float lastScrollPosition; - - /// - /// The track time in the last frame. - /// - private double lastTrackTime; - - /// - /// Whether the user is currently dragging the timeline. - /// - private bool handlingDragInput; - - /// - /// Whether the track was playing before a user drag event. - /// - private bool trackWasPlaying; - - private ITrack track; - protected override void Update() { base.Update(); From d2c2e8bbe89536f5fed2a35ea35aa514029ac28d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 21 Aug 2020 15:05:56 +0900 Subject: [PATCH 257/434] Revert some more usage of MusicController back to WorkingBeatmap --- .../TestSceneHoldNoteInput.cs | 2 +- osu.Game.Rulesets.Osu.Tests/TestSceneOutOfOrderHits.cs | 2 +- osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs | 2 +- .../Skinning/TestSceneDrawableTaikoMascot.cs | 4 ++-- .../Skinning/TestSceneTaikoPlayfield.cs | 2 +- osu.Game.Tests/Skins/TestSceneBeatmapSkinResources.cs | 10 +++++++--- osu.Game/Beatmaps/WorkingBeatmap.cs | 2 +- osu.Game/Tests/Beatmaps/TestWorkingBeatmap.cs | 2 ++ osu.Game/Tests/Visual/RateAdjustedBeatmapTestScene.cs | 3 +-- 9 files changed, 17 insertions(+), 12 deletions(-) diff --git a/osu.Game.Rulesets.Mania.Tests/TestSceneHoldNoteInput.cs b/osu.Game.Rulesets.Mania.Tests/TestSceneHoldNoteInput.cs index 19b69bac6d..95072cf4f8 100644 --- a/osu.Game.Rulesets.Mania.Tests/TestSceneHoldNoteInput.cs +++ b/osu.Game.Rulesets.Mania.Tests/TestSceneHoldNoteInput.cs @@ -343,7 +343,7 @@ namespace osu.Game.Rulesets.Mania.Tests judgementResults = new List(); }); - AddUntilStep("Beatmap at 0", () => MusicController.CurrentTrack.CurrentTime == 0); + AddUntilStep("Beatmap at 0", () => Beatmap.Value.Track.CurrentTime == 0); AddUntilStep("Wait until player is loaded", () => currentPlayer.IsCurrentScreen()); AddUntilStep("Wait for completion", () => currentPlayer.ScoreProcessor.HasCompleted.Value); } diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneOutOfOrderHits.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneOutOfOrderHits.cs index 744ad46c28..854626d362 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneOutOfOrderHits.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneOutOfOrderHits.cs @@ -385,7 +385,7 @@ namespace osu.Game.Rulesets.Osu.Tests judgementResults = new List(); }); - AddUntilStep("Beatmap at 0", () => MusicController.CurrentTrack.CurrentTime == 0); + AddUntilStep("Beatmap at 0", () => Beatmap.Value.Track.CurrentTime == 0); AddUntilStep("Wait until player is loaded", () => currentPlayer.IsCurrentScreen()); AddUntilStep("Wait for completion", () => currentPlayer.ScoreProcessor.HasCompleted.Value); } diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs index 1690f648f9..b543b6fa94 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs @@ -366,7 +366,7 @@ namespace osu.Game.Rulesets.Osu.Tests judgementResults = new List(); }); - AddUntilStep("Beatmap at 0", () => MusicController.CurrentTrack.CurrentTime == 0); + AddUntilStep("Beatmap at 0", () => Beatmap.Value.Track.CurrentTime == 0); AddUntilStep("Wait until player is loaded", () => currentPlayer.IsCurrentScreen()); AddUntilStep("Wait for completion", () => currentPlayer.ScoreProcessor.HasCompleted.Value); } diff --git a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableTaikoMascot.cs b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableTaikoMascot.cs index 6141bf062e..47d8a5c012 100644 --- a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableTaikoMascot.cs +++ b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableTaikoMascot.cs @@ -175,11 +175,11 @@ namespace osu.Game.Rulesets.Taiko.Tests.Skinning private void createDrawableRuleset() { - AddUntilStep("wait for beatmap to be loaded", () => MusicController.CurrentTrack.TrackLoaded); + AddUntilStep("wait for beatmap to be loaded", () => Beatmap.Value.Track.IsLoaded); AddStep("create drawable ruleset", () => { - MusicController.CurrentTrack.Start(); + Beatmap.Value.Track.Start(); SetContents(() => { diff --git a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneTaikoPlayfield.cs b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneTaikoPlayfield.cs index a3d3bc81c4..7b7e2c43d1 100644 --- a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneTaikoPlayfield.cs +++ b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneTaikoPlayfield.cs @@ -34,7 +34,7 @@ namespace osu.Game.Rulesets.Taiko.Tests.Skinning beatmap.ControlPointInfo.Add(0, new TimingControlPoint { BeatLength = 1000 }); - MusicController.CurrentTrack.Start(); + Beatmap.Value.Track.Start(); }); AddStep("Load playfield", () => SetContents(() => new TaikoPlayfield(new ControlPointInfo()) diff --git a/osu.Game.Tests/Skins/TestSceneBeatmapSkinResources.cs b/osu.Game.Tests/Skins/TestSceneBeatmapSkinResources.cs index 49b40daf99..eff430ac25 100644 --- a/osu.Game.Tests/Skins/TestSceneBeatmapSkinResources.cs +++ b/osu.Game.Tests/Skins/TestSceneBeatmapSkinResources.cs @@ -3,6 +3,7 @@ using NUnit.Framework; using osu.Framework.Allocation; +using osu.Framework.Audio.Track; using osu.Framework.Testing; using osu.Game.Audio; using osu.Game.Beatmaps; @@ -18,17 +19,20 @@ namespace osu.Game.Tests.Skins [Resolved] private BeatmapManager beatmaps { get; set; } + private WorkingBeatmap beatmap; + [BackgroundDependencyLoader] private void load() { var imported = beatmaps.Import(new ZipArchiveReader(TestResources.OpenResource("Archives/ogg-beatmap.osz"))).Result; - Beatmap.Value = beatmaps.GetWorkingBeatmap(imported.Beatmaps[0]); + beatmap = beatmaps.GetWorkingBeatmap(imported.Beatmaps[0]); + beatmap.LoadTrack(); } [Test] - public void TestRetrieveOggSample() => AddAssert("sample is non-null", () => Beatmap.Value.Skin.GetSample(new SampleInfo("sample")) != null); + public void TestRetrieveOggSample() => AddAssert("sample is non-null", () => beatmap.Skin.GetSample(new SampleInfo("sample")) != null); [Test] - public void TestRetrieveOggTrack() => AddAssert("track is non-null", () => !MusicController.CurrentTrack.IsDummyDevice); + public void TestRetrieveOggTrack() => AddAssert("track is non-null", () => !(beatmap.Track is TrackVirtual)); } } diff --git a/osu.Game/Beatmaps/WorkingBeatmap.cs b/osu.Game/Beatmaps/WorkingBeatmap.cs index 8d5543cadb..6a89739e6f 100644 --- a/osu.Game/Beatmaps/WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/WorkingBeatmap.cs @@ -278,7 +278,7 @@ namespace osu.Game.Beatmaps /// /// Whether this beatmap's track has been loaded via . /// - public bool TrackLoaded => loadedTrack != null; + public virtual bool TrackLoaded => loadedTrack != null; /// /// Get the loaded audio track instance. must have first been called. diff --git a/osu.Game/Tests/Beatmaps/TestWorkingBeatmap.cs b/osu.Game/Tests/Beatmaps/TestWorkingBeatmap.cs index d091da3206..bfcb2403c1 100644 --- a/osu.Game/Tests/Beatmaps/TestWorkingBeatmap.cs +++ b/osu.Game/Tests/Beatmaps/TestWorkingBeatmap.cs @@ -27,6 +27,8 @@ namespace osu.Game.Tests.Beatmaps this.storyboard = storyboard; } + public override bool TrackLoaded => true; + public override bool BeatmapLoaded => true; protected override IBeatmap GetBeatmap() => beatmap; diff --git a/osu.Game/Tests/Visual/RateAdjustedBeatmapTestScene.cs b/osu.Game/Tests/Visual/RateAdjustedBeatmapTestScene.cs index 7651285970..ad24ffc7b8 100644 --- a/osu.Game/Tests/Visual/RateAdjustedBeatmapTestScene.cs +++ b/osu.Game/Tests/Visual/RateAdjustedBeatmapTestScene.cs @@ -13,8 +13,7 @@ namespace osu.Game.Tests.Visual base.Update(); // note that this will override any mod rate application - if (MusicController.TrackLoaded) - MusicController.CurrentTrack.Tempo.Value = Clock.Rate; + Beatmap.Value.Track.Tempo.Value = Clock.Rate; } } } From f7e4feee3449630475a11a2291803997fb23e029 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 21 Aug 2020 15:25:57 +0900 Subject: [PATCH 258/434] Update remaining Player components to use WorkingBeatmap again --- osu.Game/Screens/Play/FailAnimation.cs | 13 ++++++------- osu.Game/Screens/Play/Player.cs | 8 ++++---- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/osu.Game/Screens/Play/FailAnimation.cs b/osu.Game/Screens/Play/FailAnimation.cs index dade904180..54c644c999 100644 --- a/osu.Game/Screens/Play/FailAnimation.cs +++ b/osu.Game/Screens/Play/FailAnimation.cs @@ -6,12 +6,12 @@ using osu.Framework.Bindables; using osu.Game.Rulesets.UI; using System; using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; using osu.Framework.Allocation; using osu.Framework.Audio.Sample; using osu.Framework.Audio.Track; using osu.Framework.Graphics; using osu.Framework.Utils; +using osu.Game.Beatmaps; using osu.Game.Rulesets.Objects.Drawables; using osuTK; using osuTK.Graphics; @@ -28,24 +28,23 @@ namespace osu.Game.Screens.Play private readonly DrawableRuleset drawableRuleset; - [NotNull] - private readonly ITrack track; - private readonly BindableDouble trackFreq = new BindableDouble(1); + private Track track; + private const float duration = 2500; private SampleChannel failSample; - public FailAnimation(DrawableRuleset drawableRuleset, [NotNull] ITrack track) + public FailAnimation(DrawableRuleset drawableRuleset) { this.drawableRuleset = drawableRuleset; - this.track = track; } [BackgroundDependencyLoader] - private void load(AudioManager audio) + private void load(AudioManager audio, IBindable beatmap) { + track = beatmap.Value.Track; failSample = audio.Samples.Get(@"Gameplay/failsound"); } diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index cc70995b26..a8fda10604 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -151,7 +151,7 @@ namespace osu.Game.Screens.Play } [BackgroundDependencyLoader] - private void load(AudioManager audio, OsuConfigManager config, MusicController musicController) + private void load(AudioManager audio, OsuConfigManager config) { Mods.Value = base.Mods.Value.Select(m => m.CreateCopy()).ToArray(); @@ -188,7 +188,7 @@ namespace osu.Game.Screens.Play addUnderlayComponents(GameplayClockContainer); addGameplayComponents(GameplayClockContainer, Beatmap.Value, playableBeatmap); - addOverlayComponents(GameplayClockContainer, Beatmap.Value, musicController.CurrentTrack); + addOverlayComponents(GameplayClockContainer, Beatmap.Value); if (!DrawableRuleset.AllowGameplayOverlays) { @@ -265,7 +265,7 @@ namespace osu.Game.Screens.Play }); } - private void addOverlayComponents(Container target, WorkingBeatmap working, ITrack track) + private void addOverlayComponents(Container target, WorkingBeatmap working) { target.AddRange(new[] { @@ -332,7 +332,7 @@ namespace osu.Game.Screens.Play performImmediateExit(); }, }, - failAnimation = new FailAnimation(DrawableRuleset, track) { OnComplete = onFailComplete, }, + failAnimation = new FailAnimation(DrawableRuleset) { OnComplete = onFailComplete, }, }); } From 0ae460fb8f4e7b9c235ce0cb27ae933157d162c6 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 21 Aug 2020 15:50:14 +0900 Subject: [PATCH 259/434] Avoid beatmap load call in IntroScreen --- osu.Game.Tests/Visual/Menus/TestSceneIntroWelcome.cs | 3 ++- osu.Game/Screens/Menu/IntroScreen.cs | 3 ++- osu.Game/Screens/Menu/IntroTriangles.cs | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/osu.Game.Tests/Visual/Menus/TestSceneIntroWelcome.cs b/osu.Game.Tests/Visual/Menus/TestSceneIntroWelcome.cs index 29be250b12..5f135febf4 100644 --- a/osu.Game.Tests/Visual/Menus/TestSceneIntroWelcome.cs +++ b/osu.Game.Tests/Visual/Menus/TestSceneIntroWelcome.cs @@ -3,6 +3,7 @@ using NUnit.Framework; using osu.Framework.Screens; +using osu.Framework.Utils; using osu.Game.Screens.Menu; namespace osu.Game.Tests.Visual.Menus @@ -15,7 +16,7 @@ namespace osu.Game.Tests.Visual.Menus public TestSceneIntroWelcome() { AddUntilStep("wait for load", () => MusicController.TrackLoaded); - + AddAssert("correct track", () => Precision.AlmostEquals(MusicController.CurrentTrack.Length, 48000, 1)); AddAssert("check if menu music loops", () => MusicController.CurrentTrack.Looping); } } diff --git a/osu.Game/Screens/Menu/IntroScreen.cs b/osu.Game/Screens/Menu/IntroScreen.cs index 3e4320ae44..363933694d 100644 --- a/osu.Game/Screens/Menu/IntroScreen.cs +++ b/osu.Game/Screens/Menu/IntroScreen.cs @@ -66,6 +66,7 @@ namespace osu.Game.Screens.Menu /// /// Whether the is provided by osu! resources, rather than a user beatmap. + /// Only valid during or after . /// protected bool UsingThemedIntro { get; private set; } @@ -115,7 +116,6 @@ namespace osu.Game.Screens.Menu if (setInfo != null) { initialBeatmap = beatmaps.GetWorkingBeatmap(setInfo.Beatmaps[0]); - UsingThemedIntro = !initialBeatmap.LoadTrack().IsDummyDevice; } return UsingThemedIntro; @@ -169,6 +169,7 @@ namespace osu.Game.Screens.Menu { beatmap.Value = initialBeatmap; Track = musicController.CurrentTrack; + UsingThemedIntro = !initialBeatmap.LoadTrack().IsDummyDevice; logo.MoveTo(new Vector2(0.5f)); logo.ScaleTo(Vector2.One); diff --git a/osu.Game/Screens/Menu/IntroTriangles.cs b/osu.Game/Screens/Menu/IntroTriangles.cs index a9ef20436f..52281967ee 100644 --- a/osu.Game/Screens/Menu/IntroTriangles.cs +++ b/osu.Game/Screens/Menu/IntroTriangles.cs @@ -44,7 +44,7 @@ namespace osu.Game.Screens.Menu [BackgroundDependencyLoader] private void load() { - if (MenuVoice.Value && !UsingThemedIntro) + if (MenuVoice.Value) welcome = audio.Samples.Get(@"Intro/welcome"); } From 3b03116179c3e0ec88b815dd2bcfc32961058510 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 21 Aug 2020 16:45:59 +0900 Subject: [PATCH 260/434] Remove unnecessary using statement --- osu.Game/Screens/Play/Player.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index a8fda10604..9be4fd6a65 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -8,7 +8,6 @@ using System.Linq; using osu.Framework.Allocation; using osu.Framework.Audio; using osu.Framework.Audio.Sample; -using osu.Framework.Audio.Track; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; From 70697cf1a0e36e57b3533613a5795bdb8722a746 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 21 Aug 2020 16:58:45 +0900 Subject: [PATCH 261/434] Restore remaining editor components to use Beatmap.Track --- osu.Game.Tests/Visual/Editing/TimelineTestScene.cs | 11 ++++++----- .../Screens/Edit/Components/BottomBarContainer.cs | 2 ++ osu.Game/Screens/Edit/Components/PlaybackControl.cs | 8 ++------ .../Timelines/Summary/Parts/TimelinePart.cs | 8 ++------ .../Edit/Compose/Components/Timeline/Timeline.cs | 6 +++--- .../Components/Timeline/TimelineTickDisplay.cs | 7 ++++--- osu.Game/Screens/Edit/Editor.cs | 10 ++++------ osu.Game/Screens/Edit/EditorClock.cs | 10 +++++----- osu.Game/Tests/Visual/EditorClockTestScene.cs | 3 ++- 9 files changed, 30 insertions(+), 35 deletions(-) diff --git a/osu.Game.Tests/Visual/Editing/TimelineTestScene.cs b/osu.Game.Tests/Visual/Editing/TimelineTestScene.cs index 4988a09650..fdb8781563 100644 --- a/osu.Game.Tests/Visual/Editing/TimelineTestScene.cs +++ b/osu.Game.Tests/Visual/Editing/TimelineTestScene.cs @@ -3,11 +3,12 @@ using osu.Framework.Allocation; using osu.Framework.Audio; +using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; +using osu.Game.Beatmaps; using osu.Game.Graphics.UserInterface; -using osu.Game.Overlays; using osu.Game.Rulesets.Edit; using osu.Game.Screens.Edit; using osu.Game.Screens.Edit.Compose.Components.Timeline; @@ -64,10 +65,10 @@ namespace osu.Game.Tests.Visual.Editing private readonly Drawable marker; [Resolved] - private EditorClock editorClock { get; set; } + private IBindable beatmap { get; set; } [Resolved] - private MusicController musicController { get; set; } + private EditorClock editorClock { get; set; } public AudioVisualiser() { @@ -93,8 +94,8 @@ namespace osu.Game.Tests.Visual.Editing { base.Update(); - if (musicController.TrackLoaded) - marker.X = (float)(editorClock.CurrentTime / musicController.CurrentTrack.Length); + if (beatmap.Value.Track.IsLoaded) + marker.X = (float)(editorClock.CurrentTime / beatmap.Value.Track.Length); } } diff --git a/osu.Game/Screens/Edit/Components/BottomBarContainer.cs b/osu.Game/Screens/Edit/Components/BottomBarContainer.cs index 8d8c59b2ee..cb5078a479 100644 --- a/osu.Game/Screens/Edit/Components/BottomBarContainer.cs +++ b/osu.Game/Screens/Edit/Components/BottomBarContainer.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Allocation; +using osu.Framework.Audio.Track; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -17,6 +18,7 @@ namespace osu.Game.Screens.Edit.Components private const float contents_padding = 15; protected readonly IBindable Beatmap = new Bindable(); + protected Track Track => Beatmap.Value.Track; private readonly Drawable background; private readonly Container content; diff --git a/osu.Game/Screens/Edit/Components/PlaybackControl.cs b/osu.Game/Screens/Edit/Components/PlaybackControl.cs index 5bafc120af..59b3d1c565 100644 --- a/osu.Game/Screens/Edit/Components/PlaybackControl.cs +++ b/osu.Game/Screens/Edit/Components/PlaybackControl.cs @@ -16,7 +16,6 @@ using osu.Framework.Input.Events; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; -using osu.Game.Overlays; using osuTK.Input; namespace osu.Game.Screens.Edit.Components @@ -28,9 +27,6 @@ namespace osu.Game.Screens.Edit.Components [Resolved] private EditorClock editorClock { get; set; } - [Resolved] - private MusicController musicController { get; set; } - private readonly BindableNumber tempo = new BindableDouble(1); [BackgroundDependencyLoader] @@ -66,12 +62,12 @@ namespace osu.Game.Screens.Edit.Components } }; - musicController.CurrentTrack.AddAdjustment(AdjustableProperty.Tempo, tempo); + Track?.AddAdjustment(AdjustableProperty.Tempo, tempo); } protected override void Dispose(bool isDisposing) { - musicController?.CurrentTrack.RemoveAdjustment(AdjustableProperty.Tempo, tempo); + Track?.RemoveAdjustment(AdjustableProperty.Tempo, tempo); base.Dispose(isDisposing); } diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs index c8a470c58a..4a7c3f26bc 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs @@ -8,7 +8,6 @@ using osuTK; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Beatmaps; -using osu.Game.Overlays; namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts { @@ -27,9 +26,6 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts protected override Container Content => content; - [Resolved] - private MusicController musicController { get; set; } - public TimelinePart(Container content = null) { AddInternal(this.content = content ?? new Container { RelativeSizeAxes = Axes.Both }); @@ -50,14 +46,14 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts private void updateRelativeChildSize() { // the track may not be loaded completely (only has a length once it is). - if (!musicController.TrackLoaded) + if (!Beatmap.Value.Track.IsLoaded) { content.RelativeChildSize = Vector2.One; Schedule(updateRelativeChildSize); return; } - content.RelativeChildSize = new Vector2((float)Math.Max(1, musicController.CurrentTrack.Length), 1); + content.RelativeChildSize = new Vector2((float)Math.Max(1, Beatmap.Value.Track.Length), 1); } protected virtual void LoadBeatmap(WorkingBeatmap beatmap) diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs index 96c48c0ddc..c6bfdda698 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs @@ -50,7 +50,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline /// private bool trackWasPlaying; - private ITrack track; + private Track track; public Timeline() { @@ -134,7 +134,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline private void seekTrackToCurrent() { - if (!musicController.TrackLoaded) + if (!track.IsLoaded) return; editorClock.Seek(Current / Content.DrawWidth * track.Length); @@ -142,7 +142,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline private void scrollToTrackTime() { - if (!musicController.TrackLoaded || track.Length == 0) + if (!track.IsLoaded || track.Length == 0) return; ScrollTo((float)(editorClock.CurrentTime / track.Length) * Content.DrawWidth, false); diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineTickDisplay.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineTickDisplay.cs index cb122c590e..36ee976bf7 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineTickDisplay.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineTickDisplay.cs @@ -3,9 +3,10 @@ using System.Linq; using osu.Framework.Allocation; +using osu.Framework.Bindables; using osu.Framework.Graphics; +using osu.Game.Beatmaps; using osu.Game.Graphics; -using osu.Game.Overlays; using osu.Game.Screens.Edit.Components.Timelines.Summary.Parts; using osu.Game.Screens.Edit.Components.Timelines.Summary.Visualisations; @@ -17,7 +18,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline private EditorBeatmap beatmap { get; set; } [Resolved] - private MusicController musicController { get; set; } + private Bindable working { get; set; } [Resolved] private BindableBeatDivisor beatDivisor { get; set; } @@ -43,7 +44,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline for (var i = 0; i < beatmap.ControlPointInfo.TimingPoints.Count; i++) { var point = beatmap.ControlPointInfo.TimingPoints[i]; - var until = i + 1 < beatmap.ControlPointInfo.TimingPoints.Count ? beatmap.ControlPointInfo.TimingPoints[i + 1].Time : musicController.CurrentTrack.Length; + var until = i + 1 < beatmap.ControlPointInfo.TimingPoints.Count ? beatmap.ControlPointInfo.TimingPoints[i + 1].Time : working.Value.Track.Length; int beat = 0; diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index 6722d9179c..d92f3922c3 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -14,6 +14,7 @@ using osu.Framework.Bindables; using osu.Framework.Graphics.UserInterface; using osu.Framework.Input.Events; using osu.Framework.Platform; +using osu.Framework.Timing; using osu.Game.Graphics.UserInterface; using osu.Game.Screens.Edit.Components; using osu.Game.Screens.Edit.Components.Menus; @@ -27,7 +28,6 @@ using osu.Framework.Logging; using osu.Game.Beatmaps; using osu.Game.Graphics.Cursor; using osu.Game.Input.Bindings; -using osu.Game.Overlays; using osu.Game.Rulesets.Edit; using osu.Game.Screens.Edit.Compose; using osu.Game.Screens.Edit.Setup; @@ -53,9 +53,6 @@ namespace osu.Game.Screens.Edit [Resolved] private BeatmapManager beatmapManager { get; set; } - [Resolved] - private MusicController musicController { get; set; } - private Box bottomBackground; private Container screenContainer; @@ -82,8 +79,9 @@ namespace osu.Game.Screens.Edit beatDivisor.BindValueChanged(divisor => Beatmap.Value.BeatmapInfo.BeatDivisor = divisor.NewValue); // Todo: should probably be done at a DrawableRuleset level to share logic with Player. + var sourceClock = (IAdjustableClock)Beatmap.Value.Track ?? new StopwatchClock(); clock = new EditorClock(Beatmap.Value, beatDivisor) { IsCoupled = false }; - clock.ChangeSource(musicController.CurrentTrack); + clock.ChangeSource(sourceClock); dependencies.CacheAs(clock); AddInternal(clock); @@ -348,7 +346,7 @@ namespace osu.Game.Screens.Edit private void resetTrack(bool seekToStart = false) { - musicController.CurrentTrack.Stop(); + Beatmap.Value.Track?.Stop(); if (seekToStart) { diff --git a/osu.Game/Screens/Edit/EditorClock.cs b/osu.Game/Screens/Edit/EditorClock.cs index 634a6f7e25..d4d0feb813 100644 --- a/osu.Game/Screens/Edit/EditorClock.cs +++ b/osu.Game/Screens/Edit/EditorClock.cs @@ -30,11 +30,6 @@ namespace osu.Game.Screens.Edit { } - public EditorClock() - : this(new ControlPointInfo(), 1000, new BindableBeatDivisor()) - { - } - public EditorClock(ControlPointInfo controlPointInfo, double trackLength, BindableBeatDivisor beatDivisor) { this.beatDivisor = beatDivisor; @@ -45,6 +40,11 @@ namespace osu.Game.Screens.Edit underlyingClock = new DecoupleableInterpolatingFramedClock(); } + public EditorClock() + : this(new ControlPointInfo(), 1000, new BindableBeatDivisor()) + { + } + /// /// Seek to the closest snappable beat from a time. /// diff --git a/osu.Game/Tests/Visual/EditorClockTestScene.cs b/osu.Game/Tests/Visual/EditorClockTestScene.cs index 59c9329d37..f0ec638fc9 100644 --- a/osu.Game/Tests/Visual/EditorClockTestScene.cs +++ b/osu.Game/Tests/Visual/EditorClockTestScene.cs @@ -4,6 +4,7 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Input.Events; +using osu.Framework.Timing; using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Screens.Edit; @@ -43,7 +44,7 @@ namespace osu.Game.Tests.Visual private void beatmapChanged(ValueChangedEvent e) { Clock.ControlPointInfo = e.NewValue.Beatmap.ControlPointInfo; - Clock.ChangeSource(MusicController.CurrentTrack); + Clock.ChangeSource((IAdjustableClock)e.NewValue.Track ?? new StopwatchClock()); Clock.ProcessFrame(); } From a47b8222b53a00daab14556988952824e59ec1ac Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 21 Aug 2020 16:59:11 +0900 Subject: [PATCH 262/434] Restore multiplayer to use beatmap track --- osu.Game/Screens/Multi/Multiplayer.cs | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/osu.Game/Screens/Multi/Multiplayer.cs b/osu.Game/Screens/Multi/Multiplayer.cs index 1a39d80f8d..4912df17b1 100644 --- a/osu.Game/Screens/Multi/Multiplayer.cs +++ b/osu.Game/Screens/Multi/Multiplayer.cs @@ -52,7 +52,7 @@ namespace osu.Game.Screens.Multi private readonly Bindable currentFilter = new Bindable(new FilterCriteria()); [Resolved] - private MusicController musicController { get; set; } + private MusicController music { get; set; } [Cached(Type = typeof(IRoomManager))] private RoomManager roomManager; @@ -343,10 +343,15 @@ namespace osu.Game.Screens.Multi { if (screenStack.CurrentScreen is MatchSubScreen) { - musicController.CurrentTrack.RestartPoint = Beatmap.Value.Metadata.PreviewTime; - musicController.CurrentTrack.Looping = true; + var track = Beatmap.Value?.Track; - musicController.EnsurePlayingSomething(); + if (track != null) + { + track.RestartPoint = Beatmap.Value.Metadata.PreviewTime; + track.Looping = true; + + music.EnsurePlayingSomething(); + } } else { @@ -356,8 +361,13 @@ namespace osu.Game.Screens.Multi private void cancelLooping() { - musicController.CurrentTrack.Looping = false; - musicController.CurrentTrack.RestartPoint = 0; + var track = Beatmap?.Value?.Track; + + if (track != null) + { + track.Looping = false; + track.RestartPoint = 0; + } } protected override void Dispose(bool isDisposing) From d5cbb589c2ff6fa2a8cfac96ef881d3406149ca9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 21 Aug 2020 17:21:08 +0900 Subject: [PATCH 263/434] Revert some test scene changes to use Beatmap.Track where relevant --- .../Gameplay/TestSceneCompletionCancellation.cs | 6 +++--- .../Visual/Gameplay/TestSceneGameplayRewinding.cs | 12 ++++-------- .../Gameplay/TestSceneNightcoreBeatContainer.cs | 4 ++-- osu.Game.Tests/Visual/Gameplay/TestScenePause.cs | 2 +- .../Visual/Gameplay/TestScenePlayerLoader.cs | 8 ++++---- .../Visual/Gameplay/TestSceneStoryboard.cs | 14 ++++++++++---- 6 files changed, 24 insertions(+), 22 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneCompletionCancellation.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneCompletionCancellation.cs index b39cfc3699..6fd5511e5a 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneCompletionCancellation.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneCompletionCancellation.cs @@ -31,7 +31,7 @@ namespace osu.Game.Tests.Visual.Gameplay base.SetUpSteps(); // Ensure track has actually running before attempting to seek - AddUntilStep("wait for track to start running", () => MusicController.IsPlaying); + AddUntilStep("wait for track to start running", () => Beatmap.Value.Track.IsRunning); } [Test] @@ -70,13 +70,13 @@ namespace osu.Game.Tests.Visual.Gameplay private void complete() { - AddStep("seek to completion", () => MusicController.SeekTo(5000)); + AddStep("seek to completion", () => Beatmap.Value.Track.Seek(5000)); AddUntilStep("completion set by processor", () => Player.ScoreProcessor.HasCompleted.Value); } private void cancel() { - AddStep("rewind to cancel", () => MusicController.SeekTo(4000)); + AddStep("rewind to cancel", () => Beatmap.Value.Track.Seek(4000)); AddUntilStep("completion cleared by processor", () => !Player.ScoreProcessor.HasCompleted.Value); } diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneGameplayRewinding.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneGameplayRewinding.cs index 6bdc65078a..73c6970482 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneGameplayRewinding.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneGameplayRewinding.cs @@ -8,7 +8,6 @@ using osu.Framework.Audio; using osu.Framework.Utils; using osu.Framework.Timing; using osu.Game.Beatmaps; -using osu.Game.Overlays; using osu.Game.Rulesets; using osu.Game.Rulesets.Osu.Objects; using osu.Game.Storyboards; @@ -21,16 +20,13 @@ namespace osu.Game.Tests.Visual.Gameplay [Resolved] private AudioManager audioManager { get; set; } - [Resolved] - private MusicController musicController { get; set; } - - protected override WorkingBeatmap CreateWorkingBeatmap(IBeatmap beatmap, Storyboard storyboard = null) - => new ClockBackedTestWorkingBeatmap(beatmap, storyboard, new FramedClock(new ManualClock { Rate = 1 }), audioManager); + protected override WorkingBeatmap CreateWorkingBeatmap(IBeatmap beatmap, Storyboard storyboard = null) => + new ClockBackedTestWorkingBeatmap(beatmap, storyboard, new FramedClock(new ManualClock { Rate = 1 }), audioManager); [Test] public void TestNoJudgementsOnRewind() { - AddUntilStep("wait for track to start running", () => MusicController.IsPlaying); + AddUntilStep("wait for track to start running", () => Beatmap.Value.Track.IsRunning); addSeekStep(3000); AddAssert("all judged", () => Player.DrawableRuleset.Playfield.AllHitObjects.All(h => h.Judged)); AddUntilStep("key counter counted keys", () => Player.HUDOverlay.KeyCounter.Children.All(kc => kc.CountPresses >= 7)); @@ -43,7 +39,7 @@ namespace osu.Game.Tests.Visual.Gameplay private void addSeekStep(double time) { - AddStep($"seek to {time}", () => MusicController.SeekTo(time)); + AddStep($"seek to {time}", () => Beatmap.Value.Track.Seek(time)); // Allow a few frames of lenience AddUntilStep("wait for seek to finish", () => Precision.AlmostEquals(time, Player.DrawableRuleset.FrameStableClock.CurrentTime, 100)); diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneNightcoreBeatContainer.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneNightcoreBeatContainer.cs index 53e06a632e..951ee1489d 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneNightcoreBeatContainer.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneNightcoreBeatContainer.cs @@ -19,8 +19,8 @@ namespace osu.Game.Tests.Visual.Gameplay Beatmap.Value = CreateWorkingBeatmap(new OsuRuleset().RulesetInfo); - MusicController.CurrentTrack.Start(); - MusicController.CurrentTrack.Seek(Beatmap.Value.Beatmap.HitObjects.First().StartTime - 1000); + Beatmap.Value.Track.Start(); + Beatmap.Value.Track.Seek(Beatmap.Value.Beatmap.HitObjects.First().StartTime - 1000); Add(new ModNightcore.NightcoreBeatContainer()); diff --git a/osu.Game.Tests/Visual/Gameplay/TestScenePause.cs b/osu.Game.Tests/Visual/Gameplay/TestScenePause.cs index e7dd586f4e..420bf29429 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestScenePause.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestScenePause.cs @@ -288,7 +288,7 @@ namespace osu.Game.Tests.Visual.Gameplay private void confirmNoTrackAdjustments() { - AddAssert("track has no adjustments", () => MusicController.CurrentTrack.AggregateFrequency.Value == 1); + AddAssert("track has no adjustments", () => Beatmap.Value.Track.AggregateFrequency.Value == 1); } private void restart() => AddStep("restart", () => Player.Restart()); diff --git a/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs b/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs index c3be6aee2b..4fac7bb45f 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs @@ -61,7 +61,7 @@ namespace osu.Game.Tests.Visual.Gameplay Beatmap.Value = CreateWorkingBeatmap(new OsuRuleset().RulesetInfo); foreach (var mod in SelectedMods.Value.OfType()) - mod.ApplyToTrack(MusicController.CurrentTrack); + mod.ApplyToTrack(Beatmap.Value.Track); InputManager.Child = container; } @@ -75,7 +75,7 @@ namespace osu.Game.Tests.Visual.Gameplay AddUntilStep("wait for not current", () => !loader.IsCurrentScreen()); AddAssert("player did not load", () => player == null); AddUntilStep("player disposed", () => loader.DisposalTask == null); - AddAssert("mod rate still applied", () => MusicController.CurrentTrack.Rate != 1); + AddAssert("mod rate still applied", () => Beatmap.Value.Track.Rate != 1); } /// @@ -88,13 +88,13 @@ namespace osu.Game.Tests.Visual.Gameplay { AddStep("load dummy beatmap", () => ResetPlayer(false, () => SelectedMods.Value = new[] { new OsuModNightcore() })); AddUntilStep("wait for current", () => loader.IsCurrentScreen()); - AddAssert("mod rate applied", () => MusicController.CurrentTrack.Rate != 1); + AddAssert("mod rate applied", () => Beatmap.Value.Track.Rate != 1); AddUntilStep("wait for non-null player", () => player != null); AddStep("exit loader", () => loader.Exit()); AddUntilStep("wait for not current", () => !loader.IsCurrentScreen()); AddAssert("player did not load", () => !player.IsLoaded); AddUntilStep("player disposed", () => loader.DisposalTask?.IsCompleted == true); - AddAssert("mod rate still applied", () => MusicController.CurrentTrack.Rate != 1); + AddAssert("mod rate still applied", () => Beatmap.Value.Track.Rate != 1); } [Test] diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboard.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboard.cs index c11a47d62b..9f1492a25f 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboard.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboard.cs @@ -25,12 +25,16 @@ namespace osu.Game.Tests.Visual.Gameplay private readonly Container storyboardContainer; private DrawableStoryboard storyboard; + [Cached] + private MusicController musicController = new MusicController(); + public TestSceneStoryboard() { Clock = new FramedClock(); AddRange(new Drawable[] { + musicController, new Container { RelativeSizeAxes = Axes.Both, @@ -83,9 +87,11 @@ namespace osu.Game.Tests.Visual.Gameplay private void restart() { - MusicController.CurrentTrack.Reset(); + var track = Beatmap.Value.Track; + + track.Reset(); loadStoryboard(Beatmap.Value); - MusicController.CurrentTrack.Start(); + track.Start(); } private void loadStoryboard(WorkingBeatmap working) @@ -100,7 +106,7 @@ namespace osu.Game.Tests.Visual.Gameplay storyboard.Passing = false; storyboardContainer.Add(storyboard); - decoupledClock.ChangeSource(MusicController.CurrentTrack); + decoupledClock.ChangeSource(working.Track); } private void loadStoryboardNoVideo() @@ -123,7 +129,7 @@ namespace osu.Game.Tests.Visual.Gameplay storyboard = sb.CreateDrawable(Beatmap.Value); storyboardContainer.Add(storyboard); - decoupledClock.ChangeSource(MusicController.CurrentTrack); + decoupledClock.ChangeSource(Beatmap.Value.Track); } } } From aead13628bbaa284b4dc1719c7c83e173f9e8565 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 21 Aug 2020 17:52:42 +0900 Subject: [PATCH 264/434] Rework freezing to use masking --- .../Objects/Drawables/DrawableHoldNote.cs | 112 +++++++++--------- 1 file changed, 56 insertions(+), 56 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs index 229ce355d7..e959509b96 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs @@ -12,7 +12,6 @@ using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.UI.Scrolling; using osu.Game.Skinning; -using osuTK; namespace osu.Game.Rulesets.Mania.Objects.Drawables { @@ -35,19 +34,14 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables private readonly Container tickContainer; /// - /// Contains the maximum size/position of the body prior to any offset or size adjustments. + /// Contains the size of the hold note covering the whole head/tail bounds. The size of this container changes as the hold note is being pressed. /// - private readonly Container bodyContainer; + private readonly Container sizingContainer; /// - /// Contains the offset size/position of the body such that the body extends half-way between the head and tail pieces. + /// Contains the contents of the hold note that should be masked as the hold note is being pressed. Follows changes in the size of . /// - private readonly Container bodyOffsetContainer; - - /// - /// Contains the masking area for the tail, which is resized along with . - /// - private readonly Container tailMaskingContainer; + private readonly Container maskingContainer; private readonly SkinnableDrawable bodyPiece; @@ -71,36 +65,43 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables { RelativeSizeAxes = Axes.X; - AddRangeInternal(new[] + Container maskedContents; + + AddRangeInternal(new Drawable[] { - bodyContainer = new Container + sizingContainer = new Container { RelativeSizeAxes = Axes.Both, Children = new Drawable[] { - bodyOffsetContainer = new Container + maskingContainer = new Container { - RelativeSizeAxes = Axes.X, - Child = bodyPiece = new SkinnableDrawable(new ManiaSkinComponent(ManiaSkinComponents.HoldNoteBody, hitObject.Column), _ => new DefaultBodyPiece + RelativeSizeAxes = Axes.Both, + Child = maskedContents = new Container { - RelativeSizeAxes = Axes.Both - }) + RelativeSizeAxes = Axes.Both, + Masking = true, + } }, - // The head needs to move along with changes in the size of the body. headContainer = new Container { RelativeSizeAxes = Axes.Both } } }, - tickContainer = new Container { RelativeSizeAxes = Axes.Both }, - tailMaskingContainer = new Container + bodyPiece = new SkinnableDrawable(new ManiaSkinComponent(ManiaSkinComponents.HoldNoteBody, hitObject.Column), _ => new DefaultBodyPiece { - RelativeSizeAxes = Axes.X, - Masking = true, - Child = tailContainer = new Container - { - RelativeSizeAxes = Axes.X, - } + RelativeSizeAxes = Axes.Both, + }) + { + RelativeSizeAxes = Axes.X }, - headContainer.CreateProxy() + tickContainer = new Container { RelativeSizeAxes = Axes.Both }, + tailContainer = new Container { RelativeSizeAxes = Axes.Both }, + }); + + maskedContents.AddRange(new[] + { + bodyPiece.CreateProxy(), + tickContainer.CreateProxy(), + tailContainer.CreateProxy(), }); } @@ -167,24 +168,15 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables { base.OnDirectionChanged(e); - // The body container is anchored from the position of the tail, since its height is changed when the hold note is being hit. - // The body offset container is anchored from the position of the head (inverse of the above). - // The tail containers are both anchored from the position of the tail. if (e.NewValue == ScrollingDirection.Up) { - bodyContainer.Anchor = bodyContainer.Origin = Anchor.BottomLeft; - bodyOffsetContainer.Anchor = bodyOffsetContainer.Origin = Anchor.TopLeft; - - tailMaskingContainer.Anchor = tailMaskingContainer.Origin = Anchor.BottomLeft; - tailContainer.Anchor = tailContainer.Origin = Anchor.BottomLeft; + bodyPiece.Anchor = bodyPiece.Origin = Anchor.TopLeft; + sizingContainer.Anchor = sizingContainer.Origin = Anchor.BottomLeft; } else { - bodyContainer.Anchor = bodyContainer.Origin = Anchor.TopLeft; - bodyOffsetContainer.Anchor = bodyOffsetContainer.Origin = Anchor.BottomLeft; - - tailMaskingContainer.Anchor = tailMaskingContainer.Origin = Anchor.TopLeft; - tailContainer.Anchor = tailContainer.Origin = Anchor.TopLeft; + bodyPiece.Anchor = bodyPiece.Origin = Anchor.BottomLeft; + sizingContainer.Anchor = sizingContainer.Origin = Anchor.TopLeft; } } @@ -206,26 +198,34 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables if (Time.Current < releaseTime) releaseTime = null; - // Decrease the size of the body while the hold note is held and the head has been hit. This stops at the very first release point. + // Pad the full size container so its contents (i.e. the masking container) reach under the tail. + // This is required for the tail to not be masked away, since it lies outside the bounds of the hold note. + sizingContainer.Padding = new MarginPadding + { + Top = Direction.Value == ScrollingDirection.Down ? -Tail.Height : 0, + Bottom = Direction.Value == ScrollingDirection.Up ? -Tail.Height : 0, + }; + + // Pad the masking container to the starting position of the body piece (half-way under the head). + // This is required ot make the body start getting masked immediately as soon as the note is held. + maskingContainer.Padding = new MarginPadding + { + Top = Direction.Value == ScrollingDirection.Up ? Head.Height / 2 : 0, + Bottom = Direction.Value == ScrollingDirection.Down ? Head.Height / 2 : 0, + }; + + // Position and resize the body to lie half-way under the head and the tail notes. + bodyPiece.Y = (Direction.Value == ScrollingDirection.Up ? 1 : -1) * Head.Height / 2; + bodyPiece.Height = DrawHeight - Head.Height / 2 + Tail.Height / 2; + + // As the note is being held, adjust the size of the fullSizeContainer. This has two effects: + // 1. The contained masking container will mask the body and ticks. + // 2. The head note will move along with the new "head position" in the container. if (Head.IsHit && releaseTime == null) { float heightDecrease = (float)(Math.Max(0, Time.Current - HitObject.StartTime) / HitObject.Duration); - bodyContainer.Height = MathHelper.Clamp(1 - heightDecrease, 0, 1); + sizingContainer.Height = Math.Clamp(1 - heightDecrease, 0, 1); } - - // Re-position the body half-way up the head, and extend the height until it's half-way under the tail. - bodyOffsetContainer.Y = (Direction.Value == ScrollingDirection.Up ? 1 : -1) * Head.Height / 2; - bodyOffsetContainer.Height = bodyContainer.DrawHeight + Tail.Height / 2 - Head.Height / 2; - - // The tail is positioned to be "outside" the hold note, so re-position its masking container to fully cover the tail and extend the height until it's half-way under the head. - // The masking height is determined by the size of the body so that the head and tail don't overlap as the body becomes shorter via hitting (above). - tailMaskingContainer.Y = (Direction.Value == ScrollingDirection.Up ? 1 : -1) * Tail.Height; - tailMaskingContainer.Height = bodyContainer.DrawHeight + Tail.Height - Head.Height / 2; - - // The tail container needs the reverse of the above offset applied to bring the tail to its original position. - // It also needs the full original height of the hold note to maintain positioning even as the height of the masking container changes. - tailContainer.Y = -tailMaskingContainer.Y; - tailContainer.Height = DrawHeight; } protected override void UpdateStateTransforms(ArmedState state) From 69cb9f309123ec3719064ad3bfc9b155ddb4b796 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 21 Aug 2020 18:19:47 +0900 Subject: [PATCH 265/434] Fix potential crash if disposing a DrawableStoryboardSample twice --- osu.Game/Storyboards/Drawables/DrawableStoryboardSample.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Storyboards/Drawables/DrawableStoryboardSample.cs b/osu.Game/Storyboards/Drawables/DrawableStoryboardSample.cs index 8eaf9ac652..119c48836b 100644 --- a/osu.Game/Storyboards/Drawables/DrawableStoryboardSample.cs +++ b/osu.Game/Storyboards/Drawables/DrawableStoryboardSample.cs @@ -76,6 +76,8 @@ namespace osu.Game.Storyboards.Drawables protected override void Dispose(bool isDisposing) { Channel?.Stop(); + Channel = null; + base.Dispose(isDisposing); } } From 1edafc39bac27e54ebb32dfb44124382ec3b55b5 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 21 Aug 2020 18:33:24 +0900 Subject: [PATCH 266/434] Fix intro welcome playing double due to missing conditional --- osu.Game/Screens/Menu/IntroTriangles.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Menu/IntroTriangles.cs b/osu.Game/Screens/Menu/IntroTriangles.cs index 52281967ee..a96fddb5ad 100644 --- a/osu.Game/Screens/Menu/IntroTriangles.cs +++ b/osu.Game/Screens/Menu/IntroTriangles.cs @@ -64,7 +64,8 @@ namespace osu.Game.Screens.Menu }, t => { AddInternal(t); - welcome?.Play(); + if (!UsingThemedIntro) + welcome?.Play(); StartTrack(); }); From 308d9f59679033e0585cd96b4d5e550c9d2b31d0 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 21 Aug 2020 18:43:58 +0900 Subject: [PATCH 267/434] Ensure locally executed methods are always loaded before propagation --- osu.Game/Overlays/MusicController.cs | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index c1116ff651..112026d9e2 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -231,9 +231,7 @@ namespace osu.Game.Overlays if (playable != null) { - if (beatmap is Bindable working) - working.Value = beatmaps.GetWorkingBeatmap(playable.Beatmaps.First(), beatmap.Value); - + changeBeatmap(beatmaps.GetWorkingBeatmap(playable.Beatmaps.First(), beatmap.Value)); restartTrack(); return PreviousTrackResult.Previous; } @@ -257,9 +255,7 @@ namespace osu.Game.Overlays if (playable != null) { - if (beatmap is Bindable working) - working.Value = beatmaps.GetWorkingBeatmap(playable.Beatmaps.First(), beatmap.Value); - + changeBeatmap(beatmaps.GetWorkingBeatmap(playable.Beatmaps.First(), beatmap.Value)); restartTrack(); return true; } @@ -278,11 +274,15 @@ namespace osu.Game.Overlays private TrackChangeDirection? queuedDirection; - private void beatmapChanged(ValueChangedEvent beatmap) + private void beatmapChanged(ValueChangedEvent beatmap) => changeBeatmap(beatmap.NewValue); + + private void changeBeatmap(WorkingBeatmap newWorking) { + var lastWorking = current; + TrackChangeDirection direction = TrackChangeDirection.None; - bool audioEquals = beatmap.NewValue?.BeatmapInfo?.AudioEquals(current?.BeatmapInfo) ?? false; + bool audioEquals = newWorking?.BeatmapInfo?.AudioEquals(current?.BeatmapInfo) ?? false; if (current != null) { @@ -297,13 +297,13 @@ namespace osu.Game.Overlays { // figure out the best direction based on order in playlist. var last = BeatmapSets.TakeWhile(b => b.ID != current.BeatmapSetInfo?.ID).Count(); - var next = beatmap.NewValue == null ? -1 : BeatmapSets.TakeWhile(b => b.ID != beatmap.NewValue.BeatmapSetInfo?.ID).Count(); + var next = newWorking == null ? -1 : BeatmapSets.TakeWhile(b => b.ID != newWorking.BeatmapSetInfo?.ID).Count(); direction = last > next ? TrackChangeDirection.Prev : TrackChangeDirection.Next; } } - current = beatmap.NewValue; + current = newWorking; if (!audioEquals || CurrentTrack.IsDummyDevice) { @@ -312,7 +312,7 @@ namespace osu.Game.Overlays else { // transfer still valid track to new working beatmap - current.TransferTrack(beatmap.OldValue.Track); + current.TransferTrack(lastWorking.Track); } TrackChanged?.Invoke(current, direction); @@ -320,6 +320,11 @@ namespace osu.Game.Overlays ResetTrackAdjustments(); queuedDirection = null; + + // this will be a noop if coming from the beatmapChanged event. + // the exception is local operations like next/prev, where we want to complete loading the track before sending out a change. + if (beatmap.Value != current && beatmap is Bindable working) + working.Value = current; } private void changeTrack() From 4239e9f684e7e1594fc652be1640a940d9092cd0 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 21 Aug 2020 18:44:14 +0900 Subject: [PATCH 268/434] Fix storyboard test not actually working due to incorrect track referencing --- .../Visual/Gameplay/TestSceneStoryboard.cs | 50 ++++++++----------- 1 file changed, 21 insertions(+), 29 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboard.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboard.cs index 9f1492a25f..5a2b8d22fd 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboard.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboard.cs @@ -22,19 +22,32 @@ namespace osu.Game.Tests.Visual.Gameplay [TestFixture] public class TestSceneStoryboard : OsuTestScene { - private readonly Container storyboardContainer; + private Container storyboardContainer; private DrawableStoryboard storyboard; - [Cached] - private MusicController musicController = new MusicController(); + [Test] + public void TestStoryboard() + { + AddStep("Restart", restart); + AddToggleStep("Passing", passing => + { + if (storyboard != null) storyboard.Passing = passing; + }); + } - public TestSceneStoryboard() + [Test] + public void TestStoryboardMissingVideo() + { + AddStep("Load storyboard with missing video", loadStoryboardNoVideo); + } + + [BackgroundDependencyLoader] + private void load() { Clock = new FramedClock(); AddRange(new Drawable[] { - musicController, new Container { RelativeSizeAxes = Axes.Both, @@ -58,32 +71,11 @@ namespace osu.Game.Tests.Visual.Gameplay State = { Value = Visibility.Visible }, } }); + + Beatmap.BindValueChanged(beatmapChanged, true); } - [Test] - public void TestStoryboard() - { - AddStep("Restart", restart); - AddToggleStep("Passing", passing => - { - if (storyboard != null) storyboard.Passing = passing; - }); - } - - [Test] - public void TestStoryboardMissingVideo() - { - AddStep("Load storyboard with missing video", loadStoryboardNoVideo); - } - - [BackgroundDependencyLoader] - private void load() - { - Beatmap.ValueChanged += beatmapChanged; - } - - private void beatmapChanged(ValueChangedEvent e) - => loadStoryboard(e.NewValue); + private void beatmapChanged(ValueChangedEvent e) => loadStoryboard(e.NewValue); private void restart() { From f63d1ba612df01640d3abe79a1db5217a947f54a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 21 Aug 2020 18:52:53 +0900 Subject: [PATCH 269/434] Remove stray call to LoadTrack that was forgotten --- osu.Game/Screens/Menu/IntroScreen.cs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/osu.Game/Screens/Menu/IntroScreen.cs b/osu.Game/Screens/Menu/IntroScreen.cs index 363933694d..884cbfe107 100644 --- a/osu.Game/Screens/Menu/IntroScreen.cs +++ b/osu.Game/Screens/Menu/IntroScreen.cs @@ -12,7 +12,6 @@ using osu.Framework.Screens; using osu.Game.Beatmaps; using osu.Game.Configuration; using osu.Game.IO.Archives; -using osu.Game.Overlays; using osu.Game.Screens.Backgrounds; using osu.Game.Skinning; using osuTK; @@ -61,9 +60,6 @@ namespace osu.Game.Screens.Menu [Resolved] private AudioManager audio { get; set; } - [Resolved] - private MusicController musicController { get; set; } - /// /// Whether the is provided by osu! resources, rather than a user beatmap. /// Only valid during or after . @@ -168,8 +164,8 @@ namespace osu.Game.Screens.Menu if (!resuming) { beatmap.Value = initialBeatmap; - Track = musicController.CurrentTrack; - UsingThemedIntro = !initialBeatmap.LoadTrack().IsDummyDevice; + Track = initialBeatmap.Track; + UsingThemedIntro = !initialBeatmap.Track.IsDummyDevice; logo.MoveTo(new Vector2(0.5f)); logo.ScaleTo(Vector2.One); From 42ee9b75df7a411fb2354ab2a47feafd288b815f Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Fri, 21 Aug 2020 19:38:59 +0900 Subject: [PATCH 270/434] Apply suggestions from code review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bartłomiej Dach --- .../Objects/Drawables/DrawableHoldNote.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs index e959509b96..40c5764a97 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs @@ -207,7 +207,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables }; // Pad the masking container to the starting position of the body piece (half-way under the head). - // This is required ot make the body start getting masked immediately as soon as the note is held. + // This is required to make the body start getting masked immediately as soon as the note is held. maskingContainer.Padding = new MarginPadding { Top = Direction.Value == ScrollingDirection.Up ? Head.Height / 2 : 0, @@ -218,13 +218,13 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables bodyPiece.Y = (Direction.Value == ScrollingDirection.Up ? 1 : -1) * Head.Height / 2; bodyPiece.Height = DrawHeight - Head.Height / 2 + Tail.Height / 2; - // As the note is being held, adjust the size of the fullSizeContainer. This has two effects: + // As the note is being held, adjust the size of the sizing container. This has two effects: // 1. The contained masking container will mask the body and ticks. // 2. The head note will move along with the new "head position" in the container. if (Head.IsHit && releaseTime == null) { - float heightDecrease = (float)(Math.Max(0, Time.Current - HitObject.StartTime) / HitObject.Duration); - sizingContainer.Height = Math.Clamp(1 - heightDecrease, 0, 1); + float remainingHeight = (float)(Math.Max(0, HitObject.GetEndTime() - Time.Current) / HitObject.Duration); + sizingContainer.Height = Math.Clamp(remainingHeight, 0, 1); } } From 8632c3adf0c1bc945aa26d14b7206db5ed37a69c Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 21 Aug 2020 23:11:15 +0900 Subject: [PATCH 271/434] Fix hold notes bouncing with SV changes --- .../Objects/Drawables/DrawableHoldNote.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs index 40c5764a97..0712026ca6 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs @@ -223,8 +223,9 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables // 2. The head note will move along with the new "head position" in the container. if (Head.IsHit && releaseTime == null) { - float remainingHeight = (float)(Math.Max(0, HitObject.GetEndTime() - Time.Current) / HitObject.Duration); - sizingContainer.Height = Math.Clamp(remainingHeight, 0, 1); + // How far past the hit target this hold note is. Always a positive value. + float yOffset = Math.Max(0, Direction.Value == ScrollingDirection.Up ? -Y : Y); + sizingContainer.Height = Math.Clamp(1 - yOffset / DrawHeight, 0, 1); } } From b3338347b7fd99375bc0926c4c29beda38f1171c Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 21 Aug 2020 23:56:27 +0900 Subject: [PATCH 272/434] Remove fade on successful hits --- .../Objects/Drawables/DrawableManiaHitObject.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs index a44d8b09aa..ab76a5b8f8 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs @@ -120,7 +120,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables break; case ArmedState.Hit: - this.FadeOut(150, Easing.OutQuint); + this.FadeOut(); break; } } From 88d50b6c4751e7fc87580b8e5bed753052017fa3 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Sat, 22 Aug 2020 00:15:37 +0900 Subject: [PATCH 273/434] Remove alpha mangling from LegacyDecoder --- osu.Game/Beatmaps/Formats/LegacyDecoder.cs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/osu.Game/Beatmaps/Formats/LegacyDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyDecoder.cs index 44ef9bcacc..c15240a4f6 100644 --- a/osu.Game/Beatmaps/Formats/LegacyDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyDecoder.cs @@ -104,10 +104,6 @@ namespace osu.Game.Beatmaps.Formats try { byte alpha = split.Length == 4 ? byte.Parse(split[3]) : (byte)255; - - if (alpha == 0) - alpha = 255; - colour = new Color4(byte.Parse(split[0]), byte.Parse(split[1]), byte.Parse(split[2]), alpha); } catch From 2424fa08027ebe105e1102997e8379ec31528c0a Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Sat, 22 Aug 2020 00:15:58 +0900 Subject: [PATCH 274/434] Add helper methods --- osu.Game/Skinning/LegacySkinExtensions.cs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/osu.Game/Skinning/LegacySkinExtensions.cs b/osu.Game/Skinning/LegacySkinExtensions.cs index bb46dc8b9f..088eae4bce 100644 --- a/osu.Game/Skinning/LegacySkinExtensions.cs +++ b/osu.Game/Skinning/LegacySkinExtensions.cs @@ -9,6 +9,7 @@ using osu.Framework.Graphics.Animations; using osu.Framework.Graphics.OpenGL.Textures; using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Textures; +using osuTK.Graphics; using static osu.Game.Skinning.LegacySkinConfiguration; namespace osu.Game.Skinning @@ -62,6 +63,21 @@ namespace osu.Game.Skinning } } + public static Color4 ToLegacyColour(this Color4 colour) + { + if (colour.A == 0) + colour.A = 1; + return colour; + } + + public static T WithInitialColour(this T drawable, Color4 colour) + where T : Drawable + { + drawable.Alpha = colour.A; + drawable.Colour = ToLegacyColour(colour); + return drawable; + } + public class SkinnableTextureAnimation : TextureAnimation { [Resolved(canBeNull: true)] From eaba32335327dc0a4f987f8b8f35bb89a01d51cb Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Sat, 22 Aug 2020 00:17:35 +0900 Subject: [PATCH 275/434] Update catch with legacy colour setters --- .../Skinning/CatchLegacySkinTransformer.cs | 8 +++++++- osu.Game.Rulesets.Catch/Skinning/LegacyFruitPiece.cs | 3 +-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Skinning/CatchLegacySkinTransformer.cs b/osu.Game.Rulesets.Catch/Skinning/CatchLegacySkinTransformer.cs index d929da1a29..5abd87d6f4 100644 --- a/osu.Game.Rulesets.Catch/Skinning/CatchLegacySkinTransformer.cs +++ b/osu.Game.Rulesets.Catch/Skinning/CatchLegacySkinTransformer.cs @@ -6,6 +6,7 @@ using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Game.Skinning; using osuTK; +using osuTK.Graphics; namespace osu.Game.Rulesets.Catch.Skinning { @@ -61,7 +62,12 @@ namespace osu.Game.Rulesets.Catch.Skinning switch (lookup) { case CatchSkinColour colour: - return Source.GetConfig(new SkinCustomColourLookup(colour)); + var result = (Bindable)Source.GetConfig(new SkinCustomColourLookup(colour)); + if (result == null) + return null; + + result.Value = result.Value.ToLegacyColour(); + return (IBindable)result; } return Source.GetConfig(lookup); diff --git a/osu.Game.Rulesets.Catch/Skinning/LegacyFruitPiece.cs b/osu.Game.Rulesets.Catch/Skinning/LegacyFruitPiece.cs index 5be54d3882..c9dd1d1f3e 100644 --- a/osu.Game.Rulesets.Catch/Skinning/LegacyFruitPiece.cs +++ b/osu.Game.Rulesets.Catch/Skinning/LegacyFruitPiece.cs @@ -40,7 +40,6 @@ namespace osu.Game.Rulesets.Catch.Skinning colouredSprite = new Sprite { Texture = skin.GetTexture(lookupName), - Colour = drawableObject.AccentColour.Value, Anchor = Anchor.Centre, Origin = Anchor.Centre, }, @@ -76,7 +75,7 @@ namespace osu.Game.Rulesets.Catch.Skinning { base.LoadComplete(); - accentColour.BindValueChanged(colour => colouredSprite.Colour = colour.NewValue, true); + accentColour.BindValueChanged(colour => colouredSprite.Colour = colour.NewValue.ToLegacyColour(), true); } } } From 454564b18928a17525e12596ca38446844cb0600 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Sat, 22 Aug 2020 00:19:15 +0900 Subject: [PATCH 276/434] Update mania with legacy colour setters --- .../Skinning/LegacyColumnBackground.cs | 20 ++++++++----------- .../Skinning/LegacyHitTarget.cs | 2 +- 2 files changed, 9 insertions(+), 13 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Skinning/LegacyColumnBackground.cs b/osu.Game.Rulesets.Mania/Skinning/LegacyColumnBackground.cs index 64a7641421..b97547bbc6 100644 --- a/osu.Game.Rulesets.Mania/Skinning/LegacyColumnBackground.cs +++ b/osu.Game.Rulesets.Mania/Skinning/LegacyColumnBackground.cs @@ -58,28 +58,24 @@ namespace osu.Game.Rulesets.Mania.Skinning InternalChildren = new Drawable[] { - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = backgroundColour - }, - new Box + new Box { RelativeSizeAxes = Axes.Both }.WithInitialColour(backgroundColour), + new Container { RelativeSizeAxes = Axes.Y, Width = leftLineWidth, Scale = new Vector2(0.740f, 1), - Colour = lineColour, - Alpha = hasLeftLine ? 1 : 0 + Alpha = hasLeftLine ? 1 : 0, + Child = new Box { RelativeSizeAxes = Axes.Both }.WithInitialColour(lineColour) }, - new Box + new Container { Anchor = Anchor.TopRight, Origin = Anchor.TopRight, RelativeSizeAxes = Axes.Y, Width = rightLineWidth, Scale = new Vector2(0.740f, 1), - Colour = lineColour, - Alpha = hasRightLine ? 1 : 0 + Alpha = hasRightLine ? 1 : 0, + Child = new Box { RelativeSizeAxes = Axes.Both }.WithInitialColour(lineColour) }, lightContainer = new Container { @@ -90,7 +86,7 @@ namespace osu.Game.Rulesets.Mania.Skinning { Anchor = Anchor.BottomCentre, Origin = Anchor.BottomCentre, - Colour = lightColour, + Colour = lightColour.ToLegacyColour(), Texture = skin.GetTexture(lightImage), RelativeSizeAxes = Axes.X, Width = 1, diff --git a/osu.Game.Rulesets.Mania/Skinning/LegacyHitTarget.cs b/osu.Game.Rulesets.Mania/Skinning/LegacyHitTarget.cs index d055ef3480..2177eaa5e6 100644 --- a/osu.Game.Rulesets.Mania/Skinning/LegacyHitTarget.cs +++ b/osu.Game.Rulesets.Mania/Skinning/LegacyHitTarget.cs @@ -56,7 +56,7 @@ namespace osu.Game.Rulesets.Mania.Skinning Anchor = Anchor.CentreLeft, RelativeSizeAxes = Axes.X, Height = 1, - Colour = lineColour, + Colour = lineColour.ToLegacyColour(), Alpha = showJudgementLine ? 0.9f : 0 } } From 16a2ab9dea4fd58e56eb00c017e61fce002b7ed2 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Sat, 22 Aug 2020 00:20:33 +0900 Subject: [PATCH 277/434] Update osu with legacy colour setters --- osu.Game.Rulesets.Osu/Skinning/LegacyMainCirclePiece.cs | 3 +-- osu.Game.Rulesets.Osu/Skinning/LegacySliderBall.cs | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Skinning/LegacyMainCirclePiece.cs b/osu.Game.Rulesets.Osu/Skinning/LegacyMainCirclePiece.cs index 0ab3e8825b..8a6beddb51 100644 --- a/osu.Game.Rulesets.Osu/Skinning/LegacyMainCirclePiece.cs +++ b/osu.Game.Rulesets.Osu/Skinning/LegacyMainCirclePiece.cs @@ -59,7 +59,6 @@ namespace osu.Game.Rulesets.Osu.Skinning hitCircleSprite = new Sprite { Texture = getTextureWithFallback(string.Empty), - Colour = drawableObject.AccentColour.Value, Anchor = Anchor.Centre, Origin = Anchor.Centre, }, @@ -107,7 +106,7 @@ namespace osu.Game.Rulesets.Osu.Skinning base.LoadComplete(); state.BindValueChanged(updateState, true); - accentColour.BindValueChanged(colour => hitCircleSprite.Colour = colour.NewValue, true); + accentColour.BindValueChanged(colour => hitCircleSprite.Colour = colour.NewValue.ToLegacyColour(), true); indexInCurrentCombo.BindValueChanged(index => hitCircleText.Text = (index.NewValue + 1).ToString(), true); } diff --git a/osu.Game.Rulesets.Osu/Skinning/LegacySliderBall.cs b/osu.Game.Rulesets.Osu/Skinning/LegacySliderBall.cs index 0f586034d5..3b75fcc8a0 100644 --- a/osu.Game.Rulesets.Osu/Skinning/LegacySliderBall.cs +++ b/osu.Game.Rulesets.Osu/Skinning/LegacySliderBall.cs @@ -28,7 +28,7 @@ namespace osu.Game.Rulesets.Osu.Skinning [BackgroundDependencyLoader] private void load(ISkinSource skin, DrawableHitObject drawableObject) { - animationContent.Colour = skin.GetConfig(OsuSkinColour.SliderBall)?.Value ?? Color4.White; + var ballColour = skin.GetConfig(OsuSkinColour.SliderBall)?.Value ?? Color4.White; InternalChildren = new[] { @@ -39,7 +39,7 @@ namespace osu.Game.Rulesets.Osu.Skinning Texture = skin.GetTexture("sliderb-nd"), Colour = new Color4(5, 5, 5, 255), }, - animationContent.With(d => + animationContent.WithInitialColour(ballColour).With(d => { d.Anchor = Anchor.Centre; d.Origin = Anchor.Centre; From 9fbc5f3aeb546fc27572a4c511793d6dd91088ea Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Sat, 22 Aug 2020 00:23:08 +0900 Subject: [PATCH 278/434] Update taiko with legacy colour setters --- osu.Game.Rulesets.Taiko/Skinning/LegacyCirclePiece.cs | 2 +- osu.Game.Rulesets.Taiko/Skinning/LegacyDrumRoll.cs | 6 +++--- osu.Game.Rulesets.Taiko/Skinning/LegacyHit.cs | 5 +++-- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Skinning/LegacyCirclePiece.cs b/osu.Game.Rulesets.Taiko/Skinning/LegacyCirclePiece.cs index bfcf268c3d..ed69b529ed 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/LegacyCirclePiece.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/LegacyCirclePiece.cs @@ -90,7 +90,7 @@ namespace osu.Game.Rulesets.Taiko.Skinning private void updateAccentColour() { - backgroundLayer.Colour = accentColour; + backgroundLayer.Colour = accentColour.ToLegacyColour(); } } } diff --git a/osu.Game.Rulesets.Taiko/Skinning/LegacyDrumRoll.cs b/osu.Game.Rulesets.Taiko/Skinning/LegacyDrumRoll.cs index 8223e3bc01..6bb8f9433e 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/LegacyDrumRoll.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/LegacyDrumRoll.cs @@ -76,9 +76,9 @@ namespace osu.Game.Rulesets.Taiko.Skinning private void updateAccentColour() { - headCircle.AccentColour = accentColour; - body.Colour = accentColour; - end.Colour = accentColour; + headCircle.AccentColour = accentColour.ToLegacyColour(); + body.Colour = accentColour.ToLegacyColour(); + end.Colour = accentColour.ToLegacyColour(); } } } diff --git a/osu.Game.Rulesets.Taiko/Skinning/LegacyHit.cs b/osu.Game.Rulesets.Taiko/Skinning/LegacyHit.cs index 656728f6e4..f36aae205a 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/LegacyHit.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/LegacyHit.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Allocation; +using osu.Game.Skinning; using osuTK.Graphics; namespace osu.Game.Rulesets.Taiko.Skinning @@ -18,9 +19,9 @@ namespace osu.Game.Rulesets.Taiko.Skinning [BackgroundDependencyLoader] private void load() { - AccentColour = component == TaikoSkinComponents.CentreHit + AccentColour = (component == TaikoSkinComponents.CentreHit ? new Color4(235, 69, 44, 255) - : new Color4(67, 142, 172, 255); + : new Color4(67, 142, 172, 255)).ToLegacyColour(); } } } From f89b6f44653112a86cc5df93be0d6e11ad0ad8d3 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Sat, 22 Aug 2020 00:52:53 +0900 Subject: [PATCH 279/434] Add xmldocs --- osu.Game/Skinning/LegacySkinExtensions.cs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/osu.Game/Skinning/LegacySkinExtensions.cs b/osu.Game/Skinning/LegacySkinExtensions.cs index 088eae4bce..ee7d74d7ec 100644 --- a/osu.Game/Skinning/LegacySkinExtensions.cs +++ b/osu.Game/Skinning/LegacySkinExtensions.cs @@ -63,6 +63,11 @@ namespace osu.Game.Skinning } } + /// + /// The resultant colour after setting a post-constructor colour in osu!stable. + /// + /// The to convert. + /// The converted . public static Color4 ToLegacyColour(this Color4 colour) { if (colour.A == 0) @@ -70,6 +75,16 @@ namespace osu.Game.Skinning return colour; } + /// + /// Equivalent of setting a colour in the constructor in osu!stable. + /// Doubles the alpha channel into and uses to set . + /// + /// + /// Beware: Any existing value in is overwritten. + /// + /// The to set the "InitialColour" of. + /// The to set. + /// The given . public static T WithInitialColour(this T drawable, Color4 colour) where T : Drawable { From 356c67f00d778e1f6d2535eb534a864d6b04caa4 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Sat, 22 Aug 2020 00:55:03 +0900 Subject: [PATCH 280/434] Remove outdated/wrong test --- osu.Game.Tests/Resources/skin-zero-alpha-colour.ini | 5 ----- osu.Game.Tests/Skins/LegacySkinDecoderTest.cs | 10 ---------- 2 files changed, 15 deletions(-) delete mode 100644 osu.Game.Tests/Resources/skin-zero-alpha-colour.ini diff --git a/osu.Game.Tests/Resources/skin-zero-alpha-colour.ini b/osu.Game.Tests/Resources/skin-zero-alpha-colour.ini deleted file mode 100644 index 3c0dae6b13..0000000000 --- a/osu.Game.Tests/Resources/skin-zero-alpha-colour.ini +++ /dev/null @@ -1,5 +0,0 @@ -[General] -Version: latest - -[Colours] -Combo1: 255,255,255,0 \ No newline at end of file diff --git a/osu.Game.Tests/Skins/LegacySkinDecoderTest.cs b/osu.Game.Tests/Skins/LegacySkinDecoderTest.cs index c408d2f182..aedf26ee75 100644 --- a/osu.Game.Tests/Skins/LegacySkinDecoderTest.cs +++ b/osu.Game.Tests/Skins/LegacySkinDecoderTest.cs @@ -108,15 +108,5 @@ namespace osu.Game.Tests.Skins using (var stream = new LineBufferedReader(resStream)) Assert.That(decoder.Decode(stream).LegacyVersion, Is.EqualTo(1.0m)); } - - [Test] - public void TestDecodeColourWithZeroAlpha() - { - var decoder = new LegacySkinDecoder(); - - using (var resStream = TestResources.OpenResource("skin-zero-alpha-colour.ini")) - using (var stream = new LineBufferedReader(resStream)) - Assert.That(decoder.Decode(stream).ComboColours[0].A, Is.EqualTo(1.0f)); - } } } From 08078b9513895806f9df2a08922fc7c4bf826fd9 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Sat, 22 Aug 2020 00:56:29 +0900 Subject: [PATCH 281/434] Rename method to remove "InitialColour" namings --- osu.Game.Rulesets.Mania/Skinning/LegacyColumnBackground.cs | 6 +++--- osu.Game.Rulesets.Osu/Skinning/LegacySliderBall.cs | 2 +- osu.Game/Skinning/LegacySkinExtensions.cs | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Skinning/LegacyColumnBackground.cs b/osu.Game.Rulesets.Mania/Skinning/LegacyColumnBackground.cs index b97547bbc6..54a16b840f 100644 --- a/osu.Game.Rulesets.Mania/Skinning/LegacyColumnBackground.cs +++ b/osu.Game.Rulesets.Mania/Skinning/LegacyColumnBackground.cs @@ -58,14 +58,14 @@ namespace osu.Game.Rulesets.Mania.Skinning InternalChildren = new Drawable[] { - new Box { RelativeSizeAxes = Axes.Both }.WithInitialColour(backgroundColour), + new Box { RelativeSizeAxes = Axes.Both }.WithLegacyColour(backgroundColour), new Container { RelativeSizeAxes = Axes.Y, Width = leftLineWidth, Scale = new Vector2(0.740f, 1), Alpha = hasLeftLine ? 1 : 0, - Child = new Box { RelativeSizeAxes = Axes.Both }.WithInitialColour(lineColour) + Child = new Box { RelativeSizeAxes = Axes.Both }.WithLegacyColour(lineColour) }, new Container { @@ -75,7 +75,7 @@ namespace osu.Game.Rulesets.Mania.Skinning Width = rightLineWidth, Scale = new Vector2(0.740f, 1), Alpha = hasRightLine ? 1 : 0, - Child = new Box { RelativeSizeAxes = Axes.Both }.WithInitialColour(lineColour) + Child = new Box { RelativeSizeAxes = Axes.Both }.WithLegacyColour(lineColour) }, lightContainer = new Container { diff --git a/osu.Game.Rulesets.Osu/Skinning/LegacySliderBall.cs b/osu.Game.Rulesets.Osu/Skinning/LegacySliderBall.cs index 3b75fcc8a0..27dec1b691 100644 --- a/osu.Game.Rulesets.Osu/Skinning/LegacySliderBall.cs +++ b/osu.Game.Rulesets.Osu/Skinning/LegacySliderBall.cs @@ -39,7 +39,7 @@ namespace osu.Game.Rulesets.Osu.Skinning Texture = skin.GetTexture("sliderb-nd"), Colour = new Color4(5, 5, 5, 255), }, - animationContent.WithInitialColour(ballColour).With(d => + animationContent.WithLegacyColour(ballColour).With(d => { d.Anchor = Anchor.Centre; d.Origin = Anchor.Centre; diff --git a/osu.Game/Skinning/LegacySkinExtensions.cs b/osu.Game/Skinning/LegacySkinExtensions.cs index ee7d74d7ec..7420f82f04 100644 --- a/osu.Game/Skinning/LegacySkinExtensions.cs +++ b/osu.Game/Skinning/LegacySkinExtensions.cs @@ -82,10 +82,10 @@ namespace osu.Game.Skinning /// /// Beware: Any existing value in is overwritten. /// - /// The to set the "InitialColour" of. + /// The to set the colour of. /// The to set. /// The given . - public static T WithInitialColour(this T drawable, Color4 colour) + public static T WithLegacyColour(this T drawable, Color4 colour) where T : Drawable { drawable.Alpha = colour.A; From 891f5cb130b50748cc517369cd33f1f6cf91aca1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Fri, 21 Aug 2020 20:00:20 +0200 Subject: [PATCH 282/434] Add padding to mania column borders to match stable --- .../Skinning/LegacyColumnBackground.cs | 50 +++++++++++++------ 1 file changed, 34 insertions(+), 16 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Skinning/LegacyColumnBackground.cs b/osu.Game.Rulesets.Mania/Skinning/LegacyColumnBackground.cs index 64a7641421..f9286b5095 100644 --- a/osu.Game.Rulesets.Mania/Skinning/LegacyColumnBackground.cs +++ b/osu.Game.Rulesets.Mania/Skinning/LegacyColumnBackground.cs @@ -8,6 +8,7 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Sprites; using osu.Framework.Input.Bindings; +using osu.Game.Rulesets.Mania.UI; using osu.Game.Rulesets.UI.Scrolling; using osu.Game.Skinning; using osuTK; @@ -20,9 +21,12 @@ namespace osu.Game.Rulesets.Mania.Skinning private readonly IBindable direction = new Bindable(); private readonly bool isLastColumn; + private Container borderLineContainer; private Container lightContainer; private Sprite light; + private float hitPosition; + public LegacyColumnBackground(bool isLastColumn) { this.isLastColumn = isLastColumn; @@ -44,6 +48,9 @@ namespace osu.Game.Rulesets.Mania.Skinning bool hasRightLine = rightLineWidth > 0 && skin.GetConfig(LegacySkinConfiguration.LegacySetting.Version)?.Value >= 2.4m || isLastColumn; + hitPosition = GetColumnSkinConfig(skin, LegacyManiaSkinConfigurationLookups.HitPosition)?.Value + ?? Stage.HIT_TARGET_POSITION; + float lightPosition = GetColumnSkinConfig(skin, LegacyManiaSkinConfigurationLookups.LightPosition)?.Value ?? 0; @@ -63,23 +70,30 @@ namespace osu.Game.Rulesets.Mania.Skinning RelativeSizeAxes = Axes.Both, Colour = backgroundColour }, - new Box + borderLineContainer = new Container { - RelativeSizeAxes = Axes.Y, - Width = leftLineWidth, - Scale = new Vector2(0.740f, 1), - Colour = lineColour, - Alpha = hasLeftLine ? 1 : 0 - }, - new Box - { - Anchor = Anchor.TopRight, - Origin = Anchor.TopRight, - RelativeSizeAxes = Axes.Y, - Width = rightLineWidth, - Scale = new Vector2(0.740f, 1), - Colour = lineColour, - Alpha = hasRightLine ? 1 : 0 + RelativeSizeAxes = Axes.Both, + Children = new[] + { + new Box + { + RelativeSizeAxes = Axes.Y, + Width = leftLineWidth, + Scale = new Vector2(0.740f, 1), + Colour = lineColour, + Alpha = hasLeftLine ? 1 : 0 + }, + new Box + { + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, + RelativeSizeAxes = Axes.Y, + Width = rightLineWidth, + Scale = new Vector2(0.740f, 1), + Colour = lineColour, + Alpha = hasRightLine ? 1 : 0 + } + } }, lightContainer = new Container { @@ -109,11 +123,15 @@ namespace osu.Game.Rulesets.Mania.Skinning { lightContainer.Anchor = Anchor.TopCentre; lightContainer.Scale = new Vector2(1, -1); + + borderLineContainer.Padding = new MarginPadding { Top = hitPosition }; } else { lightContainer.Anchor = Anchor.BottomCentre; lightContainer.Scale = Vector2.One; + + borderLineContainer.Padding = new MarginPadding { Bottom = hitPosition }; } } From 809a61afcbb07daa8683191fbafdd16cc6204d5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Fri, 21 Aug 2020 23:05:19 +0200 Subject: [PATCH 283/434] Adjust key binding panel tests to not rely on row indices --- .../Settings/TestSceneKeyBindingPanel.cs | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/osu.Game.Tests/Visual/Settings/TestSceneKeyBindingPanel.cs b/osu.Game.Tests/Visual/Settings/TestSceneKeyBindingPanel.cs index e06b3a8a7e..987a4a67fe 100644 --- a/osu.Game.Tests/Visual/Settings/TestSceneKeyBindingPanel.cs +++ b/osu.Game.Tests/Visual/Settings/TestSceneKeyBindingPanel.cs @@ -68,22 +68,22 @@ namespace osu.Game.Tests.Visual.Settings [Test] public void TestClearButtonOnBindings() { - KeyBindingRow backBindingRow = null; + KeyBindingRow multiBindingRow = null; - AddStep("click back binding row", () => + AddStep("click first row with two bindings", () => { - backBindingRow = panel.ChildrenOfType().ElementAt(10); - InputManager.MoveMouseTo(backBindingRow); + multiBindingRow = panel.ChildrenOfType().First(row => row.Defaults.Count() > 1); + InputManager.MoveMouseTo(multiBindingRow); InputManager.Click(MouseButton.Left); }); clickClearButton(); - AddAssert("first binding cleared", () => string.IsNullOrEmpty(backBindingRow.ChildrenOfType().First().Text.Text)); + AddAssert("first binding cleared", () => string.IsNullOrEmpty(multiBindingRow.ChildrenOfType().First().Text.Text)); AddStep("click second binding", () => { - var target = backBindingRow.ChildrenOfType().ElementAt(1); + var target = multiBindingRow.ChildrenOfType().ElementAt(1); InputManager.MoveMouseTo(target); InputManager.Click(MouseButton.Left); @@ -91,13 +91,13 @@ namespace osu.Game.Tests.Visual.Settings clickClearButton(); - AddAssert("second binding cleared", () => string.IsNullOrEmpty(backBindingRow.ChildrenOfType().ElementAt(1).Text.Text)); + AddAssert("second binding cleared", () => string.IsNullOrEmpty(multiBindingRow.ChildrenOfType().ElementAt(1).Text.Text)); void clickClearButton() { AddStep("click clear button", () => { - var clearButton = backBindingRow.ChildrenOfType().Single(); + var clearButton = multiBindingRow.ChildrenOfType().Single(); InputManager.MoveMouseTo(clearButton); InputManager.Click(MouseButton.Left); @@ -108,20 +108,20 @@ namespace osu.Game.Tests.Visual.Settings [Test] public void TestClickRowSelectsFirstBinding() { - KeyBindingRow backBindingRow = null; + KeyBindingRow multiBindingRow = null; - AddStep("click back binding row", () => + AddStep("click first row with two bindings", () => { - backBindingRow = panel.ChildrenOfType().ElementAt(10); - InputManager.MoveMouseTo(backBindingRow); + multiBindingRow = panel.ChildrenOfType().First(row => row.Defaults.Count() > 1); + InputManager.MoveMouseTo(multiBindingRow); InputManager.Click(MouseButton.Left); }); - AddAssert("first binding selected", () => backBindingRow.ChildrenOfType().First().IsBinding); + AddAssert("first binding selected", () => multiBindingRow.ChildrenOfType().First().IsBinding); AddStep("click second binding", () => { - var target = backBindingRow.ChildrenOfType().ElementAt(1); + var target = multiBindingRow.ChildrenOfType().ElementAt(1); InputManager.MoveMouseTo(target); InputManager.Click(MouseButton.Left); @@ -129,12 +129,12 @@ namespace osu.Game.Tests.Visual.Settings AddStep("click back binding row", () => { - backBindingRow = panel.ChildrenOfType().ElementAt(10); - InputManager.MoveMouseTo(backBindingRow); + multiBindingRow = panel.ChildrenOfType().ElementAt(10); + InputManager.MoveMouseTo(multiBindingRow); InputManager.Click(MouseButton.Left); }); - AddAssert("first binding selected", () => backBindingRow.ChildrenOfType().First().IsBinding); + AddAssert("first binding selected", () => multiBindingRow.ChildrenOfType().First().IsBinding); } } } From 0b6185cd14c18b32a031ef0b8d67b00ea6eef134 Mon Sep 17 00:00:00 2001 From: Keijia Date: Sat, 22 Aug 2020 01:09:35 +0300 Subject: [PATCH 284/434] add "hp" filter keyword --- osu.Game/Screens/Select/FilterQueryParser.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Select/FilterQueryParser.cs b/osu.Game/Screens/Select/FilterQueryParser.cs index 89afc729fe..b7bcf99ce0 100644 --- a/osu.Game/Screens/Select/FilterQueryParser.cs +++ b/osu.Game/Screens/Select/FilterQueryParser.cs @@ -11,7 +11,7 @@ namespace osu.Game.Screens.Select internal static class FilterQueryParser { private static readonly Regex query_syntax_regex = new Regex( - @"\b(?stars|ar|dr|cs|divisor|length|objects|bpm|status|creator|artist)(?[=:><]+)(?("".*"")|(\S*))", + @"\b(?stars|ar|dr|hp|cs|divisor|length|objects|bpm|status|creator|artist)(?[=:><]+)(?("".*"")|(\S*))", RegexOptions.Compiled | RegexOptions.IgnoreCase); internal static void ApplyQueries(FilterCriteria criteria, string query) @@ -46,6 +46,10 @@ namespace osu.Game.Screens.Select updateCriteriaRange(ref criteria.DrainRate, op, dr, 0.1f / 2); break; + case "hp" when parseFloatWithPoint(value, out var dr): + updateCriteriaRange(ref criteria.DrainRate, op, dr, 0.1f / 2); + break; + case "cs" when parseFloatWithPoint(value, out var cs): updateCriteriaRange(ref criteria.CircleSize, op, cs, 0.1f / 2); break; From f9fe37a8a51aba8955bcf3a6e5d7169cd480adbb Mon Sep 17 00:00:00 2001 From: Keijia Date: Sat, 22 Aug 2020 01:54:01 +0300 Subject: [PATCH 285/434] Added test for "hp" filter keyword --- .../NonVisual/Filtering/FilterQueryParserTest.cs | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/osu.Game.Tests/NonVisual/Filtering/FilterQueryParserTest.cs b/osu.Game.Tests/NonVisual/Filtering/FilterQueryParserTest.cs index 7b2913b817..d15682b1eb 100644 --- a/osu.Game.Tests/NonVisual/Filtering/FilterQueryParserTest.cs +++ b/osu.Game.Tests/NonVisual/Filtering/FilterQueryParserTest.cs @@ -60,7 +60,7 @@ namespace osu.Game.Tests.NonVisual.Filtering } [Test] - public void TestApplyDrainRateQueries() + public void TestApplyDrainRateQueriesByDrKeyword() { const string query = "dr>2 quite specific dr<:6"; var filterCriteria = new FilterCriteria(); @@ -73,6 +73,20 @@ namespace osu.Game.Tests.NonVisual.Filtering Assert.Less(filterCriteria.DrainRate.Min, 6.1f); } + [Test] + public void TestApplyDrainRateQueriesByHpKeyword() + { + const string query = "hp>2 quite specific hp<=6"; + var filterCriteria = new FilterCriteria(); + FilterQueryParser.ApplyQueries(filterCriteria, query); + Assert.AreEqual("quite specific", filterCriteria.SearchText.Trim()); + Assert.AreEqual(2, filterCriteria.SearchTerms.Length); + Assert.Greater(filterCriteria.DrainRate.Min, 2.0f); + Assert.Less(filterCriteria.DrainRate.Min, 2.1f); + Assert.Greater(filterCriteria.DrainRate.Max, 6.0f); + Assert.Less(filterCriteria.DrainRate.Min, 6.1f); + } + [Test] public void TestApplyBPMQueries() { From b5b2e523ad3493f059fc33e15c810a98995d1a0d Mon Sep 17 00:00:00 2001 From: Keijia Date: Sat, 22 Aug 2020 12:10:31 +0300 Subject: [PATCH 286/434] change switch cases --- osu.Game/Screens/Select/FilterQueryParser.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/osu.Game/Screens/Select/FilterQueryParser.cs b/osu.Game/Screens/Select/FilterQueryParser.cs index b7bcf99ce0..39fa4f777d 100644 --- a/osu.Game/Screens/Select/FilterQueryParser.cs +++ b/osu.Game/Screens/Select/FilterQueryParser.cs @@ -43,10 +43,7 @@ namespace osu.Game.Screens.Select break; case "dr" when parseFloatWithPoint(value, out var dr): - updateCriteriaRange(ref criteria.DrainRate, op, dr, 0.1f / 2); - break; - - case "hp" when parseFloatWithPoint(value, out var dr): + case "hp" when parseFloatWithPoint(value, out dr): updateCriteriaRange(ref criteria.DrainRate, op, dr, 0.1f / 2); break; From b72f06fef68a219b599671cefe3ce2e2b252d3e9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 22 Aug 2020 19:42:34 +0900 Subject: [PATCH 287/434] Centralise and clarify LoadTrack documentation --- osu.Game/Beatmaps/IWorkingBeatmap.cs | 10 +++++++++- osu.Game/Beatmaps/WorkingBeatmap.cs | 4 ---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/osu.Game/Beatmaps/IWorkingBeatmap.cs b/osu.Game/Beatmaps/IWorkingBeatmap.cs index 88d73fd7c4..bcd94d76fd 100644 --- a/osu.Game/Beatmaps/IWorkingBeatmap.cs +++ b/osu.Game/Beatmaps/IWorkingBeatmap.cs @@ -56,8 +56,16 @@ namespace osu.Game.Beatmaps IBeatmap GetPlayableBeatmap(RulesetInfo ruleset, IReadOnlyList mods = null, TimeSpan? timeout = null); /// - /// Retrieves the which this provides. + /// Load a new audio track instance for this beatmap. This should be called once before accessing . + /// The caller of this method is responsible for the lifetime of the track. /// + /// + /// In a standard game context, the loading of the track is managed solely by MusicController, which will + /// automatically load the track of the current global IBindable WorkingBeatmap. + /// As such, this method should only be called in very special scenarios, such as external tests or apps which are + /// outside of the game context. + /// + /// A fresh track instance, which will also be available via . Track LoadTrack(); } } diff --git a/osu.Game/Beatmaps/WorkingBeatmap.cs b/osu.Game/Beatmaps/WorkingBeatmap.cs index 6a89739e6f..6a161e6e04 100644 --- a/osu.Game/Beatmaps/WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/WorkingBeatmap.cs @@ -261,10 +261,6 @@ namespace osu.Game.Beatmaps private Track loadedTrack; - /// - /// Load a new audio track instance for this beatmap. - /// - /// A fresh track instance, which will also be available via . [NotNull] public Track LoadTrack() => loadedTrack = GetBeatmapTrack() ?? GetVirtualTrack(1000); From db5226042747b7e5078903cdb14d3a36f9e4af73 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 22 Aug 2020 19:44:54 +0900 Subject: [PATCH 288/434] Rename and clarify comment regarding "previous" track disposal --- osu.Game/Overlays/MusicController.cs | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index 112026d9e2..6d5b5d43cd 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -331,10 +331,10 @@ namespace osu.Game.Overlays { var lastTrack = CurrentTrack; - var newTrack = new DrawableTrack(current.LoadTrack()); - newTrack.Completed += () => onTrackCompleted(current); + var queuedTrack = new DrawableTrack(current.LoadTrack()); + queuedTrack.Completed += () => onTrackCompleted(current); - CurrentTrack = newTrack; + CurrentTrack = queuedTrack; // At this point we may potentially be in an async context from tests. This is extremely dangerous but we have to make do for now. // CurrentTrack is immediately updated above for situations where a immediate knowledge about the new track is required, @@ -343,12 +343,13 @@ namespace osu.Game.Overlays { lastTrack.Expire(); - if (newTrack == CurrentTrack) - AddInternal(newTrack); + if (queuedTrack == CurrentTrack) + AddInternal(queuedTrack); else { - // If the track has changed via changeTrack() being called multiple times in a single update, force disposal on the old track. - newTrack.Dispose(); + // If the track has changed since the call to changeTrack, it is safe to dispose the + // queued track rather than consume it. + queuedTrack.Dispose(); } }); } From 122265ff0e233a72a48a329370e8f6f8c1fde6e3 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 22 Aug 2020 19:47:05 +0900 Subject: [PATCH 289/434] Revert non-track usage --- osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs index c6bfdda698..c617950c64 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs @@ -86,7 +86,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline track = b.NewValue.Track; // todo: i don't think this is safe, the track may not be loaded yet. - if (b.NewValue.Track.Length > 0) + if (track.Length > 0) { MaxZoom = getZoomLevelForVisibleMilliseconds(500); MinZoom = getZoomLevelForVisibleMilliseconds(10000); From 2dce850f5b61b248285d8df4b10ead3e7167948d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 23 Aug 2020 23:11:56 +0900 Subject: [PATCH 290/434] Rewrite hyperdash test to not rely on timing --- .../TestSceneHyperDash.cs | 39 +++++++++++++------ 1 file changed, 28 insertions(+), 11 deletions(-) diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneHyperDash.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneHyperDash.cs index 6dab2a0b56..514d2aae22 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneHyperDash.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneHyperDash.cs @@ -22,21 +22,38 @@ namespace osu.Game.Rulesets.Catch.Tests [Test] public void TestHyperDash() { - AddAssert("First note is hyperdash", () => Beatmap.Value.Beatmap.HitObjects[0] is Fruit f && f.HyperDash); - AddUntilStep("wait for right movement", () => getCatcher().Scale.X > 0); // don't check hyperdashing as it happens too fast. - - AddUntilStep("wait for left movement", () => getCatcher().Scale.X < 0); - - for (int i = 0; i < 3; i++) + AddStep("reset count", () => { - AddUntilStep("wait for right hyperdash", () => getCatcher().Scale.X > 0 && getCatcher().HyperDashing); - AddUntilStep("wait for left hyperdash", () => getCatcher().Scale.X < 0 && getCatcher().HyperDashing); - } + inHyperDash = false; + hyperDashCount = 0; + }); - AddUntilStep("wait for right hyperdash", () => getCatcher().Scale.X > 0 && getCatcher().HyperDashing); + AddAssert("First note is hyperdash", () => Beatmap.Value.Beatmap.HitObjects[0] is Fruit f && f.HyperDash); + + for (int i = 0; i < 9; i++) + { + int count = i + 1; + AddUntilStep("wait for next hyperdash", () => hyperDashCount == count); + } } - private Catcher getCatcher() => Player.ChildrenOfType().First().MovableCatcher; + private int hyperDashCount; + private bool inHyperDash; + + protected override void Update() + { + var catcher = Player.ChildrenOfType().FirstOrDefault()?.MovableCatcher; + + if (catcher == null) + return; + + if (catcher.HyperDashing != inHyperDash) + { + inHyperDash = catcher.HyperDashing; + if (catcher.HyperDashing) + hyperDashCount++; + } + } protected override IBeatmap CreateBeatmap(RulesetInfo ruleset) { From d274652b3a30ace18ab23d92c7d4064c2421fd5f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 24 Aug 2020 00:13:26 +0900 Subject: [PATCH 291/434] Fix failures if test ran too fast --- osu.Game.Rulesets.Catch.Tests/TestSceneHyperDash.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneHyperDash.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneHyperDash.cs index 514d2aae22..a12e4b69e3 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneHyperDash.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneHyperDash.cs @@ -33,7 +33,7 @@ namespace osu.Game.Rulesets.Catch.Tests for (int i = 0; i < 9; i++) { int count = i + 1; - AddUntilStep("wait for next hyperdash", () => hyperDashCount == count); + AddUntilStep("wait for next hyperdash", () => hyperDashCount >= count); } } From 12ca870b74e3883ccc3396e32e160d239f419193 Mon Sep 17 00:00:00 2001 From: "Orosfai I. Zsolt" Date: Sun, 23 Aug 2020 17:34:57 +0200 Subject: [PATCH 292/434] Fix osu!catch relax mod --- osu.Game.Rulesets.Catch/Mods/CatchModRelax.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Catch/Mods/CatchModRelax.cs b/osu.Game.Rulesets.Catch/Mods/CatchModRelax.cs index c1d24395e4..1e42c6a240 100644 --- a/osu.Game.Rulesets.Catch/Mods/CatchModRelax.cs +++ b/osu.Game.Rulesets.Catch/Mods/CatchModRelax.cs @@ -52,7 +52,7 @@ namespace osu.Game.Rulesets.Catch.Mods protected override bool OnMouseMove(MouseMoveEvent e) { - catcher.UpdatePosition(e.MousePosition.X / DrawSize.X); + catcher.UpdatePosition(e.MousePosition.X / DrawSize.X * CatchPlayfield.WIDTH); return base.OnMouseMove(e); } } From 68a043a0703202fc918e5879cc6eef296b14f7eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sun, 23 Aug 2020 18:00:06 +0200 Subject: [PATCH 293/434] Add test case covering regression --- .../Mods/TestSceneCatchModRelax.cs | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 osu.Game.Rulesets.Catch.Tests/Mods/TestSceneCatchModRelax.cs diff --git a/osu.Game.Rulesets.Catch.Tests/Mods/TestSceneCatchModRelax.cs b/osu.Game.Rulesets.Catch.Tests/Mods/TestSceneCatchModRelax.cs new file mode 100644 index 0000000000..80939d756e --- /dev/null +++ b/osu.Game.Rulesets.Catch.Tests/Mods/TestSceneCatchModRelax.cs @@ -0,0 +1,45 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Collections.Generic; +using System.Linq; +using NUnit.Framework; +using osu.Framework.Testing; +using osu.Game.Beatmaps; +using osu.Game.Rulesets.Catch.Mods; +using osu.Game.Rulesets.Catch.Objects; +using osu.Game.Rulesets.Catch.UI; +using osu.Game.Rulesets.Objects; +using osu.Game.Tests.Visual; + +namespace osu.Game.Rulesets.Catch.Tests.Mods +{ + public class TestSceneCatchModRelax : ModTestScene + { + protected override Ruleset CreatePlayerRuleset() => new CatchRuleset(); + + [Test] + public void TestModRelax() => CreateModTest(new ModTestData + { + Mod = new CatchModRelax(), + Autoplay = false, + PassCondition = () => + { + var playfield = this.ChildrenOfType().Single(); + InputManager.MoveMouseTo(playfield.ScreenSpaceDrawQuad.Centre); + + return Player.ScoreProcessor.Combo.Value > 0; + }, + Beatmap = new Beatmap + { + HitObjects = new List + { + new Fruit + { + X = CatchPlayfield.CENTER_X + } + } + } + }); + } +} From a8a7d9af297efdca7a6aecd414e1c8f16421cf16 Mon Sep 17 00:00:00 2001 From: "Orosfai I. Zsolt" Date: Sun, 23 Aug 2020 21:35:15 +0200 Subject: [PATCH 294/434] Add testcase to osu!catch relax mod --- .../Mods/TestSceneCatchModRelax.cs | 52 ++++++++++++++++--- 1 file changed, 44 insertions(+), 8 deletions(-) diff --git a/osu.Game.Rulesets.Catch.Tests/Mods/TestSceneCatchModRelax.cs b/osu.Game.Rulesets.Catch.Tests/Mods/TestSceneCatchModRelax.cs index 80939d756e..385de0cea7 100644 --- a/osu.Game.Rulesets.Catch.Tests/Mods/TestSceneCatchModRelax.cs +++ b/osu.Game.Rulesets.Catch.Tests/Mods/TestSceneCatchModRelax.cs @@ -10,7 +10,9 @@ using osu.Game.Rulesets.Catch.Mods; using osu.Game.Rulesets.Catch.Objects; using osu.Game.Rulesets.Catch.UI; using osu.Game.Rulesets.Objects; +using osu.Game.Rulesets.Objects.Types; using osu.Game.Tests.Visual; +using osuTK; namespace osu.Game.Rulesets.Catch.Tests.Mods { @@ -23,23 +25,57 @@ namespace osu.Game.Rulesets.Catch.Tests.Mods { Mod = new CatchModRelax(), Autoplay = false, - PassCondition = () => - { - var playfield = this.ChildrenOfType().Single(); - InputManager.MoveMouseTo(playfield.ScreenSpaceDrawQuad.Centre); - - return Player.ScoreProcessor.Combo.Value > 0; - }, + PassCondition = passCondition, Beatmap = new Beatmap { HitObjects = new List { new Fruit { - X = CatchPlayfield.CENTER_X + X = CatchPlayfield.CENTER_X, + StartTime = 0 + }, + new Fruit + { + X = 0, + StartTime = 250 + }, + new Fruit + { + X = CatchPlayfield.WIDTH, + StartTime = 500 + }, + new JuiceStream + { + X = CatchPlayfield.CENTER_X, + StartTime = 750, + Path = new SliderPath(PathType.Linear, new Vector2[] { Vector2.Zero, Vector2.UnitY * 200 }) } } } }); + + private bool passCondition() + { + var playfield = this.ChildrenOfType().Single(); + + switch (Player.ScoreProcessor.Combo.Value) + { + case 0: + InputManager.MoveMouseTo(playfield.ScreenSpaceDrawQuad.Centre); + break; + case 1: + InputManager.MoveMouseTo(playfield.ScreenSpaceDrawQuad.BottomLeft); + break; + case 2: + InputManager.MoveMouseTo(playfield.ScreenSpaceDrawQuad.BottomRight); + break; + case 3: + InputManager.MoveMouseTo(playfield.ScreenSpaceDrawQuad.Centre); + break; + } + + return Player.ScoreProcessor.Combo.Value >= 6; + } } } From 3d68f30467c02390e50f5176f294d2a1053056d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sun, 23 Aug 2020 21:52:50 +0200 Subject: [PATCH 295/434] Fix code style issues --- osu.Game.Rulesets.Catch.Tests/Mods/TestSceneCatchModRelax.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Catch.Tests/Mods/TestSceneCatchModRelax.cs b/osu.Game.Rulesets.Catch.Tests/Mods/TestSceneCatchModRelax.cs index 385de0cea7..1eb0975010 100644 --- a/osu.Game.Rulesets.Catch.Tests/Mods/TestSceneCatchModRelax.cs +++ b/osu.Game.Rulesets.Catch.Tests/Mods/TestSceneCatchModRelax.cs @@ -49,7 +49,7 @@ namespace osu.Game.Rulesets.Catch.Tests.Mods { X = CatchPlayfield.CENTER_X, StartTime = 750, - Path = new SliderPath(PathType.Linear, new Vector2[] { Vector2.Zero, Vector2.UnitY * 200 }) + Path = new SliderPath(PathType.Linear, new[] { Vector2.Zero, Vector2.UnitY * 200 }) } } } @@ -64,12 +64,15 @@ namespace osu.Game.Rulesets.Catch.Tests.Mods case 0: InputManager.MoveMouseTo(playfield.ScreenSpaceDrawQuad.Centre); break; + case 1: InputManager.MoveMouseTo(playfield.ScreenSpaceDrawQuad.BottomLeft); break; + case 2: InputManager.MoveMouseTo(playfield.ScreenSpaceDrawQuad.BottomRight); break; + case 3: InputManager.MoveMouseTo(playfield.ScreenSpaceDrawQuad.Centre); break; From c03cc754e3764bda4ae8b9394eedb846bfd48eef Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 24 Aug 2020 11:38:03 +0900 Subject: [PATCH 296/434] Move event attaching to ensure reporting is done at a high enough rate --- .../TestSceneHyperDash.cs | 39 ++++++++++--------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneHyperDash.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneHyperDash.cs index a12e4b69e3..db09b2bc6b 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneHyperDash.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneHyperDash.cs @@ -19,6 +19,9 @@ namespace osu.Game.Rulesets.Catch.Tests { protected override bool Autoplay => true; + private int hyperDashCount; + private bool inHyperDash; + [Test] public void TestHyperDash() { @@ -26,6 +29,22 @@ namespace osu.Game.Rulesets.Catch.Tests { inHyperDash = false; hyperDashCount = 0; + + // this needs to be done within the frame stable context due to how quickly hyperdash state changes occur. + Player.DrawableRuleset.FrameStableComponents.OnUpdate += d => + { + var catcher = Player.ChildrenOfType().FirstOrDefault()?.MovableCatcher; + + if (catcher == null) + return; + + if (catcher.HyperDashing != inHyperDash) + { + inHyperDash = catcher.HyperDashing; + if (catcher.HyperDashing) + hyperDashCount++; + } + }; }); AddAssert("First note is hyperdash", () => Beatmap.Value.Beatmap.HitObjects[0] is Fruit f && f.HyperDash); @@ -33,25 +52,7 @@ namespace osu.Game.Rulesets.Catch.Tests for (int i = 0; i < 9; i++) { int count = i + 1; - AddUntilStep("wait for next hyperdash", () => hyperDashCount >= count); - } - } - - private int hyperDashCount; - private bool inHyperDash; - - protected override void Update() - { - var catcher = Player.ChildrenOfType().FirstOrDefault()?.MovableCatcher; - - if (catcher == null) - return; - - if (catcher.HyperDashing != inHyperDash) - { - inHyperDash = catcher.HyperDashing; - if (catcher.HyperDashing) - hyperDashCount++; + AddUntilStep($"wait for hyperdash #{count}", () => hyperDashCount >= count); } } From dca307e93379e258c15b5423130014afb9f8f03a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 24 Aug 2020 13:02:39 +0900 Subject: [PATCH 297/434] Use beatmap directly in ReadyButton --- osu.Game/Screens/Multi/Match/Components/ReadyButton.cs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/osu.Game/Screens/Multi/Match/Components/ReadyButton.cs b/osu.Game/Screens/Multi/Match/Components/ReadyButton.cs index 384d3bd5a5..a64f24dd7e 100644 --- a/osu.Game/Screens/Multi/Match/Components/ReadyButton.cs +++ b/osu.Game/Screens/Multi/Match/Components/ReadyButton.cs @@ -10,7 +10,6 @@ using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Graphics.UserInterface; using osu.Game.Online.Multiplayer; -using osu.Game.Overlays; namespace osu.Game.Screens.Multi.Match.Components { @@ -27,9 +26,6 @@ namespace osu.Game.Screens.Multi.Match.Components [Resolved] private BeatmapManager beatmaps { get; set; } - [Resolved] - private MusicController musicController { get; set; } - private bool hasBeatmap; public ReadyButton() @@ -104,7 +100,7 @@ namespace osu.Game.Screens.Multi.Match.Components return; } - bool hasEnoughTime = DateTimeOffset.UtcNow.AddSeconds(30).AddMilliseconds(musicController.CurrentTrack.Length) < endDate.Value; + bool hasEnoughTime = DateTimeOffset.UtcNow.AddSeconds(30).AddMilliseconds(gameBeatmap.Value.Track.Length) < endDate.Value; Enabled.Value = hasBeatmap && hasEnoughTime; } From db45d9aa8a1f395c57f6e276feb62364845dab54 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 24 Aug 2020 22:11:04 +0900 Subject: [PATCH 298/434] Fix catch hyper dash colour defaults not being set correctly As the defaults were not set, if a skin happened to specify 0,0,0,0 it would be ignored due to the early returns in property setters. --- osu.Game.Rulesets.Catch/UI/CatcherTrailDisplay.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Catch/UI/CatcherTrailDisplay.cs b/osu.Game.Rulesets.Catch/UI/CatcherTrailDisplay.cs index bab3cb748b..4dcc533dac 100644 --- a/osu.Game.Rulesets.Catch/UI/CatcherTrailDisplay.cs +++ b/osu.Game.Rulesets.Catch/UI/CatcherTrailDisplay.cs @@ -24,7 +24,7 @@ namespace osu.Game.Rulesets.Catch.UI private readonly Container hyperDashTrails; private readonly Container endGlowSprites; - private Color4 hyperDashTrailsColour; + private Color4 hyperDashTrailsColour = Catcher.DEFAULT_HYPER_DASH_COLOUR; public Color4 HyperDashTrailsColour { @@ -39,7 +39,7 @@ namespace osu.Game.Rulesets.Catch.UI } } - private Color4 endGlowSpritesColour; + private Color4 endGlowSpritesColour = Catcher.DEFAULT_HYPER_DASH_COLOUR; public Color4 EndGlowSpritesColour { From 500cb0ccf5c5f6f09a3874fe98731c41382b6a3c Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 24 Aug 2020 22:36:37 +0900 Subject: [PATCH 299/434] Fix legacy hit target being layered incorrectly --- .../Skinning/LegacyColumnBackground.cs | 41 +++++++++++++++---- .../Skinning/LegacyHitTarget.cs | 5 --- .../Skinning/LegacyStageBackground.cs | 6 ++- .../Skinning/ManiaLegacySkinTransformer.cs | 9 ++-- 4 files changed, 45 insertions(+), 16 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Skinning/LegacyColumnBackground.cs b/osu.Game.Rulesets.Mania/Skinning/LegacyColumnBackground.cs index f9286b5095..543ea23db8 100644 --- a/osu.Game.Rulesets.Mania/Skinning/LegacyColumnBackground.cs +++ b/osu.Game.Rulesets.Mania/Skinning/LegacyColumnBackground.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 JetBrains.Annotations; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -21,15 +22,20 @@ namespace osu.Game.Rulesets.Mania.Skinning private readonly IBindable direction = new Bindable(); private readonly bool isLastColumn; - private Container borderLineContainer; + [CanBeNull] + private readonly LegacyStageBackground stageBackground; + + private Container hitTargetContainer; private Container lightContainer; private Sprite light; + private Drawable hitTarget; private float hitPosition; - public LegacyColumnBackground(bool isLastColumn) + public LegacyColumnBackground(bool isLastColumn, [CanBeNull] LegacyStageBackground stageBackground) { this.isLastColumn = isLastColumn; + this.stageBackground = stageBackground; RelativeSizeAxes = Axes.Both; } @@ -47,6 +53,7 @@ namespace osu.Game.Rulesets.Mania.Skinning bool hasLeftLine = leftLineWidth > 0; bool hasRightLine = rightLineWidth > 0 && skin.GetConfig(LegacySkinConfiguration.LegacySetting.Version)?.Value >= 2.4m || isLastColumn; + bool hasHitTarget = Column.Index == 0 || stageBackground == null; hitPosition = GetColumnSkinConfig(skin, LegacyManiaSkinConfigurationLookups.HitPosition)?.Value ?? Stage.HIT_TARGET_POSITION; @@ -63,18 +70,29 @@ namespace osu.Game.Rulesets.Mania.Skinning Color4 lightColour = GetColumnSkinConfig(skin, LegacyManiaSkinConfigurationLookups.ColumnLightColour)?.Value ?? Color4.White; - InternalChildren = new Drawable[] + Drawable background; + + InternalChildren = new[] { - new Box + background = new Box { RelativeSizeAxes = Axes.Both, Colour = backgroundColour }, - borderLineContainer = new Container + hitTargetContainer = new Container { RelativeSizeAxes = Axes.Both, Children = new[] { + // In legacy skins, the hit target takes on the full stage size and is sandwiched between the column background and the column light. + // To simulate this effect in lazer's hierarchy, the hit target is added to the first column's background and manually extended to the full size of the stage. + // Adding to the first columns allows depth issues to be resolved - if it were added to the last column, the previous column lights would appear below it. + // This still means that the hit target will appear below the next column backgrounds, but that's a much easier problem to solve by proxying the backgrounds below. + hitTarget = new LegacyHitTarget + { + RelativeSizeAxes = Axes.Y, + Alpha = hasHitTarget ? 1 : 0 + }, new Box { RelativeSizeAxes = Axes.Y, @@ -113,6 +131,9 @@ namespace osu.Game.Rulesets.Mania.Skinning } }; + // Resolve depth issues with the hit target appearing under the next column backgrounds by proxying to the stage background (always below the columns). + stageBackground?.AddColumnBackground(background.CreateProxy()); + direction.BindTo(scrollingInfo.Direction); direction.BindValueChanged(onDirectionChanged, true); } @@ -124,17 +145,23 @@ namespace osu.Game.Rulesets.Mania.Skinning lightContainer.Anchor = Anchor.TopCentre; lightContainer.Scale = new Vector2(1, -1); - borderLineContainer.Padding = new MarginPadding { Top = hitPosition }; + hitTargetContainer.Padding = new MarginPadding { Top = hitPosition }; } else { lightContainer.Anchor = Anchor.BottomCentre; lightContainer.Scale = Vector2.One; - borderLineContainer.Padding = new MarginPadding { Bottom = hitPosition }; + hitTargetContainer.Padding = new MarginPadding { Bottom = hitPosition }; } } + protected override void Update() + { + base.Update(); + hitTarget.Width = stageBackground?.DrawWidth ?? DrawWidth; + } + public bool OnPressed(ManiaAction action) { if (action == Column.Action.Value) diff --git a/osu.Game.Rulesets.Mania/Skinning/LegacyHitTarget.cs b/osu.Game.Rulesets.Mania/Skinning/LegacyHitTarget.cs index d055ef3480..1e1a9c2237 100644 --- a/osu.Game.Rulesets.Mania/Skinning/LegacyHitTarget.cs +++ b/osu.Game.Rulesets.Mania/Skinning/LegacyHitTarget.cs @@ -20,11 +20,6 @@ namespace osu.Game.Rulesets.Mania.Skinning private Container directionContainer; - public LegacyHitTarget() - { - RelativeSizeAxes = Axes.Both; - } - [BackgroundDependencyLoader] private void load(ISkinSource skin, IScrollingInfo scrollingInfo) { diff --git a/osu.Game.Rulesets.Mania/Skinning/LegacyStageBackground.cs b/osu.Game.Rulesets.Mania/Skinning/LegacyStageBackground.cs index 7f5de601ca..3998f21c96 100644 --- a/osu.Game.Rulesets.Mania/Skinning/LegacyStageBackground.cs +++ b/osu.Game.Rulesets.Mania/Skinning/LegacyStageBackground.cs @@ -14,6 +14,7 @@ namespace osu.Game.Rulesets.Mania.Skinning { private Drawable leftSprite; private Drawable rightSprite; + private Container columnBackgroundContainer; public LegacyStageBackground() { @@ -44,7 +45,8 @@ namespace osu.Game.Rulesets.Mania.Skinning Origin = Anchor.TopLeft, X = -0.05f, Texture = skin.GetTexture(rightImage) - } + }, + columnBackgroundContainer = new Container { RelativeSizeAxes = Axes.Both } }; } @@ -58,5 +60,7 @@ namespace osu.Game.Rulesets.Mania.Skinning if (rightSprite?.Height > 0) rightSprite.Scale = new Vector2(1, DrawHeight / rightSprite.Height); } + + public void AddColumnBackground(Drawable background) => columnBackgroundContainer.Add(background); } } diff --git a/osu.Game.Rulesets.Mania/Skinning/ManiaLegacySkinTransformer.cs b/osu.Game.Rulesets.Mania/Skinning/ManiaLegacySkinTransformer.cs index e167135556..d928f1080f 100644 --- a/osu.Game.Rulesets.Mania/Skinning/ManiaLegacySkinTransformer.cs +++ b/osu.Game.Rulesets.Mania/Skinning/ManiaLegacySkinTransformer.cs @@ -57,6 +57,8 @@ namespace osu.Game.Rulesets.Mania.Skinning /// private Lazy hasKeyTexture; + private LegacyStageBackground stageBackground; + public ManiaLegacySkinTransformer(ISkinSource source, IBeatmap beatmap) : base(source) { @@ -88,10 +90,11 @@ namespace osu.Game.Rulesets.Mania.Skinning switch (maniaComponent.Component) { case ManiaSkinComponents.ColumnBackground: - return new LegacyColumnBackground(maniaComponent.TargetColumn == beatmap.TotalColumns - 1); + return new LegacyColumnBackground(maniaComponent.TargetColumn == beatmap.TotalColumns - 1, stageBackground); case ManiaSkinComponents.HitTarget: - return new LegacyHitTarget(); + // Created within the column background, but should not fall back. See comments in LegacyColumnBackground. + return Drawable.Empty(); case ManiaSkinComponents.KeyArea: return new LegacyKeyArea(); @@ -112,7 +115,7 @@ namespace osu.Game.Rulesets.Mania.Skinning return new LegacyHitExplosion(); case ManiaSkinComponents.StageBackground: - return new LegacyStageBackground(); + return stageBackground = new LegacyStageBackground(); case ManiaSkinComponents.StageForeground: return new LegacyStageForeground(); From 60695bee8c25ce8a40894382d338ee7a883e96f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Mon, 24 Aug 2020 15:57:41 +0200 Subject: [PATCH 300/434] Remove fades when changing trail colour across skins --- osu.Game.Rulesets.Catch/UI/Catcher.cs | 5 +++-- osu.Game.Rulesets.Catch/UI/CatcherTrailDisplay.cs | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Catch/UI/Catcher.cs b/osu.Game.Rulesets.Catch/UI/Catcher.cs index a30e1b7b47..9289a6162c 100644 --- a/osu.Game.Rulesets.Catch/UI/Catcher.cs +++ b/osu.Game.Rulesets.Catch/UI/Catcher.cs @@ -285,8 +285,6 @@ namespace osu.Game.Rulesets.Catch.UI private void runHyperDashStateTransition(bool hyperDashing) { - trails.HyperDashTrailsColour = hyperDashColour; - trails.EndGlowSpritesColour = hyperDashEndGlowColour; updateTrailVisibility(); if (hyperDashing) @@ -403,6 +401,9 @@ namespace osu.Game.Rulesets.Catch.UI skin.GetConfig(CatchSkinColour.HyperDashAfterImage)?.Value ?? hyperDashColour; + trails.HyperDashTrailsColour = hyperDashColour; + trails.EndGlowSpritesColour = hyperDashEndGlowColour; + runHyperDashStateTransition(HyperDashing); } diff --git a/osu.Game.Rulesets.Catch/UI/CatcherTrailDisplay.cs b/osu.Game.Rulesets.Catch/UI/CatcherTrailDisplay.cs index 4dcc533dac..f7e9fd19a7 100644 --- a/osu.Game.Rulesets.Catch/UI/CatcherTrailDisplay.cs +++ b/osu.Game.Rulesets.Catch/UI/CatcherTrailDisplay.cs @@ -35,7 +35,7 @@ namespace osu.Game.Rulesets.Catch.UI return; hyperDashTrailsColour = value; - hyperDashTrails.FadeColour(hyperDashTrailsColour, Catcher.HYPER_DASH_TRANSITION_DURATION, Easing.OutQuint); + hyperDashTrails.Colour = hyperDashTrailsColour; } } @@ -50,7 +50,7 @@ namespace osu.Game.Rulesets.Catch.UI return; endGlowSpritesColour = value; - endGlowSprites.FadeColour(endGlowSpritesColour, Catcher.HYPER_DASH_TRANSITION_DURATION, Easing.OutQuint); + endGlowSprites.Colour = endGlowSpritesColour; } } From 77bf646ea09823b123ea44993adf6da3f3e6b320 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 24 Aug 2020 23:01:06 +0900 Subject: [PATCH 301/434] Move column lines to background layer --- .../Skinning/LegacyColumnBackground.cs | 40 +++++++++++-------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Skinning/LegacyColumnBackground.cs b/osu.Game.Rulesets.Mania/Skinning/LegacyColumnBackground.cs index 543ea23db8..f22903accf 100644 --- a/osu.Game.Rulesets.Mania/Skinning/LegacyColumnBackground.cs +++ b/osu.Game.Rulesets.Mania/Skinning/LegacyColumnBackground.cs @@ -70,30 +70,27 @@ namespace osu.Game.Rulesets.Mania.Skinning Color4 lightColour = GetColumnSkinConfig(skin, LegacyManiaSkinConfigurationLookups.ColumnLightColour)?.Value ?? Color4.White; - Drawable background; + Container backgroundLayer; + Drawable leftLine; + Drawable rightLine; InternalChildren = new[] { - background = new Box + backgroundLayer = new Container { RelativeSizeAxes = Axes.Both, - Colour = backgroundColour + Child = new Box + { + RelativeSizeAxes = Axes.Both, + Colour = backgroundColour + }, }, hitTargetContainer = new Container { RelativeSizeAxes = Axes.Both, Children = new[] { - // In legacy skins, the hit target takes on the full stage size and is sandwiched between the column background and the column light. - // To simulate this effect in lazer's hierarchy, the hit target is added to the first column's background and manually extended to the full size of the stage. - // Adding to the first columns allows depth issues to be resolved - if it were added to the last column, the previous column lights would appear below it. - // This still means that the hit target will appear below the next column backgrounds, but that's a much easier problem to solve by proxying the backgrounds below. - hitTarget = new LegacyHitTarget - { - RelativeSizeAxes = Axes.Y, - Alpha = hasHitTarget ? 1 : 0 - }, - new Box + leftLine = new Box { RelativeSizeAxes = Axes.Y, Width = leftLineWidth, @@ -101,7 +98,7 @@ namespace osu.Game.Rulesets.Mania.Skinning Colour = lineColour, Alpha = hasLeftLine ? 1 : 0 }, - new Box + rightLine = new Box { Anchor = Anchor.TopRight, Origin = Anchor.TopRight, @@ -110,7 +107,16 @@ namespace osu.Game.Rulesets.Mania.Skinning Scale = new Vector2(0.740f, 1), Colour = lineColour, Alpha = hasRightLine ? 1 : 0 - } + }, + // In legacy skins, the hit target takes on the full stage size and is sandwiched between the column background and the column light. + // To simulate this effect in lazer's hierarchy, the hit target is added to the first column's background and manually extended to the full size of the stage. + // Adding to the first columns allows depth issues to be resolved - if it were added to the last column, the previous column lights would appear below it. + // This still means that the hit target will appear below the next column backgrounds, but that's a much easier problem to solve by proxying the background layer below. + hitTarget = new LegacyHitTarget + { + RelativeSizeAxes = Axes.Y, + Alpha = hasHitTarget ? 1 : 0 + }, } }, lightContainer = new Container @@ -132,7 +138,9 @@ namespace osu.Game.Rulesets.Mania.Skinning }; // Resolve depth issues with the hit target appearing under the next column backgrounds by proxying to the stage background (always below the columns). - stageBackground?.AddColumnBackground(background.CreateProxy()); + backgroundLayer.Add(leftLine.CreateProxy()); + backgroundLayer.Add(rightLine.CreateProxy()); + stageBackground?.AddColumnBackground(backgroundLayer.CreateProxy()); direction.BindTo(scrollingInfo.Direction); direction.BindValueChanged(onDirectionChanged, true); From 018523a43a8c11243b6806fc4c4adf3384e24e6f Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 25 Aug 2020 01:21:27 +0900 Subject: [PATCH 302/434] Rework to remove cross-class pollutions --- .../Beatmaps/StageDefinition.cs | 4 +- osu.Game.Rulesets.Mania/ManiaSkinComponent.cs | 11 +- .../Skinning/LegacyColumnBackground.cs | 96 +------------- .../Skinning/LegacyStageBackground.cs | 124 +++++++++++++++++- .../Skinning/ManiaLegacySkinTransformer.cs | 11 +- osu.Game.Rulesets.Mania/UI/Column.cs | 2 - osu.Game.Rulesets.Mania/UI/ColumnFlow.cs | 105 +++++++++++++++ osu.Game.Rulesets.Mania/UI/Stage.cs | 55 ++------ 8 files changed, 252 insertions(+), 156 deletions(-) create mode 100644 osu.Game.Rulesets.Mania/UI/ColumnFlow.cs diff --git a/osu.Game.Rulesets.Mania/Beatmaps/StageDefinition.cs b/osu.Game.Rulesets.Mania/Beatmaps/StageDefinition.cs index 2557f2acdf..3052fc7d34 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/StageDefinition.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/StageDefinition.cs @@ -21,14 +21,14 @@ namespace osu.Game.Rulesets.Mania.Beatmaps /// /// The 0-based column index. /// Whether the column is a special column. - public bool IsSpecialColumn(int column) => Columns % 2 == 1 && column == Columns / 2; + public readonly bool IsSpecialColumn(int column) => Columns % 2 == 1 && column == Columns / 2; /// /// Get the type of column given a column index. /// /// The 0-based column index. /// The type of the column. - public ColumnType GetTypeOfColumn(int column) + public readonly ColumnType GetTypeOfColumn(int column) { if (IsSpecialColumn(column)) return ColumnType.Special; diff --git a/osu.Game.Rulesets.Mania/ManiaSkinComponent.cs b/osu.Game.Rulesets.Mania/ManiaSkinComponent.cs index c0c8505f44..f078345fc1 100644 --- a/osu.Game.Rulesets.Mania/ManiaSkinComponent.cs +++ b/osu.Game.Rulesets.Mania/ManiaSkinComponent.cs @@ -1,6 +1,7 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using osu.Game.Rulesets.Mania.Beatmaps; using osu.Game.Rulesets.Mania.UI; using osu.Game.Skinning; @@ -14,15 +15,23 @@ namespace osu.Game.Rulesets.Mania /// public readonly int? TargetColumn; + /// + /// The intended for this component. + /// May be null if the component is not a direct member of a . + /// + public readonly StageDefinition? StageDefinition; + /// /// Creates a new . /// /// The component. /// The intended index for this component. May be null if the component does not exist in a . - public ManiaSkinComponent(ManiaSkinComponents component, int? targetColumn = null) + /// The intended for this component. May be null if the component is not a direct member of a . + public ManiaSkinComponent(ManiaSkinComponents component, int? targetColumn = null, StageDefinition? stageDefinition = null) : base(component) { TargetColumn = targetColumn; + StageDefinition = stageDefinition; } protected override string RulesetPrefix => ManiaRuleset.SHORT_NAME; diff --git a/osu.Game.Rulesets.Mania/Skinning/LegacyColumnBackground.cs b/osu.Game.Rulesets.Mania/Skinning/LegacyColumnBackground.cs index f22903accf..acae4cd6fb 100644 --- a/osu.Game.Rulesets.Mania/Skinning/LegacyColumnBackground.cs +++ b/osu.Game.Rulesets.Mania/Skinning/LegacyColumnBackground.cs @@ -1,15 +1,12 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using JetBrains.Annotations; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Sprites; using osu.Framework.Input.Bindings; -using osu.Game.Rulesets.Mania.UI; using osu.Game.Rulesets.UI.Scrolling; using osu.Game.Skinning; using osuTK; @@ -20,22 +17,12 @@ namespace osu.Game.Rulesets.Mania.Skinning public class LegacyColumnBackground : LegacyManiaColumnElement, IKeyBindingHandler { private readonly IBindable direction = new Bindable(); - private readonly bool isLastColumn; - [CanBeNull] - private readonly LegacyStageBackground stageBackground; - - private Container hitTargetContainer; private Container lightContainer; private Sprite light; - private Drawable hitTarget; - private float hitPosition; - - public LegacyColumnBackground(bool isLastColumn, [CanBeNull] LegacyStageBackground stageBackground) + public LegacyColumnBackground() { - this.isLastColumn = isLastColumn; - this.stageBackground = stageBackground; RelativeSizeAxes = Axes.Both; } @@ -45,80 +32,14 @@ namespace osu.Game.Rulesets.Mania.Skinning string lightImage = skin.GetManiaSkinConfig(LegacyManiaSkinConfigurationLookups.LightImage)?.Value ?? "mania-stage-light"; - float leftLineWidth = GetColumnSkinConfig(skin, LegacyManiaSkinConfigurationLookups.LeftLineWidth) - ?.Value ?? 1; - float rightLineWidth = GetColumnSkinConfig(skin, LegacyManiaSkinConfigurationLookups.RightLineWidth) - ?.Value ?? 1; - - bool hasLeftLine = leftLineWidth > 0; - bool hasRightLine = rightLineWidth > 0 && skin.GetConfig(LegacySkinConfiguration.LegacySetting.Version)?.Value >= 2.4m - || isLastColumn; - bool hasHitTarget = Column.Index == 0 || stageBackground == null; - - hitPosition = GetColumnSkinConfig(skin, LegacyManiaSkinConfigurationLookups.HitPosition)?.Value - ?? Stage.HIT_TARGET_POSITION; - float lightPosition = GetColumnSkinConfig(skin, LegacyManiaSkinConfigurationLookups.LightPosition)?.Value ?? 0; - Color4 lineColour = GetColumnSkinConfig(skin, LegacyManiaSkinConfigurationLookups.ColumnLineColour)?.Value - ?? Color4.White; - - Color4 backgroundColour = GetColumnSkinConfig(skin, LegacyManiaSkinConfigurationLookups.ColumnBackgroundColour)?.Value - ?? Color4.Black; - Color4 lightColour = GetColumnSkinConfig(skin, LegacyManiaSkinConfigurationLookups.ColumnLightColour)?.Value ?? Color4.White; - Container backgroundLayer; - Drawable leftLine; - Drawable rightLine; - InternalChildren = new[] { - backgroundLayer = new Container - { - RelativeSizeAxes = Axes.Both, - Child = new Box - { - RelativeSizeAxes = Axes.Both, - Colour = backgroundColour - }, - }, - hitTargetContainer = new Container - { - RelativeSizeAxes = Axes.Both, - Children = new[] - { - leftLine = new Box - { - RelativeSizeAxes = Axes.Y, - Width = leftLineWidth, - Scale = new Vector2(0.740f, 1), - Colour = lineColour, - Alpha = hasLeftLine ? 1 : 0 - }, - rightLine = new Box - { - Anchor = Anchor.TopRight, - Origin = Anchor.TopRight, - RelativeSizeAxes = Axes.Y, - Width = rightLineWidth, - Scale = new Vector2(0.740f, 1), - Colour = lineColour, - Alpha = hasRightLine ? 1 : 0 - }, - // In legacy skins, the hit target takes on the full stage size and is sandwiched between the column background and the column light. - // To simulate this effect in lazer's hierarchy, the hit target is added to the first column's background and manually extended to the full size of the stage. - // Adding to the first columns allows depth issues to be resolved - if it were added to the last column, the previous column lights would appear below it. - // This still means that the hit target will appear below the next column backgrounds, but that's a much easier problem to solve by proxying the background layer below. - hitTarget = new LegacyHitTarget - { - RelativeSizeAxes = Axes.Y, - Alpha = hasHitTarget ? 1 : 0 - }, - } - }, lightContainer = new Container { Origin = Anchor.BottomCentre, @@ -137,11 +58,6 @@ namespace osu.Game.Rulesets.Mania.Skinning } }; - // Resolve depth issues with the hit target appearing under the next column backgrounds by proxying to the stage background (always below the columns). - backgroundLayer.Add(leftLine.CreateProxy()); - backgroundLayer.Add(rightLine.CreateProxy()); - stageBackground?.AddColumnBackground(backgroundLayer.CreateProxy()); - direction.BindTo(scrollingInfo.Direction); direction.BindValueChanged(onDirectionChanged, true); } @@ -152,24 +68,14 @@ namespace osu.Game.Rulesets.Mania.Skinning { lightContainer.Anchor = Anchor.TopCentre; lightContainer.Scale = new Vector2(1, -1); - - hitTargetContainer.Padding = new MarginPadding { Top = hitPosition }; } else { lightContainer.Anchor = Anchor.BottomCentre; lightContainer.Scale = Vector2.One; - - hitTargetContainer.Padding = new MarginPadding { Bottom = hitPosition }; } } - protected override void Update() - { - base.Update(); - hitTarget.Width = stageBackground?.DrawWidth ?? DrawWidth; - } - public bool OnPressed(ManiaAction action) { if (action == Column.Action.Value) diff --git a/osu.Game.Rulesets.Mania/Skinning/LegacyStageBackground.cs b/osu.Game.Rulesets.Mania/Skinning/LegacyStageBackground.cs index 3998f21c96..675c154b82 100644 --- a/osu.Game.Rulesets.Mania/Skinning/LegacyStageBackground.cs +++ b/osu.Game.Rulesets.Mania/Skinning/LegacyStageBackground.cs @@ -2,22 +2,31 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Allocation; +using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Sprites; +using osu.Game.Rulesets.Mania.Beatmaps; +using osu.Game.Rulesets.Mania.UI; +using osu.Game.Rulesets.UI.Scrolling; using osu.Game.Skinning; using osuTK; +using osuTK.Graphics; namespace osu.Game.Rulesets.Mania.Skinning { public class LegacyStageBackground : CompositeDrawable { + private readonly StageDefinition stageDefinition; + private Drawable leftSprite; private Drawable rightSprite; - private Container columnBackgroundContainer; + private ColumnFlow columnBackgrounds; - public LegacyStageBackground() + public LegacyStageBackground(StageDefinition stageDefinition) { + this.stageDefinition = stageDefinition; RelativeSizeAxes = Axes.Both; } @@ -46,8 +55,18 @@ namespace osu.Game.Rulesets.Mania.Skinning X = -0.05f, Texture = skin.GetTexture(rightImage) }, - columnBackgroundContainer = new Container { RelativeSizeAxes = Axes.Both } + columnBackgrounds = new ColumnFlow(stageDefinition) + { + RelativeSizeAxes = Axes.Y + }, + new HitTargetInsetContainer + { + Child = new LegacyHitTarget { RelativeSizeAxes = Axes.Both } + } }; + + for (int i = 0; i < stageDefinition.Columns; i++) + columnBackgrounds.SetColumn(i, new ColumnBackground(i, i == stageDefinition.Columns - 1)); } protected override void Update() @@ -61,6 +80,103 @@ namespace osu.Game.Rulesets.Mania.Skinning rightSprite.Scale = new Vector2(1, DrawHeight / rightSprite.Height); } - public void AddColumnBackground(Drawable background) => columnBackgroundContainer.Add(background); + private class ColumnBackground : CompositeDrawable + { + private readonly int columnIndex; + private readonly bool isLastColumn; + + public ColumnBackground(int columnIndex, bool isLastColumn) + { + this.columnIndex = columnIndex; + this.isLastColumn = isLastColumn; + + RelativeSizeAxes = Axes.Both; + } + + [BackgroundDependencyLoader] + private void load(ISkinSource skin) + { + float leftLineWidth = skin.GetManiaSkinConfig(LegacyManiaSkinConfigurationLookups.LeftLineWidth, columnIndex)?.Value ?? 1; + float rightLineWidth = skin.GetManiaSkinConfig(LegacyManiaSkinConfigurationLookups.RightLineWidth, columnIndex)?.Value ?? 1; + + bool hasLeftLine = leftLineWidth > 0; + bool hasRightLine = rightLineWidth > 0 && skin.GetConfig(LegacySkinConfiguration.LegacySetting.Version)?.Value >= 2.4m + || isLastColumn; + + Color4 lineColour = skin.GetManiaSkinConfig(LegacyManiaSkinConfigurationLookups.ColumnLineColour, columnIndex)?.Value ?? Color4.White; + Color4 backgroundColour = skin.GetManiaSkinConfig(LegacyManiaSkinConfigurationLookups.ColumnBackgroundColour, columnIndex)?.Value ?? Color4.Black; + + InternalChildren = new Drawable[] + { + new Container + { + RelativeSizeAxes = Axes.Both, + Child = new Box + { + RelativeSizeAxes = Axes.Both, + Colour = backgroundColour + }, + }, + new HitTargetInsetContainer + { + RelativeSizeAxes = Axes.Both, + Children = new[] + { + new Box + { + RelativeSizeAxes = Axes.Y, + Width = leftLineWidth, + Scale = new Vector2(0.740f, 1), + Colour = lineColour, + Alpha = hasLeftLine ? 1 : 0 + }, + new Box + { + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, + RelativeSizeAxes = Axes.Y, + Width = rightLineWidth, + Scale = new Vector2(0.740f, 1), + Colour = lineColour, + Alpha = hasRightLine ? 1 : 0 + }, + } + } + }; + } + } + + private class HitTargetInsetContainer : Container + { + private readonly IBindable direction = new Bindable(); + + protected override Container Content => content; + private readonly Container content; + + private float hitPosition; + + public HitTargetInsetContainer() + { + RelativeSizeAxes = Axes.Both; + + InternalChild = content = new Container { RelativeSizeAxes = Axes.Both }; + } + + [BackgroundDependencyLoader] + private void load(ISkinSource skin, IScrollingInfo scrollingInfo) + { + hitPosition = skin.GetManiaSkinConfig(LegacyManiaSkinConfigurationLookups.HitPosition)?.Value ?? Stage.HIT_TARGET_POSITION; + + direction.BindTo(scrollingInfo.Direction); + direction.BindValueChanged(onDirectionChanged, true); + } + + private void onDirectionChanged(ValueChangedEvent direction) + { + content.Padding = direction.NewValue == ScrollingDirection.Up + ? new MarginPadding { Top = hitPosition } + : new MarginPadding { Bottom = hitPosition }; + } + } } } diff --git a/osu.Game.Rulesets.Mania/Skinning/ManiaLegacySkinTransformer.cs b/osu.Game.Rulesets.Mania/Skinning/ManiaLegacySkinTransformer.cs index d928f1080f..439e6f7df2 100644 --- a/osu.Game.Rulesets.Mania/Skinning/ManiaLegacySkinTransformer.cs +++ b/osu.Game.Rulesets.Mania/Skinning/ManiaLegacySkinTransformer.cs @@ -9,6 +9,7 @@ using osu.Game.Beatmaps; using osu.Game.Rulesets.Mania.Beatmaps; using osu.Game.Skinning; using System.Collections.Generic; +using System.Diagnostics; using osu.Framework.Audio.Sample; using osu.Game.Audio; using osu.Game.Rulesets.Objects.Legacy; @@ -57,8 +58,6 @@ namespace osu.Game.Rulesets.Mania.Skinning /// private Lazy hasKeyTexture; - private LegacyStageBackground stageBackground; - public ManiaLegacySkinTransformer(ISkinSource source, IBeatmap beatmap) : base(source) { @@ -90,10 +89,11 @@ namespace osu.Game.Rulesets.Mania.Skinning switch (maniaComponent.Component) { case ManiaSkinComponents.ColumnBackground: - return new LegacyColumnBackground(maniaComponent.TargetColumn == beatmap.TotalColumns - 1, stageBackground); + return new LegacyColumnBackground(); case ManiaSkinComponents.HitTarget: - // Created within the column background, but should not fall back. See comments in LegacyColumnBackground. + // Legacy skins sandwich the hit target between the column background and the column light. + // To preserve this ordering, it's created manually inside LegacyStageBackground. return Drawable.Empty(); case ManiaSkinComponents.KeyArea: @@ -115,7 +115,8 @@ namespace osu.Game.Rulesets.Mania.Skinning return new LegacyHitExplosion(); case ManiaSkinComponents.StageBackground: - return stageBackground = new LegacyStageBackground(); + Debug.Assert(maniaComponent.StageDefinition != null); + return new LegacyStageBackground(maniaComponent.StageDefinition.Value); case ManiaSkinComponents.StageForeground: return new LegacyStageForeground(); diff --git a/osu.Game.Rulesets.Mania/UI/Column.cs b/osu.Game.Rulesets.Mania/UI/Column.cs index 255ce4c064..de4648e4fa 100644 --- a/osu.Game.Rulesets.Mania/UI/Column.cs +++ b/osu.Game.Rulesets.Mania/UI/Column.cs @@ -68,8 +68,6 @@ namespace osu.Game.Rulesets.Mania.UI TopLevelContainer.Add(HitObjectArea.Explosions.CreateProxy()); } - public override Axes RelativeSizeAxes => Axes.Y; - public ColumnType ColumnType { get; set; } public bool IsSpecial => ColumnType == ColumnType.Special; diff --git a/osu.Game.Rulesets.Mania/UI/ColumnFlow.cs b/osu.Game.Rulesets.Mania/UI/ColumnFlow.cs new file mode 100644 index 0000000000..37ad5c609b --- /dev/null +++ b/osu.Game.Rulesets.Mania/UI/ColumnFlow.cs @@ -0,0 +1,105 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Collections.Generic; +using System.Linq; +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Game.Rulesets.Mania.Beatmaps; +using osu.Game.Rulesets.Mania.Skinning; +using osu.Game.Skinning; + +namespace osu.Game.Rulesets.Mania.UI +{ + /// + /// A which flows its contents according to the s in a . + /// Content can be added to individual columns via . + /// + /// The type of content in each column. + public class ColumnFlow : CompositeDrawable + where TContent : Drawable + { + /// + /// All contents added to this . + /// + public IReadOnlyList Content => columns.Children.Select(c => c.Count == 0 ? null : (TContent)c.Child).ToList(); + + private readonly FillFlowContainer columns; + private readonly StageDefinition stageDefinition; + + public ColumnFlow(StageDefinition stageDefinition) + { + this.stageDefinition = stageDefinition; + + AutoSizeAxes = Axes.X; + + InternalChild = columns = new FillFlowContainer + { + RelativeSizeAxes = Axes.Y, + AutoSizeAxes = Axes.X, + Direction = FillDirection.Horizontal, + }; + + for (int i = 0; i < stageDefinition.Columns; i++) + columns.Add(new Container { RelativeSizeAxes = Axes.Y }); + } + + private ISkinSource currentSkin; + + [BackgroundDependencyLoader] + private void load(ISkinSource skin) + { + currentSkin = skin; + + skin.SourceChanged += onSkinChanged; + onSkinChanged(); + } + + private void onSkinChanged() + { + for (int i = 0; i < stageDefinition.Columns; i++) + { + if (i > 0) + { + float spacing = currentSkin.GetConfig( + new ManiaSkinConfigurationLookup(LegacyManiaSkinConfigurationLookups.ColumnSpacing, i - 1)) + ?.Value ?? Stage.COLUMN_SPACING; + + columns[i].Margin = new MarginPadding { Left = spacing }; + } + + float? width = currentSkin.GetConfig( + new ManiaSkinConfigurationLookup(LegacyManiaSkinConfigurationLookups.ColumnWidth, i)) + ?.Value; + + if (width == null) + // only used by default skin (legacy skins get defaults set in LegacyManiaSkinConfiguration) + columns[i].Width = stageDefinition.IsSpecialColumn(i) ? Column.SPECIAL_COLUMN_WIDTH : Column.COLUMN_WIDTH; + else + columns[i].Width = width.Value; + } + } + + /// + /// Sets the content of one of the columns of this . + /// + /// The index of the column to set the content of. + /// The content. + public void SetColumn(int column, TContent content) => columns[column].Child = content; + + public new MarginPadding Padding + { + get => base.Padding; + set => base.Padding = value; + } + + protected override void Dispose(bool isDisposing) + { + base.Dispose(isDisposing); + + if (currentSkin != null) + currentSkin.SourceChanged -= onSkinChanged; + } + } +} diff --git a/osu.Game.Rulesets.Mania/UI/Stage.cs b/osu.Game.Rulesets.Mania/UI/Stage.cs index 36780b0f80..5944c8c218 100644 --- a/osu.Game.Rulesets.Mania/UI/Stage.cs +++ b/osu.Game.Rulesets.Mania/UI/Stage.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.Linq; -using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Pooling; @@ -11,7 +10,6 @@ using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Mania.Beatmaps; using osu.Game.Rulesets.Mania.Objects; using osu.Game.Rulesets.Mania.Objects.Drawables; -using osu.Game.Rulesets.Mania.Skinning; using osu.Game.Rulesets.Mania.UI.Components; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.UI; @@ -31,8 +29,8 @@ namespace osu.Game.Rulesets.Mania.UI public const float HIT_TARGET_POSITION = 110; - public IReadOnlyList Columns => columnFlow.Children; - private readonly FillFlowContainer columnFlow; + public IReadOnlyList Columns => columnFlow.Content; + private readonly ColumnFlow columnFlow; private readonly JudgementContainer judgements; private readonly DrawablePool judgementPool; @@ -73,16 +71,13 @@ namespace osu.Game.Rulesets.Mania.UI AutoSizeAxes = Axes.X, Children = new Drawable[] { - new SkinnableDrawable(new ManiaSkinComponent(ManiaSkinComponents.StageBackground), _ => new DefaultStageBackground()) + new SkinnableDrawable(new ManiaSkinComponent(ManiaSkinComponents.StageBackground, stageDefinition: definition), _ => new DefaultStageBackground()) { RelativeSizeAxes = Axes.Both }, - columnFlow = new FillFlowContainer + columnFlow = new ColumnFlow(definition) { - Name = "Columns", RelativeSizeAxes = Axes.Y, - AutoSizeAxes = Axes.X, - Direction = FillDirection.Horizontal, Padding = new MarginPadding { Left = COLUMN_SPACING, Right = COLUMN_SPACING }, }, new Container @@ -102,7 +97,7 @@ namespace osu.Game.Rulesets.Mania.UI RelativeSizeAxes = Axes.Y, } }, - new SkinnableDrawable(new ManiaSkinComponent(ManiaSkinComponents.StageForeground), _ => null) + new SkinnableDrawable(new ManiaSkinComponent(ManiaSkinComponents.StageForeground, stageDefinition: definition), _ => null) { RelativeSizeAxes = Axes.Both }, @@ -123,6 +118,8 @@ namespace osu.Game.Rulesets.Mania.UI var columnType = definition.GetTypeOfColumn(i); var column = new Column(firstColumnIndex + i) { + RelativeSizeAxes = Axes.Both, + Width = 1, ColumnType = columnType, AccentColour = columnColours[columnType], Action = { Value = columnType == ColumnType.Special ? specialColumnStartAction++ : normalColumnStartAction++ } @@ -132,46 +129,10 @@ namespace osu.Game.Rulesets.Mania.UI } } - private ISkin currentSkin; - - [BackgroundDependencyLoader] - private void load(ISkinSource skin) - { - currentSkin = skin; - skin.SourceChanged += onSkinChanged; - - onSkinChanged(); - } - - private void onSkinChanged() - { - foreach (var col in columnFlow) - { - if (col.Index > 0) - { - float spacing = currentSkin.GetConfig( - new ManiaSkinConfigurationLookup(LegacyManiaSkinConfigurationLookups.ColumnSpacing, col.Index - 1)) - ?.Value ?? COLUMN_SPACING; - - col.Margin = new MarginPadding { Left = spacing }; - } - - float? width = currentSkin.GetConfig( - new ManiaSkinConfigurationLookup(LegacyManiaSkinConfigurationLookups.ColumnWidth, col.Index)) - ?.Value; - - if (width == null) - // only used by default skin (legacy skins get defaults set in LegacyManiaSkinConfiguration) - col.Width = col.IsSpecial ? Column.SPECIAL_COLUMN_WIDTH : Column.COLUMN_WIDTH; - else - col.Width = width.Value; - } - } - public void AddColumn(Column c) { topLevelContainer.Add(c.TopLevelContainer.CreateProxy()); - columnFlow.Add(c); + columnFlow.SetColumn(c.Index, c); AddNested(c); } From 50d5b020b7c579a7bea931d58267e793a90ce412 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Mon, 24 Aug 2020 20:19:33 +0200 Subject: [PATCH 303/434] Add failing test case --- .../TestSceneBeatmapSetOverlaySuccessRate.cs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlaySuccessRate.cs b/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlaySuccessRate.cs index 4cb22bf1fe..954eb74ad9 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlaySuccessRate.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlaySuccessRate.cs @@ -7,8 +7,10 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; +using osu.Framework.Testing; using osu.Framework.Utils; using osu.Game.Beatmaps; +using osu.Game.Graphics.UserInterface; using osu.Game.Overlays; using osu.Game.Overlays.BeatmapSet; using osu.Game.Screens.Select.Details; @@ -72,6 +74,20 @@ namespace osu.Game.Tests.Visual.Online }; } + [Test] + public void TestOnlyFailMetrics() + { + AddStep("set beatmap", () => successRate.Beatmap = new BeatmapInfo + { + Metrics = new BeatmapMetrics + { + Fails = Enumerable.Range(1, 100).ToArray(), + } + }); + AddAssert("graph max values correct", + () => successRate.ChildrenOfType().All(graph => graph.MaxValue == 100)); + } + private class GraphExposingSuccessRate : SuccessRate { public new FailRetryGraph Graph => base.Graph; From cc6ae8e3bd2a4ff21dee50dc7cd72f1663f32428 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Mon, 24 Aug 2020 20:41:31 +0200 Subject: [PATCH 304/434] Fix crash if only one count list is received from API --- .../Screens/Select/Details/FailRetryGraph.cs | 20 ++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Select/Details/FailRetryGraph.cs b/osu.Game/Screens/Select/Details/FailRetryGraph.cs index 134fd0598a..7cc80acfd3 100644 --- a/osu.Game/Screens/Select/Details/FailRetryGraph.cs +++ b/osu.Game/Screens/Select/Details/FailRetryGraph.cs @@ -29,16 +29,30 @@ namespace osu.Game.Screens.Select.Details var retries = Metrics?.Retries ?? Array.Empty(); var fails = Metrics?.Fails ?? Array.Empty(); + var retriesAndFails = sumRetriesAndFails(retries, fails); - float maxValue = fails.Any() ? fails.Zip(retries, (fail, retry) => fail + retry).Max() : 0; + float maxValue = retriesAndFails.Any() ? retriesAndFails.Max() : 0; failGraph.MaxValue = maxValue; retryGraph.MaxValue = maxValue; - failGraph.Values = fails.Select(f => (float)f); - retryGraph.Values = retries.Zip(fails, (retry, fail) => retry + Math.Clamp(fail, 0, maxValue)); + failGraph.Values = fails.Select(v => (float)v); + retryGraph.Values = retriesAndFails.Select(v => (float)v); } } + private int[] sumRetriesAndFails(int[] retries, int[] fails) + { + var result = new int[Math.Max(retries.Length, fails.Length)]; + + for (int i = 0; i < retries.Length; ++i) + result[i] = retries[i]; + + for (int i = 0; i < fails.Length; ++i) + result[i] += fails[i]; + + return result; + } + public FailRetryGraph() { Children = new[] From 29b4d98aaccdbd2b4440289a04cb8247492a2092 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Mon, 24 Aug 2020 20:41:50 +0200 Subject: [PATCH 305/434] Show retry/fail graph when either list is present --- osu.Game/Screens/Select/BeatmapDetails.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Select/BeatmapDetails.cs b/osu.Game/Screens/Select/BeatmapDetails.cs index 9669a1391c..0ee52f3e48 100644 --- a/osu.Game/Screens/Select/BeatmapDetails.cs +++ b/osu.Game/Screens/Select/BeatmapDetails.cs @@ -236,7 +236,7 @@ namespace osu.Game.Screens.Select private void updateMetrics() { var hasRatings = beatmap?.BeatmapSet?.Metrics?.Ratings?.Any() ?? false; - var hasRetriesFails = (beatmap?.Metrics?.Retries?.Any() ?? false) && (beatmap?.Metrics.Fails?.Any() ?? false); + var hasRetriesFails = (beatmap?.Metrics?.Retries?.Any() ?? false) || (beatmap?.Metrics?.Fails?.Any() ?? false); if (hasRatings) { From dbf90551d65dda6b3bb8e03ad67bd75a124cd07b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Mon, 24 Aug 2020 20:47:29 +0200 Subject: [PATCH 306/434] Add coverage for empty metrics case --- .../Online/TestSceneBeatmapSetOverlaySuccessRate.cs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlaySuccessRate.cs b/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlaySuccessRate.cs index 954eb74ad9..fd5c188b94 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlaySuccessRate.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlaySuccessRate.cs @@ -88,6 +88,18 @@ namespace osu.Game.Tests.Visual.Online () => successRate.ChildrenOfType().All(graph => graph.MaxValue == 100)); } + [Test] + public void TestEmptyMetrics() + { + AddStep("set beatmap", () => successRate.Beatmap = new BeatmapInfo + { + Metrics = new BeatmapMetrics() + }); + + AddAssert("graph max values correct", + () => successRate.ChildrenOfType().All(graph => graph.MaxValue == 0)); + } + private class GraphExposingSuccessRate : SuccessRate { public new FailRetryGraph Graph => base.Graph; From 723e5cafb6d1610c1857e7036a10d514db1c47eb Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 25 Aug 2020 14:49:04 +0900 Subject: [PATCH 307/434] Fix column potentially added at wrong indices --- osu.Game.Rulesets.Mania/UI/Stage.cs | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/osu.Game.Rulesets.Mania/UI/Stage.cs b/osu.Game.Rulesets.Mania/UI/Stage.cs index 5944c8c218..dfb1ee210d 100644 --- a/osu.Game.Rulesets.Mania/UI/Stage.cs +++ b/osu.Game.Rulesets.Mania/UI/Stage.cs @@ -36,7 +36,6 @@ namespace osu.Game.Rulesets.Mania.UI private readonly DrawablePool judgementPool; private readonly Drawable barLineContainer; - private readonly Container topLevelContainer; private readonly Dictionary columnColours = new Dictionary { @@ -60,6 +59,8 @@ namespace osu.Game.Rulesets.Mania.UI RelativeSizeAxes = Axes.Y; AutoSizeAxes = Axes.X; + Container topLevelContainer; + InternalChildren = new Drawable[] { judgementPool = new DrawablePool(2), @@ -116,6 +117,7 @@ namespace osu.Game.Rulesets.Mania.UI for (int i = 0; i < definition.Columns; i++) { var columnType = definition.GetTypeOfColumn(i); + var column = new Column(firstColumnIndex + i) { RelativeSizeAxes = Axes.Both, @@ -125,17 +127,12 @@ namespace osu.Game.Rulesets.Mania.UI Action = { Value = columnType == ColumnType.Special ? specialColumnStartAction++ : normalColumnStartAction++ } }; - AddColumn(column); + topLevelContainer.Add(column.TopLevelContainer.CreateProxy()); + columnFlow.SetColumn(i, column); + AddNested(column); } } - public void AddColumn(Column c) - { - topLevelContainer.Add(c.TopLevelContainer.CreateProxy()); - columnFlow.SetColumn(c.Index, c); - AddNested(c); - } - public override void Add(DrawableHitObject h) { var maniaObject = (ManiaHitObject)h.HitObject; From 7e9567dae978a1030807a33f97d8355c64719ba1 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 25 Aug 2020 14:49:29 +0900 Subject: [PATCH 308/434] Fix tests --- .../Skinning/TestSceneStageBackground.cs | 4 +++- .../Skinning/TestSceneStageForeground.cs | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneStageBackground.cs b/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneStageBackground.cs index 87c84cf89c..a15fb392d6 100644 --- a/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneStageBackground.cs +++ b/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneStageBackground.cs @@ -3,6 +3,7 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; +using osu.Game.Rulesets.Mania.Beatmaps; using osu.Game.Rulesets.Mania.UI.Components; using osu.Game.Skinning; @@ -13,7 +14,8 @@ namespace osu.Game.Rulesets.Mania.Tests.Skinning [BackgroundDependencyLoader] private void load() { - SetContents(() => new SkinnableDrawable(new ManiaSkinComponent(ManiaSkinComponents.StageBackground), _ => new DefaultStageBackground()) + SetContents(() => new SkinnableDrawable(new ManiaSkinComponent(ManiaSkinComponents.StageBackground, stageDefinition: new StageDefinition { Columns = 4 }), + _ => new DefaultStageBackground()) { Anchor = Anchor.Centre, Origin = Anchor.Centre, diff --git a/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneStageForeground.cs b/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneStageForeground.cs index 4e99068ed5..bceee1c599 100644 --- a/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneStageForeground.cs +++ b/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneStageForeground.cs @@ -3,6 +3,7 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; +using osu.Game.Rulesets.Mania.Beatmaps; using osu.Game.Skinning; namespace osu.Game.Rulesets.Mania.Tests.Skinning @@ -12,7 +13,7 @@ namespace osu.Game.Rulesets.Mania.Tests.Skinning [BackgroundDependencyLoader] private void load() { - SetContents(() => new SkinnableDrawable(new ManiaSkinComponent(ManiaSkinComponents.StageForeground), _ => null) + SetContents(() => new SkinnableDrawable(new ManiaSkinComponent(ManiaSkinComponents.StageForeground, stageDefinition: new StageDefinition { Columns = 4 }), _ => null) { Anchor = Anchor.Centre, Origin = Anchor.Centre, From ab8d9be095e4925d67cb1c06be49a2e92f24195f Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 25 Aug 2020 15:16:41 +0900 Subject: [PATCH 309/434] Move out into a separate method --- .../Skinning/CatchLegacySkinTransformer.cs | 2 +- .../Skinning/LegacyFruitPiece.cs | 2 +- .../Skinning/LegacyColumnBackground.cs | 17 +++++-- .../Skinning/LegacyHitTarget.cs | 2 +- .../Skinning/LegacyMainCirclePiece.cs | 2 +- .../Skinning/LegacySliderBall.cs | 4 +- .../Skinning/LegacyCirclePiece.cs | 2 +- .../Skinning/LegacyDrumRoll.cs | 6 +-- osu.Game.Rulesets.Taiko/Skinning/LegacyHit.cs | 7 +-- .../Skinning/LegacyColourCompatibility.cs | 46 +++++++++++++++++++ osu.Game/Skinning/LegacySkinExtensions.cs | 31 ------------- 11 files changed, 73 insertions(+), 48 deletions(-) create mode 100644 osu.Game/Skinning/LegacyColourCompatibility.cs diff --git a/osu.Game.Rulesets.Catch/Skinning/CatchLegacySkinTransformer.cs b/osu.Game.Rulesets.Catch/Skinning/CatchLegacySkinTransformer.cs index 5abd87d6f4..ea2f031d65 100644 --- a/osu.Game.Rulesets.Catch/Skinning/CatchLegacySkinTransformer.cs +++ b/osu.Game.Rulesets.Catch/Skinning/CatchLegacySkinTransformer.cs @@ -66,7 +66,7 @@ namespace osu.Game.Rulesets.Catch.Skinning if (result == null) return null; - result.Value = result.Value.ToLegacyColour(); + result.Value = LegacyColourCompatibility.DisallowZeroAlpha(result.Value); return (IBindable)result; } diff --git a/osu.Game.Rulesets.Catch/Skinning/LegacyFruitPiece.cs b/osu.Game.Rulesets.Catch/Skinning/LegacyFruitPiece.cs index c9dd1d1f3e..381d066750 100644 --- a/osu.Game.Rulesets.Catch/Skinning/LegacyFruitPiece.cs +++ b/osu.Game.Rulesets.Catch/Skinning/LegacyFruitPiece.cs @@ -75,7 +75,7 @@ namespace osu.Game.Rulesets.Catch.Skinning { base.LoadComplete(); - accentColour.BindValueChanged(colour => colouredSprite.Colour = colour.NewValue.ToLegacyColour(), true); + accentColour.BindValueChanged(colour => colouredSprite.Colour = LegacyColourCompatibility.DisallowZeroAlpha(colour.NewValue), true); } } } diff --git a/osu.Game.Rulesets.Mania/Skinning/LegacyColumnBackground.cs b/osu.Game.Rulesets.Mania/Skinning/LegacyColumnBackground.cs index 54a16b840f..da6075248a 100644 --- a/osu.Game.Rulesets.Mania/Skinning/LegacyColumnBackground.cs +++ b/osu.Game.Rulesets.Mania/Skinning/LegacyColumnBackground.cs @@ -58,14 +58,20 @@ namespace osu.Game.Rulesets.Mania.Skinning InternalChildren = new Drawable[] { - new Box { RelativeSizeAxes = Axes.Both }.WithLegacyColour(backgroundColour), + LegacyColourCompatibility.ApplyWithDoubledAlpha(new Box + { + RelativeSizeAxes = Axes.Both + }, backgroundColour), new Container { RelativeSizeAxes = Axes.Y, Width = leftLineWidth, Scale = new Vector2(0.740f, 1), Alpha = hasLeftLine ? 1 : 0, - Child = new Box { RelativeSizeAxes = Axes.Both }.WithLegacyColour(lineColour) + Child = LegacyColourCompatibility.ApplyWithDoubledAlpha(new Box + { + RelativeSizeAxes = Axes.Both + }, lineColour) }, new Container { @@ -75,7 +81,10 @@ namespace osu.Game.Rulesets.Mania.Skinning Width = rightLineWidth, Scale = new Vector2(0.740f, 1), Alpha = hasRightLine ? 1 : 0, - Child = new Box { RelativeSizeAxes = Axes.Both }.WithLegacyColour(lineColour) + Child = LegacyColourCompatibility.ApplyWithDoubledAlpha(new Box + { + RelativeSizeAxes = Axes.Both + }, lineColour) }, lightContainer = new Container { @@ -86,7 +95,7 @@ namespace osu.Game.Rulesets.Mania.Skinning { Anchor = Anchor.BottomCentre, Origin = Anchor.BottomCentre, - Colour = lightColour.ToLegacyColour(), + Colour = LegacyColourCompatibility.DisallowZeroAlpha(lightColour), Texture = skin.GetTexture(lightImage), RelativeSizeAxes = Axes.X, Width = 1, diff --git a/osu.Game.Rulesets.Mania/Skinning/LegacyHitTarget.cs b/osu.Game.Rulesets.Mania/Skinning/LegacyHitTarget.cs index 2177eaa5e6..48504e6548 100644 --- a/osu.Game.Rulesets.Mania/Skinning/LegacyHitTarget.cs +++ b/osu.Game.Rulesets.Mania/Skinning/LegacyHitTarget.cs @@ -56,7 +56,7 @@ namespace osu.Game.Rulesets.Mania.Skinning Anchor = Anchor.CentreLeft, RelativeSizeAxes = Axes.X, Height = 1, - Colour = lineColour.ToLegacyColour(), + Colour = LegacyColourCompatibility.DisallowZeroAlpha(lineColour), Alpha = showJudgementLine ? 0.9f : 0 } } diff --git a/osu.Game.Rulesets.Osu/Skinning/LegacyMainCirclePiece.cs b/osu.Game.Rulesets.Osu/Skinning/LegacyMainCirclePiece.cs index 8a6beddb51..d15a0a3203 100644 --- a/osu.Game.Rulesets.Osu/Skinning/LegacyMainCirclePiece.cs +++ b/osu.Game.Rulesets.Osu/Skinning/LegacyMainCirclePiece.cs @@ -106,7 +106,7 @@ namespace osu.Game.Rulesets.Osu.Skinning base.LoadComplete(); state.BindValueChanged(updateState, true); - accentColour.BindValueChanged(colour => hitCircleSprite.Colour = colour.NewValue.ToLegacyColour(), true); + accentColour.BindValueChanged(colour => hitCircleSprite.Colour = LegacyColourCompatibility.DisallowZeroAlpha(colour.NewValue), true); indexInCurrentCombo.BindValueChanged(index => hitCircleText.Text = (index.NewValue + 1).ToString(), true); } diff --git a/osu.Game.Rulesets.Osu/Skinning/LegacySliderBall.cs b/osu.Game.Rulesets.Osu/Skinning/LegacySliderBall.cs index 27dec1b691..25ab96445a 100644 --- a/osu.Game.Rulesets.Osu/Skinning/LegacySliderBall.cs +++ b/osu.Game.Rulesets.Osu/Skinning/LegacySliderBall.cs @@ -39,11 +39,11 @@ namespace osu.Game.Rulesets.Osu.Skinning Texture = skin.GetTexture("sliderb-nd"), Colour = new Color4(5, 5, 5, 255), }, - animationContent.WithLegacyColour(ballColour).With(d => + LegacyColourCompatibility.ApplyWithDoubledAlpha(animationContent.With(d => { d.Anchor = Anchor.Centre; d.Origin = Anchor.Centre; - }), + }), ballColour), layerSpec = new Sprite { Anchor = Anchor.Centre, diff --git a/osu.Game.Rulesets.Taiko/Skinning/LegacyCirclePiece.cs b/osu.Game.Rulesets.Taiko/Skinning/LegacyCirclePiece.cs index ed69b529ed..9b73ccd248 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/LegacyCirclePiece.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/LegacyCirclePiece.cs @@ -90,7 +90,7 @@ namespace osu.Game.Rulesets.Taiko.Skinning private void updateAccentColour() { - backgroundLayer.Colour = accentColour.ToLegacyColour(); + backgroundLayer.Colour = LegacyColourCompatibility.DisallowZeroAlpha(accentColour); } } } diff --git a/osu.Game.Rulesets.Taiko/Skinning/LegacyDrumRoll.cs b/osu.Game.Rulesets.Taiko/Skinning/LegacyDrumRoll.cs index 6bb8f9433e..025eff53d5 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/LegacyDrumRoll.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/LegacyDrumRoll.cs @@ -76,9 +76,9 @@ namespace osu.Game.Rulesets.Taiko.Skinning private void updateAccentColour() { - headCircle.AccentColour = accentColour.ToLegacyColour(); - body.Colour = accentColour.ToLegacyColour(); - end.Colour = accentColour.ToLegacyColour(); + headCircle.AccentColour = LegacyColourCompatibility.DisallowZeroAlpha(accentColour); + body.Colour = LegacyColourCompatibility.DisallowZeroAlpha(accentColour); + end.Colour = LegacyColourCompatibility.DisallowZeroAlpha(accentColour); } } } diff --git a/osu.Game.Rulesets.Taiko/Skinning/LegacyHit.cs b/osu.Game.Rulesets.Taiko/Skinning/LegacyHit.cs index f36aae205a..b11b64c22c 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/LegacyHit.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/LegacyHit.cs @@ -19,9 +19,10 @@ namespace osu.Game.Rulesets.Taiko.Skinning [BackgroundDependencyLoader] private void load() { - AccentColour = (component == TaikoSkinComponents.CentreHit - ? new Color4(235, 69, 44, 255) - : new Color4(67, 142, 172, 255)).ToLegacyColour(); + AccentColour = LegacyColourCompatibility.DisallowZeroAlpha( + component == TaikoSkinComponents.CentreHit + ? new Color4(235, 69, 44, 255) + : new Color4(67, 142, 172, 255)); } } } diff --git a/osu.Game/Skinning/LegacyColourCompatibility.cs b/osu.Game/Skinning/LegacyColourCompatibility.cs new file mode 100644 index 0000000000..b842b50426 --- /dev/null +++ b/osu.Game/Skinning/LegacyColourCompatibility.cs @@ -0,0 +1,46 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Graphics; +using osuTK.Graphics; + +namespace osu.Game.Skinning +{ + /// + /// Compatibility methods to convert osu!stable colours to osu!lazer-compatible ones. Should be used for legacy skins only. + /// + public static class LegacyColourCompatibility + { + /// + /// Forces an alpha of 1 if a given is fully transparent. + /// + /// + /// This is equivalent to setting colour post-constructor in osu!stable. + /// + /// The to disallow zero alpha on. + /// The resultant . + public static Color4 DisallowZeroAlpha(Color4 colour) + { + if (colour.A == 0) + colour.A = 1; + return colour; + } + + /// + /// Applies a to a , doubling the alpha value into the property. + /// + /// + /// This is equivalent to setting colour in the constructor in osu!stable. + /// + /// The to apply the colour to. + /// The to apply. + /// The given . + public static T ApplyWithDoubledAlpha(T drawable, Color4 colour) + where T : Drawable + { + drawable.Alpha = colour.A; + drawable.Colour = DisallowZeroAlpha(colour); + return drawable; + } + } +} diff --git a/osu.Game/Skinning/LegacySkinExtensions.cs b/osu.Game/Skinning/LegacySkinExtensions.cs index 7420f82f04..bb46dc8b9f 100644 --- a/osu.Game/Skinning/LegacySkinExtensions.cs +++ b/osu.Game/Skinning/LegacySkinExtensions.cs @@ -9,7 +9,6 @@ using osu.Framework.Graphics.Animations; using osu.Framework.Graphics.OpenGL.Textures; using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Textures; -using osuTK.Graphics; using static osu.Game.Skinning.LegacySkinConfiguration; namespace osu.Game.Skinning @@ -63,36 +62,6 @@ namespace osu.Game.Skinning } } - /// - /// The resultant colour after setting a post-constructor colour in osu!stable. - /// - /// The to convert. - /// The converted . - public static Color4 ToLegacyColour(this Color4 colour) - { - if (colour.A == 0) - colour.A = 1; - return colour; - } - - /// - /// Equivalent of setting a colour in the constructor in osu!stable. - /// Doubles the alpha channel into and uses to set . - /// - /// - /// Beware: Any existing value in is overwritten. - /// - /// The to set the colour of. - /// The to set. - /// The given . - public static T WithLegacyColour(this T drawable, Color4 colour) - where T : Drawable - { - drawable.Alpha = colour.A; - drawable.Colour = ToLegacyColour(colour); - return drawable; - } - public class SkinnableTextureAnimation : TextureAnimation { [Resolved(canBeNull: true)] From 7a70d063428890ee92e843001b31c08433ebe3fc Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 25 Aug 2020 15:35:37 +0900 Subject: [PATCH 310/434] Add support for custom LightingN paths --- osu.Game/Skinning/LegacyManiaSkinDecoder.cs | 1 + osu.Game/Skinning/LegacySkin.cs | 3 +++ 2 files changed, 4 insertions(+) diff --git a/osu.Game/Skinning/LegacyManiaSkinDecoder.cs b/osu.Game/Skinning/LegacyManiaSkinDecoder.cs index aebc229f7c..1e6102eaa4 100644 --- a/osu.Game/Skinning/LegacyManiaSkinDecoder.cs +++ b/osu.Game/Skinning/LegacyManiaSkinDecoder.cs @@ -116,6 +116,7 @@ namespace osu.Game.Skinning case string _ when pair.Key.StartsWith("KeyImage"): case string _ when pair.Key.StartsWith("Hit"): case string _ when pair.Key.StartsWith("Stage"): + case string _ when pair.Key.StartsWith("Lighting"): currentConfig.ImageLookups[pair.Key] = pair.Value; break; } diff --git a/osu.Game/Skinning/LegacySkin.cs b/osu.Game/Skinning/LegacySkin.cs index 02d07eee45..10fb476728 100644 --- a/osu.Game/Skinning/LegacySkin.cs +++ b/osu.Game/Skinning/LegacySkin.cs @@ -173,6 +173,9 @@ namespace osu.Game.Skinning case LegacyManiaSkinConfigurationLookups.ShowJudgementLine: return SkinUtils.As(new Bindable(existing.ShowJudgementLine)); + case LegacyManiaSkinConfigurationLookups.ExplosionImage: + return SkinUtils.As(getManiaImage(existing, "LightingN")); + case LegacyManiaSkinConfigurationLookups.ExplosionScale: Debug.Assert(maniaLookup.TargetColumn != null); From ff72ccabd8c15a98e597eb7464d6f5833cc122fd Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 25 Aug 2020 18:44:32 +0900 Subject: [PATCH 311/434] Rename method --- osu.Game.Rulesets.Mania/Skinning/LegacyStageBackground.cs | 2 +- osu.Game.Rulesets.Mania/UI/ColumnFlow.cs | 4 ++-- osu.Game.Rulesets.Mania/UI/Stage.cs | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Skinning/LegacyStageBackground.cs b/osu.Game.Rulesets.Mania/Skinning/LegacyStageBackground.cs index 675c154b82..19ec86b1ed 100644 --- a/osu.Game.Rulesets.Mania/Skinning/LegacyStageBackground.cs +++ b/osu.Game.Rulesets.Mania/Skinning/LegacyStageBackground.cs @@ -66,7 +66,7 @@ namespace osu.Game.Rulesets.Mania.Skinning }; for (int i = 0; i < stageDefinition.Columns; i++) - columnBackgrounds.SetColumn(i, new ColumnBackground(i, i == stageDefinition.Columns - 1)); + columnBackgrounds.SetContentForColumn(i, new ColumnBackground(i, i == stageDefinition.Columns - 1)); } protected override void Update() diff --git a/osu.Game.Rulesets.Mania/UI/ColumnFlow.cs b/osu.Game.Rulesets.Mania/UI/ColumnFlow.cs index 37ad5c609b..aef82d4c08 100644 --- a/osu.Game.Rulesets.Mania/UI/ColumnFlow.cs +++ b/osu.Game.Rulesets.Mania/UI/ColumnFlow.cs @@ -14,7 +14,7 @@ namespace osu.Game.Rulesets.Mania.UI { /// /// A which flows its contents according to the s in a . - /// Content can be added to individual columns via . + /// Content can be added to individual columns via . /// /// The type of content in each column. public class ColumnFlow : CompositeDrawable @@ -86,7 +86,7 @@ namespace osu.Game.Rulesets.Mania.UI /// /// The index of the column to set the content of. /// The content. - public void SetColumn(int column, TContent content) => columns[column].Child = content; + public void SetContentForColumn(int column, TContent content) => columns[column].Child = content; public new MarginPadding Padding { diff --git a/osu.Game.Rulesets.Mania/UI/Stage.cs b/osu.Game.Rulesets.Mania/UI/Stage.cs index dfb1ee210d..f4b00ec476 100644 --- a/osu.Game.Rulesets.Mania/UI/Stage.cs +++ b/osu.Game.Rulesets.Mania/UI/Stage.cs @@ -128,7 +128,7 @@ namespace osu.Game.Rulesets.Mania.UI }; topLevelContainer.Add(column.TopLevelContainer.CreateProxy()); - columnFlow.SetColumn(i, column); + columnFlow.SetContentForColumn(i, column); AddNested(column); } } From 6c7475f085f1a06b238226d71f27e528b222fbf3 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 25 Aug 2020 18:56:15 +0900 Subject: [PATCH 312/434] Fix snapped distances potentially exceeding the source distance This results in slider placement including "excess" length, where the curve is not applied to the placed path. This is generally not what we want. I considered adding a bool parameter (or enum) to change the floor/rounding mode, but on further examination I think this is what we always expect from this function. --- .../TestSceneHitObjectComposerDistanceSnapping.cs | 14 +++++++------- osu.Game/Rulesets/Edit/HitObjectComposer.cs | 8 +++++++- osu.Game/Rulesets/Edit/IPositionSnapProvider.cs | 1 + 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/osu.Game.Tests/Editing/TestSceneHitObjectComposerDistanceSnapping.cs b/osu.Game.Tests/Editing/TestSceneHitObjectComposerDistanceSnapping.cs index 168ec0f09d..bd34eaff63 100644 --- a/osu.Game.Tests/Editing/TestSceneHitObjectComposerDistanceSnapping.cs +++ b/osu.Game.Tests/Editing/TestSceneHitObjectComposerDistanceSnapping.cs @@ -169,17 +169,17 @@ namespace osu.Game.Tests.Editing [Test] public void GetSnappedDistanceFromDistance() { - assertSnappedDistance(50, 100); + assertSnappedDistance(50, 0); assertSnappedDistance(100, 100); - assertSnappedDistance(150, 200); + assertSnappedDistance(150, 100); assertSnappedDistance(200, 200); - assertSnappedDistance(250, 300); + assertSnappedDistance(250, 200); AddStep("set slider multiplier = 2", () => composer.EditorBeatmap.BeatmapInfo.BaseDifficulty.SliderMultiplier = 2); assertSnappedDistance(50, 0); - assertSnappedDistance(100, 200); - assertSnappedDistance(150, 200); + assertSnappedDistance(100, 0); + assertSnappedDistance(150, 0); assertSnappedDistance(200, 200); assertSnappedDistance(250, 200); @@ -190,8 +190,8 @@ namespace osu.Game.Tests.Editing }); assertSnappedDistance(50, 0); - assertSnappedDistance(100, 200); - assertSnappedDistance(150, 200); + assertSnappedDistance(100, 0); + assertSnappedDistance(150, 0); assertSnappedDistance(200, 200); assertSnappedDistance(250, 200); assertSnappedDistance(400, 400); diff --git a/osu.Game/Rulesets/Edit/HitObjectComposer.cs b/osu.Game/Rulesets/Edit/HitObjectComposer.cs index c25fb03fd0..d0b06ce0ad 100644 --- a/osu.Game/Rulesets/Edit/HitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/HitObjectComposer.cs @@ -293,7 +293,13 @@ namespace osu.Game.Rulesets.Edit public override float GetSnappedDistanceFromDistance(double referenceTime, float distance) { - var snappedEndTime = BeatSnapProvider.SnapTime(referenceTime + DistanceToDuration(referenceTime, distance), referenceTime); + double actualDuration = referenceTime + DistanceToDuration(referenceTime, distance); + + double snappedEndTime = BeatSnapProvider.SnapTime(actualDuration, referenceTime); + + // we don't want to exceed the actual duration and snap to a point in the future. + if (snappedEndTime > actualDuration) + snappedEndTime -= BeatSnapProvider.GetBeatLengthAtTime(referenceTime); return DurationToDistance(referenceTime, snappedEndTime - referenceTime); } diff --git a/osu.Game/Rulesets/Edit/IPositionSnapProvider.cs b/osu.Game/Rulesets/Edit/IPositionSnapProvider.cs index c854c06031..cce631464f 100644 --- a/osu.Game/Rulesets/Edit/IPositionSnapProvider.cs +++ b/osu.Game/Rulesets/Edit/IPositionSnapProvider.cs @@ -47,6 +47,7 @@ namespace osu.Game.Rulesets.Edit /// /// Converts an unsnapped distance to a snapped distance. + /// The returned distance will always be floored (as to never exceed the provided . /// /// The time of the timing point which resides in. /// The distance to convert. From c09cef4fca2d5264d96958cc388534012aa7ede0 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 25 Aug 2020 19:39:03 +0900 Subject: [PATCH 313/434] Apply post-merge fixes to LegacyStageBackground --- .../Skinning/LegacyStageBackground.cs | 29 ++++++++++--------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Skinning/LegacyStageBackground.cs b/osu.Game.Rulesets.Mania/Skinning/LegacyStageBackground.cs index 19ec86b1ed..16a6123724 100644 --- a/osu.Game.Rulesets.Mania/Skinning/LegacyStageBackground.cs +++ b/osu.Game.Rulesets.Mania/Skinning/LegacyStageBackground.cs @@ -108,37 +108,38 @@ namespace osu.Game.Rulesets.Mania.Skinning InternalChildren = new Drawable[] { - new Container + LegacyColourCompatibility.ApplyWithDoubledAlpha(new Box { - RelativeSizeAxes = Axes.Both, - Child = new Box - { - RelativeSizeAxes = Axes.Both, - Colour = backgroundColour - }, - }, + RelativeSizeAxes = Axes.Both + }, backgroundColour), new HitTargetInsetContainer { RelativeSizeAxes = Axes.Both, Children = new[] { - new Box + new Container { RelativeSizeAxes = Axes.Y, Width = leftLineWidth, Scale = new Vector2(0.740f, 1), - Colour = lineColour, - Alpha = hasLeftLine ? 1 : 0 + Alpha = hasLeftLine ? 1 : 0, + Child = LegacyColourCompatibility.ApplyWithDoubledAlpha(new Box + { + RelativeSizeAxes = Axes.Both + }, lineColour) }, - new Box + new Container { Anchor = Anchor.TopRight, Origin = Anchor.TopRight, RelativeSizeAxes = Axes.Y, Width = rightLineWidth, Scale = new Vector2(0.740f, 1), - Colour = lineColour, - Alpha = hasRightLine ? 1 : 0 + Alpha = hasRightLine ? 1 : 0, + Child = LegacyColourCompatibility.ApplyWithDoubledAlpha(new Box + { + RelativeSizeAxes = Axes.Both + }, lineColour) }, } } From 0800e4379689e8ac301ea8906f4a0e9ce7e518ce Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 25 Aug 2020 19:57:49 +0900 Subject: [PATCH 314/434] Remove padding from columns --- osu.Game.Rulesets.Mania/UI/Stage.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game.Rulesets.Mania/UI/Stage.cs b/osu.Game.Rulesets.Mania/UI/Stage.cs index f4b00ec476..e7a2de266d 100644 --- a/osu.Game.Rulesets.Mania/UI/Stage.cs +++ b/osu.Game.Rulesets.Mania/UI/Stage.cs @@ -79,7 +79,6 @@ namespace osu.Game.Rulesets.Mania.UI columnFlow = new ColumnFlow(definition) { RelativeSizeAxes = Axes.Y, - Padding = new MarginPadding { Left = COLUMN_SPACING, Right = COLUMN_SPACING }, }, new Container { From 127330b8f9bb7ff7a9d03ad3db5044c002404f37 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 25 Aug 2020 20:57:31 +0900 Subject: [PATCH 315/434] Add 1ms lenience to avoid potential precision issues --- osu.Game/Rulesets/Edit/HitObjectComposer.cs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/osu.Game/Rulesets/Edit/HitObjectComposer.cs b/osu.Game/Rulesets/Edit/HitObjectComposer.cs index d0b06ce0ad..f134db1ffe 100644 --- a/osu.Game/Rulesets/Edit/HitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/HitObjectComposer.cs @@ -25,7 +25,7 @@ using osu.Game.Screens.Edit.Components.RadioButtons; using osu.Game.Screens.Edit.Compose; using osu.Game.Screens.Edit.Compose.Components; using osuTK; -using Key = osuTK.Input.Key; +using osuTK.Input; namespace osu.Game.Rulesets.Edit { @@ -297,9 +297,12 @@ namespace osu.Game.Rulesets.Edit double snappedEndTime = BeatSnapProvider.SnapTime(actualDuration, referenceTime); + double beatLength = BeatSnapProvider.GetBeatLengthAtTime(referenceTime); + // we don't want to exceed the actual duration and snap to a point in the future. - if (snappedEndTime > actualDuration) - snappedEndTime -= BeatSnapProvider.GetBeatLengthAtTime(referenceTime); + // as we are snapping to beat length via SnapTime (which will round-to-nearest), check for snapping in the forward direction and reverse it. + if (snappedEndTime > actualDuration + 1) + snappedEndTime -= beatLength; return DurationToDistance(referenceTime, snappedEndTime - referenceTime); } From f09f882cc77f9264ad1292bc7df4c55ca3b548b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Tue, 25 Aug 2020 22:43:23 +0200 Subject: [PATCH 316/434] Add component for displaying simple statistics on result screen --- .../Ranking/TestSceneSimpleStatisticRow.cs | 68 ++++++++++ .../Ranking/Statistics/SimpleStatisticItem.cs | 80 ++++++++++++ .../Ranking/Statistics/SimpleStatisticRow.cs | 122 ++++++++++++++++++ 3 files changed, 270 insertions(+) create mode 100644 osu.Game.Tests/Visual/Ranking/TestSceneSimpleStatisticRow.cs create mode 100644 osu.Game/Screens/Ranking/Statistics/SimpleStatisticItem.cs create mode 100644 osu.Game/Screens/Ranking/Statistics/SimpleStatisticRow.cs diff --git a/osu.Game.Tests/Visual/Ranking/TestSceneSimpleStatisticRow.cs b/osu.Game.Tests/Visual/Ranking/TestSceneSimpleStatisticRow.cs new file mode 100644 index 0000000000..aa569e47b1 --- /dev/null +++ b/osu.Game.Tests/Visual/Ranking/TestSceneSimpleStatisticRow.cs @@ -0,0 +1,68 @@ +// 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 Humanizer; +using NUnit.Framework; +using osu.Framework.Extensions.Color4Extensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Utils; +using osu.Game.Screens.Ranking.Statistics; + +namespace osu.Game.Tests.Visual.Ranking +{ + public class TestSceneSimpleStatisticRow : OsuTestScene + { + private Container container; + + [SetUp] + public void SetUp() => Schedule(() => + { + Child = new Container + { + AutoSizeAxes = Axes.Y, + Width = 700, + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4Extensions.FromHex("#333"), + }, + container = new Container + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Padding = new MarginPadding(20) + } + } + }; + }); + + [Test] + public void TestEmpty() + { + AddStep("create with no items", + () => container.Add(new SimpleStatisticRow(2, Enumerable.Empty()))); + } + + [Test] + public void TestManyItems( + [Values(1, 2, 3, 4, 12)] int itemCount, + [Values(1, 3, 5)] int columnCount) + { + AddStep($"create with {"item".ToQuantity(itemCount)}", () => + { + var items = Enumerable.Range(1, itemCount) + .Select(i => new SimpleStatisticItem($"Statistic #{i}") + { + Value = RNG.Next(100) + }); + + container.Add(new SimpleStatisticRow(columnCount, items)); + }); + } + } +} diff --git a/osu.Game/Screens/Ranking/Statistics/SimpleStatisticItem.cs b/osu.Game/Screens/Ranking/Statistics/SimpleStatisticItem.cs new file mode 100644 index 0000000000..e6c4ab1c4e --- /dev/null +++ b/osu.Game/Screens/Ranking/Statistics/SimpleStatisticItem.cs @@ -0,0 +1,80 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; + +namespace osu.Game.Screens.Ranking.Statistics +{ + /// + /// Represents a simple statistic item (one that only needs textual display). + /// Richer visualisations should be done with s. + /// + public abstract class SimpleStatisticItem : Container + { + /// + /// The text to display as the statistic's value. + /// + protected string Value + { + set => this.value.Text = value; + } + + private readonly OsuSpriteText value; + + /// + /// Creates a new simple statistic item. + /// + /// The name of the statistic. + protected SimpleStatisticItem(string name) + { + Name = name; + + RelativeSizeAxes = Axes.X; + AutoSizeAxes = Axes.Y; + + AddRange(new[] + { + new OsuSpriteText + { + Text = Name, + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft + }, + value = new OsuSpriteText + { + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight, + Font = OsuFont.Torus.With(weight: FontWeight.Bold) + } + }); + } + } + + /// + /// Strongly-typed generic specialisation for . + /// + public class SimpleStatisticItem : SimpleStatisticItem + { + /// + /// The statistic's value to be displayed. + /// + public new TValue Value + { + set => base.Value = DisplayValue(value); + } + + /// + /// Used to convert to a text representation. + /// Defaults to using . + /// + protected virtual string DisplayValue(TValue value) => value.ToString(); + + public SimpleStatisticItem(string name) + : base(name) + { + } + } +} diff --git a/osu.Game/Screens/Ranking/Statistics/SimpleStatisticRow.cs b/osu.Game/Screens/Ranking/Statistics/SimpleStatisticRow.cs new file mode 100644 index 0000000000..16501aae54 --- /dev/null +++ b/osu.Game/Screens/Ranking/Statistics/SimpleStatisticRow.cs @@ -0,0 +1,122 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System; +using System.Collections.Generic; +using System.Linq; +using osu.Framework.Allocation; +using osu.Framework.Extensions.Color4Extensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; + +namespace osu.Game.Screens.Ranking.Statistics +{ + /// + /// Represents a statistic row with simple statistics (ones that only need textual display). + /// Richer visualisations should be done with s and s. + /// + public class SimpleStatisticRow : CompositeDrawable + { + private readonly SimpleStatisticItem[] items; + private readonly int columnCount; + + private FillFlowContainer[] columns; + + /// + /// Creates a statistic row for the supplied s. + /// + /// The number of columns to layout the into. + /// The s to display in this row. + public SimpleStatisticRow(int columnCount, IEnumerable items) + { + if (columnCount < 1) + throw new ArgumentOutOfRangeException(nameof(columnCount)); + + this.columnCount = columnCount; + this.items = items.ToArray(); + } + + [BackgroundDependencyLoader] + private void load() + { + columns = new FillFlowContainer[columnCount]; + + RelativeSizeAxes = Axes.X; + AutoSizeAxes = Axes.Y; + + InternalChild = new GridContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + RowDimensions = new[] + { + new Dimension(GridSizeMode.AutoSize) + }, + ColumnDimensions = createColumnDimensions().ToArray(), + Content = new[] { createColumns().ToArray() } + }; + + for (int i = 0; i < items.Length; ++i) + columns[i % columnCount].Add(items[i]); + } + + private IEnumerable createColumnDimensions() + { + for (int column = 0; column < columnCount; ++column) + { + if (column > 0) + yield return new Dimension(GridSizeMode.Absolute, 30); + + yield return new Dimension(); + } + } + + private IEnumerable createColumns() + { + for (int column = 0; column < columnCount; ++column) + { + if (column > 0) + { + yield return new Spacer + { + Alpha = items.Length > column ? 1 : 0 + }; + } + + yield return columns[column] = createColumn(); + } + } + + private FillFlowContainer createColumn() => new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Vertical + }; + + private class Spacer : CompositeDrawable + { + public Spacer() + { + RelativeSizeAxes = Axes.Both; + Padding = new MarginPadding { Vertical = 4 }; + + InternalChild = new CircularContainer + { + RelativeSizeAxes = Axes.Y, + Width = 3, + Origin = Anchor.Centre, + Anchor = Anchor.Centre, + CornerRadius = 2, + Masking = true, + Child = new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4Extensions.FromHex("#222") + } + }; + } + } + } +} From 2cf2ba8fc5cb0e1648756774d99e81b1f045c70b Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 26 Aug 2020 14:24:04 +0900 Subject: [PATCH 317/434] Store computed accent colour to local --- osu.Game.Rulesets.Taiko/Skinning/LegacyDrumRoll.cs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Skinning/LegacyDrumRoll.cs b/osu.Game.Rulesets.Taiko/Skinning/LegacyDrumRoll.cs index 025eff53d5..5ab8e3a8c8 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/LegacyDrumRoll.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/LegacyDrumRoll.cs @@ -76,9 +76,11 @@ namespace osu.Game.Rulesets.Taiko.Skinning private void updateAccentColour() { - headCircle.AccentColour = LegacyColourCompatibility.DisallowZeroAlpha(accentColour); - body.Colour = LegacyColourCompatibility.DisallowZeroAlpha(accentColour); - end.Colour = LegacyColourCompatibility.DisallowZeroAlpha(accentColour); + var colour = LegacyColourCompatibility.DisallowZeroAlpha(accentColour); + + headCircle.AccentColour = colour; + body.Colour = colour; + end.Colour = colour; } } } From d057f5f4bce9297c9dc65d8eafc85cc585f604d6 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 26 Aug 2020 15:37:16 +0900 Subject: [PATCH 318/434] Implement mania "KeysUnderNotes" skin config --- osu.Game.Rulesets.Mania/Skinning/LegacyKeyArea.cs | 3 +++ osu.Game/Skinning/LegacyManiaSkinConfiguration.cs | 1 + osu.Game/Skinning/LegacyManiaSkinConfigurationLookup.cs | 1 + osu.Game/Skinning/LegacyManiaSkinDecoder.cs | 4 ++++ osu.Game/Skinning/LegacySkin.cs | 3 +++ 5 files changed, 12 insertions(+) diff --git a/osu.Game.Rulesets.Mania/Skinning/LegacyKeyArea.cs b/osu.Game.Rulesets.Mania/Skinning/LegacyKeyArea.cs index 44f3e7d7b3..b269ea25d4 100644 --- a/osu.Game.Rulesets.Mania/Skinning/LegacyKeyArea.cs +++ b/osu.Game.Rulesets.Mania/Skinning/LegacyKeyArea.cs @@ -65,6 +65,9 @@ namespace osu.Game.Rulesets.Mania.Skinning direction.BindTo(scrollingInfo.Direction); direction.BindValueChanged(onDirectionChanged, true); + + if (GetColumnSkinConfig(skin, LegacyManiaSkinConfigurationLookups.KeysUnderNotes)?.Value ?? false) + Column.UnderlayElements.Add(CreateProxy()); } private void onDirectionChanged(ValueChangedEvent direction) diff --git a/osu.Game/Skinning/LegacyManiaSkinConfiguration.cs b/osu.Game/Skinning/LegacyManiaSkinConfiguration.cs index af7d6007f3..a5cc899b53 100644 --- a/osu.Game/Skinning/LegacyManiaSkinConfiguration.cs +++ b/osu.Game/Skinning/LegacyManiaSkinConfiguration.cs @@ -35,6 +35,7 @@ namespace osu.Game.Skinning public float HitPosition = (480 - 402) * POSITION_SCALE_FACTOR; public float LightPosition = (480 - 413) * POSITION_SCALE_FACTOR; public bool ShowJudgementLine = true; + public bool KeysUnderNotes; public LegacyManiaSkinConfiguration(int keys) { diff --git a/osu.Game/Skinning/LegacyManiaSkinConfigurationLookup.cs b/osu.Game/Skinning/LegacyManiaSkinConfigurationLookup.cs index 4990ca8e60..890a0cc4ff 100644 --- a/osu.Game/Skinning/LegacyManiaSkinConfigurationLookup.cs +++ b/osu.Game/Skinning/LegacyManiaSkinConfigurationLookup.cs @@ -50,5 +50,6 @@ namespace osu.Game.Skinning Hit100, Hit50, Hit0, + KeysUnderNotes, } } diff --git a/osu.Game/Skinning/LegacyManiaSkinDecoder.cs b/osu.Game/Skinning/LegacyManiaSkinDecoder.cs index aebc229f7c..1ea120e8a4 100644 --- a/osu.Game/Skinning/LegacyManiaSkinDecoder.cs +++ b/osu.Game/Skinning/LegacyManiaSkinDecoder.cs @@ -97,6 +97,10 @@ namespace osu.Game.Skinning currentConfig.ShowJudgementLine = pair.Value == "1"; break; + case "KeysUnderNotes": + currentConfig.KeysUnderNotes = pair.Value == "1"; + break; + case "LightingNWidth": parseArrayValue(pair.Value, currentConfig.ExplosionWidth); break; diff --git a/osu.Game/Skinning/LegacySkin.cs b/osu.Game/Skinning/LegacySkin.cs index 02d07eee45..13a43c8aae 100644 --- a/osu.Game/Skinning/LegacySkin.cs +++ b/osu.Game/Skinning/LegacySkin.cs @@ -255,6 +255,9 @@ namespace osu.Game.Skinning case LegacyManiaSkinConfigurationLookups.Hit300: case LegacyManiaSkinConfigurationLookups.Hit300g: return SkinUtils.As(getManiaImage(existing, maniaLookup.Lookup.ToString())); + + case LegacyManiaSkinConfigurationLookups.KeysUnderNotes: + return SkinUtils.As(new Bindable(existing.KeysUnderNotes)); } return null; From c50e495e035bad956cf1883f510a41c2eb3e867a Mon Sep 17 00:00:00 2001 From: Poliwrath Date: Wed, 26 Aug 2020 02:49:55 -0400 Subject: [PATCH 319/434] fix lingering small ring in circles! intro --- osu.Game/Screens/Menu/IntroSequence.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Screens/Menu/IntroSequence.cs b/osu.Game/Screens/Menu/IntroSequence.cs index 6731fef6f7..98da31b93e 100644 --- a/osu.Game/Screens/Menu/IntroSequence.cs +++ b/osu.Game/Screens/Menu/IntroSequence.cs @@ -205,6 +205,7 @@ namespace osu.Game.Screens.Menu const int line_end_offset = 120; smallRing.Foreground.ResizeTo(1, line_duration, Easing.OutQuint); + smallRing.Delay(400).FadeOut(); lineTopLeft.MoveTo(new Vector2(-line_end_offset, -line_end_offset), line_duration, Easing.OutQuint); lineTopRight.MoveTo(new Vector2(line_end_offset, -line_end_offset), line_duration, Easing.OutQuint); From 97637bc747aaba00507f28f1c582e181fa7a7694 Mon Sep 17 00:00:00 2001 From: Poliwrath Date: Wed, 26 Aug 2020 01:59:53 -0400 Subject: [PATCH 320/434] remove new.ppy.sh from MessageFormatter --- osu.Game/Online/Chat/MessageFormatter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Online/Chat/MessageFormatter.cs b/osu.Game/Online/Chat/MessageFormatter.cs index 6af2561c89..648e4a762b 100644 --- a/osu.Game/Online/Chat/MessageFormatter.cs +++ b/osu.Game/Online/Chat/MessageFormatter.cs @@ -119,7 +119,7 @@ namespace osu.Game.Online.Chat case "http": case "https": // length > 3 since all these links need another argument to work - if (args.Length > 3 && (args[1] == "osu.ppy.sh" || args[1] == "new.ppy.sh")) + if (args.Length > 3 && args[1] == "osu.ppy.sh") { switch (args[2]) { From e6116890afbdcf93c7d032844b1670f9172a24ca Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 26 Aug 2020 20:00:38 +0900 Subject: [PATCH 321/434] Make hitobject tests display the column --- .../Skinning/ColumnTestContainer.cs | 24 +++++++++++-------- .../Skinning/ManiaHitObjectTestScene.cs | 4 ++-- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/osu.Game.Rulesets.Mania.Tests/Skinning/ColumnTestContainer.cs b/osu.Game.Rulesets.Mania.Tests/Skinning/ColumnTestContainer.cs index ff4865c71d..8ba58e3af3 100644 --- a/osu.Game.Rulesets.Mania.Tests/Skinning/ColumnTestContainer.cs +++ b/osu.Game.Rulesets.Mania.Tests/Skinning/ColumnTestContainer.cs @@ -22,18 +22,22 @@ namespace osu.Game.Rulesets.Mania.Tests.Skinning [Cached] private readonly Column column; - public ColumnTestContainer(int column, ManiaAction action) + public ColumnTestContainer(int column, ManiaAction action, bool showColumn = false) { - this.column = new Column(column) + InternalChildren = new[] { - Action = { Value = action }, - AccentColour = Color4.Orange, - ColumnType = column % 2 == 0 ? ColumnType.Even : ColumnType.Odd - }; - - InternalChild = content = new ManiaInputManager(new ManiaRuleset().RulesetInfo, 4) - { - RelativeSizeAxes = Axes.Both + this.column = new Column(column) + { + Action = { Value = action }, + AccentColour = Color4.Orange, + ColumnType = column % 2 == 0 ? ColumnType.Even : ColumnType.Odd, + Alpha = showColumn ? 1 : 0 + }, + content = new ManiaInputManager(new ManiaRuleset().RulesetInfo, 4) + { + RelativeSizeAxes = Axes.Both + }, + this.column.TopLevelContainer.CreateProxy() }; } } diff --git a/osu.Game.Rulesets.Mania.Tests/Skinning/ManiaHitObjectTestScene.cs b/osu.Game.Rulesets.Mania.Tests/Skinning/ManiaHitObjectTestScene.cs index 18eebada00..d24c81dac6 100644 --- a/osu.Game.Rulesets.Mania.Tests/Skinning/ManiaHitObjectTestScene.cs +++ b/osu.Game.Rulesets.Mania.Tests/Skinning/ManiaHitObjectTestScene.cs @@ -27,7 +27,7 @@ namespace osu.Game.Rulesets.Mania.Tests.Skinning Direction = FillDirection.Horizontal, Children = new Drawable[] { - new ColumnTestContainer(0, ManiaAction.Key1) + new ColumnTestContainer(0, ManiaAction.Key1, true) { Anchor = Anchor.Centre, Origin = Anchor.Centre, @@ -45,7 +45,7 @@ namespace osu.Game.Rulesets.Mania.Tests.Skinning })); }) }, - new ColumnTestContainer(1, ManiaAction.Key2) + new ColumnTestContainer(1, ManiaAction.Key2, true) { Anchor = Anchor.Centre, Origin = Anchor.Centre, From c0c67c11b12d0df3b318c763f196f383f91f2f8c Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 26 Aug 2020 20:21:41 +0900 Subject: [PATCH 322/434] Add parsing for hold note light/scale --- osu.Game/Skinning/LegacyManiaSkinConfiguration.cs | 2 ++ .../Skinning/LegacyManiaSkinConfigurationLookup.cs | 2 ++ osu.Game/Skinning/LegacyManiaSkinDecoder.cs | 4 ++++ osu.Game/Skinning/LegacySkin.cs | 14 ++++++++++++++ 4 files changed, 22 insertions(+) diff --git a/osu.Game/Skinning/LegacyManiaSkinConfiguration.cs b/osu.Game/Skinning/LegacyManiaSkinConfiguration.cs index af7d6007f3..18ae6acb38 100644 --- a/osu.Game/Skinning/LegacyManiaSkinConfiguration.cs +++ b/osu.Game/Skinning/LegacyManiaSkinConfiguration.cs @@ -31,6 +31,7 @@ namespace osu.Game.Skinning public readonly float[] ColumnSpacing; public readonly float[] ColumnWidth; public readonly float[] ExplosionWidth; + public readonly float[] HoldNoteLightWidth; public float HitPosition = (480 - 402) * POSITION_SCALE_FACTOR; public float LightPosition = (480 - 413) * POSITION_SCALE_FACTOR; @@ -44,6 +45,7 @@ namespace osu.Game.Skinning ColumnSpacing = new float[keys - 1]; ColumnWidth = new float[keys]; ExplosionWidth = new float[keys]; + HoldNoteLightWidth = new float[keys]; ColumnLineWidth.AsSpan().Fill(2); ColumnWidth.AsSpan().Fill(DEFAULT_COLUMN_SIZE); diff --git a/osu.Game/Skinning/LegacyManiaSkinConfigurationLookup.cs b/osu.Game/Skinning/LegacyManiaSkinConfigurationLookup.cs index 4990ca8e60..131c3fde34 100644 --- a/osu.Game/Skinning/LegacyManiaSkinConfigurationLookup.cs +++ b/osu.Game/Skinning/LegacyManiaSkinConfigurationLookup.cs @@ -34,6 +34,8 @@ namespace osu.Game.Skinning HoldNoteHeadImage, HoldNoteTailImage, HoldNoteBodyImage, + HoldNoteLightImage, + HoldNoteLightScale, ExplosionImage, ExplosionScale, ColumnLineColour, diff --git a/osu.Game/Skinning/LegacyManiaSkinDecoder.cs b/osu.Game/Skinning/LegacyManiaSkinDecoder.cs index 1e6102eaa4..ca492b5a21 100644 --- a/osu.Game/Skinning/LegacyManiaSkinDecoder.cs +++ b/osu.Game/Skinning/LegacyManiaSkinDecoder.cs @@ -101,6 +101,10 @@ namespace osu.Game.Skinning parseArrayValue(pair.Value, currentConfig.ExplosionWidth); break; + case "LightingLWidth": + parseArrayValue(pair.Value, currentConfig.HoldNoteLightWidth); + break; + case "WidthForNoteHeightScale": float minWidth = float.Parse(pair.Value, CultureInfo.InvariantCulture) * LegacyManiaSkinConfiguration.POSITION_SCALE_FACTOR; if (minWidth > 0) diff --git a/osu.Game/Skinning/LegacySkin.cs b/osu.Game/Skinning/LegacySkin.cs index 10fb476728..628169584a 100644 --- a/osu.Game/Skinning/LegacySkin.cs +++ b/osu.Game/Skinning/LegacySkin.cs @@ -220,6 +220,20 @@ namespace osu.Game.Skinning Debug.Assert(maniaLookup.TargetColumn != null); return SkinUtils.As(getManiaImage(existing, $"NoteImage{maniaLookup.TargetColumn}L")); + case LegacyManiaSkinConfigurationLookups.HoldNoteLightImage: + return SkinUtils.As(getManiaImage(existing, "LightingL")); + + case LegacyManiaSkinConfigurationLookups.HoldNoteLightScale: + Debug.Assert(maniaLookup.TargetColumn != null); + + if (GetConfig(LegacySkinConfiguration.LegacySetting.Version)?.Value < 2.5m) + return SkinUtils.As(new Bindable(1)); + + if (existing.HoldNoteLightWidth[maniaLookup.TargetColumn.Value] != 0) + return SkinUtils.As(new Bindable(existing.HoldNoteLightWidth[maniaLookup.TargetColumn.Value] / LegacyManiaSkinConfiguration.DEFAULT_COLUMN_SIZE)); + + return SkinUtils.As(new Bindable(existing.ColumnWidth[maniaLookup.TargetColumn.Value] / LegacyManiaSkinConfiguration.DEFAULT_COLUMN_SIZE)); + case LegacyManiaSkinConfigurationLookups.KeyImage: Debug.Assert(maniaLookup.TargetColumn != null); return SkinUtils.As(getManiaImage(existing, $"KeyImage{maniaLookup.TargetColumn}")); From 9372c6eef6e90ff35d5bdd81d332dbded910416b Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 26 Aug 2020 20:21:56 +0900 Subject: [PATCH 323/434] Implement hold note lighting --- .../Objects/Drawables/DrawableHoldNote.cs | 3 + .../Skinning/LegacyBodyPiece.cs | 124 +++++++++++++++--- 2 files changed, 112 insertions(+), 15 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs index a44f8a8886..4f29e0417e 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs @@ -159,7 +159,10 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables protected override void CheckForResult(bool userTriggered, double timeOffset) { if (Tail.AllJudged) + { ApplyResult(r => r.Type = HitResult.Perfect); + endHold(); + } if (Tail.Result.Type == HitResult.Miss) HasBroken = true; diff --git a/osu.Game.Rulesets.Mania/Skinning/LegacyBodyPiece.cs b/osu.Game.Rulesets.Mania/Skinning/LegacyBodyPiece.cs index 9f716428c0..d922934532 100644 --- a/osu.Game.Rulesets.Mania/Skinning/LegacyBodyPiece.cs +++ b/osu.Game.Rulesets.Mania/Skinning/LegacyBodyPiece.cs @@ -1,12 +1,15 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Animations; +using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.OpenGL.Textures; using osu.Game.Rulesets.Mania.Objects.Drawables; +using osu.Game.Rulesets.Mania.UI; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.UI.Scrolling; using osu.Game.Skinning; @@ -19,7 +22,9 @@ namespace osu.Game.Rulesets.Mania.Skinning private readonly IBindable direction = new Bindable(); private readonly IBindable isHitting = new Bindable(); - private Drawable sprite; + private Drawable bodySprite; + private Drawable lightContainer; + private Drawable light; public LegacyBodyPiece() { @@ -32,7 +37,33 @@ namespace osu.Game.Rulesets.Mania.Skinning string imageName = GetColumnSkinConfig(skin, LegacyManiaSkinConfigurationLookups.HoldNoteBodyImage)?.Value ?? $"mania-note{FallbackColumnIndex}L"; - sprite = skin.GetAnimation(imageName, WrapMode.ClampToEdge, WrapMode.ClampToEdge, true, true).With(d => + string lightImage = GetColumnSkinConfig(skin, LegacyManiaSkinConfigurationLookups.HoldNoteLightImage)?.Value + ?? "lightingL"; + + float lightScale = GetColumnSkinConfig(skin, LegacyManiaSkinConfigurationLookups.HoldNoteLightScale)?.Value + ?? 1; + + // Create a temporary animation to retrieve the number of frames, in an effort to calculate the intended frame length. + // This animation is discarded and re-queried with the appropriate frame length afterwards. + var tmp = skin.GetAnimation(lightImage, true, false); + double frameLength = 0; + if (tmp is IFramedAnimation tmpAnimation && tmpAnimation.FrameCount > 0) + frameLength = Math.Max(1000 / 60.0, 170.0 / tmpAnimation.FrameCount); + + light = skin.GetAnimation(lightImage, true, true, frameLength: frameLength).With(d => + { + if (d == null) + return; + + d.Origin = Anchor.Centre; + d.Blending = BlendingParameters.Additive; + d.Scale = new Vector2(lightScale); + }); + + if (light != null) + lightContainer = new HitTargetInsetContainer { Child = light }; + + bodySprite = skin.GetAnimation(imageName, WrapMode.ClampToEdge, WrapMode.ClampToEdge, true, true).With(d => { if (d == null) return; @@ -47,8 +78,8 @@ namespace osu.Game.Rulesets.Mania.Skinning // Todo: Wrap }); - if (sprite != null) - InternalChild = sprite; + if (bodySprite != null) + InternalChild = bodySprite; direction.BindTo(scrollingInfo.Direction); direction.BindValueChanged(onDirectionChanged, true); @@ -60,27 +91,90 @@ namespace osu.Game.Rulesets.Mania.Skinning private void onIsHittingChanged(ValueChangedEvent isHitting) { - if (!(sprite is TextureAnimation animation)) - return; + if (bodySprite is TextureAnimation bodyAnimation) + { + bodyAnimation.GotoFrame(0); + bodyAnimation.IsPlaying = isHitting.NewValue; + } - animation.GotoFrame(0); - animation.IsPlaying = isHitting.NewValue; + if (lightContainer != null) + { + if (isHitting.NewValue) + { + Column.TopLevelContainer.Add(lightContainer); + + // The light must be seeked only after being loaded, otherwise a nullref happens (https://github.com/ppy/osu-framework/issues/3847). + if (light is TextureAnimation lightAnimation) + lightAnimation.GotoFrame(0); + } + else + Column.TopLevelContainer.Remove(lightContainer); + } } private void onDirectionChanged(ValueChangedEvent direction) { - if (sprite == null) - return; - if (direction.NewValue == ScrollingDirection.Up) { - sprite.Origin = Anchor.BottomCentre; - sprite.Scale = new Vector2(1, -1); + if (bodySprite != null) + { + bodySprite.Origin = Anchor.BottomCentre; + bodySprite.Scale = new Vector2(1, -1); + } + + if (light != null) + light.Anchor = Anchor.TopCentre; } else { - sprite.Origin = Anchor.TopCentre; - sprite.Scale = Vector2.One; + if (bodySprite != null) + { + bodySprite.Origin = Anchor.TopCentre; + bodySprite.Scale = Vector2.One; + } + + if (light != null) + light.Anchor = Anchor.BottomCentre; + } + } + + protected override void Dispose(bool isDisposing) + { + base.Dispose(isDisposing); + + lightContainer?.Expire(); + } + + private class HitTargetInsetContainer : Container + { + private readonly IBindable direction = new Bindable(); + + protected override Container Content => content; + private readonly Container content; + + private float hitPosition; + + public HitTargetInsetContainer() + { + RelativeSizeAxes = Axes.Both; + + InternalChild = content = new Container { RelativeSizeAxes = Axes.Both }; + } + + [BackgroundDependencyLoader] + private void load(ISkinSource skin, IScrollingInfo scrollingInfo) + { + hitPosition = skin.GetManiaSkinConfig(LegacyManiaSkinConfigurationLookups.HitPosition)?.Value ?? Stage.HIT_TARGET_POSITION; + + direction.BindTo(scrollingInfo.Direction); + direction.BindValueChanged(onDirectionChanged, true); + } + + private void onDirectionChanged(ValueChangedEvent direction) + { + content.Padding = direction.NewValue == ScrollingDirection.Up + ? new MarginPadding { Top = hitPosition } + : new MarginPadding { Bottom = hitPosition }; } } } From 6fe1279e9deb3b3bea1ec7c53b2695fd47d6eb30 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 26 Aug 2020 20:23:01 +0900 Subject: [PATCH 324/434] Re-use existing inset container --- .../Skinning/HitTargetInsetContainer.cs | 46 +++++++++++++++++++ .../Skinning/LegacyBodyPiece.cs | 35 -------------- .../Skinning/LegacyStageBackground.cs | 35 -------------- 3 files changed, 46 insertions(+), 70 deletions(-) create mode 100644 osu.Game.Rulesets.Mania/Skinning/HitTargetInsetContainer.cs diff --git a/osu.Game.Rulesets.Mania/Skinning/HitTargetInsetContainer.cs b/osu.Game.Rulesets.Mania/Skinning/HitTargetInsetContainer.cs new file mode 100644 index 0000000000..c8b05ed2f8 --- /dev/null +++ b/osu.Game.Rulesets.Mania/Skinning/HitTargetInsetContainer.cs @@ -0,0 +1,46 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Allocation; +using osu.Framework.Bindables; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Game.Rulesets.Mania.UI; +using osu.Game.Rulesets.UI.Scrolling; +using osu.Game.Skinning; + +namespace osu.Game.Rulesets.Mania.Skinning +{ + public class HitTargetInsetContainer : Container + { + private readonly IBindable direction = new Bindable(); + + protected override Container Content => content; + private readonly Container content; + + private float hitPosition; + + public HitTargetInsetContainer() + { + RelativeSizeAxes = Axes.Both; + + InternalChild = content = new Container { RelativeSizeAxes = Axes.Both }; + } + + [BackgroundDependencyLoader] + private void load(ISkinSource skin, IScrollingInfo scrollingInfo) + { + hitPosition = skin.GetManiaSkinConfig(LegacyManiaSkinConfigurationLookups.HitPosition)?.Value ?? Stage.HIT_TARGET_POSITION; + + direction.BindTo(scrollingInfo.Direction); + direction.BindValueChanged(onDirectionChanged, true); + } + + private void onDirectionChanged(ValueChangedEvent direction) + { + content.Padding = direction.NewValue == ScrollingDirection.Up + ? new MarginPadding { Top = hitPosition } + : new MarginPadding { Bottom = hitPosition }; + } + } +} diff --git a/osu.Game.Rulesets.Mania/Skinning/LegacyBodyPiece.cs b/osu.Game.Rulesets.Mania/Skinning/LegacyBodyPiece.cs index d922934532..338dd5bb1d 100644 --- a/osu.Game.Rulesets.Mania/Skinning/LegacyBodyPiece.cs +++ b/osu.Game.Rulesets.Mania/Skinning/LegacyBodyPiece.cs @@ -6,10 +6,8 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Animations; -using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.OpenGL.Textures; using osu.Game.Rulesets.Mania.Objects.Drawables; -using osu.Game.Rulesets.Mania.UI; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.UI.Scrolling; using osu.Game.Skinning; @@ -144,38 +142,5 @@ namespace osu.Game.Rulesets.Mania.Skinning lightContainer?.Expire(); } - - private class HitTargetInsetContainer : Container - { - private readonly IBindable direction = new Bindable(); - - protected override Container Content => content; - private readonly Container content; - - private float hitPosition; - - public HitTargetInsetContainer() - { - RelativeSizeAxes = Axes.Both; - - InternalChild = content = new Container { RelativeSizeAxes = Axes.Both }; - } - - [BackgroundDependencyLoader] - private void load(ISkinSource skin, IScrollingInfo scrollingInfo) - { - hitPosition = skin.GetManiaSkinConfig(LegacyManiaSkinConfigurationLookups.HitPosition)?.Value ?? Stage.HIT_TARGET_POSITION; - - direction.BindTo(scrollingInfo.Direction); - direction.BindValueChanged(onDirectionChanged, true); - } - - private void onDirectionChanged(ValueChangedEvent direction) - { - content.Padding = direction.NewValue == ScrollingDirection.Up - ? new MarginPadding { Top = hitPosition } - : new MarginPadding { Bottom = hitPosition }; - } - } } } diff --git a/osu.Game.Rulesets.Mania/Skinning/LegacyStageBackground.cs b/osu.Game.Rulesets.Mania/Skinning/LegacyStageBackground.cs index 19ec86b1ed..ead51d91d7 100644 --- a/osu.Game.Rulesets.Mania/Skinning/LegacyStageBackground.cs +++ b/osu.Game.Rulesets.Mania/Skinning/LegacyStageBackground.cs @@ -2,14 +2,12 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Allocation; -using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Sprites; using osu.Game.Rulesets.Mania.Beatmaps; using osu.Game.Rulesets.Mania.UI; -using osu.Game.Rulesets.UI.Scrolling; using osu.Game.Skinning; using osuTK; using osuTK.Graphics; @@ -145,38 +143,5 @@ namespace osu.Game.Rulesets.Mania.Skinning }; } } - - private class HitTargetInsetContainer : Container - { - private readonly IBindable direction = new Bindable(); - - protected override Container Content => content; - private readonly Container content; - - private float hitPosition; - - public HitTargetInsetContainer() - { - RelativeSizeAxes = Axes.Both; - - InternalChild = content = new Container { RelativeSizeAxes = Axes.Both }; - } - - [BackgroundDependencyLoader] - private void load(ISkinSource skin, IScrollingInfo scrollingInfo) - { - hitPosition = skin.GetManiaSkinConfig(LegacyManiaSkinConfigurationLookups.HitPosition)?.Value ?? Stage.HIT_TARGET_POSITION; - - direction.BindTo(scrollingInfo.Direction); - direction.BindValueChanged(onDirectionChanged, true); - } - - private void onDirectionChanged(ValueChangedEvent direction) - { - content.Padding = direction.NewValue == ScrollingDirection.Up - ? new MarginPadding { Top = hitPosition } - : new MarginPadding { Bottom = hitPosition }; - } - } } } From 157e1d89651a4866b1e413ee1f953eea5058e948 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 26 Aug 2020 20:46:12 +0900 Subject: [PATCH 325/434] Add fades --- .../Skinning/LegacyBodyPiece.cs | 24 +++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Skinning/LegacyBodyPiece.cs b/osu.Game.Rulesets.Mania/Skinning/LegacyBodyPiece.cs index 338dd5bb1d..a1c2559386 100644 --- a/osu.Game.Rulesets.Mania/Skinning/LegacyBodyPiece.cs +++ b/osu.Game.Rulesets.Mania/Skinning/LegacyBodyPiece.cs @@ -59,7 +59,13 @@ namespace osu.Game.Rulesets.Mania.Skinning }); if (light != null) - lightContainer = new HitTargetInsetContainer { Child = light }; + { + lightContainer = new HitTargetInsetContainer + { + Alpha = 0, + Child = light + }; + } bodySprite = skin.GetAnimation(imageName, WrapMode.ClampToEdge, WrapMode.ClampToEdge, true, true).With(d => { @@ -99,14 +105,24 @@ namespace osu.Game.Rulesets.Mania.Skinning { if (isHitting.NewValue) { - Column.TopLevelContainer.Add(lightContainer); + // Clear the fade out and, more importantly, the removal. + lightContainer.ClearTransforms(); - // The light must be seeked only after being loaded, otherwise a nullref happens (https://github.com/ppy/osu-framework/issues/3847). + // Only add the container if the removal has taken place. + if (lightContainer.Parent == null) + Column.TopLevelContainer.Add(lightContainer); + + // The light must be seeked only after being loaded, otherwise a nullref occurs (https://github.com/ppy/osu-framework/issues/3847). if (light is TextureAnimation lightAnimation) lightAnimation.GotoFrame(0); + + lightContainer.FadeIn(80); } else - Column.TopLevelContainer.Remove(lightContainer); + { + lightContainer.FadeOut(120) + .OnComplete(d => Column.TopLevelContainer.Remove(d)); + } } } From f65991f31fbe30fcfd55a30e921b890b0709715d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 26 Aug 2020 23:28:58 +0900 Subject: [PATCH 326/434] Revert some usages based on review feedback --- osu.Game/Graphics/Containers/BeatSyncedContainer.cs | 8 ++------ osu.Game/Overlays/Music/PlaylistOverlay.cs | 9 +++------ .../Edit/Compose/Components/Timeline/Timeline.cs | 4 ---- osu.Game/Screens/Menu/LogoVisualisation.cs | 12 ++++-------- 4 files changed, 9 insertions(+), 24 deletions(-) diff --git a/osu.Game/Graphics/Containers/BeatSyncedContainer.cs b/osu.Game/Graphics/Containers/BeatSyncedContainer.cs index 69021e1634..1c9cdc174a 100644 --- a/osu.Game/Graphics/Containers/BeatSyncedContainer.cs +++ b/osu.Game/Graphics/Containers/BeatSyncedContainer.cs @@ -7,7 +7,6 @@ using osu.Framework.Bindables; using osu.Framework.Graphics.Containers; using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; -using osu.Game.Overlays; namespace osu.Game.Graphics.Containers { @@ -15,9 +14,6 @@ namespace osu.Game.Graphics.Containers { protected readonly IBindable Beatmap = new Bindable(); - [Resolved] - private MusicController musicController { get; set; } - private int lastBeat; private TimingControlPoint lastTimingPoint; @@ -58,9 +54,9 @@ namespace osu.Game.Graphics.Containers TimingControlPoint timingPoint = null; EffectControlPoint effectPoint = null; - if (musicController.TrackLoaded && Beatmap.Value.BeatmapLoaded) + if (Beatmap.Value.TrackLoaded && Beatmap.Value.BeatmapLoaded) { - track = musicController.CurrentTrack; + track = Beatmap.Value.Track; beatmap = Beatmap.Value.Beatmap; } diff --git a/osu.Game/Overlays/Music/PlaylistOverlay.cs b/osu.Game/Overlays/Music/PlaylistOverlay.cs index 7471e31923..b45d84049f 100644 --- a/osu.Game/Overlays/Music/PlaylistOverlay.cs +++ b/osu.Game/Overlays/Music/PlaylistOverlay.cs @@ -30,9 +30,6 @@ namespace osu.Game.Overlays.Music [Resolved] private BeatmapManager beatmaps { get; set; } - [Resolved] - private MusicController musicController { get; set; } - private FilterControl filter; private Playlist list; @@ -85,7 +82,7 @@ namespace osu.Game.Overlays.Music if (toSelect != null) { beatmap.Value = beatmaps.GetWorkingBeatmap(toSelect); - musicController.CurrentTrack.Restart(); + beatmap.Value.Track.Restart(); } }; } @@ -119,12 +116,12 @@ namespace osu.Game.Overlays.Music { if (set.ID == (beatmap.Value?.BeatmapSetInfo?.ID ?? -1)) { - musicController.CurrentTrack.Seek(0); + beatmap.Value?.Track.Seek(0); return; } beatmap.Value = beatmaps.GetWorkingBeatmap(set.Beatmaps.First()); - musicController.CurrentTrack.Restart(); + beatmap.Value.Track.Restart(); } } diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs index c617950c64..8c0e35b80e 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs @@ -11,7 +11,6 @@ using osu.Framework.Graphics.Audio; using osu.Framework.Input.Events; using osu.Game.Beatmaps; using osu.Game.Graphics; -using osu.Game.Overlays; using osu.Game.Rulesets.Edit; using osuTK; @@ -27,9 +26,6 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline [Resolved] private EditorClock editorClock { get; set; } - [Resolved] - private MusicController musicController { get; set; } - /// /// The timeline's scroll position in the last frame. /// diff --git a/osu.Game/Screens/Menu/LogoVisualisation.cs b/osu.Game/Screens/Menu/LogoVisualisation.cs index 4d95ee9b7b..ebbb19636c 100644 --- a/osu.Game/Screens/Menu/LogoVisualisation.cs +++ b/osu.Game/Screens/Menu/LogoVisualisation.cs @@ -20,7 +20,6 @@ using osu.Framework.Audio; using osu.Framework.Audio.Track; using osu.Framework.Bindables; using osu.Framework.Utils; -using osu.Game.Overlays; namespace osu.Game.Screens.Menu { @@ -75,9 +74,6 @@ namespace osu.Game.Screens.Menu /// public float Magnitude { get; set; } = 1; - [Resolved] - private MusicController musicController { get; set; } - private readonly float[] frequencyAmplitudes = new float[256]; private IShader shader; @@ -107,15 +103,15 @@ namespace osu.Game.Screens.Menu private void updateAmplitudes() { - var effect = beatmap.Value.BeatmapLoaded && musicController.TrackLoaded - ? beatmap.Value.Beatmap?.ControlPointInfo.EffectPointAt(musicController.CurrentTrack.CurrentTime) + var effect = beatmap.Value.BeatmapLoaded && beatmap.Value.TrackLoaded + ? beatmap.Value.Beatmap?.ControlPointInfo.EffectPointAt(beatmap.Value.Track.CurrentTime) : null; for (int i = 0; i < temporalAmplitudes.Length; i++) temporalAmplitudes[i] = 0; - if (musicController.TrackLoaded) - addAmplitudesFromSource(musicController.CurrentTrack); + if (beatmap.Value.TrackLoaded) + addAmplitudesFromSource(beatmap.Value.Track); foreach (var source in amplitudeSources) addAmplitudesFromSource(source); From fcf703864288ea6b974f21f8bf049cd254ab4036 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 27 Aug 2020 00:21:50 +0900 Subject: [PATCH 327/434] Fix a couple of missed cases --- osu.Game.Rulesets.Osu.Tests/TestSceneSliderSnaking.cs | 4 ++-- osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerRotation.cs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderSnaking.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderSnaking.cs index cd46e8c545..3d100e4b1c 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderSnaking.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderSnaking.cs @@ -65,7 +65,7 @@ namespace osu.Game.Rulesets.Osu.Tests { AddStep("enable autoplay", () => autoplay = true); base.SetUpSteps(); - AddUntilStep("wait for track to start running", () => MusicController.IsPlaying); + AddUntilStep("wait for track to start running", () => Beatmap.Value.Track.IsRunning); double startTime = hitObjects[sliderIndex].StartTime; retrieveDrawableSlider(sliderIndex); @@ -90,7 +90,7 @@ namespace osu.Game.Rulesets.Osu.Tests { AddStep("have autoplay", () => autoplay = true); base.SetUpSteps(); - AddUntilStep("wait for track to start running", () => MusicController.IsPlaying); + AddUntilStep("wait for track to start running", () => Beatmap.Value.Track.IsRunning); double startTime = hitObjects[sliderIndex].StartTime; retrieveDrawableSlider(sliderIndex); diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerRotation.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerRotation.cs index 3c559765d4..f7909071ea 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerRotation.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerRotation.cs @@ -48,7 +48,7 @@ namespace osu.Game.Rulesets.Osu.Tests { base.SetUpSteps(); - AddUntilStep("wait for track to start running", () => MusicController.IsPlaying); + AddUntilStep("wait for track to start running", () => Beatmap.Value.Track.IsRunning); AddStep("retrieve spinner", () => drawableSpinner = (DrawableSpinner)Player.DrawableRuleset.Playfield.AllHitObjects.First()); } From edc15c965cf6a29321cf84c1dcd1d7bb0fcdd17a Mon Sep 17 00:00:00 2001 From: Poliwrath Date: Wed, 26 Aug 2020 12:52:39 -0400 Subject: [PATCH 328/434] Update osu.Game/Screens/Menu/IntroSequence.cs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bartłomiej Dach --- osu.Game/Screens/Menu/IntroSequence.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Menu/IntroSequence.cs b/osu.Game/Screens/Menu/IntroSequence.cs index 98da31b93e..d92d38da45 100644 --- a/osu.Game/Screens/Menu/IntroSequence.cs +++ b/osu.Game/Screens/Menu/IntroSequence.cs @@ -205,7 +205,7 @@ namespace osu.Game.Screens.Menu const int line_end_offset = 120; smallRing.Foreground.ResizeTo(1, line_duration, Easing.OutQuint); - smallRing.Delay(400).FadeOut(); + smallRing.Delay(400).FadeColour(Color4.Black, 300); lineTopLeft.MoveTo(new Vector2(-line_end_offset, -line_end_offset), line_duration, Easing.OutQuint); lineTopRight.MoveTo(new Vector2(line_end_offset, -line_end_offset), line_duration, Easing.OutQuint); From 927a2a3d2df98bb3c93e9c4b8d7af6f35e71636e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Wed, 26 Aug 2020 19:19:42 +0200 Subject: [PATCH 329/434] Introduce IStatisticRow interface --- .../Ranking/Statistics/IStatisticRow.cs | 18 +++++++++++++ .../Ranking/Statistics/StatisticRow.cs | 26 +++++++++++++++++-- .../Ranking/Statistics/StatisticsPanel.cs | 24 +++-------------- 3 files changed, 45 insertions(+), 23 deletions(-) create mode 100644 osu.Game/Screens/Ranking/Statistics/IStatisticRow.cs diff --git a/osu.Game/Screens/Ranking/Statistics/IStatisticRow.cs b/osu.Game/Screens/Ranking/Statistics/IStatisticRow.cs new file mode 100644 index 0000000000..67224041d5 --- /dev/null +++ b/osu.Game/Screens/Ranking/Statistics/IStatisticRow.cs @@ -0,0 +1,18 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Graphics; + +namespace osu.Game.Screens.Ranking.Statistics +{ + /// + /// A row of statistics to be displayed on the results screen. + /// + public interface IStatisticRow + { + /// + /// Creates the visual representation of this row. + /// + Drawable CreateDrawableStatisticRow(); + } +} diff --git a/osu.Game/Screens/Ranking/Statistics/StatisticRow.cs b/osu.Game/Screens/Ranking/Statistics/StatisticRow.cs index e1ca9799a3..fff60cdcad 100644 --- a/osu.Game/Screens/Ranking/Statistics/StatisticRow.cs +++ b/osu.Game/Screens/Ranking/Statistics/StatisticRow.cs @@ -1,19 +1,41 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System.Linq; using JetBrains.Annotations; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; namespace osu.Game.Screens.Ranking.Statistics { /// - /// A row of statistics to be displayed in the results screen. + /// A row of graphically detailed s to be displayed in the results screen. /// - public class StatisticRow + public class StatisticRow : IStatisticRow { /// /// The columns of this . /// [ItemNotNull] public StatisticItem[] Columns; + + public Drawable CreateDrawableStatisticRow() => new GridContainer + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Content = new[] + { + Columns?.Select(c => new StatisticContainer(c) + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + }).Cast().ToArray() + }, + ColumnDimensions = Enumerable.Range(0, Columns?.Length ?? 0) + .Select(i => Columns[i].Dimension ?? new Dimension()).ToArray(), + RowDimensions = new[] { new Dimension(GridSizeMode.AutoSize) } + }; } } diff --git a/osu.Game/Screens/Ranking/Statistics/StatisticsPanel.cs b/osu.Game/Screens/Ranking/Statistics/StatisticsPanel.cs index 7f406331cd..fd62c9e7d9 100644 --- a/osu.Game/Screens/Ranking/Statistics/StatisticsPanel.cs +++ b/osu.Game/Screens/Ranking/Statistics/StatisticsPanel.cs @@ -96,27 +96,9 @@ namespace osu.Game.Screens.Ranking.Statistics Spacing = new Vector2(30, 15), }; - foreach (var row in newScore.Ruleset.CreateInstance().CreateStatisticsForScore(newScore, playableBeatmap)) - { - rows.Add(new GridContainer - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Content = new[] - { - row.Columns?.Select(c => new StatisticContainer(c) - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - }).Cast().ToArray() - }, - ColumnDimensions = Enumerable.Range(0, row.Columns?.Length ?? 0) - .Select(i => row.Columns[i].Dimension ?? new Dimension()).ToArray(), - RowDimensions = new[] { new Dimension(GridSizeMode.AutoSize) } - }); - } + rows.AddRange(newScore.Ruleset.CreateInstance() + .CreateStatisticsForScore(newScore, playableBeatmap) + .Select(row => row.CreateDrawableStatisticRow())); LoadComponentAsync(rows, d => { From bbb3d7522e3e606c94d3564b28b9ec21c3865a51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Wed, 26 Aug 2020 19:24:12 +0200 Subject: [PATCH 330/434] Scope up return type to IStatisticRow --- osu.Game.Rulesets.Mania/ManiaRuleset.cs | 2 +- osu.Game.Rulesets.Osu/OsuRuleset.cs | 2 +- osu.Game.Rulesets.Taiko/TaikoRuleset.cs | 2 +- osu.Game/Rulesets/Ruleset.cs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Mania/ManiaRuleset.cs b/osu.Game.Rulesets.Mania/ManiaRuleset.cs index 2795868c97..8cc635c316 100644 --- a/osu.Game.Rulesets.Mania/ManiaRuleset.cs +++ b/osu.Game.Rulesets.Mania/ManiaRuleset.cs @@ -314,7 +314,7 @@ namespace osu.Game.Rulesets.Mania return (PlayfieldType)Enum.GetValues(typeof(PlayfieldType)).Cast().OrderByDescending(i => i).First(v => variant >= v); } - public override StatisticRow[] CreateStatisticsForScore(ScoreInfo score, IBeatmap playableBeatmap) => new[] + public override IStatisticRow[] CreateStatisticsForScore(ScoreInfo score, IBeatmap playableBeatmap) => new IStatisticRow[] { new StatisticRow { diff --git a/osu.Game.Rulesets.Osu/OsuRuleset.cs b/osu.Game.Rulesets.Osu/OsuRuleset.cs index eaa5d8937a..298f1aec91 100644 --- a/osu.Game.Rulesets.Osu/OsuRuleset.cs +++ b/osu.Game.Rulesets.Osu/OsuRuleset.cs @@ -193,7 +193,7 @@ namespace osu.Game.Rulesets.Osu public override IRulesetConfigManager CreateConfig(SettingsStore settings) => new OsuRulesetConfigManager(settings, RulesetInfo); - public override StatisticRow[] CreateStatisticsForScore(ScoreInfo score, IBeatmap playableBeatmap) => new[] + public override IStatisticRow[] CreateStatisticsForScore(ScoreInfo score, IBeatmap playableBeatmap) => new IStatisticRow[] { new StatisticRow { diff --git a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs index 2011842591..0125e0a3ad 100644 --- a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs +++ b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs @@ -161,7 +161,7 @@ namespace osu.Game.Rulesets.Taiko public override IConvertibleReplayFrame CreateConvertibleReplayFrame() => new TaikoReplayFrame(); - public override StatisticRow[] CreateStatisticsForScore(ScoreInfo score, IBeatmap playableBeatmap) => new[] + public override IStatisticRow[] CreateStatisticsForScore(ScoreInfo score, IBeatmap playableBeatmap) => new IStatisticRow[] { new StatisticRow { diff --git a/osu.Game/Rulesets/Ruleset.cs b/osu.Game/Rulesets/Ruleset.cs index 3a7f433a37..f82ecd842a 100644 --- a/osu.Game/Rulesets/Ruleset.cs +++ b/osu.Game/Rulesets/Ruleset.cs @@ -217,6 +217,6 @@ namespace osu.Game.Rulesets /// The , converted for this with all relevant s applied. /// The s to display. Each may contain 0 or more . [NotNull] - public virtual StatisticRow[] CreateStatisticsForScore(ScoreInfo score, IBeatmap playableBeatmap) => Array.Empty(); + public virtual IStatisticRow[] CreateStatisticsForScore(ScoreInfo score, IBeatmap playableBeatmap) => Array.Empty(); } } From f5e52c80b4db250bcb18df027a06095f35347508 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Wed, 26 Aug 2020 19:25:59 +0200 Subject: [PATCH 331/434] Rename {-> Drawable}SimpleStatisticRow --- ...atisticRow.cs => TestSceneDrawableSimpleStatisticRow.cs} | 6 +++--- ...{SimpleStatisticRow.cs => DrawableSimpleStatisticRow.cs} | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) rename osu.Game.Tests/Visual/Ranking/{TestSceneSimpleStatisticRow.cs => TestSceneDrawableSimpleStatisticRow.cs} (88%) rename osu.Game/Screens/Ranking/Statistics/{SimpleStatisticRow.cs => DrawableSimpleStatisticRow.cs} (96%) diff --git a/osu.Game.Tests/Visual/Ranking/TestSceneSimpleStatisticRow.cs b/osu.Game.Tests/Visual/Ranking/TestSceneDrawableSimpleStatisticRow.cs similarity index 88% rename from osu.Game.Tests/Visual/Ranking/TestSceneSimpleStatisticRow.cs rename to osu.Game.Tests/Visual/Ranking/TestSceneDrawableSimpleStatisticRow.cs index aa569e47b1..2b0ba30357 100644 --- a/osu.Game.Tests/Visual/Ranking/TestSceneSimpleStatisticRow.cs +++ b/osu.Game.Tests/Visual/Ranking/TestSceneDrawableSimpleStatisticRow.cs @@ -13,7 +13,7 @@ using osu.Game.Screens.Ranking.Statistics; namespace osu.Game.Tests.Visual.Ranking { - public class TestSceneSimpleStatisticRow : OsuTestScene + public class TestSceneDrawableSimpleStatisticRow : OsuTestScene { private Container container; @@ -45,7 +45,7 @@ namespace osu.Game.Tests.Visual.Ranking public void TestEmpty() { AddStep("create with no items", - () => container.Add(new SimpleStatisticRow(2, Enumerable.Empty()))); + () => container.Add(new DrawableSimpleStatisticRow(2, Enumerable.Empty()))); } [Test] @@ -61,7 +61,7 @@ namespace osu.Game.Tests.Visual.Ranking Value = RNG.Next(100) }); - container.Add(new SimpleStatisticRow(columnCount, items)); + container.Add(new DrawableSimpleStatisticRow(columnCount, items)); }); } } diff --git a/osu.Game/Screens/Ranking/Statistics/SimpleStatisticRow.cs b/osu.Game/Screens/Ranking/Statistics/DrawableSimpleStatisticRow.cs similarity index 96% rename from osu.Game/Screens/Ranking/Statistics/SimpleStatisticRow.cs rename to osu.Game/Screens/Ranking/Statistics/DrawableSimpleStatisticRow.cs index 16501aae54..a592724bc3 100644 --- a/osu.Game/Screens/Ranking/Statistics/SimpleStatisticRow.cs +++ b/osu.Game/Screens/Ranking/Statistics/DrawableSimpleStatisticRow.cs @@ -16,7 +16,7 @@ namespace osu.Game.Screens.Ranking.Statistics /// Represents a statistic row with simple statistics (ones that only need textual display). /// Richer visualisations should be done with s and s. /// - public class SimpleStatisticRow : CompositeDrawable + public class DrawableSimpleStatisticRow : CompositeDrawable { private readonly SimpleStatisticItem[] items; private readonly int columnCount; @@ -28,7 +28,7 @@ namespace osu.Game.Screens.Ranking.Statistics /// /// The number of columns to layout the into. /// The s to display in this row. - public SimpleStatisticRow(int columnCount, IEnumerable items) + public DrawableSimpleStatisticRow(int columnCount, IEnumerable items) { if (columnCount < 1) throw new ArgumentOutOfRangeException(nameof(columnCount)); From 7c3368ecbe1ed8c6af1bd684f5af13027049b548 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Wed, 26 Aug 2020 19:30:49 +0200 Subject: [PATCH 332/434] Reintroduce SimpleStatisticRow as a data class --- .../Statistics/DrawableSimpleStatisticRow.cs | 3 +- .../Ranking/Statistics/SimpleStatisticRow.cs | 34 +++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 osu.Game/Screens/Ranking/Statistics/SimpleStatisticRow.cs diff --git a/osu.Game/Screens/Ranking/Statistics/DrawableSimpleStatisticRow.cs b/osu.Game/Screens/Ranking/Statistics/DrawableSimpleStatisticRow.cs index a592724bc3..7f69b323d8 100644 --- a/osu.Game/Screens/Ranking/Statistics/DrawableSimpleStatisticRow.cs +++ b/osu.Game/Screens/Ranking/Statistics/DrawableSimpleStatisticRow.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Linq; +using JetBrains.Annotations; using osu.Framework.Allocation; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; @@ -28,7 +29,7 @@ namespace osu.Game.Screens.Ranking.Statistics /// /// The number of columns to layout the into. /// The s to display in this row. - public DrawableSimpleStatisticRow(int columnCount, IEnumerable items) + public DrawableSimpleStatisticRow(int columnCount, [ItemNotNull] IEnumerable items) { if (columnCount < 1) throw new ArgumentOutOfRangeException(nameof(columnCount)); diff --git a/osu.Game/Screens/Ranking/Statistics/SimpleStatisticRow.cs b/osu.Game/Screens/Ranking/Statistics/SimpleStatisticRow.cs new file mode 100644 index 0000000000..cd6afeb3a5 --- /dev/null +++ b/osu.Game/Screens/Ranking/Statistics/SimpleStatisticRow.cs @@ -0,0 +1,34 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using JetBrains.Annotations; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; + +namespace osu.Game.Screens.Ranking.Statistics +{ + /// + /// Contains textual statistic data to display in a . + /// + public class SimpleStatisticRow : IStatisticRow + { + /// + /// The number of columns to layout the in. + /// + public int Columns { get; set; } + + /// + /// The s that this row should contain. + /// + [ItemNotNull] + public SimpleStatisticItem[] Items { get; set; } + + public Drawable CreateDrawableStatisticRow() => new Container + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Padding = new MarginPadding(20), + Child = new DrawableSimpleStatisticRow(Columns, Items) + }; + } +} From 5973e2ce4e6d595a6f910b55250ed174a97db92d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Wed, 26 Aug 2020 21:20:43 +0200 Subject: [PATCH 333/434] Add component for unstable rate statistic --- .../Ranking/Statistics/UnstableRate.cs | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 osu.Game/Screens/Ranking/Statistics/UnstableRate.cs diff --git a/osu.Game/Screens/Ranking/Statistics/UnstableRate.cs b/osu.Game/Screens/Ranking/Statistics/UnstableRate.cs new file mode 100644 index 0000000000..5b368c3e8d --- /dev/null +++ b/osu.Game/Screens/Ranking/Statistics/UnstableRate.cs @@ -0,0 +1,39 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System; +using System.Collections.Generic; +using System.Linq; +using osu.Game.Rulesets.Scoring; + +namespace osu.Game.Screens.Ranking.Statistics +{ + /// + /// Displays the unstable rate statistic for a given play. + /// + public class UnstableRate : SimpleStatisticItem + { + /// + /// Creates and computes an statistic. + /// + /// Sequence of s to calculate the unstable rate based on. + public UnstableRate(IEnumerable hitEvents) + : base("Unstable Rate") + { + var timeOffsets = hitEvents.Select(ev => ev.TimeOffset).ToArray(); + Value = 10 * standardDeviation(timeOffsets); + } + + private static double standardDeviation(double[] timeOffsets) + { + if (timeOffsets.Length == 0) + return double.NaN; + + var mean = timeOffsets.Average(); + var squares = timeOffsets.Select(offset => Math.Pow(offset - mean, 2)).Sum(); + return Math.Sqrt(squares / timeOffsets.Length); + } + + protected override string DisplayValue(double value) => double.IsNaN(value) ? "(not available)" : value.ToString("N2"); + } +} From 05e725d59fd5b7710e18f2fb414eb51e02d99e6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Wed, 26 Aug 2020 21:28:41 +0200 Subject: [PATCH 334/434] Add unstable rate statistic to rulesets in which it makes sense --- osu.Game.Rulesets.Mania/ManiaRuleset.cs | 8 ++++ osu.Game.Rulesets.Osu/OsuRuleset.cs | 50 ++++++++++++++++--------- osu.Game.Rulesets.Taiko/TaikoRuleset.cs | 31 ++++++++++----- 3 files changed, 62 insertions(+), 27 deletions(-) diff --git a/osu.Game.Rulesets.Mania/ManiaRuleset.cs b/osu.Game.Rulesets.Mania/ManiaRuleset.cs index 8cc635c316..490223b7a5 100644 --- a/osu.Game.Rulesets.Mania/ManiaRuleset.cs +++ b/osu.Game.Rulesets.Mania/ManiaRuleset.cs @@ -326,6 +326,14 @@ namespace osu.Game.Rulesets.Mania Height = 250 }), } + }, + new SimpleStatisticRow + { + Columns = 3, + Items = new SimpleStatisticItem[] + { + new UnstableRate(score.HitEvents) + } } }; } diff --git a/osu.Game.Rulesets.Osu/OsuRuleset.cs b/osu.Game.Rulesets.Osu/OsuRuleset.cs index 298f1aec91..dd950c60ec 100644 --- a/osu.Game.Rulesets.Osu/OsuRuleset.cs +++ b/osu.Game.Rulesets.Osu/OsuRuleset.cs @@ -193,30 +193,44 @@ namespace osu.Game.Rulesets.Osu public override IRulesetConfigManager CreateConfig(SettingsStore settings) => new OsuRulesetConfigManager(settings, RulesetInfo); - public override IStatisticRow[] CreateStatisticsForScore(ScoreInfo score, IBeatmap playableBeatmap) => new IStatisticRow[] + public override IStatisticRow[] CreateStatisticsForScore(ScoreInfo score, IBeatmap playableBeatmap) { - new StatisticRow + var timedHitEvents = score.HitEvents.Where(e => e.HitObject is HitCircle && !(e.HitObject is SliderTailCircle)).ToList(); + + return new IStatisticRow[] { - Columns = new[] + new StatisticRow { - new StatisticItem("Timing Distribution", new HitEventTimingDistributionGraph(score.HitEvents.Where(e => e.HitObject is HitCircle && !(e.HitObject is SliderTailCircle)).ToList()) + Columns = new[] { - RelativeSizeAxes = Axes.X, - Height = 250 - }), - } - }, - new StatisticRow - { - Columns = new[] + new StatisticItem("Timing Distribution", + new HitEventTimingDistributionGraph(timedHitEvents) + { + RelativeSizeAxes = Axes.X, + Height = 250 + }), + } + }, + new StatisticRow { - new StatisticItem("Accuracy Heatmap", new AccuracyHeatmap(score, playableBeatmap) + Columns = new[] { - RelativeSizeAxes = Axes.X, - Height = 250 - }), + new StatisticItem("Accuracy Heatmap", new AccuracyHeatmap(score, playableBeatmap) + { + RelativeSizeAxes = Axes.X, + Height = 250 + }), + } + }, + new SimpleStatisticRow + { + Columns = 3, + Items = new SimpleStatisticItem[] + { + new UnstableRate(timedHitEvents) + } } - } - }; + }; + } } } diff --git a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs index 0125e0a3ad..938c038413 100644 --- a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs +++ b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs @@ -161,19 +161,32 @@ namespace osu.Game.Rulesets.Taiko public override IConvertibleReplayFrame CreateConvertibleReplayFrame() => new TaikoReplayFrame(); - public override IStatisticRow[] CreateStatisticsForScore(ScoreInfo score, IBeatmap playableBeatmap) => new IStatisticRow[] + public override IStatisticRow[] CreateStatisticsForScore(ScoreInfo score, IBeatmap playableBeatmap) { - new StatisticRow + var timedHitEvents = score.HitEvents.Where(e => e.HitObject is Hit).ToList(); + + return new IStatisticRow[] { - Columns = new[] + new StatisticRow { - new StatisticItem("Timing Distribution", new HitEventTimingDistributionGraph(score.HitEvents.Where(e => e.HitObject is Hit).ToList()) + Columns = new[] { - RelativeSizeAxes = Axes.X, - Height = 250 - }), + new StatisticItem("Timing Distribution", new HitEventTimingDistributionGraph(timedHitEvents) + { + RelativeSizeAxes = Axes.X, + Height = 250 + }), + } + }, + new SimpleStatisticRow + { + Columns = 3, + Items = new SimpleStatisticItem[] + { + new UnstableRate(timedHitEvents) + } } - } - }; + }; + } } } From d81d538b7e202362c8208f403c449bdc018cf443 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Wed, 26 Aug 2020 21:29:01 +0200 Subject: [PATCH 335/434] Move out row anchor/origin set to one central place --- osu.Game/Screens/Ranking/Statistics/StatisticRow.cs | 2 -- osu.Game/Screens/Ranking/Statistics/StatisticsPanel.cs | 6 +++++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Ranking/Statistics/StatisticRow.cs b/osu.Game/Screens/Ranking/Statistics/StatisticRow.cs index fff60cdcad..d5324e14f0 100644 --- a/osu.Game/Screens/Ranking/Statistics/StatisticRow.cs +++ b/osu.Game/Screens/Ranking/Statistics/StatisticRow.cs @@ -21,8 +21,6 @@ namespace osu.Game.Screens.Ranking.Statistics public Drawable CreateDrawableStatisticRow() => new GridContainer { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, Content = new[] diff --git a/osu.Game/Screens/Ranking/Statistics/StatisticsPanel.cs b/osu.Game/Screens/Ranking/Statistics/StatisticsPanel.cs index fd62c9e7d9..2f3304e810 100644 --- a/osu.Game/Screens/Ranking/Statistics/StatisticsPanel.cs +++ b/osu.Game/Screens/Ranking/Statistics/StatisticsPanel.cs @@ -98,7 +98,11 @@ namespace osu.Game.Screens.Ranking.Statistics rows.AddRange(newScore.Ruleset.CreateInstance() .CreateStatisticsForScore(newScore, playableBeatmap) - .Select(row => row.CreateDrawableStatisticRow())); + .Select(row => row.CreateDrawableStatisticRow().With(r => + { + r.Anchor = Anchor.TopCentre; + r.Origin = Anchor.TopCentre; + }))); LoadComponentAsync(rows, d => { From c3197da3dac494617364c88899eef62b5d7f9bcd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Wed, 26 Aug 2020 21:43:33 +0200 Subject: [PATCH 336/434] Adjust simple statistic item font sizes --- osu.Game/Screens/Ranking/Statistics/SimpleStatisticItem.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Ranking/Statistics/SimpleStatisticItem.cs b/osu.Game/Screens/Ranking/Statistics/SimpleStatisticItem.cs index e6c4ab1c4e..3d9ba2f225 100644 --- a/osu.Game/Screens/Ranking/Statistics/SimpleStatisticItem.cs +++ b/osu.Game/Screens/Ranking/Statistics/SimpleStatisticItem.cs @@ -41,13 +41,14 @@ namespace osu.Game.Screens.Ranking.Statistics { Text = Name, Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft + Origin = Anchor.CentreLeft, + Font = OsuFont.GetFont(size: 14) }, value = new OsuSpriteText { Anchor = Anchor.CentreRight, Origin = Anchor.CentreRight, - Font = OsuFont.Torus.With(weight: FontWeight.Bold) + Font = OsuFont.GetFont(size: 14, weight: FontWeight.Bold) } }); } From f8042e6fd311b4f6713e75c310de746d4ea5daf7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Wed, 26 Aug 2020 22:34:02 +0200 Subject: [PATCH 337/434] Add fade to prevent jarring transitions --- osu.Game/Screens/Ranking/Statistics/StatisticsPanel.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Screens/Ranking/Statistics/StatisticsPanel.cs b/osu.Game/Screens/Ranking/Statistics/StatisticsPanel.cs index 2f3304e810..3b8f980070 100644 --- a/osu.Game/Screens/Ranking/Statistics/StatisticsPanel.cs +++ b/osu.Game/Screens/Ranking/Statistics/StatisticsPanel.cs @@ -94,6 +94,7 @@ namespace osu.Game.Screens.Ranking.Statistics RelativeSizeAxes = Axes.Both, Direction = FillDirection.Vertical, Spacing = new Vector2(30, 15), + Alpha = 0 }; rows.AddRange(newScore.Ruleset.CreateInstance() @@ -111,6 +112,7 @@ namespace osu.Game.Screens.Ranking.Statistics spinner.Hide(); content.Add(d); + d.FadeIn(250, Easing.OutQuint); }, localCancellationSource.Token); }), localCancellationSource.Token); } From deb172bb6ccab9cc46f015957eb45bb06ce1c04f Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 27 Aug 2020 20:24:08 +0900 Subject: [PATCH 338/434] Implement basic mania hit order policy --- .../TestSceneOutOfOrderHits.cs | 124 ++++++++++++++++++ .../Objects/Drawables/DrawableHoldNote.cs | 3 + .../Drawables/DrawableManiaHitObject.cs | 9 ++ .../Objects/Drawables/DrawableNote.cs | 3 + osu.Game.Rulesets.Mania/UI/Column.cs | 10 ++ .../UI/OrderedHitPolicy.cs | 66 ++++++++++ 6 files changed, 215 insertions(+) create mode 100644 osu.Game.Rulesets.Mania.Tests/TestSceneOutOfOrderHits.cs create mode 100644 osu.Game.Rulesets.Mania/UI/OrderedHitPolicy.cs diff --git a/osu.Game.Rulesets.Mania.Tests/TestSceneOutOfOrderHits.cs b/osu.Game.Rulesets.Mania.Tests/TestSceneOutOfOrderHits.cs new file mode 100644 index 0000000000..ed187e65bf --- /dev/null +++ b/osu.Game.Rulesets.Mania.Tests/TestSceneOutOfOrderHits.cs @@ -0,0 +1,124 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System; +using System.Collections.Generic; +using System.Linq; +using NUnit.Framework; +using osu.Framework.Extensions.TypeExtensions; +using osu.Framework.Screens; +using osu.Framework.Utils; +using osu.Game.Beatmaps.ControlPoints; +using osu.Game.Replays; +using osu.Game.Rulesets.Judgements; +using osu.Game.Rulesets.Mania.Beatmaps; +using osu.Game.Rulesets.Mania.Objects; +using osu.Game.Rulesets.Mania.Replays; +using osu.Game.Rulesets.Replays; +using osu.Game.Rulesets.Scoring; +using osu.Game.Scoring; +using osu.Game.Screens.Play; +using osu.Game.Tests.Visual; + +namespace osu.Game.Rulesets.Mania.Tests +{ + public class TestSceneOutOfOrderHits : RateAdjustedBeatmapTestScene + { + [Test] + public void TestPreviousHitWindowDoesNotExtendPastNextObject() + { + var objects = new List(); + var frames = new List(); + + for (int i = 0; i < 7; i++) + { + double time = 1000 + i * 100; + + objects.Add(new Note { StartTime = time }); + + if (i > 0) + { + frames.Add(new ManiaReplayFrame(time + 10, ManiaAction.Key1)); + frames.Add(new ManiaReplayFrame(time + 11)); + } + } + + performTest(objects, frames); + + addJudgementAssert(objects[0], HitResult.Miss); + + for (int i = 1; i < 7; i++) + { + addJudgementAssert(objects[i], HitResult.Perfect); + addJudgementOffsetAssert(objects[i], 10); + } + } + + private void addJudgementAssert(ManiaHitObject hitObject, HitResult result) + { + AddAssert($"({hitObject.GetType().ReadableName()} @ {hitObject.StartTime}) judgement is {result}", + () => judgementResults.Single(r => r.HitObject == hitObject).Type == result); + } + + private void addJudgementAssert(string name, Func hitObject, HitResult result) + { + AddAssert($"{name} judgement is {result}", + () => judgementResults.Single(r => r.HitObject == hitObject()).Type == result); + } + + private void addJudgementOffsetAssert(ManiaHitObject hitObject, double offset) + { + AddAssert($"({hitObject.GetType().ReadableName()} @ {hitObject.StartTime}) judged at {offset}", + () => Precision.AlmostEquals(judgementResults.Single(r => r.HitObject == hitObject).TimeOffset, offset, 100)); + } + + private ScoreAccessibleReplayPlayer currentPlayer; + private List judgementResults; + + private void performTest(List hitObjects, List frames) + { + AddStep("load player", () => + { + Beatmap.Value = CreateWorkingBeatmap(new ManiaBeatmap(new StageDefinition { Columns = 4 }) + { + HitObjects = hitObjects, + BeatmapInfo = + { + Ruleset = new ManiaRuleset().RulesetInfo + }, + }); + + Beatmap.Value.Beatmap.ControlPointInfo.Add(0, new DifficultyControlPoint { SpeedMultiplier = 0.1f }); + + var p = new ScoreAccessibleReplayPlayer(new Score { Replay = new Replay { Frames = frames } }); + + p.OnLoadComplete += _ => + { + p.ScoreProcessor.NewJudgement += result => + { + if (currentPlayer == p) judgementResults.Add(result); + }; + }; + + LoadScreen(currentPlayer = p); + judgementResults = new List(); + }); + + AddUntilStep("Beatmap at 0", () => Beatmap.Value.Track.CurrentTime == 0); + AddUntilStep("Wait until player is loaded", () => currentPlayer.IsCurrentScreen()); + AddUntilStep("Wait for completion", () => currentPlayer.ScoreProcessor.HasCompleted.Value); + } + + private class ScoreAccessibleReplayPlayer : ReplayPlayer + { + public new ScoreProcessor ScoreProcessor => base.ScoreProcessor; + + protected override bool PauseOnFocusLost => false; + + public ScoreAccessibleReplayPlayer(Score score) + : base(score, false, false) + { + } + } + } +} diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs index 0712026ca6..a04e5bc2f9 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs @@ -252,6 +252,9 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables if (action != Action.Value) return false; + if (CheckHittable?.Invoke(this, Time.Current) == false) + return false; + // The tail has a lenience applied to it which is factored into the miss window (i.e. the miss judgement will be delayed). // But the hold cannot ever be started within the late-lenience window, so we should skip trying to begin the hold during that time. // Note: Unlike below, we use the tail's start time to determine the time offset. diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs index ab76a5b8f8..0594d1e143 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs @@ -1,6 +1,7 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System; using JetBrains.Annotations; using osu.Framework.Allocation; using osu.Framework.Bindables; @@ -8,6 +9,7 @@ using osu.Framework.Graphics; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.UI.Scrolling; using osu.Game.Rulesets.Mania.UI; +using osu.Game.Rulesets.Scoring; namespace osu.Game.Rulesets.Mania.Objects.Drawables { @@ -34,6 +36,8 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables } } + public Func CheckHittable; + protected DrawableManiaHitObject(ManiaHitObject hitObject) : base(hitObject) { @@ -124,6 +128,11 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables break; } } + + /// + /// Causes this to get missed, disregarding all conditions in implementations of . + /// + public void MissForcefully() => ApplyResult(r => r.Type = HitResult.Miss); } public abstract class DrawableManiaHitObject : DrawableManiaHitObject diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs index 9451bc4430..973dc06e05 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs @@ -64,6 +64,9 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables if (action != Action.Value) return false; + if (CheckHittable?.Invoke(this, Time.Current) == false) + return false; + return UpdateResult(true); } diff --git a/osu.Game.Rulesets.Mania/UI/Column.cs b/osu.Game.Rulesets.Mania/UI/Column.cs index de4648e4fa..9aabcc6699 100644 --- a/osu.Game.Rulesets.Mania/UI/Column.cs +++ b/osu.Game.Rulesets.Mania/UI/Column.cs @@ -17,6 +17,7 @@ using osu.Game.Rulesets.UI.Scrolling; using osu.Game.Skinning; using osuTK; using osu.Game.Rulesets.Mania.Beatmaps; +using osu.Game.Rulesets.Mania.Objects.Drawables; namespace osu.Game.Rulesets.Mania.UI { @@ -36,6 +37,7 @@ namespace osu.Game.Rulesets.Mania.UI public readonly ColumnHitObjectArea HitObjectArea; internal readonly Container TopLevelContainer; private readonly DrawablePool hitExplosionPool; + private readonly OrderedHitPolicy hitPolicy; public Container UnderlayElements => HitObjectArea.UnderlayElements; @@ -65,6 +67,8 @@ namespace osu.Game.Rulesets.Mania.UI TopLevelContainer = new Container { RelativeSizeAxes = Axes.Both } }; + hitPolicy = new OrderedHitPolicy(HitObjectContainer); + TopLevelContainer.Add(HitObjectArea.Explosions.CreateProxy()); } @@ -90,6 +94,9 @@ namespace osu.Game.Rulesets.Mania.UI hitObject.AccentColour.Value = AccentColour; hitObject.OnNewResult += OnNewResult; + DrawableManiaHitObject maniaObject = (DrawableManiaHitObject)hitObject; + maniaObject.CheckHittable = hitPolicy.IsHittable; + HitObjectContainer.Add(hitObject); } @@ -104,6 +111,9 @@ namespace osu.Game.Rulesets.Mania.UI internal void OnNewResult(DrawableHitObject judgedObject, JudgementResult result) { + if (result.IsHit) + hitPolicy.HandleHit(judgedObject); + if (!result.IsHit || !judgedObject.DisplayResult || !DisplayJudgements.Value) return; diff --git a/osu.Game.Rulesets.Mania/UI/OrderedHitPolicy.cs b/osu.Game.Rulesets.Mania/UI/OrderedHitPolicy.cs new file mode 100644 index 0000000000..68183be89f --- /dev/null +++ b/osu.Game.Rulesets.Mania/UI/OrderedHitPolicy.cs @@ -0,0 +1,66 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System; +using System.Collections.Generic; +using osu.Framework.Extensions.IEnumerableExtensions; +using osu.Game.Rulesets.Mania.Objects.Drawables; +using osu.Game.Rulesets.Objects; +using osu.Game.Rulesets.Objects.Drawables; +using osu.Game.Rulesets.UI; + +namespace osu.Game.Rulesets.Mania.UI +{ + public class OrderedHitPolicy + { + private readonly HitObjectContainer hitObjectContainer; + + public OrderedHitPolicy(HitObjectContainer hitObjectContainer) + { + this.hitObjectContainer = hitObjectContainer; + } + + public bool IsHittable(DrawableHitObject hitObject, double time) + { + var nextObject = hitObjectContainer.AliveObjects.GetNext(hitObject); + return nextObject == null || time < nextObject.HitObject.StartTime; + } + + /// + /// Handles a being hit to potentially miss all earlier s. + /// + /// The that was hit. + public void HandleHit(DrawableHitObject hitObject) + { + if (!IsHittable(hitObject, hitObject.HitObject.StartTime + hitObject.Result.TimeOffset)) + throw new InvalidOperationException($"A {hitObject} was hit before it became hittable!"); + + foreach (var obj in enumerateHitObjectsUpTo(hitObject.HitObject.StartTime)) + { + if (obj.Judged) + continue; + + ((DrawableManiaHitObject)obj).MissForcefully(); + } + } + + private IEnumerable enumerateHitObjectsUpTo(double targetTime) + { + foreach (var obj in hitObjectContainer.AliveObjects) + { + if (obj.HitObject.StartTime >= targetTime) + yield break; + + yield return obj; + + foreach (var nestedObj in obj.NestedHitObjects) + { + if (nestedObj.HitObject.StartTime >= targetTime) + break; + + yield return nestedObj; + } + } + } + } +} From 6f93df0b9dbd1317b072c61b124fb50b30017b41 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 27 Aug 2020 21:05:12 +0900 Subject: [PATCH 339/434] Fix ticks causing hold note misses --- osu.Game.Rulesets.Mania/UI/OrderedHitPolicy.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Mania/UI/OrderedHitPolicy.cs b/osu.Game.Rulesets.Mania/UI/OrderedHitPolicy.cs index 68183be89f..dfd5136e3e 100644 --- a/osu.Game.Rulesets.Mania/UI/OrderedHitPolicy.cs +++ b/osu.Game.Rulesets.Mania/UI/OrderedHitPolicy.cs @@ -48,14 +48,14 @@ namespace osu.Game.Rulesets.Mania.UI { foreach (var obj in hitObjectContainer.AliveObjects) { - if (obj.HitObject.StartTime >= targetTime) + if (obj.HitObject.GetEndTime() >= targetTime) yield break; yield return obj; foreach (var nestedObj in obj.NestedHitObjects) { - if (nestedObj.HitObject.StartTime >= targetTime) + if (nestedObj.HitObject.GetEndTime() >= targetTime) break; yield return nestedObj; From 7a5292936e57096e3521a1781d33d777fdc386d4 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 27 Aug 2020 21:15:05 +0900 Subject: [PATCH 340/434] Add some xmldocs --- osu.Game.Rulesets.Mania/UI/OrderedHitPolicy.cs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/osu.Game.Rulesets.Mania/UI/OrderedHitPolicy.cs b/osu.Game.Rulesets.Mania/UI/OrderedHitPolicy.cs index dfd5136e3e..0f9cd48dd8 100644 --- a/osu.Game.Rulesets.Mania/UI/OrderedHitPolicy.cs +++ b/osu.Game.Rulesets.Mania/UI/OrderedHitPolicy.cs @@ -11,6 +11,9 @@ using osu.Game.Rulesets.UI; namespace osu.Game.Rulesets.Mania.UI { + /// + /// Ensures that only the most recent is hittable, affectionately known as "note lock". + /// public class OrderedHitPolicy { private readonly HitObjectContainer hitObjectContainer; @@ -20,6 +23,15 @@ namespace osu.Game.Rulesets.Mania.UI this.hitObjectContainer = hitObjectContainer; } + /// + /// Determines whether a can be hit at a point in time. + /// + /// + /// Only the most recent can be hit, a previous hitobject's window cannot extend past the next one. + /// + /// The to check. + /// The time to check. + /// Whether can be hit at the given . public bool IsHittable(DrawableHitObject hitObject, double time) { var nextObject = hitObjectContainer.AliveObjects.GetNext(hitObject); From 29b29cde8e69330a1fdb62aec6ea802288242ec3 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 27 Aug 2020 23:09:54 +0900 Subject: [PATCH 341/434] Flip condition to reduce nesting --- .../Skinning/LegacyBodyPiece.cs | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Skinning/LegacyBodyPiece.cs b/osu.Game.Rulesets.Mania/Skinning/LegacyBodyPiece.cs index a1c2559386..f2e92a7258 100644 --- a/osu.Game.Rulesets.Mania/Skinning/LegacyBodyPiece.cs +++ b/osu.Game.Rulesets.Mania/Skinning/LegacyBodyPiece.cs @@ -101,28 +101,28 @@ namespace osu.Game.Rulesets.Mania.Skinning bodyAnimation.IsPlaying = isHitting.NewValue; } - if (lightContainer != null) + if (lightContainer == null) + return; + + if (isHitting.NewValue) { - if (isHitting.NewValue) - { - // Clear the fade out and, more importantly, the removal. - lightContainer.ClearTransforms(); + // Clear the fade out and, more importantly, the removal. + lightContainer.ClearTransforms(); - // Only add the container if the removal has taken place. - if (lightContainer.Parent == null) - Column.TopLevelContainer.Add(lightContainer); + // Only add the container if the removal has taken place. + if (lightContainer.Parent == null) + Column.TopLevelContainer.Add(lightContainer); - // The light must be seeked only after being loaded, otherwise a nullref occurs (https://github.com/ppy/osu-framework/issues/3847). - if (light is TextureAnimation lightAnimation) - lightAnimation.GotoFrame(0); + // The light must be seeked only after being loaded, otherwise a nullref occurs (https://github.com/ppy/osu-framework/issues/3847). + if (light is TextureAnimation lightAnimation) + lightAnimation.GotoFrame(0); - lightContainer.FadeIn(80); - } - else - { - lightContainer.FadeOut(120) - .OnComplete(d => Column.TopLevelContainer.Remove(d)); - } + lightContainer.FadeIn(80); + } + else + { + lightContainer.FadeOut(120) + .OnComplete(d => Column.TopLevelContainer.Remove(d)); } } From 700219316519201aa90ec2327091244553b6e250 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 27 Aug 2020 23:16:54 +0900 Subject: [PATCH 342/434] Mark nullable members --- osu.Game.Rulesets.Mania/Skinning/LegacyBodyPiece.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/osu.Game.Rulesets.Mania/Skinning/LegacyBodyPiece.cs b/osu.Game.Rulesets.Mania/Skinning/LegacyBodyPiece.cs index f2e92a7258..c0f0fcb4af 100644 --- a/osu.Game.Rulesets.Mania/Skinning/LegacyBodyPiece.cs +++ b/osu.Game.Rulesets.Mania/Skinning/LegacyBodyPiece.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System; +using JetBrains.Annotations; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -20,8 +21,13 @@ namespace osu.Game.Rulesets.Mania.Skinning private readonly IBindable direction = new Bindable(); private readonly IBindable isHitting = new Bindable(); + [CanBeNull] private Drawable bodySprite; + + [CanBeNull] private Drawable lightContainer; + + [CanBeNull] private Drawable light; public LegacyBodyPiece() From 9d70b4af0922a20a1877df82bd745896d8b72132 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Thu, 27 Aug 2020 17:35:42 +0200 Subject: [PATCH 343/434] Add failing test case --- .../Formats/LegacyScoreDecoderTest.cs | 66 ++++++++++++++++++ .../Resources/Replays/mania-replay.osr | Bin 0 -> 1012 bytes 2 files changed, 66 insertions(+) create mode 100644 osu.Game.Tests/Beatmaps/Formats/LegacyScoreDecoderTest.cs create mode 100644 osu.Game.Tests/Resources/Replays/mania-replay.osr diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyScoreDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyScoreDecoderTest.cs new file mode 100644 index 0000000000..31c367aad1 --- /dev/null +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyScoreDecoderTest.cs @@ -0,0 +1,66 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Collections.Generic; +using System.Linq; +using NUnit.Framework; +using osu.Game.Beatmaps; +using osu.Game.Rulesets; +using osu.Game.Rulesets.Catch; +using osu.Game.Rulesets.Mania; +using osu.Game.Rulesets.Osu; +using osu.Game.Rulesets.Scoring; +using osu.Game.Rulesets.Taiko; +using osu.Game.Scoring.Legacy; +using osu.Game.Tests.Resources; + +namespace osu.Game.Tests.Beatmaps.Formats +{ + [TestFixture] + public class LegacyScoreDecoderTest + { + [Test] + public void TestDecodeManiaReplay() + { + var decoder = new TestLegacyScoreDecoder(); + + using (var resourceStream = TestResources.OpenResource("Replays/mania-replay.osr")) + { + var score = decoder.Parse(resourceStream); + + Assert.AreEqual(3, score.ScoreInfo.Ruleset.ID); + + Assert.AreEqual(2, score.ScoreInfo.Statistics[HitResult.Great]); + Assert.AreEqual(1, score.ScoreInfo.Statistics[HitResult.Good]); + + Assert.AreEqual(829_931, score.ScoreInfo.TotalScore); + Assert.AreEqual(3, score.ScoreInfo.MaxCombo); + + Assert.That(score.Replay.Frames, Is.Not.Empty); + } + } + + private class TestLegacyScoreDecoder : LegacyScoreDecoder + { + private static readonly Dictionary rulesets = new Ruleset[] + { + new OsuRuleset(), + new TaikoRuleset(), + new CatchRuleset(), + new ManiaRuleset() + }.ToDictionary(ruleset => ((ILegacyRuleset)ruleset).LegacyID); + + protected override Ruleset GetRuleset(int rulesetId) => rulesets[rulesetId]; + + protected override WorkingBeatmap GetBeatmap(string md5Hash) => new TestWorkingBeatmap(new Beatmap + { + BeatmapInfo = new BeatmapInfo + { + MD5Hash = md5Hash, + Ruleset = new OsuRuleset().RulesetInfo, + BaseDifficulty = new BeatmapDifficulty() + } + }); + } + } +} diff --git a/osu.Game.Tests/Resources/Replays/mania-replay.osr b/osu.Game.Tests/Resources/Replays/mania-replay.osr new file mode 100644 index 0000000000000000000000000000000000000000..da1a7bdd28e5b89eddd9742bce2b27bc8e75e6f5 GIT binary patch literal 1012 zcmV2Fk>_^VL323Gh;F`G&3?}Wi$c+0000000031008T$3;+WF00000 z01FT?FgZ6ed@(FBI50Uld@(FxP`z80O4tZ&0{{SB001BWz5CvGFroXr>*+lrR^_@@;>&b?uOx<^mMIMT(+z#h{kY?X9fc(g(Lwebtx# z7Q6Lh=|qk7uqqmlbl#mwF~34O;`FY?03m(j9XrY3L)0)1?Fw}$4J_CNJKO;4?X$~q z;+wGa#wD!!0q2PlCzFrV3*3>Lz{D|fez@9JR^@L#NXJJJ;9{+KP~}bh@_eim%+NSk zzegnGWya)SS7pW`<9yI$g`b0t!?MZslqBX+4bVy#tZV0pDNGmeSXKuOXGQ|f3zg8y zGrMu+gxo2?L-AA5RBaNH&*&Dv9Dc!%ufdTEO? zp@}%SBej)D4N{g#xwHF)8|Ks=@OJ2^BGnjH?@$dDOeELCl()%CSSocJ#J0 zrMz`0akC4=AW51K>p71-r!saF*3AP)S9{~98w6pYSsUr1=*o_Q#S)6A-dHA@d9~(^0+ax|D@!;n;Z|| zFvVlqvtKZJf2x8EVoS#`3YPzS-*vaun`i1N*BG`MvK_+XgTPh^GgHpdy!e==KZIaT z3!YC}(8nGj*i;imyixwy9zyF`AooHY90sBzR$Obzb-Vi~&7$v#i3~s7*O{}|SLmeL zoMGZCnRwCc_XbwVIh5g#M@wt{FGra$aqhxs9vn18+0v`>fSkg3XKs=0k_AUDZ~8>a zDG78!sD4dHOSBcg!q83SKA#^J)eG3=oY`jU3QIF2QVgemNl8@7S4(W%aYN@e0jDu% zmqiUorSh0*IbBRsW~4cH;@gJJOutPU2TVP<=OEnHm=mZ{2D~6Z=U*j5r!6K@YHyj* zwhC8cbzc~TkcHU?&2W;Km_To^u4o{p7%^`#txPglTyDDFl%vh Date: Thu, 27 Aug 2020 17:40:22 +0200 Subject: [PATCH 344/434] Fix some legacy mania replays crashing on import --- osu.Game/Scoring/Legacy/LegacyScoreDecoder.cs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/osu.Game/Scoring/Legacy/LegacyScoreDecoder.cs b/osu.Game/Scoring/Legacy/LegacyScoreDecoder.cs index a4a560c8e4..a3469f0965 100644 --- a/osu.Game/Scoring/Legacy/LegacyScoreDecoder.cs +++ b/osu.Game/Scoring/Legacy/LegacyScoreDecoder.cs @@ -241,12 +241,15 @@ namespace osu.Game.Scoring.Legacy } var diff = Parsing.ParseFloat(split[0]); + var mouseX = Parsing.ParseFloat(split[1], Parsing.MAX_COORDINATE_VALUE); + var mouseY = Parsing.ParseFloat(split[2], Parsing.MAX_COORDINATE_VALUE); lastTime += diff; - if (i == 0 && diff == 0) - // osu-stable adds a zero-time frame before potentially valid negative user frames. - // we need to ignore this. + if (i < 2 && mouseX == 256 && mouseY == -500) + // at the start of the replay, stable places two replay frames, at time 0 and SkipBoundary - 1, respectively. + // both frames use a position of (256, -500). + // ignore these frames as they serve no real purpose (and can even mislead ruleset-specific handlers - see mania) continue; // Todo: At some point we probably want to rewind and play back the negative-time frames @@ -255,8 +258,8 @@ namespace osu.Game.Scoring.Legacy continue; currentFrame = convertFrame(new LegacyReplayFrame(lastTime, - Parsing.ParseFloat(split[1], Parsing.MAX_COORDINATE_VALUE), - Parsing.ParseFloat(split[2], Parsing.MAX_COORDINATE_VALUE), + mouseX, + mouseY, (ReplayButtonState)Parsing.ParseInt(split[3])), currentFrame); replay.Frames.Add(currentFrame); From 37387d774165340e14c1e1ea493e23bb3aea693a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Thu, 27 Aug 2020 17:57:55 +0200 Subject: [PATCH 345/434] Add assertions to existing test to cover bug --- osu.Game.Tests/Beatmaps/Formats/LegacyScoreDecoderTest.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyScoreDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyScoreDecoderTest.cs index 31c367aad1..9c71466489 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyScoreDecoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyScoreDecoderTest.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Linq; using NUnit.Framework; +using osu.Framework.Utils; using osu.Game.Beatmaps; using osu.Game.Rulesets; using osu.Game.Rulesets.Catch; @@ -11,6 +12,7 @@ using osu.Game.Rulesets.Mania; using osu.Game.Rulesets.Osu; using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.Taiko; +using osu.Game.Scoring; using osu.Game.Scoring.Legacy; using osu.Game.Tests.Resources; @@ -35,6 +37,8 @@ namespace osu.Game.Tests.Beatmaps.Formats Assert.AreEqual(829_931, score.ScoreInfo.TotalScore); Assert.AreEqual(3, score.ScoreInfo.MaxCombo); + Assert.IsTrue(Precision.AlmostEquals(0.8889, score.ScoreInfo.Accuracy, 0.0001)); + Assert.AreEqual(ScoreRank.B, score.ScoreInfo.Rank); Assert.That(score.Replay.Frames, Is.Not.Empty); } From af59e2c17954ce8fbf3df20ed2a0b6d3eeb74fa1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Thu, 27 Aug 2020 18:05:06 +0200 Subject: [PATCH 346/434] Use extension methods instead of reading directly --- osu.Game/Scoring/Legacy/LegacyScoreDecoder.cs | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/osu.Game/Scoring/Legacy/LegacyScoreDecoder.cs b/osu.Game/Scoring/Legacy/LegacyScoreDecoder.cs index a3469f0965..97cb5ca7ab 100644 --- a/osu.Game/Scoring/Legacy/LegacyScoreDecoder.cs +++ b/osu.Game/Scoring/Legacy/LegacyScoreDecoder.cs @@ -13,7 +13,6 @@ using osu.Game.Replays.Legacy; using osu.Game.Rulesets; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Replays; -using osu.Game.Rulesets.Scoring; using osu.Game.Users; using SharpCompress.Compressors.LZMA; @@ -123,12 +122,12 @@ namespace osu.Game.Scoring.Legacy protected void CalculateAccuracy(ScoreInfo score) { - score.Statistics.TryGetValue(HitResult.Miss, out int countMiss); - score.Statistics.TryGetValue(HitResult.Meh, out int count50); - score.Statistics.TryGetValue(HitResult.Good, out int count100); - score.Statistics.TryGetValue(HitResult.Great, out int count300); - score.Statistics.TryGetValue(HitResult.Perfect, out int countGeki); - score.Statistics.TryGetValue(HitResult.Ok, out int countKatu); + int countMiss = score.GetCountMiss() ?? 0; + int count50 = score.GetCount50() ?? 0; + int count100 = score.GetCount100() ?? 0; + int count300 = score.GetCount300() ?? 0; + int countGeki = score.GetCountGeki() ?? 0; + int countKatu = score.GetCountKatu() ?? 0; switch (score.Ruleset.ID) { From f152e1b924f23da565ce0a89fb19ca3f2f16ac50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Thu, 27 Aug 2020 20:07:30 +0200 Subject: [PATCH 347/434] Revert IStatisticRow changes --- osu.Game.Rulesets.Mania/ManiaRuleset.cs | 10 +------ osu.Game.Rulesets.Osu/OsuRuleset.cs | 12 ++------ osu.Game.Rulesets.Taiko/TaikoRuleset.cs | 12 ++------ osu.Game/Rulesets/Ruleset.cs | 2 +- .../Ranking/Statistics/IStatisticRow.cs | 18 ------------ .../Ranking/Statistics/SimpleStatisticRow.cs | 2 +- .../Ranking/Statistics/StatisticRow.cs | 24 ++-------------- .../Ranking/Statistics/StatisticsPanel.cs | 28 ++++++++++++++----- 8 files changed, 30 insertions(+), 78 deletions(-) delete mode 100644 osu.Game/Screens/Ranking/Statistics/IStatisticRow.cs diff --git a/osu.Game.Rulesets.Mania/ManiaRuleset.cs b/osu.Game.Rulesets.Mania/ManiaRuleset.cs index 490223b7a5..bbfc5739ec 100644 --- a/osu.Game.Rulesets.Mania/ManiaRuleset.cs +++ b/osu.Game.Rulesets.Mania/ManiaRuleset.cs @@ -314,7 +314,7 @@ namespace osu.Game.Rulesets.Mania return (PlayfieldType)Enum.GetValues(typeof(PlayfieldType)).Cast().OrderByDescending(i => i).First(v => variant >= v); } - public override IStatisticRow[] CreateStatisticsForScore(ScoreInfo score, IBeatmap playableBeatmap) => new IStatisticRow[] + public override StatisticRow[] CreateStatisticsForScore(ScoreInfo score, IBeatmap playableBeatmap) => new[] { new StatisticRow { @@ -327,14 +327,6 @@ namespace osu.Game.Rulesets.Mania }), } }, - new SimpleStatisticRow - { - Columns = 3, - Items = new SimpleStatisticItem[] - { - new UnstableRate(score.HitEvents) - } - } }; } diff --git a/osu.Game.Rulesets.Osu/OsuRuleset.cs b/osu.Game.Rulesets.Osu/OsuRuleset.cs index dd950c60ec..14e7b9e9a4 100644 --- a/osu.Game.Rulesets.Osu/OsuRuleset.cs +++ b/osu.Game.Rulesets.Osu/OsuRuleset.cs @@ -193,11 +193,11 @@ namespace osu.Game.Rulesets.Osu public override IRulesetConfigManager CreateConfig(SettingsStore settings) => new OsuRulesetConfigManager(settings, RulesetInfo); - public override IStatisticRow[] CreateStatisticsForScore(ScoreInfo score, IBeatmap playableBeatmap) + public override StatisticRow[] CreateStatisticsForScore(ScoreInfo score, IBeatmap playableBeatmap) { var timedHitEvents = score.HitEvents.Where(e => e.HitObject is HitCircle && !(e.HitObject is SliderTailCircle)).ToList(); - return new IStatisticRow[] + return new[] { new StatisticRow { @@ -222,14 +222,6 @@ namespace osu.Game.Rulesets.Osu }), } }, - new SimpleStatisticRow - { - Columns = 3, - Items = new SimpleStatisticItem[] - { - new UnstableRate(timedHitEvents) - } - } }; } } diff --git a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs index 938c038413..367d991677 100644 --- a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs +++ b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs @@ -161,11 +161,11 @@ namespace osu.Game.Rulesets.Taiko public override IConvertibleReplayFrame CreateConvertibleReplayFrame() => new TaikoReplayFrame(); - public override IStatisticRow[] CreateStatisticsForScore(ScoreInfo score, IBeatmap playableBeatmap) + public override StatisticRow[] CreateStatisticsForScore(ScoreInfo score, IBeatmap playableBeatmap) { var timedHitEvents = score.HitEvents.Where(e => e.HitObject is Hit).ToList(); - return new IStatisticRow[] + return new[] { new StatisticRow { @@ -178,14 +178,6 @@ namespace osu.Game.Rulesets.Taiko }), } }, - new SimpleStatisticRow - { - Columns = 3, - Items = new SimpleStatisticItem[] - { - new UnstableRate(timedHitEvents) - } - } }; } } diff --git a/osu.Game/Rulesets/Ruleset.cs b/osu.Game/Rulesets/Ruleset.cs index f82ecd842a..3a7f433a37 100644 --- a/osu.Game/Rulesets/Ruleset.cs +++ b/osu.Game/Rulesets/Ruleset.cs @@ -217,6 +217,6 @@ namespace osu.Game.Rulesets /// The , converted for this with all relevant s applied. /// The s to display. Each may contain 0 or more . [NotNull] - public virtual IStatisticRow[] CreateStatisticsForScore(ScoreInfo score, IBeatmap playableBeatmap) => Array.Empty(); + public virtual StatisticRow[] CreateStatisticsForScore(ScoreInfo score, IBeatmap playableBeatmap) => Array.Empty(); } } diff --git a/osu.Game/Screens/Ranking/Statistics/IStatisticRow.cs b/osu.Game/Screens/Ranking/Statistics/IStatisticRow.cs deleted file mode 100644 index 67224041d5..0000000000 --- a/osu.Game/Screens/Ranking/Statistics/IStatisticRow.cs +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using osu.Framework.Graphics; - -namespace osu.Game.Screens.Ranking.Statistics -{ - /// - /// A row of statistics to be displayed on the results screen. - /// - public interface IStatisticRow - { - /// - /// Creates the visual representation of this row. - /// - Drawable CreateDrawableStatisticRow(); - } -} diff --git a/osu.Game/Screens/Ranking/Statistics/SimpleStatisticRow.cs b/osu.Game/Screens/Ranking/Statistics/SimpleStatisticRow.cs index cd6afeb3a5..5c0cb5b116 100644 --- a/osu.Game/Screens/Ranking/Statistics/SimpleStatisticRow.cs +++ b/osu.Game/Screens/Ranking/Statistics/SimpleStatisticRow.cs @@ -10,7 +10,7 @@ namespace osu.Game.Screens.Ranking.Statistics /// /// Contains textual statistic data to display in a . /// - public class SimpleStatisticRow : IStatisticRow + public class SimpleStatisticRow { /// /// The number of columns to layout the in. diff --git a/osu.Game/Screens/Ranking/Statistics/StatisticRow.cs b/osu.Game/Screens/Ranking/Statistics/StatisticRow.cs index d5324e14f0..e1ca9799a3 100644 --- a/osu.Game/Screens/Ranking/Statistics/StatisticRow.cs +++ b/osu.Game/Screens/Ranking/Statistics/StatisticRow.cs @@ -1,39 +1,19 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System.Linq; using JetBrains.Annotations; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; namespace osu.Game.Screens.Ranking.Statistics { /// - /// A row of graphically detailed s to be displayed in the results screen. + /// A row of statistics to be displayed in the results screen. /// - public class StatisticRow : IStatisticRow + public class StatisticRow { /// /// The columns of this . /// [ItemNotNull] public StatisticItem[] Columns; - - public Drawable CreateDrawableStatisticRow() => new GridContainer - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Content = new[] - { - Columns?.Select(c => new StatisticContainer(c) - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - }).Cast().ToArray() - }, - ColumnDimensions = Enumerable.Range(0, Columns?.Length ?? 0) - .Select(i => Columns[i].Dimension ?? new Dimension()).ToArray(), - RowDimensions = new[] { new Dimension(GridSizeMode.AutoSize) } - }; } } diff --git a/osu.Game/Screens/Ranking/Statistics/StatisticsPanel.cs b/osu.Game/Screens/Ranking/Statistics/StatisticsPanel.cs index 3b8f980070..128c6674e8 100644 --- a/osu.Game/Screens/Ranking/Statistics/StatisticsPanel.cs +++ b/osu.Game/Screens/Ranking/Statistics/StatisticsPanel.cs @@ -97,13 +97,27 @@ namespace osu.Game.Screens.Ranking.Statistics Alpha = 0 }; - rows.AddRange(newScore.Ruleset.CreateInstance() - .CreateStatisticsForScore(newScore, playableBeatmap) - .Select(row => row.CreateDrawableStatisticRow().With(r => - { - r.Anchor = Anchor.TopCentre; - r.Origin = Anchor.TopCentre; - }))); + foreach (var row in newScore.Ruleset.CreateInstance().CreateStatisticsForScore(newScore, playableBeatmap)) + { + rows.Add(new GridContainer + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Content = new[] + { + row.Columns?.Select(c => new StatisticContainer(c) + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + }).Cast().ToArray() + }, + ColumnDimensions = Enumerable.Range(0, row.Columns?.Length ?? 0) + .Select(i => row.Columns[i].Dimension ?? new Dimension()).ToArray(), + RowDimensions = new[] { new Dimension(GridSizeMode.AutoSize) } + }); + } LoadComponentAsync(rows, d => { From ce013ac9b4fe80910f187b2856985b695b93cf88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Thu, 27 Aug 2020 20:18:53 +0200 Subject: [PATCH 348/434] Make statistic header optional --- .../Ranking/Statistics/StatisticContainer.cs | 60 +++++++++++-------- .../Ranking/Statistics/StatisticItem.cs | 2 +- 2 files changed, 35 insertions(+), 27 deletions(-) diff --git a/osu.Game/Screens/Ranking/Statistics/StatisticContainer.cs b/osu.Game/Screens/Ranking/Statistics/StatisticContainer.cs index ed98698411..485d24d024 100644 --- a/osu.Game/Screens/Ranking/Statistics/StatisticContainer.cs +++ b/osu.Game/Screens/Ranking/Statistics/StatisticContainer.cs @@ -32,33 +32,9 @@ namespace osu.Game.Screens.Ranking.Statistics AutoSizeAxes = Axes.Y, Content = new[] { - new Drawable[] + new[] { - new FillFlowContainer - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Direction = FillDirection.Horizontal, - Spacing = new Vector2(5, 0), - Children = new Drawable[] - { - new Circle - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - Height = 9, - Width = 4, - Colour = Color4Extensions.FromHex("#00FFAA") - }, - new OsuSpriteText - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - Text = item.Name, - Font = OsuFont.GetFont(size: 14, weight: FontWeight.SemiBold), - } - } - } + createHeader(item) }, new Drawable[] { @@ -78,5 +54,37 @@ namespace osu.Game.Screens.Ranking.Statistics } }; } + + private static Drawable createHeader(StatisticItem item) + { + if (string.IsNullOrEmpty(item.Name)) + return Empty(); + + return new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(5, 0), + Children = new Drawable[] + { + new Circle + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Height = 9, + Width = 4, + Colour = Color4Extensions.FromHex("#00FFAA") + }, + new OsuSpriteText + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Text = item.Name, + Font = OsuFont.GetFont(size: 14, weight: FontWeight.SemiBold), + } + } + }; + } } } diff --git a/osu.Game/Screens/Ranking/Statistics/StatisticItem.cs b/osu.Game/Screens/Ranking/Statistics/StatisticItem.cs index e959ed24fc..4903983759 100644 --- a/osu.Game/Screens/Ranking/Statistics/StatisticItem.cs +++ b/osu.Game/Screens/Ranking/Statistics/StatisticItem.cs @@ -30,7 +30,7 @@ namespace osu.Game.Screens.Ranking.Statistics /// /// Creates a new , to be displayed inside a in the results screen. /// - /// The name of the item. + /// The name of the item. Can be to hide the item header. /// The content to be displayed. /// The of this item. This can be thought of as the column dimension of an encompassing . public StatisticItem([NotNull] string name, [NotNull] Drawable content, [CanBeNull] Dimension dimension = null) From ea1f07e311add124437f0346fbb85300c88ab699 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Thu, 27 Aug 2020 20:30:57 +0200 Subject: [PATCH 349/434] Simplify/rename SimpleStatisticRow mess --- ...ow.cs => TestSceneSimpleStatisticTable.cs} | 6 ++-- .../Ranking/Statistics/SimpleStatisticRow.cs | 34 ------------------- ...tatisticRow.cs => SimpleStatisticTable.cs} | 6 ++-- 3 files changed, 6 insertions(+), 40 deletions(-) rename osu.Game.Tests/Visual/Ranking/{TestSceneDrawableSimpleStatisticRow.cs => TestSceneSimpleStatisticTable.cs} (88%) delete mode 100644 osu.Game/Screens/Ranking/Statistics/SimpleStatisticRow.cs rename osu.Game/Screens/Ranking/Statistics/{DrawableSimpleStatisticRow.cs => SimpleStatisticTable.cs} (93%) diff --git a/osu.Game.Tests/Visual/Ranking/TestSceneDrawableSimpleStatisticRow.cs b/osu.Game.Tests/Visual/Ranking/TestSceneSimpleStatisticTable.cs similarity index 88% rename from osu.Game.Tests/Visual/Ranking/TestSceneDrawableSimpleStatisticRow.cs rename to osu.Game.Tests/Visual/Ranking/TestSceneSimpleStatisticTable.cs index 2b0ba30357..07a0bcc8d8 100644 --- a/osu.Game.Tests/Visual/Ranking/TestSceneDrawableSimpleStatisticRow.cs +++ b/osu.Game.Tests/Visual/Ranking/TestSceneSimpleStatisticTable.cs @@ -13,7 +13,7 @@ using osu.Game.Screens.Ranking.Statistics; namespace osu.Game.Tests.Visual.Ranking { - public class TestSceneDrawableSimpleStatisticRow : OsuTestScene + public class TestSceneSimpleStatisticTable : OsuTestScene { private Container container; @@ -45,7 +45,7 @@ namespace osu.Game.Tests.Visual.Ranking public void TestEmpty() { AddStep("create with no items", - () => container.Add(new DrawableSimpleStatisticRow(2, Enumerable.Empty()))); + () => container.Add(new SimpleStatisticTable(2, Enumerable.Empty()))); } [Test] @@ -61,7 +61,7 @@ namespace osu.Game.Tests.Visual.Ranking Value = RNG.Next(100) }); - container.Add(new DrawableSimpleStatisticRow(columnCount, items)); + container.Add(new SimpleStatisticTable(columnCount, items)); }); } } diff --git a/osu.Game/Screens/Ranking/Statistics/SimpleStatisticRow.cs b/osu.Game/Screens/Ranking/Statistics/SimpleStatisticRow.cs deleted file mode 100644 index 5c0cb5b116..0000000000 --- a/osu.Game/Screens/Ranking/Statistics/SimpleStatisticRow.cs +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using JetBrains.Annotations; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; - -namespace osu.Game.Screens.Ranking.Statistics -{ - /// - /// Contains textual statistic data to display in a . - /// - public class SimpleStatisticRow - { - /// - /// The number of columns to layout the in. - /// - public int Columns { get; set; } - - /// - /// The s that this row should contain. - /// - [ItemNotNull] - public SimpleStatisticItem[] Items { get; set; } - - public Drawable CreateDrawableStatisticRow() => new Container - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Padding = new MarginPadding(20), - Child = new DrawableSimpleStatisticRow(Columns, Items) - }; - } -} diff --git a/osu.Game/Screens/Ranking/Statistics/DrawableSimpleStatisticRow.cs b/osu.Game/Screens/Ranking/Statistics/SimpleStatisticTable.cs similarity index 93% rename from osu.Game/Screens/Ranking/Statistics/DrawableSimpleStatisticRow.cs rename to osu.Game/Screens/Ranking/Statistics/SimpleStatisticTable.cs index 7f69b323d8..8b503cc04e 100644 --- a/osu.Game/Screens/Ranking/Statistics/DrawableSimpleStatisticRow.cs +++ b/osu.Game/Screens/Ranking/Statistics/SimpleStatisticTable.cs @@ -14,10 +14,10 @@ using osu.Framework.Graphics.Shapes; namespace osu.Game.Screens.Ranking.Statistics { /// - /// Represents a statistic row with simple statistics (ones that only need textual display). + /// Represents a table with simple statistics (ones that only need textual display). /// Richer visualisations should be done with s and s. /// - public class DrawableSimpleStatisticRow : CompositeDrawable + public class SimpleStatisticTable : CompositeDrawable { private readonly SimpleStatisticItem[] items; private readonly int columnCount; @@ -29,7 +29,7 @@ namespace osu.Game.Screens.Ranking.Statistics /// /// The number of columns to layout the into. /// The s to display in this row. - public DrawableSimpleStatisticRow(int columnCount, [ItemNotNull] IEnumerable items) + public SimpleStatisticTable(int columnCount, [ItemNotNull] IEnumerable items) { if (columnCount < 1) throw new ArgumentOutOfRangeException(nameof(columnCount)); From 43d6d2b2e8845d073f78fa491d4f9946217828c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Thu, 27 Aug 2020 20:46:49 +0200 Subject: [PATCH 350/434] Add back unstable rate display --- osu.Game.Rulesets.Mania/ManiaRuleset.cs | 10 ++++++++++ osu.Game.Rulesets.Osu/OsuRuleset.cs | 10 ++++++++++ osu.Game.Rulesets.Taiko/TaikoRuleset.cs | 10 ++++++++++ 3 files changed, 30 insertions(+) diff --git a/osu.Game.Rulesets.Mania/ManiaRuleset.cs b/osu.Game.Rulesets.Mania/ManiaRuleset.cs index bbfc5739ec..f7098faa5d 100644 --- a/osu.Game.Rulesets.Mania/ManiaRuleset.cs +++ b/osu.Game.Rulesets.Mania/ManiaRuleset.cs @@ -327,6 +327,16 @@ namespace osu.Game.Rulesets.Mania }), } }, + new StatisticRow + { + Columns = new[] + { + new StatisticItem(string.Empty, new SimpleStatisticTable(3, new SimpleStatisticItem[] + { + new UnstableRate(score.HitEvents) + })) + } + } }; } diff --git a/osu.Game.Rulesets.Osu/OsuRuleset.cs b/osu.Game.Rulesets.Osu/OsuRuleset.cs index 14e7b9e9a4..f527eb2312 100644 --- a/osu.Game.Rulesets.Osu/OsuRuleset.cs +++ b/osu.Game.Rulesets.Osu/OsuRuleset.cs @@ -222,6 +222,16 @@ namespace osu.Game.Rulesets.Osu }), } }, + new StatisticRow + { + Columns = new[] + { + new StatisticItem(string.Empty, new SimpleStatisticTable(3, new SimpleStatisticItem[] + { + new UnstableRate(timedHitEvents) + })) + } + } }; } } diff --git a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs index 367d991677..dbc32f2c3e 100644 --- a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs +++ b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs @@ -178,6 +178,16 @@ namespace osu.Game.Rulesets.Taiko }), } }, + new StatisticRow + { + Columns = new[] + { + new StatisticItem(string.Empty, new SimpleStatisticTable(3, new SimpleStatisticItem[] + { + new UnstableRate(timedHitEvents) + })) + } + } }; } } From 6846a245f42e60955ea20be79c7a2b43e334cbde Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Thu, 27 Aug 2020 20:51:28 +0200 Subject: [PATCH 351/434] Reapply lost anchoring fix --- osu.Game/Screens/Ranking/Statistics/StatisticsPanel.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Ranking/Statistics/StatisticsPanel.cs b/osu.Game/Screens/Ranking/Statistics/StatisticsPanel.cs index 128c6674e8..c2ace6a04e 100644 --- a/osu.Game/Screens/Ranking/Statistics/StatisticsPanel.cs +++ b/osu.Game/Screens/Ranking/Statistics/StatisticsPanel.cs @@ -101,8 +101,8 @@ namespace osu.Game.Screens.Ranking.Statistics { rows.Add(new GridContainer { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, Content = new[] From 43c61e58308e2f411971a72da430292088d03487 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 28 Aug 2020 22:08:28 +0900 Subject: [PATCH 352/434] Re-query beatmap difficulty before computing --- osu.Game/Beatmaps/BeatmapDifficultyManager.cs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapDifficultyManager.cs b/osu.Game/Beatmaps/BeatmapDifficultyManager.cs index b80b4e45ed..490f1ba67c 100644 --- a/osu.Game/Beatmaps/BeatmapDifficultyManager.cs +++ b/osu.Game/Beatmaps/BeatmapDifficultyManager.cs @@ -89,8 +89,14 @@ namespace osu.Game.Beatmaps if (tryGetExisting(beatmapInfo, rulesetInfo, mods, out var existing, out var key)) return existing; - return await Task.Factory.StartNew(() => computeDifficulty(key, beatmapInfo, rulesetInfo), cancellationToken, - TaskCreationOptions.HideScheduler | TaskCreationOptions.RunContinuationsAsynchronously, updateScheduler); + return await Task.Factory.StartNew(() => + { + // Computation may have finished in a previous task. + if (tryGetExisting(beatmapInfo, rulesetInfo, mods, out existing, out _)) + return existing; + + return computeDifficulty(key, beatmapInfo, rulesetInfo); + }, cancellationToken, TaskCreationOptions.HideScheduler | TaskCreationOptions.RunContinuationsAsynchronously, updateScheduler); } /// From 436dbafe57614261e9380825aea13b802c9a6dbb Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 28 Aug 2020 22:12:17 +0900 Subject: [PATCH 353/434] Fix incorrect comparison for mods of different instances --- .../Beatmaps/BeatmapDifficultyManagerTest.cs | 32 +++++++++++++++++++ osu.Game/Beatmaps/BeatmapDifficultyManager.cs | 4 +-- 2 files changed, 34 insertions(+), 2 deletions(-) create mode 100644 osu.Game.Tests/Beatmaps/BeatmapDifficultyManagerTest.cs diff --git a/osu.Game.Tests/Beatmaps/BeatmapDifficultyManagerTest.cs b/osu.Game.Tests/Beatmaps/BeatmapDifficultyManagerTest.cs new file mode 100644 index 0000000000..0f6d956b3c --- /dev/null +++ b/osu.Game.Tests/Beatmaps/BeatmapDifficultyManagerTest.cs @@ -0,0 +1,32 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using NUnit.Framework; +using osu.Game.Beatmaps; +using osu.Game.Rulesets.Mods; +using osu.Game.Rulesets.Osu.Mods; + +namespace osu.Game.Tests.Beatmaps +{ + [TestFixture] + public class BeatmapDifficultyManagerTest + { + [Test] + public void TestKeyEqualsWithDifferentModInstances() + { + var key1 = new BeatmapDifficultyManager.DifficultyCacheLookup(1234, 0, new Mod[] { new OsuModHardRock(), new OsuModHidden() }); + var key2 = new BeatmapDifficultyManager.DifficultyCacheLookup(1234, 0, new Mod[] { new OsuModHardRock(), new OsuModHidden() }); + + Assert.That(key1, Is.EqualTo(key2)); + } + + [Test] + public void TestKeyEqualsWithDifferentModOrder() + { + var key1 = new BeatmapDifficultyManager.DifficultyCacheLookup(1234, 0, new Mod[] { new OsuModHardRock(), new OsuModHidden() }); + var key2 = new BeatmapDifficultyManager.DifficultyCacheLookup(1234, 0, new Mod[] { new OsuModHidden(), new OsuModHardRock() }); + + Assert.That(key1, Is.EqualTo(key2)); + } + } +} diff --git a/osu.Game/Beatmaps/BeatmapDifficultyManager.cs b/osu.Game/Beatmaps/BeatmapDifficultyManager.cs index 490f1ba67c..0100c9b210 100644 --- a/osu.Game/Beatmaps/BeatmapDifficultyManager.cs +++ b/osu.Game/Beatmaps/BeatmapDifficultyManager.cs @@ -251,7 +251,7 @@ namespace osu.Game.Beatmaps updateScheduler?.Dispose(); } - private readonly struct DifficultyCacheLookup : IEquatable + public readonly struct DifficultyCacheLookup : IEquatable { public readonly int BeatmapId; public readonly int RulesetId; @@ -267,7 +267,7 @@ namespace osu.Game.Beatmaps public bool Equals(DifficultyCacheLookup other) => BeatmapId == other.BeatmapId && RulesetId == other.RulesetId - && Mods.SequenceEqual(other.Mods); + && Mods.Select(m => m.Acronym).SequenceEqual(other.Mods.Select(m => m.Acronym)); public override int GetHashCode() { From 4cb9e1d4438895b7176c72464fcd6c65e738ac71 Mon Sep 17 00:00:00 2001 From: Craftplacer Date: Sat, 29 Aug 2020 10:33:43 +0200 Subject: [PATCH 354/434] Initial commit --- .../TestSceneLegacyBeatmapSkin.cs | 2 +- osu.Game.Rulesets.Osu.Tests/TestSceneSkinFallbacks.cs | 9 ++++++--- osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs | 5 +++-- osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs | 2 +- osu.Game/Beatmaps/IWorkingBeatmap.cs | 2 +- osu.Game/Beatmaps/WorkingBeatmap.cs | 8 ++++---- osu.Game/Skinning/BeatmapSkinProvidingContainer.cs | 4 ++-- osu.Game/Skinning/DefaultBeatmapSkin.cs | 9 +++++++++ osu.Game/Skinning/IBeatmapSkin.cs | 9 +++++++++ osu.Game/Skinning/LegacyBeatmapSkin.cs | 2 +- osu.Game/Tests/Beatmaps/HitObjectSampleTest.cs | 2 +- 11 files changed, 38 insertions(+), 16 deletions(-) create mode 100644 osu.Game/Skinning/DefaultBeatmapSkin.cs create mode 100644 osu.Game/Skinning/IBeatmapSkin.cs diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneLegacyBeatmapSkin.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneLegacyBeatmapSkin.cs index 3ff37c4147..03d18cefef 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneLegacyBeatmapSkin.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneLegacyBeatmapSkin.cs @@ -110,7 +110,7 @@ namespace osu.Game.Rulesets.Osu.Tests this.hasColours = hasColours; } - protected override ISkin GetSkin() => new TestBeatmapSkin(BeatmapInfo, hasColours); + protected override IBeatmapSkin GetSkin() => new TestBeatmapSkin(BeatmapInfo, hasColours); } private class TestBeatmapSkin : LegacyBeatmapSkin diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSkinFallbacks.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSkinFallbacks.cs index 075bf314bc..c3c19de17c 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSkinFallbacks.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSkinFallbacks.cs @@ -80,15 +80,18 @@ namespace osu.Game.Rulesets.Osu.Tests public class CustomSkinWorkingBeatmap : ClockBackedTestWorkingBeatmap { - private readonly ISkinSource skin; + private readonly ISkinSource skinSource; public CustomSkinWorkingBeatmap(IBeatmap beatmap, Storyboard storyboard, IFrameBasedClock frameBasedClock, AudioManager audio, ISkinSource skin) : base(beatmap, storyboard, frameBasedClock, audio) { - this.skin = skin; + if (!(skinSource is IBeatmapSkin)) + throw new ArgumentException("The provided skin source must be of type IBeatmapSkin."); + + skinSource = skin; } - protected override ISkin GetSkin() => skin; + protected override IBeatmapSkin GetSkin() => (IBeatmapSkin)skinSource; } public class SkinProvidingPlayer : TestPlayer diff --git a/osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs b/osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs index b30870d057..996d495e17 100644 --- a/osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs +++ b/osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs @@ -116,7 +116,8 @@ namespace osu.Game.Tests.Gameplay AddAssert("sample playback rate matches mod rates", () => sample.Channel.AggregateFrequency.Value == expectedRate); } - private class TestSkin : LegacySkin + // TODO: adding IBeatmapSkin changes are as minimal as possible, but this shouldn't exist or should be reworked to work with LegacyBeatmapSkin + private class TestSkin : LegacySkin, IBeatmapSkin { public TestSkin(string resourceName, AudioManager audioManager) : base(DefaultLegacySkin.Info, new TestResourceStore(resourceName), audioManager, "skin.ini") @@ -156,7 +157,7 @@ namespace osu.Game.Tests.Gameplay this.audio = audio; } - protected override ISkin GetSkin() => new TestSkin("test-sample", audio); + protected override IBeatmapSkin GetSkin() => new TestSkin("test-sample", audio); } private class TestDrawableStoryboardSample : DrawableStoryboardSample diff --git a/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs b/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs index 39c5ccab27..44728cc251 100644 --- a/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs @@ -140,7 +140,7 @@ namespace osu.Game.Beatmaps return storyboard; } - protected override ISkin GetSkin() + protected override IBeatmapSkin GetSkin() { try { diff --git a/osu.Game/Beatmaps/IWorkingBeatmap.cs b/osu.Game/Beatmaps/IWorkingBeatmap.cs index 31975157a0..dac9389822 100644 --- a/osu.Game/Beatmaps/IWorkingBeatmap.cs +++ b/osu.Game/Beatmaps/IWorkingBeatmap.cs @@ -44,7 +44,7 @@ namespace osu.Game.Beatmaps /// /// Retrieves the which this provides. /// - ISkin Skin { get; } + IBeatmapSkin Skin { get; } /// /// Constructs a playable from using the applicable converters for a specific . diff --git a/osu.Game/Beatmaps/WorkingBeatmap.cs b/osu.Game/Beatmaps/WorkingBeatmap.cs index b4bcf285b9..163b62a55c 100644 --- a/osu.Game/Beatmaps/WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/WorkingBeatmap.cs @@ -44,7 +44,7 @@ namespace osu.Game.Beatmaps background = new RecyclableLazy(GetBackground, BackgroundStillValid); waveform = new RecyclableLazy(GetWaveform); storyboard = new RecyclableLazy(GetStoryboard); - skin = new RecyclableLazy(GetSkin); + skin = new RecyclableLazy(GetSkin); total_count.Value++; } @@ -275,10 +275,10 @@ namespace osu.Game.Beatmaps private readonly RecyclableLazy storyboard; public bool SkinLoaded => skin.IsResultAvailable; - public ISkin Skin => skin.Value; + public IBeatmapSkin Skin => skin.Value; - protected virtual ISkin GetSkin() => new DefaultSkin(); - private readonly RecyclableLazy skin; + protected virtual IBeatmapSkin GetSkin() => new DefaultBeatmapSkin(); + private readonly RecyclableLazy skin; /// /// Transfer pieces of a beatmap to a new one, where possible, to save on loading. diff --git a/osu.Game/Skinning/BeatmapSkinProvidingContainer.cs b/osu.Game/Skinning/BeatmapSkinProvidingContainer.cs index 40335db697..346bfe53b8 100644 --- a/osu.Game/Skinning/BeatmapSkinProvidingContainer.cs +++ b/osu.Game/Skinning/BeatmapSkinProvidingContainer.cs @@ -11,7 +11,7 @@ namespace osu.Game.Skinning /// /// A container which overrides existing skin options with beatmap-local values. /// - public class BeatmapSkinProvidingContainer : SkinProvidingContainer + public class BeatmapSkinProvidingContainer : SkinProvidingContainer, IBeatmapSkin { private readonly Bindable beatmapSkins = new Bindable(); private readonly Bindable beatmapHitsounds = new Bindable(); @@ -21,7 +21,7 @@ namespace osu.Game.Skinning protected override bool AllowTextureLookup(string componentName) => beatmapSkins.Value; protected override bool AllowSampleLookup(ISampleInfo componentName) => beatmapHitsounds.Value; - public BeatmapSkinProvidingContainer(ISkin skin) + public BeatmapSkinProvidingContainer(IBeatmapSkin skin) : base(skin) { } diff --git a/osu.Game/Skinning/DefaultBeatmapSkin.cs b/osu.Game/Skinning/DefaultBeatmapSkin.cs new file mode 100644 index 0000000000..7b5ccd45c3 --- /dev/null +++ b/osu.Game/Skinning/DefaultBeatmapSkin.cs @@ -0,0 +1,9 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +namespace osu.Game.Skinning +{ + public class DefaultBeatmapSkin : DefaultSkin, IBeatmapSkin + { + } +} diff --git a/osu.Game/Skinning/IBeatmapSkin.cs b/osu.Game/Skinning/IBeatmapSkin.cs new file mode 100644 index 0000000000..77c34b8ad7 --- /dev/null +++ b/osu.Game/Skinning/IBeatmapSkin.cs @@ -0,0 +1,9 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +namespace osu.Game.Skinning +{ + public interface IBeatmapSkin : ISkin + { + } +} diff --git a/osu.Game/Skinning/LegacyBeatmapSkin.cs b/osu.Game/Skinning/LegacyBeatmapSkin.cs index d647bc4a2d..d53349dd11 100644 --- a/osu.Game/Skinning/LegacyBeatmapSkin.cs +++ b/osu.Game/Skinning/LegacyBeatmapSkin.cs @@ -11,7 +11,7 @@ using osu.Game.Rulesets.Objects.Legacy; namespace osu.Game.Skinning { - public class LegacyBeatmapSkin : LegacySkin + public class LegacyBeatmapSkin : LegacySkin, IBeatmapSkin { protected override bool AllowManiaSkin => false; protected override bool UseCustomSampleBanks => true; diff --git a/osu.Game/Tests/Beatmaps/HitObjectSampleTest.cs b/osu.Game/Tests/Beatmaps/HitObjectSampleTest.cs index ab4fb38657..db080d889f 100644 --- a/osu.Game/Tests/Beatmaps/HitObjectSampleTest.cs +++ b/osu.Game/Tests/Beatmaps/HitObjectSampleTest.cs @@ -188,7 +188,7 @@ namespace osu.Game.Tests.Beatmaps this.resourceStore = resourceStore; } - protected override ISkin GetSkin() => new LegacyBeatmapSkin(skinBeatmapInfo, resourceStore, AudioManager); + protected override IBeatmapSkin GetSkin() => new LegacyBeatmapSkin(skinBeatmapInfo, resourceStore, AudioManager); } } } From 1b81415a16e82131bb170f5473202112a82182ab Mon Sep 17 00:00:00 2001 From: Craftplacer Date: Sat, 29 Aug 2020 10:50:25 +0200 Subject: [PATCH 355/434] Correct comment --- osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs b/osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs index 996d495e17..1e3755c186 100644 --- a/osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs +++ b/osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs @@ -116,7 +116,7 @@ namespace osu.Game.Tests.Gameplay AddAssert("sample playback rate matches mod rates", () => sample.Channel.AggregateFrequency.Value == expectedRate); } - // TODO: adding IBeatmapSkin changes are as minimal as possible, but this shouldn't exist or should be reworked to work with LegacyBeatmapSkin + // TODO: adding IBeatmapSkin to keep changes as minimal as possible, but this shouldn't exist or should be reworked to inherit LegacyBeatmapSkin private class TestSkin : LegacySkin, IBeatmapSkin { public TestSkin(string resourceName, AudioManager audioManager) From 08329aa382d7afd64e9ce5afe30a94d55d0557ec Mon Sep 17 00:00:00 2001 From: Craftplacer Date: Sat, 29 Aug 2020 11:05:10 +0200 Subject: [PATCH 356/434] Remove comment again --- osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs b/osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs index 1e3755c186..bc9528beb6 100644 --- a/osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs +++ b/osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs @@ -116,7 +116,6 @@ namespace osu.Game.Tests.Gameplay AddAssert("sample playback rate matches mod rates", () => sample.Channel.AggregateFrequency.Value == expectedRate); } - // TODO: adding IBeatmapSkin to keep changes as minimal as possible, but this shouldn't exist or should be reworked to inherit LegacyBeatmapSkin private class TestSkin : LegacySkin, IBeatmapSkin { public TestSkin(string resourceName, AudioManager audioManager) From 82acb3506cbc36a0546ff77fc76c20d8854bb2ed Mon Sep 17 00:00:00 2001 From: Craftplacer Date: Sat, 29 Aug 2020 11:07:28 +0200 Subject: [PATCH 357/434] Add and change xmldocs --- osu.Game/Beatmaps/IWorkingBeatmap.cs | 2 +- osu.Game/Skinning/IBeatmapSkin.cs | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/IWorkingBeatmap.cs b/osu.Game/Beatmaps/IWorkingBeatmap.cs index dac9389822..aac41725a9 100644 --- a/osu.Game/Beatmaps/IWorkingBeatmap.cs +++ b/osu.Game/Beatmaps/IWorkingBeatmap.cs @@ -42,7 +42,7 @@ namespace osu.Game.Beatmaps Storyboard Storyboard { get; } /// - /// Retrieves the which this provides. + /// Retrieves the which this provides. /// IBeatmapSkin Skin { get; } diff --git a/osu.Game/Skinning/IBeatmapSkin.cs b/osu.Game/Skinning/IBeatmapSkin.cs index 77c34b8ad7..91caaed557 100644 --- a/osu.Game/Skinning/IBeatmapSkin.cs +++ b/osu.Game/Skinning/IBeatmapSkin.cs @@ -3,6 +3,9 @@ namespace osu.Game.Skinning { + /// + /// Marker interface for skins that originate from beatmaps. + /// public interface IBeatmapSkin : ISkin { } From 658a1d159f03df2a55339c5eab7e11085c75ac43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 29 Aug 2020 11:45:59 +0200 Subject: [PATCH 358/434] Add legacy flag value for mirror mod --- osu.Game/Beatmaps/Legacy/LegacyMods.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Beatmaps/Legacy/LegacyMods.cs b/osu.Game/Beatmaps/Legacy/LegacyMods.cs index 583e950e49..0e517ea3df 100644 --- a/osu.Game/Beatmaps/Legacy/LegacyMods.cs +++ b/osu.Game/Beatmaps/Legacy/LegacyMods.cs @@ -38,5 +38,6 @@ namespace osu.Game.Beatmaps.Legacy Key1 = 1 << 26, Key3 = 1 << 27, Key2 = 1 << 28, + Mirror = 1 << 30, } } From 58742afd99f131baeb23f0bc85b8161da1559847 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 29 Aug 2020 11:47:31 +0200 Subject: [PATCH 359/434] Add failing test case --- osu.Game.Rulesets.Mania.Tests/ManiaLegacyModConversionTest.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game.Rulesets.Mania.Tests/ManiaLegacyModConversionTest.cs b/osu.Game.Rulesets.Mania.Tests/ManiaLegacyModConversionTest.cs index 957743c5f1..b22687a0a7 100644 --- a/osu.Game.Rulesets.Mania.Tests/ManiaLegacyModConversionTest.cs +++ b/osu.Game.Rulesets.Mania.Tests/ManiaLegacyModConversionTest.cs @@ -23,6 +23,7 @@ namespace osu.Game.Rulesets.Mania.Tests [TestCase(LegacyMods.Perfect | LegacyMods.SuddenDeath, new[] { typeof(ManiaModPerfect) })] [TestCase(LegacyMods.Perfect | LegacyMods.SuddenDeath | LegacyMods.DoubleTime, new[] { typeof(ManiaModDoubleTime), typeof(ManiaModPerfect) })] [TestCase(LegacyMods.Random | LegacyMods.SuddenDeath, new[] { typeof(ManiaModRandom), typeof(ManiaModSuddenDeath) })] + [TestCase(LegacyMods.Flashlight | LegacyMods.Mirror, new[] { typeof(ManiaModFlashlight), typeof(ManiaModMirror) })] public new void Test(LegacyMods legacyMods, Type[] expectedMods) => base.Test(legacyMods, expectedMods); protected override Ruleset CreateRuleset() => new ManiaRuleset(); From da82556f6b647dff1d17b384c4061d80665b0393 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 29 Aug 2020 11:49:17 +0200 Subject: [PATCH 360/434] Add two-way legacy conversions for mirror mod --- osu.Game.Rulesets.Mania/ManiaRuleset.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/osu.Game.Rulesets.Mania/ManiaRuleset.cs b/osu.Game.Rulesets.Mania/ManiaRuleset.cs index f7098faa5d..37b34d1721 100644 --- a/osu.Game.Rulesets.Mania/ManiaRuleset.cs +++ b/osu.Game.Rulesets.Mania/ManiaRuleset.cs @@ -126,6 +126,9 @@ namespace osu.Game.Rulesets.Mania if (mods.HasFlag(LegacyMods.Random)) yield return new ManiaModRandom(); + + if (mods.HasFlag(LegacyMods.Mirror)) + yield return new ManiaModMirror(); } public override LegacyMods ConvertToLegacyMods(Mod[] mods) @@ -175,6 +178,10 @@ namespace osu.Game.Rulesets.Mania case ManiaModFadeIn _: value |= LegacyMods.FadeIn; break; + + case ManiaModMirror _: + value |= LegacyMods.Mirror; + break; } } From 9ce9ba3a0d1906448611749a0dc391dcf3944e3d Mon Sep 17 00:00:00 2001 From: Craftplacer Date: Sat, 29 Aug 2020 13:50:29 +0200 Subject: [PATCH 361/434] Update TestSceneSkinFallbacks.cs --- .../TestSceneSkinFallbacks.cs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSkinFallbacks.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSkinFallbacks.cs index c3c19de17c..0fe8949360 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSkinFallbacks.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSkinFallbacks.cs @@ -34,7 +34,7 @@ namespace osu.Game.Rulesets.Osu.Tests public TestSceneSkinFallbacks() { testUserSkin = new TestSource("user"); - testBeatmapSkin = new TestSource("beatmap"); + testBeatmapSkin = new BeatmapTestSource(); } [Test] @@ -85,7 +85,7 @@ namespace osu.Game.Rulesets.Osu.Tests public CustomSkinWorkingBeatmap(IBeatmap beatmap, Storyboard storyboard, IFrameBasedClock frameBasedClock, AudioManager audio, ISkinSource skin) : base(beatmap, storyboard, frameBasedClock, audio) { - if (!(skinSource is IBeatmapSkin)) + if (!(skin is IBeatmapSkin)) throw new ArgumentException("The provided skin source must be of type IBeatmapSkin."); skinSource = skin; @@ -115,6 +115,14 @@ namespace osu.Game.Rulesets.Osu.Tests } } + public class BeatmapTestSource : TestSource, IBeatmapSkin + { + public BeatmapTestSource() + : base("beatmap") + { + } + } + public class TestSource : ISkinSource { private readonly string identifier; From 43e91877a71c3451f4b9617212dbd0c38f7bdb2f Mon Sep 17 00:00:00 2001 From: Craftplacer Date: Sat, 29 Aug 2020 14:47:26 +0200 Subject: [PATCH 362/434] Scope and limit parameter to IBeatmapSkin --- .../TestSceneSkinFallbacks.cs | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSkinFallbacks.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSkinFallbacks.cs index 0fe8949360..64da80a88e 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSkinFallbacks.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSkinFallbacks.cs @@ -29,7 +29,7 @@ namespace osu.Game.Rulesets.Osu.Tests public class TestSceneSkinFallbacks : TestSceneOsuPlayer { private readonly TestSource testUserSkin; - private readonly TestSource testBeatmapSkin; + private readonly BeatmapTestSource testBeatmapSkin; public TestSceneSkinFallbacks() { @@ -80,18 +80,15 @@ namespace osu.Game.Rulesets.Osu.Tests public class CustomSkinWorkingBeatmap : ClockBackedTestWorkingBeatmap { - private readonly ISkinSource skinSource; + private readonly IBeatmapSkin skin; - public CustomSkinWorkingBeatmap(IBeatmap beatmap, Storyboard storyboard, IFrameBasedClock frameBasedClock, AudioManager audio, ISkinSource skin) + public CustomSkinWorkingBeatmap(IBeatmap beatmap, Storyboard storyboard, IFrameBasedClock frameBasedClock, AudioManager audio, IBeatmapSkin skin) : base(beatmap, storyboard, frameBasedClock, audio) { - if (!(skin is IBeatmapSkin)) - throw new ArgumentException("The provided skin source must be of type IBeatmapSkin."); - - skinSource = skin; + this.skin = skin; } - protected override IBeatmapSkin GetSkin() => (IBeatmapSkin)skinSource; + protected override IBeatmapSkin GetSkin() => skin; } public class SkinProvidingPlayer : TestPlayer @@ -115,7 +112,7 @@ namespace osu.Game.Rulesets.Osu.Tests } } - public class BeatmapTestSource : TestSource, IBeatmapSkin + private class BeatmapTestSource : TestSource, IBeatmapSkin { public BeatmapTestSource() : base("beatmap") From 69fae0f4122ad64b9c25bdc83ccd4e9cb00c34ba Mon Sep 17 00:00:00 2001 From: Joehu Date: Sat, 29 Aug 2020 09:30:56 -0700 Subject: [PATCH 363/434] Add failing replay download button test --- .../Visual/Ranking/TestSceneResultsScreen.cs | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/osu.Game.Tests/Visual/Ranking/TestSceneResultsScreen.cs b/osu.Game.Tests/Visual/Ranking/TestSceneResultsScreen.cs index 74808bc2f5..a86fa05129 100644 --- a/osu.Game.Tests/Visual/Ranking/TestSceneResultsScreen.cs +++ b/osu.Game.Tests/Visual/Ranking/TestSceneResultsScreen.cs @@ -13,6 +13,7 @@ using osu.Framework.Screens; using osu.Framework.Testing; using osu.Framework.Utils; using osu.Game.Beatmaps; +using osu.Game.Graphics.UserInterface; using osu.Game.Online.API; using osu.Game.Rulesets.Osu; using osu.Game.Scoring; @@ -212,6 +213,25 @@ namespace osu.Game.Tests.Visual.Ranking AddAssert("expanded panel still on screen", () => this.ChildrenOfType().Single(p => p.State == PanelState.Expanded).ScreenSpaceDrawQuad.TopLeft.X > 0); } + [Test] + public void TestDownloadButtonInitallyDisabled() + { + TestResultsScreen screen = null; + + AddStep("load results", () => Child = new TestResultsContainer(screen = createResultsScreen())); + + AddAssert("download button is disabled", () => !screen.ChildrenOfType().First().Enabled.Value); + + AddStep("click contracted panel", () => + { + var contractedPanel = this.ChildrenOfType().First(p => p.State == PanelState.Contracted && p.ScreenSpaceDrawQuad.TopLeft.X > screen.ScreenSpaceDrawQuad.TopLeft.X); + InputManager.MoveMouseTo(contractedPanel); + InputManager.Click(MouseButton.Left); + }); + + AddAssert("download button is enabled", () => screen.ChildrenOfType().First().Enabled.Value); + } + private class TestResultsContainer : Container { [Cached(typeof(Player))] @@ -255,6 +275,7 @@ namespace osu.Game.Tests.Visual.Ranking { var score = new TestScoreInfo(new OsuRuleset().RulesetInfo); score.TotalScore += 10 - i; + score.Hash = $"test{i}"; scores.Add(score); } From 0a643fd5e5a4f8b6e5b92f0a27ffe6995fc26b2c Mon Sep 17 00:00:00 2001 From: Joehu Date: Sat, 29 Aug 2020 09:33:01 -0700 Subject: [PATCH 364/434] Fix replay download button always being disabled when initial score's replay is unavailable --- .../Screens/Ranking/ReplayDownloadButton.cs | 40 ++++++++++++------- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/osu.Game/Screens/Ranking/ReplayDownloadButton.cs b/osu.Game/Screens/Ranking/ReplayDownloadButton.cs index d0142e57fe..b76842f405 100644 --- a/osu.Game/Screens/Ranking/ReplayDownloadButton.cs +++ b/osu.Game/Screens/Ranking/ReplayDownloadButton.cs @@ -74,23 +74,33 @@ namespace osu.Game.Screens.Ranking { button.State.Value = state.NewValue; - switch (replayAvailability) - { - case ReplayAvailability.Local: - button.TooltipText = @"watch replay"; - break; - - case ReplayAvailability.Online: - button.TooltipText = @"download replay"; - break; - - default: - button.TooltipText = @"replay unavailable"; - break; - } + updateTooltip(); }, true); - button.Enabled.Value = replayAvailability != ReplayAvailability.NotAvailable; + Model.BindValueChanged(_ => + { + button.Enabled.Value = replayAvailability != ReplayAvailability.NotAvailable; + + updateTooltip(); + }, true); + } + + private void updateTooltip() + { + switch (replayAvailability) + { + case ReplayAvailability.Local: + button.TooltipText = @"watch replay"; + break; + + case ReplayAvailability.Online: + button.TooltipText = @"download replay"; + break; + + default: + button.TooltipText = @"replay unavailable"; + break; + } } private enum ReplayAvailability From 5949a281fc54e94b34843ec5d91d8b819b1851b4 Mon Sep 17 00:00:00 2001 From: Lucas A Date: Thu, 27 Aug 2020 19:29:18 +0200 Subject: [PATCH 365/434] Make Introduce bindable property OverlayActivationMode in OsuScreen --- osu.Game/OsuGame.cs | 5 ++++- osu.Game/Screens/IOsuScreen.cs | 4 ++-- osu.Game/Screens/OsuScreen.cs | 6 +++++- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 053eb01dcd..6a390942b7 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -972,9 +972,12 @@ namespace osu.Game break; } + if (current is IOsuScreen currentOsuScreen) + OverlayActivationMode.UnbindFrom(currentOsuScreen.OverlayActivationMode); + if (newScreen is IOsuScreen newOsuScreen) { - OverlayActivationMode.Value = newOsuScreen.InitialOverlayActivationMode; + OverlayActivationMode.BindTo(newOsuScreen.OverlayActivationMode); MusicController.AllowRateAdjustments = newOsuScreen.AllowRateAdjustments; diff --git a/osu.Game/Screens/IOsuScreen.cs b/osu.Game/Screens/IOsuScreen.cs index 761f842c22..c9dce310af 100644 --- a/osu.Game/Screens/IOsuScreen.cs +++ b/osu.Game/Screens/IOsuScreen.cs @@ -39,9 +39,9 @@ namespace osu.Game.Screens bool HideOverlaysOnEnter { get; } /// - /// Whether overlays should be able to be opened once this screen is entered or resumed. + /// Whether overlays should be able to be opened when this screen is current. /// - OverlayActivation InitialOverlayActivationMode { get; } + public Bindable OverlayActivationMode { get; } /// /// The amount of parallax to be applied while this screen is displayed. diff --git a/osu.Game/Screens/OsuScreen.cs b/osu.Game/Screens/OsuScreen.cs index 872a1cd39a..c687c34ce9 100644 --- a/osu.Game/Screens/OsuScreen.cs +++ b/osu.Game/Screens/OsuScreen.cs @@ -44,10 +44,12 @@ namespace osu.Game.Screens public virtual bool HideOverlaysOnEnter => false; /// - /// Whether overlays should be able to be opened once this screen is entered or resumed. + /// The initial initial overlay activation mode to use when this screen is entered for the first time. /// public virtual OverlayActivation InitialOverlayActivationMode => OverlayActivation.All; + public Bindable OverlayActivationMode { get; } + public virtual bool CursorVisible => true; protected new OsuGameBase Game => base.Game as OsuGameBase; @@ -138,6 +140,8 @@ namespace osu.Game.Screens { Anchor = Anchor.Centre; Origin = Anchor.Centre; + + OverlayActivationMode = new Bindable(InitialOverlayActivationMode); } [BackgroundDependencyLoader(true)] From ad223bc460ea0d1a6a4d07a86d17cfa3ad0b5b38 Mon Sep 17 00:00:00 2001 From: Lucas A Date: Thu, 27 Aug 2020 20:07:24 +0200 Subject: [PATCH 366/434] Make game bindable immutable. --- osu.Game.Tests/Visual/Menus/TestSceneToolbar.cs | 7 ++++++- osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs | 2 +- osu.Game/OsuGame.cs | 2 +- osu.Game/Overlays/Toolbar/Toolbar.cs | 2 +- osu.Game/Screens/Menu/ButtonSystem.cs | 3 --- 5 files changed, 9 insertions(+), 7 deletions(-) diff --git a/osu.Game.Tests/Visual/Menus/TestSceneToolbar.cs b/osu.Game.Tests/Visual/Menus/TestSceneToolbar.cs index f819ae4682..841860accb 100644 --- a/osu.Game.Tests/Visual/Menus/TestSceneToolbar.cs +++ b/osu.Game.Tests/Visual/Menus/TestSceneToolbar.cs @@ -91,7 +91,12 @@ namespace osu.Game.Tests.Visual.Menus public class TestToolbar : Toolbar { - public new Bindable OverlayActivationMode => base.OverlayActivationMode; + public TestToolbar() + { + base.OverlayActivationMode.BindTo(OverlayActivationMode); + } + + public new Bindable OverlayActivationMode { get; } = new Bindable(OverlayActivation.All); } } } diff --git a/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs b/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs index 93ac69bdbf..751ccc8f15 100644 --- a/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs +++ b/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs @@ -35,7 +35,7 @@ namespace osu.Game.Graphics.Containers [Resolved] private PreviewTrackManager previewTrackManager { get; set; } - protected readonly Bindable OverlayActivationMode = new Bindable(OverlayActivation.All); + protected readonly IBindable OverlayActivationMode = new Bindable(OverlayActivation.All); [BackgroundDependencyLoader(true)] private void load(AudioManager audio) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 6a390942b7..e6d96df927 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -88,7 +88,7 @@ namespace osu.Game private IdleTracker idleTracker; - public readonly Bindable OverlayActivationMode = new Bindable(); + public readonly IBindable OverlayActivationMode = new Bindable(); protected OsuScreenStack ScreenStack; diff --git a/osu.Game/Overlays/Toolbar/Toolbar.cs b/osu.Game/Overlays/Toolbar/Toolbar.cs index 3bf9e85428..393e349bd0 100644 --- a/osu.Game/Overlays/Toolbar/Toolbar.cs +++ b/osu.Game/Overlays/Toolbar/Toolbar.cs @@ -28,7 +28,7 @@ namespace osu.Game.Overlays.Toolbar private const double transition_time = 500; - protected readonly Bindable OverlayActivationMode = new Bindable(OverlayActivation.All); + protected readonly IBindable OverlayActivationMode = new Bindable(OverlayActivation.All); // Toolbar components like RulesetSelector should receive keyboard input events even when the toolbar is hidden. public override bool PropagateNonPositionalInputSubTree => true; diff --git a/osu.Game/Screens/Menu/ButtonSystem.cs b/osu.Game/Screens/Menu/ButtonSystem.cs index 5ba7a8ddc3..4becdd58cd 100644 --- a/osu.Game/Screens/Menu/ButtonSystem.cs +++ b/osu.Game/Screens/Menu/ButtonSystem.cs @@ -270,9 +270,6 @@ namespace osu.Game.Screens.Menu ButtonSystemState lastState = state; state = value; - if (game != null) - game.OverlayActivationMode.Value = state == ButtonSystemState.Exit ? OverlayActivation.Disabled : OverlayActivation.All; - updateLogoState(lastState); Logger.Log($"{nameof(ButtonSystem)}'s state changed from {lastState} to {state}"); From 8de7744b52e98d0e42a9b88ec08b10ac1a5c2f6f Mon Sep 17 00:00:00 2001 From: Lucas A Date: Fri, 28 Aug 2020 09:55:14 +0200 Subject: [PATCH 367/434] Add back disabling of overlays on exiting game. --- osu.Game/Screens/Menu/MainMenu.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Screens/Menu/MainMenu.cs b/osu.Game/Screens/Menu/MainMenu.cs index 57252d557e..859184834b 100644 --- a/osu.Game/Screens/Menu/MainMenu.cs +++ b/osu.Game/Screens/Menu/MainMenu.cs @@ -280,6 +280,7 @@ namespace osu.Game.Screens.Menu } buttons.State = ButtonSystemState.Exit; + OverlayActivationMode.Value = OverlayActivation.Disabled; songTicker.Hide(); From 03b7c8b88969ae337ac52bcddd56c0c5d034f111 Mon Sep 17 00:00:00 2001 From: Lucas A Date: Sat, 29 Aug 2020 19:39:50 +0200 Subject: [PATCH 368/434] Remove unneeded access modifier. --- osu.Game/Screens/IOsuScreen.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/IOsuScreen.cs b/osu.Game/Screens/IOsuScreen.cs index c9dce310af..ead8e4bc22 100644 --- a/osu.Game/Screens/IOsuScreen.cs +++ b/osu.Game/Screens/IOsuScreen.cs @@ -41,7 +41,7 @@ namespace osu.Game.Screens /// /// Whether overlays should be able to be opened when this screen is current. /// - public Bindable OverlayActivationMode { get; } + Bindable OverlayActivationMode { get; } /// /// The amount of parallax to be applied while this screen is displayed. From e0eece11b1cde8e12856b33c5050335605b8c3cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 29 Aug 2020 20:13:03 +0200 Subject: [PATCH 369/434] Fix typo in test name --- osu.Game.Tests/Visual/Ranking/TestSceneResultsScreen.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Ranking/TestSceneResultsScreen.cs b/osu.Game.Tests/Visual/Ranking/TestSceneResultsScreen.cs index a86fa05129..49fa581108 100644 --- a/osu.Game.Tests/Visual/Ranking/TestSceneResultsScreen.cs +++ b/osu.Game.Tests/Visual/Ranking/TestSceneResultsScreen.cs @@ -214,7 +214,7 @@ namespace osu.Game.Tests.Visual.Ranking } [Test] - public void TestDownloadButtonInitallyDisabled() + public void TestDownloadButtonInitiallyDisabled() { TestResultsScreen screen = null; From 13df0783fe091b3171cf37972df3aa5a62c0d267 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 29 Aug 2020 20:23:22 +0200 Subject: [PATCH 370/434] Use Single() instead of First() where applicable --- osu.Game.Tests/Visual/Ranking/TestSceneResultsScreen.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/Ranking/TestSceneResultsScreen.cs b/osu.Game.Tests/Visual/Ranking/TestSceneResultsScreen.cs index 49fa581108..03cb5fa3db 100644 --- a/osu.Game.Tests/Visual/Ranking/TestSceneResultsScreen.cs +++ b/osu.Game.Tests/Visual/Ranking/TestSceneResultsScreen.cs @@ -220,7 +220,7 @@ namespace osu.Game.Tests.Visual.Ranking AddStep("load results", () => Child = new TestResultsContainer(screen = createResultsScreen())); - AddAssert("download button is disabled", () => !screen.ChildrenOfType().First().Enabled.Value); + AddAssert("download button is disabled", () => !screen.ChildrenOfType().Single().Enabled.Value); AddStep("click contracted panel", () => { @@ -229,7 +229,7 @@ namespace osu.Game.Tests.Visual.Ranking InputManager.Click(MouseButton.Left); }); - AddAssert("download button is enabled", () => screen.ChildrenOfType().First().Enabled.Value); + AddAssert("download button is enabled", () => screen.ChildrenOfType().Single().Enabled.Value); } private class TestResultsContainer : Container From d22768a98cba3c9d312ba2408536905371840668 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 29 Aug 2020 23:20:59 +0200 Subject: [PATCH 371/434] Add scale specification to spinner scene for visibility --- osu.Game.Rulesets.Osu.Tests/TestSceneSpinner.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSpinner.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSpinner.cs index 47b3926ceb..94d1cb8864 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSpinner.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSpinner.cs @@ -9,6 +9,7 @@ using osu.Game.Beatmaps.ControlPoints; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Osu.Objects.Drawables; +using osuTK; namespace osu.Game.Rulesets.Osu.Tests { @@ -62,7 +63,8 @@ namespace osu.Game.Rulesets.Osu.Tests drawableSpinner = new TestDrawableSpinner(spinner, auto) { Anchor = Anchor.Centre, - Depth = depthIndex++ + Depth = depthIndex++, + Scale = new Vector2(0.75f) }; foreach (var mod in SelectedMods.Value.OfType()) From c9723e541a464c84b8e3e5c27e94af4f0c3fd32d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 29 Aug 2020 23:21:19 +0200 Subject: [PATCH 372/434] Add metrics skin resources for old style spinner --- .../metrics-skin/spinner-background@2x.png | Bin 0 -> 14515 bytes .../metrics-skin/spinner-circle@2x.png | Bin 0 -> 6561 bytes .../Resources/metrics-skin/spinner-metre@2x.png | Bin 0 -> 14516 bytes 3 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 osu.Game.Rulesets.Osu.Tests/Resources/metrics-skin/spinner-background@2x.png create mode 100644 osu.Game.Rulesets.Osu.Tests/Resources/metrics-skin/spinner-circle@2x.png create mode 100644 osu.Game.Rulesets.Osu.Tests/Resources/metrics-skin/spinner-metre@2x.png diff --git a/osu.Game.Rulesets.Osu.Tests/Resources/metrics-skin/spinner-background@2x.png b/osu.Game.Rulesets.Osu.Tests/Resources/metrics-skin/spinner-background@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..4f50f638c5de06d711fc7d09a3a4ee13618cd59e GIT binary patch literal 14515 zcmeHNO)G>^6n=(b#_-liY7o6PHa3!?BrnZ0Grp3Pln{j-@{v*u+4u)Seu8Xl*pOm; z6rvQ$EbPd_Mxi)&ym$V7L$?+uU=Wd(Lz2dzRbVf`+Hi1HcG}{2hQ>)Qk~# zrVQ0L^+z&f4m1b-G6G-M4V|wtW{riqCxGlc^>bi#-6t1ali}8Y>(O1DpIcjAr!JWY z`x`oEZlCY>4U~EhteVUD)7h#1p{D5F$;S4OL(M7D_0jU90B@C|nG~>iHlwyCK|~OdfT^9pPhdQo`P&4{QZSASqk2k3_0NLiL%>(1 zdI7}$^nOZtpB`5+FPR$i_ml!#WwMmsqIiqWMJ&;OLvBKDLT;kAIlmi$EhYbp;`HoJ zo9P1Wis-|8N#D2}cJ4(K)Z>z#XtK;n^k7z)_Dw!W^Jpj#6xtFXD6}aE3T+93g6YG? s0<$YQg$)J9N5)6n0;Ja(3XG2_6dx^P)VSK|ID1mw4+q-(n~nX8-{y?j8UO$Q literal 0 HcmV?d00001 diff --git a/osu.Game.Rulesets.Osu.Tests/Resources/metrics-skin/spinner-circle@2x.png b/osu.Game.Rulesets.Osu.Tests/Resources/metrics-skin/spinner-circle@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..daf28e09cbe6bbb7fc531b4773e4d381054e65cf GIT binary patch literal 6561 zcmai32UHVT+fF7SA(Vt}D24z5L;(S5(u{(VP&J|=H6lf-EK(xPWJO>BAp{XriekhK zA|N(Ez*$+Ast8g90fUW>QKT#g{NuN-{@*$OIsZ8`XYPIPo#!p{&O7%$^V@zWTX7Ku z5f}_6PNmq;U@$oQ+bN8KB+SRgozMm4V{dB%U16||-rX*rp(`ewa`Y4oCMx~ygu^Zu z;2|M8lIpk@{Z4qZEJieI!*CV`lh>u%>~>)c&5k5w5d3OeK7I6TE_G{<4&@Hf(gF{8 z+1*iCl``y;lEI$PA>6YCiSSs}-9Sp(fjuHc0#zgO5JiP9(j2=#j?bJ>kuwR}Vl+f+ zPp`AF3%s8n^@tpGu)A=+B?B$tHdJ^i;6u^hiJY}ZU8hEtydHb)FkfPlsGR@jm^4D# zU;T?Zff~hTphr;|9f@@;T|SX67ETn%(OnkjOJ~NrQ!E@@xwBME_9Q~EgMX8pWiso>+|vI%AKi(t;yB7r)h~bu&@)%POqUi#Dj#GO_c4U>isULqw%=qre8x5^3y?l_yTw zoNz$P!RA@lbtq~Uz_3ucN>y7#E9^k_HGLsd*<~4lmuSxkMb<}nj1;2>8t4w+bKI~> zVp(kReE9t?1Q^5YLq;EkkYXG7`RD>vyqqcct1v^d2I2bN`&1jOdsoUnlW+~ePWok` zZm$s3Vc_-Wozn8eS#0JYcoZBT5gqzCf_Ml#lyD8$DJF4${Ky%VaO~uZF`Abp=!iV* zE`qRmDt0~_+{D}qx`>uYeF02>4$RC0B~_Zu$Yp8$&RIN(pofi(r3@`FjmNAEvEh8Eq3(=g#b??+#;bIm7Tk zdcZTP@j=@=N!Cb4VQTuJOk{|Np=gd6v$>}n~?9F{6k-%Chg1cRx0m3sNVRp z9oAjcbX+A|T(8@QQduqTI>UR6O7)UgLL&w^jhOvCqql+ern3s-66yumcmzH`pPSH+ z_Mq^iAw%xzo7OR>Dc)+^0vU&aO%nJj85G6+$y;e|i-&VHo)+fLn#T->YMFI3Etx43 z27nlO0_~UvJjU;_djt^Z8}5K^#B@Hu(*pb98&33`8+zo+QiOn<#%)8tId6R}QI!fl zz4!$7o25k<^4Wa}TFY%>RjUD>sE=wfxziFjWuGaC#Ad2-fex6N5Qgl8T=CVM`4E6k6k zCpWW$P9nn1SS=7BEs9Y?Qsh{ffS3Udn7?@zj*jN*bc6a&tH8?FcJOkD!s$GSry)B2Y=Ynj=$uw+M z7=IP?NLMjBj0+cGB|@>3ktO8Z-6*Ud@S&W4DCtV3r$ZAzC%0sSXAlQb-9GhY#iU-Oc&V{5&W|gRceo;$Lxk&mdtRI=%ojgD_`;8A_tVh{&U2 zyag092lI6pN~l#S!V-W!Dn`9D&dd>$MEIT@(^stNYP0SkXk<$_6!RhOmsLjR z+4lkxK+LGC3E7K4umv{K&xEQ^E`*}3rizyph#L%wATj=#bx-58Q0B?irsP>H`wN4k z{8st{XYutuevPqmT+b+sireRr9^g(@Xe7|R+;Q}f`BidbFoV(_7}js^#w&z#8oQd* z2GwPc?e0G)#+FNJk&2hU!1XD7^_Pj_gJ}X~W&OCf^){Y%x^Ov^ADal8z^?E!_FD%Z zOVo710-YF2@UKev>CuZW)rH_4B*BFI2A7o$o(090?sKt&uuhe#M{VBK;wIfEcUX|3 zUS^ap8M@s?kj5hTE=$#1k%G$$SN{r{Q!h_C2RSd;lY7*J{ObbL`&v6S2r)h7_O6%!gh}lY^}gPn zNgo{4o?_TZliV|LmQO6V@=BAL@csHyZuC`!&8M>!7C_#7JmcSJh<%vA# zv6RJ?yK-gWiCfu62>3N{aAX(9ts)P6R6t&|w2)IIaFAecxuzLw#+s1zz;b#2@9c_(7rB`Xbfqb4J1buY*3m~g(!%@on;{@=G7TaW^?)>eEp z*#kvZ8VKiFTT);pR;{WT^Db96!ka>~Xs9MgQ=VMgpJkKF6?V`N+>@qE0ZV5|&3!v= z6_cf~sKhLjF7-ffarj4~Amo)Mdmi$C=;LUD*CS1KQZ|T<58uyO9DwN+fpZU>h~9dT zM%TJ(!q5=rPw5!-z~!x$yoYrd(y?n}D%4tsr?G(@0P@){v+7!-UT#kzw+F$q6^}@= zK3G;%=q2*Ahz517xuT)JF{EpX6W51_y4|{>ACdAiS!DQuR73kq;Yi<=A~veeOs<@+l(-(Z(Mn%U7>a!2Dj8j^DL#2J4^ zUEta&Inqy+OSiUF6q62>_7XgznFa4ws5C#j*+1TULTJJkZ=voDtV)&61I#<*fFoz? z5x4ESJIGca>Zr8$cGJy%UQc4-_}L+7R20j_I%nc3PfcoB;gh&i^6<|p15{4XO~I(g zK4$#$C=Pc>tKMW&9FBBN^yQ=(m8NrEU2p#Y#y4|Xje7ski7Z_+vVW}=$Ho2J;zS9; zxAb4}3Zd2MYKIY|LxHIGAQ4I=Nhr8|Zb$lW1gpI|9he2uG5Z!nrRq zCBQq%fHkM&0HsTJD;XPO`9o}3kwV&gon7SF>3!^U(r=_@E?dpBs~PiASCx!CwV9-4RvQ;12{#ywVsj_n&5i6uwvq;R zb4qd^#cYx!rqp0LGKIqp<{PJom^1KwwQ?Mp+}*&*iZFmW0liyVcGs&3UI&=qD^CP9 z?QjL5$b|ft`sM zHaYr_+At=C1E*1$_1!D>w0r--{fzp7K&e{i$lUg@j89s~Asvz={-%E6yT*4P`@K0O zxwlfr#o3R)V?o}m2mQC*1}FZz|2g0XcB|-5gz?)y4DI>}hWcs#+RwRG-x2=xWS85I z07kq1Xs*-$QOsD6xvcqB2>;%ULUTc3>TBCENcxp&BDK41>$X^|WDz zME!Wa)y+Sj@4=rLkT?#Zd`}GO_s5>H$7`SV8b8(Em)}5EDvbF zBe0>S)818@72shGO;bTWXf|STl^KP>n$+B*M-DSCC=z*bp1Y`J4m``68CY%0LJqh6 z!qC|caW?4BmmJv7F`LUSN86f1;P1cJR&z;Wu!k*ms-`FIZu}uB8{d{&ahKHm+Wl5OxsKInw;oCjDn;ULuRb1>rmP5^jA~Hl z={<}#vna!`dvz)vlA1>j-omg!v#TvedEDXH>Y^bIj5_kJ4k`u>_l6V)F^`2x>()7j z+6~CjLw&ofO5SWga~*n9ep!58rpboByH`6Bh}2a-7~Yv4W3I{mlD_?vGNmWc{jeXy zWfzNku=Nk{BX2$8GO5`|n1N;m-1;ifXEJ*aW>TX}3M?MkAI0cB4p48htywyA80wH_ z4#vWBA?5cLzw7rTMn$u^0}sowV+V>cq{2Pl77ix=Svd5*O>;~L^SCKgJKCT^jf+h1 zd~)4Onqqd&0rudHw=cD4mm;7c`O+&7=Tf<^Q0_y}(r=`O_P!{QtQAM%q>KTIp-}9U z$326GVbulkg;p+Wy0SNf>U!2xsT&{L>(1F)YO?b*B%P;nxoOVB=YxUMZ3EDv$K|yb zKFISyQZek*w|wKbf8(9$hr?kEM4TH+=~|KC_@nrQu`3jFzJy1j)K2pxGBriiTM7{5ncM7 zRRU)!-I=J5xME20z}IBU5X|-vV^~wfM)|_<3)) z3DJ=ljspJ)zDW(*L0G?wrr(Hjru})?zd^glSm|z(E?ru$En$n6fjeswiSk(k)Jk;E zxGm3*q;OOt6FbKw&oH?v5hhi=4O_HS?eC7to?Z=2OF~2IYS%=QBv$b--laRA8hf($&N)+!9{jE~)?NNhw?F+{oC{6-c5AH5S+_9hzvm>V z3sO(bt;E<#fnaRBcm)^Qaqhr`gbi&9{vbXcdF@%mYr8Vm-OG5wQ}O?}e558u{m?`j z-g$6j$@o}l5>g3tqJGyEwt&g6eJ|F<|^l-%kSW6YPVG^@poQBJ7mA4 z*8R~T^CHmpyj^6^Biueive_n5y5MOt?V!i#UwOM_Ux*mRW5xj!H(@Qe^r1xsHw4!U zGOL5mJ=~{*3?^E39J1O-?L2{jWw|llbE%%ftK(%Q*73r z?0!Uxq-hqY+i~Dw^o>~in$#~z-Z+1kD`G&NRD4)F#^$tYqLyCnmq>4(co@7?f#5{k z8m(|i)C1LdA0Kq}2T@i}+=*BYGQLE)GcDA(k8k{qJUg|!8ozAt+)rQT+7IHbFRAq( zj?UTszc{)CwgXHT)p$bR<@f-?TeE5e%8oK`wgXBRcynUn%- zf{nkup>ybX>X-XM1CorP2s|-uI|ci!G<#m)|H$k(@rvn1Nk;!S@h-|fz#AqvR=iQB z)Bv6bBY;ObDew~i12k_^Z$1LRBSPPGR3 zt{1<$_*hP!7u;W8xF9Ccte`Q%b#6E#ybRU9k_$fHiRrFD2u~VuLo^@J*_w%mIjrkU zHC7XA3HC8eaL)kt6}4<6Knn1J-?ty*z*S{8X}@J@f#$3xW*bQ2OVCyI%1VplC0?Q| z5FtVjV9xNzh$2!|Q*$m{^^l_82>6Qi34F!;WzadsxIqb-0mmXoIYQ62@Er%c6j>(q zGfQglb?jI1<>18~`D)ZUv% U!O2zVX9|qE*U6@05B=Bw0VYd*8vpn&Wa)oHgy>;=0`AK-hts z0}&;PqoOHpc;DH#+pbEUxAuGAw(tA4-aXIrzP~?fBf|s!+Ll@Xek&0l1w0Z~&wE_r zy03dr#kpn%2jb#^ugln2L3~XzF|i1E8}#MCR<=prbT3&${q84Eu+bY?Zgal?CaidD zY~}X(_P8FVFTZ>8*|QmWwK|?MZh zX6R2Yni(wxfWv8ro`4JX`D4^e>ZKrodP%($7*H?&f?n3|1m}RJ zE+s9Sv)L8Xd^#um3`mCYcj!;4TjT)N1 z&jru)%Y22s!_)CrId$nPpSSEZ^%J$DbkXThRX%yi3+<#ZJp@Gw3*?MV3MvJKw1frf pBlVH`Sj+&aKq`<5q=IJP-%q8CgOLB?u=&}m*|7SD Date: Sat, 29 Aug 2020 23:29:29 +0200 Subject: [PATCH 373/434] Change structure of old style spinner to be closer to stable --- .../Skinning/LegacyOldStyleSpinner.cs | 85 +++++++++++-------- 1 file changed, 51 insertions(+), 34 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Skinning/LegacyOldStyleSpinner.cs b/osu.Game.Rulesets.Osu/Skinning/LegacyOldStyleSpinner.cs index 81a0df5ea5..e157842fd1 100644 --- a/osu.Game.Rulesets.Osu/Skinning/LegacyOldStyleSpinner.cs +++ b/osu.Game.Rulesets.Osu/Skinning/LegacyOldStyleSpinner.cs @@ -22,11 +22,11 @@ namespace osu.Game.Rulesets.Osu.Skinning { private DrawableSpinner drawableSpinner; private Sprite disc; + private Sprite metreSprite; private Container metre; - private const float background_y_offset = 20; - private const float sprite_scale = 1 / 1.6f; + private const float final_metre_height = 692 * sprite_scale; [BackgroundDependencyLoader] private void load(ISkinSource source, DrawableHitObject drawableObject) @@ -35,50 +35,58 @@ namespace osu.Game.Rulesets.Osu.Skinning RelativeSizeAxes = Axes.Both; - InternalChildren = new Drawable[] + InternalChild = new Container { - new Sprite + // the old-style spinner relied heavily on absolute screen-space coordinate values. + // wrap everything in a container simulating absolute coords to preserve alignment + // as there are skins that depend on it. + Width = 640, + Height = 480, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Children = new Drawable[] { - Anchor = Anchor.BottomCentre, - Origin = Anchor.BottomCentre, - Texture = source.GetTexture("spinner-background"), - Y = background_y_offset, - Scale = new Vector2(sprite_scale) - }, - disc = new Sprite - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Texture = source.GetTexture("spinner-circle"), - Scale = new Vector2(sprite_scale) - }, - metre = new Container - { - Anchor = Anchor.BottomCentre, - Origin = Anchor.BottomCentre, - Y = background_y_offset, - Masking = true, - Child = new Sprite + new Sprite { - Texture = source.GetTexture("spinner-metre"), - Anchor = Anchor.BottomCentre, - Origin = Anchor.BottomCentre, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Texture = source.GetTexture("spinner-background"), + Scale = new Vector2(sprite_scale) }, - Scale = new Vector2(0.625f) + disc = new Sprite + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Texture = source.GetTexture("spinner-circle"), + Scale = new Vector2(sprite_scale) + }, + metre = new Container + { + AutoSizeAxes = Axes.Both, + // this anchor makes no sense, but that's what stable uses. + Anchor = Anchor.TopLeft, + Origin = Anchor.TopLeft, + // adjustment for stable (metre has additional offset) + Margin = new MarginPadding { Top = 20 }, + Masking = true, + Child = metreSprite = new Sprite + { + Texture = source.GetTexture("spinner-metre"), + Anchor = Anchor.TopLeft, + Origin = Anchor.TopLeft, + Scale = new Vector2(0.625f) + } + } } }; } - private Vector2 metreFinalSize; - protected override void LoadComplete() { base.LoadComplete(); this.FadeOut(); drawableSpinner.State.BindValueChanged(updateStateTransforms, true); - - metreFinalSize = metre.Size = metre.Child.Size; } private void updateStateTransforms(ValueChangedEvent state) @@ -93,7 +101,16 @@ namespace osu.Game.Rulesets.Osu.Skinning { base.Update(); disc.Rotation = drawableSpinner.RotationTracker.Rotation; - metre.Height = getMetreHeight(drawableSpinner.Progress); + + // careful: need to call this exactly once for all calculations in a frame + // as the function has a random factor in it + var metreHeight = getMetreHeight(drawableSpinner.Progress); + + // hack to make the metre blink up from below than down from above. + // move down the container to be able to apply masking for the metre, + // and then move the sprite back up the same amount to keep its position absolute. + metre.Y = final_metre_height - metreHeight; + metreSprite.Y = -metre.Y; } private const int total_bars = 10; @@ -108,7 +125,7 @@ namespace osu.Game.Rulesets.Osu.Skinning if (RNG.NextBool(((int)progress % 10) / 10f)) barCount++; - return (float)barCount / total_bars * metreFinalSize.Y; + return (float)barCount / total_bars * final_metre_height; } } } From 8151aa6ed8b761f4b51ceb7345c0c9bb855d7ad1 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 31 Aug 2020 13:31:55 +0900 Subject: [PATCH 374/434] Remove unused method --- osu.Game.Rulesets.Mania.Tests/TestSceneOutOfOrderHits.cs | 7 ------- 1 file changed, 7 deletions(-) diff --git a/osu.Game.Rulesets.Mania.Tests/TestSceneOutOfOrderHits.cs b/osu.Game.Rulesets.Mania.Tests/TestSceneOutOfOrderHits.cs index ed187e65bf..ab840e1c46 100644 --- a/osu.Game.Rulesets.Mania.Tests/TestSceneOutOfOrderHits.cs +++ b/osu.Game.Rulesets.Mania.Tests/TestSceneOutOfOrderHits.cs @@ -1,7 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System; using System.Collections.Generic; using System.Linq; using NUnit.Framework; @@ -60,12 +59,6 @@ namespace osu.Game.Rulesets.Mania.Tests () => judgementResults.Single(r => r.HitObject == hitObject).Type == result); } - private void addJudgementAssert(string name, Func hitObject, HitResult result) - { - AddAssert($"{name} judgement is {result}", - () => judgementResults.Single(r => r.HitObject == hitObject()).Type == result); - } - private void addJudgementOffsetAssert(ManiaHitObject hitObject, double offset) { AddAssert($"({hitObject.GetType().ReadableName()} @ {hitObject.StartTime}) judged at {offset}", From acbeb5406f320d5749e2301f3b471b14eb85b62c Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 31 Aug 2020 13:33:41 +0900 Subject: [PATCH 375/434] Add/improve xmldoc --- .../Objects/Drawables/DrawableManiaHitObject.cs | 4 ++++ .../Objects/Drawables/DrawableOsuHitObject.cs | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs index 0594d1e143..e16413bce7 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs @@ -36,6 +36,10 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables } } + /// + /// Whether this can be hit, given a time value. + /// If non-null, judgements will be ignored (resulting in a shake) whilst the function returns false. + /// public Func CheckHittable; protected DrawableManiaHitObject(ManiaHitObject hitObject) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs index 8308c0c576..2946331bc6 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs @@ -22,7 +22,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables protected override float SamplePlaybackPosition => HitObject.X / OsuPlayfield.BASE_SIZE.X; /// - /// Whether this can be hit. + /// Whether this can be hit, given a time value. /// If non-null, judgements will be ignored (resulting in a shake) whilst the function returns false. /// public Func CheckHittable; From abdb99192397e21964706822c9d9fa8948a54c8f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 31 Aug 2020 14:15:47 +0900 Subject: [PATCH 376/434] Hide misses from timing distribution graph --- .../TestSceneHitEventTimingDistributionGraph.cs | 12 ++++++++++++ .../Statistics/HitEventTimingDistributionGraph.cs | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Ranking/TestSceneHitEventTimingDistributionGraph.cs b/osu.Game.Tests/Visual/Ranking/TestSceneHitEventTimingDistributionGraph.cs index 7ca1fc842f..144f8da2fa 100644 --- a/osu.Game.Tests/Visual/Ranking/TestSceneHitEventTimingDistributionGraph.cs +++ b/osu.Game.Tests/Visual/Ranking/TestSceneHitEventTimingDistributionGraph.cs @@ -35,6 +35,18 @@ namespace osu.Game.Tests.Visual.Ranking createTest(new List()); } + [Test] + public void TestMissesDontShow() + { + createTest(Enumerable.Range(0, 100).Select(i => + { + if (i % 2 == 0) + return new HitEvent(0, HitResult.Perfect, new HitCircle(), new HitCircle(), null); + + return new HitEvent(30, HitResult.Miss, new HitCircle(), new HitCircle(), null); + }).ToList()); + } + private void createTest(List events) => AddStep("create test", () => { Children = new Drawable[] diff --git a/osu.Game/Screens/Ranking/Statistics/HitEventTimingDistributionGraph.cs b/osu.Game/Screens/Ranking/Statistics/HitEventTimingDistributionGraph.cs index 527da429ed..45fdc3ff33 100644 --- a/osu.Game/Screens/Ranking/Statistics/HitEventTimingDistributionGraph.cs +++ b/osu.Game/Screens/Ranking/Statistics/HitEventTimingDistributionGraph.cs @@ -48,7 +48,7 @@ namespace osu.Game.Screens.Ranking.Statistics /// The s to display the timing distribution of. public HitEventTimingDistributionGraph(IReadOnlyList hitEvents) { - this.hitEvents = hitEvents.Where(e => !(e.HitObject.HitWindows is HitWindows.EmptyHitWindows)).ToList(); + this.hitEvents = hitEvents.Where(e => !(e.HitObject.HitWindows is HitWindows.EmptyHitWindows) && e.Result != HitResult.Miss).ToList(); } [BackgroundDependencyLoader] From c3bfce6ccff2bd908a80e47614b1329d1f585e00 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 31 Aug 2020 15:03:41 +0900 Subject: [PATCH 377/434] Add star rating to beatmap wedge --- osu.Game/Screens/Select/BeatmapInfoWedge.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/osu.Game/Screens/Select/BeatmapInfoWedge.cs b/osu.Game/Screens/Select/BeatmapInfoWedge.cs index 27ce9e82dd..cb3a347af4 100644 --- a/osu.Game/Screens/Select/BeatmapInfoWedge.cs +++ b/osu.Game/Screens/Select/BeatmapInfoWedge.cs @@ -27,6 +27,7 @@ using osu.Framework.Logging; using osu.Game.Rulesets; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.UI; +using osu.Game.Screens.Ranking.Expanded; namespace osu.Game.Screens.Select { @@ -224,8 +225,15 @@ namespace osu.Game.Screens.Select AutoSizeAxes = Axes.Both, Children = new Drawable[] { + new StarRatingDisplay(beatmapInfo) + { + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight, + }, StatusPill = new BeatmapSetOnlineStatusPill { + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight, TextSize = 11, TextPadding = new MarginPadding { Horizontal = 8, Vertical = 2 }, Status = beatmapInfo.Status, From 4736845318acac3c4e4da894500389a933bc8c22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Mon, 31 Aug 2020 10:56:06 +0200 Subject: [PATCH 378/434] Add spacing between star rating and beatmap status --- osu.Game/Screens/Select/BeatmapInfoWedge.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Screens/Select/BeatmapInfoWedge.cs b/osu.Game/Screens/Select/BeatmapInfoWedge.cs index cb3a347af4..518ad33529 100644 --- a/osu.Game/Screens/Select/BeatmapInfoWedge.cs +++ b/osu.Game/Screens/Select/BeatmapInfoWedge.cs @@ -229,6 +229,7 @@ namespace osu.Game.Screens.Select { Anchor = Anchor.CentreRight, Origin = Anchor.CentreRight, + Margin = new MarginPadding { Bottom = 5 } }, StatusPill = new BeatmapSetOnlineStatusPill { From bee01bdd38cf13bfeddac343c68ad315daef570f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 31 Aug 2020 18:01:16 +0900 Subject: [PATCH 379/434] Fix first scroll wheel in editor incorrectly advancing twice --- osu.Game/Screens/Edit/Editor.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index d92f3922c3..e178459d5c 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -284,7 +284,7 @@ namespace osu.Game.Screens.Edit // this is a special case to handle the "pivot" scenario. // if we are precise scrolling in one direction then change our mind and scroll backwards, // the existing accumulation should be applied in the inverse direction to maintain responsiveness. - if (Math.Sign(scrollAccumulation) != scrollDirection) + if (scrollAccumulation != 0 && Math.Sign(scrollAccumulation) != scrollDirection) scrollAccumulation = scrollDirection * (precision - Math.Abs(scrollAccumulation)); scrollAccumulation += scrollComponent * (e.IsPrecise ? 0.1 : 1); From 7d273d631be6491d3ad6ae769770469ba0cb9214 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Mon, 31 Aug 2020 11:05:42 +0200 Subject: [PATCH 380/434] Do not show star difficulty on wedge if zero --- osu.Game/Screens/Select/BeatmapInfoWedge.cs | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/osu.Game/Screens/Select/BeatmapInfoWedge.cs b/osu.Game/Screens/Select/BeatmapInfoWedge.cs index 518ad33529..2b2c40411d 100644 --- a/osu.Game/Screens/Select/BeatmapInfoWedge.cs +++ b/osu.Game/Screens/Select/BeatmapInfoWedge.cs @@ -223,14 +223,13 @@ namespace osu.Game.Screens.Select Direction = FillDirection.Vertical, Padding = new MarginPadding { Top = 14, Right = shear_width / 2 }, AutoSizeAxes = Axes.Both, - Children = new Drawable[] + Children = new[] { - new StarRatingDisplay(beatmapInfo) + createStarRatingDisplay(beatmapInfo).With(display => { - Anchor = Anchor.CentreRight, - Origin = Anchor.CentreRight, - Margin = new MarginPadding { Bottom = 5 } - }, + display.Anchor = Anchor.CentreRight; + display.Origin = Anchor.CentreRight; + }), StatusPill = new BeatmapSetOnlineStatusPill { Anchor = Anchor.CentreRight, @@ -291,6 +290,13 @@ namespace osu.Game.Screens.Select StatusPill.Hide(); } + private static Drawable createStarRatingDisplay(BeatmapInfo beatmapInfo) => beatmapInfo.StarDifficulty > 0 + ? new StarRatingDisplay(beatmapInfo) + { + Margin = new MarginPadding { Bottom = 5 } + } + : Empty(); + private void setMetadata(string source) { ArtistLabel.Text = artistBinding.Value; From 8b7446c43f1a53bbf83804486289ee6e42c5ec8e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 31 Aug 2020 18:13:51 +0900 Subject: [PATCH 381/434] Fix RollingCounter not updating initial value if changed before loaded --- osu.Game/Graphics/UserInterface/RollingCounter.cs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/RollingCounter.cs b/osu.Game/Graphics/UserInterface/RollingCounter.cs index 6763198213..ceb388600e 100644 --- a/osu.Game/Graphics/UserInterface/RollingCounter.cs +++ b/osu.Game/Graphics/UserInterface/RollingCounter.cs @@ -65,12 +65,6 @@ namespace osu.Game.Graphics.UserInterface protected RollingCounter() { AutoSizeAxes = Axes.Both; - - Current.ValueChanged += val => - { - if (IsLoaded) - TransformCount(DisplayedCount, val.NewValue); - }; } [BackgroundDependencyLoader] @@ -81,6 +75,13 @@ namespace osu.Game.Graphics.UserInterface Child = displayedCountSpriteText; } + protected override void LoadComplete() + { + base.LoadComplete(); + + Current.BindValueChanged(val => TransformCount(DisplayedCount, val.NewValue), true); + } + /// /// Sets count value, bypassing rollover animation. /// From a171d0e292be37a8c85d1f5e40b933f9d07b7619 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 31 Aug 2020 18:14:22 +0900 Subject: [PATCH 382/434] Remove unused methods and classes --- .../UserInterface/PercentageCounter.cs | 5 --- .../Graphics/UserInterface/RollingCounter.cs | 2 -- .../Graphics/UserInterface/ScoreCounter.cs | 5 --- .../UserInterface/SimpleComboCounter.cs | 5 --- .../Screens/Play/HUD/ComboResultCounter.cs | 32 ------------------- .../Expanded/Statistics/AccuracyStatistic.cs | 3 -- .../Expanded/Statistics/CounterStatistic.cs | 3 -- .../Ranking/Expanded/TotalScoreCounter.cs | 3 -- 8 files changed, 58 deletions(-) delete mode 100644 osu.Game/Screens/Play/HUD/ComboResultCounter.cs diff --git a/osu.Game/Graphics/UserInterface/PercentageCounter.cs b/osu.Game/Graphics/UserInterface/PercentageCounter.cs index 3ea9c1053c..1ccf7798e5 100644 --- a/osu.Game/Graphics/UserInterface/PercentageCounter.cs +++ b/osu.Game/Graphics/UserInterface/PercentageCounter.cs @@ -40,10 +40,5 @@ namespace osu.Game.Graphics.UserInterface protected override OsuSpriteText CreateSpriteText() => base.CreateSpriteText().With(s => s.Font = s.Font.With(size: 20f, fixedWidth: true)); - - public override void Increment(double amount) - { - Current.Value += amount; - } } } diff --git a/osu.Game/Graphics/UserInterface/RollingCounter.cs b/osu.Game/Graphics/UserInterface/RollingCounter.cs index ceb388600e..ece1b8e22c 100644 --- a/osu.Game/Graphics/UserInterface/RollingCounter.cs +++ b/osu.Game/Graphics/UserInterface/RollingCounter.cs @@ -57,8 +57,6 @@ namespace osu.Game.Graphics.UserInterface } } - public abstract void Increment(T amount); - /// /// Skeleton of a numeric counter which value rolls over time. /// diff --git a/osu.Game/Graphics/UserInterface/ScoreCounter.cs b/osu.Game/Graphics/UserInterface/ScoreCounter.cs index faabe69f87..73bbe5f03e 100644 --- a/osu.Game/Graphics/UserInterface/ScoreCounter.cs +++ b/osu.Game/Graphics/UserInterface/ScoreCounter.cs @@ -51,10 +51,5 @@ namespace osu.Game.Graphics.UserInterface protected override OsuSpriteText CreateSpriteText() => base.CreateSpriteText().With(s => s.Font = s.Font.With(fixedWidth: true)); - - public override void Increment(double amount) - { - Current.Value += amount; - } } } diff --git a/osu.Game/Graphics/UserInterface/SimpleComboCounter.cs b/osu.Game/Graphics/UserInterface/SimpleComboCounter.cs index aac0166774..c9790aed46 100644 --- a/osu.Game/Graphics/UserInterface/SimpleComboCounter.cs +++ b/osu.Game/Graphics/UserInterface/SimpleComboCounter.cs @@ -33,11 +33,6 @@ namespace osu.Game.Graphics.UserInterface return Math.Abs(currentValue - newValue) * RollingDuration * 100.0f; } - public override void Increment(int amount) - { - Current.Value += amount; - } - protected override OsuSpriteText CreateSpriteText() => base.CreateSpriteText().With(s => s.Font = s.Font.With(size: 20f)); } diff --git a/osu.Game/Screens/Play/HUD/ComboResultCounter.cs b/osu.Game/Screens/Play/HUD/ComboResultCounter.cs deleted file mode 100644 index 7ae8bc0ddf..0000000000 --- a/osu.Game/Screens/Play/HUD/ComboResultCounter.cs +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using osu.Framework.Graphics; -using osu.Game.Graphics.UserInterface; - -namespace osu.Game.Screens.Play.HUD -{ - /// - /// Used to display combo with a roll-up animation in results screen. - /// - public class ComboResultCounter : RollingCounter - { - protected override double RollingDuration => 500; - protected override Easing RollingEasing => Easing.Out; - - protected override double GetProportionalDuration(long currentValue, long newValue) - { - return currentValue > newValue ? currentValue - newValue : newValue - currentValue; - } - - protected override string FormatCount(long count) - { - return $@"{count}x"; - } - - public override void Increment(long amount) - { - Current.Value += amount; - } - } -} diff --git a/osu.Game/Screens/Ranking/Expanded/Statistics/AccuracyStatistic.cs b/osu.Game/Screens/Ranking/Expanded/Statistics/AccuracyStatistic.cs index 6933456e7e..288a107874 100644 --- a/osu.Game/Screens/Ranking/Expanded/Statistics/AccuracyStatistic.cs +++ b/osu.Game/Screens/Ranking/Expanded/Statistics/AccuracyStatistic.cs @@ -46,9 +46,6 @@ namespace osu.Game.Screens.Ranking.Expanded.Statistics protected override string FormatCount(double count) => count.FormatAccuracy(); - public override void Increment(double amount) - => Current.Value += amount; - protected override OsuSpriteText CreateSpriteText() => base.CreateSpriteText().With(s => { s.Font = OsuFont.Torus.With(size: 20, fixedWidth: true); diff --git a/osu.Game/Screens/Ranking/Expanded/Statistics/CounterStatistic.cs b/osu.Game/Screens/Ranking/Expanded/Statistics/CounterStatistic.cs index 043a560d12..e820831809 100644 --- a/osu.Game/Screens/Ranking/Expanded/Statistics/CounterStatistic.cs +++ b/osu.Game/Screens/Ranking/Expanded/Statistics/CounterStatistic.cs @@ -49,9 +49,6 @@ namespace osu.Game.Screens.Ranking.Expanded.Statistics s.Font = OsuFont.Torus.With(size: 20, fixedWidth: true); s.Spacing = new Vector2(-2, 0); }); - - public override void Increment(int amount) - => Current.Value += amount; } } } diff --git a/osu.Game/Screens/Ranking/Expanded/TotalScoreCounter.cs b/osu.Game/Screens/Ranking/Expanded/TotalScoreCounter.cs index 7f6fd1eabe..65082d3fae 100644 --- a/osu.Game/Screens/Ranking/Expanded/TotalScoreCounter.cs +++ b/osu.Game/Screens/Ranking/Expanded/TotalScoreCounter.cs @@ -36,8 +36,5 @@ namespace osu.Game.Screens.Ranking.Expanded s.Font = OsuFont.Torus.With(size: 60, weight: FontWeight.Light, fixedWidth: true); s.Spacing = new Vector2(-5, 0); }); - - public override void Increment(long amount) - => Current.Value += amount; } } From dd093f44d8826af623ed5232e6a38d8f39b0ce20 Mon Sep 17 00:00:00 2001 From: Lucas A Date: Mon, 31 Aug 2020 11:16:13 +0200 Subject: [PATCH 383/434] Cast base immutable bindable to mutable for testing purposes and make InitialOverlayActivationMode property protected --- osu.Game.Tests/Visual/Menus/TestSceneToolbar.cs | 7 +------ osu.Game/Screens/OsuScreen.cs | 2 +- osu.Game/Screens/Play/Player.cs | 2 +- osu.Game/Screens/StartupScreen.cs | 2 +- 4 files changed, 4 insertions(+), 9 deletions(-) diff --git a/osu.Game.Tests/Visual/Menus/TestSceneToolbar.cs b/osu.Game.Tests/Visual/Menus/TestSceneToolbar.cs index 841860accb..2a4486812c 100644 --- a/osu.Game.Tests/Visual/Menus/TestSceneToolbar.cs +++ b/osu.Game.Tests/Visual/Menus/TestSceneToolbar.cs @@ -91,12 +91,7 @@ namespace osu.Game.Tests.Visual.Menus public class TestToolbar : Toolbar { - public TestToolbar() - { - base.OverlayActivationMode.BindTo(OverlayActivationMode); - } - - public new Bindable OverlayActivationMode { get; } = new Bindable(OverlayActivation.All); + public new Bindable OverlayActivationMode => base.OverlayActivationMode as Bindable; } } } diff --git a/osu.Game/Screens/OsuScreen.cs b/osu.Game/Screens/OsuScreen.cs index c687c34ce9..c10deaf1e5 100644 --- a/osu.Game/Screens/OsuScreen.cs +++ b/osu.Game/Screens/OsuScreen.cs @@ -46,7 +46,7 @@ namespace osu.Game.Screens /// /// The initial initial overlay activation mode to use when this screen is entered for the first time. /// - public virtual OverlayActivation InitialOverlayActivationMode => OverlayActivation.All; + protected virtual OverlayActivation InitialOverlayActivationMode => OverlayActivation.All; public Bindable OverlayActivationMode { get; } diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 541275cf55..0a5158c6dc 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -50,7 +50,7 @@ namespace osu.Game.Screens.Play public override bool HideOverlaysOnEnter => true; - public override OverlayActivation InitialOverlayActivationMode => OverlayActivation.UserTriggered; + protected override OverlayActivation InitialOverlayActivationMode => OverlayActivation.UserTriggered; /// /// Whether gameplay should pause when the game window focus is lost. diff --git a/osu.Game/Screens/StartupScreen.cs b/osu.Game/Screens/StartupScreen.cs index c3e36c8e9d..e5e134fd39 100644 --- a/osu.Game/Screens/StartupScreen.cs +++ b/osu.Game/Screens/StartupScreen.cs @@ -18,6 +18,6 @@ namespace osu.Game.Screens public override bool AllowRateAdjustments => false; - public override OverlayActivation InitialOverlayActivationMode => OverlayActivation.Disabled; + protected override OverlayActivation InitialOverlayActivationMode => OverlayActivation.Disabled; } } From d419fe4dbf5f54edddd67cfb4507150ae43c2f8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Mon, 31 Aug 2020 12:02:02 +0200 Subject: [PATCH 384/434] Remove note shaking mention that doesn't apply in mania --- .../Objects/Drawables/DrawableManiaHitObject.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs index e16413bce7..08c41b0d75 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs @@ -38,7 +38,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables /// /// Whether this can be hit, given a time value. - /// If non-null, judgements will be ignored (resulting in a shake) whilst the function returns false. + /// If non-null, judgements will be ignored whilst the function returns false. /// public Func CheckHittable; From ed74c39b5587e2084dd9fe957aef6d4e9f422644 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 31 Aug 2020 19:54:22 +0900 Subject: [PATCH 385/434] Move UserTopScoreContainer into base leaderboard --- .../SongSelect/TestSceneBeatmapLeaderboard.cs | 61 ++++++------- .../TestSceneUserTopScoreContainer.cs | 91 +++++++++---------- .../API/Requests/Responses/APILegacyScores.cs | 9 ++ osu.Game/Online/Leaderboards/Leaderboard.cs | 21 ++++- .../Leaderboards/UserTopScoreContainer.cs | 26 ++---- .../Match/Components/MatchLeaderboard.cs | 2 + .../Select/Leaderboards/BeatmapLeaderboard.cs | 30 ++---- 7 files changed, 114 insertions(+), 126 deletions(-) rename osu.Game/{Screens/Select => Online}/Leaderboards/UserTopScoreContainer.cs (77%) diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapLeaderboard.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapLeaderboard.cs index 48b718c04d..67cd720260 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapLeaderboard.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapLeaderboard.cs @@ -5,9 +5,9 @@ using System; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Game.Beatmaps; -using osu.Game.Online.API.Requests.Responses; using osu.Game.Online.Leaderboards; using osu.Game.Overlays; +using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Osu.Mods; using osu.Game.Scoring; using osu.Game.Screens.Select.Leaderboards; @@ -53,53 +53,46 @@ namespace osu.Game.Tests.Visual.SongSelect private void showPersonalBestWithNullPosition() { - leaderboard.TopScore = new APILegacyUserTopScoreInfo + leaderboard.TopScore = new ScoreInfo { - Position = null, - Score = new APILegacyScoreInfo + Rank = ScoreRank.XH, + Accuracy = 1, + MaxCombo = 244, + TotalScore = 1707827, + Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock() }, + User = new User { - Rank = ScoreRank.XH, - Accuracy = 1, - MaxCombo = 244, - TotalScore = 1707827, - Mods = new[] { new OsuModHidden().Acronym, new OsuModHardRock().Acronym, }, - User = new User + Id = 6602580, + Username = @"waaiiru", + Country = new Country { - Id = 6602580, - Username = @"waaiiru", - Country = new Country - { - FullName = @"Spain", - FlagName = @"ES", - }, + FullName = @"Spain", + FlagName = @"ES", }, - } + }, }; } private void showPersonalBest() { - leaderboard.TopScore = new APILegacyUserTopScoreInfo + leaderboard.TopScore = new ScoreInfo { Position = 999, - Score = new APILegacyScoreInfo + Rank = ScoreRank.XH, + Accuracy = 1, + MaxCombo = 244, + TotalScore = 1707827, + Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), }, + User = new User { - Rank = ScoreRank.XH, - Accuracy = 1, - MaxCombo = 244, - TotalScore = 1707827, - Mods = new[] { new OsuModHidden().Acronym, new OsuModHardRock().Acronym, }, - User = new User + Id = 6602580, + Username = @"waaiiru", + Country = new Country { - Id = 6602580, - Username = @"waaiiru", - Country = new Country - { - FullName = @"Spain", - FlagName = @"ES", - }, + FullName = @"Spain", + FlagName = @"ES", }, - } + }, }; } diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneUserTopScoreContainer.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneUserTopScoreContainer.cs index 0598324110..b8b8792b9b 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestSceneUserTopScoreContainer.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestSceneUserTopScoreContainer.cs @@ -6,11 +6,11 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osuTK.Graphics; -using osu.Game.Online.API.Requests.Responses; +using osu.Game.Online.Leaderboards; using osu.Game.Overlays; +using osu.Game.Rulesets.Mods; using osu.Game.Scoring; using osu.Game.Rulesets.Osu.Mods; -using osu.Game.Screens.Select.Leaderboards; using osu.Game.Users; namespace osu.Game.Tests.Visual.SongSelect @@ -22,7 +22,7 @@ namespace osu.Game.Tests.Visual.SongSelect public TestSceneUserTopScoreContainer() { - UserTopScoreContainer topScoreContainer; + UserTopScoreContainer topScoreContainer; Add(dialogOverlay = new DialogOverlay { @@ -42,7 +42,7 @@ namespace osu.Game.Tests.Visual.SongSelect RelativeSizeAxes = Axes.Both, Colour = Color4.DarkGreen, }, - topScoreContainer = new UserTopScoreContainer + topScoreContainer = new UserTopScoreContainer(s => new LeaderboardScore(s, s.Position, false)) { Origin = Anchor.BottomCentre, Anchor = Anchor.BottomCentre, @@ -52,69 +52,60 @@ namespace osu.Game.Tests.Visual.SongSelect var scores = new[] { - new APILegacyUserTopScoreInfo + new ScoreInfo { Position = 999, - Score = new APILegacyScoreInfo + Rank = ScoreRank.XH, + Accuracy = 1, + MaxCombo = 244, + TotalScore = 1707827, + Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), }, + User = new User { - Rank = ScoreRank.XH, - Accuracy = 1, - MaxCombo = 244, - TotalScore = 1707827, - Mods = new[] { new OsuModHidden().Acronym, new OsuModHardRock().Acronym, }, - User = new User + Id = 6602580, + Username = @"waaiiru", + Country = new Country { - Id = 6602580, - Username = @"waaiiru", - Country = new Country - { - FullName = @"Spain", - FlagName = @"ES", - }, + FullName = @"Spain", + FlagName = @"ES", }, - } + }, }, - new APILegacyUserTopScoreInfo + new ScoreInfo { Position = 110000, - Score = new APILegacyScoreInfo + Rank = ScoreRank.X, + Accuracy = 1, + MaxCombo = 244, + TotalScore = 1707827, + User = new User { - Rank = ScoreRank.X, - Accuracy = 1, - MaxCombo = 244, - TotalScore = 1707827, - User = new User + Id = 4608074, + Username = @"Skycries", + Country = new Country { - Id = 4608074, - Username = @"Skycries", - Country = new Country - { - FullName = @"Brazil", - FlagName = @"BR", - }, + FullName = @"Brazil", + FlagName = @"BR", }, - } + }, }, - new APILegacyUserTopScoreInfo + new ScoreInfo { Position = 22333, - Score = new APILegacyScoreInfo + Rank = ScoreRank.S, + Accuracy = 1, + MaxCombo = 244, + TotalScore = 1707827, + User = new User { - Rank = ScoreRank.S, - Accuracy = 1, - MaxCombo = 244, - TotalScore = 1707827, - User = new User + Id = 1541390, + Username = @"Toukai", + Country = new Country { - Id = 1541390, - Username = @"Toukai", - Country = new Country - { - FullName = @"Canada", - FlagName = @"CA", - }, + FullName = @"Canada", + FlagName = @"CA", }, - } + }, } }; diff --git a/osu.Game/Online/API/Requests/Responses/APILegacyScores.cs b/osu.Game/Online/API/Requests/Responses/APILegacyScores.cs index 75be9171b0..009639c1dc 100644 --- a/osu.Game/Online/API/Requests/Responses/APILegacyScores.cs +++ b/osu.Game/Online/API/Requests/Responses/APILegacyScores.cs @@ -3,6 +3,8 @@ using System.Collections.Generic; using Newtonsoft.Json; +using osu.Game.Rulesets; +using osu.Game.Scoring; namespace osu.Game.Online.API.Requests.Responses { @@ -22,5 +24,12 @@ namespace osu.Game.Online.API.Requests.Responses [JsonProperty(@"score")] public APILegacyScoreInfo Score; + + public ScoreInfo CreateScoreInfo(RulesetStore rulesets) + { + var score = Score.CreateScoreInfo(rulesets); + score.Position = Position; + return score; + } } } diff --git a/osu.Game/Online/Leaderboards/Leaderboard.cs b/osu.Game/Online/Leaderboards/Leaderboard.cs index 800029ceb9..003d90d400 100644 --- a/osu.Game/Online/Leaderboards/Leaderboard.cs +++ b/osu.Game/Online/Leaderboards/Leaderboard.cs @@ -27,6 +27,7 @@ namespace osu.Game.Online.Leaderboards private readonly OsuScrollContainer scrollContainer; private readonly Container placeholderContainer; + private readonly UserTopScoreContainer topScoreContainer; private FillFlowContainer scrollFlow; @@ -87,6 +88,21 @@ namespace osu.Game.Online.Leaderboards } } + public TScoreInfo TopScore + { + get => topScoreContainer.Score.Value; + set + { + if (value == null) + topScoreContainer.Hide(); + else + { + topScoreContainer.Show(); + topScoreContainer.Score.Value = value; + } + } + } + protected virtual FillFlowContainer CreateScoreFlow() => new FillFlowContainer { @@ -198,8 +214,9 @@ namespace osu.Game.Online.Leaderboards { AutoSizeAxes = Axes.Y, RelativeSizeAxes = Axes.X, + Child = topScoreContainer = new UserTopScoreContainer(CreateDrawableTopScore) }, - } + }, }, }, }, @@ -367,5 +384,7 @@ namespace osu.Game.Online.Leaderboards } protected abstract LeaderboardScore CreateDrawableScore(TScoreInfo model, int index); + + protected abstract LeaderboardScore CreateDrawableTopScore(TScoreInfo model); } } diff --git a/osu.Game/Screens/Select/Leaderboards/UserTopScoreContainer.cs b/osu.Game/Online/Leaderboards/UserTopScoreContainer.cs similarity index 77% rename from osu.Game/Screens/Select/Leaderboards/UserTopScoreContainer.cs rename to osu.Game/Online/Leaderboards/UserTopScoreContainer.cs index 8e10734454..ffa7fa2c0b 100644 --- a/osu.Game/Screens/Select/Leaderboards/UserTopScoreContainer.cs +++ b/osu.Game/Online/Leaderboards/UserTopScoreContainer.cs @@ -9,31 +9,28 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; -using osu.Game.Online.API.Requests.Responses; -using osu.Game.Online.Leaderboards; using osu.Game.Rulesets; -using osu.Game.Scoring; using osuTK; -namespace osu.Game.Screens.Select.Leaderboards +namespace osu.Game.Online.Leaderboards { - public class UserTopScoreContainer : VisibilityContainer + public class UserTopScoreContainer : VisibilityContainer { private const int duration = 500; + public Bindable Score = new Bindable(); + private readonly Container scoreContainer; - - public Bindable Score = new Bindable(); - - public Action ScoreSelected; + private readonly Func createScoreDelegate; protected override bool StartHidden => true; [Resolved] private RulesetStore rulesets { get; set; } - public UserTopScoreContainer() + public UserTopScoreContainer(Func createScoreDelegate) { + this.createScoreDelegate = createScoreDelegate; RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; @@ -72,7 +69,7 @@ namespace osu.Game.Screens.Select.Leaderboards private CancellationTokenSource loadScoreCancellation; - private void onScoreChanged(ValueChangedEvent score) + private void onScoreChanged(ValueChangedEvent score) { var newScore = score.NewValue; @@ -82,12 +79,7 @@ namespace osu.Game.Screens.Select.Leaderboards if (newScore == null) return; - var scoreInfo = newScore.Score.CreateScoreInfo(rulesets); - - LoadComponentAsync(new LeaderboardScore(scoreInfo, newScore.Position, false) - { - Action = () => ScoreSelected?.Invoke(scoreInfo) - }, drawableScore => + LoadComponentAsync(createScoreDelegate(newScore), drawableScore => { scoreContainer.Child = drawableScore; drawableScore.FadeInFromZero(duration, Easing.OutQuint); diff --git a/osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs b/osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs index 1afbf5c32a..01137dad43 100644 --- a/osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs +++ b/osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs @@ -51,6 +51,8 @@ namespace osu.Game.Screens.Multi.Match.Components } protected override LeaderboardScore CreateDrawableScore(APIUserScoreAggregate model, int index) => new MatchLeaderboardScore(model, index); + + protected override LeaderboardScore CreateDrawableTopScore(APIUserScoreAggregate model) => new MatchLeaderboardScore(model, 0); } public enum MatchLeaderboardScope diff --git a/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs b/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs index 8e85eb4eb2..a78d8e3be0 100644 --- a/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs +++ b/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs @@ -9,7 +9,6 @@ using osu.Framework.Bindables; using osu.Game.Beatmaps; using osu.Game.Online.API; using osu.Game.Online.API.Requests; -using osu.Game.Online.API.Requests.Responses; using osu.Game.Online.Leaderboards; using osu.Game.Rulesets; using osu.Game.Rulesets.Mods; @@ -41,25 +40,8 @@ namespace osu.Game.Screens.Select.Leaderboards } } - public APILegacyUserTopScoreInfo TopScore - { - get => topScoreContainer.Score.Value; - set - { - if (value == null) - topScoreContainer.Hide(); - else - { - topScoreContainer.Show(); - topScoreContainer.Score.Value = value; - } - } - } - private bool filterMods; - private UserTopScoreContainer topScoreContainer; - private IBindable> itemRemoved; /// @@ -101,11 +83,6 @@ namespace osu.Game.Screens.Select.Leaderboards UpdateScores(); }; - Content.Add(topScoreContainer = new UserTopScoreContainer - { - ScoreSelected = s => ScoreSelected?.Invoke(s) - }); - itemRemoved = scoreManager.ItemRemoved.GetBoundCopy(); itemRemoved.BindValueChanged(onScoreRemoved); } @@ -183,7 +160,7 @@ namespace osu.Game.Screens.Select.Leaderboards req.Success += r => { scoresCallback?.Invoke(r.Scores.Select(s => s.CreateScoreInfo(rulesets))); - TopScore = r.UserScore; + TopScore = r.UserScore.CreateScoreInfo(rulesets); }; return req; @@ -193,5 +170,10 @@ namespace osu.Game.Screens.Select.Leaderboards { Action = () => ScoreSelected?.Invoke(model) }; + + protected override LeaderboardScore CreateDrawableTopScore(ScoreInfo model) => new LeaderboardScore(model, model.Position, false) + { + Action = () => ScoreSelected?.Invoke(model) + }; } } From d1ceb81797a8bd19b931f3816c26502673b0d8be Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 31 Aug 2020 19:54:41 +0900 Subject: [PATCH 386/434] Rename request --- ...GetRoomScoresRequest.cs => GetRoomLeaderboardRequest.cs} | 6 ++---- osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) rename osu.Game/Online/Multiplayer/{GetRoomScoresRequest.cs => GetRoomLeaderboardRequest.cs} (65%) diff --git a/osu.Game/Online/Multiplayer/GetRoomScoresRequest.cs b/osu.Game/Online/Multiplayer/GetRoomLeaderboardRequest.cs similarity index 65% rename from osu.Game/Online/Multiplayer/GetRoomScoresRequest.cs rename to osu.Game/Online/Multiplayer/GetRoomLeaderboardRequest.cs index bc913030dd..37c21457bc 100644 --- a/osu.Game/Online/Multiplayer/GetRoomScoresRequest.cs +++ b/osu.Game/Online/Multiplayer/GetRoomLeaderboardRequest.cs @@ -1,17 +1,15 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System.Collections.Generic; using osu.Game.Online.API; -using osu.Game.Online.API.Requests.Responses; namespace osu.Game.Online.Multiplayer { - public class GetRoomScoresRequest : APIRequest> + public class GetRoomLeaderboardRequest : APIRequest { private readonly int roomId; - public GetRoomScoresRequest(int roomId) + public GetRoomLeaderboardRequest(int roomId) { this.roomId = roomId; } diff --git a/osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs b/osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs index 01137dad43..56381dccb6 100644 --- a/osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs +++ b/osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs @@ -39,7 +39,7 @@ namespace osu.Game.Screens.Multi.Match.Components if (roomId.Value == null) return null; - var req = new GetRoomScoresRequest(roomId.Value ?? 0); + var req = new GetRoomLeaderboardRequest(roomId.Value ?? 0); req.Success += r => { From 77698ec31e8cae2550c2dac2d68bae51ab2805a6 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 31 Aug 2020 19:54:57 +0900 Subject: [PATCH 387/434] Add support for showing own top score in timeshift --- osu.Game/Online/Multiplayer/APILeaderboard.cs | 18 ++++++++++++++++++ .../Multi/Match/Components/MatchLeaderboard.cs | 6 ++---- 2 files changed, 20 insertions(+), 4 deletions(-) create mode 100644 osu.Game/Online/Multiplayer/APILeaderboard.cs diff --git a/osu.Game/Online/Multiplayer/APILeaderboard.cs b/osu.Game/Online/Multiplayer/APILeaderboard.cs new file mode 100644 index 0000000000..96fe7cefb0 --- /dev/null +++ b/osu.Game/Online/Multiplayer/APILeaderboard.cs @@ -0,0 +1,18 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Collections.Generic; +using Newtonsoft.Json; +using osu.Game.Online.API.Requests.Responses; + +namespace osu.Game.Online.Multiplayer +{ + public class APILeaderboard + { + [JsonProperty("leaderboard")] + public List Leaderboard; + + [JsonProperty("own_score")] + public APIUserScoreAggregate OwnScore; + } +} diff --git a/osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs b/osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs index 56381dccb6..847f3a7b55 100644 --- a/osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs +++ b/osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs @@ -14,8 +14,6 @@ namespace osu.Game.Screens.Multi.Match.Components { public class MatchLeaderboard : Leaderboard { - public Action> ScoresLoaded; - [Resolved(typeof(Room), nameof(Room.RoomID))] private Bindable roomId { get; set; } @@ -43,8 +41,8 @@ namespace osu.Game.Screens.Multi.Match.Components req.Success += r => { - scoresCallback?.Invoke(r); - ScoresLoaded?.Invoke(r); + scoresCallback?.Invoke(r.Leaderboard); + TopScore = r.OwnScore; }; return req; From 6ed191786f978e3b6bb943bc8e33633ac17ff80e Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 31 Aug 2020 20:01:59 +0900 Subject: [PATCH 388/434] Add support for position --- .../Online/API/Requests/Responses/APIUserScoreAggregate.cs | 4 ++++ osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/osu.Game/Online/API/Requests/Responses/APIUserScoreAggregate.cs b/osu.Game/Online/API/Requests/Responses/APIUserScoreAggregate.cs index 0bba6a93bd..bcc8721400 100644 --- a/osu.Game/Online/API/Requests/Responses/APIUserScoreAggregate.cs +++ b/osu.Game/Online/API/Requests/Responses/APIUserScoreAggregate.cs @@ -33,6 +33,9 @@ namespace osu.Game.Online.API.Requests.Responses [JsonProperty("user")] public User User { get; set; } + [JsonProperty("position")] + public int? Position { get; set; } + public ScoreInfo CreateScoreInfo() => new ScoreInfo { @@ -40,6 +43,7 @@ namespace osu.Game.Online.API.Requests.Responses PP = PP, TotalScore = TotalScore, User = User, + Position = Position }; } } diff --git a/osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs b/osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs index 847f3a7b55..7d5968202c 100644 --- a/osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs +++ b/osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs @@ -50,7 +50,7 @@ namespace osu.Game.Screens.Multi.Match.Components protected override LeaderboardScore CreateDrawableScore(APIUserScoreAggregate model, int index) => new MatchLeaderboardScore(model, index); - protected override LeaderboardScore CreateDrawableTopScore(APIUserScoreAggregate model) => new MatchLeaderboardScore(model, 0); + protected override LeaderboardScore CreateDrawableTopScore(APIUserScoreAggregate model) => new MatchLeaderboardScore(model, model.Position ?? 0); } public enum MatchLeaderboardScope From d22de26afb354e82769fd2ffdd3a587ae1a32f04 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 31 Aug 2020 20:08:36 +0900 Subject: [PATCH 389/434] Add whitespace --- osu.Game/Online/Leaderboards/UserTopScoreContainer.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Online/Leaderboards/UserTopScoreContainer.cs b/osu.Game/Online/Leaderboards/UserTopScoreContainer.cs index ffa7fa2c0b..ab4210251e 100644 --- a/osu.Game/Online/Leaderboards/UserTopScoreContainer.cs +++ b/osu.Game/Online/Leaderboards/UserTopScoreContainer.cs @@ -31,6 +31,7 @@ namespace osu.Game.Online.Leaderboards public UserTopScoreContainer(Func createScoreDelegate) { this.createScoreDelegate = createScoreDelegate; + RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; From 8cf26979fb11ec81199cf87378b20134a809d816 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 31 Aug 2020 20:16:28 +0900 Subject: [PATCH 390/434] Allow null user score --- osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs b/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs index a78d8e3be0..8ddae67dba 100644 --- a/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs +++ b/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs @@ -160,7 +160,7 @@ namespace osu.Game.Screens.Select.Leaderboards req.Success += r => { scoresCallback?.Invoke(r.Scores.Select(s => s.CreateScoreInfo(rulesets))); - TopScore = r.UserScore.CreateScoreInfo(rulesets); + TopScore = r.UserScore?.CreateScoreInfo(rulesets); }; return req; From 61d580b6ba9841793e81600d0c228ea7848bff3e Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 31 Aug 2020 20:17:23 +0900 Subject: [PATCH 391/434] Don't highlight top score --- osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs | 2 +- .../Screens/Multi/Match/Components/MatchLeaderboardScore.cs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs b/osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs index 7d5968202c..50afbb39fe 100644 --- a/osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs +++ b/osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs @@ -50,7 +50,7 @@ namespace osu.Game.Screens.Multi.Match.Components protected override LeaderboardScore CreateDrawableScore(APIUserScoreAggregate model, int index) => new MatchLeaderboardScore(model, index); - protected override LeaderboardScore CreateDrawableTopScore(APIUserScoreAggregate model) => new MatchLeaderboardScore(model, model.Position ?? 0); + protected override LeaderboardScore CreateDrawableTopScore(APIUserScoreAggregate model) => new MatchLeaderboardScore(model, model.Position ?? 0, false); } public enum MatchLeaderboardScope diff --git a/osu.Game/Screens/Multi/Match/Components/MatchLeaderboardScore.cs b/osu.Game/Screens/Multi/Match/Components/MatchLeaderboardScore.cs index 73a40d9579..c4e2b332b3 100644 --- a/osu.Game/Screens/Multi/Match/Components/MatchLeaderboardScore.cs +++ b/osu.Game/Screens/Multi/Match/Components/MatchLeaderboardScore.cs @@ -14,8 +14,8 @@ namespace osu.Game.Screens.Multi.Match.Components { private readonly APIUserScoreAggregate score; - public MatchLeaderboardScore(APIUserScoreAggregate score, int rank) - : base(score.CreateScoreInfo(), rank) + public MatchLeaderboardScore(APIUserScoreAggregate score, int rank, bool allowHighlight = true) + : base(score.CreateScoreInfo(), rank, allowHighlight) { this.score = score; } From 5e77e8cfcf74e642c2076773799ab355097fa22b Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 31 Aug 2020 20:21:57 +0900 Subject: [PATCH 392/434] Reduce min size of chat --- osu.Game/Screens/Multi/Match/MatchSubScreen.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Multi/Match/MatchSubScreen.cs b/osu.Game/Screens/Multi/Match/MatchSubScreen.cs index 7c2d5cf85d..0d2adeb27c 100644 --- a/osu.Game/Screens/Multi/Match/MatchSubScreen.cs +++ b/osu.Game/Screens/Multi/Match/MatchSubScreen.cs @@ -172,7 +172,7 @@ namespace osu.Game.Screens.Multi.Match new Dimension(GridSizeMode.AutoSize), new Dimension(), new Dimension(GridSizeMode.AutoSize), - new Dimension(GridSizeMode.Relative, size: 0.4f, minSize: 240), + new Dimension(GridSizeMode.Relative, size: 0.4f, minSize: 120), } }, null From 3b22b891d13e9d53d0266d234363dfd2362436c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Mon, 31 Aug 2020 14:28:45 +0200 Subject: [PATCH 393/434] Add failing test cases --- .../NonVisual/Ranking/UnstableRateTest.cs | 43 +++++++++++++++++++ .../Ranking/Statistics/SimpleStatisticItem.cs | 9 +++- 2 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 osu.Game.Tests/NonVisual/Ranking/UnstableRateTest.cs diff --git a/osu.Game.Tests/NonVisual/Ranking/UnstableRateTest.cs b/osu.Game.Tests/NonVisual/Ranking/UnstableRateTest.cs new file mode 100644 index 0000000000..bf4145754a --- /dev/null +++ b/osu.Game.Tests/NonVisual/Ranking/UnstableRateTest.cs @@ -0,0 +1,43 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System; +using System.Linq; +using NUnit.Framework; +using osu.Framework.Utils; +using osu.Game.Rulesets.Objects; +using osu.Game.Rulesets.Scoring; +using osu.Game.Screens.Ranking.Statistics; + +namespace osu.Game.Tests.NonVisual.Ranking +{ + [TestFixture] + public class UnstableRateTest + { + [Test] + public void TestDistributedHits() + { + var events = Enumerable.Range(-5, 11) + .Select(t => new HitEvent(t - 5, HitResult.Great, new HitObject(), null, null)); + + var unstableRate = new UnstableRate(events); + + Assert.IsTrue(Precision.AlmostEquals(unstableRate.Value, 10 * Math.Sqrt(10))); + } + + [Test] + public void TestMissesAndEmptyWindows() + { + var events = new[] + { + new HitEvent(-100, HitResult.Miss, new HitObject(), null, null), + new HitEvent(0, HitResult.Great, new HitObject(), null, null), + new HitEvent(200, HitResult.Meh, new HitObject { HitWindows = HitWindows.Empty }, null, null), + }; + + var unstableRate = new UnstableRate(events); + + Assert.IsTrue(Precision.AlmostEquals(0, unstableRate.Value)); + } + } +} diff --git a/osu.Game/Screens/Ranking/Statistics/SimpleStatisticItem.cs b/osu.Game/Screens/Ranking/Statistics/SimpleStatisticItem.cs index 3d9ba2f225..6fe7e4eda8 100644 --- a/osu.Game/Screens/Ranking/Statistics/SimpleStatisticItem.cs +++ b/osu.Game/Screens/Ranking/Statistics/SimpleStatisticItem.cs @@ -59,12 +59,19 @@ namespace osu.Game.Screens.Ranking.Statistics /// public class SimpleStatisticItem : SimpleStatisticItem { + private TValue value; + /// /// The statistic's value to be displayed. /// public new TValue Value { - set => base.Value = DisplayValue(value); + get => value; + set + { + this.value = value; + base.Value = DisplayValue(value); + } } /// From 3ca2a7767a04d2911d8244bb1d2755747e099a45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Mon, 31 Aug 2020 14:29:01 +0200 Subject: [PATCH 394/434] Exclude misses and empty window hits from UR calculation --- osu.Game/Screens/Ranking/Statistics/UnstableRate.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Ranking/Statistics/UnstableRate.cs b/osu.Game/Screens/Ranking/Statistics/UnstableRate.cs index 5b368c3e8d..18a2238784 100644 --- a/osu.Game/Screens/Ranking/Statistics/UnstableRate.cs +++ b/osu.Game/Screens/Ranking/Statistics/UnstableRate.cs @@ -20,7 +20,8 @@ namespace osu.Game.Screens.Ranking.Statistics public UnstableRate(IEnumerable hitEvents) : base("Unstable Rate") { - var timeOffsets = hitEvents.Select(ev => ev.TimeOffset).ToArray(); + var timeOffsets = hitEvents.Where(e => !(e.HitObject.HitWindows is HitWindows.EmptyHitWindows) && e.Result != HitResult.Miss) + .Select(ev => ev.TimeOffset).ToArray(); Value = 10 * standardDeviation(timeOffsets); } From 0980f97ea2c8da99030f6f9d7b16425c35865ba5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Mon, 31 Aug 2020 16:06:24 +0200 Subject: [PATCH 395/434] Replace precision check with absolute equality assert --- osu.Game.Tests/NonVisual/Ranking/UnstableRateTest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Tests/NonVisual/Ranking/UnstableRateTest.cs b/osu.Game.Tests/NonVisual/Ranking/UnstableRateTest.cs index bf4145754a..ad6f01881b 100644 --- a/osu.Game.Tests/NonVisual/Ranking/UnstableRateTest.cs +++ b/osu.Game.Tests/NonVisual/Ranking/UnstableRateTest.cs @@ -37,7 +37,7 @@ namespace osu.Game.Tests.NonVisual.Ranking var unstableRate = new UnstableRate(events); - Assert.IsTrue(Precision.AlmostEquals(0, unstableRate.Value)); + Assert.AreEqual(0, unstableRate.Value); } } } From fde4b03dabe1f58d871f7785f431a6c68f5b5ee5 Mon Sep 17 00:00:00 2001 From: Pavle Aleksov Date: Mon, 31 Aug 2020 16:21:00 +0200 Subject: [PATCH 396/434] added spinner duration check - skip HitObjectReplay if duration is 0 --- osu.Game.Rulesets.Osu/Replays/OsuAutoGenerator.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/osu.Game.Rulesets.Osu/Replays/OsuAutoGenerator.cs b/osu.Game.Rulesets.Osu/Replays/OsuAutoGenerator.cs index 4cb2cd6539..5a439734c6 100644 --- a/osu.Game.Rulesets.Osu/Replays/OsuAutoGenerator.cs +++ b/osu.Game.Rulesets.Osu/Replays/OsuAutoGenerator.cs @@ -156,6 +156,9 @@ namespace osu.Game.Rulesets.Osu.Replays // TODO: Shouldn't the spinner always spin in the same direction? if (h is Spinner) { + if ((h as Spinner).Duration == 0) + return; + calcSpinnerStartPosAndDirection(((OsuReplayFrame)Frames[^1]).Position, out startPosition, out spinnerDirection); Vector2 spinCentreOffset = SPINNER_CENTRE - ((OsuReplayFrame)Frames[^1]).Position; From 0655fc14737c76def98ebb375329044c4ff0392b Mon Sep 17 00:00:00 2001 From: PajLe Date: Mon, 31 Aug 2020 16:50:31 +0200 Subject: [PATCH 397/434] changed comparing Duration to autoplay's reactionTime instead of 0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bartłomiej Dach --- osu.Game.Rulesets.Osu/Replays/OsuAutoGenerator.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Replays/OsuAutoGenerator.cs b/osu.Game.Rulesets.Osu/Replays/OsuAutoGenerator.cs index 5a439734c6..9ef2ff9ebb 100644 --- a/osu.Game.Rulesets.Osu/Replays/OsuAutoGenerator.cs +++ b/osu.Game.Rulesets.Osu/Replays/OsuAutoGenerator.cs @@ -154,9 +154,9 @@ namespace osu.Game.Rulesets.Osu.Replays // The startPosition for the slider should not be its .Position, but the point on the circle whose tangent crosses the current cursor position // We also modify spinnerDirection so it spins in the direction it enters the spin circle, to make a smooth transition. // TODO: Shouldn't the spinner always spin in the same direction? - if (h is Spinner) + if (h is Spinner spinner) { - if ((h as Spinner).Duration == 0) + if (spinner.Duration < reactionTime) return; calcSpinnerStartPosAndDirection(((OsuReplayFrame)Frames[^1]).Position, out startPosition, out spinnerDirection); From 69ec2a76ef1586f76bb26658fec7ab183cc7762e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Mon, 31 Aug 2020 17:20:45 +0200 Subject: [PATCH 398/434] Replace reaction time check with spins required check --- osu.Game.Rulesets.Osu/Replays/OsuAutoGenerator.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Replays/OsuAutoGenerator.cs b/osu.Game.Rulesets.Osu/Replays/OsuAutoGenerator.cs index 9ef2ff9ebb..76b2631894 100644 --- a/osu.Game.Rulesets.Osu/Replays/OsuAutoGenerator.cs +++ b/osu.Game.Rulesets.Osu/Replays/OsuAutoGenerator.cs @@ -156,7 +156,8 @@ namespace osu.Game.Rulesets.Osu.Replays // TODO: Shouldn't the spinner always spin in the same direction? if (h is Spinner spinner) { - if (spinner.Duration < reactionTime) + // spinners with 0 spins required will auto-complete - don't bother + if (spinner.SpinsRequired == 0) return; calcSpinnerStartPosAndDirection(((OsuReplayFrame)Frames[^1]).Position, out startPosition, out spinnerDirection); From 9b3a48ee5e3426c8474232518755b429d563ff5d Mon Sep 17 00:00:00 2001 From: Craftplacer Date: Mon, 31 Aug 2020 18:29:46 +0200 Subject: [PATCH 399/434] Revert "Add marker interface for beatmap skins" --- .../TestSceneLegacyBeatmapSkin.cs | 2 +- .../TestSceneSkinFallbacks.cs | 18 +++++------------- .../Gameplay/TestSceneStoryboardSamples.cs | 4 ++-- .../Beatmaps/BeatmapManager_WorkingBeatmap.cs | 2 +- osu.Game/Beatmaps/IWorkingBeatmap.cs | 4 ++-- osu.Game/Beatmaps/WorkingBeatmap.cs | 8 ++++---- .../Skinning/BeatmapSkinProvidingContainer.cs | 4 ++-- osu.Game/Skinning/DefaultBeatmapSkin.cs | 9 --------- osu.Game/Skinning/IBeatmapSkin.cs | 12 ------------ osu.Game/Skinning/LegacyBeatmapSkin.cs | 2 +- osu.Game/Tests/Beatmaps/HitObjectSampleTest.cs | 2 +- 11 files changed, 19 insertions(+), 48 deletions(-) delete mode 100644 osu.Game/Skinning/DefaultBeatmapSkin.cs delete mode 100644 osu.Game/Skinning/IBeatmapSkin.cs diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneLegacyBeatmapSkin.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneLegacyBeatmapSkin.cs index 03d18cefef..3ff37c4147 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneLegacyBeatmapSkin.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneLegacyBeatmapSkin.cs @@ -110,7 +110,7 @@ namespace osu.Game.Rulesets.Osu.Tests this.hasColours = hasColours; } - protected override IBeatmapSkin GetSkin() => new TestBeatmapSkin(BeatmapInfo, hasColours); + protected override ISkin GetSkin() => new TestBeatmapSkin(BeatmapInfo, hasColours); } private class TestBeatmapSkin : LegacyBeatmapSkin diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSkinFallbacks.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSkinFallbacks.cs index 64da80a88e..075bf314bc 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSkinFallbacks.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSkinFallbacks.cs @@ -29,12 +29,12 @@ namespace osu.Game.Rulesets.Osu.Tests public class TestSceneSkinFallbacks : TestSceneOsuPlayer { private readonly TestSource testUserSkin; - private readonly BeatmapTestSource testBeatmapSkin; + private readonly TestSource testBeatmapSkin; public TestSceneSkinFallbacks() { testUserSkin = new TestSource("user"); - testBeatmapSkin = new BeatmapTestSource(); + testBeatmapSkin = new TestSource("beatmap"); } [Test] @@ -80,15 +80,15 @@ namespace osu.Game.Rulesets.Osu.Tests public class CustomSkinWorkingBeatmap : ClockBackedTestWorkingBeatmap { - private readonly IBeatmapSkin skin; + private readonly ISkinSource skin; - public CustomSkinWorkingBeatmap(IBeatmap beatmap, Storyboard storyboard, IFrameBasedClock frameBasedClock, AudioManager audio, IBeatmapSkin skin) + public CustomSkinWorkingBeatmap(IBeatmap beatmap, Storyboard storyboard, IFrameBasedClock frameBasedClock, AudioManager audio, ISkinSource skin) : base(beatmap, storyboard, frameBasedClock, audio) { this.skin = skin; } - protected override IBeatmapSkin GetSkin() => skin; + protected override ISkin GetSkin() => skin; } public class SkinProvidingPlayer : TestPlayer @@ -112,14 +112,6 @@ namespace osu.Game.Rulesets.Osu.Tests } } - private class BeatmapTestSource : TestSource, IBeatmapSkin - { - public BeatmapTestSource() - : base("beatmap") - { - } - } - public class TestSource : ISkinSource { private readonly string identifier; diff --git a/osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs b/osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs index bc9528beb6..b30870d057 100644 --- a/osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs +++ b/osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs @@ -116,7 +116,7 @@ namespace osu.Game.Tests.Gameplay AddAssert("sample playback rate matches mod rates", () => sample.Channel.AggregateFrequency.Value == expectedRate); } - private class TestSkin : LegacySkin, IBeatmapSkin + private class TestSkin : LegacySkin { public TestSkin(string resourceName, AudioManager audioManager) : base(DefaultLegacySkin.Info, new TestResourceStore(resourceName), audioManager, "skin.ini") @@ -156,7 +156,7 @@ namespace osu.Game.Tests.Gameplay this.audio = audio; } - protected override IBeatmapSkin GetSkin() => new TestSkin("test-sample", audio); + protected override ISkin GetSkin() => new TestSkin("test-sample", audio); } private class TestDrawableStoryboardSample : DrawableStoryboardSample diff --git a/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs b/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs index 44728cc251..39c5ccab27 100644 --- a/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs @@ -140,7 +140,7 @@ namespace osu.Game.Beatmaps return storyboard; } - protected override IBeatmapSkin GetSkin() + protected override ISkin GetSkin() { try { diff --git a/osu.Game/Beatmaps/IWorkingBeatmap.cs b/osu.Game/Beatmaps/IWorkingBeatmap.cs index aac41725a9..31975157a0 100644 --- a/osu.Game/Beatmaps/IWorkingBeatmap.cs +++ b/osu.Game/Beatmaps/IWorkingBeatmap.cs @@ -42,9 +42,9 @@ namespace osu.Game.Beatmaps Storyboard Storyboard { get; } /// - /// Retrieves the which this provides. + /// Retrieves the which this provides. /// - IBeatmapSkin Skin { get; } + ISkin Skin { get; } /// /// Constructs a playable from using the applicable converters for a specific . diff --git a/osu.Game/Beatmaps/WorkingBeatmap.cs b/osu.Game/Beatmaps/WorkingBeatmap.cs index 163b62a55c..b4bcf285b9 100644 --- a/osu.Game/Beatmaps/WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/WorkingBeatmap.cs @@ -44,7 +44,7 @@ namespace osu.Game.Beatmaps background = new RecyclableLazy(GetBackground, BackgroundStillValid); waveform = new RecyclableLazy(GetWaveform); storyboard = new RecyclableLazy(GetStoryboard); - skin = new RecyclableLazy(GetSkin); + skin = new RecyclableLazy(GetSkin); total_count.Value++; } @@ -275,10 +275,10 @@ namespace osu.Game.Beatmaps private readonly RecyclableLazy storyboard; public bool SkinLoaded => skin.IsResultAvailable; - public IBeatmapSkin Skin => skin.Value; + public ISkin Skin => skin.Value; - protected virtual IBeatmapSkin GetSkin() => new DefaultBeatmapSkin(); - private readonly RecyclableLazy skin; + protected virtual ISkin GetSkin() => new DefaultSkin(); + private readonly RecyclableLazy skin; /// /// Transfer pieces of a beatmap to a new one, where possible, to save on loading. diff --git a/osu.Game/Skinning/BeatmapSkinProvidingContainer.cs b/osu.Game/Skinning/BeatmapSkinProvidingContainer.cs index 346bfe53b8..40335db697 100644 --- a/osu.Game/Skinning/BeatmapSkinProvidingContainer.cs +++ b/osu.Game/Skinning/BeatmapSkinProvidingContainer.cs @@ -11,7 +11,7 @@ namespace osu.Game.Skinning /// /// A container which overrides existing skin options with beatmap-local values. /// - public class BeatmapSkinProvidingContainer : SkinProvidingContainer, IBeatmapSkin + public class BeatmapSkinProvidingContainer : SkinProvidingContainer { private readonly Bindable beatmapSkins = new Bindable(); private readonly Bindable beatmapHitsounds = new Bindable(); @@ -21,7 +21,7 @@ namespace osu.Game.Skinning protected override bool AllowTextureLookup(string componentName) => beatmapSkins.Value; protected override bool AllowSampleLookup(ISampleInfo componentName) => beatmapHitsounds.Value; - public BeatmapSkinProvidingContainer(IBeatmapSkin skin) + public BeatmapSkinProvidingContainer(ISkin skin) : base(skin) { } diff --git a/osu.Game/Skinning/DefaultBeatmapSkin.cs b/osu.Game/Skinning/DefaultBeatmapSkin.cs deleted file mode 100644 index 7b5ccd45c3..0000000000 --- a/osu.Game/Skinning/DefaultBeatmapSkin.cs +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -namespace osu.Game.Skinning -{ - public class DefaultBeatmapSkin : DefaultSkin, IBeatmapSkin - { - } -} diff --git a/osu.Game/Skinning/IBeatmapSkin.cs b/osu.Game/Skinning/IBeatmapSkin.cs deleted file mode 100644 index 91caaed557..0000000000 --- a/osu.Game/Skinning/IBeatmapSkin.cs +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -namespace osu.Game.Skinning -{ - /// - /// Marker interface for skins that originate from beatmaps. - /// - public interface IBeatmapSkin : ISkin - { - } -} diff --git a/osu.Game/Skinning/LegacyBeatmapSkin.cs b/osu.Game/Skinning/LegacyBeatmapSkin.cs index d53349dd11..d647bc4a2d 100644 --- a/osu.Game/Skinning/LegacyBeatmapSkin.cs +++ b/osu.Game/Skinning/LegacyBeatmapSkin.cs @@ -11,7 +11,7 @@ using osu.Game.Rulesets.Objects.Legacy; namespace osu.Game.Skinning { - public class LegacyBeatmapSkin : LegacySkin, IBeatmapSkin + public class LegacyBeatmapSkin : LegacySkin { protected override bool AllowManiaSkin => false; protected override bool UseCustomSampleBanks => true; diff --git a/osu.Game/Tests/Beatmaps/HitObjectSampleTest.cs b/osu.Game/Tests/Beatmaps/HitObjectSampleTest.cs index db080d889f..ab4fb38657 100644 --- a/osu.Game/Tests/Beatmaps/HitObjectSampleTest.cs +++ b/osu.Game/Tests/Beatmaps/HitObjectSampleTest.cs @@ -188,7 +188,7 @@ namespace osu.Game.Tests.Beatmaps this.resourceStore = resourceStore; } - protected override IBeatmapSkin GetSkin() => new LegacyBeatmapSkin(skinBeatmapInfo, resourceStore, AudioManager); + protected override ISkin GetSkin() => new LegacyBeatmapSkin(skinBeatmapInfo, resourceStore, AudioManager); } } } From 2e2f26449d1304e6bcd0af00a7aa2e130bb9919d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Mon, 31 Aug 2020 19:23:19 +0200 Subject: [PATCH 400/434] Change anchoring to TopRight --- osu.Game/Screens/Select/BeatmapInfoWedge.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game/Screens/Select/BeatmapInfoWedge.cs b/osu.Game/Screens/Select/BeatmapInfoWedge.cs index 2b2c40411d..44d7d0f765 100644 --- a/osu.Game/Screens/Select/BeatmapInfoWedge.cs +++ b/osu.Game/Screens/Select/BeatmapInfoWedge.cs @@ -227,13 +227,13 @@ namespace osu.Game.Screens.Select { createStarRatingDisplay(beatmapInfo).With(display => { - display.Anchor = Anchor.CentreRight; - display.Origin = Anchor.CentreRight; + display.Anchor = Anchor.TopRight; + display.Origin = Anchor.TopRight; }), StatusPill = new BeatmapSetOnlineStatusPill { - Anchor = Anchor.CentreRight, - Origin = Anchor.CentreRight, + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, TextSize = 11, TextPadding = new MarginPadding { Horizontal = 8, Vertical = 2 }, Status = beatmapInfo.Status, From 876fd21230a401d0d75877a3d681d167c2f38a9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Mon, 31 Aug 2020 19:31:47 +0200 Subject: [PATCH 401/434] Apply shear to right-anchored items --- osu.Game/Screens/Select/BeatmapInfoWedge.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/osu.Game/Screens/Select/BeatmapInfoWedge.cs b/osu.Game/Screens/Select/BeatmapInfoWedge.cs index 44d7d0f765..ad977c70b5 100644 --- a/osu.Game/Screens/Select/BeatmapInfoWedge.cs +++ b/osu.Game/Screens/Select/BeatmapInfoWedge.cs @@ -223,17 +223,20 @@ namespace osu.Game.Screens.Select Direction = FillDirection.Vertical, Padding = new MarginPadding { Top = 14, Right = shear_width / 2 }, AutoSizeAxes = Axes.Both, + Shear = wedged_container_shear, Children = new[] { createStarRatingDisplay(beatmapInfo).With(display => { display.Anchor = Anchor.TopRight; display.Origin = Anchor.TopRight; + display.Shear = -wedged_container_shear; }), StatusPill = new BeatmapSetOnlineStatusPill { Anchor = Anchor.TopRight, Origin = Anchor.TopRight, + Shear = -wedged_container_shear, TextSize = 11, TextPadding = new MarginPadding { Horizontal = 8, Vertical = 2 }, Status = beatmapInfo.Status, From c8aa197e5b472f9b3389382106253d0eeea61cb0 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 1 Sep 2020 11:36:18 +0900 Subject: [PATCH 402/434] Update framework --- osu.Android.props | 2 +- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index 1a76a24496..d4a6d6759e 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -52,6 +52,6 @@ - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index d1e2033596..5cc2f61e86 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -24,7 +24,7 @@ - + diff --git a/osu.iOS.props b/osu.iOS.props index 9b25eaab41..e7addc1c2c 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -70,7 +70,7 @@ - + @@ -80,7 +80,7 @@ - + From d45a1521a1e6441ec47f391c2575c5ac79239fb8 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 1 Sep 2020 11:56:23 +0900 Subject: [PATCH 403/434] Update BindableList usages --- osu.Game/Overlays/ChatOverlay.cs | 63 ++++++++++--------- .../Sections/Graphics/LayoutSettings.cs | 3 +- .../Screens/Edit/Timing/ControlPointTable.cs | 3 +- osu.Game/Screens/Edit/Timing/TimingScreen.cs | 3 +- .../Multi/Lounge/Components/RoomsContainer.cs | 18 +++++- 5 files changed, 53 insertions(+), 37 deletions(-) diff --git a/osu.Game/Overlays/ChatOverlay.cs b/osu.Game/Overlays/ChatOverlay.cs index 5ba55f6d45..692175603c 100644 --- a/osu.Game/Overlays/ChatOverlay.cs +++ b/osu.Game/Overlays/ChatOverlay.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System.Collections.Generic; +using System.Collections.Specialized; using System.Linq; using osuTK; using osuTK.Graphics; @@ -218,14 +219,13 @@ namespace osu.Game.Overlays Schedule(() => { // TODO: consider scheduling bindable callbacks to not perform when overlay is not present. - channelManager.JoinedChannels.ItemsAdded += onChannelAddedToJoinedChannels; - channelManager.JoinedChannels.ItemsRemoved += onChannelRemovedFromJoinedChannels; + channelManager.JoinedChannels.CollectionChanged += joinedChannelsChanged; + foreach (Channel channel in channelManager.JoinedChannels) ChannelTabControl.AddChannel(channel); - channelManager.AvailableChannels.ItemsAdded += availableChannelsChanged; - channelManager.AvailableChannels.ItemsRemoved += availableChannelsChanged; - ChannelSelectionOverlay.UpdateAvailableChannels(channelManager.AvailableChannels); + channelManager.AvailableChannels.CollectionChanged += availableChannelsChanged; + availableChannelsChanged(null, null); currentChannel = channelManager.CurrentChannel.GetBoundCopy(); currentChannel.BindValueChanged(currentChannelChanged, true); @@ -384,34 +384,41 @@ namespace osu.Game.Overlays base.PopOut(); } - private void onChannelAddedToJoinedChannels(IEnumerable channels) + private void joinedChannelsChanged(object sender, NotifyCollectionChangedEventArgs args) { - foreach (Channel channel in channels) - ChannelTabControl.AddChannel(channel); - } - - private void onChannelRemovedFromJoinedChannels(IEnumerable channels) - { - foreach (Channel channel in channels) + switch (args.Action) { - ChannelTabControl.RemoveChannel(channel); + case NotifyCollectionChangedAction.Add: + foreach (Channel channel in args.NewItems.Cast()) + ChannelTabControl.AddChannel(channel); + break; - var loaded = loadedChannels.Find(c => c.Channel == channel); + case NotifyCollectionChangedAction.Remove: + foreach (Channel channel in args.OldItems.Cast()) + { + ChannelTabControl.RemoveChannel(channel); - if (loaded != null) - { - loadedChannels.Remove(loaded); + var loaded = loadedChannels.Find(c => c.Channel == channel); - // Because the container is only cleared in the async load callback of a new channel, it is forcefully cleared - // to ensure that the previous channel doesn't get updated after it's disposed - currentChannelContainer.Remove(loaded); - loaded.Dispose(); - } + if (loaded != null) + { + loadedChannels.Remove(loaded); + + // Because the container is only cleared in the async load callback of a new channel, it is forcefully cleared + // to ensure that the previous channel doesn't get updated after it's disposed + currentChannelContainer.Remove(loaded); + loaded.Dispose(); + } + } + + break; } } - private void availableChannelsChanged(IEnumerable channels) - => ChannelSelectionOverlay.UpdateAvailableChannels(channelManager.AvailableChannels); + private void availableChannelsChanged(object sender, NotifyCollectionChangedEventArgs args) + { + ChannelSelectionOverlay.UpdateAvailableChannels(channelManager.AvailableChannels); + } protected override void Dispose(bool isDisposing) { @@ -420,10 +427,8 @@ namespace osu.Game.Overlays if (channelManager != null) { channelManager.CurrentChannel.ValueChanged -= currentChannelChanged; - channelManager.JoinedChannels.ItemsAdded -= onChannelAddedToJoinedChannels; - channelManager.JoinedChannels.ItemsRemoved -= onChannelRemovedFromJoinedChannels; - channelManager.AvailableChannels.ItemsAdded -= availableChannelsChanged; - channelManager.AvailableChannels.ItemsRemoved -= availableChannelsChanged; + channelManager.JoinedChannels.CollectionChanged -= joinedChannelsChanged; + channelManager.AvailableChannels.CollectionChanged -= availableChannelsChanged; } } diff --git a/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs b/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs index 00b7643332..4312b319c0 100644 --- a/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs @@ -163,8 +163,7 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics scalingSettings.ForEach(s => s.TransferValueOnCommit = mode.NewValue == ScalingMode.Everything); }, true); - windowModes.ItemsAdded += _ => windowModesChanged(); - windowModes.ItemsRemoved += _ => windowModesChanged(); + windowModes.CollectionChanged += (sender, args) => windowModesChanged(); windowModesChanged(); } diff --git a/osu.Game/Screens/Edit/Timing/ControlPointTable.cs b/osu.Game/Screens/Edit/Timing/ControlPointTable.cs index 5c59cfbfe8..c0c0bcead2 100644 --- a/osu.Game/Screens/Edit/Timing/ControlPointTable.cs +++ b/osu.Game/Screens/Edit/Timing/ControlPointTable.cs @@ -112,8 +112,7 @@ namespace osu.Game.Screens.Edit.Timing }; controlPoints = group.ControlPoints.GetBoundCopy(); - controlPoints.ItemsAdded += _ => createChildren(); - controlPoints.ItemsRemoved += _ => createChildren(); + controlPoints.CollectionChanged += (_, __) => createChildren(); createChildren(); } diff --git a/osu.Game/Screens/Edit/Timing/TimingScreen.cs b/osu.Game/Screens/Edit/Timing/TimingScreen.cs index a08a660e7e..8c40c8e721 100644 --- a/osu.Game/Screens/Edit/Timing/TimingScreen.cs +++ b/osu.Game/Screens/Edit/Timing/TimingScreen.cs @@ -124,8 +124,7 @@ namespace osu.Game.Screens.Edit.Timing selectedGroup.BindValueChanged(selected => { deleteButton.Enabled.Value = selected.NewValue != null; }, true); controlGroups = Beatmap.Value.Beatmap.ControlPointInfo.Groups.GetBoundCopy(); - controlGroups.ItemsAdded += _ => createContent(); - controlGroups.ItemsRemoved += _ => createContent(); + controlGroups.CollectionChanged += (sender, args) => createContent(); createContent(); } diff --git a/osu.Game/Screens/Multi/Lounge/Components/RoomsContainer.cs b/osu.Game/Screens/Multi/Lounge/Components/RoomsContainer.cs index 447c99039a..321d7b0a19 100644 --- a/osu.Game/Screens/Multi/Lounge/Components/RoomsContainer.cs +++ b/osu.Game/Screens/Multi/Lounge/Components/RoomsContainer.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Collections.Specialized; using System.Linq; using osu.Framework.Allocation; using osu.Framework.Bindables; @@ -53,8 +54,7 @@ namespace osu.Game.Screens.Multi.Lounge.Components protected override void LoadComplete() { - rooms.ItemsAdded += addRooms; - rooms.ItemsRemoved += removeRooms; + rooms.CollectionChanged += roomsChanged; roomManager.RoomsUpdated += updateSorting; rooms.BindTo(roomManager.Rooms); @@ -82,6 +82,20 @@ namespace osu.Game.Screens.Multi.Lounge.Components }); } + private void roomsChanged(object sender, NotifyCollectionChangedEventArgs args) + { + switch (args.Action) + { + case NotifyCollectionChangedAction.Add: + addRooms(args.NewItems.Cast()); + break; + + case NotifyCollectionChangedAction.Remove: + removeRooms(args.OldItems.Cast()); + break; + } + } + private void addRooms(IEnumerable rooms) { foreach (var room in rooms) From d1f79a6a488a9b8f07f88e35d7b96ac71192a458 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 24 Aug 2020 20:00:24 +0900 Subject: [PATCH 404/434] Fix potentially incorrect zoom level getting set on very short audio track --- osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs index 717d60b4f3..ce2954f301 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs @@ -68,7 +68,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline }, true); } - private float getZoomLevelForVisibleMilliseconds(double milliseconds) => (float)(track.Length / milliseconds); + private float getZoomLevelForVisibleMilliseconds(double milliseconds) => Math.Max(1, (float)(track.Length / milliseconds)); /// /// The timeline's scroll position in the last frame. From 9e3b809cab6f61489f90379327928768778672fb Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 1 Sep 2020 15:42:47 +0900 Subject: [PATCH 405/434] Rename to user_score to match API --- osu.Game/Online/Multiplayer/APILeaderboard.cs | 4 ++-- osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Online/Multiplayer/APILeaderboard.cs b/osu.Game/Online/Multiplayer/APILeaderboard.cs index 96fe7cefb0..65863d6e0e 100644 --- a/osu.Game/Online/Multiplayer/APILeaderboard.cs +++ b/osu.Game/Online/Multiplayer/APILeaderboard.cs @@ -12,7 +12,7 @@ namespace osu.Game.Online.Multiplayer [JsonProperty("leaderboard")] public List Leaderboard; - [JsonProperty("own_score")] - public APIUserScoreAggregate OwnScore; + [JsonProperty("user_score")] + public APIUserScoreAggregate UserScore; } } diff --git a/osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs b/osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs index 50afbb39fe..5bf61eb4ee 100644 --- a/osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs +++ b/osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs @@ -42,7 +42,7 @@ namespace osu.Game.Screens.Multi.Match.Components req.Success += r => { scoresCallback?.Invoke(r.Leaderboard); - TopScore = r.OwnScore; + TopScore = r.UserScore; }; return req; From 26b4226b5538c9f95657fdc985b9a873c763b4f1 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 1 Sep 2020 16:55:10 +0900 Subject: [PATCH 406/434] Fix ModTimeRamp not working --- osu.Game/Screens/Play/Player.cs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 9be4fd6a65..07be482529 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -52,6 +52,9 @@ namespace osu.Game.Screens.Play public override OverlayActivation InitialOverlayActivationMode => OverlayActivation.UserTriggered; + // We are managing our own adjustments (see OnEntering/OnExiting). + public override bool AllowRateAdjustments => false; + /// /// Whether gameplay should pause when the game window focus is lost. /// @@ -627,6 +630,10 @@ namespace osu.Game.Screens.Play foreach (var mod in Mods.Value.OfType()) mod.ApplyToHUD(HUDOverlay); + + Beatmap.Value.Track.ResetSpeedAdjustments(); + foreach (var mod in Mods.Value.OfType()) + mod.ApplyToTrack(Beatmap.Value.Track); } public override void OnSuspending(IScreen next) @@ -660,6 +667,8 @@ namespace osu.Game.Screens.Play // as we are no longer the current screen, we cannot guarantee the track is still usable. GameplayClockContainer?.StopUsingBeatmapClock(); + Beatmap.Value.Track.ResetSpeedAdjustments(); + fadeOut(); return base.OnExiting(next); } From 7e1844ed773368a4b932ea0e2d7fc87fa0fc53b4 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 1 Sep 2020 18:07:19 +0900 Subject: [PATCH 407/434] Fix track adjusments being reset incorrectly --- osu.Game/Screens/Play/Player.cs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 07be482529..82c446f5e4 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -80,6 +80,9 @@ namespace osu.Game.Screens.Play [Resolved] private IAPIProvider api { get; set; } + [Resolved] + private MusicController musicController { get; set; } + private SampleChannel sampleRestart; public BreakOverlay BreakOverlay; @@ -631,9 +634,12 @@ namespace osu.Game.Screens.Play foreach (var mod in Mods.Value.OfType()) mod.ApplyToHUD(HUDOverlay); - Beatmap.Value.Track.ResetSpeedAdjustments(); + // Our mods are local copies of the global mods so they need to be re-applied to the track. + // This is done through the music controller (for now), because resetting speed adjustments on the beatmap track also removes adjustments provided by DrawableTrack. + // Todo: In the future, player will receive in a track and will probably not have to worry about this... + musicController.ResetTrackAdjustments(); foreach (var mod in Mods.Value.OfType()) - mod.ApplyToTrack(Beatmap.Value.Track); + mod.ApplyToTrack(musicController.CurrentTrack); } public override void OnSuspending(IScreen next) @@ -667,7 +673,7 @@ namespace osu.Game.Screens.Play // as we are no longer the current screen, we cannot guarantee the track is still usable. GameplayClockContainer?.StopUsingBeatmapClock(); - Beatmap.Value.Track.ResetSpeedAdjustments(); + musicController.ResetTrackAdjustments(); fadeOut(); return base.OnExiting(next); From 112ecf085d6a44b59be0c12f131d7fee2a20d4f1 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 1 Sep 2020 17:19:04 +0000 Subject: [PATCH 408/434] Bump Sentry from 2.1.5 to 2.1.6 Bumps [Sentry](https://github.com/getsentry/sentry-dotnet) from 2.1.5 to 2.1.6. - [Release notes](https://github.com/getsentry/sentry-dotnet/releases) - [Commits](https://github.com/getsentry/sentry-dotnet/compare/2.1.5...2.1.6) Signed-off-by: dependabot-preview[bot] --- osu.Game/osu.Game.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index d1e2033596..c021770d7b 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -26,7 +26,7 @@ - + From 846189659b935cf970a22fa17e23a63f1353604a Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 1 Sep 2020 17:19:29 +0000 Subject: [PATCH 409/434] Bump Microsoft.Build.Traversal from 2.0.52 to 2.1.1 Bumps [Microsoft.Build.Traversal](https://github.com/Microsoft/MSBuildSdks) from 2.0.52 to 2.1.1. - [Release notes](https://github.com/Microsoft/MSBuildSdks/releases) - [Changelog](https://github.com/microsoft/MSBuildSdks/blob/master/RELEASE.md) - [Commits](https://github.com/Microsoft/MSBuildSdks/compare/Microsoft.Build.Traversal.2.0.52...Microsoft.Build.Traversal.2.1.1) Signed-off-by: dependabot-preview[bot] --- global.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/global.json b/global.json index 233a040d18..a9a531f59c 100644 --- a/global.json +++ b/global.json @@ -5,6 +5,6 @@ "version": "3.1.100" }, "msbuild-sdks": { - "Microsoft.Build.Traversal": "2.0.52" + "Microsoft.Build.Traversal": "2.1.1" } } \ No newline at end of file From 66c0d12da619a86b43cbbb594987c59712a8acff Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 1 Sep 2020 17:19:46 +0000 Subject: [PATCH 410/434] Bump Microsoft.NET.Test.Sdk from 16.7.0 to 16.7.1 Bumps [Microsoft.NET.Test.Sdk](https://github.com/microsoft/vstest) from 16.7.0 to 16.7.1. - [Release notes](https://github.com/microsoft/vstest/releases) - [Commits](https://github.com/microsoft/vstest/compare/v16.7.0...v16.7.1) Signed-off-by: dependabot-preview[bot] --- .../osu.Game.Rulesets.Catch.Tests.csproj | 2 +- .../osu.Game.Rulesets.Mania.Tests.csproj | 2 +- osu.Game.Rulesets.Osu.Tests/osu.Game.Rulesets.Osu.Tests.csproj | 2 +- .../osu.Game.Rulesets.Taiko.Tests.csproj | 2 +- osu.Game.Tests/osu.Game.Tests.csproj | 2 +- osu.Game.Tournament.Tests/osu.Game.Tournament.Tests.csproj | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/osu.Game.Rulesets.Catch.Tests/osu.Game.Rulesets.Catch.Tests.csproj b/osu.Game.Rulesets.Catch.Tests/osu.Game.Rulesets.Catch.Tests.csproj index f9d56dfa78..dfe3bf8af4 100644 --- a/osu.Game.Rulesets.Catch.Tests/osu.Game.Rulesets.Catch.Tests.csproj +++ b/osu.Game.Rulesets.Catch.Tests/osu.Game.Rulesets.Catch.Tests.csproj @@ -2,7 +2,7 @@ - + diff --git a/osu.Game.Rulesets.Mania.Tests/osu.Game.Rulesets.Mania.Tests.csproj b/osu.Game.Rulesets.Mania.Tests/osu.Game.Rulesets.Mania.Tests.csproj index ed00ed0b4c..892f27d27f 100644 --- a/osu.Game.Rulesets.Mania.Tests/osu.Game.Rulesets.Mania.Tests.csproj +++ b/osu.Game.Rulesets.Mania.Tests/osu.Game.Rulesets.Mania.Tests.csproj @@ -2,7 +2,7 @@ - + diff --git a/osu.Game.Rulesets.Osu.Tests/osu.Game.Rulesets.Osu.Tests.csproj b/osu.Game.Rulesets.Osu.Tests/osu.Game.Rulesets.Osu.Tests.csproj index f3837ea6b1..3639c3616f 100644 --- a/osu.Game.Rulesets.Osu.Tests/osu.Game.Rulesets.Osu.Tests.csproj +++ b/osu.Game.Rulesets.Osu.Tests/osu.Game.Rulesets.Osu.Tests.csproj @@ -2,7 +2,7 @@ - + diff --git a/osu.Game.Rulesets.Taiko.Tests/osu.Game.Rulesets.Taiko.Tests.csproj b/osu.Game.Rulesets.Taiko.Tests/osu.Game.Rulesets.Taiko.Tests.csproj index e896606ee8..b59f3a4344 100644 --- a/osu.Game.Rulesets.Taiko.Tests/osu.Game.Rulesets.Taiko.Tests.csproj +++ b/osu.Game.Rulesets.Taiko.Tests/osu.Game.Rulesets.Taiko.Tests.csproj @@ -2,7 +2,7 @@ - + diff --git a/osu.Game.Tests/osu.Game.Tests.csproj b/osu.Game.Tests/osu.Game.Tests.csproj index d767973528..c692bcd5e4 100644 --- a/osu.Game.Tests/osu.Game.Tests.csproj +++ b/osu.Game.Tests/osu.Game.Tests.csproj @@ -3,7 +3,7 @@ - + diff --git a/osu.Game.Tournament.Tests/osu.Game.Tournament.Tests.csproj b/osu.Game.Tournament.Tests/osu.Game.Tournament.Tests.csproj index 95f5deb2cc..5d55196dcf 100644 --- a/osu.Game.Tournament.Tests/osu.Game.Tournament.Tests.csproj +++ b/osu.Game.Tournament.Tests/osu.Game.Tournament.Tests.csproj @@ -5,7 +5,7 @@ - + From 8bf679db8be69f18ac06aba4972a14bcf5e8f513 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 2 Sep 2020 13:17:17 +0900 Subject: [PATCH 411/434] Fix nullref in date text box --- osu.Game.Tournament/Components/DateTextBox.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game.Tournament/Components/DateTextBox.cs b/osu.Game.Tournament/Components/DateTextBox.cs index ee7e350970..aee5241e35 100644 --- a/osu.Game.Tournament/Components/DateTextBox.cs +++ b/osu.Game.Tournament/Components/DateTextBox.cs @@ -22,11 +22,12 @@ namespace osu.Game.Tournament.Components } // hold a reference to the provided bindable so we don't have to in every settings section. - private Bindable bindable; + private Bindable bindable = new Bindable(); public DateTextBox() { base.Bindable = new Bindable(); + ((OsuTextBox)Control).OnCommit = (sender, newText) => { try From 8f90cc182099075a3651d22d1c31b9303aabd6ed Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 2 Sep 2020 13:21:51 +0900 Subject: [PATCH 412/434] Add test --- .../Components/TestSceneDateTextBox.cs | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 osu.Game.Tournament.Tests/Components/TestSceneDateTextBox.cs diff --git a/osu.Game.Tournament.Tests/Components/TestSceneDateTextBox.cs b/osu.Game.Tournament.Tests/Components/TestSceneDateTextBox.cs new file mode 100644 index 0000000000..33165d385a --- /dev/null +++ b/osu.Game.Tournament.Tests/Components/TestSceneDateTextBox.cs @@ -0,0 +1,41 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using NUnit.Framework; +using osu.Game.Tests.Visual; +using osu.Game.Tournament.Components; +using osuTK; +using osuTK.Input; + +namespace osu.Game.Tournament.Tests.Components +{ + public class TestSceneDateTextBox : OsuManualInputManagerTestScene + { + private DateTextBox textBox; + + [SetUp] + public void Setup() => Schedule(() => + { + Child = textBox = new DateTextBox + { + Width = 0.3f + }; + }); + + [Test] + public void TestCommitWithoutSettingBindable() + { + AddStep("click textbox", () => + { + InputManager.MoveMouseTo(textBox); + InputManager.Click(MouseButton.Left); + }); + + AddStep("unfocus", () => + { + InputManager.MoveMouseTo(Vector2.Zero); + InputManager.Click(MouseButton.Left); + }); + } + } +} From f793bf66e5e34c94c374b4f19391c83ce08fd361 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 2 Sep 2020 14:25:24 +0900 Subject: [PATCH 413/434] Remove rate adjustment from player test scene --- osu.Game/Tests/Visual/PlayerTestScene.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.Game/Tests/Visual/PlayerTestScene.cs b/osu.Game/Tests/Visual/PlayerTestScene.cs index 7d06c99133..2c46e7f6d3 100644 --- a/osu.Game/Tests/Visual/PlayerTestScene.cs +++ b/osu.Game/Tests/Visual/PlayerTestScene.cs @@ -29,8 +29,6 @@ namespace osu.Game.Tests.Visual { Dependencies.Cache(LocalConfig = new OsuConfigManager(LocalStorage)); LocalConfig.GetBindable(OsuSetting.DimLevel).Value = 1.0; - - MusicController.AllowRateAdjustments = true; } [SetUpSteps] From 7a6e02c558cffb2eaa5f665611f6ce778359d035 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 2 Sep 2020 14:28:31 +0900 Subject: [PATCH 414/434] Allow null rank --- osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs | 2 +- .../Screens/Multi/Match/Components/MatchLeaderboardScore.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs b/osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs index 5bf61eb4ee..f2409d64e7 100644 --- a/osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs +++ b/osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs @@ -50,7 +50,7 @@ namespace osu.Game.Screens.Multi.Match.Components protected override LeaderboardScore CreateDrawableScore(APIUserScoreAggregate model, int index) => new MatchLeaderboardScore(model, index); - protected override LeaderboardScore CreateDrawableTopScore(APIUserScoreAggregate model) => new MatchLeaderboardScore(model, model.Position ?? 0, false); + protected override LeaderboardScore CreateDrawableTopScore(APIUserScoreAggregate model) => new MatchLeaderboardScore(model, model.Position, false); } public enum MatchLeaderboardScope diff --git a/osu.Game/Screens/Multi/Match/Components/MatchLeaderboardScore.cs b/osu.Game/Screens/Multi/Match/Components/MatchLeaderboardScore.cs index c4e2b332b3..1fabdbb86a 100644 --- a/osu.Game/Screens/Multi/Match/Components/MatchLeaderboardScore.cs +++ b/osu.Game/Screens/Multi/Match/Components/MatchLeaderboardScore.cs @@ -14,7 +14,7 @@ namespace osu.Game.Screens.Multi.Match.Components { private readonly APIUserScoreAggregate score; - public MatchLeaderboardScore(APIUserScoreAggregate score, int rank, bool allowHighlight = true) + public MatchLeaderboardScore(APIUserScoreAggregate score, int? rank, bool allowHighlight = true) : base(score.CreateScoreInfo(), rank, allowHighlight) { this.score = score; From bff652a26f4755e3b18546af495d8bab778ef67f Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 2 Sep 2020 14:29:46 +0900 Subject: [PATCH 415/434] Persist nulls to the top score bindable --- osu.Game/Online/Leaderboards/Leaderboard.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/osu.Game/Online/Leaderboards/Leaderboard.cs b/osu.Game/Online/Leaderboards/Leaderboard.cs index 003d90d400..db0f835c67 100644 --- a/osu.Game/Online/Leaderboards/Leaderboard.cs +++ b/osu.Game/Online/Leaderboards/Leaderboard.cs @@ -93,13 +93,12 @@ namespace osu.Game.Online.Leaderboards get => topScoreContainer.Score.Value; set { + topScoreContainer.Score.Value = value; + if (value == null) topScoreContainer.Hide(); else - { topScoreContainer.Show(); - topScoreContainer.Score.Value = value; - } } } From 5195da3ceb6abc93db51e711c94086a009bf197d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 2 Sep 2020 15:18:51 +0900 Subject: [PATCH 416/434] Add message box in bracket editor explaining how to get started --- .../Screens/Editors/LadderEditorScreen.cs | 12 ++++++ osu.Game.Tournament/TournamentGame.cs | 25 +----------- osu.Game.Tournament/WarningBox.cs | 40 +++++++++++++++++++ 3 files changed, 53 insertions(+), 24 deletions(-) create mode 100644 osu.Game.Tournament/WarningBox.cs diff --git a/osu.Game.Tournament/Screens/Editors/LadderEditorScreen.cs b/osu.Game.Tournament/Screens/Editors/LadderEditorScreen.cs index f3eecf8afe..efec4cffdd 100644 --- a/osu.Game.Tournament/Screens/Editors/LadderEditorScreen.cs +++ b/osu.Game.Tournament/Screens/Editors/LadderEditorScreen.cs @@ -26,6 +26,8 @@ namespace osu.Game.Tournament.Screens.Editors [Cached] private LadderEditorInfo editorInfo = new LadderEditorInfo(); + private WarningBox rightClickMessage; + protected override bool DrawLoserPaths => true; [BackgroundDependencyLoader] @@ -37,6 +39,16 @@ namespace osu.Game.Tournament.Screens.Editors Origin = Anchor.TopRight, Margin = new MarginPadding(5) }); + + AddInternal(rightClickMessage = new WarningBox("Right click to place and link matches")); + + LadderInfo.Matches.CollectionChanged += (_, __) => updateMessage(); + updateMessage(); + } + + private void updateMessage() + { + rightClickMessage.Alpha = LadderInfo.Matches.Count > 0 ? 0 : 1; } public void BeginJoin(TournamentMatch match, bool losers) diff --git a/osu.Game.Tournament/TournamentGame.cs b/osu.Game.Tournament/TournamentGame.cs index 307ee1c773..bbe4a53d8f 100644 --- a/osu.Game.Tournament/TournamentGame.cs +++ b/osu.Game.Tournament/TournamentGame.cs @@ -87,30 +87,7 @@ namespace osu.Game.Tournament }, } }, - heightWarning = new Container - { - Masking = true, - CornerRadius = 5, - Depth = float.MinValue, - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - AutoSizeAxes = Axes.Both, - Children = new Drawable[] - { - new Box - { - Colour = Color4.Red, - RelativeSizeAxes = Axes.Both, - }, - new TournamentSpriteText - { - Text = "Please make the window wider", - Font = OsuFont.Torus.With(weight: FontWeight.Bold), - Colour = Color4.White, - Padding = new MarginPadding(20) - } - } - }, + heightWarning = new WarningBox("Please make the window wider"), new OsuContextMenuContainer { RelativeSizeAxes = Axes.Both, diff --git a/osu.Game.Tournament/WarningBox.cs b/osu.Game.Tournament/WarningBox.cs new file mode 100644 index 0000000000..814482aea4 --- /dev/null +++ b/osu.Game.Tournament/WarningBox.cs @@ -0,0 +1,40 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Game.Graphics; +using osuTK.Graphics; + +namespace osu.Game.Tournament +{ + internal class WarningBox : Container + { + public WarningBox(string text) + { + Masking = true; + CornerRadius = 5; + Depth = float.MinValue; + Anchor = Anchor.Centre; + Origin = Anchor.Centre; + AutoSizeAxes = Axes.Both; + + Children = new Drawable[] + { + new Box + { + Colour = Color4.Red, + RelativeSizeAxes = Axes.Both, + }, + new TournamentSpriteText + { + Text = text, + Font = OsuFont.Torus.With(weight: FontWeight.Bold), + Colour = Color4.White, + Padding = new MarginPadding(20) + } + }; + } + } +} From 555b2196b734cbce88a2acd2a0832367bf1c33d4 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 2 Sep 2020 15:23:50 +0900 Subject: [PATCH 417/434] Add xmldoc to MusicController.ResetTrackAdjustments() --- osu.Game/Overlays/MusicController.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index 6d5b5d43cd..c831584248 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -382,6 +382,12 @@ namespace osu.Game.Overlays } } + /// + /// Resets the speed adjustments currently applied on and applies the mod adjustments if is true. + /// + /// + /// Does not reset speed adjustments applied directly to the beatmap track. + /// public void ResetTrackAdjustments() { CurrentTrack.ResetSpeedAdjustments(); From 6a765d2d765dd01f4bd145560d6b30542aae7813 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 2 Sep 2020 20:04:56 +0900 Subject: [PATCH 418/434] Add smooth fading between audio tracks on transition --- osu.Game/Overlays/MusicController.cs | 6 +++++- osu.Game/Screens/Menu/IntroScreen.cs | 7 +++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index c831584248..17877a69a5 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.Linq; using JetBrains.Annotations; using osu.Framework.Allocation; +using osu.Framework.Audio; using osu.Framework.Audio.Track; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -341,10 +342,13 @@ namespace osu.Game.Overlays // but the mutation of the hierarchy is scheduled to avoid exceptions. Schedule(() => { - lastTrack.Expire(); + lastTrack.VolumeTo(0, 500, Easing.Out).Expire(); if (queuedTrack == CurrentTrack) + { AddInternal(queuedTrack); + queuedTrack.VolumeTo(0).Then().VolumeTo(1, 300, Easing.Out); + } else { // If the track has changed since the call to changeTrack, it is safe to dispose the diff --git a/osu.Game/Screens/Menu/IntroScreen.cs b/osu.Game/Screens/Menu/IntroScreen.cs index 884cbfe107..473e6b0364 100644 --- a/osu.Game/Screens/Menu/IntroScreen.cs +++ b/osu.Game/Screens/Menu/IntroScreen.cs @@ -12,6 +12,7 @@ using osu.Framework.Screens; using osu.Game.Beatmaps; using osu.Game.Configuration; using osu.Game.IO.Archives; +using osu.Game.Overlays; using osu.Game.Screens.Backgrounds; using osu.Game.Skinning; using osuTK; @@ -60,6 +61,9 @@ namespace osu.Game.Screens.Menu [Resolved] private AudioManager audio { get; set; } + [Resolved] + private MusicController musicController { get; set; } + /// /// Whether the is provided by osu! resources, rather than a user beatmap. /// Only valid during or after . @@ -167,6 +171,9 @@ namespace osu.Game.Screens.Menu Track = initialBeatmap.Track; UsingThemedIntro = !initialBeatmap.Track.IsDummyDevice; + // ensure the track starts at maximum volume + musicController.CurrentTrack.FinishTransforms(); + logo.MoveTo(new Vector2(0.5f)); logo.ScaleTo(Vector2.One); logo.Hide(); From 3fc6a74fdfa1bfd30c05b4748b7712c97530a923 Mon Sep 17 00:00:00 2001 From: Lucas A Date: Wed, 2 Sep 2020 19:55:46 +0200 Subject: [PATCH 419/434] Expose an immutable bindable in interface. --- osu.Game/Screens/IOsuScreen.cs | 2 +- osu.Game/Screens/OsuScreen.cs | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/IOsuScreen.cs b/osu.Game/Screens/IOsuScreen.cs index ead8e4bc22..e19037c2c4 100644 --- a/osu.Game/Screens/IOsuScreen.cs +++ b/osu.Game/Screens/IOsuScreen.cs @@ -41,7 +41,7 @@ namespace osu.Game.Screens /// /// Whether overlays should be able to be opened when this screen is current. /// - Bindable OverlayActivationMode { get; } + IBindable OverlayActivationMode { get; } /// /// The amount of parallax to be applied while this screen is displayed. diff --git a/osu.Game/Screens/OsuScreen.cs b/osu.Game/Screens/OsuScreen.cs index c10deaf1e5..cb8f2d21fe 100644 --- a/osu.Game/Screens/OsuScreen.cs +++ b/osu.Game/Screens/OsuScreen.cs @@ -48,7 +48,9 @@ namespace osu.Game.Screens /// protected virtual OverlayActivation InitialOverlayActivationMode => OverlayActivation.All; - public Bindable OverlayActivationMode { get; } + protected readonly Bindable OverlayActivationMode; + + IBindable IOsuScreen.OverlayActivationMode => OverlayActivationMode; public virtual bool CursorVisible => true; From 754274a146522ce3a8e69bda0ff4541819b539a2 Mon Sep 17 00:00:00 2001 From: Lucas A Date: Wed, 2 Sep 2020 20:55:26 +0200 Subject: [PATCH 420/434] Fix and add XMLDoc --- osu.Game/OsuGame.cs | 3 +++ osu.Game/Screens/OsuScreen.cs | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index e6d96df927..31926a6845 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -88,6 +88,9 @@ namespace osu.Game private IdleTracker idleTracker; + /// + /// Whether overlays should be able to be opened game-wide. Value is sourced from the current active screen. + /// public readonly IBindable OverlayActivationMode = new Bindable(); protected OsuScreenStack ScreenStack; diff --git a/osu.Game/Screens/OsuScreen.cs b/osu.Game/Screens/OsuScreen.cs index cb8f2d21fe..a44d14fb5c 100644 --- a/osu.Game/Screens/OsuScreen.cs +++ b/osu.Game/Screens/OsuScreen.cs @@ -44,7 +44,7 @@ namespace osu.Game.Screens public virtual bool HideOverlaysOnEnter => false; /// - /// The initial initial overlay activation mode to use when this screen is entered for the first time. + /// The initial overlay activation mode to use when this screen is entered for the first time. /// protected virtual OverlayActivation InitialOverlayActivationMode => OverlayActivation.All; From 547c8090e5a5ae5d3c232debdfe5cbb95ce2f8ca Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 3 Sep 2020 13:13:48 +0900 Subject: [PATCH 421/434] Improve game exit music fade --- osu.Game/Screens/Menu/IntroScreen.cs | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/osu.Game/Screens/Menu/IntroScreen.cs b/osu.Game/Screens/Menu/IntroScreen.cs index 473e6b0364..bed8dbcdcb 100644 --- a/osu.Game/Screens/Menu/IntroScreen.cs +++ b/osu.Game/Screens/Menu/IntroScreen.cs @@ -46,8 +46,6 @@ namespace osu.Game.Screens.Menu protected ITrack Track { get; private set; } - private readonly BindableDouble exitingVolumeFade = new BindableDouble(1); - private const int exit_delay = 3000; private SampleChannel seeya; @@ -127,17 +125,29 @@ namespace osu.Game.Screens.Menu this.FadeIn(300); double fadeOutTime = exit_delay; + // we also handle the exit transition. if (MenuVoice.Value) + { seeya.Play(); + + // if playing the outro voice, we have more time to have fun with the background track. + // initially fade to almost silent then ramp out over the remaining time. + const double initial_fade = 200; + musicController.CurrentTrack + .VolumeTo(0.03f, initial_fade).Then() + .VolumeTo(0, fadeOutTime - initial_fade, Easing.In); + } else + { fadeOutTime = 500; - audio.AddAdjustment(AdjustableProperty.Volume, exitingVolumeFade); - this.TransformBindableTo(exitingVolumeFade, 0, fadeOutTime).OnComplete(_ => this.Exit()); + // if outro voice is turned off, just do a simple fade out. + musicController.CurrentTrack.VolumeTo(0, fadeOutTime, Easing.Out); + } //don't want to fade out completely else we will stop running updates. - Game.FadeTo(0.01f, fadeOutTime); + Game.FadeTo(0.01f, fadeOutTime).OnComplete(_ => this.Exit()); base.OnResuming(last); } From 2f42c57f4b7cbe4a9ae4f2ab0ed5fb5d2e65a53d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 3 Sep 2020 13:15:16 +0900 Subject: [PATCH 422/434] Add safeties to ensure the current track doesn't loop or change --- osu.Game/Screens/Menu/IntroScreen.cs | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/osu.Game/Screens/Menu/IntroScreen.cs b/osu.Game/Screens/Menu/IntroScreen.cs index bed8dbcdcb..1df5c503d6 100644 --- a/osu.Game/Screens/Menu/IntroScreen.cs +++ b/osu.Game/Screens/Menu/IntroScreen.cs @@ -126,6 +126,12 @@ namespace osu.Game.Screens.Menu double fadeOutTime = exit_delay; + var track = musicController.CurrentTrack; + + // ensure the track doesn't change or loop as we are exiting. + track.Looping = false; + Beatmap.Disabled = true; + // we also handle the exit transition. if (MenuVoice.Value) { @@ -134,16 +140,16 @@ namespace osu.Game.Screens.Menu // if playing the outro voice, we have more time to have fun with the background track. // initially fade to almost silent then ramp out over the remaining time. const double initial_fade = 200; - musicController.CurrentTrack - .VolumeTo(0.03f, initial_fade).Then() - .VolumeTo(0, fadeOutTime - initial_fade, Easing.In); + track + .VolumeTo(0.03f, initial_fade).Then() + .VolumeTo(0, fadeOutTime - initial_fade, Easing.In); } else { fadeOutTime = 500; // if outro voice is turned off, just do a simple fade out. - musicController.CurrentTrack.VolumeTo(0, fadeOutTime, Easing.Out); + track.VolumeTo(0, fadeOutTime, Easing.Out); } //don't want to fade out completely else we will stop running updates. From 0530c4b8a740d63f6c4c06faab5dac23cf517c63 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 3 Sep 2020 14:58:22 +0900 Subject: [PATCH 423/434] Update framework --- osu.Android.props | 2 +- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index d4a6d6759e..2d3bfaf7ce 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -52,6 +52,6 @@ - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 2a592108b7..166910b165 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -24,7 +24,7 @@ - + diff --git a/osu.iOS.props b/osu.iOS.props index e7addc1c2c..51f8141bac 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -70,7 +70,7 @@ - + @@ -80,7 +80,7 @@ - + From dceae21bbf4083f912b61b5fcb9d4b3b9422ffb0 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 3 Sep 2020 15:46:56 +0900 Subject: [PATCH 424/434] Centralise fetching of overlay component titles and textures --- .../BeatmapListing/BeatmapListingHeader.cs | 3 ++- osu.Game/Overlays/BeatmapSetOverlay.cs | 4 +++- .../Overlays/Changelog/ChangelogHeader.cs | 1 + osu.Game/Overlays/ChangelogOverlay.cs | 9 ++++---- osu.Game/Overlays/ChatOverlay.cs | 6 ++++- .../Dashboard/DashboardOverlayHeader.cs | 3 ++- osu.Game/Overlays/DashboardOverlay.cs | 2 +- osu.Game/Overlays/FullscreenOverlay.cs | 8 ++++++- osu.Game/Overlays/INamedOverlayComponent.cs | 14 ++++++++++++ osu.Game/Overlays/News/NewsHeader.cs | 1 + osu.Game/Overlays/NewsOverlay.cs | 5 +++-- osu.Game/Overlays/NotificationOverlay.cs | 6 ++++- osu.Game/Overlays/NowPlayingOverlay.cs | 6 ++++- osu.Game/Overlays/OverlayHeader.cs | 4 +++- osu.Game/Overlays/OverlayTitle.cs | 22 +++++++++++++------ .../Rankings/RankingsOverlayHeader.cs | 1 + osu.Game/Overlays/RankingsOverlay.cs | 2 +- .../SearchableList/SearchableListOverlay.cs | 2 +- osu.Game/Overlays/SettingsOverlay.cs | 6 ++++- .../Toolbar/ToolbarBeatmapListingButton.cs | 5 ----- osu.Game/Overlays/Toolbar/ToolbarButton.cs | 11 ---------- .../Toolbar/ToolbarChangelogButton.cs | 8 ------- .../Overlays/Toolbar/ToolbarChatButton.cs | 5 ----- .../Overlays/Toolbar/ToolbarHomeButton.cs | 3 +-- .../Overlays/Toolbar/ToolbarMusicButton.cs | 5 ----- .../Overlays/Toolbar/ToolbarNewsButton.cs | 8 ------- .../Toolbar/ToolbarNotificationButton.cs | 5 ----- .../Toolbar/ToolbarOverlayToggleButton.cs | 16 ++++++++++++++ .../Overlays/Toolbar/ToolbarRankingsButton.cs | 8 ------- .../Overlays/Toolbar/ToolbarSettingsButton.cs | 5 ----- .../Overlays/Toolbar/ToolbarSocialButton.cs | 5 ----- osu.Game/Overlays/UserProfileOverlay.cs | 4 ++-- 32 files changed, 98 insertions(+), 95 deletions(-) create mode 100644 osu.Game/Overlays/INamedOverlayComponent.cs diff --git a/osu.Game/Overlays/BeatmapListing/BeatmapListingHeader.cs b/osu.Game/Overlays/BeatmapListing/BeatmapListingHeader.cs index 1bab200fec..1cf86b78cf 100644 --- a/osu.Game/Overlays/BeatmapListing/BeatmapListingHeader.cs +++ b/osu.Game/Overlays/BeatmapListing/BeatmapListingHeader.cs @@ -12,7 +12,8 @@ namespace osu.Game.Overlays.BeatmapListing public BeatmapListingTitle() { Title = "beatmap listing"; - IconTexture = "Icons/changelog"; + Description = "Browse for new beatmaps"; + IconTexture = "Icons/Hexacons/music"; } } } diff --git a/osu.Game/Overlays/BeatmapSetOverlay.cs b/osu.Game/Overlays/BeatmapSetOverlay.cs index 3e23442023..2dfd1fa20f 100644 --- a/osu.Game/Overlays/BeatmapSetOverlay.cs +++ b/osu.Game/Overlays/BeatmapSetOverlay.cs @@ -24,7 +24,9 @@ namespace osu.Game.Overlays public const float X_PADDING = 40; public const float Y_PADDING = 25; public const float RIGHT_WIDTH = 275; - protected readonly Header Header; + + //todo: should be an OverlayHeader? or maybe not? + protected new readonly Header Header; [Resolved] private RulesetStore rulesets { get; set; } diff --git a/osu.Game/Overlays/Changelog/ChangelogHeader.cs b/osu.Game/Overlays/Changelog/ChangelogHeader.cs index 050bdea03a..35a4fc7014 100644 --- a/osu.Game/Overlays/Changelog/ChangelogHeader.cs +++ b/osu.Game/Overlays/Changelog/ChangelogHeader.cs @@ -115,6 +115,7 @@ namespace osu.Game.Overlays.Changelog public ChangelogHeaderTitle() { Title = "changelog"; + Description = "Track recent dev updates in the osu! ecosystem"; IconTexture = "Icons/changelog"; } } diff --git a/osu.Game/Overlays/ChangelogOverlay.cs b/osu.Game/Overlays/ChangelogOverlay.cs index 726be9e194..e9520906ea 100644 --- a/osu.Game/Overlays/ChangelogOverlay.cs +++ b/osu.Game/Overlays/ChangelogOverlay.cs @@ -25,10 +25,10 @@ namespace osu.Game.Overlays { public readonly Bindable Current = new Bindable(); - protected ChangelogHeader Header; - private Container content; + protected new ChangelogHeader Header; + private SampleChannel sampleBack; private List builds; @@ -61,9 +61,10 @@ namespace osu.Game.Overlays Direction = FillDirection.Vertical, Children = new Drawable[] { - Header = new ChangelogHeader + base.Header = Header = new ChangelogHeader { ListingSelected = ShowListing, + Build = { BindTarget = Current } }, content = new Container { @@ -77,8 +78,6 @@ namespace osu.Game.Overlays sampleBack = audio.Samples.Get(@"UI/generic-select-soft"); - Header.Build.BindTo(Current); - Current.BindValueChanged(e => { if (e.NewValue != null) diff --git a/osu.Game/Overlays/ChatOverlay.cs b/osu.Game/Overlays/ChatOverlay.cs index 692175603c..8e34f5d2c0 100644 --- a/osu.Game/Overlays/ChatOverlay.cs +++ b/osu.Game/Overlays/ChatOverlay.cs @@ -26,8 +26,12 @@ using osu.Framework.Graphics.Sprites; namespace osu.Game.Overlays { - public class ChatOverlay : OsuFocusedOverlayContainer + public class ChatOverlay : OsuFocusedOverlayContainer, INamedOverlayComponent { + public string IconTexture => "Icons/chat"; + public string Title => "Chat"; + public string Description => "Join the real-time discussion"; + private const float textbox_height = 60; private const float channel_selection_min_height = 0.3f; diff --git a/osu.Game/Overlays/Dashboard/DashboardOverlayHeader.cs b/osu.Game/Overlays/Dashboard/DashboardOverlayHeader.cs index 9ee679a866..1330a44374 100644 --- a/osu.Game/Overlays/Dashboard/DashboardOverlayHeader.cs +++ b/osu.Game/Overlays/Dashboard/DashboardOverlayHeader.cs @@ -12,7 +12,8 @@ namespace osu.Game.Overlays.Dashboard public DashboardTitle() { Title = "dashboard"; - IconTexture = "Icons/changelog"; + Description = "View your friends and other top level information"; + IconTexture = "Icons/hexacons/dashboard"; } } } diff --git a/osu.Game/Overlays/DashboardOverlay.cs b/osu.Game/Overlays/DashboardOverlay.cs index e3a4b0e152..68eb35c7da 100644 --- a/osu.Game/Overlays/DashboardOverlay.cs +++ b/osu.Game/Overlays/DashboardOverlay.cs @@ -50,7 +50,7 @@ namespace osu.Game.Overlays Direction = FillDirection.Vertical, Children = new Drawable[] { - header = new DashboardOverlayHeader + Header = header = new DashboardOverlayHeader { Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, diff --git a/osu.Game/Overlays/FullscreenOverlay.cs b/osu.Game/Overlays/FullscreenOverlay.cs index 3464ce6086..6d0441ff46 100644 --- a/osu.Game/Overlays/FullscreenOverlay.cs +++ b/osu.Game/Overlays/FullscreenOverlay.cs @@ -12,8 +12,14 @@ using osuTK.Graphics; namespace osu.Game.Overlays { - public abstract class FullscreenOverlay : WaveOverlayContainer, IOnlineComponent + public abstract class FullscreenOverlay : WaveOverlayContainer, IOnlineComponent, INamedOverlayComponent { + public virtual string IconTexture => Header?.Title.IconTexture ?? string.Empty; + public virtual string Title => Header?.Title.Title ?? string.Empty; + public virtual string Description => Header?.Title.Description ?? string.Empty; + + public OverlayHeader Header { get; protected set; } + [Resolved] protected IAPIProvider API { get; private set; } diff --git a/osu.Game/Overlays/INamedOverlayComponent.cs b/osu.Game/Overlays/INamedOverlayComponent.cs new file mode 100644 index 0000000000..38fb8679a0 --- /dev/null +++ b/osu.Game/Overlays/INamedOverlayComponent.cs @@ -0,0 +1,14 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +namespace osu.Game.Overlays +{ + public interface INamedOverlayComponent + { + string IconTexture { get; } + + string Title { get; } + + string Description { get; } + } +} diff --git a/osu.Game/Overlays/News/NewsHeader.cs b/osu.Game/Overlays/News/NewsHeader.cs index ddada2bdaf..f85d765d46 100644 --- a/osu.Game/Overlays/News/NewsHeader.cs +++ b/osu.Game/Overlays/News/NewsHeader.cs @@ -57,6 +57,7 @@ namespace osu.Game.Overlays.News public NewsHeaderTitle() { Title = "news"; + Description = "Get up-to-date on community happenings"; IconTexture = "Icons/news"; } } diff --git a/osu.Game/Overlays/NewsOverlay.cs b/osu.Game/Overlays/NewsOverlay.cs index 09fb445b1f..bc3e080158 100644 --- a/osu.Game/Overlays/NewsOverlay.cs +++ b/osu.Game/Overlays/NewsOverlay.cs @@ -19,7 +19,6 @@ namespace osu.Game.Overlays private Container content; private LoadingLayer loading; - private NewsHeader header; private OverlayScrollContainer scrollFlow; public NewsOverlay() @@ -48,7 +47,7 @@ namespace osu.Game.Overlays Direction = FillDirection.Vertical, Children = new Drawable[] { - header = new NewsHeader + Header = new NewsHeader { ShowFrontPage = ShowFrontPage }, @@ -110,6 +109,8 @@ namespace osu.Game.Overlays cancellationToken?.Cancel(); loading.Show(); + var header = (NewsHeader)Header; + if (e.NewValue == null) { header.SetFrontPage(); diff --git a/osu.Game/Overlays/NotificationOverlay.cs b/osu.Game/Overlays/NotificationOverlay.cs index 41160d10ec..6bdacb9c5e 100644 --- a/osu.Game/Overlays/NotificationOverlay.cs +++ b/osu.Game/Overlays/NotificationOverlay.cs @@ -16,8 +16,12 @@ using osu.Framework.Threading; namespace osu.Game.Overlays { - public class NotificationOverlay : OsuFocusedOverlayContainer + public class NotificationOverlay : OsuFocusedOverlayContainer, INamedOverlayComponent { + public string IconTexture => "Icons/Hexacons/"; + public string Title => "Notifications"; + public string Description => "Waiting for 'ya"; + private const float width = 320; public const float TRANSITION_LENGTH = 600; diff --git a/osu.Game/Overlays/NowPlayingOverlay.cs b/osu.Game/Overlays/NowPlayingOverlay.cs index af692486b7..f19f7bbc61 100644 --- a/osu.Game/Overlays/NowPlayingOverlay.cs +++ b/osu.Game/Overlays/NowPlayingOverlay.cs @@ -25,8 +25,12 @@ using osuTK.Graphics; namespace osu.Game.Overlays { - public class NowPlayingOverlay : OsuFocusedOverlayContainer + public class NowPlayingOverlay : OsuFocusedOverlayContainer, INamedOverlayComponent { + public string IconTexture => "Icons/Hexacons/music"; + public string Title => "Now playing"; + public string Description => "Manage the currently playing track"; + private const float player_height = 130; private const float transition_length = 800; private const float progress_height = 10; diff --git a/osu.Game/Overlays/OverlayHeader.cs b/osu.Game/Overlays/OverlayHeader.cs index cc7f798c4a..fed1e57686 100644 --- a/osu.Game/Overlays/OverlayHeader.cs +++ b/osu.Game/Overlays/OverlayHeader.cs @@ -12,6 +12,8 @@ namespace osu.Game.Overlays { public abstract class OverlayHeader : Container { + public OverlayTitle Title { get; } + private float contentSidePadding; /// @@ -73,7 +75,7 @@ namespace osu.Game.Overlays AutoSizeAxes = Axes.Y, Children = new[] { - CreateTitle().With(title => + Title = CreateTitle().With(title => { title.Anchor = Anchor.CentreLeft; title.Origin = Anchor.CentreLeft; diff --git a/osu.Game/Overlays/OverlayTitle.cs b/osu.Game/Overlays/OverlayTitle.cs index 1c9567428c..17eeece1f8 100644 --- a/osu.Game/Overlays/OverlayTitle.cs +++ b/osu.Game/Overlays/OverlayTitle.cs @@ -12,19 +12,27 @@ using osuTK; namespace osu.Game.Overlays { - public abstract class OverlayTitle : CompositeDrawable + public abstract class OverlayTitle : CompositeDrawable, INamedOverlayComponent { - private readonly OsuSpriteText title; + private readonly OsuSpriteText titleText; private readonly Container icon; - protected string Title + private string title; + + public string Title { - set => title.Text = value; + get => title; + protected set => titleText.Text = title = value; } - protected string IconTexture + public string Description { get; protected set; } + + private string iconTexture; + + public string IconTexture { - set => icon.Child = new OverlayTitleIcon(value); + get => iconTexture; + protected set => icon.Child = new OverlayTitleIcon(iconTexture = value); } protected OverlayTitle() @@ -45,7 +53,7 @@ namespace osu.Game.Overlays Margin = new MarginPadding { Horizontal = 5 }, // compensates for osu-web sprites having around 5px of whitespace on each side Size = new Vector2(30) }, - title = new OsuSpriteText + titleText = new OsuSpriteText { Anchor = Anchor.Centre, Origin = Anchor.Centre, diff --git a/osu.Game/Overlays/Rankings/RankingsOverlayHeader.cs b/osu.Game/Overlays/Rankings/RankingsOverlayHeader.cs index e30c6f07a8..b12294c6c1 100644 --- a/osu.Game/Overlays/Rankings/RankingsOverlayHeader.cs +++ b/osu.Game/Overlays/Rankings/RankingsOverlayHeader.cs @@ -30,6 +30,7 @@ namespace osu.Game.Overlays.Rankings public RankingsTitle() { Title = "ranking"; + Description = "Find out who's the best right now"; IconTexture = "Icons/rankings"; } } diff --git a/osu.Game/Overlays/RankingsOverlay.cs b/osu.Game/Overlays/RankingsOverlay.cs index 7b200d4226..6e8a7d8554 100644 --- a/osu.Game/Overlays/RankingsOverlay.cs +++ b/osu.Game/Overlays/RankingsOverlay.cs @@ -55,7 +55,7 @@ namespace osu.Game.Overlays Direction = FillDirection.Vertical, Children = new Drawable[] { - header = new RankingsOverlayHeader + Header = header = new RankingsOverlayHeader { Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, diff --git a/osu.Game/Overlays/SearchableList/SearchableListOverlay.cs b/osu.Game/Overlays/SearchableList/SearchableListOverlay.cs index 4ab2de06b6..da2066e677 100644 --- a/osu.Game/Overlays/SearchableList/SearchableListOverlay.cs +++ b/osu.Game/Overlays/SearchableList/SearchableListOverlay.cs @@ -29,7 +29,7 @@ namespace osu.Game.Overlays.SearchableList { private readonly Container scrollContainer; - protected readonly SearchableListHeader Header; + protected new readonly SearchableListHeader Header; protected readonly SearchableListFilterControl Filter; protected readonly FillFlowContainer ScrollFlow; diff --git a/osu.Game/Overlays/SettingsOverlay.cs b/osu.Game/Overlays/SettingsOverlay.cs index bb84de5d3a..9a7937dfce 100644 --- a/osu.Game/Overlays/SettingsOverlay.cs +++ b/osu.Game/Overlays/SettingsOverlay.cs @@ -13,8 +13,12 @@ using osu.Framework.Bindables; namespace osu.Game.Overlays { - public class SettingsOverlay : SettingsPanel + public class SettingsOverlay : SettingsPanel, INamedOverlayComponent { + public string IconTexture => "Icons/Hexacons/settings"; + public string Title => "Settings"; + public string Description => "Change your settings"; + protected override IEnumerable CreateSections() => new SettingsSection[] { new GeneralSection(), diff --git a/osu.Game/Overlays/Toolbar/ToolbarBeatmapListingButton.cs b/osu.Game/Overlays/Toolbar/ToolbarBeatmapListingButton.cs index cde305fffd..0363873326 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarBeatmapListingButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarBeatmapListingButton.cs @@ -2,7 +2,6 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Allocation; -using osu.Game.Graphics; using osu.Game.Input.Bindings; namespace osu.Game.Overlays.Toolbar @@ -11,10 +10,6 @@ namespace osu.Game.Overlays.Toolbar { public ToolbarBeatmapListingButton() { - SetIcon(OsuIcon.ChevronDownCircle); - TooltipMain = "Beatmap listing"; - TooltipSub = "Browse for new beatmaps"; - Hotkey = GlobalAction.ToggleDirect; } diff --git a/osu.Game/Overlays/Toolbar/ToolbarButton.cs b/osu.Game/Overlays/Toolbar/ToolbarButton.cs index 0afc6642b2..5d402c9a23 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarButton.cs @@ -35,17 +35,6 @@ namespace osu.Game.Overlays.Toolbar IconContainer.Show(); } - public void SetIcon(IconUsage icon) => SetIcon(new SpriteIcon - { - Size = new Vector2(20), - Icon = icon - }); - - public IconUsage Icon - { - set => SetIcon(value); - } - public string Text { get => DrawableText.Text; diff --git a/osu.Game/Overlays/Toolbar/ToolbarChangelogButton.cs b/osu.Game/Overlays/Toolbar/ToolbarChangelogButton.cs index c88b418853..23f8b141b2 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarChangelogButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarChangelogButton.cs @@ -2,19 +2,11 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Allocation; -using osu.Framework.Graphics.Sprites; namespace osu.Game.Overlays.Toolbar { public class ToolbarChangelogButton : ToolbarOverlayToggleButton { - public ToolbarChangelogButton() - { - SetIcon(FontAwesome.Solid.Bullhorn); - TooltipMain = "Changelog"; - TooltipSub = "Track recent dev updates in the osu! ecosystem"; - } - [BackgroundDependencyLoader(true)] private void load(ChangelogOverlay changelog) { diff --git a/osu.Game/Overlays/Toolbar/ToolbarChatButton.cs b/osu.Game/Overlays/Toolbar/ToolbarChatButton.cs index dee4be0c1f..f9a66ae7bb 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarChatButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarChatButton.cs @@ -2,7 +2,6 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Allocation; -using osu.Framework.Graphics.Sprites; using osu.Game.Input.Bindings; namespace osu.Game.Overlays.Toolbar @@ -11,10 +10,6 @@ namespace osu.Game.Overlays.Toolbar { public ToolbarChatButton() { - SetIcon(FontAwesome.Solid.Comments); - TooltipMain = "Chat"; - TooltipSub = "Join the real-time discussion"; - Hotkey = GlobalAction.ToggleChat; } diff --git a/osu.Game/Overlays/Toolbar/ToolbarHomeButton.cs b/osu.Game/Overlays/Toolbar/ToolbarHomeButton.cs index 4845c9a99f..08ba65fc47 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarHomeButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarHomeButton.cs @@ -1,7 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using osu.Framework.Graphics.Sprites; using osu.Game.Input.Bindings; namespace osu.Game.Overlays.Toolbar @@ -10,7 +9,7 @@ namespace osu.Game.Overlays.Toolbar { public ToolbarHomeButton() { - Icon = FontAwesome.Solid.Home; + // todo: icon TooltipMain = "Home"; TooltipSub = "Return to the main menu"; diff --git a/osu.Game/Overlays/Toolbar/ToolbarMusicButton.cs b/osu.Game/Overlays/Toolbar/ToolbarMusicButton.cs index f9aa2de497..0f5e8e5456 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarMusicButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarMusicButton.cs @@ -3,7 +3,6 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; -using osu.Framework.Graphics.Sprites; using osu.Game.Input.Bindings; namespace osu.Game.Overlays.Toolbar @@ -14,10 +13,6 @@ namespace osu.Game.Overlays.Toolbar public ToolbarMusicButton() { - Icon = FontAwesome.Solid.Music; - TooltipMain = "Now playing"; - TooltipSub = "Manage the currently playing track"; - Hotkey = GlobalAction.ToggleNowPlaying; } diff --git a/osu.Game/Overlays/Toolbar/ToolbarNewsButton.cs b/osu.Game/Overlays/Toolbar/ToolbarNewsButton.cs index 106c67a041..0ba2935c80 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarNewsButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarNewsButton.cs @@ -2,19 +2,11 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Allocation; -using osu.Framework.Graphics.Sprites; namespace osu.Game.Overlays.Toolbar { public class ToolbarNewsButton : ToolbarOverlayToggleButton { - public ToolbarNewsButton() - { - Icon = FontAwesome.Solid.Newspaper; - TooltipMain = "News"; - TooltipSub = "Get up-to-date on community happenings"; - } - [BackgroundDependencyLoader(true)] private void load(NewsOverlay news) { diff --git a/osu.Game/Overlays/Toolbar/ToolbarNotificationButton.cs b/osu.Game/Overlays/Toolbar/ToolbarNotificationButton.cs index a699fd907f..79d0fc74c1 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarNotificationButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarNotificationButton.cs @@ -6,7 +6,6 @@ using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; -using osu.Framework.Graphics.Sprites; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Input.Bindings; @@ -25,10 +24,6 @@ namespace osu.Game.Overlays.Toolbar public ToolbarNotificationButton() { - Icon = FontAwesome.Solid.Bars; - TooltipMain = "Notifications"; - TooltipSub = "Waiting for 'ya"; - Hotkey = GlobalAction.ToggleNotifications; Add(countDisplay = new CountCircle diff --git a/osu.Game/Overlays/Toolbar/ToolbarOverlayToggleButton.cs b/osu.Game/Overlays/Toolbar/ToolbarOverlayToggleButton.cs index 36387bb00d..a76ca26a47 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarOverlayToggleButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarOverlayToggleButton.cs @@ -1,11 +1,14 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Graphics.Textures; using osu.Game.Graphics; namespace osu.Game.Overlays.Toolbar @@ -18,6 +21,9 @@ namespace osu.Game.Overlays.Toolbar private readonly Bindable overlayState = new Bindable(); + [Resolved] + private TextureStore textures { get; set; } + public OverlayContainer StateContainer { get => stateContainer; @@ -32,6 +38,16 @@ namespace osu.Game.Overlays.Toolbar Action = stateContainer.ToggleVisibility; overlayState.BindTo(stateContainer.State); } + + if (stateContainer is INamedOverlayComponent named) + { + TooltipMain = named.Title; + TooltipSub = named.Description; + SetIcon(new Sprite + { + Texture = textures.Get(named.IconTexture), + }); + } } } diff --git a/osu.Game/Overlays/Toolbar/ToolbarRankingsButton.cs b/osu.Game/Overlays/Toolbar/ToolbarRankingsButton.cs index c026ce99fe..22a01bcdb5 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarRankingsButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarRankingsButton.cs @@ -2,19 +2,11 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Allocation; -using osu.Framework.Graphics.Sprites; namespace osu.Game.Overlays.Toolbar { public class ToolbarRankingsButton : ToolbarOverlayToggleButton { - public ToolbarRankingsButton() - { - SetIcon(FontAwesome.Regular.ChartBar); - TooltipMain = "Ranking"; - TooltipSub = "Find out who's the best right now"; - } - [BackgroundDependencyLoader(true)] private void load(RankingsOverlay rankings) { diff --git a/osu.Game/Overlays/Toolbar/ToolbarSettingsButton.cs b/osu.Game/Overlays/Toolbar/ToolbarSettingsButton.cs index ed2a23ec2a..4051a2a194 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarSettingsButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarSettingsButton.cs @@ -2,7 +2,6 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Allocation; -using osu.Framework.Graphics.Sprites; using osu.Game.Input.Bindings; namespace osu.Game.Overlays.Toolbar @@ -11,10 +10,6 @@ namespace osu.Game.Overlays.Toolbar { public ToolbarSettingsButton() { - Icon = FontAwesome.Solid.Cog; - TooltipMain = "Settings"; - TooltipSub = "Change your settings"; - Hotkey = GlobalAction.ToggleSettings; } diff --git a/osu.Game/Overlays/Toolbar/ToolbarSocialButton.cs b/osu.Game/Overlays/Toolbar/ToolbarSocialButton.cs index 6faa58c559..e62c7bc807 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarSocialButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarSocialButton.cs @@ -2,7 +2,6 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Allocation; -using osu.Framework.Graphics.Sprites; using osu.Game.Input.Bindings; namespace osu.Game.Overlays.Toolbar @@ -11,10 +10,6 @@ namespace osu.Game.Overlays.Toolbar { public ToolbarSocialButton() { - Icon = FontAwesome.Solid.Users; - TooltipMain = "Friends"; - TooltipSub = "Interact with those close to you"; - Hotkey = GlobalAction.ToggleSocial; } diff --git a/osu.Game/Overlays/UserProfileOverlay.cs b/osu.Game/Overlays/UserProfileOverlay.cs index b4c8a2d3ca..625758614e 100644 --- a/osu.Game/Overlays/UserProfileOverlay.cs +++ b/osu.Game/Overlays/UserProfileOverlay.cs @@ -22,7 +22,7 @@ namespace osu.Game.Overlays private ProfileSection lastSection; private ProfileSection[] sections; private GetUserRequest userReq; - protected ProfileHeader Header; + protected new ProfileHeader Header; private ProfileSectionsContainer sectionsContainer; private ProfileSectionTabControl tabs; @@ -77,7 +77,7 @@ namespace osu.Game.Overlays Add(sectionsContainer = new ProfileSectionsContainer { - ExpandableHeader = Header = new ProfileHeader(), + ExpandableHeader = base.Header = Header = new ProfileHeader(), FixedHeader = tabs, HeaderBackground = new Box { From dbf44fbaf265b2bf7142e57370e5764d7f7269ca Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 3 Sep 2020 16:26:09 +0900 Subject: [PATCH 425/434] Update names and icons to match new designs --- osu.Game/Overlays/BeatmapSet/BeatmapSetHeader.cs | 2 +- osu.Game/Overlays/Changelog/ChangelogHeader.cs | 2 +- osu.Game/Overlays/ChatOverlay.cs | 4 ++-- osu.Game/Overlays/Dashboard/DashboardOverlayHeader.cs | 4 ++-- osu.Game/Overlays/News/NewsHeader.cs | 2 +- osu.Game/Overlays/NowPlayingOverlay.cs | 2 +- osu.Game/Overlays/Profile/ProfileHeader.cs | 2 +- osu.Game/Overlays/Rankings/RankingsOverlayHeader.cs | 2 +- 8 files changed, 10 insertions(+), 10 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/BeatmapSetHeader.cs b/osu.Game/Overlays/BeatmapSet/BeatmapSetHeader.cs index 4626589d81..329045c743 100644 --- a/osu.Game/Overlays/BeatmapSet/BeatmapSetHeader.cs +++ b/osu.Game/Overlays/BeatmapSet/BeatmapSetHeader.cs @@ -25,7 +25,7 @@ namespace osu.Game.Overlays.BeatmapSet public BeatmapHeaderTitle() { Title = "beatmap info"; - IconTexture = "Icons/changelog"; + IconTexture = "Icons/Hexacons/music"; } } } diff --git a/osu.Game/Overlays/Changelog/ChangelogHeader.cs b/osu.Game/Overlays/Changelog/ChangelogHeader.cs index 35a4fc7014..bdc59297bb 100644 --- a/osu.Game/Overlays/Changelog/ChangelogHeader.cs +++ b/osu.Game/Overlays/Changelog/ChangelogHeader.cs @@ -116,7 +116,7 @@ namespace osu.Game.Overlays.Changelog { Title = "changelog"; Description = "Track recent dev updates in the osu! ecosystem"; - IconTexture = "Icons/changelog"; + IconTexture = "Icons/Hexacons/devtools"; } } } diff --git a/osu.Game/Overlays/ChatOverlay.cs b/osu.Game/Overlays/ChatOverlay.cs index 8e34f5d2c0..bcc2227be8 100644 --- a/osu.Game/Overlays/ChatOverlay.cs +++ b/osu.Game/Overlays/ChatOverlay.cs @@ -28,8 +28,8 @@ namespace osu.Game.Overlays { public class ChatOverlay : OsuFocusedOverlayContainer, INamedOverlayComponent { - public string IconTexture => "Icons/chat"; - public string Title => "Chat"; + public string IconTexture => "Icons/Hexacons/messaging"; + public string Title => "chat"; public string Description => "Join the real-time discussion"; private const float textbox_height = 60; diff --git a/osu.Game/Overlays/Dashboard/DashboardOverlayHeader.cs b/osu.Game/Overlays/Dashboard/DashboardOverlayHeader.cs index 1330a44374..a964d84c4f 100644 --- a/osu.Game/Overlays/Dashboard/DashboardOverlayHeader.cs +++ b/osu.Game/Overlays/Dashboard/DashboardOverlayHeader.cs @@ -12,8 +12,8 @@ namespace osu.Game.Overlays.Dashboard public DashboardTitle() { Title = "dashboard"; - Description = "View your friends and other top level information"; - IconTexture = "Icons/hexacons/dashboard"; + Description = "View your friends and other information"; + IconTexture = "Icons/Hexacons/social"; } } } diff --git a/osu.Game/Overlays/News/NewsHeader.cs b/osu.Game/Overlays/News/NewsHeader.cs index f85d765d46..38ac519387 100644 --- a/osu.Game/Overlays/News/NewsHeader.cs +++ b/osu.Game/Overlays/News/NewsHeader.cs @@ -58,7 +58,7 @@ namespace osu.Game.Overlays.News { Title = "news"; Description = "Get up-to-date on community happenings"; - IconTexture = "Icons/news"; + IconTexture = "Icons/Hexacons/news"; } } } diff --git a/osu.Game/Overlays/NowPlayingOverlay.cs b/osu.Game/Overlays/NowPlayingOverlay.cs index f19f7bbc61..d1df1fa936 100644 --- a/osu.Game/Overlays/NowPlayingOverlay.cs +++ b/osu.Game/Overlays/NowPlayingOverlay.cs @@ -28,7 +28,7 @@ namespace osu.Game.Overlays public class NowPlayingOverlay : OsuFocusedOverlayContainer, INamedOverlayComponent { public string IconTexture => "Icons/Hexacons/music"; - public string Title => "Now playing"; + public string Title => "now playing"; public string Description => "Manage the currently playing track"; private const float player_height = 130; diff --git a/osu.Game/Overlays/Profile/ProfileHeader.cs b/osu.Game/Overlays/Profile/ProfileHeader.cs index 55474c9d3e..c947ef0781 100644 --- a/osu.Game/Overlays/Profile/ProfileHeader.cs +++ b/osu.Game/Overlays/Profile/ProfileHeader.cs @@ -97,7 +97,7 @@ namespace osu.Game.Overlays.Profile public ProfileHeaderTitle() { Title = "player info"; - IconTexture = "Icons/profile"; + IconTexture = "Icons/Hexacons/profile"; } } diff --git a/osu.Game/Overlays/Rankings/RankingsOverlayHeader.cs b/osu.Game/Overlays/Rankings/RankingsOverlayHeader.cs index b12294c6c1..7039ab8214 100644 --- a/osu.Game/Overlays/Rankings/RankingsOverlayHeader.cs +++ b/osu.Game/Overlays/Rankings/RankingsOverlayHeader.cs @@ -31,7 +31,7 @@ namespace osu.Game.Overlays.Rankings { Title = "ranking"; Description = "Find out who's the best right now"; - IconTexture = "Icons/rankings"; + IconTexture = "Icons/Hexacons/rankings"; } } } From 7bcbac6f45000482ed566b7be6b221eef639d05b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 3 Sep 2020 16:27:31 +0900 Subject: [PATCH 426/434] Move header setting to FullscreenOverlay --- .../Online/TestSceneFullscreenOverlay.cs | 6 ++--- osu.Game/Overlays/BeatmapListingOverlay.cs | 6 ++--- osu.Game/Overlays/BeatmapSetOverlay.cs | 4 ++-- osu.Game/Overlays/ChangelogOverlay.cs | 14 +++++------ osu.Game/Overlays/DashboardOverlay.cs | 23 +++++++++---------- osu.Game/Overlays/FullscreenOverlay.cs | 9 +++++--- osu.Game/Overlays/NewsOverlay.cs | 16 ++++++------- osu.Game/Overlays/OverlayScrollContainer.cs | 2 +- osu.Game/Overlays/OverlayView.cs | 2 +- osu.Game/Overlays/RankingsOverlay.cs | 23 +++++++++---------- osu.Game/Overlays/UserProfileOverlay.cs | 7 +++--- 11 files changed, 54 insertions(+), 58 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneFullscreenOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneFullscreenOverlay.cs index e60adcee34..8f20bcdcc1 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneFullscreenOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneFullscreenOverlay.cs @@ -12,7 +12,7 @@ namespace osu.Game.Tests.Visual.Online [TestFixture] public class TestSceneFullscreenOverlay : OsuTestScene { - private FullscreenOverlay overlay; + private FullscreenOverlay overlay; protected override void LoadComplete() { @@ -38,10 +38,10 @@ namespace osu.Game.Tests.Visual.Online AddAssert("fire count 3", () => fireCount == 3); } - private class TestFullscreenOverlay : FullscreenOverlay + private class TestFullscreenOverlay : FullscreenOverlay { public TestFullscreenOverlay() - : base(OverlayColourScheme.Pink) + : base(OverlayColourScheme.Pink, null) { Children = new Drawable[] { diff --git a/osu.Game/Overlays/BeatmapListingOverlay.cs b/osu.Game/Overlays/BeatmapListingOverlay.cs index 225a8a0578..144af91145 100644 --- a/osu.Game/Overlays/BeatmapListingOverlay.cs +++ b/osu.Game/Overlays/BeatmapListingOverlay.cs @@ -24,7 +24,7 @@ using osuTK; namespace osu.Game.Overlays { - public class BeatmapListingOverlay : FullscreenOverlay + public class BeatmapListingOverlay : FullscreenOverlay { [Resolved] private PreviewTrackManager previewTrackManager { get; set; } @@ -38,7 +38,7 @@ namespace osu.Game.Overlays private OverlayScrollContainer resultScrollContainer; public BeatmapListingOverlay() - : base(OverlayColourScheme.Blue) + : base(OverlayColourScheme.Blue, new BeatmapListingHeader()) { } @@ -65,7 +65,7 @@ namespace osu.Game.Overlays Direction = FillDirection.Vertical, Children = new Drawable[] { - new BeatmapListingHeader(), + Header, filterControl = new BeatmapListingFilterControl { SearchStarted = onSearchStarted, diff --git a/osu.Game/Overlays/BeatmapSetOverlay.cs b/osu.Game/Overlays/BeatmapSetOverlay.cs index 2dfd1fa20f..bbec62a85a 100644 --- a/osu.Game/Overlays/BeatmapSetOverlay.cs +++ b/osu.Game/Overlays/BeatmapSetOverlay.cs @@ -19,7 +19,7 @@ using osuTK; namespace osu.Game.Overlays { - public class BeatmapSetOverlay : FullscreenOverlay + public class BeatmapSetOverlay : FullscreenOverlay // we don't provide a standard header for now. { public const float X_PADDING = 40; public const float Y_PADDING = 25; @@ -39,7 +39,7 @@ namespace osu.Game.Overlays private readonly Box background; public BeatmapSetOverlay() - : base(OverlayColourScheme.Blue) + : base(OverlayColourScheme.Blue, null) { OverlayScrollContainer scroll; Info info; diff --git a/osu.Game/Overlays/ChangelogOverlay.cs b/osu.Game/Overlays/ChangelogOverlay.cs index e9520906ea..c7e9a86fa4 100644 --- a/osu.Game/Overlays/ChangelogOverlay.cs +++ b/osu.Game/Overlays/ChangelogOverlay.cs @@ -21,14 +21,12 @@ using osu.Game.Overlays.Changelog; namespace osu.Game.Overlays { - public class ChangelogOverlay : FullscreenOverlay + public class ChangelogOverlay : FullscreenOverlay { public readonly Bindable Current = new Bindable(); private Container content; - protected new ChangelogHeader Header; - private SampleChannel sampleBack; private List builds; @@ -36,7 +34,7 @@ namespace osu.Game.Overlays protected List Streams; public ChangelogOverlay() - : base(OverlayColourScheme.Purple) + : base(OverlayColourScheme.Purple, new ChangelogHeader()) { } @@ -61,11 +59,11 @@ namespace osu.Game.Overlays Direction = FillDirection.Vertical, Children = new Drawable[] { - base.Header = Header = new ChangelogHeader + Header.With(h => { - ListingSelected = ShowListing, - Build = { BindTarget = Current } - }, + h.ListingSelected = ShowListing; + h.Build.BindTarget = Current; + }), content = new Container { RelativeSizeAxes = Axes.X, diff --git a/osu.Game/Overlays/DashboardOverlay.cs b/osu.Game/Overlays/DashboardOverlay.cs index 68eb35c7da..8135b83a03 100644 --- a/osu.Game/Overlays/DashboardOverlay.cs +++ b/osu.Game/Overlays/DashboardOverlay.cs @@ -15,17 +15,21 @@ using osu.Game.Overlays.Dashboard.Friends; namespace osu.Game.Overlays { - public class DashboardOverlay : FullscreenOverlay + public class DashboardOverlay : FullscreenOverlay { private CancellationTokenSource cancellationToken; private Container content; - private DashboardOverlayHeader header; private LoadingLayer loading; private OverlayScrollContainer scrollFlow; public DashboardOverlay() - : base(OverlayColourScheme.Purple) + : base(OverlayColourScheme.Purple, new DashboardOverlayHeader + { + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + Depth = -float.MaxValue + }) { } @@ -50,12 +54,7 @@ namespace osu.Game.Overlays Direction = FillDirection.Vertical, Children = new Drawable[] { - Header = header = new DashboardOverlayHeader - { - Anchor = Anchor.TopCentre, - Origin = Anchor.TopCentre, - Depth = -float.MaxValue - }, + Header, content = new Container { RelativeSizeAxes = Axes.X, @@ -72,7 +71,7 @@ namespace osu.Game.Overlays { base.LoadComplete(); - header.Current.BindValueChanged(onTabChanged); + Header.Current.BindValueChanged(onTabChanged); } private bool displayUpdateRequired = true; @@ -84,7 +83,7 @@ namespace osu.Game.Overlays // We don't want to create a new display on every call, only when exiting from fully closed state. if (displayUpdateRequired) { - header.Current.TriggerChange(); + Header.Current.TriggerChange(); displayUpdateRequired = false; } } @@ -136,7 +135,7 @@ namespace osu.Game.Overlays if (State.Value == Visibility.Hidden) return; - header.Current.TriggerChange(); + Header.Current.TriggerChange(); } protected override void Dispose(bool isDisposing) diff --git a/osu.Game/Overlays/FullscreenOverlay.cs b/osu.Game/Overlays/FullscreenOverlay.cs index 6d0441ff46..bd6b07c65f 100644 --- a/osu.Game/Overlays/FullscreenOverlay.cs +++ b/osu.Game/Overlays/FullscreenOverlay.cs @@ -12,13 +12,14 @@ using osuTK.Graphics; namespace osu.Game.Overlays { - public abstract class FullscreenOverlay : WaveOverlayContainer, IOnlineComponent, INamedOverlayComponent + public abstract class FullscreenOverlay : WaveOverlayContainer, IOnlineComponent, INamedOverlayComponent + where T : OverlayHeader { public virtual string IconTexture => Header?.Title.IconTexture ?? string.Empty; public virtual string Title => Header?.Title.Title ?? string.Empty; public virtual string Description => Header?.Title.Description ?? string.Empty; - public OverlayHeader Header { get; protected set; } + public T Header { get; } [Resolved] protected IAPIProvider API { get; private set; } @@ -26,8 +27,10 @@ namespace osu.Game.Overlays [Cached] protected readonly OverlayColourProvider ColourProvider; - protected FullscreenOverlay(OverlayColourScheme colourScheme) + protected FullscreenOverlay(OverlayColourScheme colourScheme, T header) { + Header = header; + ColourProvider = new OverlayColourProvider(colourScheme); RelativeSizeAxes = Axes.Both; diff --git a/osu.Game/Overlays/NewsOverlay.cs b/osu.Game/Overlays/NewsOverlay.cs index bc3e080158..c8c1db012f 100644 --- a/osu.Game/Overlays/NewsOverlay.cs +++ b/osu.Game/Overlays/NewsOverlay.cs @@ -13,7 +13,7 @@ using osu.Game.Overlays.News.Displays; namespace osu.Game.Overlays { - public class NewsOverlay : FullscreenOverlay + public class NewsOverlay : FullscreenOverlay { private readonly Bindable article = new Bindable(null); @@ -22,7 +22,7 @@ namespace osu.Game.Overlays private OverlayScrollContainer scrollFlow; public NewsOverlay() - : base(OverlayColourScheme.Purple) + : base(OverlayColourScheme.Purple, new NewsHeader()) { } @@ -47,10 +47,10 @@ namespace osu.Game.Overlays Direction = FillDirection.Vertical, Children = new Drawable[] { - Header = new NewsHeader + Header.With(h => { - ShowFrontPage = ShowFrontPage - }, + h.ShowFrontPage = ShowFrontPage; + }), content = new Container { RelativeSizeAxes = Axes.X, @@ -109,16 +109,14 @@ namespace osu.Game.Overlays cancellationToken?.Cancel(); loading.Show(); - var header = (NewsHeader)Header; - if (e.NewValue == null) { - header.SetFrontPage(); + Header.SetFrontPage(); LoadDisplay(new FrontPageDisplay()); return; } - header.SetArticle(e.NewValue); + Header.SetArticle(e.NewValue); LoadDisplay(Empty()); } diff --git a/osu.Game/Overlays/OverlayScrollContainer.cs b/osu.Game/Overlays/OverlayScrollContainer.cs index e7415e6f74..b67d5db1a4 100644 --- a/osu.Game/Overlays/OverlayScrollContainer.cs +++ b/osu.Game/Overlays/OverlayScrollContainer.cs @@ -17,7 +17,7 @@ using osuTK.Graphics; namespace osu.Game.Overlays { /// - /// which provides . Mostly used in . + /// which provides . Mostly used in . /// public class OverlayScrollContainer : OsuScrollContainer { diff --git a/osu.Game/Overlays/OverlayView.cs b/osu.Game/Overlays/OverlayView.cs index 3e2c54c726..312271316a 100644 --- a/osu.Game/Overlays/OverlayView.cs +++ b/osu.Game/Overlays/OverlayView.cs @@ -9,7 +9,7 @@ using osu.Game.Online.API; namespace osu.Game.Overlays { /// - /// A subview containing online content, to be displayed inside a . + /// A subview containing online content, to be displayed inside a . /// /// /// Automatically performs a data fetch on load. diff --git a/osu.Game/Overlays/RankingsOverlay.cs b/osu.Game/Overlays/RankingsOverlay.cs index 6e8a7d8554..ae6d49960a 100644 --- a/osu.Game/Overlays/RankingsOverlay.cs +++ b/osu.Game/Overlays/RankingsOverlay.cs @@ -17,17 +17,16 @@ using osu.Game.Overlays.Rankings.Tables; namespace osu.Game.Overlays { - public class RankingsOverlay : FullscreenOverlay + public class RankingsOverlay : FullscreenOverlay { - protected Bindable Country => header.Country; + protected Bindable Country => Header.Country; - protected Bindable Scope => header.Current; + protected Bindable Scope => Header.Current; private readonly OverlayScrollContainer scrollFlow; private readonly Container contentContainer; private readonly LoadingLayer loading; private readonly Box background; - private readonly RankingsOverlayHeader header; private APIRequest lastRequest; private CancellationTokenSource cancellationToken; @@ -36,7 +35,12 @@ namespace osu.Game.Overlays private IAPIProvider api { get; set; } public RankingsOverlay() - : base(OverlayColourScheme.Green) + : base(OverlayColourScheme.Green, new RankingsOverlayHeader + { + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + Depth = -float.MaxValue + }) { Children = new Drawable[] { @@ -55,12 +59,7 @@ namespace osu.Game.Overlays Direction = FillDirection.Vertical, Children = new Drawable[] { - Header = header = new RankingsOverlayHeader - { - Anchor = Anchor.TopCentre, - Origin = Anchor.TopCentre, - Depth = -float.MaxValue - }, + Header, new Container { RelativeSizeAxes = Axes.X, @@ -97,7 +96,7 @@ namespace osu.Game.Overlays { base.LoadComplete(); - header.Ruleset.BindTo(ruleset); + Header.Ruleset.BindTo(ruleset); Country.BindValueChanged(_ => { diff --git a/osu.Game/Overlays/UserProfileOverlay.cs b/osu.Game/Overlays/UserProfileOverlay.cs index 625758614e..965ad790ed 100644 --- a/osu.Game/Overlays/UserProfileOverlay.cs +++ b/osu.Game/Overlays/UserProfileOverlay.cs @@ -17,19 +17,18 @@ using osuTK; namespace osu.Game.Overlays { - public class UserProfileOverlay : FullscreenOverlay + public class UserProfileOverlay : FullscreenOverlay { private ProfileSection lastSection; private ProfileSection[] sections; private GetUserRequest userReq; - protected new ProfileHeader Header; private ProfileSectionsContainer sectionsContainer; private ProfileSectionTabControl tabs; public const float CONTENT_X_MARGIN = 70; public UserProfileOverlay() - : base(OverlayColourScheme.Pink) + : base(OverlayColourScheme.Pink, new ProfileHeader()) { } @@ -77,7 +76,7 @@ namespace osu.Game.Overlays Add(sectionsContainer = new ProfileSectionsContainer { - ExpandableHeader = base.Header = Header = new ProfileHeader(), + ExpandableHeader = Header, FixedHeader = tabs, HeaderBackground = new Box { From 942276d88f10e83fb8eb1ddb4894583f94876a0f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 3 Sep 2020 16:28:14 +0900 Subject: [PATCH 427/434] Remove outdated SearchableList classes --- .../Chat/Selection/ChannelSelectionOverlay.cs | 2 +- .../SearchableListFilterControl.cs | 2 +- .../SearchableList/SearchableListHeader.cs | 82 ----------- .../SearchableList/SearchableListOverlay.cs | 128 ------------------ osu.Game/Overlays/WaveOverlayContainer.cs | 2 + osu.Game/Screens/Multi/Header.cs | 4 +- .../Screens/Multi/Lounge/LoungeSubScreen.cs | 5 +- .../Match/Components/MatchSettingsOverlay.cs | 4 +- 8 files changed, 10 insertions(+), 219 deletions(-) delete mode 100644 osu.Game/Overlays/SearchableList/SearchableListHeader.cs delete mode 100644 osu.Game/Overlays/SearchableList/SearchableListOverlay.cs diff --git a/osu.Game/Overlays/Chat/Selection/ChannelSelectionOverlay.cs b/osu.Game/Overlays/Chat/Selection/ChannelSelectionOverlay.cs index b46ca6b040..be9ecc6746 100644 --- a/osu.Game/Overlays/Chat/Selection/ChannelSelectionOverlay.cs +++ b/osu.Game/Overlays/Chat/Selection/ChannelSelectionOverlay.cs @@ -22,7 +22,7 @@ namespace osu.Game.Overlays.Chat.Selection { public class ChannelSelectionOverlay : WaveOverlayContainer { - public const float WIDTH_PADDING = 170; + public new const float WIDTH_PADDING = 170; private const float transition_duration = 500; diff --git a/osu.Game/Overlays/SearchableList/SearchableListFilterControl.cs b/osu.Game/Overlays/SearchableList/SearchableListFilterControl.cs index e0163b5b0c..1990674aa9 100644 --- a/osu.Game/Overlays/SearchableList/SearchableListFilterControl.cs +++ b/osu.Game/Overlays/SearchableList/SearchableListFilterControl.cs @@ -36,7 +36,7 @@ namespace osu.Game.Overlays.SearchableList /// /// The amount of padding added to content (does not affect background or tab control strip). /// - protected virtual float ContentHorizontalPadding => SearchableListOverlay.WIDTH_PADDING; + protected virtual float ContentHorizontalPadding => WaveOverlayContainer.WIDTH_PADDING; protected SearchableListFilterControl() { diff --git a/osu.Game/Overlays/SearchableList/SearchableListHeader.cs b/osu.Game/Overlays/SearchableList/SearchableListHeader.cs deleted file mode 100644 index 66fedf0a56..0000000000 --- a/osu.Game/Overlays/SearchableList/SearchableListHeader.cs +++ /dev/null @@ -1,82 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using System; -using osuTK; -using osuTK.Graphics; -using osu.Framework.Allocation; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Game.Graphics; -using osu.Framework.Graphics.Shapes; -using osu.Framework.Graphics.Sprites; - -namespace osu.Game.Overlays.SearchableList -{ - public abstract class SearchableListHeader : Container - where T : struct, Enum - { - public readonly HeaderTabControl Tabs; - - protected abstract Color4 BackgroundColour { get; } - protected abstract T DefaultTab { get; } - protected abstract Drawable CreateHeaderText(); - protected abstract IconUsage Icon { get; } - - protected SearchableListHeader() - { - RelativeSizeAxes = Axes.X; - Height = 90; - - Children = new Drawable[] - { - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = BackgroundColour, - }, - new Container - { - RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding { Left = SearchableListOverlay.WIDTH_PADDING, Right = SearchableListOverlay.WIDTH_PADDING }, - Children = new Drawable[] - { - new FillFlowContainer - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.BottomLeft, - Position = new Vector2(-35f, 5f), - AutoSizeAxes = Axes.Both, - Direction = FillDirection.Horizontal, - Spacing = new Vector2(10f, 0f), - Children = new[] - { - new SpriteIcon - { - Size = new Vector2(25), - Icon = Icon, - }, - CreateHeaderText(), - }, - }, - Tabs = new HeaderTabControl - { - Anchor = Anchor.BottomLeft, - Origin = Anchor.BottomLeft, - RelativeSizeAxes = Axes.X, - }, - }, - }, - }; - - Tabs.Current.Value = DefaultTab; - Tabs.Current.TriggerChange(); - } - - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { - Tabs.StripColour = colours.Green; - } - } -} diff --git a/osu.Game/Overlays/SearchableList/SearchableListOverlay.cs b/osu.Game/Overlays/SearchableList/SearchableListOverlay.cs deleted file mode 100644 index da2066e677..0000000000 --- a/osu.Game/Overlays/SearchableList/SearchableListOverlay.cs +++ /dev/null @@ -1,128 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using System; -using osuTK.Graphics; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Shapes; -using osu.Framework.Input.Events; -using osu.Game.Graphics.Backgrounds; -using osu.Game.Graphics.Cursor; - -namespace osu.Game.Overlays.SearchableList -{ - public abstract class SearchableListOverlay : FullscreenOverlay - { - public const float WIDTH_PADDING = 80; - - protected SearchableListOverlay(OverlayColourScheme colourScheme) - : base(colourScheme) - { - } - } - - public abstract class SearchableListOverlay : SearchableListOverlay - where THeader : struct, Enum - where TTab : struct, Enum - where TCategory : struct, Enum - { - private readonly Container scrollContainer; - - protected new readonly SearchableListHeader Header; - protected readonly SearchableListFilterControl Filter; - protected readonly FillFlowContainer ScrollFlow; - - protected abstract Color4 BackgroundColour { get; } - protected abstract Color4 TrianglesColourLight { get; } - protected abstract Color4 TrianglesColourDark { get; } - protected abstract SearchableListHeader CreateHeader(); - protected abstract SearchableListFilterControl CreateFilterControl(); - - protected SearchableListOverlay(OverlayColourScheme colourScheme) - : base(colourScheme) - { - Children = new Drawable[] - { - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = BackgroundColour, - }, - new Container - { - RelativeSizeAxes = Axes.Both, - Masking = true, - Children = new[] - { - new Triangles - { - RelativeSizeAxes = Axes.Both, - TriangleScale = 5, - ColourLight = TrianglesColourLight, - ColourDark = TrianglesColourDark, - }, - }, - }, - scrollContainer = new Container - { - RelativeSizeAxes = Axes.Both, - Child = new OsuContextMenuContainer - { - RelativeSizeAxes = Axes.Both, - Masking = true, - Child = new OverlayScrollContainer - { - RelativeSizeAxes = Axes.Both, - ScrollbarVisible = false, - Child = ScrollFlow = new FillFlowContainer - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Padding = new MarginPadding { Horizontal = 10, Bottom = 50 }, - Direction = FillDirection.Vertical, - }, - }, - }, - }, - new FillFlowContainer - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Direction = FillDirection.Vertical, - Children = new Drawable[] - { - Header = CreateHeader(), - Filter = CreateFilterControl(), - }, - }, - }; - } - - protected override void Update() - { - base.Update(); - - scrollContainer.Padding = new MarginPadding { Top = Header.Height + Filter.Height }; - } - - protected override void OnFocus(FocusEvent e) - { - Filter.Search.TakeFocus(); - } - - protected override void PopIn() - { - base.PopIn(); - - Filter.Search.HoldFocus = true; - } - - protected override void PopOut() - { - base.PopOut(); - - Filter.Search.HoldFocus = false; - } - } -} diff --git a/osu.Game/Overlays/WaveOverlayContainer.cs b/osu.Game/Overlays/WaveOverlayContainer.cs index 5c87096dd4..d0fa9987d5 100644 --- a/osu.Game/Overlays/WaveOverlayContainer.cs +++ b/osu.Game/Overlays/WaveOverlayContainer.cs @@ -14,6 +14,8 @@ namespace osu.Game.Overlays protected override bool BlockNonPositionalInput => true; protected override Container Content => Waves; + public const float WIDTH_PADDING = 80; + protected override bool StartHidden => true; protected WaveOverlayContainer() diff --git a/osu.Game/Screens/Multi/Header.cs b/osu.Game/Screens/Multi/Header.cs index 653cb3791a..cd8695286b 100644 --- a/osu.Game/Screens/Multi/Header.cs +++ b/osu.Game/Screens/Multi/Header.cs @@ -11,8 +11,8 @@ using osu.Framework.Graphics.UserInterface; using osu.Framework.Screens; using osu.Game.Graphics; using osu.Game.Graphics.UserInterface; -using osu.Game.Overlays.SearchableList; using osu.Game.Graphics.Sprites; +using osu.Game.Overlays; using osuTK; using osuTK.Graphics; @@ -42,7 +42,7 @@ namespace osu.Game.Screens.Multi Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding { Left = SearchableListOverlay.WIDTH_PADDING + OsuScreen.HORIZONTAL_OVERFLOW_PADDING }, + Padding = new MarginPadding { Left = WaveOverlayContainer.WIDTH_PADDING + OsuScreen.HORIZONTAL_OVERFLOW_PADDING }, Children = new Drawable[] { title = new MultiHeaderTitle diff --git a/osu.Game/Screens/Multi/Lounge/LoungeSubScreen.cs b/osu.Game/Screens/Multi/Lounge/LoungeSubScreen.cs index f9c5fd13a4..a1e99c83b2 100644 --- a/osu.Game/Screens/Multi/Lounge/LoungeSubScreen.cs +++ b/osu.Game/Screens/Multi/Lounge/LoungeSubScreen.cs @@ -12,7 +12,6 @@ using osu.Game.Graphics.Containers; using osu.Game.Graphics.UserInterface; using osu.Game.Online.Multiplayer; using osu.Game.Overlays; -using osu.Game.Overlays.SearchableList; using osu.Game.Screens.Multi.Lounge.Components; using osu.Game.Screens.Multi.Match; @@ -102,8 +101,8 @@ namespace osu.Game.Screens.Multi.Lounge content.Padding = new MarginPadding { Top = Filter.DrawHeight, - Left = SearchableListOverlay.WIDTH_PADDING - DrawableRoom.SELECTION_BORDER_WIDTH + HORIZONTAL_OVERFLOW_PADDING, - Right = SearchableListOverlay.WIDTH_PADDING + HORIZONTAL_OVERFLOW_PADDING, + Left = WaveOverlayContainer.WIDTH_PADDING - DrawableRoom.SELECTION_BORDER_WIDTH + HORIZONTAL_OVERFLOW_PADDING, + Right = WaveOverlayContainer.WIDTH_PADDING + HORIZONTAL_OVERFLOW_PADDING, }; } diff --git a/osu.Game/Screens/Multi/Match/Components/MatchSettingsOverlay.cs b/osu.Game/Screens/Multi/Match/Components/MatchSettingsOverlay.cs index 49a0fc434b..caefc194b1 100644 --- a/osu.Game/Screens/Multi/Match/Components/MatchSettingsOverlay.cs +++ b/osu.Game/Screens/Multi/Match/Components/MatchSettingsOverlay.cs @@ -14,7 +14,7 @@ using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; using osu.Game.Online.Multiplayer; -using osu.Game.Overlays.SearchableList; +using osu.Game.Overlays; using osuTK; using osuTK.Graphics; @@ -117,7 +117,7 @@ namespace osu.Game.Screens.Multi.Match.Components { new Container { - Padding = new MarginPadding { Horizontal = SearchableListOverlay.WIDTH_PADDING }, + Padding = new MarginPadding { Horizontal = WaveOverlayContainer.WIDTH_PADDING }, RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, Children = new Drawable[] From 98c5a04a09b715de91ed305c4313e6d2055db963 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 3 Sep 2020 16:28:53 +0900 Subject: [PATCH 428/434] Update home button --- osu.Game/Overlays/Toolbar/ToolbarButton.cs | 9 +++++++++ osu.Game/Overlays/Toolbar/ToolbarHomeButton.cs | 12 +++++++++--- .../Overlays/Toolbar/ToolbarOverlayToggleButton.cs | 11 +---------- 3 files changed, 19 insertions(+), 13 deletions(-) diff --git a/osu.Game/Overlays/Toolbar/ToolbarButton.cs b/osu.Game/Overlays/Toolbar/ToolbarButton.cs index 5d402c9a23..d0787664a0 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarButton.cs @@ -35,6 +35,15 @@ namespace osu.Game.Overlays.Toolbar IconContainer.Show(); } + [Resolved] + private TextureStore textures { get; set; } + + public void SetIcon(string texture) => + SetIcon(new Sprite + { + Texture = textures.Get(texture), + }); + public string Text { get => DrawableText.Text; diff --git a/osu.Game/Overlays/Toolbar/ToolbarHomeButton.cs b/osu.Game/Overlays/Toolbar/ToolbarHomeButton.cs index 08ba65fc47..6b2c24c0f3 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarHomeButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarHomeButton.cs @@ -1,6 +1,7 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using osu.Framework.Allocation; using osu.Game.Input.Bindings; namespace osu.Game.Overlays.Toolbar @@ -9,11 +10,16 @@ namespace osu.Game.Overlays.Toolbar { public ToolbarHomeButton() { - // todo: icon + Width *= 1.4f; + Hotkey = GlobalAction.Home; + } + + [BackgroundDependencyLoader] + private void load() + { TooltipMain = "Home"; TooltipSub = "Return to the main menu"; - - Hotkey = GlobalAction.Home; + SetIcon("Icons/Hexacons/home"); } } } diff --git a/osu.Game/Overlays/Toolbar/ToolbarOverlayToggleButton.cs b/osu.Game/Overlays/Toolbar/ToolbarOverlayToggleButton.cs index a76ca26a47..0dea71cc08 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarOverlayToggleButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarOverlayToggleButton.cs @@ -1,14 +1,11 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; -using osu.Framework.Graphics.Sprites; -using osu.Framework.Graphics.Textures; using osu.Game.Graphics; namespace osu.Game.Overlays.Toolbar @@ -21,9 +18,6 @@ namespace osu.Game.Overlays.Toolbar private readonly Bindable overlayState = new Bindable(); - [Resolved] - private TextureStore textures { get; set; } - public OverlayContainer StateContainer { get => stateContainer; @@ -43,10 +37,7 @@ namespace osu.Game.Overlays.Toolbar { TooltipMain = named.Title; TooltipSub = named.Description; - SetIcon(new Sprite - { - Texture = textures.Get(named.IconTexture), - }); + SetIcon(named.IconTexture); } } } From 2fac0a180e0640362b8ce0294e261b3ac2134d5b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 3 Sep 2020 16:29:15 +0900 Subject: [PATCH 429/434] Adjust toolbar button sizing --- osu.Game/OsuGame.cs | 4 ++-- osu.Game/Overlays/Settings/Sidebar.cs | 7 +++---- osu.Game/Overlays/Toolbar/ToolbarButton.cs | 7 +++---- osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.cs | 2 +- osu.Game/Overlays/Toolbar/ToolbarRulesetTabButton.cs | 6 ------ osu.Game/Overlays/Toolbar/ToolbarSettingsButton.cs | 1 + 6 files changed, 10 insertions(+), 17 deletions(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 6b8e70e546..164a40c6a5 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -698,9 +698,9 @@ namespace osu.Game float offset = 0; if (Settings.State.Value == Visibility.Visible) - offset += ToolbarButton.WIDTH / 2; + offset += Toolbar.HEIGHT / 2; if (notifications.State.Value == Visibility.Visible) - offset -= ToolbarButton.WIDTH / 2; + offset -= Toolbar.HEIGHT / 2; screenContainer.MoveToX(offset, SettingsPanel.TRANSITION_LENGTH, Easing.OutQuint); } diff --git a/osu.Game/Overlays/Settings/Sidebar.cs b/osu.Game/Overlays/Settings/Sidebar.cs index 358f94b659..3783d15e5a 100644 --- a/osu.Game/Overlays/Settings/Sidebar.cs +++ b/osu.Game/Overlays/Settings/Sidebar.cs @@ -4,22 +4,21 @@ using System; using System.Linq; using osu.Framework; -using osuTK; -using osuTK.Graphics; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Framework.Input.Events; using osu.Framework.Threading; using osu.Game.Graphics.Containers; -using osu.Game.Overlays.Toolbar; +using osuTK; +using osuTK.Graphics; namespace osu.Game.Overlays.Settings { public class Sidebar : Container, IStateful { private readonly FillFlowContainer content; - public const float DEFAULT_WIDTH = ToolbarButton.WIDTH; + public const float DEFAULT_WIDTH = Toolbar.Toolbar.HEIGHT; public const int EXPANDED_WIDTH = 200; public event Action StateChanged; diff --git a/osu.Game/Overlays/Toolbar/ToolbarButton.cs b/osu.Game/Overlays/Toolbar/ToolbarButton.cs index d0787664a0..49b9c62d85 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarButton.cs @@ -9,6 +9,7 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Effects; using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Sprites; +using osu.Framework.Graphics.Textures; using osu.Framework.Input.Bindings; using osu.Framework.Input.Events; using osu.Game.Graphics; @@ -25,8 +26,6 @@ namespace osu.Game.Overlays.Toolbar { public abstract class ToolbarButton : OsuClickableContainer, IKeyBindingHandler { - public const float WIDTH = Toolbar.HEIGHT * 1.4f; - protected GlobalAction? Hotkey { get; set; } public void SetIcon(Drawable icon) @@ -80,7 +79,7 @@ namespace osu.Game.Overlays.Toolbar protected ToolbarButton() : base(HoverSampleSet.Loud) { - Width = WIDTH; + Width = Toolbar.HEIGHT; RelativeSizeAxes = Axes.Y; Children = new Drawable[] @@ -114,7 +113,7 @@ namespace osu.Game.Overlays.Toolbar { Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, - Size = new Vector2(20), + Size = new Vector2(26), Alpha = 0, }, DrawableText = new OsuSpriteText diff --git a/osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.cs b/osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.cs index 422bf00c6d..905d5b44c6 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.cs @@ -37,7 +37,7 @@ namespace osu.Game.Overlays.Toolbar }, ModeButtonLine = new Container { - Size = new Vector2(ToolbarButton.WIDTH, 3), + Size = new Vector2(Toolbar.HEIGHT, 3), Anchor = Anchor.BottomLeft, Origin = Anchor.TopLeft, Masking = true, diff --git a/osu.Game/Overlays/Toolbar/ToolbarRulesetTabButton.cs b/osu.Game/Overlays/Toolbar/ToolbarRulesetTabButton.cs index a5194ea752..754b679599 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarRulesetTabButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarRulesetTabButton.cs @@ -65,12 +65,6 @@ namespace osu.Game.Overlays.Toolbar Parent.Click(); return base.OnClick(e); } - - protected override void LoadComplete() - { - base.LoadComplete(); - IconContainer.Scale *= 1.4f; - } } } } diff --git a/osu.Game/Overlays/Toolbar/ToolbarSettingsButton.cs b/osu.Game/Overlays/Toolbar/ToolbarSettingsButton.cs index 4051a2a194..c53f4a55d9 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarSettingsButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarSettingsButton.cs @@ -10,6 +10,7 @@ namespace osu.Game.Overlays.Toolbar { public ToolbarSettingsButton() { + Width *= 1.4f; Hotkey = GlobalAction.ToggleSettings; } From 0d1674ca5e28fce53ab48fe478e44faa376b7caa Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 3 Sep 2020 16:32:43 +0900 Subject: [PATCH 430/434] Combine settings strings to read from same location --- osu.Game/Overlays/SettingsOverlay.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Overlays/SettingsOverlay.cs b/osu.Game/Overlays/SettingsOverlay.cs index 9a7937dfce..0532a031f3 100644 --- a/osu.Game/Overlays/SettingsOverlay.cs +++ b/osu.Game/Overlays/SettingsOverlay.cs @@ -16,8 +16,8 @@ namespace osu.Game.Overlays public class SettingsOverlay : SettingsPanel, INamedOverlayComponent { public string IconTexture => "Icons/Hexacons/settings"; - public string Title => "Settings"; - public string Description => "Change your settings"; + public string Title => "settings"; + public string Description => "Change the way osu! behaves"; protected override IEnumerable CreateSections() => new SettingsSection[] { @@ -34,7 +34,7 @@ namespace osu.Game.Overlays private readonly List subPanels = new List(); - protected override Drawable CreateHeader() => new SettingsHeader("settings", "Change the way osu! behaves"); + protected override Drawable CreateHeader() => new SettingsHeader(Title, Description); protected override Drawable CreateFooter() => new SettingsFooter(); public SettingsOverlay() From f5a73130e1aa32ca1001669f4118a15decfce8c4 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 3 Sep 2020 16:34:47 +0900 Subject: [PATCH 431/434] Fix regression in sidebar button sizing --- osu.Game/Overlays/Settings/Sidebar.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Settings/Sidebar.cs b/osu.Game/Overlays/Settings/Sidebar.cs index 3783d15e5a..031ecaae46 100644 --- a/osu.Game/Overlays/Settings/Sidebar.cs +++ b/osu.Game/Overlays/Settings/Sidebar.cs @@ -18,7 +18,7 @@ namespace osu.Game.Overlays.Settings public class Sidebar : Container, IStateful { private readonly FillFlowContainer content; - public const float DEFAULT_WIDTH = Toolbar.Toolbar.HEIGHT; + public const float DEFAULT_WIDTH = Toolbar.Toolbar.HEIGHT * 1.4f; public const int EXPANDED_WIDTH = 200; public event Action StateChanged; From 99e34d85621b283476376d72d8cb70c3f9a50eb8 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 3 Sep 2020 17:05:45 +0900 Subject: [PATCH 432/434] Update with missing icons --- osu.Game/Overlays/BeatmapListing/BeatmapListingHeader.cs | 2 +- osu.Game/Overlays/BeatmapSet/BeatmapSetHeader.cs | 2 +- osu.Game/Overlays/NotificationOverlay.cs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Overlays/BeatmapListing/BeatmapListingHeader.cs b/osu.Game/Overlays/BeatmapListing/BeatmapListingHeader.cs index 1cf86b78cf..b7f511271c 100644 --- a/osu.Game/Overlays/BeatmapListing/BeatmapListingHeader.cs +++ b/osu.Game/Overlays/BeatmapListing/BeatmapListingHeader.cs @@ -13,7 +13,7 @@ namespace osu.Game.Overlays.BeatmapListing { Title = "beatmap listing"; Description = "Browse for new beatmaps"; - IconTexture = "Icons/Hexacons/music"; + IconTexture = "Icons/Hexacons/beatmap"; } } } diff --git a/osu.Game/Overlays/BeatmapSet/BeatmapSetHeader.cs b/osu.Game/Overlays/BeatmapSet/BeatmapSetHeader.cs index 329045c743..6511b15fc8 100644 --- a/osu.Game/Overlays/BeatmapSet/BeatmapSetHeader.cs +++ b/osu.Game/Overlays/BeatmapSet/BeatmapSetHeader.cs @@ -25,7 +25,7 @@ namespace osu.Game.Overlays.BeatmapSet public BeatmapHeaderTitle() { Title = "beatmap info"; - IconTexture = "Icons/Hexacons/music"; + IconTexture = "Icons/Hexacons/beatmap"; } } } diff --git a/osu.Game/Overlays/NotificationOverlay.cs b/osu.Game/Overlays/NotificationOverlay.cs index 6bdacb9c5e..b7d916c48f 100644 --- a/osu.Game/Overlays/NotificationOverlay.cs +++ b/osu.Game/Overlays/NotificationOverlay.cs @@ -18,7 +18,7 @@ namespace osu.Game.Overlays { public class NotificationOverlay : OsuFocusedOverlayContainer, INamedOverlayComponent { - public string IconTexture => "Icons/Hexacons/"; + public string IconTexture => "Icons/Hexacons/notification"; public string Title => "Notifications"; public string Description => "Waiting for 'ya"; From d55c9c3cc2e6f951ff5bf8776c9cff638f3f5726 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 3 Sep 2020 17:11:34 +0900 Subject: [PATCH 433/434] Fix UserProfile weirdness --- osu.Game/Graphics/Containers/SectionsContainer.cs | 5 ++++- osu.Game/Overlays/UserProfileOverlay.cs | 3 +++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/osu.Game/Graphics/Containers/SectionsContainer.cs b/osu.Game/Graphics/Containers/SectionsContainer.cs index d739f56828..f32f8e0c67 100644 --- a/osu.Game/Graphics/Containers/SectionsContainer.cs +++ b/osu.Game/Graphics/Containers/SectionsContainer.cs @@ -26,8 +26,11 @@ namespace osu.Game.Graphics.Containers { if (value == expandableHeader) return; - expandableHeader?.Expire(); + if (expandableHeader != null) + RemoveInternal(expandableHeader); + expandableHeader = value; + if (value == null) return; AddInternal(expandableHeader); diff --git a/osu.Game/Overlays/UserProfileOverlay.cs b/osu.Game/Overlays/UserProfileOverlay.cs index 965ad790ed..2b316c0e34 100644 --- a/osu.Game/Overlays/UserProfileOverlay.cs +++ b/osu.Game/Overlays/UserProfileOverlay.cs @@ -44,6 +44,9 @@ namespace osu.Game.Overlays if (user.Id == Header?.User.Value?.Id) return; + if (sectionsContainer != null) + sectionsContainer.ExpandableHeader = null; + userReq?.Cancel(); Clear(); lastSection = null; From ebed7d09e3412206660666a3231b406e4550206d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 3 Sep 2020 21:56:36 +0900 Subject: [PATCH 434/434] Update resources --- osu.Android.props | 2 +- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index 2d3bfaf7ce..a41c1a5864 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -51,7 +51,7 @@ - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 166910b165..d79806883e 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -25,7 +25,7 @@ - + diff --git a/osu.iOS.props b/osu.iOS.props index 51f8141bac..16a8a1acb7 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -71,7 +71,7 @@ - +