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 @@
-
-
-
+
+
+
@@ -14,7 +14,7 @@
-
+
\ 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)