From 43f8f3638a9550a0d2d14d827ef3ee53f552f4e3 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Sun, 27 Dec 2020 02:42:13 +0300 Subject: [PATCH 01/15] Fix mod using reference equality unless casted to `IMod` --- osu.Game/Online/API/APIMod.cs | 4 ++-- osu.Game/Rulesets/Mods/IMod.cs | 3 +-- osu.Game/Rulesets/Mods/Mod.cs | 4 ++-- osu.Game/Scoring/ScoreInfo.cs | 4 ++-- 4 files changed, 7 insertions(+), 8 deletions(-) diff --git a/osu.Game/Online/API/APIMod.cs b/osu.Game/Online/API/APIMod.cs index 780e5daa16..f4e0e1b11f 100644 --- a/osu.Game/Online/API/APIMod.cs +++ b/osu.Game/Online/API/APIMod.cs @@ -13,7 +13,7 @@ using osu.Game.Rulesets.Mods; namespace osu.Game.Online.API { - public class APIMod : IMod + public class APIMod : IMod, IEquatable { [JsonProperty("acronym")] public string Acronym { get; set; } @@ -52,7 +52,7 @@ namespace osu.Game.Online.API return resultMod; } - public bool Equals(IMod other) => Acronym == other?.Acronym; + public bool Equals(APIMod other) => Acronym == other?.Acronym; public override string ToString() { diff --git a/osu.Game/Rulesets/Mods/IMod.cs b/osu.Game/Rulesets/Mods/IMod.cs index a5e19f293c..448ad0eb30 100644 --- a/osu.Game/Rulesets/Mods/IMod.cs +++ b/osu.Game/Rulesets/Mods/IMod.cs @@ -1,12 +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 Newtonsoft.Json; namespace osu.Game.Rulesets.Mods { - public interface IMod : IEquatable + public interface IMod { /// /// The shortened name of this mod. diff --git a/osu.Game/Rulesets/Mods/Mod.cs b/osu.Game/Rulesets/Mods/Mod.cs index b8dc7a2661..33550e070b 100644 --- a/osu.Game/Rulesets/Mods/Mod.cs +++ b/osu.Game/Rulesets/Mods/Mod.cs @@ -20,7 +20,7 @@ namespace osu.Game.Rulesets.Mods /// The base class for gameplay modifiers. /// [ExcludeFromDynamicCompile] - public abstract class Mod : IMod, IJsonSerializable + public abstract class Mod : IMod, IEquatable, IJsonSerializable { /// /// The name of this mod. @@ -149,6 +149,6 @@ namespace osu.Game.Rulesets.Mods return copy; } - public bool Equals(IMod other) => GetType() == other?.GetType(); + public bool Equals(Mod other) => GetType() == other?.GetType(); } } diff --git a/osu.Game/Scoring/ScoreInfo.cs b/osu.Game/Scoring/ScoreInfo.cs index f5192f3a40..59eaa994c2 100644 --- a/osu.Game/Scoring/ScoreInfo.cs +++ b/osu.Game/Scoring/ScoreInfo.cs @@ -252,11 +252,11 @@ namespace osu.Game.Scoring } [Serializable] - protected class DeserializedMod : IMod + protected class DeserializedMod : IMod, IEquatable { public string Acronym { get; set; } - public bool Equals(IMod other) => Acronym == other?.Acronym; + public bool Equals(DeserializedMod other) => Acronym == other?.Acronym; } public override string ToString() => $"{User} playing {Beatmap}"; From 5efcdbd431153a902fd510d727f9b02400afcb66 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Mon, 28 Dec 2020 15:19:28 +0300 Subject: [PATCH 02/15] Fix IMod now using reference equality as well --- osu.Game/Online/API/APIMod.cs | 3 ++- osu.Game/Rulesets/Mods/IMod.cs | 3 ++- osu.Game/Rulesets/Mods/Mod.cs | 3 ++- osu.Game/Scoring/ScoreInfo.cs | 3 ++- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/osu.Game/Online/API/APIMod.cs b/osu.Game/Online/API/APIMod.cs index f4e0e1b11f..c1b243c743 100644 --- a/osu.Game/Online/API/APIMod.cs +++ b/osu.Game/Online/API/APIMod.cs @@ -52,7 +52,8 @@ namespace osu.Game.Online.API return resultMod; } - public bool Equals(APIMod other) => Acronym == other?.Acronym; + public bool Equals(IMod other) => other is APIMod them && Equals(them); + public bool Equals(APIMod other) => ((IMod)this).Equals(other); public override string ToString() { diff --git a/osu.Game/Rulesets/Mods/IMod.cs b/osu.Game/Rulesets/Mods/IMod.cs index 448ad0eb30..a5e19f293c 100644 --- a/osu.Game/Rulesets/Mods/IMod.cs +++ b/osu.Game/Rulesets/Mods/IMod.cs @@ -1,11 +1,12 @@ // 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 Newtonsoft.Json; namespace osu.Game.Rulesets.Mods { - public interface IMod + public interface IMod : IEquatable { /// /// The shortened name of this mod. diff --git a/osu.Game/Rulesets/Mods/Mod.cs b/osu.Game/Rulesets/Mods/Mod.cs index 33550e070b..3ccebe4174 100644 --- a/osu.Game/Rulesets/Mods/Mod.cs +++ b/osu.Game/Rulesets/Mods/Mod.cs @@ -149,6 +149,7 @@ namespace osu.Game.Rulesets.Mods return copy; } - public bool Equals(Mod other) => GetType() == other?.GetType(); + public bool Equals(IMod other) => other is Mod them && Equals(them); + public bool Equals(Mod other) => Acronym == other?.Acronym; } } diff --git a/osu.Game/Scoring/ScoreInfo.cs b/osu.Game/Scoring/ScoreInfo.cs index 59eaa994c2..335671ea4e 100644 --- a/osu.Game/Scoring/ScoreInfo.cs +++ b/osu.Game/Scoring/ScoreInfo.cs @@ -256,7 +256,8 @@ namespace osu.Game.Scoring { public string Acronym { get; set; } - public bool Equals(DeserializedMod other) => Acronym == other?.Acronym; + bool IEquatable.Equals(IMod other) => other is DeserializedMod them && Equals(them); + public bool Equals(DeserializedMod other) => ((IMod)this).Equals(other); } public override string ToString() => $"{User} playing {Beatmap}"; From 41b79d938b401d7101440e4ee21f6f28a7590b4a Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Mon, 28 Dec 2020 15:30:52 +0300 Subject: [PATCH 03/15] Fix wrong checks.. --- osu.Game/Online/API/APIMod.cs | 2 +- osu.Game/Rulesets/Mods/Mod.cs | 2 +- osu.Game/Scoring/ScoreInfo.cs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Online/API/APIMod.cs b/osu.Game/Online/API/APIMod.cs index c1b243c743..f4fed4e5c5 100644 --- a/osu.Game/Online/API/APIMod.cs +++ b/osu.Game/Online/API/APIMod.cs @@ -53,7 +53,7 @@ namespace osu.Game.Online.API } public bool Equals(IMod other) => other is APIMod them && Equals(them); - public bool Equals(APIMod other) => ((IMod)this).Equals(other); + public bool Equals(APIMod other) => Acronym == other?.Acronym; public override string ToString() { diff --git a/osu.Game/Rulesets/Mods/Mod.cs b/osu.Game/Rulesets/Mods/Mod.cs index 3ccebe4174..dbb2a0fdc1 100644 --- a/osu.Game/Rulesets/Mods/Mod.cs +++ b/osu.Game/Rulesets/Mods/Mod.cs @@ -150,6 +150,6 @@ namespace osu.Game.Rulesets.Mods } public bool Equals(IMod other) => other is Mod them && Equals(them); - public bool Equals(Mod other) => Acronym == other?.Acronym; + public bool Equals(Mod other) => GetType() == other?.GetType(); } } diff --git a/osu.Game/Scoring/ScoreInfo.cs b/osu.Game/Scoring/ScoreInfo.cs index 335671ea4e..1e5742c358 100644 --- a/osu.Game/Scoring/ScoreInfo.cs +++ b/osu.Game/Scoring/ScoreInfo.cs @@ -257,7 +257,7 @@ namespace osu.Game.Scoring public string Acronym { get; set; } bool IEquatable.Equals(IMod other) => other is DeserializedMod them && Equals(them); - public bool Equals(DeserializedMod other) => ((IMod)this).Equals(other); + public bool Equals(DeserializedMod other) => Acronym == other?.Acronym; } public override string ToString() => $"{User} playing {Beatmap}"; From 9d9c0df64c9213757c51f379ee6be56cce68b87b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Tue, 29 Dec 2020 17:17:44 +0100 Subject: [PATCH 04/15] Make DeserializedMod equality members match other IMods --- 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 1e5742c358..3084afb833 100644 --- a/osu.Game/Scoring/ScoreInfo.cs +++ b/osu.Game/Scoring/ScoreInfo.cs @@ -256,7 +256,7 @@ namespace osu.Game.Scoring { public string Acronym { get; set; } - bool IEquatable.Equals(IMod other) => other is DeserializedMod them && Equals(them); + public bool Equals(IMod other) => other is DeserializedMod them && Equals(them); public bool Equals(DeserializedMod other) => Acronym == other?.Acronym; } From fbd5195738bdd9843434ea7462a906e928285d5a Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Mon, 12 Apr 2021 03:37:03 +0300 Subject: [PATCH 05/15] Extract mod setting value handling to utils class --- .../API/ModSettingsDictionaryFormatter.cs | 34 ++---------------- osu.Game/Utils/ModUtils.cs | 36 +++++++++++++++++++ 2 files changed, 38 insertions(+), 32 deletions(-) diff --git a/osu.Game/Online/API/ModSettingsDictionaryFormatter.cs b/osu.Game/Online/API/ModSettingsDictionaryFormatter.cs index dd854acc32..81ecc74ddb 100644 --- a/osu.Game/Online/API/ModSettingsDictionaryFormatter.cs +++ b/osu.Game/Online/API/ModSettingsDictionaryFormatter.cs @@ -3,11 +3,10 @@ using System.Buffers; using System.Collections.Generic; -using System.Diagnostics; using System.Text; using MessagePack; using MessagePack.Formatters; -using osu.Framework.Bindables; +using osu.Game.Utils; namespace osu.Game.Online.API { @@ -24,36 +23,7 @@ namespace osu.Game.Online.API var stringBytes = new ReadOnlySequence(Encoding.UTF8.GetBytes(kvp.Key)); writer.WriteString(in stringBytes); - switch (kvp.Value) - { - case Bindable d: - primitiveFormatter.Serialize(ref writer, d.Value, options); - break; - - case Bindable i: - primitiveFormatter.Serialize(ref writer, i.Value, options); - break; - - case Bindable f: - primitiveFormatter.Serialize(ref writer, f.Value, options); - break; - - case Bindable b: - primitiveFormatter.Serialize(ref writer, b.Value, options); - break; - - case IBindable u: - // A mod with unknown (e.g. enum) generic type. - var valueMethod = u.GetType().GetProperty(nameof(IBindable.Value)); - Debug.Assert(valueMethod != null); - primitiveFormatter.Serialize(ref writer, valueMethod.GetValue(u), options); - break; - - default: - // fall back for non-bindable cases. - primitiveFormatter.Serialize(ref writer, kvp.Value, options); - break; - } + primitiveFormatter.Serialize(ref writer, ModUtils.GetSettingUnderlyingValue(kvp.Value), options); } } diff --git a/osu.Game/Utils/ModUtils.cs b/osu.Game/Utils/ModUtils.cs index c12b5a9fd4..596880f2e7 100644 --- a/osu.Game/Utils/ModUtils.cs +++ b/osu.Game/Utils/ModUtils.cs @@ -3,8 +3,11 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Linq; +using osu.Framework.Bindables; +using osu.Game.Online.API; using osu.Game.Rulesets.Mods; #nullable enable @@ -129,5 +132,38 @@ namespace osu.Game.Utils else yield return mod; } + + /// + /// Returns the underlying value of the given mod setting object. + /// Used in for serialization and equality comparison purposes. + /// + /// The mod setting. + public static object GetSettingUnderlyingValue(object setting) + { + switch (setting) + { + case Bindable d: + return d.Value; + + case Bindable i: + return i.Value; + + case Bindable f: + return f.Value; + + case Bindable b: + return b.Value; + + case IBindable u: + // A mod with unknown (e.g. enum) generic type. + var valueMethod = u.GetType().GetProperty(nameof(IBindable.Value)); + Debug.Assert(valueMethod != null); + return valueMethod.GetValue(u); + + default: + // fall back for non-bindable cases. + return setting; + } + } } } From 92fab653e175b594327cbce5a7702a6068cf6a58 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Mon, 12 Apr 2021 20:10:22 +0300 Subject: [PATCH 06/15] Take current mod settings value into account on equality comparsion --- osu.Game/Online/API/APIMod.cs | 26 +++++++++++++++++++++++++- osu.Game/Rulesets/Mods/Mod.cs | 14 +++++++++++++- 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/osu.Game/Online/API/APIMod.cs b/osu.Game/Online/API/APIMod.cs index bad7e0af38..4427c82a8b 100644 --- a/osu.Game/Online/API/APIMod.cs +++ b/osu.Game/Online/API/APIMod.cs @@ -11,6 +11,7 @@ using osu.Framework.Bindables; using osu.Game.Configuration; using osu.Game.Rulesets; using osu.Game.Rulesets.Mods; +using osu.Game.Utils; namespace osu.Game.Online.API { @@ -64,7 +65,15 @@ namespace osu.Game.Online.API } public bool Equals(IMod other) => other is APIMod them && Equals(them); - public bool Equals(APIMod other) => Acronym == other?.Acronym; + + public bool Equals(APIMod other) + { + if (ReferenceEquals(null, other)) return false; + if (ReferenceEquals(this, other)) return true; + + return Acronym == other.Acronym && + Settings.SequenceEqual(other.Settings, ModSettingsEqualityComparer.Default); + } public override string ToString() { @@ -73,5 +82,20 @@ namespace osu.Game.Online.API return $"{Acronym}"; } + + private class ModSettingsEqualityComparer : IEqualityComparer> + { + public static ModSettingsEqualityComparer Default { get; } = new ModSettingsEqualityComparer(); + + public bool Equals(KeyValuePair x, KeyValuePair y) + { + object xValue = ModUtils.GetSettingUnderlyingValue(x.Value); + object yValue = ModUtils.GetSettingUnderlyingValue(y.Value); + + return x.Key == y.Key && EqualityComparer.Default.Equals(xValue, yValue); + } + + public int GetHashCode(KeyValuePair obj) => HashCode.Combine(obj.Key, ModUtils.GetSettingUnderlyingValue(obj.Value)); + } } } diff --git a/osu.Game/Rulesets/Mods/Mod.cs b/osu.Game/Rulesets/Mods/Mod.cs index 93a11e70f8..832a14ee1e 100644 --- a/osu.Game/Rulesets/Mods/Mod.cs +++ b/osu.Game/Rulesets/Mods/Mod.cs @@ -12,6 +12,7 @@ using osu.Framework.Testing; using osu.Game.Configuration; using osu.Game.IO.Serialization; using osu.Game.Rulesets.UI; +using osu.Game.Utils; namespace osu.Game.Rulesets.Mods { @@ -173,7 +174,18 @@ namespace osu.Game.Rulesets.Mods } public bool Equals(IMod other) => other is Mod them && Equals(them); - public bool Equals(Mod other) => GetType() == other?.GetType(); + + public bool Equals(Mod other) + { + if (ReferenceEquals(null, other)) return false; + if (ReferenceEquals(this, other)) return true; + + return GetType() == other.GetType() && + this.GetSettingsSourceProperties().All(pair => + EqualityComparer.Default.Equals( + ModUtils.GetSettingUnderlyingValue(pair.Item2.GetValue(this)), + ModUtils.GetSettingUnderlyingValue(pair.Item2.GetValue(other)))); + } /// /// Reset all custom settings for this mod back to their defaults. From 589e1a2a471ef69c49d24d42d5b56df9362f7b6c Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Mon, 12 Apr 2021 20:51:24 +0300 Subject: [PATCH 07/15] Add mod settings equality test --- .../Mods/ModSettingsEqualityComparsion.cs | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 osu.Game.Tests/Mods/ModSettingsEqualityComparsion.cs diff --git a/osu.Game.Tests/Mods/ModSettingsEqualityComparsion.cs b/osu.Game.Tests/Mods/ModSettingsEqualityComparsion.cs new file mode 100644 index 0000000000..7a5789f01a --- /dev/null +++ b/osu.Game.Tests/Mods/ModSettingsEqualityComparsion.cs @@ -0,0 +1,36 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using NUnit.Framework; +using osu.Game.Online.API; +using osu.Game.Rulesets.Osu.Mods; + +namespace osu.Game.Tests.Mods +{ + [TestFixture] + public class ModSettingsEqualityComparison + { + [Test] + public void Test() + { + var mod1 = new OsuModDoubleTime { SpeedChange = { Value = 1.25 } }; + var mod2 = new OsuModDoubleTime { SpeedChange = { Value = 1.26 } }; + var mod3 = new OsuModDoubleTime { SpeedChange = { Value = 1.26 } }; + var apiMod1 = new APIMod(mod1); + var apiMod2 = new APIMod(mod2); + var apiMod3 = new APIMod(mod3); + + Assert.That(mod1, Is.Not.EqualTo(mod2)); + Assert.That(apiMod1, Is.Not.EqualTo(apiMod2)); + + Assert.That(mod2, Is.EqualTo(mod2)); + Assert.That(apiMod2, Is.EqualTo(apiMod2)); + + Assert.That(mod2, Is.EqualTo(mod3)); + Assert.That(apiMod2, Is.EqualTo(apiMod3)); + + Assert.That(mod3, Is.EqualTo(mod2)); + Assert.That(apiMod3, Is.EqualTo(apiMod2)); + } + } +} From 17c2c4e885b63761fa179ddc2ee193b6078a4b03 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Tue, 13 Apr 2021 05:31:56 +0300 Subject: [PATCH 08/15] Fix test case filename not matching --- ...ingsEqualityComparsion.cs => ModSettingsEqualityComparison.cs} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename osu.Game.Tests/Mods/{ModSettingsEqualityComparsion.cs => ModSettingsEqualityComparison.cs} (100%) diff --git a/osu.Game.Tests/Mods/ModSettingsEqualityComparsion.cs b/osu.Game.Tests/Mods/ModSettingsEqualityComparison.cs similarity index 100% rename from osu.Game.Tests/Mods/ModSettingsEqualityComparsion.cs rename to osu.Game.Tests/Mods/ModSettingsEqualityComparison.cs From 273099d53c6b0dfab4a694055fc12bf45d5611f2 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 13 Apr 2021 14:31:41 +0900 Subject: [PATCH 09/15] Don't store online IDs from score submission responses for now Closes remaining portion of https://github.com/ppy/osu/issues/12372. --- osu.Game/Screens/Play/SubmittingPlayer.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Play/SubmittingPlayer.cs b/osu.Game/Screens/Play/SubmittingPlayer.cs index d22199447d..b64d835c58 100644 --- a/osu.Game/Screens/Play/SubmittingPlayer.cs +++ b/osu.Game/Screens/Play/SubmittingPlayer.cs @@ -109,7 +109,12 @@ namespace osu.Game.Screens.Play request.Success += s => { - score.ScoreInfo.OnlineScoreID = s.ID; + // For the time being, online ID responses are not really useful for anything. + // In addition, the IDs provided via new (lazer) endpoints are based on a different autoincrement from legacy (stable) scores. + // + // Until we better define the server-side logic behind this, let's not store the online ID to avoid potential unique constraint + // conflicts across various systems (ie. solo and multiplayer). + // score.ScoreInfo.OnlineScoreID = s.ID; tcs.SetResult(true); }; From a9652b7b259b2921648c220e1d7f2ccf98276afa Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 13 Apr 2021 16:05:12 +0900 Subject: [PATCH 10/15] Start TimelineTestScene in a more visible place --- osu.Game.Tests/Visual/Editing/TimelineTestScene.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/osu.Game.Tests/Visual/Editing/TimelineTestScene.cs b/osu.Game.Tests/Visual/Editing/TimelineTestScene.cs index 1da6433707..88b4614791 100644 --- a/osu.Game.Tests/Visual/Editing/TimelineTestScene.cs +++ b/osu.Game.Tests/Visual/Editing/TimelineTestScene.cs @@ -64,6 +64,13 @@ namespace osu.Game.Tests.Visual.Editing }); } + protected override void LoadComplete() + { + base.LoadComplete(); + + Clock.Seek(2500); + } + public abstract Drawable CreateTestComponent(); private class AudioVisualiser : CompositeDrawable From ebf97ff48ff43a5879b19fcb9365c84c8369fe21 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 13 Apr 2021 16:25:43 +0900 Subject: [PATCH 11/15] Update timeline ticks to use width as a differentiation method, rather than height --- .../Visualisations/PointVisualisation.cs | 10 ++-- .../Timeline/TimelineTickDisplay.cs | 56 +++++++++++-------- 2 files changed, 39 insertions(+), 27 deletions(-) diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/Visualisations/PointVisualisation.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/Visualisations/PointVisualisation.cs index b0ecffdd24..b5c4cd6dda 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Visualisations/PointVisualisation.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Visualisations/PointVisualisation.cs @@ -3,7 +3,6 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Shapes; -using osuTK; namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Visualisations { @@ -12,7 +11,7 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Visualisations /// public class PointVisualisation : Box { - public const float WIDTH = 1; + public const float MAX_WIDTH = 5; public PointVisualisation(double startTime) : this() @@ -27,8 +26,11 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Visualisations RelativePositionAxes = Axes.X; RelativeSizeAxes = Axes.Y; - Width = WIDTH; - EdgeSmoothness = new Vector2(WIDTH, 0); + Anchor = Anchor.CentreLeft; + Origin = Anchor.Centre; + + Width = MAX_WIDTH; + Height = 0.75f; } } } diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineTickDisplay.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineTickDisplay.cs index c070c833f8..7ec5bb7197 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineTickDisplay.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineTickDisplay.cs @@ -6,9 +6,7 @@ using System.Linq; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Caching; -using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; -using osu.Framework.Graphics.Colour; using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Screens.Edit.Components.Timelines.Summary.Parts; @@ -33,6 +31,8 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline [Resolved] private OsuColour colours { get; set; } + private static readonly int highest_divisor = BindableBeatDivisor.VALID_DIVISORS.Last(); + public TimelineTickDisplay() { RelativeSizeAxes = Axes.Both; @@ -80,8 +80,8 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline if (timeline != null) { var newRange = ( - (ToLocalSpace(timeline.ScreenSpaceDrawQuad.TopLeft).X - PointVisualisation.WIDTH * 2) / DrawWidth * Content.RelativeChildSize.X, - (ToLocalSpace(timeline.ScreenSpaceDrawQuad.TopRight).X + PointVisualisation.WIDTH * 2) / DrawWidth * Content.RelativeChildSize.X); + (ToLocalSpace(timeline.ScreenSpaceDrawQuad.TopLeft).X - PointVisualisation.MAX_WIDTH * 2) / DrawWidth * Content.RelativeChildSize.X, + (ToLocalSpace(timeline.ScreenSpaceDrawQuad.TopRight).X + PointVisualisation.MAX_WIDTH * 2) / DrawWidth * Content.RelativeChildSize.X); if (visibleRange != newRange) { @@ -100,7 +100,6 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline private void createTicks() { int drawableIndex = 0; - int highestDivisor = BindableBeatDivisor.VALID_DIVISORS.Last(); nextMinTick = null; nextMaxTick = null; @@ -131,25 +130,12 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline var divisor = BindableBeatDivisor.GetDivisorForBeatIndex(beat, beatDivisor.Value); var colour = BindableBeatDivisor.GetColourFor(divisor, colours); - bool isMainBeat = indexInBar == 0; - // even though "bar lines" take up the full vertical space, we render them in two pieces because it allows for less anchor/origin churn. - float height = isMainBeat ? 0.5f : 0.4f - (float)divisor / highestDivisor * 0.2f; - float gradientOpacity = isMainBeat ? 1 : 0; - var topPoint = getNextUsablePoint(); - topPoint.X = xPos; - topPoint.Height = height; - topPoint.Colour = ColourInfo.GradientVertical(colour, colour.Opacity(gradientOpacity)); - topPoint.Anchor = Anchor.TopLeft; - topPoint.Origin = Anchor.TopCentre; - - var bottomPoint = getNextUsablePoint(); - bottomPoint.X = xPos; - bottomPoint.Anchor = Anchor.BottomLeft; - bottomPoint.Colour = ColourInfo.GradientVertical(colour.Opacity(gradientOpacity), colour); - bottomPoint.Origin = Anchor.BottomCentre; - bottomPoint.Height = height; + var line = getNextUsableLine(); + line.X = xPos; + line.Width = PointVisualisation.MAX_WIDTH * getWidth(indexInBar, divisor); + line.Colour = colour; } beat++; @@ -168,7 +154,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline tickCache.Validate(); - Drawable getNextUsablePoint() + Drawable getNextUsableLine() { PointVisualisation point; if (drawableIndex >= Count) @@ -183,6 +169,30 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline } } + private static float getWidth(int indexInBar, int divisor) + { + if (indexInBar == 0) + return 1; + + switch (divisor) + { + case 1: + case 2: + return 0.6f; + + case 3: + case 4: + return 0.5f; + + case 6: + case 8: + return 0.4f; + + default: + return 0.3f; + } + } + protected override void Dispose(bool isDisposing) { base.Dispose(isDisposing); From 27e851c2eed2b0edc1833a620e7ec4e9e85973f0 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 13 Apr 2021 16:41:29 +0900 Subject: [PATCH 12/15] Also adjust height --- .../Visualisations/PointVisualisation.cs | 2 +- .../Timeline/TimelineTickDisplay.cs | 25 +++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/Visualisations/PointVisualisation.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/Visualisations/PointVisualisation.cs index b5c4cd6dda..53a1f94731 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Visualisations/PointVisualisation.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Visualisations/PointVisualisation.cs @@ -11,7 +11,7 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Visualisations /// public class PointVisualisation : Box { - public const float MAX_WIDTH = 5; + public const float MAX_WIDTH = 4; public PointVisualisation(double startTime) : this() diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineTickDisplay.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineTickDisplay.cs index 7ec5bb7197..3aaf0451c8 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineTickDisplay.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineTickDisplay.cs @@ -135,6 +135,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline var line = getNextUsableLine(); line.X = xPos; line.Width = PointVisualisation.MAX_WIDTH * getWidth(indexInBar, divisor); + line.Height = 0.9f * getHeight(indexInBar, divisor); line.Colour = colour; } @@ -193,6 +194,30 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline } } + private static float getHeight(int indexInBar, int divisor) + { + if (indexInBar == 0) + return 1; + + switch (divisor) + { + case 1: + case 2: + return 0.9f; + + case 3: + case 4: + return 0.8f; + + case 6: + case 8: + return 0.7f; + + default: + return 0.6f; + } + } + protected override void Dispose(bool isDisposing) { base.Dispose(isDisposing); From 5a06db8a113dfd012a46b304f9967508f0ca609e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 13 Apr 2021 16:48:05 +0900 Subject: [PATCH 13/15] Change default editor waveform opacity to 25% The previous setting felt way too high. --- osu.Game/Configuration/OsuConfigManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs index 387cfbb193..0525e84077 100644 --- a/osu.Game/Configuration/OsuConfigManager.cs +++ b/osu.Game/Configuration/OsuConfigManager.cs @@ -143,7 +143,7 @@ namespace osu.Game.Configuration SetDefault(OsuSetting.DiscordRichPresence, DiscordRichPresenceMode.Full); - SetDefault(OsuSetting.EditorWaveformOpacity, 1f); + SetDefault(OsuSetting.EditorWaveformOpacity, 0.25f); } public OsuConfigManager(Storage storage) From 0932daeaa8564fe9fd9e25560abe1bfa5a8b20b3 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 13 Apr 2021 16:50:03 +0900 Subject: [PATCH 14/15] Force the new default on update --- osu.Game/Configuration/OsuConfigManager.cs | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs index 0525e84077..21a1a1d430 100644 --- a/osu.Game/Configuration/OsuConfigManager.cs +++ b/osu.Game/Configuration/OsuConfigManager.cs @@ -169,14 +169,9 @@ namespace osu.Game.Configuration int combined = (year * 10000) + monthDay; - if (combined < 20200305) + if (combined < 20210413) { - // the maximum value of this setting was changed. - // if we don't manually increase this, it causes song select to filter out beatmaps the user expects to see. - var maxStars = (BindableDouble)GetOriginalBindable(OsuSetting.DisplayStarsMaximum); - - if (maxStars.Value == 10) - maxStars.Value = maxStars.MaxValue; + SetValue(OsuSetting.EditorWaveformOpacity, 0.25f); } } From b41e3a2e7a84046981007ebc6a6d2ecd85d1b42b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 13 Apr 2021 17:38:13 +0900 Subject: [PATCH 15/15] Remove unused using statement --- osu.Game/Configuration/OsuConfigManager.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs index 21a1a1d430..f9b1c9618b 100644 --- a/osu.Game/Configuration/OsuConfigManager.cs +++ b/osu.Game/Configuration/OsuConfigManager.cs @@ -3,7 +3,6 @@ using System; using System.Diagnostics; -using osu.Framework.Bindables; using osu.Framework.Configuration; using osu.Framework.Configuration.Tracking; using osu.Framework.Extensions;