From 8d30c35104378baee846b75c338313291543c724 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 27 Aug 2019 03:10:58 +0300 Subject: [PATCH 01/33] Implement sorting --- osu.Game/Overlays/SocialOverlay.cs | 65 +++++++++++++++++++++++++++++- 1 file changed, 63 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/SocialOverlay.cs b/osu.Game/Overlays/SocialOverlay.cs index 4def249200..dc63b0ab9a 100644 --- a/osu.Game/Overlays/SocialOverlay.cs +++ b/osu.Game/Overlays/SocialOverlay.cs @@ -16,6 +16,7 @@ using osu.Game.Overlays.SearchableList; using osu.Game.Overlays.Social; using osu.Game.Users; using osu.Framework.Threading; +using System; namespace osu.Game.Overlays { @@ -71,7 +72,7 @@ namespace osu.Game.Overlays Filter.Tabs.Current.ValueChanged += _ => queueUpdate(); Filter.DisplayStyleControl.DisplayStyle.ValueChanged += style => recreatePanels(style.NewValue); - Filter.DisplayStyleControl.Dropdown.Current.ValueChanged += _ => queueUpdate(); + Filter.DisplayStyleControl.Dropdown.Current.ValueChanged += _ => onDropdownChanged(); currentQuery.BindTo(Filter.Search.Current); currentQuery.ValueChanged += query => @@ -175,11 +176,71 @@ namespace osu.Game.Overlays private void updateUsers(IEnumerable newUsers) { - Users = newUsers; + var sortDirection = Filter.DisplayStyleControl.Dropdown.Current.Value; + + IEnumerable sortedUsers = newUsers; + + switch (Filter.Tabs.Current.Value) + { + case SocialSortCriteria.Location: + switch (sortDirection) + { + case SortDirection.Ascending: + sortedUsers = newUsers.OrderBy(u => u.Country.FullName); + break; + + case SortDirection.Descending: + sortedUsers = newUsers.OrderByDescending(u => u.Country.FullName); + break; + } + break; + + case SocialSortCriteria.Name: + switch (sortDirection) + { + case SortDirection.Ascending: + sortedUsers = newUsers.OrderBy(u => u.Username); + break; + + case SortDirection.Descending: + sortedUsers = newUsers.OrderByDescending(u => u.Username); + break; + } + break; + + case SocialSortCriteria.Rank: + if (newUsers.FirstOrDefault().Statistics != null) + { + switch (sortDirection) + { + case SortDirection.Ascending: + sortedUsers = newUsers.OrderBy(u => u.Statistics?.Ranks.Global); + break; + + case SortDirection.Descending: + sortedUsers = newUsers.OrderByDescending(u => u.Statistics?.Ranks.Global); + break; + } + } + break; + } + + Users = sortedUsers; loading.Hide(); recreatePanels(Filter.DisplayStyleControl.DisplayStyle.Value); } + private void onDropdownChanged() + { + if (Users == null) + { + queueUpdate(); + return; + } + + updateUsers(Users); + } + private void clearPanels() { if (panels != null) From cb81d1dd2fea0a174777044e7fdd8fa451f977f6 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 27 Aug 2019 03:53:16 +0300 Subject: [PATCH 02/33] Better use of loading animation --- osu.Game/Overlays/SocialOverlay.cs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/osu.Game/Overlays/SocialOverlay.cs b/osu.Game/Overlays/SocialOverlay.cs index dc63b0ab9a..2202c473f6 100644 --- a/osu.Game/Overlays/SocialOverlay.cs +++ b/osu.Game/Overlays/SocialOverlay.cs @@ -103,7 +103,6 @@ namespace osu.Game.Overlays Users = null; clearPanels(); - loading.Hide(); getUsersRequest?.Cancel(); if (API?.IsLoggedIn != true) @@ -131,8 +130,13 @@ namespace osu.Game.Overlays { clearPanels(); + loading.Show(); + if (Users == null) + { + loading.Hide(); return; + } var newPanels = new FillFlowContainer { @@ -167,15 +171,15 @@ namespace osu.Game.Overlays LoadComponentAsync(newPanels, f => { - if (panels != null) - ScrollFlow.Remove(panels); - + loading.Hide(); ScrollFlow.Add(panels = newPanels); }); } private void updateUsers(IEnumerable newUsers) { + loading.Show(); + var sortDirection = Filter.DisplayStyleControl.Dropdown.Current.Value; IEnumerable sortedUsers = newUsers; @@ -226,7 +230,6 @@ namespace osu.Game.Overlays } Users = sortedUsers; - loading.Hide(); recreatePanels(Filter.DisplayStyleControl.DisplayStyle.Value); } From 7cc6494482c7ba413012c5aa527da25b1c66eb41 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 27 Aug 2019 03:54:49 +0300 Subject: [PATCH 03/33] Remove sorting by rank Since it isn't working for any case currently --- osu.Game/Overlays/SocialOverlay.cs | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/osu.Game/Overlays/SocialOverlay.cs b/osu.Game/Overlays/SocialOverlay.cs index 2202c473f6..8353e2d683 100644 --- a/osu.Game/Overlays/SocialOverlay.cs +++ b/osu.Game/Overlays/SocialOverlay.cs @@ -211,22 +211,6 @@ namespace osu.Game.Overlays break; } break; - - case SocialSortCriteria.Rank: - if (newUsers.FirstOrDefault().Statistics != null) - { - switch (sortDirection) - { - case SortDirection.Ascending: - sortedUsers = newUsers.OrderBy(u => u.Statistics?.Ranks.Global); - break; - - case SortDirection.Descending: - sortedUsers = newUsers.OrderByDescending(u => u.Statistics?.Ranks.Global); - break; - } - } - break; } Users = sortedUsers; From 66b27875e06dedb156b76caacdedc213d6affb87 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 27 Aug 2019 04:00:22 +0300 Subject: [PATCH 04/33] Fix possible null exception --- osu.Game/Overlays/SocialOverlay.cs | 49 ++++++++++++++++-------------- 1 file changed, 26 insertions(+), 23 deletions(-) diff --git a/osu.Game/Overlays/SocialOverlay.cs b/osu.Game/Overlays/SocialOverlay.cs index 8353e2d683..22d1471229 100644 --- a/osu.Game/Overlays/SocialOverlay.cs +++ b/osu.Game/Overlays/SocialOverlay.cs @@ -184,33 +184,36 @@ namespace osu.Game.Overlays IEnumerable sortedUsers = newUsers; - switch (Filter.Tabs.Current.Value) + if (sortedUsers.Any()) { - case SocialSortCriteria.Location: - switch (sortDirection) - { - case SortDirection.Ascending: - sortedUsers = newUsers.OrderBy(u => u.Country.FullName); - break; + switch (Filter.Tabs.Current.Value) + { + case SocialSortCriteria.Location: + switch (sortDirection) + { + case SortDirection.Ascending: + sortedUsers = sortedUsers.OrderBy(u => u.Country.FullName); + break; - case SortDirection.Descending: - sortedUsers = newUsers.OrderByDescending(u => u.Country.FullName); - break; - } - break; + case SortDirection.Descending: + sortedUsers = sortedUsers.OrderByDescending(u => u.Country.FullName); + break; + } + break; - case SocialSortCriteria.Name: - switch (sortDirection) - { - case SortDirection.Ascending: - sortedUsers = newUsers.OrderBy(u => u.Username); - break; + case SocialSortCriteria.Name: + switch (sortDirection) + { + case SortDirection.Ascending: + sortedUsers = sortedUsers.OrderBy(u => u.Username); + break; - case SortDirection.Descending: - sortedUsers = newUsers.OrderByDescending(u => u.Username); - break; - } - break; + case SortDirection.Descending: + sortedUsers = sortedUsers.OrderByDescending(u => u.Username); + break; + } + break; + } } Users = sortedUsers; From 385bc6f52988c3f8c9858b8525aeceb11e6b33fa Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 27 Aug 2019 04:11:22 +0300 Subject: [PATCH 05/33] Remove using and add blank lines --- osu.Game/Overlays/SocialOverlay.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/SocialOverlay.cs b/osu.Game/Overlays/SocialOverlay.cs index 22d1471229..23185ed989 100644 --- a/osu.Game/Overlays/SocialOverlay.cs +++ b/osu.Game/Overlays/SocialOverlay.cs @@ -16,7 +16,6 @@ using osu.Game.Overlays.SearchableList; using osu.Game.Overlays.Social; using osu.Game.Users; using osu.Framework.Threading; -using System; namespace osu.Game.Overlays { @@ -199,6 +198,7 @@ namespace osu.Game.Overlays sortedUsers = sortedUsers.OrderByDescending(u => u.Country.FullName); break; } + break; case SocialSortCriteria.Name: @@ -212,6 +212,7 @@ namespace osu.Game.Overlays sortedUsers = sortedUsers.OrderByDescending(u => u.Username); break; } + break; } } From 9223a1ba8a4ff25c82e719374e37a3f3f3a90f81 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 27 Aug 2019 05:03:47 +0300 Subject: [PATCH 06/33] Simplify sorting logic --- osu.Game/Overlays/SocialOverlay.cs | 28 ++++++---------------------- 1 file changed, 6 insertions(+), 22 deletions(-) diff --git a/osu.Game/Overlays/SocialOverlay.cs b/osu.Game/Overlays/SocialOverlay.cs index 23185ed989..e2179361b1 100644 --- a/osu.Game/Overlays/SocialOverlay.cs +++ b/osu.Game/Overlays/SocialOverlay.cs @@ -16,6 +16,7 @@ using osu.Game.Overlays.SearchableList; using osu.Game.Overlays.Social; using osu.Game.Users; using osu.Framework.Threading; +using System; namespace osu.Game.Overlays { @@ -188,31 +189,11 @@ namespace osu.Game.Overlays switch (Filter.Tabs.Current.Value) { case SocialSortCriteria.Location: - switch (sortDirection) - { - case SortDirection.Ascending: - sortedUsers = sortedUsers.OrderBy(u => u.Country.FullName); - break; - - case SortDirection.Descending: - sortedUsers = sortedUsers.OrderByDescending(u => u.Country.FullName); - break; - } - + sortedUsers = sortBy(sortedUsers, u => u.Country.FullName, sortDirection); break; case SocialSortCriteria.Name: - switch (sortDirection) - { - case SortDirection.Ascending: - sortedUsers = sortedUsers.OrderBy(u => u.Username); - break; - - case SortDirection.Descending: - sortedUsers = sortedUsers.OrderByDescending(u => u.Username); - break; - } - + sortedUsers = sortBy(sortedUsers, u => u.Username, sortDirection); break; } } @@ -221,6 +202,9 @@ namespace osu.Game.Overlays recreatePanels(Filter.DisplayStyleControl.DisplayStyle.Value); } + private IEnumerable sortBy(IEnumerable users, Func condition, SortDirection sortDirection) => + sortDirection == SortDirection.Ascending ? users.OrderBy(condition) : users.OrderByDescending(condition); + private void onDropdownChanged() { if (Users == null) From 11df8c5576478f920f3c09e3b8c884623a0cb836 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 28 Aug 2019 01:02:26 +0300 Subject: [PATCH 07/33] Remove a lot of loading animation calls --- osu.Game/Overlays/SocialOverlay.cs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/osu.Game/Overlays/SocialOverlay.cs b/osu.Game/Overlays/SocialOverlay.cs index e2179361b1..a467ae6dfa 100644 --- a/osu.Game/Overlays/SocialOverlay.cs +++ b/osu.Game/Overlays/SocialOverlay.cs @@ -122,16 +122,12 @@ namespace osu.Game.Overlays API.Queue(getUsersRequest = userRequest); break; } - - loading.Show(); } private void recreatePanels(PanelDisplayStyle displayStyle) { clearPanels(); - loading.Show(); - if (Users == null) { loading.Hide(); @@ -178,8 +174,6 @@ namespace osu.Game.Overlays private void updateUsers(IEnumerable newUsers) { - loading.Show(); - var sortDirection = Filter.DisplayStyleControl.Dropdown.Current.Value; IEnumerable sortedUsers = newUsers; @@ -218,6 +212,8 @@ namespace osu.Game.Overlays private void clearPanels() { + loading.Show(); + if (panels != null) { panels.Expire(); From 9b1e8cf48b701aad40f4a3b34a4d14205bc5bb77 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 28 Aug 2019 01:03:51 +0300 Subject: [PATCH 08/33] Use CancelDelayedTasks instead of private ScheduledDelegate --- osu.Game/Overlays/SocialOverlay.cs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/osu.Game/Overlays/SocialOverlay.cs b/osu.Game/Overlays/SocialOverlay.cs index a467ae6dfa..5ed6a9a703 100644 --- a/osu.Game/Overlays/SocialOverlay.cs +++ b/osu.Game/Overlays/SocialOverlay.cs @@ -77,12 +77,12 @@ namespace osu.Game.Overlays currentQuery.BindTo(Filter.Search.Current); currentQuery.ValueChanged += query => { - queryChangedDebounce?.Cancel(); + Scheduler.CancelDelayedTasks(); if (string.IsNullOrEmpty(query.NewValue)) queueUpdate(); else - queryChangedDebounce = Scheduler.AddDelayed(updateSearch, 500); + Scheduler.AddDelayed(updateSearch, 500); }; } @@ -90,13 +90,11 @@ namespace osu.Game.Overlays private readonly Bindable currentQuery = new Bindable(); - private ScheduledDelegate queryChangedDebounce; - private void queueUpdate() => Scheduler.AddOnce(updateSearch); private void updateSearch() { - queryChangedDebounce?.Cancel(); + Scheduler.CancelDelayedTasks(); if (!IsLoaded) return; From 2d7024ffd92656a9d3646abc0e87111709e6bfe4 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 28 Aug 2019 01:14:35 +0300 Subject: [PATCH 09/33] Use CancellationTokenSource to avoid unwanted panels creation --- osu.Game/Overlays/SocialOverlay.cs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/SocialOverlay.cs b/osu.Game/Overlays/SocialOverlay.cs index 5ed6a9a703..ee3adf65b9 100644 --- a/osu.Game/Overlays/SocialOverlay.cs +++ b/osu.Game/Overlays/SocialOverlay.cs @@ -17,6 +17,7 @@ using osu.Game.Overlays.Social; using osu.Game.Users; using osu.Framework.Threading; using System; +using System.Threading; namespace osu.Game.Overlays { @@ -92,6 +93,8 @@ namespace osu.Game.Overlays private void queueUpdate() => Scheduler.AddOnce(updateSearch); + private CancellationTokenSource loadCancellation; + private void updateSearch() { Scheduler.CancelDelayedTasks(); @@ -132,6 +135,8 @@ namespace osu.Game.Overlays return; } + loadCancellation = new CancellationTokenSource(); + var newPanels = new FillFlowContainer { RelativeSizeAxes = Axes.X, @@ -167,7 +172,7 @@ namespace osu.Game.Overlays { loading.Hide(); ScrollFlow.Add(panels = newPanels); - }); + }, loadCancellation.Token); } private void updateUsers(IEnumerable newUsers) @@ -212,6 +217,8 @@ namespace osu.Game.Overlays { loading.Show(); + loadCancellation?.Cancel(); + if (panels != null) { panels.Expire(); From 6aef05f5d877dfd29b2035cdcadb5f36aa706e3a Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 28 Aug 2019 01:16:55 +0300 Subject: [PATCH 10/33] Remove useless function --- osu.Game/Overlays/SocialOverlay.cs | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/osu.Game/Overlays/SocialOverlay.cs b/osu.Game/Overlays/SocialOverlay.cs index ee3adf65b9..97e1c2b5a4 100644 --- a/osu.Game/Overlays/SocialOverlay.cs +++ b/osu.Game/Overlays/SocialOverlay.cs @@ -73,7 +73,7 @@ namespace osu.Game.Overlays Filter.Tabs.Current.ValueChanged += _ => queueUpdate(); Filter.DisplayStyleControl.DisplayStyle.ValueChanged += style => recreatePanels(style.NewValue); - Filter.DisplayStyleControl.Dropdown.Current.ValueChanged += _ => onDropdownChanged(); + Filter.DisplayStyleControl.Dropdown.Current.ValueChanged += _ => updateUsers(Users); currentQuery.BindTo(Filter.Search.Current); currentQuery.ValueChanged += query => @@ -202,17 +202,6 @@ namespace osu.Game.Overlays private IEnumerable sortBy(IEnumerable users, Func condition, SortDirection sortDirection) => sortDirection == SortDirection.Ascending ? users.OrderBy(condition) : users.OrderByDescending(condition); - private void onDropdownChanged() - { - if (Users == null) - { - queueUpdate(); - return; - } - - updateUsers(Users); - } - private void clearPanels() { loading.Show(); From b6b4173a8481987f3afc73f90d3cc712e099f000 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 28 Aug 2019 01:27:16 +0300 Subject: [PATCH 11/33] Remove unused using --- osu.Game/Overlays/SocialOverlay.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Overlays/SocialOverlay.cs b/osu.Game/Overlays/SocialOverlay.cs index 97e1c2b5a4..bf306f9569 100644 --- a/osu.Game/Overlays/SocialOverlay.cs +++ b/osu.Game/Overlays/SocialOverlay.cs @@ -15,7 +15,6 @@ using osu.Game.Online.API.Requests; using osu.Game.Overlays.SearchableList; using osu.Game.Overlays.Social; using osu.Game.Users; -using osu.Framework.Threading; using System; using System.Threading; From 3227dc87fbac1c47fb505c4e66a66ac80a935678 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Fri, 6 Sep 2019 22:56:46 +0300 Subject: [PATCH 12/33] Don't use CancelDelayedTasks to avoid cancelling unwanted tasks --- osu.Game/Overlays/SocialOverlay.cs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/osu.Game/Overlays/SocialOverlay.cs b/osu.Game/Overlays/SocialOverlay.cs index bf306f9569..1912a2c3e0 100644 --- a/osu.Game/Overlays/SocialOverlay.cs +++ b/osu.Game/Overlays/SocialOverlay.cs @@ -17,6 +17,7 @@ using osu.Game.Overlays.Social; using osu.Game.Users; using System; using System.Threading; +using osu.Framework.Threading; namespace osu.Game.Overlays { @@ -77,12 +78,12 @@ namespace osu.Game.Overlays currentQuery.BindTo(Filter.Search.Current); currentQuery.ValueChanged += query => { - Scheduler.CancelDelayedTasks(); + queryChangedDebounce?.Cancel(); if (string.IsNullOrEmpty(query.NewValue)) queueUpdate(); else - Scheduler.AddDelayed(updateSearch, 500); + queryChangedDebounce = Scheduler.AddDelayed(updateSearch, 500); }; } @@ -90,13 +91,15 @@ namespace osu.Game.Overlays private readonly Bindable currentQuery = new Bindable(); + private ScheduledDelegate queryChangedDebounce; + private void queueUpdate() => Scheduler.AddOnce(updateSearch); private CancellationTokenSource loadCancellation; private void updateSearch() { - Scheduler.CancelDelayedTasks(); + queryChangedDebounce?.Cancel(); if (!IsLoaded) return; @@ -169,6 +172,9 @@ namespace osu.Game.Overlays LoadComponentAsync(newPanels, f => { + if (panels != null) + ScrollFlow.Remove(panels); + loading.Hide(); ScrollFlow.Add(panels = newPanels); }, loadCancellation.Token); From 44412f9ddb0407318c7b9603484f806ef717266e Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 19 Sep 2019 03:35:56 +0300 Subject: [PATCH 13/33] Fix local sorting calls an online request --- osu.Game/Overlays/SocialOverlay.cs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/SocialOverlay.cs b/osu.Game/Overlays/SocialOverlay.cs index 1912a2c3e0..7fd9ef153e 100644 --- a/osu.Game/Overlays/SocialOverlay.cs +++ b/osu.Game/Overlays/SocialOverlay.cs @@ -70,7 +70,7 @@ namespace osu.Game.Overlays Header.Tabs.Current.ValueChanged += _ => queueUpdate(); - Filter.Tabs.Current.ValueChanged += _ => queueUpdate(); + Filter.Tabs.Current.ValueChanged += _ => onFilterUpdate(); Filter.DisplayStyleControl.DisplayStyle.ValueChanged += style => recreatePanels(style.NewValue); Filter.DisplayStyleControl.Dropdown.Current.ValueChanged += _ => updateUsers(Users); @@ -180,6 +180,17 @@ namespace osu.Game.Overlays }, loadCancellation.Token); } + private void onFilterUpdate() + { + if (Users == null || Filter.Tabs.Current.Value == SocialSortCriteria.Rank) + { + queueUpdate(); + return; + } + + updateUsers(Users); + } + private void updateUsers(IEnumerable newUsers) { var sortDirection = Filter.DisplayStyleControl.Dropdown.Current.Value; From 647433a8d1c21187d86f656571d0abe8b5a0423f Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 19 Sep 2019 04:09:14 +0300 Subject: [PATCH 14/33] Don't trigger request if there are no avaliable users --- osu.Game/Overlays/SocialOverlay.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/SocialOverlay.cs b/osu.Game/Overlays/SocialOverlay.cs index 7fd9ef153e..a77172c90c 100644 --- a/osu.Game/Overlays/SocialOverlay.cs +++ b/osu.Game/Overlays/SocialOverlay.cs @@ -182,7 +182,7 @@ namespace osu.Game.Overlays private void onFilterUpdate() { - if (Users == null || Filter.Tabs.Current.Value == SocialSortCriteria.Rank) + if (Filter.Tabs.Current.Value == SocialSortCriteria.Rank) { queueUpdate(); return; From 9ac15ef3a8141d0e583009aa7a604e112f6c1d06 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 18 Dec 2019 22:56:00 +0900 Subject: [PATCH 15/33] Don't log discord connection failures --- osu.Desktop/DiscordRichPresence.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/osu.Desktop/DiscordRichPresence.cs b/osu.Desktop/DiscordRichPresence.cs index b53ca6161b..8818cef8eb 100644 --- a/osu.Desktop/DiscordRichPresence.cs +++ b/osu.Desktop/DiscordRichPresence.cs @@ -43,8 +43,7 @@ namespace osu.Desktop }; client.OnReady += onReady; - client.OnError += (_, e) => Logger.Log($"An error occurred with Discord RPC Client: {e.Code} {e.Message}", LoggingTarget.Network, LogLevel.Error); - client.OnConnectionFailed += (_, e) => Logger.Log($"An connection occurred with Discord RPC Client: {e.Type}", LoggingTarget.Network, LogLevel.Error); + client.OnError += (_, e) => Logger.Log($"An error occurred with Discord RPC Client: {e.Code} {e.Message}", LoggingTarget.Network); (user = provider.LocalUser.GetBoundCopy()).BindValueChanged(u => { From 8d6987c8703d27b4459fb3f30f586a1b1b9ae8a9 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 18 Dec 2019 23:59:48 +0900 Subject: [PATCH 16/33] Refactor storyboard timeline to reduce GC / fix crashes --- osu.Game/Storyboards/CommandTimeline.cs | 29 +++++---- osu.Game/Storyboards/CommandTimelineGroup.cs | 65 +++++++++++++++----- 2 files changed, 69 insertions(+), 25 deletions(-) diff --git a/osu.Game/Storyboards/CommandTimeline.cs b/osu.Game/Storyboards/CommandTimeline.cs index bcf642b4ea..c71806352d 100644 --- a/osu.Game/Storyboards/CommandTimeline.cs +++ b/osu.Game/Storyboards/CommandTimeline.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.Caching; using osu.Framework.Graphics; using System; using System.Collections.Generic; @@ -12,27 +11,35 @@ namespace osu.Game.Storyboards public class CommandTimeline : ICommandTimeline { private readonly List commands = new List(); + public IEnumerable Commands => commands.OrderBy(c => c.StartTime); + public bool HasCommands => commands.Count > 0; - private readonly Cached startTimeBacking = new Cached(); - public double StartTime => startTimeBacking.IsValid ? startTimeBacking : startTimeBacking.Value = HasCommands ? commands.Min(c => c.StartTime) : double.MinValue; + public double StartTime { get; private set; } = double.MaxValue; + public double EndTime { get; private set; } = double.MinValue; - private readonly Cached endTimeBacking = new Cached(); - public double EndTime => endTimeBacking.IsValid ? endTimeBacking : endTimeBacking.Value = HasCommands ? commands.Max(c => c.EndTime) : double.MaxValue; - - public T StartValue => HasCommands ? commands.OrderBy(c => c.StartTime).First().StartValue : default; - public T EndValue => HasCommands ? commands.OrderByDescending(c => c.EndTime).First().EndValue : default; + public T StartValue { get; private set; } + public T EndValue { get; private set; } public void Add(Easing easing, double startTime, double endTime, T startValue, T endValue) { if (endTime < startTime) return; - commands.Add(new TypedCommand { Easing = easing, StartTime = startTime, EndTime = endTime, StartValue = startValue, EndValue = endValue, }); + commands.Add(new TypedCommand { Easing = easing, StartTime = startTime, EndTime = endTime, StartValue = startValue, EndValue = endValue }); - startTimeBacking.Invalidate(); - endTimeBacking.Invalidate(); + if (startTime < StartTime) + { + StartValue = startValue; + StartTime = startTime; + } + + if (endTime > EndTime) + { + EndValue = endValue; + EndTime = endTime; + } } public override string ToString() diff --git a/osu.Game/Storyboards/CommandTimelineGroup.cs b/osu.Game/Storyboards/CommandTimelineGroup.cs index 7b6e667d4f..6ce3b617e9 100644 --- a/osu.Game/Storyboards/CommandTimelineGroup.cs +++ b/osu.Game/Storyboards/CommandTimelineGroup.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 osuTK; using osuTK.Graphics; using osu.Framework.Graphics; @@ -25,28 +26,52 @@ namespace osu.Game.Storyboards public CommandTimeline FlipH = new CommandTimeline(); public CommandTimeline FlipV = new CommandTimeline(); + private readonly ICommandTimeline[] timelines; + + public CommandTimelineGroup() + { + timelines = new ICommandTimeline[] + { + X, + Y, + Scale, + VectorScale, + Rotation, + Colour, + Alpha, + BlendingParameters, + FlipH, + FlipV + }; + } + [JsonIgnore] - public IEnumerable Timelines + public double CommandsStartTime { get { - yield return X; - yield return Y; - yield return Scale; - yield return Rotation; - yield return Colour; - yield return Alpha; - yield return BlendingParameters; - yield return FlipH; - yield return FlipV; + double min = double.MaxValue; + + for (int i = 0; i < timelines.Length; i++) + min = Math.Min(min, timelines[i].StartTime); + + return min; } } [JsonIgnore] - public double CommandsStartTime => Timelines.Where(t => t.HasCommands).Min(t => t.StartTime); + public double CommandsEndTime + { + get + { + double max = double.MinValue; - [JsonIgnore] - public double CommandsEndTime => Timelines.Where(t => t.HasCommands).Max(t => t.EndTime); + for (int i = 0; i < timelines.Length; i++) + max = Math.Max(max, timelines[i].EndTime); + + return max; + } + } [JsonIgnore] public double CommandsDuration => CommandsEndTime - CommandsStartTime; @@ -61,7 +86,19 @@ namespace osu.Game.Storyboards public double Duration => EndTime - StartTime; [JsonIgnore] - public bool HasCommands => Timelines.Any(t => t.HasCommands); + public bool HasCommands + { + get + { + for (int i = 0; i < timelines.Length; i++) + { + if (timelines[i].HasCommands) + return true; + } + + return false; + } + } public virtual IEnumerable.TypedCommand> GetCommands(CommandTimelineSelector timelineSelector, double offset = 0) { From f38853d2291835e6cbda7cc12a2dcf1e4f9eae5f Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 19 Dec 2019 00:52:50 +0900 Subject: [PATCH 17/33] Improve performance of storyboard loading --- osu.Game/Storyboards/StoryboardSprite.cs | 83 ++++++++++++++++++------ 1 file changed, 62 insertions(+), 21 deletions(-) diff --git a/osu.Game/Storyboards/StoryboardSprite.cs b/osu.Game/Storyboards/StoryboardSprite.cs index abf9f58804..22e1929419 100644 --- a/osu.Game/Storyboards/StoryboardSprite.cs +++ b/osu.Game/Storyboards/StoryboardSprite.cs @@ -7,6 +7,7 @@ using osu.Game.Storyboards.Drawables; using System; using System.Collections.Generic; using System.Linq; +using JetBrains.Annotations; namespace osu.Game.Storyboards { @@ -63,50 +64,56 @@ namespace osu.Game.Storyboards public void ApplyTransforms(Drawable drawable, IEnumerable> triggeredGroups = null) { - applyCommands(drawable, getCommands(g => g.X, triggeredGroups), (d, value) => d.X = value, (d, value, duration, easing) => d.MoveToX(value, duration, easing)); - applyCommands(drawable, getCommands(g => g.Y, triggeredGroups), (d, value) => d.Y = value, (d, value, duration, easing) => d.MoveToY(value, duration, easing)); - applyCommands(drawable, getCommands(g => g.Scale, triggeredGroups), (d, value) => d.Scale = new Vector2(value), (d, value, duration, easing) => d.ScaleTo(value, duration, easing)); - applyCommands(drawable, getCommands(g => g.Rotation, triggeredGroups), (d, value) => d.Rotation = value, (d, value, duration, easing) => d.RotateTo(value, duration, easing)); - applyCommands(drawable, getCommands(g => g.Colour, triggeredGroups), (d, value) => d.Colour = value, (d, value, duration, easing) => d.FadeColour(value, duration, easing)); - applyCommands(drawable, getCommands(g => g.Alpha, triggeredGroups), (d, value) => d.Alpha = value, (d, value, duration, easing) => d.FadeTo(value, duration, easing)); - applyCommands(drawable, getCommands(g => g.BlendingParameters, triggeredGroups), (d, value) => d.Blending = value, (d, value, duration, easing) => d.TransformBlendingMode(value, duration), + // For performance reasons, we need to apply the commands in order by start time. Not doing so will cause many functions to be interleaved, resulting in O(n^2) complexity. + // To achieve this, commands are "generated" as pairs of (command, initFunc, transformFunc) and batched into a contiguous list + // The list is then stably-sorted (to preserve command order), and applied to the drawable sequentially. + + List generated = new List(); + + generateCommands(generated, getCommands(g => g.X, triggeredGroups), (d, value) => d.X = value, (d, value, duration, easing) => d.MoveToX(value, duration, easing)); + generateCommands(generated, getCommands(g => g.Y, triggeredGroups), (d, value) => d.Y = value, (d, value, duration, easing) => d.MoveToY(value, duration, easing)); + generateCommands(generated, getCommands(g => g.Scale, triggeredGroups), (d, value) => d.Scale = new Vector2(value), (d, value, duration, easing) => d.ScaleTo(value, duration, easing)); + generateCommands(generated, getCommands(g => g.Rotation, triggeredGroups), (d, value) => d.Rotation = value, (d, value, duration, easing) => d.RotateTo(value, duration, easing)); + generateCommands(generated, getCommands(g => g.Colour, triggeredGroups), (d, value) => d.Colour = value, (d, value, duration, easing) => d.FadeColour(value, duration, easing)); + generateCommands(generated, getCommands(g => g.Alpha, triggeredGroups), (d, value) => d.Alpha = value, (d, value, duration, easing) => d.FadeTo(value, duration, easing)); + generateCommands(generated, getCommands(g => g.BlendingParameters, triggeredGroups), (d, value) => d.Blending = value, (d, value, duration, easing) => d.TransformBlendingMode(value, duration), false); if (drawable is IVectorScalable vectorScalable) { - applyCommands(drawable, getCommands(g => g.VectorScale, triggeredGroups), (d, value) => vectorScalable.VectorScale = value, + generateCommands(generated, getCommands(g => g.VectorScale, triggeredGroups), (d, value) => vectorScalable.VectorScale = value, (d, value, duration, easing) => vectorScalable.VectorScaleTo(value, duration, easing)); } if (drawable is IFlippable flippable) { - applyCommands(drawable, getCommands(g => g.FlipH, triggeredGroups), (d, value) => flippable.FlipH = value, (d, value, duration, easing) => flippable.TransformFlipH(value, duration), + generateCommands(generated, getCommands(g => g.FlipH, triggeredGroups), (d, value) => flippable.FlipH = value, (d, value, duration, easing) => flippable.TransformFlipH(value, duration), false); - applyCommands(drawable, getCommands(g => g.FlipV, triggeredGroups), (d, value) => flippable.FlipV = value, (d, value, duration, easing) => flippable.TransformFlipV(value, duration), + generateCommands(generated, getCommands(g => g.FlipV, triggeredGroups), (d, value) => flippable.FlipV = value, (d, value, duration, easing) => flippable.TransformFlipV(value, duration), false); } + + foreach (var command in generated.OrderBy(g => g.StartTime)) + command.ApplyTo(drawable); } - private void applyCommands(Drawable drawable, IEnumerable.TypedCommand> commands, DrawablePropertyInitializer initializeProperty, DrawableTransformer transform, - bool alwaysInitialize = true) - where T : struct + private void generateCommands(List resultList, IEnumerable.TypedCommand> commands, + DrawablePropertyInitializer initializeProperty, DrawableTransformer transform, bool alwaysInitialize = true) { - var initialized = false; + bool initialized = false; - foreach (var command in commands.OrderBy(l => l)) + foreach (var command in commands) { + DrawablePropertyInitializer initFunc = null; + if (!initialized) { if (alwaysInitialize || command.StartTime == command.EndTime) - initializeProperty.Invoke(drawable, command.StartValue); + initFunc = initializeProperty; initialized = true; } - using (drawable.BeginAbsoluteSequence(command.StartTime)) - { - transform(drawable, command.StartValue, 0, Easing.None); - transform(drawable, command.EndValue, command.Duration, command.Easing); - } + resultList.Add(new GeneratedCommand(command, initFunc, transform)); } } @@ -127,5 +134,39 @@ namespace osu.Game.Storyboards public override string ToString() => $"{Path}, {Origin}, {InitialPosition}"; + + private interface IGeneratedCommand + { + double StartTime { get; } + + void ApplyTo(Drawable drawable); + } + + private readonly struct GeneratedCommand : IGeneratedCommand + { + public double StartTime => command.StartTime; + + private readonly DrawablePropertyInitializer initializeProperty; + private readonly DrawableTransformer transform; + private readonly CommandTimeline.TypedCommand command; + + public GeneratedCommand([NotNull] CommandTimeline.TypedCommand command, [CanBeNull] DrawablePropertyInitializer initializeProperty, [NotNull] DrawableTransformer transform) + { + this.command = command; + this.initializeProperty = initializeProperty; + this.transform = transform; + } + + public void ApplyTo(Drawable drawable) + { + initializeProperty?.Invoke(drawable, command.StartValue); + + using (drawable.BeginAbsoluteSequence(command.StartTime)) + { + transform(drawable, command.StartValue, 0, Easing.None); + transform(drawable, command.EndValue, command.Duration, command.Easing); + } + } + } } } From 007e2e80c1cd193e9e7a1ded3df6191571bed8a3 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 19 Dec 2019 02:02:57 +0900 Subject: [PATCH 18/33] Refactor to fix sorting issues --- osu.Game/Overlays/SocialOverlay.cs | 70 +++++++++++++----------------- 1 file changed, 30 insertions(+), 40 deletions(-) diff --git a/osu.Game/Overlays/SocialOverlay.cs b/osu.Game/Overlays/SocialOverlay.cs index 5b3acf8e46..01dd1ee635 100644 --- a/osu.Game/Overlays/SocialOverlay.cs +++ b/osu.Game/Overlays/SocialOverlay.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.Bindables; @@ -15,7 +16,6 @@ using osu.Game.Online.API.Requests; using osu.Game.Overlays.SearchableList; using osu.Game.Overlays.Social; using osu.Game.Users; -using System; using System.Threading; using osu.Framework.Threading; @@ -33,17 +33,18 @@ namespace osu.Game.Overlays protected override SearchableListHeader CreateHeader() => new Header(); protected override SearchableListFilterControl CreateFilterControl() => new FilterControl(); - private IEnumerable users; + private User[] users = Array.Empty(); - public IEnumerable Users + public User[] Users { get => users; set { - if (ReferenceEquals(users, value)) + if (users == value) return; - users = value?.ToList(); + users = value ?? Array.Empty(); + recreatePanels(); } } @@ -72,8 +73,8 @@ namespace osu.Game.Overlays Filter.Tabs.Current.ValueChanged += _ => onFilterUpdate(); - Filter.DisplayStyleControl.DisplayStyle.ValueChanged += style => recreatePanels(style.NewValue); - Filter.DisplayStyleControl.Dropdown.Current.ValueChanged += _ => updateUsers(Users); + Filter.DisplayStyleControl.DisplayStyle.ValueChanged += _ => recreatePanels(); + Filter.DisplayStyleControl.Dropdown.Current.ValueChanged += _ => recreatePanels(); currentQuery.BindTo(Filter.Search.Current); currentQuery.ValueChanged += query => @@ -115,19 +116,19 @@ namespace osu.Game.Overlays { case SocialTab.Friends: var friendRequest = new GetFriendsRequest(); // TODO filter arguments? - friendRequest.Success += updateUsers; + friendRequest.Success += users => Users = users.ToArray(); API.Queue(getUsersRequest = friendRequest); break; default: var userRequest = new GetUsersRequest(); // TODO filter arguments! - userRequest.Success += res => updateUsers(res.Users.Select(r => r.User)); + userRequest.Success += res => Users = res.Users.Select(r => r.User).ToArray(); API.Queue(getUsersRequest = userRequest); break; } } - private void recreatePanels(PanelDisplayStyle displayStyle) + private void recreatePanels() { clearPanels(); @@ -139,17 +140,33 @@ namespace osu.Game.Overlays loadCancellation = new CancellationTokenSource(); + IEnumerable sortedUsers = Users; + + switch (Filter.Tabs.Current.Value) + { + case SocialSortCriteria.Location: + sortedUsers = sortedUsers.OrderBy(u => u.Country.FullName); + break; + + case SocialSortCriteria.Name: + sortedUsers = sortedUsers.OrderBy(u => u.Username); + break; + } + + if (Filter.DisplayStyleControl.Dropdown.Current.Value == SortDirection.Descending) + sortedUsers = sortedUsers.Reverse(); + var newPanels = new FillFlowContainer { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, Spacing = new Vector2(10f), Margin = new MarginPadding { Top = 10 }, - ChildrenEnumerable = Users.Select(u => + ChildrenEnumerable = sortedUsers.Select(u => { SocialPanel panel; - switch (displayStyle) + switch (Filter.DisplayStyleControl.DisplayStyle.Value) { case PanelDisplayStyle.Grid: panel = new SocialGridPanel(u) @@ -188,36 +205,9 @@ namespace osu.Game.Overlays return; } - updateUsers(Users); + recreatePanels(); } - private void updateUsers(IEnumerable newUsers) - { - var sortDirection = Filter.DisplayStyleControl.Dropdown.Current.Value; - - IEnumerable sortedUsers = newUsers; - - if (sortedUsers.Any()) - { - switch (Filter.Tabs.Current.Value) - { - case SocialSortCriteria.Location: - sortedUsers = sortBy(sortedUsers, u => u.Country.FullName, sortDirection); - break; - - case SocialSortCriteria.Name: - sortedUsers = sortBy(sortedUsers, u => u.Username, sortDirection); - break; - } - } - - Users = sortedUsers; - recreatePanels(Filter.DisplayStyleControl.DisplayStyle.Value); - } - - private IEnumerable sortBy(IEnumerable users, Func condition, SortDirection sortDirection) => - sortDirection == SortDirection.Ascending ? users.OrderBy(condition) : users.OrderByDescending(condition); - private void clearPanels() { loading.Show(); From dd68106d909d9deffb321a39536fbb35454bf05d Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 19 Dec 2019 02:21:33 +0900 Subject: [PATCH 19/33] Recreate panels only while loading/loaded --- osu.Game/Overlays/SocialOverlay.cs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/SocialOverlay.cs b/osu.Game/Overlays/SocialOverlay.cs index 01dd1ee635..7cc3b6e3ce 100644 --- a/osu.Game/Overlays/SocialOverlay.cs +++ b/osu.Game/Overlays/SocialOverlay.cs @@ -17,6 +17,7 @@ using osu.Game.Overlays.SearchableList; using osu.Game.Overlays.Social; using osu.Game.Users; using System.Threading; +using osu.Framework.Allocation; using osu.Framework.Threading; namespace osu.Game.Overlays @@ -44,7 +45,9 @@ namespace osu.Game.Overlays return; users = value ?? Array.Empty(); - recreatePanels(); + + if (LoadState >= LoadState.Ready) + recreatePanels(); } } @@ -70,7 +73,6 @@ namespace osu.Game.Overlays }; Header.Tabs.Current.ValueChanged += _ => queueUpdate(); - Filter.Tabs.Current.ValueChanged += _ => onFilterUpdate(); Filter.DisplayStyleControl.DisplayStyle.ValueChanged += _ => recreatePanels(); @@ -88,6 +90,12 @@ namespace osu.Game.Overlays }; } + [BackgroundDependencyLoader] + private void load() + { + recreatePanels(); + } + private APIRequest getUsersRequest; private readonly Bindable currentQuery = new Bindable(); From a46602f705c2686ad45a58ea2997bb715bb8265e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 19 Dec 2019 11:26:22 +0900 Subject: [PATCH 20/33] Move cancellation token construction closer to usage --- osu.Game/Overlays/SocialOverlay.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/osu.Game/Overlays/SocialOverlay.cs b/osu.Game/Overlays/SocialOverlay.cs index 7cc3b6e3ce..0c99962def 100644 --- a/osu.Game/Overlays/SocialOverlay.cs +++ b/osu.Game/Overlays/SocialOverlay.cs @@ -146,8 +146,6 @@ namespace osu.Game.Overlays return; } - loadCancellation = new CancellationTokenSource(); - IEnumerable sortedUsers = Users; switch (Filter.Tabs.Current.Value) @@ -202,7 +200,7 @@ namespace osu.Game.Overlays loading.Hide(); ScrollFlow.Add(panels = newPanels); - }, loadCancellation.Token); + }, (loadCancellation = new CancellationTokenSource()).Token); } private void onFilterUpdate() From b1533ae2a9d32eee264464d1d12ee374c59cd1bb Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 19 Dec 2019 14:58:56 +0900 Subject: [PATCH 21/33] Fix score serialisation failing for unknown mod properties --- osu.Game/Scoring/ScoreInfo.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Scoring/ScoreInfo.cs b/osu.Game/Scoring/ScoreInfo.cs index c7609e8a0b..c37bab9086 100644 --- a/osu.Game/Scoring/ScoreInfo.cs +++ b/osu.Game/Scoring/ScoreInfo.cs @@ -89,7 +89,7 @@ namespace osu.Game.Scoring if (mods == null) return null; - return modsJson = JsonConvert.SerializeObject(mods); + return modsJson = JsonConvert.SerializeObject(mods.Select(m => new DeserializedMod { Acronym = m.Acronym })); } set { From 81e842f6b4bab33100c8f79eae63c6ab41155730 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 19 Dec 2019 19:48:48 +0900 Subject: [PATCH 22/33] Fix waveform test beatmap accessing zip archive across multiple threads --- .../Editor/TestSceneEditorComposeTimeline.cs | 14 +++----- osu.Game.Tests/WaveformTestBeatmap.cs | 32 +++++++++++-------- 2 files changed, 24 insertions(+), 22 deletions(-) diff --git a/osu.Game.Tests/Visual/Editor/TestSceneEditorComposeTimeline.cs b/osu.Game.Tests/Visual/Editor/TestSceneEditorComposeTimeline.cs index e618256c03..ed6bc5fe0c 100644 --- a/osu.Game.Tests/Visual/Editor/TestSceneEditorComposeTimeline.cs +++ b/osu.Game.Tests/Visual/Editor/TestSceneEditorComposeTimeline.cs @@ -68,8 +68,11 @@ namespace osu.Game.Tests.Visual.Editor { private readonly Drawable marker; - private readonly IBindable beatmap = new Bindable(); - private IAdjustableClock adjustableClock; + [Resolved] + private IBindable beatmap { get; set; } + + [Resolved] + private IAdjustableClock adjustableClock { get; set; } public AudioVisualiser() { @@ -91,13 +94,6 @@ namespace osu.Game.Tests.Visual.Editor }; } - [BackgroundDependencyLoader] - private void load(IAdjustableClock adjustableClock, IBindable beatmap) - { - this.adjustableClock = adjustableClock; - this.beatmap.BindTo(beatmap); - } - protected override void Update() { base.Update(); diff --git a/osu.Game.Tests/WaveformTestBeatmap.cs b/osu.Game.Tests/WaveformTestBeatmap.cs index 0d16a78f75..59f322e24c 100644 --- a/osu.Game.Tests/WaveformTestBeatmap.cs +++ b/osu.Game.Tests/WaveformTestBeatmap.cs @@ -20,23 +20,21 @@ namespace osu.Game.Tests /// public class WaveformTestBeatmap : WorkingBeatmap { - private readonly ZipArchiveReader reader; - private readonly Stream stream; private readonly ITrackStore trackStore; + private Stream getStream() => TestResources.GetTestBeatmapStream(); + + private ZipArchiveReader getZipReader() => new ZipArchiveReader(getStream()); + public WaveformTestBeatmap(AudioManager audioManager) : base(new BeatmapInfo(), audioManager) { - stream = TestResources.GetTestBeatmapStream(); - reader = new ZipArchiveReader(stream); - trackStore = audioManager.GetTrackStore(reader); + trackStore = audioManager.GetTrackStore(getZipReader()); } protected override void Dispose(bool isDisposing) { base.Dispose(isDisposing); - stream?.Dispose(); - reader?.Dispose(); trackStore?.Dispose(); } @@ -50,15 +48,23 @@ namespace osu.Game.Tests protected override Track GetTrack() => trackStore.Get(firstAudioFile); - private string firstAudioFile => reader.Filenames.First(f => f.EndsWith(".mp3")); - - private Stream getBeatmapStream() => reader.GetStream(reader.Filenames.First(f => f.EndsWith(".osu"))); + private string firstAudioFile + { + get + { + using (var reader = getZipReader()) + return reader.Filenames.First(f => f.EndsWith(".mp3")); + } + } private Beatmap createTestBeatmap() { - using (var beatmapStream = getBeatmapStream()) - using (var beatmapReader = new LineBufferedReader(beatmapStream)) - return Decoder.GetDecoder(beatmapReader).Decode(beatmapReader); + using (var reader = getZipReader()) + { + using (var beatmapStream = reader.GetStream(reader.Filenames.First(f => f.EndsWith(".osu")))) + using (var beatmapReader = new LineBufferedReader(beatmapStream)) + return Decoder.GetDecoder(beatmapReader).Decode(beatmapReader); + } } } } From a3154f2f7b3046db8930de15b55636adf6f510d8 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 19 Dec 2019 20:30:58 +0900 Subject: [PATCH 23/33] 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 abb3cc8244..dd11804b90 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -54,6 +54,6 @@ - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index e5f34b1c7e..757e0e11fa 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -23,7 +23,7 @@ - + diff --git a/osu.iOS.props b/osu.iOS.props index c84e617285..0dba92b975 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -74,7 +74,7 @@ - + @@ -82,7 +82,7 @@ - + From 3ac0e3ce51cd811cb2cc07afbfd329aae5e853a5 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 19 Dec 2019 23:03:31 +0900 Subject: [PATCH 24/33] Fix iOS project failing to compile --- osu.Game.Rulesets.Catch.Tests.iOS/Application.cs | 2 +- osu.Game.Rulesets.Mania.Tests.iOS/Application.cs | 2 +- osu.Game.Rulesets.Osu.Tests.iOS/Application.cs | 2 +- osu.Game.Rulesets.Taiko.Tests.iOS/Application.cs | 2 +- osu.Game.Tests.iOS/Application.cs | 2 +- osu.iOS/Application.cs | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/osu.Game.Rulesets.Catch.Tests.iOS/Application.cs b/osu.Game.Rulesets.Catch.Tests.iOS/Application.cs index beca477943..f7f07ef938 100644 --- a/osu.Game.Rulesets.Catch.Tests.iOS/Application.cs +++ b/osu.Game.Rulesets.Catch.Tests.iOS/Application.cs @@ -5,7 +5,7 @@ using UIKit; namespace osu.Game.Rulesets.Catch.Tests.iOS { - public class Application + public static class Application { public static void Main(string[] args) { diff --git a/osu.Game.Rulesets.Mania.Tests.iOS/Application.cs b/osu.Game.Rulesets.Mania.Tests.iOS/Application.cs index 0362402320..c381ea585d 100644 --- a/osu.Game.Rulesets.Mania.Tests.iOS/Application.cs +++ b/osu.Game.Rulesets.Mania.Tests.iOS/Application.cs @@ -5,7 +5,7 @@ using UIKit; namespace osu.Game.Rulesets.Mania.Tests.iOS { - public class Application + public static class Application { public static void Main(string[] args) { diff --git a/osu.Game.Rulesets.Osu.Tests.iOS/Application.cs b/osu.Game.Rulesets.Osu.Tests.iOS/Application.cs index 3718264a42..b36d0b5728 100644 --- a/osu.Game.Rulesets.Osu.Tests.iOS/Application.cs +++ b/osu.Game.Rulesets.Osu.Tests.iOS/Application.cs @@ -5,7 +5,7 @@ using UIKit; namespace osu.Game.Rulesets.Osu.Tests.iOS { - public class Application + public static class Application { public static void Main(string[] args) { diff --git a/osu.Game.Rulesets.Taiko.Tests.iOS/Application.cs b/osu.Game.Rulesets.Taiko.Tests.iOS/Application.cs index 330cb42901..73faf16d9f 100644 --- a/osu.Game.Rulesets.Taiko.Tests.iOS/Application.cs +++ b/osu.Game.Rulesets.Taiko.Tests.iOS/Application.cs @@ -5,7 +5,7 @@ using UIKit; namespace osu.Game.Rulesets.Taiko.Tests.iOS { - public class Application + public static class Application { public static void Main(string[] args) { diff --git a/osu.Game.Tests.iOS/Application.cs b/osu.Game.Tests.iOS/Application.cs index d96a3e27a4..9533b90131 100644 --- a/osu.Game.Tests.iOS/Application.cs +++ b/osu.Game.Tests.iOS/Application.cs @@ -5,7 +5,7 @@ using UIKit; namespace osu.Game.Tests.iOS { - public class Application + public static class Application { public static void Main(string[] args) { diff --git a/osu.iOS/Application.cs b/osu.iOS/Application.cs index 30e0e15ad1..740937e0e1 100644 --- a/osu.iOS/Application.cs +++ b/osu.iOS/Application.cs @@ -5,7 +5,7 @@ using UIKit; namespace osu.iOS { - public class Application + public static class Application { public static void Main(string[] args) { From 7d090d6cd90fd14810aa84d0c30d549f198c09a7 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Thu, 19 Dec 2019 17:52:58 +0300 Subject: [PATCH 25/33] Fix key overlay appearing regardless of the setting --- osu.Game/Screens/Play/KeyCounterDisplay.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/osu.Game/Screens/Play/KeyCounterDisplay.cs b/osu.Game/Screens/Play/KeyCounterDisplay.cs index 1edb95ca46..9c107f0293 100644 --- a/osu.Game/Screens/Play/KeyCounterDisplay.cs +++ b/osu.Game/Screens/Play/KeyCounterDisplay.cs @@ -43,6 +43,11 @@ namespace osu.Game.Screens.Play private void load(OsuConfigManager config) { config.BindWith(OsuSetting.KeyOverlay, configVisibility); + } + + protected override void LoadComplete() + { + base.LoadComplete(); Visible.BindValueChanged(_ => updateVisibility()); configVisibility.BindValueChanged(_ => updateVisibility(), true); From 656c58450305770ec5f76a7742cf3964e74c40aa Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 20 Dec 2019 13:50:47 +0900 Subject: [PATCH 26/33] Update RestoreDefaultValueButton when default value changes --- osu.Game/Overlays/Settings/SettingsItem.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Overlays/Settings/SettingsItem.cs b/osu.Game/Overlays/Settings/SettingsItem.cs index 9c390c34ec..31fcb7abd8 100644 --- a/osu.Game/Overlays/Settings/SettingsItem.cs +++ b/osu.Game/Overlays/Settings/SettingsItem.cs @@ -113,6 +113,7 @@ namespace osu.Game.Overlays.Settings bindable = value; bindable.ValueChanged += _ => UpdateState(); bindable.DisabledChanged += _ => UpdateState(); + bindable.DefaultChanged += _ => UpdateState(); UpdateState(); } } From de8154bc7f5af6a970715c35b347d7900915f34b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 20 Dec 2019 13:54:13 +0900 Subject: [PATCH 27/33] Update readme with new testflight link source --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e2e854c755..753dee548b 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ If you are not interested in developing the game, you can still consume our [bin **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) | [iOS(iOS 10+)](https://testflight.apple.com/join/2tLcjWlF) | [Android (5+)](https://github.com/ppy/osu/releases/latest/download/sh.ppy.osulazer.apk) +| [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) | [iOS(iOS 10+)](https://osu.ppy.sh/home/testflight) | [Android (5+)](https://github.com/ppy/osu/releases/latest/download/sh.ppy.osulazer.apk) | ------------- | ------------- | ------------- | ------------- | - **Linux** users are recommended to self-compile until we have official deployment in place. From 11214628adb34e9cec915706c38b9efae6833d64 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 20 Dec 2019 13:50:57 +0900 Subject: [PATCH 28/33] Add post-update notification for iOS users --- osu.Game/Updater/UpdateManager.cs | 5 ++++- osu.iOS/OsuGameIOS.cs | 8 ++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/osu.Game/Updater/UpdateManager.cs b/osu.Game/Updater/UpdateManager.cs index e256cdbe45..48505a9891 100644 --- a/osu.Game/Updater/UpdateManager.cs +++ b/osu.Game/Updater/UpdateManager.cs @@ -11,7 +11,10 @@ using osu.Game.Overlays.Notifications; namespace osu.Game.Updater { - public abstract class UpdateManager : CompositeDrawable + /// + /// An update manager which only shows notifications after an update completes. + /// + public class UpdateManager : CompositeDrawable { [Resolved] private OsuConfigManager config { get; set; } diff --git a/osu.iOS/OsuGameIOS.cs b/osu.iOS/OsuGameIOS.cs index 6cf18df9a6..e5ff4aec95 100644 --- a/osu.iOS/OsuGameIOS.cs +++ b/osu.iOS/OsuGameIOS.cs @@ -4,11 +4,19 @@ using System; using Foundation; using osu.Game; +using osu.Game.Updater; namespace osu.iOS { public class OsuGameIOS : OsuGame { public override Version AssemblyVersion => new Version(NSBundle.MainBundle.InfoDictionary["CFBundleVersion"].ToString()); + + protected override void LoadComplete() + { + base.LoadComplete(); + + Add(new UpdateManager()); + } } } From 1802e0ff111559f07dd28eba251498d3e2876b1b Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 20 Dec 2019 16:04:05 +0900 Subject: [PATCH 29/33] Fix storyboard incorrectly re-ordering elements --- osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs index 67c4105e6d..b1b27278fe 100644 --- a/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs @@ -5,7 +5,6 @@ using System; using System.Collections.Generic; using System.Globalization; using System.IO; -using System.Linq; using osuTK; using osuTK.Graphics; using osu.Framework.Extensions; @@ -42,10 +41,6 @@ namespace osu.Game.Beatmaps.Formats { this.storyboard = storyboard; base.ParseStreamInto(stream, storyboard); - - // OrderBy is used to guarantee that the parsing order of elements with equal start times is maintained (stably-sorted) - foreach (StoryboardLayer layer in storyboard.Layers) - layer.Elements = layer.Elements.OrderBy(h => h.StartTime).ToList(); } protected override void ParseLine(Storyboard storyboard, Section section, string line) From 705cdde148db14e740e51d02662a0152800b5666 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 20 Dec 2019 16:42:45 +0900 Subject: [PATCH 30/33] Fix incorrect test --- osu.Game.Tests/Beatmaps/Formats/LegacyStoryboardDecoderTest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyStoryboardDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyStoryboardDecoderTest.cs index 66d53d7e7b..96ff6b81e3 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyStoryboardDecoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyStoryboardDecoderTest.cs @@ -71,7 +71,7 @@ namespace osu.Game.Tests.Beatmaps.Formats Assert.AreEqual(new Vector2(320, 240), sprite.InitialPosition); Assert.IsTrue(sprite.IsDrawable); Assert.AreEqual(Anchor.Centre, sprite.Origin); - Assert.AreEqual("SB/black.jpg", sprite.Path); + Assert.AreEqual("SB/lyric/ja-21.png", sprite.Path); var animation = background.Elements.OfType().First(); Assert.NotNull(animation); From 351e826120093ea0fb383f37237b361d4debd741 Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Mon, 16 Dec 2019 15:28:18 +0800 Subject: [PATCH 31/33] Upgrade project targets to netcoreapp3.1 --- .../CatchRuleset__Tests_.xml | 4 +-- .../ManiaRuleset__Tests_.xml | 4 +-- .../runConfigurations/OsuRuleset__Tests_.xml | 4 +-- .../TaikoRuleset__Tests_.xml | 4 +-- .../.idea/runConfigurations/Tournament.xml | 4 +-- .../runConfigurations/Tournament__Tests_.xml | 4 +-- .../.idea/runConfigurations/osu_.xml | 4 +-- .../.idea/runConfigurations/osu___Tests_.xml | 4 +-- .vscode/launch.json | 32 +++++++++---------- .vscode/tasks.json | 2 +- README.md | 4 +-- osu.Desktop/osu.Desktop.csproj | 2 +- .../osu.Game.Rulesets.Catch.Tests.csproj | 2 +- .../osu.Game.Rulesets.Mania.Tests.csproj | 2 +- .../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.csproj | 2 +- 18 files changed, 42 insertions(+), 42 deletions(-) diff --git a/.idea/.idea.osu.Desktop/.idea/runConfigurations/CatchRuleset__Tests_.xml b/.idea/.idea.osu.Desktop/.idea/runConfigurations/CatchRuleset__Tests_.xml index 5372b6f28a..a4154623b6 100644 --- a/.idea/.idea.osu.Desktop/.idea/runConfigurations/CatchRuleset__Tests_.xml +++ b/.idea/.idea.osu.Desktop/.idea/runConfigurations/CatchRuleset__Tests_.xml @@ -1,6 +1,6 @@ - WinExe - netcoreapp3.0 + netcoreapp3.1 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 8fc4dbfe72..dea6e6c0fb 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 @@ -9,7 +9,7 @@ WinExe - netcoreapp3.0 + netcoreapp3.1 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 fddf176fd0..9d4e016eae 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 @@ -9,7 +9,7 @@ WinExe - netcoreapp3.0 + netcoreapp3.1 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 b5bd384e05..d728d65bfd 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 @@ -9,7 +9,7 @@ WinExe - netcoreapp3.0 + netcoreapp3.1 diff --git a/osu.Game.Tests/osu.Game.Tests.csproj b/osu.Game.Tests/osu.Game.Tests.csproj index c5998c9cfc..6c799e5e90 100644 --- a/osu.Game.Tests/osu.Game.Tests.csproj +++ b/osu.Game.Tests/osu.Game.Tests.csproj @@ -10,7 +10,7 @@ WinExe - netcoreapp3.0 + netcoreapp3.1 diff --git a/osu.Game.Tournament.Tests/osu.Game.Tournament.Tests.csproj b/osu.Game.Tournament.Tests/osu.Game.Tournament.Tests.csproj index d58a724c27..7ecfd6ef70 100644 --- a/osu.Game.Tournament.Tests/osu.Game.Tournament.Tests.csproj +++ b/osu.Game.Tournament.Tests/osu.Game.Tournament.Tests.csproj @@ -11,7 +11,7 @@ WinExe - netcoreapp3.0 + netcoreapp3.1 From 0ebdf90dfa9d4ed99b6df992844fe16a85beaf33 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 20 Dec 2019 18:07:39 +0900 Subject: [PATCH 32/33] Move methods below ctor --- osu.Game.Tests/WaveformTestBeatmap.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game.Tests/WaveformTestBeatmap.cs b/osu.Game.Tests/WaveformTestBeatmap.cs index 59f322e24c..b7d7bb1ee1 100644 --- a/osu.Game.Tests/WaveformTestBeatmap.cs +++ b/osu.Game.Tests/WaveformTestBeatmap.cs @@ -22,10 +22,6 @@ namespace osu.Game.Tests { private readonly ITrackStore trackStore; - private Stream getStream() => TestResources.GetTestBeatmapStream(); - - private ZipArchiveReader getZipReader() => new ZipArchiveReader(getStream()); - public WaveformTestBeatmap(AudioManager audioManager) : base(new BeatmapInfo(), audioManager) { @@ -38,6 +34,10 @@ namespace osu.Game.Tests trackStore?.Dispose(); } + private Stream getStream() => TestResources.GetTestBeatmapStream(); + + private ZipArchiveReader getZipReader() => new ZipArchiveReader(getStream()); + protected override IBeatmap GetBeatmap() => createTestBeatmap(); protected override Texture GetBackground() => null; From 492a91067191708b5e4d1896181249a4c0fcb3ef Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 20 Dec 2019 19:08:05 +0900 Subject: [PATCH 33/33] Update missed launch configurations --- osu.Game.Rulesets.Catch.Tests/.vscode/launch.json | 4 ++-- osu.Game.Rulesets.Mania.Tests/.vscode/launch.json | 4 ++-- osu.Game.Rulesets.Osu.Tests/.vscode/launch.json | 4 ++-- osu.Game.Rulesets.Taiko.Tests/.vscode/launch.json | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/osu.Game.Rulesets.Catch.Tests/.vscode/launch.json b/osu.Game.Rulesets.Catch.Tests/.vscode/launch.json index 4030d2d9e7..67d27c33eb 100644 --- a/osu.Game.Rulesets.Catch.Tests/.vscode/launch.json +++ b/osu.Game.Rulesets.Catch.Tests/.vscode/launch.json @@ -7,7 +7,7 @@ "request": "launch", "program": "dotnet", "args": [ - "${workspaceRoot}/bin/Debug/netcoreapp3.0/osu.Game.Rulesets.Catch.Tests.dll" + "${workspaceRoot}/bin/Debug/netcoreapp3.1/osu.Game.Rulesets.Catch.Tests.dll" ], "cwd": "${workspaceRoot}", "preLaunchTask": "Build (Debug)", @@ -20,7 +20,7 @@ "request": "launch", "program": "dotnet", "args": [ - "${workspaceRoot}/bin/Release/netcoreapp3.0/osu.Game.Rulesets.Catch.Tests.dll" + "${workspaceRoot}/bin/Release/netcoreapp3.1/osu.Game.Rulesets.Catch.Tests.dll" ], "cwd": "${workspaceRoot}", "preLaunchTask": "Build (Release)", diff --git a/osu.Game.Rulesets.Mania.Tests/.vscode/launch.json b/osu.Game.Rulesets.Mania.Tests/.vscode/launch.json index 779eb4f277..0811c2724c 100644 --- a/osu.Game.Rulesets.Mania.Tests/.vscode/launch.json +++ b/osu.Game.Rulesets.Mania.Tests/.vscode/launch.json @@ -7,7 +7,7 @@ "request": "launch", "program": "dotnet", "args": [ - "${workspaceRoot}/bin/Debug/netcoreapp3.0/osu.Game.Rulesets.Mania.Tests.dll" + "${workspaceRoot}/bin/Debug/netcoreapp3.1/osu.Game.Rulesets.Mania.Tests.dll" ], "cwd": "${workspaceRoot}", "preLaunchTask": "Build (Debug)", @@ -20,7 +20,7 @@ "request": "launch", "program": "dotnet", "args": [ - "${workspaceRoot}/bin/Release/netcoreapp3.0/osu.Game.Rulesets.Mania.Tests.dll" + "${workspaceRoot}/bin/Release/netcoreapp3.1/osu.Game.Rulesets.Mania.Tests.dll" ], "cwd": "${workspaceRoot}", "preLaunchTask": "Build (Release)", diff --git a/osu.Game.Rulesets.Osu.Tests/.vscode/launch.json b/osu.Game.Rulesets.Osu.Tests/.vscode/launch.json index 67338b7bbe..94568e3852 100644 --- a/osu.Game.Rulesets.Osu.Tests/.vscode/launch.json +++ b/osu.Game.Rulesets.Osu.Tests/.vscode/launch.json @@ -7,7 +7,7 @@ "request": "launch", "program": "dotnet", "args": [ - "${workspaceRoot}/bin/Debug/netcoreapp3.0/osu.Game.Rulesets.Osu.Tests.dll" + "${workspaceRoot}/bin/Debug/netcoreapp3.1/osu.Game.Rulesets.Osu.Tests.dll" ], "cwd": "${workspaceRoot}", "preLaunchTask": "Build (Debug)", @@ -20,7 +20,7 @@ "request": "launch", "program": "dotnet", "args": [ - "${workspaceRoot}/bin/Release/netcoreapp3.0/osu.Game.Rulesets.Osu.Tests.dll" + "${workspaceRoot}/bin/Release/netcoreapp3.1/osu.Game.Rulesets.Osu.Tests.dll" ], "cwd": "${workspaceRoot}", "preLaunchTask": "Build (Release)", diff --git a/osu.Game.Rulesets.Taiko.Tests/.vscode/launch.json b/osu.Game.Rulesets.Taiko.Tests/.vscode/launch.json index 7d929e6bbf..5b02ecfc91 100644 --- a/osu.Game.Rulesets.Taiko.Tests/.vscode/launch.json +++ b/osu.Game.Rulesets.Taiko.Tests/.vscode/launch.json @@ -7,7 +7,7 @@ "request": "launch", "program": "dotnet", "args": [ - "${workspaceRoot}/bin/Debug/netcoreapp3.0/osu.Game.Rulesets.Taiko.Tests.dll" + "${workspaceRoot}/bin/Debug/netcoreapp3.1/osu.Game.Rulesets.Taiko.Tests.dll" ], "cwd": "${workspaceRoot}", "preLaunchTask": "Build (Debug)", @@ -20,7 +20,7 @@ "request": "launch", "program": "dotnet", "args": [ - "${workspaceRoot}/bin/Release/netcoreapp3.0/osu.Game.Rulesets.Taiko.Tests.dll" + "${workspaceRoot}/bin/Release/netcoreapp3.1/osu.Game.Rulesets.Taiko.Tests.dll" ], "cwd": "${workspaceRoot}", "preLaunchTask": "Build (Release)",