From d2775680e66129c34297246ce047914d2b94fd90 Mon Sep 17 00:00:00 2001 From: Chandler Stowell Date: Wed, 24 Jan 2024 13:13:45 -0500 Subject: [PATCH] use stack to pass action state when applying hit results this removes closure allocations --- .../Drawables/DrawableEmptyFreeformHitObject.cs | 2 +- .../Drawables/DrawablePippidonHitObject.cs | 7 ++++++- .../Drawables/DrawableEmptyScrollingHitObject.cs | 2 +- .../Drawables/DrawablePippidonHitObject.cs | 7 ++++++- .../Objects/Drawables/DrawableCatchHitObject.cs | 7 ++++++- .../Objects/Drawables/DrawableHoldNote.cs | 2 +- .../Objects/Drawables/DrawableHoldNoteBody.cs | 2 +- .../Objects/Drawables/DrawableManiaHitObject.cs | 2 +- .../Objects/Drawables/DrawableNote.cs | 4 ++-- .../Objects/Drawables/DrawableHitCircle.cs | 15 ++++++++------- .../Objects/Drawables/DrawableOsuHitObject.cs | 4 ++-- .../Objects/Drawables/DrawableSlider.cs | 13 ++++++++----- .../Objects/Drawables/DrawableSpinner.cs | 12 ++++++------ .../Objects/Drawables/DrawableSpinnerTick.cs | 2 +- .../Objects/Drawables/DrawableDrumRoll.cs | 7 +++++-- .../Objects/Drawables/DrawableDrumRollTick.cs | 11 +++++++---- .../Objects/Drawables/DrawableFlyingHit.cs | 2 +- .../Objects/Drawables/DrawableHit.cs | 12 ++++++------ .../Objects/Drawables/DrawableStrongNestedHit.cs | 2 +- .../Objects/Drawables/DrawableSwell.cs | 8 ++++++-- .../Objects/Drawables/DrawableSwellTick.cs | 5 ++++- .../Objects/Drawables/DrawableHitObject.cs | 13 +++++++++++-- 22 files changed, 91 insertions(+), 50 deletions(-) diff --git a/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform/Objects/Drawables/DrawableEmptyFreeformHitObject.cs b/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform/Objects/Drawables/DrawableEmptyFreeformHitObject.cs index 744e207b57..e8f511bc4b 100644 --- a/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform/Objects/Drawables/DrawableEmptyFreeformHitObject.cs +++ b/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform/Objects/Drawables/DrawableEmptyFreeformHitObject.cs @@ -26,7 +26,7 @@ namespace osu.Game.Rulesets.EmptyFreeform.Objects.Drawables { if (timeOffset >= 0) // todo: implement judgement logic - ApplyResult(r => r.Type = HitResult.Perfect); + ApplyResult(static r => r.Type = HitResult.Perfect); } protected override void UpdateHitStateTransforms(ArmedState state) diff --git a/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon/Objects/Drawables/DrawablePippidonHitObject.cs b/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon/Objects/Drawables/DrawablePippidonHitObject.cs index c5ada4288d..a8bb57ba18 100644 --- a/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon/Objects/Drawables/DrawablePippidonHitObject.cs +++ b/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon/Objects/Drawables/DrawablePippidonHitObject.cs @@ -49,7 +49,12 @@ namespace osu.Game.Rulesets.Pippidon.Objects.Drawables protected override void CheckForResult(bool userTriggered, double timeOffset) { if (timeOffset >= 0) - ApplyResult(r => r.Type = IsHovered ? HitResult.Perfect : HitResult.Miss); + { + ApplyResult(static (r, isHovered) => + { + r.Type = isHovered ? HitResult.Perfect : HitResult.Miss; + }, IsHovered); + } } protected override double InitialLifetimeOffset => time_preempt; diff --git a/Templates/Rulesets/ruleset-scrolling-empty/osu.Game.Rulesets.EmptyScrolling/Objects/Drawables/DrawableEmptyScrollingHitObject.cs b/Templates/Rulesets/ruleset-scrolling-empty/osu.Game.Rulesets.EmptyScrolling/Objects/Drawables/DrawableEmptyScrollingHitObject.cs index a3c3b89105..070a802aea 100644 --- a/Templates/Rulesets/ruleset-scrolling-empty/osu.Game.Rulesets.EmptyScrolling/Objects/Drawables/DrawableEmptyScrollingHitObject.cs +++ b/Templates/Rulesets/ruleset-scrolling-empty/osu.Game.Rulesets.EmptyScrolling/Objects/Drawables/DrawableEmptyScrollingHitObject.cs @@ -24,7 +24,7 @@ namespace osu.Game.Rulesets.EmptyScrolling.Objects.Drawables { if (timeOffset >= 0) // todo: implement judgement logic - ApplyResult(r => r.Type = HitResult.Perfect); + ApplyResult(static r => r.Type = HitResult.Perfect); } protected override void UpdateHitStateTransforms(ArmedState state) diff --git a/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon/Objects/Drawables/DrawablePippidonHitObject.cs b/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon/Objects/Drawables/DrawablePippidonHitObject.cs index d198fa81cb..9983ec20b0 100644 --- a/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon/Objects/Drawables/DrawablePippidonHitObject.cs +++ b/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon/Objects/Drawables/DrawablePippidonHitObject.cs @@ -49,7 +49,12 @@ namespace osu.Game.Rulesets.Pippidon.Objects.Drawables protected override void CheckForResult(bool userTriggered, double timeOffset) { if (timeOffset >= 0) - ApplyResult(r => r.Type = currentLane.Value == HitObject.Lane ? HitResult.Perfect : HitResult.Miss); + { + ApplyResult(static (r, pippidonHitObject) => + { + r.Type = pippidonHitObject.currentLane.Value == pippidonHitObject.HitObject.Lane ? HitResult.Perfect : HitResult.Miss; + }, this); + } } protected override void UpdateHitStateTransforms(ArmedState state) diff --git a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableCatchHitObject.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableCatchHitObject.cs index 7f8c17861d..5a921f36f5 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableCatchHitObject.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableCatchHitObject.cs @@ -63,7 +63,12 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables if (CheckPosition == null) return; if (timeOffset >= 0 && Result != null) - ApplyResult(r => r.Type = CheckPosition.Invoke(HitObject) ? r.Judgement.MaxResult : r.Judgement.MinResult); + { + ApplyResult(static (r, state) => + { + r.Type = state.CheckPosition.Invoke(state.HitObject) ? r.Judgement.MaxResult : r.Judgement.MinResult; + }, this); + } } protected override void UpdateHitStateTransforms(ArmedState state) diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs index 3490d50871..e5056d5167 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs @@ -265,7 +265,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables if (Tail.AllJudged) { if (Tail.IsHit) - ApplyResult(r => r.Type = r.Judgement.MaxResult); + ApplyResult(static r => r.Type = r.Judgement.MaxResult); else MissForcefully(); } diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteBody.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteBody.cs index 1b2efbafdf..317da0580c 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteBody.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteBody.cs @@ -25,7 +25,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables { if (AllJudged) return; - ApplyResult(r => r.Type = hit ? r.Judgement.MaxResult : r.Judgement.MinResult); + ApplyResult(static (r, hit) => r.Type = hit ? r.Judgement.MaxResult : r.Judgement.MinResult, hit); } } } diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs index 8498fd36de..dea0817869 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs @@ -87,7 +87,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables /// /// Causes this to get missed, disregarding all conditions in implementations of . /// - public virtual void MissForcefully() => ApplyResult(r => r.Type = r.Judgement.MinResult); + public virtual void MissForcefully() => ApplyResult(static r => r.Type = r.Judgement.MinResult); } public abstract partial class DrawableManiaHitObject : DrawableManiaHitObject diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs index 680009bc4c..985007f905 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs @@ -89,7 +89,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables if (!userTriggered) { if (!HitObject.HitWindows.CanBeHit(timeOffset)) - ApplyResult(r => r.Type = r.Judgement.MinResult); + ApplyResult(static r => r.Type = r.Judgement.MinResult); return; } @@ -100,7 +100,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables result = GetCappedResult(result); - ApplyResult(r => r.Type = result); + ApplyResult(static (r, result) => r.Type = result, result); } /// diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs index 0d665cad0c..8284229d82 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs @@ -155,7 +155,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables if (!userTriggered) { if (!HitObject.HitWindows.CanBeHit(timeOffset)) - ApplyResult(r => r.Type = r.Judgement.MinResult); + ApplyResult(static r => r.Type = r.Judgement.MinResult); return; } @@ -169,19 +169,20 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables if (result == HitResult.None || clickAction != ClickAction.Hit) return; - ApplyResult(r => + ApplyResult(static (r, state) => { + var (hitCircle, hitResult) = state; var circleResult = (OsuHitCircleJudgementResult)r; // Todo: This should also consider misses, but they're a little more interesting to handle, since we don't necessarily know the position at the time of a miss. - if (result.IsHit()) + if (hitResult.IsHit()) { - var localMousePosition = ToLocalSpace(inputManager.CurrentState.Mouse.Position); - circleResult.CursorPositionAtHit = HitObject.StackedPosition + (localMousePosition - DrawSize / 2); + var localMousePosition = hitCircle.ToLocalSpace(hitCircle.inputManager.CurrentState.Mouse.Position); + circleResult.CursorPositionAtHit = hitCircle.HitObject.StackedPosition + (localMousePosition - hitCircle.DrawSize / 2); } - circleResult.Type = result; - }); + circleResult.Type = hitResult; + }, (this, result)); } /// diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs index 5b379a0d90..cc06d009c9 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs @@ -100,12 +100,12 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables /// /// Causes this to get hit, disregarding all conditions in implementations of . /// - public void HitForcefully() => ApplyResult(r => r.Type = r.Judgement.MaxResult); + public void HitForcefully() => ApplyResult(static r => r.Type = r.Judgement.MaxResult); /// /// Causes this to get missed, disregarding all conditions in implementations of . /// - public void MissForcefully() => ApplyResult(r => r.Type = r.Judgement.MinResult); + public void MissForcefully() => ApplyResult(static r => r.Type = r.Judgement.MinResult); private RectangleF parentScreenSpaceRectangle => ((DrawableOsuHitObject)ParentHitObject)?.parentScreenSpaceRectangle ?? Parent!.ScreenSpaceDrawQuad.AABBFloat; diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs index baec200107..3c298cc6af 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs @@ -292,10 +292,10 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables if (HitObject.ClassicSliderBehaviour) { // Classic behaviour means a slider is judged proportionally to the number of nested hitobjects hit. This is the classic osu!stable scoring. - ApplyResult(r => + ApplyResult(static (r, nestedHitObjects) => { - int totalTicks = NestedHitObjects.Count; - int hitTicks = NestedHitObjects.Count(h => h.IsHit); + int totalTicks = nestedHitObjects.Count; + int hitTicks = nestedHitObjects.Count(h => h.IsHit); if (hitTicks == totalTicks) r.Type = HitResult.Great; @@ -306,13 +306,16 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables double hitFraction = (double)hitTicks / totalTicks; r.Type = hitFraction >= 0.5 ? HitResult.Ok : HitResult.Meh; } - }); + }, NestedHitObjects); } else { // If only the nested hitobjects are judged, then the slider's own judgement is ignored for scoring purposes. // But the slider needs to still be judged with a reasonable hit/miss result for visual purposes (hit/miss transforms, etc). - ApplyResult(r => r.Type = NestedHitObjects.Any(h => h.Result.IsHit) ? r.Judgement.MaxResult : r.Judgement.MinResult); + ApplyResult(static (r, nestedHitObjects) => + { + r.Type = nestedHitObjects.Any(h => h.Result.IsHit) ? r.Judgement.MaxResult : r.Judgement.MinResult; + }, NestedHitObjects); } } diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs index bf4b07eaab..d21d02c8ce 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs @@ -258,17 +258,17 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables foreach (var tick in ticks.Where(t => !t.Result.HasResult)) tick.TriggerResult(false); - ApplyResult(r => + ApplyResult(static (r, spinner) => { - if (Progress >= 1) + if (spinner.Progress >= 1) r.Type = HitResult.Great; - else if (Progress > .9) + else if (spinner.Progress > .9) r.Type = HitResult.Ok; - else if (Progress > .75) + else if (spinner.Progress > .75) r.Type = HitResult.Meh; - else if (Time.Current >= HitObject.EndTime) + else if (spinner.Time.Current >= spinner.HitObject.EndTime) r.Type = r.Judgement.MinResult; - }); + }, this); } protected override void Update() diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinnerTick.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinnerTick.cs index 5b55533edd..1c3ff29118 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinnerTick.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinnerTick.cs @@ -35,6 +35,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables /// Apply a judgement result. /// /// Whether this tick was reached. - internal void TriggerResult(bool hit) => ApplyResult(r => r.Type = hit ? r.Judgement.MaxResult : r.Judgement.MinResult); + internal void TriggerResult(bool hit) => ApplyResult(static (r, hit) => r.Type = hit ? r.Judgement.MaxResult : r.Judgement.MinResult, hit); } } diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs index 2bf0c04adf..d3fe363857 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs @@ -143,7 +143,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables if (timeOffset < 0) return; - ApplyResult(r => r.Type = r.Judgement.MaxResult); + ApplyResult(static r => r.Type = r.Judgement.MaxResult); } protected override void UpdateHitStateTransforms(ArmedState state) @@ -192,7 +192,10 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables if (!ParentHitObject.Judged) return; - ApplyResult(r => r.Type = ParentHitObject.IsHit ? r.Judgement.MaxResult : r.Judgement.MinResult); + ApplyResult(static (r, parentHitObject) => + { + r.Type = parentHitObject.IsHit ? r.Judgement.MaxResult : r.Judgement.MinResult; + }, ParentHitObject); } public override bool OnPressed(KeyBindingPressEvent e) => false; diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs index c900165d34..de9a3a31c5 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs @@ -49,14 +49,14 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables if (!userTriggered) { if (timeOffset > HitObject.HitWindow) - ApplyResult(r => r.Type = r.Judgement.MinResult); + ApplyResult(static r => r.Type = r.Judgement.MinResult); return; } if (Math.Abs(timeOffset) > HitObject.HitWindow) return; - ApplyResult(r => r.Type = r.Judgement.MaxResult); + ApplyResult(static r => r.Type = r.Judgement.MaxResult); } public override void OnKilled() @@ -64,7 +64,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables base.OnKilled(); if (Time.Current > HitObject.GetEndTime() && !Judged) - ApplyResult(r => r.Type = r.Judgement.MinResult); + ApplyResult(static r => r.Type = r.Judgement.MinResult); } protected override void UpdateHitStateTransforms(ArmedState state) @@ -105,7 +105,10 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables if (!ParentHitObject.Judged) return; - ApplyResult(r => r.Type = ParentHitObject.IsHit ? r.Judgement.MaxResult : r.Judgement.MinResult); + ApplyResult(static (r, parentHitObject) => + { + r.Type = parentHitObject.IsHit ? r.Judgement.MaxResult : r.Judgement.MinResult; + }, ParentHitObject); } public override bool OnPressed(KeyBindingPressEvent e) => false; diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableFlyingHit.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableFlyingHit.cs index a039ce3407..1332b9e950 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableFlyingHit.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableFlyingHit.cs @@ -25,7 +25,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables protected override void LoadComplete() { base.LoadComplete(); - ApplyResult(r => r.Type = r.Judgement.MaxResult); + ApplyResult(static r => r.Type = r.Judgement.MaxResult); } protected override void LoadSamples() diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs index 1ef426854e..c3bd76bf81 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs @@ -99,7 +99,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables if (!userTriggered) { if (!HitObject.HitWindows.CanBeHit(timeOffset)) - ApplyResult(r => r.Type = r.Judgement.MinResult); + ApplyResult(static r => r.Type = r.Judgement.MinResult); return; } @@ -108,9 +108,9 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables return; if (!validActionPressed) - ApplyResult(r => r.Type = r.Judgement.MinResult); + ApplyResult(static r => r.Type = r.Judgement.MinResult); else - ApplyResult(r => r.Type = result); + ApplyResult(static (r, result) => r.Type = result, result); } public override bool OnPressed(KeyBindingPressEvent e) @@ -209,19 +209,19 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables if (!ParentHitObject.Result.IsHit) { - ApplyResult(r => r.Type = r.Judgement.MinResult); + ApplyResult(static r => r.Type = r.Judgement.MinResult); return; } if (!userTriggered) { if (timeOffset - ParentHitObject.Result.TimeOffset > SECOND_HIT_WINDOW) - ApplyResult(r => r.Type = r.Judgement.MinResult); + ApplyResult(static r => r.Type = r.Judgement.MinResult); return; } if (Math.Abs(timeOffset - ParentHitObject.Result.TimeOffset) <= SECOND_HIT_WINDOW) - ApplyResult(r => r.Type = r.Judgement.MaxResult); + ApplyResult(static r => r.Type = r.Judgement.MaxResult); } public override bool OnPressed(KeyBindingPressEvent e) diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableStrongNestedHit.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableStrongNestedHit.cs index 724d59edcd..4080c14066 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableStrongNestedHit.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableStrongNestedHit.cs @@ -27,7 +27,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables // it can happen that the hit window of the nested strong hit extends past the lifetime of the parent object. // this is a safety to prevent such cases from causing the nested hit to never be judged and as such prevent gameplay from completing. if (!Judged && Time.Current > ParentHitObject?.HitObject.GetEndTime()) - ApplyResult(r => r.Type = r.Judgement.MinResult); + ApplyResult(static r => r.Type = r.Judgement.MinResult); } } } diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs index e4a083f218..d48b78283b 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs @@ -206,7 +206,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables expandingRing.ScaleTo(1f + Math.Min(target_ring_scale - 1f, (target_ring_scale - 1f) * completion * 1.3f), 260, Easing.OutQuint); if (numHits == HitObject.RequiredHits) - ApplyResult(r => r.Type = r.Judgement.MaxResult); + ApplyResult(static r => r.Type = r.Judgement.MaxResult); } else { @@ -227,7 +227,11 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables tick.TriggerResult(false); } - ApplyResult(r => r.Type = numHits == HitObject.RequiredHits ? r.Judgement.MaxResult : r.Judgement.MinResult); + ApplyResult(static (r, state) => + { + var (numHits, hitObject) = state; + r.Type = numHits == hitObject.RequiredHits ? r.Judgement.MaxResult : r.Judgement.MinResult; + }, (numHits, HitObject)); } } diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwellTick.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwellTick.cs index 3a5c006962..ad1d09bc7b 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwellTick.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwellTick.cs @@ -30,7 +30,10 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables public void TriggerResult(bool hit) { HitObject.StartTime = Time.Current; - ApplyResult(r => r.Type = hit ? r.Judgement.MaxResult : r.Judgement.MinResult); + ApplyResult(static (r, hit) => + { + r.Type = hit ? r.Judgement.MaxResult : r.Judgement.MinResult; + }, hit); } protected override void CheckForResult(bool userTriggered, double timeOffset) diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index bce28361cb..9acd7b3c0f 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -687,12 +687,14 @@ namespace osu.Game.Rulesets.Objects.Drawables /// the of the . /// /// The callback that applies changes to the . - protected void ApplyResult(Action application) + /// The state passed to the callback. + /// The type of the state information that is passed to the callback method. + protected void ApplyResult(Action application, TState state) { if (Result.HasResult) throw new InvalidOperationException("Cannot apply result on a hitobject that already has a result."); - application?.Invoke(Result); + application?.Invoke(Result, state); if (!Result.HasResult) throw new InvalidOperationException($"{GetType().ReadableName()} applied a {nameof(JudgementResult)} but did not update {nameof(JudgementResult.Type)}."); @@ -714,6 +716,13 @@ namespace osu.Game.Rulesets.Objects.Drawables OnNewResult?.Invoke(this, Result); } + /// + /// Applies the of this , notifying responders such as + /// the of the . + /// + /// The callback that applies changes to the . + protected void ApplyResult(Action application) => ApplyResult((r, _) => application?.Invoke(r), null); + /// /// Processes this , checking if a scoring result has occurred. ///