From 0528469b440d33308cdc61c7d2a136027e4731e4 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 5 Feb 2021 14:04:04 +0900 Subject: [PATCH 1/7] Rename OrderedHitPolicy -> StartTimeOrderedHitPolicy --- osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs | 4 ++-- .../UI/{OrderedHitPolicy.cs => StartTimeOrderedHitPolicy.cs} | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) rename osu.Game.Rulesets.Osu/UI/{OrderedHitPolicy.cs => StartTimeOrderedHitPolicy.cs} (97%) diff --git a/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs b/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs index 975b444699..5c77112df7 100644 --- a/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs +++ b/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs @@ -31,7 +31,7 @@ namespace osu.Game.Rulesets.Osu.UI private readonly ProxyContainer spinnerProxies; private readonly JudgementContainer judgementLayer; private readonly FollowPointRenderer followPoints; - private readonly OrderedHitPolicy hitPolicy; + private readonly StartTimeOrderedHitPolicy hitPolicy; public static readonly Vector2 BASE_SIZE = new Vector2(512, 384); @@ -54,7 +54,7 @@ namespace osu.Game.Rulesets.Osu.UI approachCircles = new ProxyContainer { RelativeSizeAxes = Axes.Both }, }; - hitPolicy = new OrderedHitPolicy(HitObjectContainer); + hitPolicy = new StartTimeOrderedHitPolicy(HitObjectContainer); var hitWindows = new OsuHitWindows(); diff --git a/osu.Game.Rulesets.Osu/UI/OrderedHitPolicy.cs b/osu.Game.Rulesets.Osu/UI/StartTimeOrderedHitPolicy.cs similarity index 97% rename from osu.Game.Rulesets.Osu/UI/OrderedHitPolicy.cs rename to osu.Game.Rulesets.Osu/UI/StartTimeOrderedHitPolicy.cs index 8e4f81347d..1d9a5010ed 100644 --- a/osu.Game.Rulesets.Osu/UI/OrderedHitPolicy.cs +++ b/osu.Game.Rulesets.Osu/UI/StartTimeOrderedHitPolicy.cs @@ -18,11 +18,11 @@ namespace osu.Game.Rulesets.Osu.UI /// The hit causes all previous s to missed otherwise. /// /// - public class OrderedHitPolicy + public class StartTimeOrderedHitPolicy { private readonly HitObjectContainer hitObjectContainer; - public OrderedHitPolicy(HitObjectContainer hitObjectContainer) + public StartTimeOrderedHitPolicy(HitObjectContainer hitObjectContainer) { this.hitObjectContainer = hitObjectContainer; } From df1df8184771f096a58acc095efc576485c7301c Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 5 Feb 2021 14:04:21 +0900 Subject: [PATCH 2/7] Better indicate ordering --- osu.Game.Rulesets.Osu/UI/StartTimeOrderedHitPolicy.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/UI/StartTimeOrderedHitPolicy.cs b/osu.Game.Rulesets.Osu/UI/StartTimeOrderedHitPolicy.cs index 1d9a5010ed..2b13a36e47 100644 --- a/osu.Game.Rulesets.Osu/UI/StartTimeOrderedHitPolicy.cs +++ b/osu.Game.Rulesets.Osu/UI/StartTimeOrderedHitPolicy.cs @@ -11,7 +11,7 @@ using osu.Game.Rulesets.UI; namespace osu.Game.Rulesets.Osu.UI { /// - /// Ensures that s are hit in-order. Affectionately known as "note lock". + /// Ensures that s are hit in-order of their start times. Affectionately known as "note lock". /// If a is hit out of order: /// /// The hit is blocked if it occurred earlier than the previous 's start time. From 08aae011c10880a24204717cfea5eb5c2629571b Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 5 Feb 2021 14:04:32 +0900 Subject: [PATCH 3/7] Add IHitPolicy interface --- osu.Game.Rulesets.Osu/UI/IHitPolicy.cs | 25 +++++++++++++++++++ .../UI/StartTimeOrderedHitPolicy.cs | 13 ++-------- 2 files changed, 27 insertions(+), 11 deletions(-) create mode 100644 osu.Game.Rulesets.Osu/UI/IHitPolicy.cs diff --git a/osu.Game.Rulesets.Osu/UI/IHitPolicy.cs b/osu.Game.Rulesets.Osu/UI/IHitPolicy.cs new file mode 100644 index 0000000000..fcc18b5f6f --- /dev/null +++ b/osu.Game.Rulesets.Osu/UI/IHitPolicy.cs @@ -0,0 +1,25 @@ +// 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; +using osu.Game.Rulesets.Objects.Drawables; + +namespace osu.Game.Rulesets.Osu.UI +{ + public interface IHitPolicy + { + /// + /// Determines whether a can be hit at a point in time. + /// + /// The to check. + /// The time to check. + /// Whether can be hit at the given . + bool IsHittable(DrawableHitObject hitObject, double time); + + /// + /// Handles a being hit. + /// + /// The that was hit. + void HandleHit(DrawableHitObject hitObject); + } +} diff --git a/osu.Game.Rulesets.Osu/UI/StartTimeOrderedHitPolicy.cs b/osu.Game.Rulesets.Osu/UI/StartTimeOrderedHitPolicy.cs index 2b13a36e47..2b5a440f67 100644 --- a/osu.Game.Rulesets.Osu/UI/StartTimeOrderedHitPolicy.cs +++ b/osu.Game.Rulesets.Osu/UI/StartTimeOrderedHitPolicy.cs @@ -18,7 +18,7 @@ namespace osu.Game.Rulesets.Osu.UI /// The hit causes all previous s to missed otherwise. /// /// - public class StartTimeOrderedHitPolicy + public class StartTimeOrderedHitPolicy : IHitPolicy { private readonly HitObjectContainer hitObjectContainer; @@ -27,12 +27,6 @@ namespace osu.Game.Rulesets.Osu.UI this.hitObjectContainer = hitObjectContainer; } - /// - /// Determines whether a can be hit at a point in time. - /// - /// The to check. - /// The time to check. - /// Whether can be hit at the given . public bool IsHittable(DrawableHitObject hitObject, double time) { DrawableHitObject blockingObject = null; @@ -54,10 +48,6 @@ namespace osu.Game.Rulesets.Osu.UI return blockingObject.Judged || time >= blockingObject.HitObject.StartTime; } - /// - /// Handles a being hit to potentially miss all earlier s. - /// - /// The that was hit. public void HandleHit(DrawableHitObject hitObject) { // Hitobjects which themselves don't block future hitobjects don't cause misses (e.g. slider ticks, spinners). @@ -67,6 +57,7 @@ namespace osu.Game.Rulesets.Osu.UI if (!IsHittable(hitObject, hitObject.HitObject.StartTime + hitObject.Result.TimeOffset)) throw new InvalidOperationException($"A {hitObject} was hit before it became hittable!"); + // Miss all hitobjects prior to the hit one. foreach (var obj in enumerateHitObjectsUpTo(hitObject.HitObject.StartTime)) { if (obj.Judged) From 8adf37d958abc4bb3b42e600149a4b0fdbbbaa16 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 5 Feb 2021 14:09:25 +0900 Subject: [PATCH 4/7] Add SetHitObjects() to IHitPolicy instead of using ctor --- osu.Game.Rulesets.Osu/UI/IHitPolicy.cs | 7 +++++++ osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs | 3 ++- osu.Game.Rulesets.Osu/UI/StartTimeOrderedHitPolicy.cs | 10 +++------- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/osu.Game.Rulesets.Osu/UI/IHitPolicy.cs b/osu.Game.Rulesets.Osu/UI/IHitPolicy.cs index fcc18b5f6f..72c3d781bb 100644 --- a/osu.Game.Rulesets.Osu/UI/IHitPolicy.cs +++ b/osu.Game.Rulesets.Osu/UI/IHitPolicy.cs @@ -1,6 +1,7 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System.Collections.Generic; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Drawables; @@ -8,6 +9,12 @@ namespace osu.Game.Rulesets.Osu.UI { public interface IHitPolicy { + /// + /// Sets the s which this controls. + /// + /// An enumeration of the s. + void SetHitObjects(IEnumerable hitObjects); + /// /// Determines whether a can be hit at a point in time. /// diff --git a/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs b/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs index 5c77112df7..c7900558a0 100644 --- a/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs +++ b/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs @@ -54,7 +54,8 @@ namespace osu.Game.Rulesets.Osu.UI approachCircles = new ProxyContainer { RelativeSizeAxes = Axes.Both }, }; - hitPolicy = new StartTimeOrderedHitPolicy(HitObjectContainer); + hitPolicy = new StartTimeOrderedHitPolicy(); + hitPolicy.SetHitObjects(HitObjectContainer.AliveObjects); var hitWindows = new OsuHitWindows(); diff --git a/osu.Game.Rulesets.Osu/UI/StartTimeOrderedHitPolicy.cs b/osu.Game.Rulesets.Osu/UI/StartTimeOrderedHitPolicy.cs index 2b5a440f67..38ba5fc490 100644 --- a/osu.Game.Rulesets.Osu/UI/StartTimeOrderedHitPolicy.cs +++ b/osu.Game.Rulesets.Osu/UI/StartTimeOrderedHitPolicy.cs @@ -6,7 +6,6 @@ using System.Collections.Generic; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Osu.Objects.Drawables; -using osu.Game.Rulesets.UI; namespace osu.Game.Rulesets.Osu.UI { @@ -20,12 +19,9 @@ namespace osu.Game.Rulesets.Osu.UI /// public class StartTimeOrderedHitPolicy : IHitPolicy { - private readonly HitObjectContainer hitObjectContainer; + private IEnumerable hitObjects; - public StartTimeOrderedHitPolicy(HitObjectContainer hitObjectContainer) - { - this.hitObjectContainer = hitObjectContainer; - } + public void SetHitObjects(IEnumerable hitObjects) => this.hitObjects = hitObjects; public bool IsHittable(DrawableHitObject hitObject, double time) { @@ -77,7 +73,7 @@ namespace osu.Game.Rulesets.Osu.UI private IEnumerable enumerateHitObjectsUpTo(double targetTime) { - foreach (var obj in hitObjectContainer.AliveObjects) + foreach (var obj in hitObjects) { if (obj.HitObject.StartTime >= targetTime) yield break; From c9481ebbafa4c28ba21730448dcdfbf2b71d59e6 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 5 Feb 2021 14:49:33 +0900 Subject: [PATCH 5/7] Rename test scene --- ...eOutOfOrderHits.cs => TestSceneStartTimeOrderedHitPolicy.cs} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename osu.Game.Rulesets.Osu.Tests/{TestSceneOutOfOrderHits.cs => TestSceneStartTimeOrderedHitPolicy.cs} (99%) diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneOutOfOrderHits.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneStartTimeOrderedHitPolicy.cs similarity index 99% rename from osu.Game.Rulesets.Osu.Tests/TestSceneOutOfOrderHits.cs rename to osu.Game.Rulesets.Osu.Tests/TestSceneStartTimeOrderedHitPolicy.cs index 296b421a11..b8c1217a73 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneOutOfOrderHits.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneStartTimeOrderedHitPolicy.cs @@ -25,7 +25,7 @@ using osuTK; namespace osu.Game.Rulesets.Osu.Tests { - public class TestSceneOutOfOrderHits : RateAdjustedBeatmapTestScene + public class TestSceneStartTimeOrderedHitPolicy : RateAdjustedBeatmapTestScene { private const double early_miss_window = 1000; // time after -1000 to -500 is considered a miss private const double late_miss_window = 500; // time after +500 is considered a miss From 64a2c7825e89811dec78f803507fdd4c8696cc52 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 5 Feb 2021 14:53:47 +0900 Subject: [PATCH 6/7] Fix incorrect assert --- .../TestSceneStartTimeOrderedHitPolicy.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneStartTimeOrderedHitPolicy.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneStartTimeOrderedHitPolicy.cs index b8c1217a73..177a4f50a1 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneStartTimeOrderedHitPolicy.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneStartTimeOrderedHitPolicy.cs @@ -169,7 +169,7 @@ namespace osu.Game.Rulesets.Osu.Tests addJudgementAssert(hitObjects[0], HitResult.Great); addJudgementAssert(hitObjects[1], HitResult.Great); addJudgementOffsetAssert(hitObjects[0], -200); // time_first_circle - 200 - addJudgementOffsetAssert(hitObjects[0], -200); // time_second_circle - first_circle_time - 100 + addJudgementOffsetAssert(hitObjects[1], -200); // time_second_circle - first_circle_time - 100 } /// From f4a31287bfca31bf088f077e014f7af4d68b6232 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 8 Feb 2021 20:11:06 +0900 Subject: [PATCH 7/7] Add/use IHitObjectContainer interface instead of IEnumerables --- osu.Game.Rulesets.Osu/UI/IHitPolicy.cs | 7 +++--- osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs | 3 +-- .../UI/StartTimeOrderedHitPolicy.cs | 7 +++--- osu.Game/Rulesets/UI/HitObjectContainer.cs | 11 +-------- osu.Game/Rulesets/UI/IHitObjectContainer.cs | 24 +++++++++++++++++++ 5 files changed, 32 insertions(+), 20 deletions(-) create mode 100644 osu.Game/Rulesets/UI/IHitObjectContainer.cs diff --git a/osu.Game.Rulesets.Osu/UI/IHitPolicy.cs b/osu.Game.Rulesets.Osu/UI/IHitPolicy.cs index 72c3d781bb..5d8ea035a7 100644 --- a/osu.Game.Rulesets.Osu/UI/IHitPolicy.cs +++ b/osu.Game.Rulesets.Osu/UI/IHitPolicy.cs @@ -1,19 +1,18 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System.Collections.Generic; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Drawables; +using osu.Game.Rulesets.UI; namespace osu.Game.Rulesets.Osu.UI { public interface IHitPolicy { /// - /// Sets the s which this controls. + /// The containing the s which this applies to. /// - /// An enumeration of the s. - void SetHitObjects(IEnumerable hitObjects); + IHitObjectContainer HitObjectContainer { set; } /// /// Determines whether a can be hit at a point in time. diff --git a/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs b/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs index c7900558a0..e085714265 100644 --- a/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs +++ b/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs @@ -54,8 +54,7 @@ namespace osu.Game.Rulesets.Osu.UI approachCircles = new ProxyContainer { RelativeSizeAxes = Axes.Both }, }; - hitPolicy = new StartTimeOrderedHitPolicy(); - hitPolicy.SetHitObjects(HitObjectContainer.AliveObjects); + hitPolicy = new StartTimeOrderedHitPolicy { HitObjectContainer = HitObjectContainer }; var hitWindows = new OsuHitWindows(); diff --git a/osu.Game.Rulesets.Osu/UI/StartTimeOrderedHitPolicy.cs b/osu.Game.Rulesets.Osu/UI/StartTimeOrderedHitPolicy.cs index 38ba5fc490..0173156246 100644 --- a/osu.Game.Rulesets.Osu/UI/StartTimeOrderedHitPolicy.cs +++ b/osu.Game.Rulesets.Osu/UI/StartTimeOrderedHitPolicy.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Osu.Objects.Drawables; +using osu.Game.Rulesets.UI; namespace osu.Game.Rulesets.Osu.UI { @@ -19,9 +20,7 @@ namespace osu.Game.Rulesets.Osu.UI /// public class StartTimeOrderedHitPolicy : IHitPolicy { - private IEnumerable hitObjects; - - public void SetHitObjects(IEnumerable hitObjects) => this.hitObjects = hitObjects; + public IHitObjectContainer HitObjectContainer { get; set; } public bool IsHittable(DrawableHitObject hitObject, double time) { @@ -73,7 +72,7 @@ namespace osu.Game.Rulesets.Osu.UI private IEnumerable enumerateHitObjectsUpTo(double targetTime) { - foreach (var obj in hitObjects) + foreach (var obj in HitObjectContainer.AliveObjects) { if (obj.HitObject.StartTime >= targetTime) yield break; diff --git a/osu.Game/Rulesets/UI/HitObjectContainer.cs b/osu.Game/Rulesets/UI/HitObjectContainer.cs index 1972043ccb..11312a46df 100644 --- a/osu.Game/Rulesets/UI/HitObjectContainer.cs +++ b/osu.Game/Rulesets/UI/HitObjectContainer.cs @@ -17,19 +17,10 @@ using osu.Game.Rulesets.Objects.Drawables; namespace osu.Game.Rulesets.UI { - public class HitObjectContainer : LifetimeManagementContainer + public class HitObjectContainer : LifetimeManagementContainer, IHitObjectContainer { - /// - /// All currently in-use s. - /// public IEnumerable Objects => InternalChildren.Cast().OrderBy(h => h.HitObject.StartTime); - /// - /// All currently in-use s that are alive. - /// - /// - /// If this uses pooled objects, this is equivalent to . - /// public IEnumerable AliveObjects => AliveInternalChildren.Cast().OrderBy(h => h.HitObject.StartTime); /// diff --git a/osu.Game/Rulesets/UI/IHitObjectContainer.cs b/osu.Game/Rulesets/UI/IHitObjectContainer.cs new file mode 100644 index 0000000000..4c784132e8 --- /dev/null +++ b/osu.Game/Rulesets/UI/IHitObjectContainer.cs @@ -0,0 +1,24 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Collections.Generic; +using osu.Game.Rulesets.Objects.Drawables; + +namespace osu.Game.Rulesets.UI +{ + public interface IHitObjectContainer + { + /// + /// All currently in-use s. + /// + IEnumerable Objects { get; } + + /// + /// All currently in-use s that are alive. + /// + /// + /// If this uses pooled objects, this is equivalent to . + /// + IEnumerable AliveObjects { get; } + } +}