From 79438c19a45eecb5c0983e6a14efb98539e3686c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 18 Sep 2021 16:27:30 +0200 Subject: [PATCH] Fix slider parts not reproxying after first hitobject freed --- .../Objects/Drawables/DrawableSlider.cs | 2 +- .../Skinning/Legacy/LegacyReverseArrow.cs | 29 +++++++++++++++++-- .../Legacy/LegacySliderHeadHitCircle.cs | 27 +++++++++++++++-- 3 files changed, 52 insertions(+), 6 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs index 0e1d1043e3..3acec4498d 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs @@ -187,7 +187,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables repeatContainer.Clear(false); tickContainer.Clear(false); - OverlayElementContainer.Clear(); + OverlayElementContainer.Clear(false); } protected override DrawableHitObject CreateNestedHitObject(HitObject hitObject) diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyReverseArrow.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyReverseArrow.cs index b6956693b6..9e4bd258bd 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyReverseArrow.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyReverseArrow.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.Diagnostics; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -17,12 +18,14 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy [Resolved(canBeNull: true)] private DrawableHitObject drawableHitObject { get; set; } + private Drawable proxy; + public LegacyReverseArrow(ISkin skin) { this.skin = skin; } - [BackgroundDependencyLoader] + [BackgroundDependencyLoader(true)] private void load() { AutoSizeAxes = Axes.Both; @@ -36,9 +39,29 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy { base.LoadComplete(); + proxy = CreateProxy(); + + if (drawableHitObject != null) + { + drawableHitObject.HitObjectApplied += onHitObjectApplied; + onHitObjectApplied(drawableHitObject); + } + } + + private void onHitObjectApplied(DrawableHitObject drawableObject) + { + Debug.Assert(proxy.Parent == null); + // see logic in LegacySliderHeadHitCircle. - (drawableHitObject as DrawableSliderRepeat)?.DrawableSlider - .OverlayElementContainer.Add(CreateProxy()); + (drawableObject as DrawableSliderRepeat)?.DrawableSlider + .OverlayElementContainer.Add(proxy); + } + + protected override void Dispose(bool isDisposing) + { + base.Dispose(isDisposing); + if (drawableHitObject != null) + drawableHitObject.HitObjectApplied -= onHitObjectApplied; } } } diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacySliderHeadHitCircle.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacySliderHeadHitCircle.cs index 83ebdafa50..13ba42ba50 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacySliderHeadHitCircle.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacySliderHeadHitCircle.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.Diagnostics; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Game.Rulesets.Objects.Drawables; @@ -13,6 +14,8 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy [Resolved(canBeNull: true)] private DrawableHitObject drawableHitObject { get; set; } + private Drawable proxiedHitCircleOverlay; + public LegacySliderHeadHitCircle() : base("sliderstartcircle") { @@ -21,10 +24,30 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy protected override void LoadComplete() { base.LoadComplete(); + proxiedHitCircleOverlay = HitCircleOverlay.CreateProxy(); + + if (drawableHitObject != null) + { + drawableHitObject.HitObjectApplied += onHitObjectApplied; + onHitObjectApplied(drawableHitObject); + } + } + + private void onHitObjectApplied(DrawableHitObject drawableObject) + { + Debug.Assert(proxiedHitCircleOverlay.Parent == null); // see logic in LegacyReverseArrow. - (drawableHitObject as DrawableSliderHead)?.DrawableSlider - .OverlayElementContainer.Add(HitCircleOverlay.CreateProxy().With(d => d.Depth = float.MinValue)); + (drawableObject as DrawableSliderHead)?.DrawableSlider + .OverlayElementContainer.Add(proxiedHitCircleOverlay.With(d => d.Depth = float.MinValue)); + } + + protected override void Dispose(bool isDisposing) + { + base.Dispose(isDisposing); + + if (drawableHitObject != null) + drawableHitObject.HitObjectApplied -= onHitObjectApplied; } } }