Revert "Use entry to calculate lifetime in ScrollingHOC"

This reverts commit 632bb70e
This commit is contained in:
ekrctb
2021-05-18 19:55:31 +09:00
parent 2c65b8fa93
commit 84a1a86c63

View File

@ -5,9 +5,7 @@ using System.Collections.Generic;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Bindables; using osu.Framework.Bindables;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Primitives;
using osu.Framework.Layout; using osu.Framework.Layout;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Objects.Types;
using osuTK; using osuTK;
@ -19,18 +17,16 @@ namespace osu.Game.Rulesets.UI.Scrolling
private readonly IBindable<double> timeRange = new BindableDouble(); private readonly IBindable<double> timeRange = new BindableDouble();
private readonly IBindable<ScrollingDirection> direction = new Bindable<ScrollingDirection>(); private readonly IBindable<ScrollingDirection> direction = new Bindable<ScrollingDirection>();
/// <summary>
/// Hit objects which require lifetime computation in the next update call.
/// </summary>
private readonly HashSet<DrawableHitObject> toComputeLifetime = new HashSet<DrawableHitObject>();
/// <summary> /// <summary>
/// A set containing all <see cref="HitObjectContainer.AliveObjects"/> which have an up-to-date layout. /// A set containing all <see cref="HitObjectContainer.AliveObjects"/> which have an up-to-date layout.
/// </summary> /// </summary>
private readonly HashSet<DrawableHitObject> layoutComputed = new HashSet<DrawableHitObject>(); private readonly HashSet<DrawableHitObject> layoutComputed = new HashSet<DrawableHitObject>();
/// <summary>
/// A conservative estimate of maximum bounding box of a <see cref="DrawableHitObject"/>
/// with respect to the start time position of the hit object.
/// It is used to calculate when the object appears inbound.
/// </summary>
protected virtual RectangleF GetDrawRectangle(HitObjectLifetimeEntry entry) => new RectangleF().Inflate(100);
[Resolved] [Resolved]
private IScrollingInfo scrollingInfo { get; set; } private IScrollingInfo scrollingInfo { get; set; }
@ -58,6 +54,7 @@ namespace osu.Game.Rulesets.UI.Scrolling
{ {
base.Clear(); base.Clear();
toComputeLifetime.Clear();
layoutComputed.Clear(); layoutComputed.Clear();
} }
@ -169,6 +166,7 @@ namespace osu.Game.Rulesets.UI.Scrolling
private void onRemoveRecursive(DrawableHitObject hitObject) private void onRemoveRecursive(DrawableHitObject hitObject)
{ {
toComputeLifetime.Remove(hitObject);
layoutComputed.Remove(hitObject); layoutComputed.Remove(hitObject);
hitObject.DefaultsApplied -= invalidateHitObject; hitObject.DefaultsApplied -= invalidateHitObject;
@ -177,11 +175,14 @@ namespace osu.Game.Rulesets.UI.Scrolling
onRemoveRecursive(nested); onRemoveRecursive(nested);
} }
/// <summary>
/// Make this <see cref="DrawableHitObject"/> lifetime and layout computed in next update.
/// </summary>
private void invalidateHitObject(DrawableHitObject hitObject) private void invalidateHitObject(DrawableHitObject hitObject)
{ {
if (hitObject.ParentHitObject == null) // Lifetime computation is delayed until next update because
updateLifetime(hitObject.Entry); // when the hit object is not pooled this container is not loaded here and `scrollLength` cannot be computed.
toComputeLifetime.Add(hitObject);
layoutComputed.Remove(hitObject); layoutComputed.Remove(hitObject);
} }
@ -193,8 +194,13 @@ namespace osu.Game.Rulesets.UI.Scrolling
if (!layoutCache.IsValid) if (!layoutCache.IsValid)
{ {
foreach (var entry in Entries) toComputeLifetime.Clear();
updateLifetime(entry);
foreach (var hitObject in Objects)
{
if (hitObject.HitObject != null)
toComputeLifetime.Add(hitObject);
}
layoutComputed.Clear(); layoutComputed.Clear();
@ -214,6 +220,11 @@ namespace osu.Game.Rulesets.UI.Scrolling
layoutCache.Validate(); layoutCache.Validate();
} }
foreach (var hitObject in toComputeLifetime)
hitObject.LifetimeStart = computeOriginAdjustedLifetimeStart(hitObject);
toComputeLifetime.Clear();
} }
protected override void UpdateAfterChildrenLife() protected override void UpdateAfterChildrenLife()
@ -236,31 +247,32 @@ namespace osu.Game.Rulesets.UI.Scrolling
} }
} }
private void updateLifetime(HitObjectLifetimeEntry entry) private double computeOriginAdjustedLifetimeStart(DrawableHitObject hitObject)
{ {
var rectangle = GetDrawRectangle(entry); float originAdjustment = 0.0f;
float startOffset = 0;
// calculate the dimension of the part of the hitobject that should already be visible
// when the hitobject origin first appears inside the scrolling container
switch (direction.Value) switch (direction.Value)
{ {
case ScrollingDirection.Right: case ScrollingDirection.Up:
startOffset = rectangle.Right; originAdjustment = hitObject.OriginPosition.Y;
break; break;
case ScrollingDirection.Down: case ScrollingDirection.Down:
startOffset = rectangle.Bottom; originAdjustment = hitObject.DrawHeight - hitObject.OriginPosition.Y;
break; break;
case ScrollingDirection.Left: case ScrollingDirection.Left:
startOffset = -rectangle.Left; originAdjustment = hitObject.OriginPosition.X;
break; break;
case ScrollingDirection.Up: case ScrollingDirection.Right:
startOffset = -rectangle.Top; originAdjustment = hitObject.DrawWidth - hitObject.OriginPosition.X;
break; break;
} }
entry.LifetimeStart = scrollingInfo.Algorithm.GetDisplayStartTime(entry.HitObject.StartTime, startOffset, timeRange.Value, scrollLength); return scrollingInfo.Algorithm.GetDisplayStartTime(hitObject.HitObject.StartTime, originAdjustment, timeRange.Value, scrollLength);
} }
private void updateLayoutRecursive(DrawableHitObject hitObject) private void updateLayoutRecursive(DrawableHitObject hitObject)