Use LifetimeManagementContainer

This is a significant performance boost for gameplay,
especially for long or stroyboard-heavy maps.
This commit is contained in:
ekrctb
2018-12-13 14:55:28 +09:00
parent f29c6987d2
commit 6f8a2e6ff2
7 changed files with 29 additions and 9 deletions

View File

@ -10,7 +10,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Connections
/// <summary> /// <summary>
/// Connects hit objects visually, for example with follow points. /// Connects hit objects visually, for example with follow points.
/// </summary> /// </summary>
public abstract class ConnectionRenderer<T> : Container public abstract class ConnectionRenderer<T> : LifetimeManagementContainer
where T : HitObject where T : HitObject
{ {
/// <summary> /// <summary>

View File

@ -56,7 +56,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Connections
private void update() private void update()
{ {
Clear(); ClearInternal();
if (hitObjects == null) if (hitObjects == null)
return; return;
@ -86,7 +86,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Connections
FollowPoint fp; FollowPoint fp;
Add(fp = new FollowPoint AddInternal(fp = new FollowPoint
{ {
Position = pointStartPosition, Position = pointStartPosition,
Rotation = rotation, Rotation = rotation,

View File

@ -118,6 +118,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
ApproachCircle.FadeIn(Math.Min(HitObject.TimeFadeIn * 2, HitObject.TimePreempt)); ApproachCircle.FadeIn(Math.Min(HitObject.TimeFadeIn * 2, HitObject.TimePreempt));
ApproachCircle.ScaleTo(1.1f, HitObject.TimePreempt); ApproachCircle.ScaleTo(1.1f, HitObject.TimePreempt);
ApproachCircle.Expire(true);
} }
protected override void UpdateCurrentState(ArmedState state) protected override void UpdateCurrentState(ArmedState state)

View File

@ -12,6 +12,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
{ {
public class ApproachCircle : Container public class ApproachCircle : Container
{ {
public override bool RemoveWhenNotAlive => false;
public ApproachCircle() public ApproachCircle()
{ {
Anchor = Anchor.Centre; Anchor = Anchor.Centre;

View File

@ -16,7 +16,7 @@ namespace osu.Game.Rulesets.Osu.UI
{ {
public class OsuPlayfield : Playfield public class OsuPlayfield : Playfield
{ {
private readonly Container approachCircles; private readonly ApproachCircleProxyContainer approachCircles;
private readonly JudgementContainer<DrawableOsuJudgement> judgementLayer; private readonly JudgementContainer<DrawableOsuJudgement> judgementLayer;
private readonly ConnectionRenderer<OsuHitObject> connectionLayer; private readonly ConnectionRenderer<OsuHitObject> connectionLayer;
@ -45,7 +45,7 @@ namespace osu.Game.Rulesets.Osu.UI
Depth = 1, Depth = 1,
}, },
HitObjectContainer, HitObjectContainer,
approachCircles = new Container approachCircles = new ApproachCircleProxyContainer
{ {
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
Depth = -1, Depth = -1,
@ -60,11 +60,23 @@ namespace osu.Game.Rulesets.Osu.UI
var c = h as IDrawableHitObjectWithProxiedApproach; var c = h as IDrawableHitObjectWithProxiedApproach;
if (c != null) if (c != null)
approachCircles.Add(c.ProxiedLayer.CreateProxy()); {
var original = c.ProxiedLayer;
// lifetime is set on LoadComplete so wait until it.
original.OnLoadComplete += addApproachCircleProxy;
}
base.Add(h); base.Add(h);
} }
private void addApproachCircleProxy(Drawable d)
{
var proxy = d.CreateProxy();
proxy.LifetimeStart = d.LifetimeStart;
proxy.LifetimeEnd = d.LifetimeEnd;
approachCircles.Add(proxy);
}
public override void PostProcess() public override void PostProcess()
{ {
connectionLayer.HitObjects = HitObjectContainer.Objects.Select(d => d.HitObject).OfType<OsuHitObject>(); connectionLayer.HitObjects = HitObjectContainer.Objects.Select(d => d.HitObject).OfType<OsuHitObject>();
@ -86,5 +98,10 @@ namespace osu.Game.Rulesets.Osu.UI
} }
public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => HitObjectContainer.ReceivePositionalInputAt(screenSpacePos); public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => HitObjectContainer.ReceivePositionalInputAt(screenSpacePos);
private class ApproachCircleProxyContainer : LifetimeManagementContainer
{
public void Add(Drawable approachCircleProxy) => AddInternal(approachCircleProxy);
}
} }
} }

View File

@ -9,7 +9,7 @@ using osu.Game.Rulesets.Objects.Drawables;
namespace osu.Game.Rulesets.UI namespace osu.Game.Rulesets.UI
{ {
public class HitObjectContainer : CompositeDrawable public class HitObjectContainer : LifetimeManagementContainer
{ {
public IEnumerable<DrawableHitObject> Objects => InternalChildren.Cast<DrawableHitObject>().OrderBy(h => h.HitObject.StartTime); public IEnumerable<DrawableHitObject> Objects => InternalChildren.Cast<DrawableHitObject>().OrderBy(h => h.HitObject.StartTime);
public IEnumerable<DrawableHitObject> AliveObjects => AliveInternalChildren.Cast<DrawableHitObject>().OrderBy(h => h.HitObject.StartTime); public IEnumerable<DrawableHitObject> AliveObjects => AliveInternalChildren.Cast<DrawableHitObject>().OrderBy(h => h.HitObject.StartTime);

View File

@ -7,7 +7,7 @@ using osu.Framework.Graphics.Containers;
namespace osu.Game.Storyboards.Drawables namespace osu.Game.Storyboards.Drawables
{ {
public class DrawableStoryboardLayer : Container public class DrawableStoryboardLayer : LifetimeManagementContainer
{ {
public StoryboardLayer Layer { get; private set; } public StoryboardLayer Layer { get; private set; }
public bool Enabled; public bool Enabled;
@ -29,7 +29,7 @@ namespace osu.Game.Storyboards.Drawables
foreach (var element in Layer.Elements) foreach (var element in Layer.Elements)
{ {
if (element.IsDrawable) if (element.IsDrawable)
Add(element.CreateDrawable()); AddInternal(element.CreateDrawable());
} }
} }
} }