Delay lifetime computation until loaded

This commit is contained in:
ekrctb
2020-11-24 16:46:10 +09:00
parent d5f082e5fb
commit 7f6e4d5b21

View File

@ -21,7 +21,7 @@ namespace osu.Game.Rulesets.UI.Scrolling
private readonly HashSet<DrawableHitObject> layoutComputedHitObjects = new HashSet<DrawableHitObject>(); private readonly HashSet<DrawableHitObject> layoutComputedHitObjects = new HashSet<DrawableHitObject>();
// Used to recompute all lifetime when `layoutCache` becomes invalid // Used to recompute all lifetime when `layoutCache` becomes invalid
private readonly HashSet<DrawableHitObject> lifetimeComputedHitObjects = new HashSet<DrawableHitObject>(); private readonly HashSet<DrawableHitObject> allHitObjects = new HashSet<DrawableHitObject>();
[Resolved] [Resolved]
private IScrollingInfo scrollingInfo { get; set; } private IScrollingInfo scrollingInfo { get; set; }
@ -150,18 +150,19 @@ namespace osu.Game.Rulesets.UI.Scrolling
/// </summary> /// </summary>
public void InvalidateDrawableHitObject(DrawableHitObject hitObject) public void InvalidateDrawableHitObject(DrawableHitObject hitObject)
{ {
// Lifetime is computed once early and // Lifetime computation is delayed to the next update because `scrollLength` may not be valid here.
// layout (Width/Height if `IHasDuration`, and nested object positions) will be computed when the object becomes alive. // Layout computation will be delayed to when the object becomes alive.
// An assumption is that a hit object layout update (setting `Height` or `Width`) won't affect its lifetime. // An assumption is that a hit object layout update (setting `Height` or `Width`) won't affect its lifetime but
// This is satisfied in practice because otherwise the hit object won't be aligned to its `StartTime`. // this is satisfied in practice because otherwise the hit object won't be aligned to its `StartTime`.
hitObject.LifetimeStart = computeOriginAdjustedLifetimeStart(hitObject);
layoutCache.Invalidate();
allHitObjects.Add(hitObject);
lifetimeComputedHitObjects.Add(hitObject);
layoutComputedHitObjects.Remove(hitObject); layoutComputedHitObjects.Remove(hitObject);
} }
// Use a nonzero value to prevent infinite results private float scrollLength;
private float scrollLength = 1;
protected override void Update() protected override void Update()
{ {
@ -170,7 +171,7 @@ namespace osu.Game.Rulesets.UI.Scrolling
if (!layoutCache.IsValid) if (!layoutCache.IsValid)
{ {
// this.Objects cannot be used as it doesn't contain nested objects // this.Objects cannot be used as it doesn't contain nested objects
foreach (var hitObject in lifetimeComputedHitObjects) foreach (var hitObject in allHitObjects)
hitObject.LifetimeStart = computeOriginAdjustedLifetimeStart(hitObject); hitObject.LifetimeStart = computeOriginAdjustedLifetimeStart(hitObject);
layoutComputedHitObjects.Clear(); layoutComputedHitObjects.Clear();