From ddceafb1b041f0360446e251f9a4755f42f114d5 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 14 May 2021 09:38:25 +0900 Subject: [PATCH 1/9] 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 8c24df5c2e..90d131b117 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 3eb5050e1a..587bdaf622 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -29,7 +29,7 @@ - + diff --git a/osu.iOS.props b/osu.iOS.props index f00e20a66e..7ba7a554d6 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -70,7 +70,7 @@ - + @@ -93,7 +93,7 @@ - + From 9e8c0a7e7037e6fa118f8d1b1c2c868ca25c286d Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 14 May 2021 04:25:29 +0300 Subject: [PATCH 2/9] Fix online play subscreens not pushing player loaders when starting gameplay --- .../OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs | 3 ++- .../Screens/OnlinePlay/Playlists/PlaylistsRoomSubScreen.cs | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs index fa18b792c3..783b8b4bf2 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs @@ -27,6 +27,7 @@ using osu.Game.Screens.OnlinePlay.Match.Components; using osu.Game.Screens.OnlinePlay.Multiplayer.Match; using osu.Game.Screens.OnlinePlay.Multiplayer.Participants; using osu.Game.Screens.OnlinePlay.Multiplayer.Spectate; +using osu.Game.Screens.Play; using osu.Game.Screens.Play.HUD; using osu.Game.Users; using osuTK; @@ -452,7 +453,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer return new MultiSpectatorScreen(userIds); default: - return new MultiplayerPlayer(SelectedItem.Value, userIds); + return new PlayerLoader(() => new MultiplayerPlayer(SelectedItem.Value, userIds)); } } diff --git a/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomSubScreen.cs b/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomSubScreen.cs index 11bc55823f..26ee21a2c3 100644 --- a/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomSubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomSubScreen.cs @@ -13,6 +13,7 @@ using osu.Game.Online.Rooms; using osu.Game.Screens.OnlinePlay.Components; using osu.Game.Screens.OnlinePlay.Match; using osu.Game.Screens.OnlinePlay.Match.Components; +using osu.Game.Screens.Play; using osu.Game.Screens.Play.HUD; using osu.Game.Users; using osuTK; @@ -271,9 +272,9 @@ namespace osu.Game.Screens.OnlinePlay.Playlists }, true); } - protected override Screen CreateGameplayScreen() => new PlaylistsPlayer(SelectedItem.Value) + protected override Screen CreateGameplayScreen() => new PlayerLoader(() => new PlaylistsPlayer(SelectedItem.Value) { Exited = () => leaderboard.RefreshScores() - }; + }); } } From 46e7d9e0edbc18a48e93db72e616a7af67482c75 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 14 May 2021 12:15:56 +0900 Subject: [PATCH 3/9] Randomise the values displayed in the skinning toolbox To stop the spam of "WYSI" comments everywhere. I guess I underestimated the negative effect this would have. --- osu.Game/Skinning/Editor/SkinComponentToolbox.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/osu.Game/Skinning/Editor/SkinComponentToolbox.cs b/osu.Game/Skinning/Editor/SkinComponentToolbox.cs index 8536cba139..59420bfc87 100644 --- a/osu.Game/Skinning/Editor/SkinComponentToolbox.cs +++ b/osu.Game/Skinning/Editor/SkinComponentToolbox.cs @@ -10,6 +10,7 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Effects; using osu.Framework.Input.Events; +using osu.Framework.Utils; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; @@ -29,8 +30,8 @@ namespace osu.Game.Skinning.Editor [Cached] private ScoreProcessor scoreProcessor = new ScoreProcessor { - Combo = { Value = 727 }, - TotalScore = { Value = 1337377 } + Combo = { Value = RNG.Next(1, 1000) }, + TotalScore = { Value = RNG.Next(1000, 10000000) } }; [Cached(typeof(HealthProcessor))] From 48672f8afd156556f29628b3ae246013f72c297d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 14 May 2021 15:02:36 +0900 Subject: [PATCH 4/9] Add very basic test logic to ensure `PlayerLoader` is present for playlists --- .../TestScenePlaylistsRoomSubScreen.cs | 20 +++++++++++++++++-- .../Screens/OnlinePlay/Match/RoomSubScreen.cs | 6 +++++- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsRoomSubScreen.cs b/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsRoomSubScreen.cs index 319c2bc6fd..264004b6c3 100644 --- a/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsRoomSubScreen.cs +++ b/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsRoomSubScreen.cs @@ -11,11 +11,13 @@ using osu.Framework.Platform; using osu.Framework.Screens; using osu.Framework.Testing; using osu.Game.Beatmaps; +using osu.Game.Online.API; using osu.Game.Online.Rooms; using osu.Game.Rulesets; using osu.Game.Rulesets.Osu; using osu.Game.Screens.OnlinePlay; using osu.Game.Screens.OnlinePlay.Playlists; +using osu.Game.Screens.Play; using osu.Game.Tests.Beatmaps; using osu.Game.Users; using osuTK.Input; @@ -24,8 +26,6 @@ namespace osu.Game.Tests.Visual.Playlists { public class TestScenePlaylistsRoomSubScreen : RoomTestScene { - protected override bool UseOnlineAPI => true; - [Cached(typeof(IRoomManager))] private readonly TestRoomManager roomManager = new TestRoomManager(); @@ -41,6 +41,18 @@ namespace osu.Game.Tests.Visual.Playlists Dependencies.Cache(manager = new BeatmapManager(LocalStorage, ContextFactory, rulesets, null, audio, host, Beatmap.Default)); manager.Import(new TestBeatmap(new OsuRuleset().RulesetInfo).BeatmapInfo.BeatmapSet).Wait(); + + ((DummyAPIAccess)API).HandleRequest = req => + { + switch (req) + { + case CreateRoomScoreRequest createRoomScoreRequest: + createRoomScoreRequest.TriggerSuccess(new APIScoreToken { ID = 1 }); + return true; + } + + return false; + }; } [SetUpSteps] @@ -59,12 +71,16 @@ namespace osu.Game.Tests.Visual.Playlists Room.Name.Value = "my awesome room"; Room.Host.Value = new User { Id = 2, Username = "peppy" }; Room.RecentParticipants.Add(Room.Host.Value); + Room.EndDate.Value = DateTimeOffset.Now.AddMinutes(5); Room.Playlist.Add(new PlaylistItem { Beatmap = { Value = new TestBeatmap(new OsuRuleset().RulesetInfo).BeatmapInfo }, Ruleset = { Value = new OsuRuleset().RulesetInfo } }); }); + + AddStep("start match", () => match.ChildrenOfType().First().Click()); + AddUntilStep("player loader loaded", () => Stack.CurrentScreen is PlayerLoader); } [Test] diff --git a/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs b/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs index 68bdd9160e..28156aecf3 100644 --- a/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs @@ -150,7 +150,11 @@ namespace osu.Game.Screens.OnlinePlay.Match protected void StartPlay() { sampleStart?.Play(); - ParentScreen?.Push(CreateGameplayScreen()); + + // fallback is to allow this class to operate when there is no parent OnlineScreen (testing purposes). + var targetScreen = (Screen)ParentScreen ?? this; + + targetScreen?.Push(CreateGameplayScreen()); } /// From 8338f702c3b260dbd01e8dac1b4c19ce01364fb6 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 14 May 2021 09:32:56 +0300 Subject: [PATCH 5/9] Remove not required null conditional --- osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs b/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs index 28156aecf3..375aac729d 100644 --- a/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs @@ -154,7 +154,7 @@ namespace osu.Game.Screens.OnlinePlay.Match // fallback is to allow this class to operate when there is no parent OnlineScreen (testing purposes). var targetScreen = (Screen)ParentScreen ?? this; - targetScreen?.Push(CreateGameplayScreen()); + targetScreen.Push(CreateGameplayScreen()); } /// From d09da02673186d308e95da4482a06dade52a2a2f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 14 May 2021 16:03:22 +0900 Subject: [PATCH 6/9] Fix deleting skin elements not saving out to skin Closes https://github.com/ppy/osu/issues/12786. --- osu.Game/Skinning/Editor/SkinEditor.cs | 15 +++++++++++--- .../Skinning/Editor/SkinSelectionHandler.cs | 14 ++++++------- osu.Game/Skinning/ISkinnableTarget.cs | 9 ++++++++- osu.Game/Skinning/SkinnableTargetContainer.cs | 20 +++++++++++++++---- 4 files changed, 42 insertions(+), 16 deletions(-) diff --git a/osu.Game/Skinning/Editor/SkinEditor.cs b/osu.Game/Skinning/Editor/SkinEditor.cs index 6427d6298b..c594f8d271 100644 --- a/osu.Game/Skinning/Editor/SkinEditor.cs +++ b/osu.Game/Skinning/Editor/SkinEditor.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System; +using System.Collections.Generic; using System.Linq; using osu.Framework.Allocation; using osu.Framework.Bindables; @@ -193,14 +194,16 @@ namespace osu.Game.Skinning.Editor SelectedComponents.Add(component); } + private IEnumerable availableTargets => targetScreen.ChildrenOfType(); + private ISkinnableTarget getTarget(SkinnableTarget target) { - return targetScreen.ChildrenOfType().FirstOrDefault(c => c.Target == target); + return availableTargets.FirstOrDefault(c => c.Target == target); } private void revert() { - SkinnableTargetContainer[] targetContainers = targetScreen.ChildrenOfType().ToArray(); + ISkinnableTarget[] targetContainers = availableTargets.ToArray(); foreach (var t in targetContainers) { @@ -216,7 +219,7 @@ namespace osu.Game.Skinning.Editor if (!hasBegunMutating) return; - SkinnableTargetContainer[] targetContainers = targetScreen.ChildrenOfType().ToArray(); + ISkinnableTarget[] targetContainers = availableTargets.ToArray(); foreach (var t in targetContainers) currentSkin.Value.UpdateDrawableTarget(t); @@ -237,5 +240,11 @@ namespace osu.Game.Skinning.Editor { this.FadeOut(TRANSITION_DURATION, Easing.OutQuint); } + + public void DeleteItems(ISkinnableDrawable[] items) + { + foreach (var item in items.ToArray()) + availableTargets.FirstOrDefault(t => t.Components.Contains(item))?.Remove(item); + } } } diff --git a/osu.Game/Skinning/Editor/SkinSelectionHandler.cs b/osu.Game/Skinning/Editor/SkinSelectionHandler.cs index 9bcdc6e08b..7931a5ec41 100644 --- a/osu.Game/Skinning/Editor/SkinSelectionHandler.cs +++ b/osu.Game/Skinning/Editor/SkinSelectionHandler.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Linq; +using osu.Framework.Allocation; using osu.Framework.Extensions.EnumExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.UserInterface; @@ -17,6 +18,9 @@ namespace osu.Game.Skinning.Editor { public class SkinSelectionHandler : SelectionHandler { + [Resolved] + private SkinEditor skinEditor { get; set; } + public override bool HandleRotation(float angle) { // TODO: this doesn't correctly account for origin/anchor specs being different in a multi-selection. @@ -72,14 +76,8 @@ namespace osu.Game.Skinning.Editor SelectionBox.CanReverse = false; } - protected override void DeleteItems(IEnumerable items) - { - foreach (var i in items) - { - ((Drawable)i).Expire(); - SelectedItems.Remove(i); - } - } + protected override void DeleteItems(IEnumerable items) => + skinEditor.DeleteItems(items.ToArray()); protected override IEnumerable GetContextMenuItemsForSelection(IEnumerable> selection) { diff --git a/osu.Game/Skinning/ISkinnableTarget.cs b/osu.Game/Skinning/ISkinnableTarget.cs index 65b8ba7b17..15cad2c817 100644 --- a/osu.Game/Skinning/ISkinnableTarget.cs +++ b/osu.Game/Skinning/ISkinnableTarget.cs @@ -37,8 +37,15 @@ namespace osu.Game.Skinning void Reload(); /// - /// Add the provided item to this target. + /// Add a new skinnable component to this target. /// + /// The component to add. void Add(ISkinnableDrawable drawable); + + /// + /// Remove an existing skinnable component to this target. + /// + /// The component to add. + public void Remove(ISkinnableDrawable component); } } diff --git a/osu.Game/Skinning/SkinnableTargetContainer.cs b/osu.Game/Skinning/SkinnableTargetContainer.cs index a4d7f621eb..f055fb2533 100644 --- a/osu.Game/Skinning/SkinnableTargetContainer.cs +++ b/osu.Game/Skinning/SkinnableTargetContainer.cs @@ -43,10 +43,7 @@ namespace osu.Game.Skinning } } - /// - /// Add a new skinnable component to this target. - /// - /// The component to add. + /// /// Thrown when attempting to add an element to a target which is not supported by the current skin. /// Thrown if the provided instance is not a . public void Add(ISkinnableDrawable component) @@ -61,6 +58,21 @@ namespace osu.Game.Skinning components.Add(component); } + /// + /// Thrown when attempting to add an element to a target which is not supported by the current skin. + /// Thrown if the provided instance is not a . + public void Remove(ISkinnableDrawable component) + { + if (content == null) + throw new NotSupportedException("Attempting to add a new component to a target container which is not supported by the current skin."); + + if (!(component is Drawable drawable)) + throw new ArgumentException($"Provided argument must be of type {nameof(Drawable)}.", nameof(drawable)); + + content.Remove(drawable); + components.Remove(component); + } + protected override void SkinChanged(ISkinSource skin, bool allowFallback) { base.SkinChanged(skin, allowFallback); From 876f53bf3beb7c2f212b1634579326a5b2c7c6e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Fri, 14 May 2021 22:15:43 +0200 Subject: [PATCH 7/9] Fix copy-paste oversights in xmldoc & exception messages --- osu.Game/Skinning/ISkinnableTarget.cs | 4 ++-- osu.Game/Skinning/SkinnableTargetContainer.cs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Skinning/ISkinnableTarget.cs b/osu.Game/Skinning/ISkinnableTarget.cs index 15cad2c817..8d4f4dd0c3 100644 --- a/osu.Game/Skinning/ISkinnableTarget.cs +++ b/osu.Game/Skinning/ISkinnableTarget.cs @@ -43,9 +43,9 @@ namespace osu.Game.Skinning void Add(ISkinnableDrawable drawable); /// - /// Remove an existing skinnable component to this target. + /// Remove an existing skinnable component from this target. /// - /// The component to add. + /// The component to remove. public void Remove(ISkinnableDrawable component); } } diff --git a/osu.Game/Skinning/SkinnableTargetContainer.cs b/osu.Game/Skinning/SkinnableTargetContainer.cs index f055fb2533..c195a5516f 100644 --- a/osu.Game/Skinning/SkinnableTargetContainer.cs +++ b/osu.Game/Skinning/SkinnableTargetContainer.cs @@ -64,7 +64,7 @@ namespace osu.Game.Skinning public void Remove(ISkinnableDrawable component) { if (content == null) - throw new NotSupportedException("Attempting to add a new component to a target container which is not supported by the current skin."); + throw new NotSupportedException("Attempting to remove a new component from a target container which is not supported by the current skin."); if (!(component is Drawable drawable)) throw new ArgumentException($"Provided argument must be of type {nameof(Drawable)}.", nameof(drawable)); From 743b4fbff15bb8d506f4848b1c1ed9a803339253 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Fri, 14 May 2021 22:16:37 +0200 Subject: [PATCH 8/9] Pass correct member name to `ArgumentException`s --- osu.Game/Skinning/SkinnableTargetContainer.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Skinning/SkinnableTargetContainer.cs b/osu.Game/Skinning/SkinnableTargetContainer.cs index c195a5516f..d454e199dc 100644 --- a/osu.Game/Skinning/SkinnableTargetContainer.cs +++ b/osu.Game/Skinning/SkinnableTargetContainer.cs @@ -52,7 +52,7 @@ namespace osu.Game.Skinning throw new NotSupportedException("Attempting to add a new component to a target container which is not supported by the current skin."); if (!(component is Drawable drawable)) - throw new ArgumentException($"Provided argument must be of type {nameof(Drawable)}.", nameof(drawable)); + throw new ArgumentException($"Provided argument must be of type {nameof(Drawable)}.", nameof(component)); content.Add(drawable); components.Add(component); @@ -67,7 +67,7 @@ namespace osu.Game.Skinning throw new NotSupportedException("Attempting to remove a new component from a target container which is not supported by the current skin."); if (!(component is Drawable drawable)) - throw new ArgumentException($"Provided argument must be of type {nameof(Drawable)}.", nameof(drawable)); + throw new ArgumentException($"Provided argument must be of type {nameof(Drawable)}.", nameof(component)); content.Remove(drawable); components.Remove(component); From 3d3c5028e6df652f53706e24d7b8ee0f58d09c73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Fri, 14 May 2021 22:33:26 +0200 Subject: [PATCH 9/9] Trim unnecessary array copy --- osu.Game/Skinning/Editor/SkinEditor.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Skinning/Editor/SkinEditor.cs b/osu.Game/Skinning/Editor/SkinEditor.cs index c594f8d271..f24b0c71c0 100644 --- a/osu.Game/Skinning/Editor/SkinEditor.cs +++ b/osu.Game/Skinning/Editor/SkinEditor.cs @@ -243,7 +243,7 @@ namespace osu.Game.Skinning.Editor public void DeleteItems(ISkinnableDrawable[] items) { - foreach (var item in items.ToArray()) + foreach (var item in items) availableTargets.FirstOrDefault(t => t.Components.Contains(item))?.Remove(item); } }