From 7dd18a84f6f6a29df941c5aa2e2d7da6d7a29020 Mon Sep 17 00:00:00 2001 From: Xesquim Date: Wed, 5 Jun 2024 12:25:33 -0300 Subject: [PATCH 1/5] Fixing the GetTotalDuration in PlaylistExtesions --- osu.Game/Online/Rooms/PlaylistExtensions.cs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/osu.Game/Online/Rooms/PlaylistExtensions.cs b/osu.Game/Online/Rooms/PlaylistExtensions.cs index cd52a3c6e6..3171716992 100644 --- a/osu.Game/Online/Rooms/PlaylistExtensions.cs +++ b/osu.Game/Online/Rooms/PlaylistExtensions.cs @@ -1,11 +1,13 @@ // 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 Humanizer; using Humanizer.Localisation; using osu.Framework.Bindables; +using osu.Game.Rulesets.Mods; namespace osu.Game.Online.Rooms { @@ -39,6 +41,17 @@ namespace osu.Game.Online.Rooms } public static string GetTotalDuration(this BindableList playlist) => - playlist.Select(p => p.Beatmap.Length).Sum().Milliseconds().Humanize(minUnit: TimeUnit.Second, maxUnit: TimeUnit.Hour, precision: 2); + playlist.Select(p => + { + var ruleset = p.Beatmap.Ruleset.CreateInstance(); + double rate = 1; + if (p.RequiredMods.Count() > 0) + { + List mods = p.RequiredMods.Select(mod => mod.ToMod(ruleset)).ToList(); + foreach (var mod in mods.OfType()) + rate = mod.ApplyToRate(0, rate); + } + return p.Beatmap.Length / rate; + }).Sum().Milliseconds().Humanize(minUnit: TimeUnit.Second, maxUnit: TimeUnit.Hour, precision: 2); } } From 860afb812367c21a88f667ad1d9431f75dab26ab Mon Sep 17 00:00:00 2001 From: Xesquim Date: Thu, 6 Jun 2024 10:06:07 -0300 Subject: [PATCH 2/5] Creating method in ModUtils to calculate the rate for the song --- .../Beatmaps/Drawables/DifficultyIconTooltip.cs | 9 ++------- osu.Game/Online/Rooms/PlaylistExtensions.cs | 12 +++++------- .../Overlays/Mods/BeatmapAttributesDisplay.cs | 4 +--- osu.Game/Screens/Select/BeatmapInfoWedge.cs | 4 +--- osu.Game/Screens/Select/Details/AdvancedStats.cs | 5 ++--- osu.Game/Utils/ModUtils.cs | 16 ++++++++++++++++ 6 files changed, 27 insertions(+), 23 deletions(-) diff --git a/osu.Game/Beatmaps/Drawables/DifficultyIconTooltip.cs b/osu.Game/Beatmaps/Drawables/DifficultyIconTooltip.cs index 1f3dcfee8c..a5cac69afd 100644 --- a/osu.Game/Beatmaps/Drawables/DifficultyIconTooltip.cs +++ b/osu.Game/Beatmaps/Drawables/DifficultyIconTooltip.cs @@ -13,6 +13,7 @@ using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Rulesets; using osu.Game.Rulesets.Mods; +using osu.Game.Utils; using osuTK; namespace osu.Game.Beatmaps.Drawables @@ -123,13 +124,7 @@ namespace osu.Game.Beatmaps.Drawables difficultyFillFlowContainer.Show(); miscFillFlowContainer.Show(); - double rate = 1; - - if (displayedContent.Mods != null) - { - foreach (var mod in displayedContent.Mods.OfType()) - rate = mod.ApplyToRate(0, rate); - } + double rate = ModUtils.CalculateRateWithMods(displayedContent.Mods); double bpmAdjusted = displayedContent.BeatmapInfo.BPM * rate; diff --git a/osu.Game/Online/Rooms/PlaylistExtensions.cs b/osu.Game/Online/Rooms/PlaylistExtensions.cs index 3171716992..4bcaaa8131 100644 --- a/osu.Game/Online/Rooms/PlaylistExtensions.cs +++ b/osu.Game/Online/Rooms/PlaylistExtensions.cs @@ -8,6 +8,7 @@ using Humanizer; using Humanizer.Localisation; using osu.Framework.Bindables; using osu.Game.Rulesets.Mods; +using osu.Game.Utils; namespace osu.Game.Online.Rooms { @@ -40,17 +41,14 @@ namespace osu.Game.Online.Rooms : GetUpcomingItems(playlist).First(); } + /// + /// Returns the total duration from the in playlist order from the supplied , + /// public static string GetTotalDuration(this BindableList playlist) => playlist.Select(p => { var ruleset = p.Beatmap.Ruleset.CreateInstance(); - double rate = 1; - if (p.RequiredMods.Count() > 0) - { - List mods = p.RequiredMods.Select(mod => mod.ToMod(ruleset)).ToList(); - foreach (var mod in mods.OfType()) - rate = mod.ApplyToRate(0, rate); - } + double rate = ModUtils.CalculateRateWithMods(p.RequiredMods.Select(mod => mod.ToMod(ruleset)).ToList()); return p.Beatmap.Length / rate; }).Sum().Milliseconds().Humanize(minUnit: TimeUnit.Second, maxUnit: TimeUnit.Hour, precision: 2); } diff --git a/osu.Game/Overlays/Mods/BeatmapAttributesDisplay.cs b/osu.Game/Overlays/Mods/BeatmapAttributesDisplay.cs index 5b10a2844e..b625de27f8 100644 --- a/osu.Game/Overlays/Mods/BeatmapAttributesDisplay.cs +++ b/osu.Game/Overlays/Mods/BeatmapAttributesDisplay.cs @@ -165,9 +165,7 @@ namespace osu.Game.Overlays.Mods starRatingDisplay.FinishTransforms(true); }); - double rate = 1; - foreach (var mod in Mods.Value.OfType()) - rate = mod.ApplyToRate(0, rate); + double rate = ModUtils.CalculateRateWithMods(Mods.Value.ToList()); bpmDisplay.Current.Value = FormatUtils.RoundBPM(BeatmapInfo.Value.BPM, rate); diff --git a/osu.Game/Screens/Select/BeatmapInfoWedge.cs b/osu.Game/Screens/Select/BeatmapInfoWedge.cs index 3cab4b67b6..0e2d1db6b7 100644 --- a/osu.Game/Screens/Select/BeatmapInfoWedge.cs +++ b/osu.Game/Screens/Select/BeatmapInfoWedge.cs @@ -402,9 +402,7 @@ namespace osu.Game.Screens.Select return; // this doesn't consider mods which apply variable rates, yet. - double rate = 1; - foreach (var mod in mods.Value.OfType()) - rate = mod.ApplyToRate(0, rate); + double rate = ModUtils.CalculateRateWithMods(mods.Value.ToList()); int bpmMax = FormatUtils.RoundBPM(beatmap.ControlPointInfo.BPMMaximum, rate); int bpmMin = FormatUtils.RoundBPM(beatmap.ControlPointInfo.BPMMinimum, rate); diff --git a/osu.Game/Screens/Select/Details/AdvancedStats.cs b/osu.Game/Screens/Select/Details/AdvancedStats.cs index cb820f4da9..1da890100e 100644 --- a/osu.Game/Screens/Select/Details/AdvancedStats.cs +++ b/osu.Game/Screens/Select/Details/AdvancedStats.cs @@ -27,6 +27,7 @@ using osu.Game.Configuration; using osu.Game.Resources.Localisation.Web; using osu.Game.Rulesets; using osu.Game.Overlays.Mods; +using osu.Game.Utils; namespace osu.Game.Screens.Select.Details { @@ -179,9 +180,7 @@ namespace osu.Game.Screens.Select.Details if (Ruleset.Value != null) { - double rate = 1; - foreach (var mod in mods.Value.OfType()) - rate = mod.ApplyToRate(0, rate); + double rate = ModUtils.CalculateRateWithMods(mods.Value); adjustedDifficulty = Ruleset.Value.CreateInstance().GetRateAdjustedDisplayDifficulty(originalDifficulty, rate); diff --git a/osu.Game/Utils/ModUtils.cs b/osu.Game/Utils/ModUtils.cs index 2c9eef41e3..3378e94ec0 100644 --- a/osu.Game/Utils/ModUtils.cs +++ b/osu.Game/Utils/ModUtils.cs @@ -276,5 +276,21 @@ namespace osu.Game.Utils return scoreMultiplier.ToLocalisableString("0.00x"); } + + /// + /// Calculate the rate for the song with the selected mods. + /// + /// The list of selected mods. + /// The rate with mods. + public static double CalculateRateWithMods(IEnumerable mods) + { + double rate = 1; + if (mods != null) + { + foreach (var mod in mods.OfType()) + rate = mod.ApplyToRate(0, rate); + } + return rate; + } } } From dd3f4bcdab623c3c7563d7cc191dc060cc518d37 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 6 Jun 2024 23:59:15 +0800 Subject: [PATCH 3/5] Fix code quality and null handling --- osu.Game/Beatmaps/Drawables/DifficultyIconTooltip.cs | 4 +++- osu.Game/Online/Rooms/PlaylistExtensions.cs | 4 +--- osu.Game/Overlays/Mods/BeatmapAttributesDisplay.cs | 2 +- osu.Game/Screens/Select/BeatmapInfoWedge.cs | 2 +- osu.Game/Utils/ModUtils.cs | 9 ++++----- 5 files changed, 10 insertions(+), 11 deletions(-) diff --git a/osu.Game/Beatmaps/Drawables/DifficultyIconTooltip.cs b/osu.Game/Beatmaps/Drawables/DifficultyIconTooltip.cs index a5cac69afd..36ddb6030e 100644 --- a/osu.Game/Beatmaps/Drawables/DifficultyIconTooltip.cs +++ b/osu.Game/Beatmaps/Drawables/DifficultyIconTooltip.cs @@ -124,7 +124,9 @@ namespace osu.Game.Beatmaps.Drawables difficultyFillFlowContainer.Show(); miscFillFlowContainer.Show(); - double rate = ModUtils.CalculateRateWithMods(displayedContent.Mods); + double rate = 1; + if (displayedContent.Mods != null) + rate = ModUtils.CalculateRateWithMods(displayedContent.Mods); double bpmAdjusted = displayedContent.BeatmapInfo.BPM * rate; diff --git a/osu.Game/Online/Rooms/PlaylistExtensions.cs b/osu.Game/Online/Rooms/PlaylistExtensions.cs index 4bcaaa8131..003fd23d40 100644 --- a/osu.Game/Online/Rooms/PlaylistExtensions.cs +++ b/osu.Game/Online/Rooms/PlaylistExtensions.cs @@ -1,13 +1,11 @@ // 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 Humanizer; using Humanizer.Localisation; using osu.Framework.Bindables; -using osu.Game.Rulesets.Mods; using osu.Game.Utils; namespace osu.Game.Online.Rooms @@ -48,7 +46,7 @@ namespace osu.Game.Online.Rooms playlist.Select(p => { var ruleset = p.Beatmap.Ruleset.CreateInstance(); - double rate = ModUtils.CalculateRateWithMods(p.RequiredMods.Select(mod => mod.ToMod(ruleset)).ToList()); + double rate = ModUtils.CalculateRateWithMods(p.RequiredMods.Select(mod => mod.ToMod(ruleset))); return p.Beatmap.Length / rate; }).Sum().Milliseconds().Humanize(minUnit: TimeUnit.Second, maxUnit: TimeUnit.Hour, precision: 2); } diff --git a/osu.Game/Overlays/Mods/BeatmapAttributesDisplay.cs b/osu.Game/Overlays/Mods/BeatmapAttributesDisplay.cs index b625de27f8..1f4e007f47 100644 --- a/osu.Game/Overlays/Mods/BeatmapAttributesDisplay.cs +++ b/osu.Game/Overlays/Mods/BeatmapAttributesDisplay.cs @@ -165,7 +165,7 @@ namespace osu.Game.Overlays.Mods starRatingDisplay.FinishTransforms(true); }); - double rate = ModUtils.CalculateRateWithMods(Mods.Value.ToList()); + double rate = ModUtils.CalculateRateWithMods(Mods.Value); bpmDisplay.Current.Value = FormatUtils.RoundBPM(BeatmapInfo.Value.BPM, rate); diff --git a/osu.Game/Screens/Select/BeatmapInfoWedge.cs b/osu.Game/Screens/Select/BeatmapInfoWedge.cs index 0e2d1db6b7..02682c1851 100644 --- a/osu.Game/Screens/Select/BeatmapInfoWedge.cs +++ b/osu.Game/Screens/Select/BeatmapInfoWedge.cs @@ -402,7 +402,7 @@ namespace osu.Game.Screens.Select return; // this doesn't consider mods which apply variable rates, yet. - double rate = ModUtils.CalculateRateWithMods(mods.Value.ToList()); + double rate = ModUtils.CalculateRateWithMods(mods.Value); int bpmMax = FormatUtils.RoundBPM(beatmap.ControlPointInfo.BPMMaximum, rate); int bpmMin = FormatUtils.RoundBPM(beatmap.ControlPointInfo.BPMMinimum, rate); diff --git a/osu.Game/Utils/ModUtils.cs b/osu.Game/Utils/ModUtils.cs index 3378e94ec0..f901f15388 100644 --- a/osu.Game/Utils/ModUtils.cs +++ b/osu.Game/Utils/ModUtils.cs @@ -285,11 +285,10 @@ namespace osu.Game.Utils public static double CalculateRateWithMods(IEnumerable mods) { double rate = 1; - if (mods != null) - { - foreach (var mod in mods.OfType()) - rate = mod.ApplyToRate(0, rate); - } + + foreach (var mod in mods.OfType()) + rate = mod.ApplyToRate(0, rate); + return rate; } } From 6e3bea938e1ecfe255bc4dcfe558870007e8cb6e Mon Sep 17 00:00:00 2001 From: Xesquim Date: Thu, 6 Jun 2024 13:26:52 -0300 Subject: [PATCH 4/5] Instancing a Ruleset only when it's necessary to --- osu.Game/Online/Rooms/PlaylistExtensions.cs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/osu.Game/Online/Rooms/PlaylistExtensions.cs b/osu.Game/Online/Rooms/PlaylistExtensions.cs index 003fd23d40..5a5950333b 100644 --- a/osu.Game/Online/Rooms/PlaylistExtensions.cs +++ b/osu.Game/Online/Rooms/PlaylistExtensions.cs @@ -6,6 +6,7 @@ using System.Linq; using Humanizer; using Humanizer.Localisation; using osu.Framework.Bindables; +using osu.Game.Rulesets.Mods; using osu.Game.Utils; namespace osu.Game.Online.Rooms @@ -45,8 +46,13 @@ namespace osu.Game.Online.Rooms public static string GetTotalDuration(this BindableList playlist) => playlist.Select(p => { - var ruleset = p.Beatmap.Ruleset.CreateInstance(); - double rate = ModUtils.CalculateRateWithMods(p.RequiredMods.Select(mod => mod.ToMod(ruleset))); + IEnumerable modList = []; + if (p.RequiredMods.Length > 0) + { + var ruleset = p.Beatmap.Ruleset.CreateInstance(); + modList = p.RequiredMods.Select(mod => mod.ToMod(ruleset)); + } + double rate = ModUtils.CalculateRateWithMods(modList); return p.Beatmap.Length / rate; }).Sum().Milliseconds().Humanize(minUnit: TimeUnit.Second, maxUnit: TimeUnit.Hour, precision: 2); } From 7cbe93efc3dcef9389922f034b12a92c6777aca7 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 7 Jun 2024 10:37:27 +0800 Subject: [PATCH 5/5] Refactor latest changes to avoid unnecessary call when mods not present --- osu.Game/Online/Rooms/PlaylistExtensions.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game/Online/Rooms/PlaylistExtensions.cs b/osu.Game/Online/Rooms/PlaylistExtensions.cs index 5a5950333b..e9a0519f3d 100644 --- a/osu.Game/Online/Rooms/PlaylistExtensions.cs +++ b/osu.Game/Online/Rooms/PlaylistExtensions.cs @@ -6,7 +6,6 @@ using System.Linq; using Humanizer; using Humanizer.Localisation; using osu.Framework.Bindables; -using osu.Game.Rulesets.Mods; using osu.Game.Utils; namespace osu.Game.Online.Rooms @@ -46,13 +45,14 @@ namespace osu.Game.Online.Rooms public static string GetTotalDuration(this BindableList playlist) => playlist.Select(p => { - IEnumerable modList = []; + double rate = 1; + if (p.RequiredMods.Length > 0) { var ruleset = p.Beatmap.Ruleset.CreateInstance(); - modList = p.RequiredMods.Select(mod => mod.ToMod(ruleset)); + rate = ModUtils.CalculateRateWithMods(p.RequiredMods.Select(mod => mod.ToMod(ruleset))); } - double rate = ModUtils.CalculateRateWithMods(modList); + return p.Beatmap.Length / rate; }).Sum().Milliseconds().Humanize(minUnit: TimeUnit.Second, maxUnit: TimeUnit.Hour, precision: 2); }