diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs
index 05cb42d853..4d67c9ae34 100644
--- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs
+++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs
@@ -156,6 +156,12 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
}
}
+ public override void OnKilled()
+ {
+ base.OnKilled();
+ Body.RecyclePath();
+ }
+
protected override void SkinChanged(ISkinSource skin, bool allowFallback)
{
base.SkinChanged(skin, allowFallback);
diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBody.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBody.cs
index 33b3667c4f..97c7c9cec5 100644
--- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBody.cs
+++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBody.cs
@@ -13,7 +13,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
{
public const float DEFAULT_BORDER_SIZE = 1;
- private readonly SliderPath path;
+ private SliderPath path;
+
protected Path Path => path;
public float PathRadius
@@ -77,6 +78,22 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
InternalChild = path = new SliderPath();
}
+ ///
+ /// Initialises a new , releasing all resources retained by the old one.
+ ///
+ public void RecyclePath()
+ {
+ InternalChild = path = new SliderPath
+ {
+ Position = path.Position,
+ PathRadius = path.PathRadius,
+ AccentColour = path.AccentColour,
+ BorderColour = path.BorderColour,
+ BorderSize = path.BorderSize,
+ Vertices = path.Vertices
+ };
+ }
+
public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => path.ReceivePositionalInputAt(screenSpacePos);
///
diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs
index 76233eabf2..e61fac679e 100644
--- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs
+++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs
@@ -7,7 +7,6 @@ using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Extensions.TypeExtensions;
-using osu.Framework.Graphics;
using osu.Framework.Graphics.Primitives;
using osu.Game.Audio;
using osu.Game.Graphics;
@@ -202,12 +201,13 @@ namespace osu.Game.Rulesets.Objects.Drawables
protected virtual double InitialLifetimeOffset => 10000;
///
- /// Will called at least once after the of this has been passed.
+ /// Will be called at least once after this has become not alive.
///
- internal void OnLifetimeEnd()
+ public virtual void OnKilled()
{
foreach (var nested in NestedHitObjects)
- nested.OnLifetimeEnd();
+ nested.OnKilled();
+
UpdateResult(false);
}
diff --git a/osu.Game/Rulesets/UI/HitObjectContainer.cs b/osu.Game/Rulesets/UI/HitObjectContainer.cs
index 2f3a384e95..aa942e70df 100644
--- a/osu.Game/Rulesets/UI/HitObjectContainer.cs
+++ b/osu.Game/Rulesets/UI/HitObjectContainer.cs
@@ -34,8 +34,14 @@ namespace osu.Game.Rulesets.UI
protected override void OnChildLifetimeBoundaryCrossed(LifetimeBoundaryCrossedEvent e)
{
- if (e.Kind == LifetimeBoundaryKind.End && e.Direction == LifetimeBoundaryCrossingDirection.Forward && e.Child is DrawableHitObject hitObject)
- hitObject.OnLifetimeEnd();
+ if (!(e.Child is DrawableHitObject hitObject))
+ return;
+
+ if (e.Kind == LifetimeBoundaryKind.End && e.Direction == LifetimeBoundaryCrossingDirection.Forward
+ || e.Kind == LifetimeBoundaryKind.Start && e.Direction == LifetimeBoundaryCrossingDirection.Backward)
+ {
+ hitObject.OnKilled();
+ }
}
}
}