1
0
mirror of https://github.com/ppy/osu.git synced 2024-12-13 08:32:57 +08:00

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>
/// Connects hit objects visually, for example with follow points.
/// </summary>
public abstract class ConnectionRenderer<T> : Container
public abstract class ConnectionRenderer<T> : LifetimeManagementContainer
where T : HitObject
{
/// <summary>

View File

@ -56,7 +56,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Connections
private void update()
{
Clear();
ClearInternal();
if (hitObjects == null)
return;
@ -86,7 +86,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Connections
FollowPoint fp;
Add(fp = new FollowPoint
AddInternal(fp = new FollowPoint
{
Position = pointStartPosition,
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.ScaleTo(1.1f, HitObject.TimePreempt);
ApproachCircle.Expire(true);
}
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 override bool RemoveWhenNotAlive => false;
public ApproachCircle()
{
Anchor = Anchor.Centre;

View File

@ -16,7 +16,7 @@ namespace osu.Game.Rulesets.Osu.UI
{
public class OsuPlayfield : Playfield
{
private readonly Container approachCircles;
private readonly ApproachCircleProxyContainer approachCircles;
private readonly JudgementContainer<DrawableOsuJudgement> judgementLayer;
private readonly ConnectionRenderer<OsuHitObject> connectionLayer;
@ -45,7 +45,7 @@ namespace osu.Game.Rulesets.Osu.UI
Depth = 1,
},
HitObjectContainer,
approachCircles = new Container
approachCircles = new ApproachCircleProxyContainer
{
RelativeSizeAxes = Axes.Both,
Depth = -1,
@ -60,11 +60,23 @@ namespace osu.Game.Rulesets.Osu.UI
var c = h as IDrawableHitObjectWithProxiedApproach;
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);
}
private void addApproachCircleProxy(Drawable d)
{
var proxy = d.CreateProxy();
proxy.LifetimeStart = d.LifetimeStart;
proxy.LifetimeEnd = d.LifetimeEnd;
approachCircles.Add(proxy);
}
public override void PostProcess()
{
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);
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
{
public class HitObjectContainer : CompositeDrawable
public class HitObjectContainer : LifetimeManagementContainer
{
public IEnumerable<DrawableHitObject> Objects => InternalChildren.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
{
public class DrawableStoryboardLayer : Container
public class DrawableStoryboardLayer : LifetimeManagementContainer
{
public StoryboardLayer Layer { get; private set; }
public bool Enabled;
@ -29,7 +29,7 @@ namespace osu.Game.Storyboards.Drawables
foreach (var element in Layer.Elements)
{
if (element.IsDrawable)
Add(element.CreateDrawable());
AddInternal(element.CreateDrawable());
}
}
}