diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneMedalOverlay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneMedalOverlay.cs index ead5c5b418..a33c7e662f 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneMedalOverlay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneMedalOverlay.cs @@ -29,23 +29,48 @@ namespace osu.Game.Tests.Visual.Gameplay [Test] public void TestBasicAward() { - AddStep("award medal", () => dummyAPI.NotificationsClient.Receive(new SocketMessage + awardMedal(new UserAchievementUnlock { - Event = @"new", - Data = JObject.FromObject(new NewPrivateNotificationEvent - { - Name = @"user_achievement_unlock", - Details = JObject.FromObject(new UserAchievementUnlock - { - Title = "Time And A Half", - Description = "Having a right ol' time. One and a half of them, almost.", - Slug = @"all-intro-doubletime" - }) - }) - })); + Title = "Time And A Half", + Description = "Having a right ol' time. One and a half of them, almost.", + Slug = @"all-intro-doubletime" + }); AddUntilStep("overlay shown", () => overlay.State.Value, () => Is.EqualTo(Visibility.Visible)); AddRepeatStep("dismiss", () => InputManager.Key(Key.Escape), 2); AddUntilStep("overlay hidden", () => overlay.State.Value, () => Is.EqualTo(Visibility.Hidden)); } + + [Test] + public void TestMultipleMedalsInQuickSuccession() + { + awardMedal(new UserAchievementUnlock + { + Title = "Time And A Half", + Description = "Having a right ol' time. One and a half of them, almost.", + Slug = @"all-intro-doubletime" + }); + awardMedal(new UserAchievementUnlock + { + Title = "S-Ranker", + Description = "Accuracy is really underrated.", + Slug = @"all-secret-rank-s" + }); + awardMedal(new UserAchievementUnlock + { + Title = "500 Combo", + Description = "500 big ones! You're moving up in the world!", + Slug = @"osu-combo-500" + }); + } + + private void awardMedal(UserAchievementUnlock unlock) => AddStep("award medal", () => dummyAPI.NotificationsClient.Receive(new SocketMessage + { + Event = @"new", + Data = JObject.FromObject(new NewPrivateNotificationEvent + { + Name = @"user_achievement_unlock", + Details = JObject.FromObject(unlock) + }) + })); } } diff --git a/osu.Game/Overlays/MedalOverlay.cs b/osu.Game/Overlays/MedalOverlay.cs index c3d7b4b9fc..70cde43924 100644 --- a/osu.Game/Overlays/MedalOverlay.cs +++ b/osu.Game/Overlays/MedalOverlay.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.Collections.Generic; using System.Linq; using osu.Framework.Allocation; using osu.Framework.Extensions.ObjectExtensions; @@ -29,6 +30,8 @@ namespace osu.Game.Overlays this.FadeOut(); } + private readonly Queue queuedMedals = new Queue(); + [Resolved] private IAPIProvider api { get; set; } = null!; @@ -71,7 +74,7 @@ namespace osu.Game.Overlays Show(); LoadComponentAsync(new MedalAnimation(medal), animation => { - medalContainer.Add(animation); + queuedMedals.Enqueue(animation); showingMedals = true; }); } @@ -80,7 +83,12 @@ namespace osu.Game.Overlays { base.Update(); - if (showingMedals && !medalContainer.Any()) + if (!showingMedals || medalContainer.Any()) + return; + + if (queuedMedals.TryDequeue(out var nextMedal)) + medalContainer.Add(nextMedal); + else Hide(); }