diff --git a/.idea/.idea.osu.Desktop/.idea/runConfigurations/Benchmarks.xml b/.idea/.idea.osu.Desktop/.idea/runConfigurations/Benchmarks.xml index 8fa7608b8e..498a710df9 100644 --- a/.idea/.idea.osu.Desktop/.idea/runConfigurations/Benchmarks.xml +++ b/.idea/.idea.osu.Desktop/.idea/runConfigurations/Benchmarks.xml @@ -1,8 +1,8 @@ - \ No newline at end of file diff --git a/README.md b/README.md index 8f922f74a7..786ce2589d 100644 --- a/README.md +++ b/README.md @@ -31,12 +31,11 @@ If you are looking to install or test osu! without setting up a development envi **Latest build:** -| [Windows (x64)](https://github.com/ppy/osu/releases/latest/download/install.exe) | [macOS 10.12+](https://github.com/ppy/osu/releases/latest/download/osu.app.zip) | [Linux (x64)](https://github.com/ppy/osu/releases/latest/download/osu.AppImage) | [iOS(iOS 10+)](https://osu.ppy.sh/home/testflight) | [Android (5+)](https://github.com/ppy/osu/releases/latest/download/sh.ppy.osulazer.apk) +| [Windows 8.1+ (x64)](https://github.com/ppy/osu/releases/latest/download/install.exe) | [macOS 10.12+](https://github.com/ppy/osu/releases/latest/download/osu.app.zip) | [Linux (x64)](https://github.com/ppy/osu/releases/latest/download/osu.AppImage) | [iOS 10+](https://osu.ppy.sh/home/testflight) | [Android 5+](https://github.com/ppy/osu/releases/latest/download/sh.ppy.osulazer.apk) | ------------- | ------------- | ------------- | ------------- | ------------- | - The iOS testflight link may fill up (Apple has a hard limit of 10,000 users). We reset it occasionally when this happens. Please do not ask about this. Check back regularly for link resets or follow [peppy](https://twitter.com/ppy) on twitter for announcements of link resets. -- When running on Windows 7 or 8.1, *[additional prerequisites](https://docs.microsoft.com/en-us/dotnet/core/install/windows?tabs=net50&pivots=os-windows#dependencies)** may be required to correctly run .NET 5 applications if your operating system is not up-to-date with the latest service packs. If your platform is not listed above, there is still a chance you can manually build it by following the instructions below. ## Developing a custom ruleset diff --git a/osu.Game.Benchmarks/BenchmarkMod.cs b/osu.Game.Benchmarks/BenchmarkMod.cs index 050ddf36d5..c5375e9f09 100644 --- a/osu.Game.Benchmarks/BenchmarkMod.cs +++ b/osu.Game.Benchmarks/BenchmarkMod.cs @@ -14,9 +14,9 @@ namespace osu.Game.Benchmarks [Params(1, 10, 100)] public int Times { get; set; } - [GlobalSetup] - public void GlobalSetup() + public override void SetUp() { + base.SetUp(); mod = new OsuModDoubleTime(); } diff --git a/osu.Game.Benchmarks/Program.cs b/osu.Game.Benchmarks/Program.cs index c55075fea6..439ced53ab 100644 --- a/osu.Game.Benchmarks/Program.cs +++ b/osu.Game.Benchmarks/Program.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 BenchmarkDotNet.Configs; using BenchmarkDotNet.Running; namespace osu.Game.Benchmarks @@ -11,7 +12,7 @@ namespace osu.Game.Benchmarks { BenchmarkSwitcher .FromAssembly(typeof(Program).Assembly) - .Run(args); + .Run(args, DefaultConfig.Instance.WithOption(ConfigOptions.DisableOptimizationsValidator, true)); } } } diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableRoom.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableRoom.cs index 3973dc57b2..b1f5781f6f 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableRoom.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableRoom.cs @@ -130,6 +130,8 @@ namespace osu.Game.Tests.Visual.Multiplayer Type = { Value = MatchType.HeadToHead }, })); + AddUntilStep("wait for panel load", () => drawableRoom.ChildrenOfType().Any()); + AddAssert("password icon hidden", () => Precision.AlmostEquals(0, drawableRoom.ChildrenOfType().Single().Alpha)); AddStep("set password", () => room.Password.Value = "password"); diff --git a/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsLoungeSubScreen.cs b/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsLoungeSubScreen.cs index dafa8300f6..5c248163d7 100644 --- a/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsLoungeSubScreen.cs +++ b/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsLoungeSubScreen.cs @@ -32,6 +32,12 @@ namespace osu.Game.Tests.Visual.Playlists private RoomsContainer roomsContainer => loungeScreen.ChildrenOfType().First(); + [Test] + public void TestManyRooms() + { + AddStep("add rooms", () => RoomManager.AddRooms(500)); + } + [Test] public void TestScrollByDraggingRooms() { diff --git a/osu.Game/Graphics/Containers/LinkFlowContainer.cs b/osu.Game/Graphics/Containers/LinkFlowContainer.cs index 85ef779e48..21c1d70d45 100644 --- a/osu.Game/Graphics/Containers/LinkFlowContainer.cs +++ b/osu.Game/Graphics/Containers/LinkFlowContainer.cs @@ -87,23 +87,25 @@ namespace osu.Game.Graphics.Containers private void createLink(IEnumerable drawables, LinkDetails link, string tooltipText, Action action = null) { - AddInternal(new DrawableLinkCompiler(drawables.OfType().ToList()) + var linkCompiler = CreateLinkCompiler(drawables.OfType()); + linkCompiler.RelativeSizeAxes = Axes.Both; + linkCompiler.TooltipText = tooltipText; + linkCompiler.Action = () => { - RelativeSizeAxes = Axes.Both, - TooltipText = tooltipText, - Action = () => - { - if (action != null) - action(); - else if (game != null) - game.HandleLink(link); - // fallback to handle cases where OsuGame is not available, ie. tournament client. - else if (link.Action == LinkAction.External) - host.OpenUrlExternally(link.Argument); - }, - }); + if (action != null) + action(); + else if (game != null) + game.HandleLink(link); + // fallback to handle cases where OsuGame is not available, ie. tournament client. + else if (link.Action == LinkAction.External) + host.OpenUrlExternally(link.Argument); + }; + + AddInternal(linkCompiler); } + protected virtual DrawableLinkCompiler CreateLinkCompiler(IEnumerable parts) => new DrawableLinkCompiler(parts); + // We want the compilers to always be visible no matter where they are, so RelativeSizeAxes is used. // However due to https://github.com/ppy/osu-framework/issues/2073, it's possible for the compilers to be relative size in the flow's auto-size axes - an unsupported operation. // Since the compilers don't display any content and don't affect the layout, it's simplest to exclude them from the flow. diff --git a/osu.Game/Overlays/Changelog/ChangelogSupporterPromo.cs b/osu.Game/Overlays/Changelog/ChangelogSupporterPromo.cs index 689a7bb4a3..c2b855a0f8 100644 --- a/osu.Game/Overlays/Changelog/ChangelogSupporterPromo.cs +++ b/osu.Game/Overlays/Changelog/ChangelogSupporterPromo.cs @@ -126,7 +126,7 @@ namespace osu.Game.Overlays.Changelog }; supportLinkText.AddText("Support further development of osu! and "); - supportLinkText.AddLink("become an osu!supporter", "https://osu.ppy.sh/home/support", t => t.Font = t.Font.With(weight: FontWeight.Bold)); + supportLinkText.AddLink("become an osu!supporter", @"https://osu.ppy.sh/home/support", t => t.Font = t.Font.With(weight: FontWeight.Bold)); supportLinkText.AddText(" today!"); imageContainer.Children = new Drawable[] @@ -170,27 +170,18 @@ namespace osu.Game.Overlays.Changelog { } - public new void AddLink(string text, string url, Action creationParameters) => - AddInternal(new SupporterPromoLinkCompiler(AddText(text, creationParameters)) { Url = url }); + protected override DrawableLinkCompiler CreateLinkCompiler(IEnumerable parts) => new SupporterPromoLinkCompiler(parts); private class SupporterPromoLinkCompiler : DrawableLinkCompiler { - [Resolved(CanBeNull = true)] - private OsuGame game { get; set; } - - public string Url; - public SupporterPromoLinkCompiler(IEnumerable parts) : base(parts) { - RelativeSizeAxes = Axes.Both; } [BackgroundDependencyLoader] private void load(OsuColour colour) { - TooltipText = Url; - Action = () => game?.HandleLink(Url); IdleColour = colour.PinkDark; HoverColour = Color4.White; } diff --git a/osu.Game/Overlays/Volume/VolumeMeter.cs b/osu.Game/Overlays/Volume/VolumeMeter.cs index f4cbbf5a00..7249dd77e5 100644 --- a/osu.Game/Overlays/Volume/VolumeMeter.cs +++ b/osu.Game/Overlays/Volume/VolumeMeter.cs @@ -355,6 +355,12 @@ namespace osu.Game.Overlays.Volume return base.OnMouseMove(e); } + protected override bool OnHover(HoverEvent e) + { + State = SelectionState.Selected; + return false; + } + protected override void OnHoverLost(HoverLostEvent e) { } diff --git a/osu.Game/Screens/OnlinePlay/Lounge/Components/DrawableRoom.cs b/osu.Game/Screens/OnlinePlay/Lounge/Components/DrawableRoom.cs index 106211c833..80070aa6ba 100644 --- a/osu.Game/Screens/OnlinePlay/Lounge/Components/DrawableRoom.cs +++ b/osu.Game/Screens/OnlinePlay/Lounge/Components/DrawableRoom.cs @@ -43,6 +43,8 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components private PasswordProtectedIcon passwordIcon; private EndDateInfo endDateInfo; + private DelayedLoadWrapper wrapper; + public DrawableRoom(Room room) { Room = room; @@ -63,6 +65,14 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components [BackgroundDependencyLoader] private void load(OverlayColourProvider colours) { + ButtonsContainer = new Container + { + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight, + RelativeSizeAxes = Axes.Y, + AutoSizeAxes = Axes.X + }; + InternalChildren = new[] { // This resolves internal 1px gaps due to applying the (parenting) corner radius and masking across multiple filling background sprites. @@ -75,155 +85,153 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components { d.RelativeSizeAxes = Axes.Both; }), - new Container - { - Name = @"Room content", - RelativeSizeAxes = Axes.Both, - // This negative padding resolves 1px gaps between this background and the background above. - Padding = new MarginPadding { Left = 20, Vertical = -0.5f }, - Child = new Container + wrapper = new DelayedLoadWrapper(() => + new Container { + Name = @"Room content", RelativeSizeAxes = Axes.Both, - Masking = true, - CornerRadius = CORNER_RADIUS, - Children = new Drawable[] + // This negative padding resolves 1px gaps between this background and the background above. + Padding = new MarginPadding { Left = 20, Vertical = -0.5f }, + Child = new Container { - new GridContainer + RelativeSizeAxes = Axes.Both, + Masking = true, + CornerRadius = CORNER_RADIUS, + Children = new Drawable[] { - RelativeSizeAxes = Axes.Both, - ColumnDimensions = new[] + new GridContainer { - new Dimension(GridSizeMode.Relative, 0.2f) - }, - Content = new[] - { - new Drawable[] + RelativeSizeAxes = Axes.Both, + ColumnDimensions = new[] { - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = colours.Background5, - }, - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = ColourInfo.GradientHorizontal(colours.Background5, colours.Background5.Opacity(0.3f)) - }, - } - } - }, - new Container - { - Name = @"Left details", - RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding - { - Left = 20, - Vertical = 5 - }, - Children = new Drawable[] - { - new FillFlowContainer - { - AutoSizeAxes = Axes.Both, - Direction = FillDirection.Vertical, - Children = new Drawable[] - { - new FillFlowContainer - { - AutoSizeAxes = Axes.Both, - Direction = FillDirection.Horizontal, - Spacing = new Vector2(5), - Children = new Drawable[] - { - new RoomStatusPill - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft - }, - specialCategoryPill = new RoomSpecialCategoryPill - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft - }, - endDateInfo = new EndDateInfo - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - }, - } - }, - new FillFlowContainer - { - AutoSizeAxes = Axes.Both, - Padding = new MarginPadding { Top = 3 }, - Direction = FillDirection.Vertical, - Children = new Drawable[] - { - new RoomNameText(), - new RoomHostText(), - } - } - }, + new Dimension(GridSizeMode.Relative, 0.2f) }, - new FillFlowContainer + Content = new[] { - Anchor = Anchor.BottomLeft, - Origin = Anchor.BottomLeft, - AutoSizeAxes = Axes.Both, - Direction = FillDirection.Horizontal, - Spacing = new Vector2(5), - Children = new Drawable[] + new Drawable[] { - new PlaylistCountPill + new Box { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, + RelativeSizeAxes = Axes.Both, + Colour = colours.Background5, }, - new StarRatingRangeDisplay + new Box { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - Scale = new Vector2(0.8f) + RelativeSizeAxes = Axes.Both, + Colour = ColourInfo.GradientHorizontal(colours.Background5, colours.Background5.Opacity(0.3f)) + }, + } + } + }, + new Container + { + Name = @"Left details", + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding + { + Left = 20, + Vertical = 5 + }, + Children = new Drawable[] + { + new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Vertical, + Children = new Drawable[] + { + new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(5), + Children = new Drawable[] + { + new RoomStatusPill + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft + }, + specialCategoryPill = new RoomSpecialCategoryPill + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft + }, + endDateInfo = new EndDateInfo + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + }, + } + }, + new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Padding = new MarginPadding { Top = 3 }, + Direction = FillDirection.Vertical, + Children = new Drawable[] + { + new RoomNameText(), + new RoomHostText(), + } + } + }, + }, + new FillFlowContainer + { + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(5), + Children = new Drawable[] + { + new PlaylistCountPill + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + }, + new StarRatingRangeDisplay + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Scale = new Vector2(0.8f) + } } } } - } - }, - new FillFlowContainer - { - Name = "Right content", - Anchor = Anchor.CentreRight, - Origin = Anchor.CentreRight, - AutoSizeAxes = Axes.X, - RelativeSizeAxes = Axes.Y, - Spacing = new Vector2(5), - Padding = new MarginPadding - { - Right = 10, - Vertical = 20, }, - Children = new Drawable[] + new FillFlowContainer { - ButtonsContainer = new Container + Name = "Right content", + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight, + AutoSizeAxes = Axes.X, + RelativeSizeAxes = Axes.Y, + Spacing = new Vector2(5), + Padding = new MarginPadding { - Anchor = Anchor.CentreRight, - Origin = Anchor.CentreRight, - RelativeSizeAxes = Axes.Y, - AutoSizeAxes = Axes.X + Right = 10, + Vertical = 20, }, - recentParticipantsList = new RecentParticipantsList + Children = new Drawable[] { - Anchor = Anchor.CentreRight, - Origin = Anchor.CentreRight, - NumberOfCircles = NumberOfAvatars + ButtonsContainer, + recentParticipantsList = new RecentParticipantsList + { + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight, + NumberOfCircles = NumberOfAvatars + } } - } + }, + passwordIcon = new PasswordProtectedIcon { Alpha = 0 } }, - passwordIcon = new PasswordProtectedIcon { Alpha = 0 } }, - }, - }, + }, 0) + { + RelativeSizeAxes = Axes.Both, + } }; } @@ -231,23 +239,28 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components { base.LoadComplete(); - roomCategory.BindTo(Room.Category); - roomCategory.BindValueChanged(c => + wrapper.DelayedLoadComplete += _ => { - if (c.NewValue == RoomCategory.Spotlight) - specialCategoryPill.Show(); - else - specialCategoryPill.Hide(); - }, true); + wrapper.FadeInFromZero(200); - roomType.BindTo(Room.Type); - roomType.BindValueChanged(t => - { - endDateInfo.Alpha = t.NewValue == MatchType.Playlists ? 1 : 0; - }, true); + roomCategory.BindTo(Room.Category); + roomCategory.BindValueChanged(c => + { + if (c.NewValue == RoomCategory.Spotlight) + specialCategoryPill.Show(); + else + specialCategoryPill.Hide(); + }, true); - hasPassword.BindTo(Room.HasPassword); - hasPassword.BindValueChanged(v => passwordIcon.Alpha = v.NewValue ? 1 : 0, true); + roomType.BindTo(Room.Type); + roomType.BindValueChanged(t => + { + endDateInfo.Alpha = t.NewValue == MatchType.Playlists ? 1 : 0; + }, true); + + hasPassword.BindTo(Room.HasPassword); + hasPassword.BindValueChanged(v => passwordIcon.Alpha = v.NewValue ? 1 : 0, true); + }; } protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) diff --git a/osu.Game/Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs b/osu.Game/Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs index 6dc3cd18c5..a13d67a0c9 100644 --- a/osu.Game/Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs +++ b/osu.Game/Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs @@ -83,12 +83,10 @@ namespace osu.Game.Screens.OnlinePlay.Lounge { base.LoadComplete(); - if (matchingFilter) - this.FadeInFromZero(transition_duration); - else - Alpha = 0; + Alpha = matchingFilter ? 1 : 0; + selectionBox.Alpha = SelectedRoom.Value == Room ? 1 : 0; - SelectedRoom.BindValueChanged(updateSelectedRoom, true); + SelectedRoom.BindValueChanged(updateSelectedRoom); } private void updateSelectedRoom(ValueChangedEvent selected)