From e25cca6fbe0271976e1a711ab0037c6493b412f0 Mon Sep 17 00:00:00 2001 From: ekrctb Date: Mon, 31 May 2021 14:37:28 +0900 Subject: [PATCH 01/32] Update drawable lifetime on entry lifetime change --- .../Pooling/PoolableDrawableWithLifetime.cs | 42 +++++++++++++------ 1 file changed, 29 insertions(+), 13 deletions(-) diff --git a/osu.Game/Rulesets/Objects/Pooling/PoolableDrawableWithLifetime.cs b/osu.Game/Rulesets/Objects/Pooling/PoolableDrawableWithLifetime.cs index 64e1ac16bd..66d4421cdb 100644 --- a/osu.Game/Rulesets/Objects/Pooling/PoolableDrawableWithLifetime.cs +++ b/osu.Game/Rulesets/Objects/Pooling/PoolableDrawableWithLifetime.cs @@ -3,6 +3,7 @@ #nullable enable +using System; using System.Diagnostics; using osu.Framework.Graphics.Performance; using osu.Framework.Graphics.Pooling; @@ -26,17 +27,18 @@ namespace osu.Game.Rulesets.Objects.Pooling /// protected bool HasEntryApplied { get; private set; } - // Drawable's lifetime gets out of sync with entry's lifetime if entry's lifetime is modified. - // We cannot delegate getter to `Entry.LifetimeStart` because it is incompatible with `LifetimeManagementContainer` due to how lifetime change is detected. public override double LifetimeStart { get => base.LifetimeStart; set { - base.LifetimeStart = value; + if (Entry == null && LifetimeStart != value) + throw new InvalidOperationException($"Cannot modify lifetime of {nameof(PoolableDrawableWithLifetime)} when entry is not set"); - if (Entry != null) - Entry.LifetimeStart = value; + if (Entry == null) return; + + Entry.LifetimeStart = value; + base.LifetimeStart = Entry.LifetimeStart; } } @@ -45,10 +47,13 @@ namespace osu.Game.Rulesets.Objects.Pooling get => base.LifetimeEnd; set { - base.LifetimeEnd = value; + if (Entry == null && LifetimeEnd != value) + throw new InvalidOperationException($"Cannot modify lifetime of {nameof(PoolableDrawableWithLifetime)} when entry is not set"); - if (Entry != null) - Entry.LifetimeEnd = value; + if (Entry == null) return; + + Entry.LifetimeEnd = value; + base.LifetimeEnd = Entry.LifetimeEnd; } } @@ -79,9 +84,8 @@ namespace osu.Game.Rulesets.Objects.Pooling free(); Entry = entry; - - base.LifetimeStart = entry.LifetimeStart; - base.LifetimeEnd = entry.LifetimeEnd; + entry.LifetimeChanged += entryLifetimeChanged; + setLifetimeFromEntry(); OnApply(entry); @@ -117,11 +121,23 @@ namespace osu.Game.Rulesets.Objects.Pooling OnFree(Entry); + Entry.LifetimeChanged -= entryLifetimeChanged; Entry = null; - base.LifetimeStart = double.MinValue; - base.LifetimeEnd = double.MaxValue; + setLifetimeFromEntry(); HasEntryApplied = false; } + + private void entryLifetimeChanged(LifetimeEntry entry) + { + Debug.Assert(entry == Entry); + setLifetimeFromEntry(); + } + + private void setLifetimeFromEntry() + { + base.LifetimeStart = Entry?.LifetimeStart ?? double.MinValue; + base.LifetimeEnd = Entry?.LifetimeEnd ?? double.MaxValue; + } } } From b7afea37c4f8facce6a43e362371c2470110572c Mon Sep 17 00:00:00 2001 From: ekrctb Date: Mon, 31 May 2021 14:37:51 +0900 Subject: [PATCH 02/32] Test drawable lifetime change on entry lifetime change --- .../Gameplay/TestSceneDrawableHitObject.cs | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/osu.Game.Tests/Gameplay/TestSceneDrawableHitObject.cs b/osu.Game.Tests/Gameplay/TestSceneDrawableHitObject.cs index 3de2dc72bb..5dfc9a2786 100644 --- a/osu.Game.Tests/Gameplay/TestSceneDrawableHitObject.cs +++ b/osu.Game.Tests/Gameplay/TestSceneDrawableHitObject.cs @@ -92,6 +92,35 @@ namespace osu.Game.Tests.Gameplay AddAssert("Lifetime is correct", () => dho.LifetimeStart == TestDrawableHitObject.LIFETIME_ON_APPLY && entry.LifetimeStart == TestDrawableHitObject.LIFETIME_ON_APPLY); } + [Test] + public void TestDrawableLifetimeUpdateOnEntryLifetimeChange() + { + TestDrawableHitObject dho = null; + TestLifetimeEntry entry = null; + AddStep("Create DHO", () => + { + dho = new TestDrawableHitObject(null); + dho.Apply(entry = new TestLifetimeEntry(new HitObject())); + Child = dho; + }); + + AddStep("Set entry lifetime", () => + { + entry.LifetimeStart = 777; + entry.LifetimeEnd = 888; + }); + AddAssert("Drawable lifetime is updated", () => dho.LifetimeStart == 777 && dho.LifetimeEnd == 888); + + AddStep("KeepAlive = true", () => entry.KeepAlive = true); + AddAssert("Drawable lifetime is updated", () => dho.LifetimeStart == double.MinValue && dho.LifetimeEnd == double.MaxValue); + + AddStep("Modify start time", () => entry.HitObject.StartTime = 100); + AddAssert("Drawable lifetime is correct", () => dho.LifetimeStart == double.MinValue); + + AddStep("KeepAlive = false", () => entry.KeepAlive = false); + AddAssert("Drawable lifetime is restored", () => dho.LifetimeStart == 100 - TestLifetimeEntry.INITIAL_LIFETIME_OFFSET); + } + private class TestDrawableHitObject : DrawableHitObject { public const double INITIAL_LIFETIME_OFFSET = 100; From 771f3c48c08874c7cf2b8564c153c01ef2561619 Mon Sep 17 00:00:00 2001 From: ekrctb Date: Mon, 31 May 2021 14:48:52 +0900 Subject: [PATCH 03/32] Add failing test showing lifetime not recomputed with pooled objects --- .../Gameplay/TestSceneDrawableScrollingRuleset.cs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneDrawableScrollingRuleset.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneDrawableScrollingRuleset.cs index 9931ee4a45..75a5eec6f7 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneDrawableScrollingRuleset.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneDrawableScrollingRuleset.cs @@ -90,6 +90,20 @@ namespace osu.Game.Tests.Visual.Gameplay assertChildPosition(5); } + [TestCase("pooled")] + [TestCase("non-pooled")] + public void TestLifetimeRecomputedWhenTimeRangeChanges(string pooled) + { + var beatmap = createBeatmap(_ => pooled == "pooled" ? new TestPooledHitObject() : new TestHitObject()); + beatmap.ControlPointInfo.Add(0, new TimingControlPoint { BeatLength = time_range }); + createTest(beatmap); + + assertDead(3); + + AddStep("increase time range", () => drawableRuleset.TimeRange.Value = 3 * time_range); + assertPosition(3, 1); + } + [Test] public void TestRelativeBeatLengthScaleSingleTimingPoint() { From 56a0a24cbaf0d09df98929f2ff7576d85a00971a Mon Sep 17 00:00:00 2001 From: ekrctb Date: Mon, 31 May 2021 15:33:28 +0900 Subject: [PATCH 04/32] Make SetInitialLifetime public --- osu.Game/Rulesets/Objects/HitObjectLifetimeEntry.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Rulesets/Objects/HitObjectLifetimeEntry.cs b/osu.Game/Rulesets/Objects/HitObjectLifetimeEntry.cs index f654fa91cf..5ad0d6246e 100644 --- a/osu.Game/Rulesets/Objects/HitObjectLifetimeEntry.cs +++ b/osu.Game/Rulesets/Objects/HitObjectLifetimeEntry.cs @@ -35,11 +35,11 @@ namespace osu.Game.Rulesets.Objects HitObject = hitObject; startTimeBindable.BindTo(HitObject.StartTimeBindable); - startTimeBindable.BindValueChanged(_ => setInitialLifetime(), true); + startTimeBindable.BindValueChanged(_ => SetInitialLifetime(), true); // Subscribe to this event before the DrawableHitObject so that the local callback is invoked before the entry is re-applied as a result of DefaultsApplied. // This way, the DrawableHitObject can use OnApply() to overwrite the LifetimeStart that was set inside setInitialLifetime(). - HitObject.DefaultsApplied += _ => setInitialLifetime(); + HitObject.DefaultsApplied += _ => SetInitialLifetime(); } // The lifetime, as set by the hitobject. @@ -94,6 +94,6 @@ namespace osu.Game.Rulesets.Objects /// /// Set using . /// - private void setInitialLifetime() => LifetimeStart = HitObject.StartTime - InitialLifetimeOffset; + public void SetInitialLifetime() => LifetimeStart = HitObject.StartTime - InitialLifetimeOffset; } } From 86d1225aad80e1ac2cd79e2b22719b1df895713b Mon Sep 17 00:00:00 2001 From: ekrctb Date: Mon, 31 May 2021 16:10:31 +0900 Subject: [PATCH 05/32] Reset lifetime to initial lifetime when layout is invalidated --- .../UI/Scrolling/ScrollingHitObjectContainer.cs | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs b/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs index a9eaf3da68..10d6815c0a 100644 --- a/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs +++ b/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs @@ -195,15 +195,13 @@ namespace osu.Game.Rulesets.UI.Scrolling if (!layoutCache.IsValid) { toComputeLifetime.Clear(); - - foreach (var hitObject in Objects) - { - if (hitObject.HitObject != null) - toComputeLifetime.Add(hitObject); - } - layoutComputed.Clear(); + // Reset lifetime to the conservative estimation. + // If a drawable becomes alive by this lifetime, its lifetime will be updated to a more precise lifetime in the next update. + foreach (var entry in Entries) + entry.SetInitialLifetime(); + scrollingInfo.Algorithm.Reset(); switch (direction.Value) From d5714e63b9611f2743130f5c689e5b95a6f4f53b Mon Sep 17 00:00:00 2001 From: ekrctb Date: Tue, 1 Jun 2021 13:17:30 +0900 Subject: [PATCH 06/32] Apply code styling suggestions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bartłomiej Dach --- .../Pooling/PoolableDrawableWithLifetime.cs | 26 +++++++------------ 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/osu.Game/Rulesets/Objects/Pooling/PoolableDrawableWithLifetime.cs b/osu.Game/Rulesets/Objects/Pooling/PoolableDrawableWithLifetime.cs index 66d4421cdb..5125243bfc 100644 --- a/osu.Game/Rulesets/Objects/Pooling/PoolableDrawableWithLifetime.cs +++ b/osu.Game/Rulesets/Objects/Pooling/PoolableDrawableWithLifetime.cs @@ -37,8 +37,7 @@ namespace osu.Game.Rulesets.Objects.Pooling if (Entry == null) return; - Entry.LifetimeStart = value; - base.LifetimeStart = Entry.LifetimeStart; + base.LifetimeStart = Entry.LifetimeStart = value; } } @@ -52,8 +51,7 @@ namespace osu.Game.Rulesets.Objects.Pooling if (Entry == null) return; - Entry.LifetimeEnd = value; - base.LifetimeEnd = Entry.LifetimeEnd; + base.LifetimeEnd = Entry.LifetimeEnd = value; } } @@ -84,8 +82,8 @@ namespace osu.Game.Rulesets.Objects.Pooling free(); Entry = entry; - entry.LifetimeChanged += entryLifetimeChanged; - setLifetimeFromEntry(); + entry.LifetimeChanged += setLifetimeFromEntry; + setLifetimeFromEntry(entry); OnApply(entry); @@ -121,23 +119,19 @@ namespace osu.Game.Rulesets.Objects.Pooling OnFree(Entry); - Entry.LifetimeChanged -= entryLifetimeChanged; + Entry.LifetimeChanged -= setLifetimeFromEntry; Entry = null; - setLifetimeFromEntry(); + base.LifetimeStart = double.MinValue; + base.LifetimeEnd = double.MaxValue; HasEntryApplied = false; } - private void entryLifetimeChanged(LifetimeEntry entry) + private void setLifetimeFromEntry(LifetimeEntry entry) { Debug.Assert(entry == Entry); - setLifetimeFromEntry(); - } - - private void setLifetimeFromEntry() - { - base.LifetimeStart = Entry?.LifetimeStart ?? double.MinValue; - base.LifetimeEnd = Entry?.LifetimeEnd ?? double.MaxValue; + base.LifetimeStart = entry.LifetimeStart; + base.LifetimeEnd = entry.LifetimeEnd; } } } From 1a05a5d2f02dca6d74be4c8af2a33e111379d8f1 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 1 Jun 2021 13:50:04 +0900 Subject: [PATCH 07/32] Add test covering failure to resolve relative URLs --- osu.Game.Tests/Chat/MessageFormatterTests.cs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/osu.Game.Tests/Chat/MessageFormatterTests.cs b/osu.Game.Tests/Chat/MessageFormatterTests.cs index b80da928c8..6f9007d670 100644 --- a/osu.Game.Tests/Chat/MessageFormatterTests.cs +++ b/osu.Game.Tests/Chat/MessageFormatterTests.cs @@ -489,5 +489,14 @@ namespace osu.Game.Tests.Chat Assert.AreEqual(result.Links[2].Url, "\uD83D\uDE00"); Assert.AreEqual(result.Links[3].Url, "\uD83D\uDE20"); } + + [Test] + public void TestRelativeExternalLinks() + { + LinkDetails result = MessageFormatter.GetLinkDetails("/relative"); + + Assert.AreEqual(LinkAction.External, result.Action); + Assert.AreEqual("/relative", result.Argument); + } } } From 111bfd4d88abe484931b8789d36653832b005264 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 1 Jun 2021 13:50:20 +0900 Subject: [PATCH 08/32] Fix relative URLs having a null argument after resolution to `LinkDetails` --- osu.Game/Online/Chat/MessageFormatter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Online/Chat/MessageFormatter.cs b/osu.Game/Online/Chat/MessageFormatter.cs index b80720a0aa..54d7030457 100644 --- a/osu.Game/Online/Chat/MessageFormatter.cs +++ b/osu.Game/Online/Chat/MessageFormatter.cs @@ -217,7 +217,7 @@ namespace osu.Game.Online.Chat return new LinkDetails(LinkAction.JoinMultiplayerMatch, args[1]); } - return new LinkDetails(LinkAction.External, null); + return new LinkDetails(LinkAction.External, url); } private static MessageFormatterResult format(string toFormat, int startIndex = 0, int space = 3) From a9f4bc6285dcc84bd9cf4582b6bc2b7557815908 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 1 Jun 2021 14:09:35 +0900 Subject: [PATCH 09/32] Never return a null argument Enable nullable --- osu.Game.Tests/Chat/MessageFormatterTests.cs | 13 +++++++++++-- osu.Game/Online/Chat/MessageFormatter.cs | 8 +++++--- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/osu.Game.Tests/Chat/MessageFormatterTests.cs b/osu.Game.Tests/Chat/MessageFormatterTests.cs index 6f9007d670..ecb37706b0 100644 --- a/osu.Game.Tests/Chat/MessageFormatterTests.cs +++ b/osu.Game.Tests/Chat/MessageFormatterTests.cs @@ -24,10 +24,10 @@ namespace osu.Game.Tests.Chat [TestCase(LinkAction.OpenBeatmap, "456", "https://dev.ppy.sh/beatmapsets/123#osu/456")] [TestCase(LinkAction.OpenBeatmap, "456", "https://dev.ppy.sh/beatmapsets/123#osu/456?whatever")] [TestCase(LinkAction.OpenBeatmap, "456", "https://dev.ppy.sh/beatmapsets/123/456")] - [TestCase(LinkAction.External, null, "https://dev.ppy.sh/beatmapsets/abc/def")] + [TestCase(LinkAction.External, "https://dev.ppy.sh/beatmapsets/abc/def", "https://dev.ppy.sh/beatmapsets/abc/def")] [TestCase(LinkAction.OpenBeatmapSet, "123", "https://dev.ppy.sh/beatmapsets/123")] [TestCase(LinkAction.OpenBeatmapSet, "123", "https://dev.ppy.sh/beatmapsets/123/whatever")] - [TestCase(LinkAction.External, null, "https://dev.ppy.sh/beatmapsets/abc")] + [TestCase(LinkAction.External, "https://dev.ppy.sh/beatmapsets/abc", "https://dev.ppy.sh/beatmapsets/abc")] public void TestBeatmapLinks(LinkAction expectedAction, string expectedArg, string link) { MessageFormatter.WebsiteRootUrl = "dev.ppy.sh"; @@ -490,6 +490,15 @@ namespace osu.Game.Tests.Chat Assert.AreEqual(result.Links[3].Url, "\uD83D\uDE20"); } + [Test] + public void TestAbsoluteExternalLinks() + { + LinkDetails result = MessageFormatter.GetLinkDetails("https://google.com"); + + Assert.AreEqual(LinkAction.External, result.Action); + Assert.AreEqual("https://google.com", result.Argument); + } + [Test] public void TestRelativeExternalLinks() { diff --git a/osu.Game/Online/Chat/MessageFormatter.cs b/osu.Game/Online/Chat/MessageFormatter.cs index 54d7030457..e08cb1b35f 100644 --- a/osu.Game/Online/Chat/MessageFormatter.cs +++ b/osu.Game/Online/Chat/MessageFormatter.cs @@ -6,6 +6,8 @@ using System.Collections.Generic; using System.Linq; using System.Text.RegularExpressions; +#nullable enable + namespace osu.Game.Online.Chat { public static class MessageFormatter @@ -61,7 +63,7 @@ namespace osu.Game.Online.Chat private static string websiteRootUrl = "osu.ppy.sh"; - private static void handleMatches(Regex regex, string display, string link, MessageFormatterResult result, int startIndex = 0, LinkAction? linkActionOverride = null, char[] escapeChars = null) + private static void handleMatches(Regex regex, string display, string link, MessageFormatterResult result, int startIndex = 0, LinkAction? linkActionOverride = null, char[]? escapeChars = null) { int captureOffset = 0; @@ -170,12 +172,12 @@ namespace osu.Game.Online.Chat } } - return new LinkDetails(LinkAction.External, null); + break; case "osu": // every internal link also needs some kind of argument if (args.Length < 3) - return new LinkDetails(LinkAction.External, null); + break; LinkAction linkType; From 86020adf6463efc2565a5ffb518270eb91ce5285 Mon Sep 17 00:00:00 2001 From: ekrctb Date: Tue, 1 Jun 2021 14:22:12 +0900 Subject: [PATCH 10/32] Revert invalid code transformation --- .../Rulesets/Objects/Pooling/PoolableDrawableWithLifetime.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Objects/Pooling/PoolableDrawableWithLifetime.cs b/osu.Game/Rulesets/Objects/Pooling/PoolableDrawableWithLifetime.cs index 5125243bfc..b1515e2ac2 100644 --- a/osu.Game/Rulesets/Objects/Pooling/PoolableDrawableWithLifetime.cs +++ b/osu.Game/Rulesets/Objects/Pooling/PoolableDrawableWithLifetime.cs @@ -37,6 +37,8 @@ namespace osu.Game.Rulesets.Objects.Pooling if (Entry == null) return; + // Cannot write it as `base.LifetimeStart = Entry.LifetimeStart = value` because the change may be blocked (when `HitObjectLifetimeEntry.KeepAlive` is true). + Entry.LifetimeStart = value; base.LifetimeStart = Entry.LifetimeStart = value; } } @@ -51,7 +53,8 @@ namespace osu.Game.Rulesets.Objects.Pooling if (Entry == null) return; - base.LifetimeEnd = Entry.LifetimeEnd = value; + Entry.LifetimeEnd = value; + base.LifetimeEnd = Entry.LifetimeEnd; } } From 977d44df87a22eeed43851a89b86525523c8d51c Mon Sep 17 00:00:00 2001 From: ekrctb Date: Tue, 1 Jun 2021 14:25:32 +0900 Subject: [PATCH 11/32] Add test catching lifetime change while KeepAlive is true --- osu.Game.Tests/Gameplay/TestSceneDrawableHitObject.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/osu.Game.Tests/Gameplay/TestSceneDrawableHitObject.cs b/osu.Game.Tests/Gameplay/TestSceneDrawableHitObject.cs index 5dfc9a2786..b5b3cec15d 100644 --- a/osu.Game.Tests/Gameplay/TestSceneDrawableHitObject.cs +++ b/osu.Game.Tests/Gameplay/TestSceneDrawableHitObject.cs @@ -117,8 +117,12 @@ namespace osu.Game.Tests.Gameplay AddStep("Modify start time", () => entry.HitObject.StartTime = 100); AddAssert("Drawable lifetime is correct", () => dho.LifetimeStart == double.MinValue); + AddStep("Set LifetimeEnd", () => dho.LifetimeEnd = 999); + AddAssert("Lifetime change is blocked", () => dho.LifetimeEnd == double.MaxValue); + AddStep("KeepAlive = false", () => entry.KeepAlive = false); - AddAssert("Drawable lifetime is restored", () => dho.LifetimeStart == 100 - TestLifetimeEntry.INITIAL_LIFETIME_OFFSET); + AddAssert("Drawable lifetime is restored", () => + dho.LifetimeStart == 100 - TestLifetimeEntry.INITIAL_LIFETIME_OFFSET && dho.LifetimeEnd == 999); } private class TestDrawableHitObject : DrawableHitObject From 0f381f7758d567f4dc4796beceec10a02ba67db1 Mon Sep 17 00:00:00 2001 From: ekrctb Date: Tue, 1 Jun 2021 14:38:02 +0900 Subject: [PATCH 12/32] Fix wrong code --- osu.Game.Tests/Gameplay/TestSceneDrawableHitObject.cs | 6 ++++-- .../Objects/Pooling/PoolableDrawableWithLifetime.cs | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/osu.Game.Tests/Gameplay/TestSceneDrawableHitObject.cs b/osu.Game.Tests/Gameplay/TestSceneDrawableHitObject.cs index b5b3cec15d..da0d57f9d1 100644 --- a/osu.Game.Tests/Gameplay/TestSceneDrawableHitObject.cs +++ b/osu.Game.Tests/Gameplay/TestSceneDrawableHitObject.cs @@ -117,12 +117,14 @@ namespace osu.Game.Tests.Gameplay AddStep("Modify start time", () => entry.HitObject.StartTime = 100); AddAssert("Drawable lifetime is correct", () => dho.LifetimeStart == double.MinValue); + AddStep("Set LifetimeStart", () => dho.LifetimeStart = 666); + AddAssert("Lifetime change is blocked", () => dho.LifetimeStart == double.MinValue); + AddStep("Set LifetimeEnd", () => dho.LifetimeEnd = 999); AddAssert("Lifetime change is blocked", () => dho.LifetimeEnd == double.MaxValue); AddStep("KeepAlive = false", () => entry.KeepAlive = false); - AddAssert("Drawable lifetime is restored", () => - dho.LifetimeStart == 100 - TestLifetimeEntry.INITIAL_LIFETIME_OFFSET && dho.LifetimeEnd == 999); + AddAssert("Drawable lifetime is restored", () => dho.LifetimeStart == 666 && dho.LifetimeEnd == 999); } private class TestDrawableHitObject : DrawableHitObject diff --git a/osu.Game/Rulesets/Objects/Pooling/PoolableDrawableWithLifetime.cs b/osu.Game/Rulesets/Objects/Pooling/PoolableDrawableWithLifetime.cs index b1515e2ac2..fb1baf1d65 100644 --- a/osu.Game/Rulesets/Objects/Pooling/PoolableDrawableWithLifetime.cs +++ b/osu.Game/Rulesets/Objects/Pooling/PoolableDrawableWithLifetime.cs @@ -39,7 +39,7 @@ namespace osu.Game.Rulesets.Objects.Pooling // Cannot write it as `base.LifetimeStart = Entry.LifetimeStart = value` because the change may be blocked (when `HitObjectLifetimeEntry.KeepAlive` is true). Entry.LifetimeStart = value; - base.LifetimeStart = Entry.LifetimeStart = value; + base.LifetimeStart = Entry.LifetimeStart; } } From 40949f6c1b0c1088f4c28b94b8f9c30084952f69 Mon Sep 17 00:00:00 2001 From: ekrctb Date: Tue, 1 Jun 2021 14:46:43 +0900 Subject: [PATCH 13/32] Simplify lifetime setter Setting entry lifetime will cause `LifetimeChanged` event and `base.LifetimeStart`/`End` will be modified in the callback. --- .../Objects/Pooling/PoolableDrawableWithLifetime.cs | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/osu.Game/Rulesets/Objects/Pooling/PoolableDrawableWithLifetime.cs b/osu.Game/Rulesets/Objects/Pooling/PoolableDrawableWithLifetime.cs index fb1baf1d65..4440ca8d21 100644 --- a/osu.Game/Rulesets/Objects/Pooling/PoolableDrawableWithLifetime.cs +++ b/osu.Game/Rulesets/Objects/Pooling/PoolableDrawableWithLifetime.cs @@ -35,11 +35,8 @@ namespace osu.Game.Rulesets.Objects.Pooling if (Entry == null && LifetimeStart != value) throw new InvalidOperationException($"Cannot modify lifetime of {nameof(PoolableDrawableWithLifetime)} when entry is not set"); - if (Entry == null) return; - - // Cannot write it as `base.LifetimeStart = Entry.LifetimeStart = value` because the change may be blocked (when `HitObjectLifetimeEntry.KeepAlive` is true). - Entry.LifetimeStart = value; - base.LifetimeStart = Entry.LifetimeStart; + if (Entry != null) + Entry.LifetimeStart = value; } } @@ -51,10 +48,8 @@ namespace osu.Game.Rulesets.Objects.Pooling if (Entry == null && LifetimeEnd != value) throw new InvalidOperationException($"Cannot modify lifetime of {nameof(PoolableDrawableWithLifetime)} when entry is not set"); - if (Entry == null) return; - - Entry.LifetimeEnd = value; - base.LifetimeEnd = Entry.LifetimeEnd; + if (Entry != null) + Entry.LifetimeEnd = value; } } From 1babb05fc7ee51aef25d53468ae7b2d1129a485e Mon Sep 17 00:00:00 2001 From: Gagah Pangeran Rosfatiputra Date: Tue, 1 Jun 2021 14:03:05 +0700 Subject: [PATCH 14/32] add OsuMarkdownInlineCode --- .../Markdown/OsuMarkdownTextFlowContainer.cs | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/osu.Game/Graphics/Containers/Markdown/OsuMarkdownTextFlowContainer.cs b/osu.Game/Graphics/Containers/Markdown/OsuMarkdownTextFlowContainer.cs index c3527fa99a..267a5befb5 100644 --- a/osu.Game/Graphics/Containers/Markdown/OsuMarkdownTextFlowContainer.cs +++ b/osu.Game/Graphics/Containers/Markdown/OsuMarkdownTextFlowContainer.cs @@ -4,7 +4,9 @@ using Markdig.Syntax.Inlines; using osu.Framework.Allocation; using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers.Markdown; +using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Sprites; using osu.Game.Overlays; @@ -24,5 +26,32 @@ namespace osu.Game.Graphics.Containers.Markdown protected override SpriteText CreateEmphasisedSpriteText(bool bold, bool italic) => CreateSpriteText().With(t => t.Font = t.Font.With(weight: bold ? FontWeight.Bold : FontWeight.Regular, italics: italic)); + + private class OsuMarkdownInlineCode : Container + { + [Resolved] + private IMarkdownTextComponent parentTextComponent { get; set; } + + public string Text; + + [BackgroundDependencyLoader] + private void load(OverlayColourProvider colourProvider) + { + AutoSizeAxes = Axes.Both; + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = colourProvider.Background6, + }, + parentTextComponent.CreateSpriteText().With(t => + { + t.Colour = colourProvider.Light1; + t.Text = Text; + }), + }; + } + } } } From 5108dadfbc0d7fb8aeb0139a993bd40bf05f7ff2 Mon Sep 17 00:00:00 2001 From: Gagah Pangeran Rosfatiputra Date: Tue, 1 Jun 2021 14:03:57 +0700 Subject: [PATCH 15/32] use inline code in markdown text flow --- .../Markdown/OsuMarkdownTextFlowContainer.cs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/osu.Game/Graphics/Containers/Markdown/OsuMarkdownTextFlowContainer.cs b/osu.Game/Graphics/Containers/Markdown/OsuMarkdownTextFlowContainer.cs index 267a5befb5..b9c2b20bb6 100644 --- a/osu.Game/Graphics/Containers/Markdown/OsuMarkdownTextFlowContainer.cs +++ b/osu.Game/Graphics/Containers/Markdown/OsuMarkdownTextFlowContainer.cs @@ -14,15 +14,14 @@ namespace osu.Game.Graphics.Containers.Markdown { public class OsuMarkdownTextFlowContainer : MarkdownTextFlowContainer { - [Resolved] - private OverlayColourProvider colourProvider { get; set; } - protected override void AddLinkText(string text, LinkInline linkInline) => AddDrawable(new OsuMarkdownLinkText(text, linkInline)); - // TODO : Add background (colour B6) and change font to monospace - protected override void AddCodeInLine(CodeInline codeInline) - => AddText(codeInline.Content, t => { t.Colour = colourProvider.Light1; }); + // TODO : Change font to monospace + protected override void AddCodeInLine(CodeInline codeInline) => AddDrawable(new OsuMarkdownInlineCode + { + Text = codeInline.Content + }); protected override SpriteText CreateEmphasisedSpriteText(bool bold, bool italic) => CreateSpriteText().With(t => t.Font = t.Font.With(weight: bold ? FontWeight.Bold : FontWeight.Regular, italics: italic)); From b4dd93553892db0e43c52a6c3b7235f2aba8c41c Mon Sep 17 00:00:00 2001 From: Gagah Pangeran Rosfatiputra Date: Tue, 1 Jun 2021 14:14:12 +0700 Subject: [PATCH 16/32] add corner radius and padding --- .../Containers/Markdown/OsuMarkdownTextFlowContainer.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/osu.Game/Graphics/Containers/Markdown/OsuMarkdownTextFlowContainer.cs b/osu.Game/Graphics/Containers/Markdown/OsuMarkdownTextFlowContainer.cs index b9c2b20bb6..f3308019ce 100644 --- a/osu.Game/Graphics/Containers/Markdown/OsuMarkdownTextFlowContainer.cs +++ b/osu.Game/Graphics/Containers/Markdown/OsuMarkdownTextFlowContainer.cs @@ -37,6 +37,8 @@ namespace osu.Game.Graphics.Containers.Markdown private void load(OverlayColourProvider colourProvider) { AutoSizeAxes = Axes.Both; + CornerRadius = 4; + Masking = true; Children = new Drawable[] { new Box @@ -48,6 +50,11 @@ namespace osu.Game.Graphics.Containers.Markdown { t.Colour = colourProvider.Light1; t.Text = Text; + t.Padding = new MarginPadding + { + Vertical = 1, + Horizontal = 4, + }; }), }; } From 145e42928b08e22902fe74c9e8559e82a39c649f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 1 Jun 2021 16:46:29 +0900 Subject: [PATCH 17/32] Fix remaining null checks --- osu.Game/Graphics/Containers/LinkFlowContainer.cs | 4 ++-- osu.Game/OsuGame.cs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Graphics/Containers/LinkFlowContainer.cs b/osu.Game/Graphics/Containers/LinkFlowContainer.cs index 054febeec3..f89d7fd779 100644 --- a/osu.Game/Graphics/Containers/LinkFlowContainer.cs +++ b/osu.Game/Graphics/Containers/LinkFlowContainer.cs @@ -43,7 +43,7 @@ namespace osu.Game.Graphics.Containers AddText(text[previousLinkEnd..link.Index]); string displayText = text.Substring(link.Index, link.Length); - string linkArgument = link.Argument ?? link.Url; + string linkArgument = link.Argument; string tooltip = displayText == link.Url ? null : link.Url; AddLink(displayText, link.Action, linkArgument, tooltip); @@ -57,7 +57,7 @@ namespace osu.Game.Graphics.Containers createLink(AddText(text, creationParameters), new LinkDetails(LinkAction.External, url), url); public void AddLink(string text, Action action, string tooltipText = null, Action creationParameters = null) - => createLink(AddText(text, creationParameters), new LinkDetails(LinkAction.Custom, null), tooltipText, action); + => createLink(AddText(text, creationParameters), new LinkDetails(LinkAction.Custom, @"action"), tooltipText, action); public void AddLink(string text, LinkAction action, string argument, string tooltipText = null, Action creationParameters = null) => createLink(AddText(text, creationParameters), new LinkDetails(action, argument), tooltipText); diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index b3b0773eff..c51624341e 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -277,7 +277,7 @@ namespace osu.Game { case LinkAction.OpenBeatmap: // TODO: proper query params handling - if (link.Argument != null && int.TryParse(link.Argument.Contains('?') ? link.Argument.Split('?')[0] : link.Argument, out int beatmapId)) + if (int.TryParse(link.Argument.Contains('?') ? link.Argument.Split('?')[0] : link.Argument, out int beatmapId)) ShowBeatmap(beatmapId); break; From 3668f1861f3369a3819da6d44dd52c648f54c494 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 1 Jun 2021 17:10:09 +0900 Subject: [PATCH 18/32] Fix one more null issue --- osu.Game/Graphics/Containers/LinkFlowContainer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Graphics/Containers/LinkFlowContainer.cs b/osu.Game/Graphics/Containers/LinkFlowContainer.cs index f89d7fd779..458bc8876f 100644 --- a/osu.Game/Graphics/Containers/LinkFlowContainer.cs +++ b/osu.Game/Graphics/Containers/LinkFlowContainer.cs @@ -70,7 +70,7 @@ namespace osu.Game.Graphics.Containers createLink(spriteText.Yield(), new LinkDetails(action, argument), tooltipText); } - public void AddLink(IEnumerable text, LinkAction action = LinkAction.External, string linkArgument = null, string tooltipText = null) + public void AddLink(IEnumerable text, LinkAction action, string linkArgument, string tooltipText = null) { foreach (var t in text) AddArbitraryDrawable(t); From 92ffc4627f8bf90f3320dd71a6b20495e071ba1c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 1 Jun 2021 23:24:49 +0900 Subject: [PATCH 19/32] 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 3d51357d8b..e95c7e6619 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -52,6 +52,6 @@ - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index d299ba4fda..c9bfb4a8eb 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -34,7 +34,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/osu.iOS.props b/osu.iOS.props index 9e178b267a..70bec9b894 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -70,7 +70,7 @@ - + @@ -93,7 +93,7 @@ - + From 97d2ac19cfe679a27368b90d9e3510a214af01f0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 1 Jun 2021 19:59:09 +0000 Subject: [PATCH 20/32] Bump BenchmarkDotNet from 0.12.1 to 0.13.0 Bumps [BenchmarkDotNet](https://github.com/dotnet/BenchmarkDotNet) from 0.12.1 to 0.13.0. - [Release notes](https://github.com/dotnet/BenchmarkDotNet/releases) - [Commits](https://github.com/dotnet/BenchmarkDotNet/compare/v0.12.1...v0.13.0) --- updated-dependencies: - dependency-name: BenchmarkDotNet dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- osu.Game.Benchmarks/osu.Game.Benchmarks.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Benchmarks/osu.Game.Benchmarks.csproj b/osu.Game.Benchmarks/osu.Game.Benchmarks.csproj index bfcf4ef35e..7a74563b2b 100644 --- a/osu.Game.Benchmarks/osu.Game.Benchmarks.csproj +++ b/osu.Game.Benchmarks/osu.Game.Benchmarks.csproj @@ -7,7 +7,7 @@ - + From 069baab8839c5da5f710f0d50e2cfc8eefaff870 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 1 Jun 2021 19:59:27 +0000 Subject: [PATCH 21/32] Bump Microsoft.AspNetCore.SignalR.Protocols.NewtonsoftJson Bumps [Microsoft.AspNetCore.SignalR.Protocols.NewtonsoftJson](https://github.com/dotnet/aspnetcore) from 5.0.5 to 5.0.6. - [Release notes](https://github.com/dotnet/aspnetcore/releases) - [Commits](https://github.com/dotnet/aspnetcore/compare/v5.0.5...v5.0.6) --- updated-dependencies: - dependency-name: Microsoft.AspNetCore.SignalR.Protocols.NewtonsoftJson dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- osu.Game/osu.Game.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index c9bfb4a8eb..169c28480f 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -24,7 +24,7 @@ - + From ea9919e8fe023f4b90d101d69ddd1eff96b2992b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 1 Jun 2021 19:59:27 +0000 Subject: [PATCH 22/32] Bump Microsoft.AspNetCore.SignalR.Client from 5.0.5 to 5.0.6 Bumps [Microsoft.AspNetCore.SignalR.Client](https://github.com/dotnet/aspnetcore) from 5.0.5 to 5.0.6. - [Release notes](https://github.com/dotnet/aspnetcore/releases) - [Commits](https://github.com/dotnet/aspnetcore/compare/v5.0.5...v5.0.6) --- updated-dependencies: - dependency-name: Microsoft.AspNetCore.SignalR.Client dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- osu.Game/osu.Game.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index c9bfb4a8eb..fb675da847 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -22,7 +22,7 @@ - + From 967a7c3db5918d10223728d0a5b646ab7b6c8392 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 1 Jun 2021 19:59:27 +0000 Subject: [PATCH 23/32] Bump Microsoft.NET.Test.Sdk from 16.9.4 to 16.10.0 Bumps [Microsoft.NET.Test.Sdk](https://github.com/microsoft/vstest) from 16.9.4 to 16.10.0. - [Release notes](https://github.com/microsoft/vstest/releases) - [Commits](https://github.com/microsoft/vstest/compare/v16.9.4...v16.10.0) --- updated-dependencies: - dependency-name: Microsoft.NET.Test.Sdk dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .../osu.Game.Rulesets.EmptyFreeform.Tests.csproj | 2 +- .../osu.Game.Rulesets.Pippidon.Tests.csproj | 2 +- .../osu.Game.Rulesets.EmptyScrolling.Tests.csproj | 2 +- .../osu.Game.Rulesets.Pippidon.Tests.csproj | 2 +- .../osu.Game.Rulesets.Catch.Tests.csproj | 2 +- .../osu.Game.Rulesets.Mania.Tests.csproj | 2 +- osu.Game.Rulesets.Osu.Tests/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/osu.Game.Tournament.Tests.csproj | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform.Tests/osu.Game.Rulesets.EmptyFreeform.Tests.csproj b/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform.Tests/osu.Game.Rulesets.EmptyFreeform.Tests.csproj index 992f954a3a..5eb5efa54c 100644 --- a/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform.Tests/osu.Game.Rulesets.EmptyFreeform.Tests.csproj +++ b/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform.Tests/osu.Game.Rulesets.EmptyFreeform.Tests.csproj @@ -10,7 +10,7 @@ - + diff --git a/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon.Tests/osu.Game.Rulesets.Pippidon.Tests.csproj b/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon.Tests/osu.Game.Rulesets.Pippidon.Tests.csproj index 7571d1827a..d7c116411a 100644 --- a/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon.Tests/osu.Game.Rulesets.Pippidon.Tests.csproj +++ b/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon.Tests/osu.Game.Rulesets.Pippidon.Tests.csproj @@ -10,7 +10,7 @@ - + diff --git a/Templates/Rulesets/ruleset-scrolling-empty/osu.Game.Rulesets.EmptyScrolling.Tests/osu.Game.Rulesets.EmptyScrolling.Tests.csproj b/Templates/Rulesets/ruleset-scrolling-empty/osu.Game.Rulesets.EmptyScrolling.Tests/osu.Game.Rulesets.EmptyScrolling.Tests.csproj index 1c8ed54440..89b551286b 100644 --- a/Templates/Rulesets/ruleset-scrolling-empty/osu.Game.Rulesets.EmptyScrolling.Tests/osu.Game.Rulesets.EmptyScrolling.Tests.csproj +++ b/Templates/Rulesets/ruleset-scrolling-empty/osu.Game.Rulesets.EmptyScrolling.Tests/osu.Game.Rulesets.EmptyScrolling.Tests.csproj @@ -10,7 +10,7 @@ - + diff --git a/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon.Tests/osu.Game.Rulesets.Pippidon.Tests.csproj b/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon.Tests/osu.Game.Rulesets.Pippidon.Tests.csproj index 7571d1827a..d7c116411a 100644 --- a/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon.Tests/osu.Game.Rulesets.Pippidon.Tests.csproj +++ b/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon.Tests/osu.Game.Rulesets.Pippidon.Tests.csproj @@ -10,7 +10,7 @@ - + diff --git a/osu.Game.Rulesets.Catch.Tests/osu.Game.Rulesets.Catch.Tests.csproj b/osu.Game.Rulesets.Catch.Tests/osu.Game.Rulesets.Catch.Tests.csproj index 77e9d672e3..83d0744588 100644 --- a/osu.Game.Rulesets.Catch.Tests/osu.Game.Rulesets.Catch.Tests.csproj +++ b/osu.Game.Rulesets.Catch.Tests/osu.Game.Rulesets.Catch.Tests.csproj @@ -2,7 +2,7 @@ - + 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 8f8b99b092..b2a0912d19 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 @@ -2,7 +2,7 @@ - + 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 e01e858873..ebe642803b 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 @@ -2,7 +2,7 @@ - + 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 2dfa1dfbb7..8fb167ba10 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 @@ -2,7 +2,7 @@ - + diff --git a/osu.Game.Tests/osu.Game.Tests.csproj b/osu.Game.Tests/osu.Game.Tests.csproj index 895518e1b9..35d3c7f202 100644 --- a/osu.Game.Tests/osu.Game.Tests.csproj +++ b/osu.Game.Tests/osu.Game.Tests.csproj @@ -3,7 +3,7 @@ - + diff --git a/osu.Game.Tournament.Tests/osu.Game.Tournament.Tests.csproj b/osu.Game.Tournament.Tests/osu.Game.Tournament.Tests.csproj index d5dda39aa5..2084be765a 100644 --- a/osu.Game.Tournament.Tests/osu.Game.Tournament.Tests.csproj +++ b/osu.Game.Tournament.Tests/osu.Game.Tournament.Tests.csproj @@ -5,7 +5,7 @@ - + From bd8db2ce63869e243cccd2efae812891f075e020 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 1 Jun 2021 19:59:28 +0000 Subject: [PATCH 24/32] Bump ppy.LocalisationAnalyser from 2021.524.0 to 2021.525.0 Bumps [ppy.LocalisationAnalyser](https://github.com/ppy/osu-localisation-analyser) from 2021.524.0 to 2021.525.0. - [Release notes](https://github.com/ppy/osu-localisation-analyser/releases) - [Commits](https://github.com/ppy/osu-localisation-analyser/compare/2021.524.0...2021.525.0) --- updated-dependencies: - dependency-name: ppy.LocalisationAnalyser dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- osu.Game/osu.Game.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index c9bfb4a8eb..c8eea7c4f3 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -30,7 +30,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive From deaa381440f0f8e02dd3809da69efa4948975b50 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 1 Jun 2021 19:59:30 +0000 Subject: [PATCH 25/32] Bump Sentry from 3.3.4 to 3.4.0 Bumps [Sentry](https://github.com/getsentry/sentry-dotnet) from 3.3.4 to 3.4.0. - [Release notes](https://github.com/getsentry/sentry-dotnet/releases) - [Changelog](https://github.com/getsentry/sentry-dotnet/blob/main/CHANGELOG.md) - [Commits](https://github.com/getsentry/sentry-dotnet/compare/3.3.4...3.4.0) --- updated-dependencies: - dependency-name: Sentry dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- osu.Game/osu.Game.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index c9bfb4a8eb..967f0af1df 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -36,7 +36,7 @@ - + From a10ef2ba6513cb617886270b2bd6792d7b06819a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 1 Jun 2021 19:59:31 +0000 Subject: [PATCH 26/32] Bump Humanizer from 2.8.26 to 2.10.1 Bumps [Humanizer](https://github.com/Humanizr/Humanizer) from 2.8.26 to 2.10.1. - [Release notes](https://github.com/Humanizr/Humanizer/releases) - [Changelog](https://github.com/Humanizr/Humanizer/blob/main/release_notes.md) - [Commits](https://github.com/Humanizr/Humanizer/compare/v2.8.26...v2.10.1) --- updated-dependencies: - dependency-name: Humanizer dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index c9bfb4a8eb..28b77a32ec 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -20,7 +20,7 @@ - + diff --git a/osu.iOS.props b/osu.iOS.props index 70bec9b894..c1d63f3236 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -89,7 +89,7 @@ - + From a758b382784ac346764d3b5d803044fc96cf2f78 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 1 Jun 2021 19:59:32 +0000 Subject: [PATCH 27/32] Bump Microsoft.AspNetCore.SignalR.Protocols.MessagePack Bumps [Microsoft.AspNetCore.SignalR.Protocols.MessagePack](https://github.com/dotnet/aspnetcore) from 5.0.5 to 5.0.6. - [Release notes](https://github.com/dotnet/aspnetcore/releases) - [Commits](https://github.com/dotnet/aspnetcore/compare/v5.0.5...v5.0.6) --- updated-dependencies: - dependency-name: Microsoft.AspNetCore.SignalR.Protocols.MessagePack dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- osu.Game/osu.Game.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index c9bfb4a8eb..12f8163bfa 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -23,7 +23,7 @@ - + From d3d8941ec8559a173c23ff63da47554681124e31 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 2 Jun 2021 11:11:41 +0900 Subject: [PATCH 28/32] Make method internal --- osu.Game/Rulesets/Objects/HitObjectLifetimeEntry.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Objects/HitObjectLifetimeEntry.cs b/osu.Game/Rulesets/Objects/HitObjectLifetimeEntry.cs index 5ad0d6246e..096dad88bd 100644 --- a/osu.Game/Rulesets/Objects/HitObjectLifetimeEntry.cs +++ b/osu.Game/Rulesets/Objects/HitObjectLifetimeEntry.cs @@ -94,6 +94,6 @@ namespace osu.Game.Rulesets.Objects /// /// Set using . /// - public void SetInitialLifetime() => LifetimeStart = HitObject.StartTime - InitialLifetimeOffset; + internal void SetInitialLifetime() => LifetimeStart = HitObject.StartTime - InitialLifetimeOffset; } } From b82190e157deb303bf15ba69b56fb5a55ae4584d Mon Sep 17 00:00:00 2001 From: ekrctb Date: Wed, 2 Jun 2021 11:32:24 +0900 Subject: [PATCH 29/32] Fix hit circle animation reset when skin is changed The transforms applied in `Animate` call was not applied because the piece is recreated. --- osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs | 2 -- osu.Game.Rulesets.Osu/Skinning/Default/MainCirclePiece.cs | 4 ++++ .../Skinning/Legacy/LegacyMainCirclePiece.cs | 4 ++++ 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs index 1bf9e76d7d..236af4b3f1 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs @@ -182,8 +182,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables // todo: temporary / arbitrary, used for lifetime optimisation. this.Delay(800).FadeOut(); - (CirclePiece.Drawable as IMainCirclePiece)?.Animate(state); - switch (state) { case ArmedState.Idle: diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/MainCirclePiece.cs b/osu.Game.Rulesets.Osu/Skinning/Default/MainCirclePiece.cs index b46baa00ba..9af9d2ea95 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Default/MainCirclePiece.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Default/MainCirclePiece.cs @@ -42,6 +42,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default private readonly IBindable accentColour = new Bindable(); private readonly IBindable indexInCurrentCombo = new Bindable(); + private readonly IBindable armedState = new Bindable(); [Resolved] private DrawableHitObject drawableObject { get; set; } @@ -53,6 +54,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default accentColour.BindTo(drawableObject.AccentColour); indexInCurrentCombo.BindTo(drawableOsuObject.IndexInCurrentComboBindable); + armedState.BindTo(drawableObject.State); } protected override void LoadComplete() @@ -67,6 +69,8 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default }, true); indexInCurrentCombo.BindValueChanged(index => number.Text = (index.NewValue + 1).ToString(), true); + + armedState.BindValueChanged(state => Animate(state.NewValue), true); } public void Animate(ArmedState state) diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyMainCirclePiece.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyMainCirclePiece.cs index cf62165929..57af247562 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyMainCirclePiece.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyMainCirclePiece.cs @@ -41,6 +41,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy private readonly Bindable accentColour = new Bindable(); private readonly IBindable indexInCurrentCombo = new Bindable(); + private readonly IBindable armedState = new Bindable(); [Resolved] private DrawableHitObject drawableObject { get; set; } @@ -115,6 +116,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy accentColour.BindTo(drawableObject.AccentColour); indexInCurrentCombo.BindTo(drawableOsuObject.IndexInCurrentComboBindable); + armedState.BindTo(drawableObject.State); Texture getTextureWithFallback(string name) { @@ -139,6 +141,8 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy accentColour.BindValueChanged(colour => hitCircleSprite.Colour = LegacyColourCompatibility.DisallowZeroAlpha(colour.NewValue), true); if (hasNumber) indexInCurrentCombo.BindValueChanged(index => hitCircleText.Text = (index.NewValue + 1).ToString(), true); + + armedState.BindValueChanged(state => Animate(state.NewValue), true); } public void Animate(ArmedState state) From c06ff3c623321a15ad318fafb89b7d3d5c5632ce Mon Sep 17 00:00:00 2001 From: ekrctb Date: Wed, 2 Jun 2021 11:46:28 +0900 Subject: [PATCH 30/32] Remove defunct `Animate` calls --- .../Objects/Drawables/DrawableSliderRepeat.cs | 2 -- .../Objects/Drawables/DrawableSliderTail.cs | 2 -- .../Skinning/Default/IMainCirclePiece.cs | 17 ----------------- .../Skinning/Default/MainCirclePiece.cs | 12 +++++++----- .../Skinning/Legacy/LegacyMainCirclePiece.cs | 13 +++++++------ 5 files changed, 14 insertions(+), 32 deletions(-) delete mode 100644 osu.Game.Rulesets.Osu/Skinning/Default/IMainCirclePiece.cs diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderRepeat.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderRepeat.cs index 7b4188edab..b7458b5695 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderRepeat.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderRepeat.cs @@ -97,8 +97,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables { base.UpdateHitStateTransforms(state); - (CirclePiece.Drawable as IMainCirclePiece)?.Animate(state); - switch (state) { case ArmedState.Idle: diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTail.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTail.cs index cd6bf1d8d2..ec1387eb54 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTail.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTail.cs @@ -87,8 +87,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables Debug.Assert(HitObject.HitWindows != null); - (CirclePiece.Drawable as IMainCirclePiece)?.Animate(state); - switch (state) { case ArmedState.Idle: diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/IMainCirclePiece.cs b/osu.Game.Rulesets.Osu/Skinning/Default/IMainCirclePiece.cs deleted file mode 100644 index 17a1e29094..0000000000 --- a/osu.Game.Rulesets.Osu/Skinning/Default/IMainCirclePiece.cs +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using osu.Game.Rulesets.Objects.Drawables; -using osu.Game.Rulesets.Osu.Objects.Drawables; - -namespace osu.Game.Rulesets.Osu.Skinning.Default -{ - public interface IMainCirclePiece - { - /// - /// Begins animating this . - /// - /// The of the related . - void Animate(ArmedState state); - } -} diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/MainCirclePiece.cs b/osu.Game.Rulesets.Osu/Skinning/Default/MainCirclePiece.cs index 9af9d2ea95..b52dc749f0 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Default/MainCirclePiece.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Default/MainCirclePiece.cs @@ -13,7 +13,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Osu.Skinning.Default { - public class MainCirclePiece : CompositeDrawable, IMainCirclePiece + public class MainCirclePiece : CompositeDrawable { private readonly CirclePiece circle; private readonly RingPiece ring; @@ -70,17 +70,19 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default indexInCurrentCombo.BindValueChanged(index => number.Text = (index.NewValue + 1).ToString(), true); - armedState.BindValueChanged(state => Animate(state.NewValue), true); + armedState.BindValueChanged(animate, true); } - public void Animate(ArmedState state) + private void animate(ValueChangedEvent state) { + ClearTransforms(true); + using (BeginAbsoluteSequence(drawableObject.StateUpdateTime)) glow.FadeOut(400); using (BeginAbsoluteSequence(drawableObject.HitStateUpdateTime)) { - switch (state) + switch (state.NewValue) { case ArmedState.Hit: const double flash_in = 40; @@ -93,7 +95,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default explode.FadeIn(flash_in); this.ScaleTo(1.5f, 400, Easing.OutQuad); - using (BeginDelayedSequence(flash_in, true)) + using (BeginDelayedSequence(flash_in)) { // after the flash, we can hide some elements that were behind it ring.FadeOut(); diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyMainCirclePiece.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyMainCirclePiece.cs index 57af247562..ffbeea5e0e 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyMainCirclePiece.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyMainCirclePiece.cs @@ -12,7 +12,6 @@ using osu.Game.Graphics.Sprites; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Osu.Objects.Drawables; -using osu.Game.Rulesets.Osu.Skinning.Default; using osu.Game.Skinning; using osuTK; using osuTK.Graphics; @@ -20,7 +19,7 @@ using static osu.Game.Skinning.LegacySkinConfiguration; namespace osu.Game.Rulesets.Osu.Skinning.Legacy { - public class LegacyMainCirclePiece : CompositeDrawable, IMainCirclePiece + public class LegacyMainCirclePiece : CompositeDrawable { private readonly string priorityLookup; private readonly bool hasNumber; @@ -142,16 +141,18 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy if (hasNumber) indexInCurrentCombo.BindValueChanged(index => hitCircleText.Text = (index.NewValue + 1).ToString(), true); - armedState.BindValueChanged(state => Animate(state.NewValue), true); + armedState.BindValueChanged(animate, true); } - public void Animate(ArmedState state) + private void animate(ValueChangedEvent state) { const double legacy_fade_duration = 240; - using (BeginAbsoluteSequence(drawableObject.HitStateUpdateTime, true)) + ClearTransforms(true); + + using (BeginAbsoluteSequence(drawableObject.HitStateUpdateTime)) { - switch (state) + switch (state.NewValue) { case ArmedState.Hit: circleSprites.FadeOut(legacy_fade_duration, Easing.Out); From 82c1a9ae4c6bfdbbd95945f33b823faaf33354fa Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Tue, 1 Jun 2021 18:59:31 -0700 Subject: [PATCH 31/32] Remove windows-only note from InspectCode section of readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index eb790ca18f..3054f19e79 100644 --- a/README.md +++ b/README.md @@ -97,7 +97,7 @@ Before committing your code, please run a code formatter. This can be achieved b We have adopted some cross-platform, compiler integrated analyzers. They can provide warnings when you are editing, building inside IDE or from command line, as-if they are provided by the compiler itself. -JetBrains ReSharper InspectCode is also used for wider rule sets. You can run it from PowerShell with `.\InspectCode.ps1`, which is [only supported on Windows](https://youtrack.jetbrains.com/issue/RSRP-410004). Alternatively, you can install ReSharper or use Rider to get inline support in your IDE of choice. +JetBrains ReSharper InspectCode is also used for wider rule sets. You can run it from PowerShell with `.\InspectCode.ps1`. Alternatively, you can install ReSharper or use Rider to get inline support in your IDE of choice. ## Contributing From ac761bb0755bb0f377a1c57a09688354b6fea5a1 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 2 Jun 2021 14:43:35 +0900 Subject: [PATCH 32/32] Use `string.Empty` instead of arbitrary string --- osu.Game/Graphics/Containers/LinkFlowContainer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Graphics/Containers/LinkFlowContainer.cs b/osu.Game/Graphics/Containers/LinkFlowContainer.cs index 458bc8876f..5ff2fdf6b2 100644 --- a/osu.Game/Graphics/Containers/LinkFlowContainer.cs +++ b/osu.Game/Graphics/Containers/LinkFlowContainer.cs @@ -57,7 +57,7 @@ namespace osu.Game.Graphics.Containers createLink(AddText(text, creationParameters), new LinkDetails(LinkAction.External, url), url); public void AddLink(string text, Action action, string tooltipText = null, Action creationParameters = null) - => createLink(AddText(text, creationParameters), new LinkDetails(LinkAction.Custom, @"action"), tooltipText, action); + => createLink(AddText(text, creationParameters), new LinkDetails(LinkAction.Custom, string.Empty), tooltipText, action); public void AddLink(string text, LinkAction action, string argument, string tooltipText = null, Action creationParameters = null) => createLink(AddText(text, creationParameters), new LinkDetails(action, argument), tooltipText);