mirror of
https://github.com/osukey/osukey.git
synced 2025-07-02 00:40:09 +09:00
Compute lifetime from entry in scrolling container
This commit is contained in:
@ -5,10 +5,10 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Primitives;
|
||||
using osu.Framework.Layout;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
using osu.Game.Rulesets.Objects.Drawables;
|
||||
@ -127,6 +127,16 @@ namespace osu.Game.Rulesets.UI.Scrolling
|
||||
|
||||
private float scrollLength => scrollingAxis == Direction.Horizontal ? DrawWidth : DrawHeight;
|
||||
|
||||
public override void Add(HitObjectLifetimeEntry entry)
|
||||
{
|
||||
// Scroll info is not available until loaded.
|
||||
// The lifetime of all entries will be updated in the first Update.
|
||||
if (IsLoaded)
|
||||
setComputedLifetimeStart(entry);
|
||||
|
||||
base.Add(entry);
|
||||
}
|
||||
|
||||
protected override void AddDrawable(HitObjectLifetimeEntry entry, DrawableHitObject drawable)
|
||||
{
|
||||
base.AddDrawable(entry, drawable);
|
||||
@ -145,7 +155,6 @@ namespace osu.Game.Rulesets.UI.Scrolling
|
||||
|
||||
private void invalidateHitObject(DrawableHitObject hitObject)
|
||||
{
|
||||
hitObject.LifetimeStart = computeOriginAdjustedLifetimeStart(hitObject);
|
||||
layoutComputed.Remove(hitObject);
|
||||
}
|
||||
|
||||
@ -157,10 +166,8 @@ namespace osu.Game.Rulesets.UI.Scrolling
|
||||
|
||||
layoutComputed.Clear();
|
||||
|
||||
// Reset lifetime to the conservative estimation.
|
||||
// If a drawable becomes alive by this lifetime, its lifetime will be updated to a more precise lifetime in the next update.
|
||||
foreach (var entry in Entries)
|
||||
entry.SetInitialLifetime();
|
||||
setComputedLifetimeStart(entry);
|
||||
|
||||
scrollingInfo.Algorithm.Reset();
|
||||
|
||||
@ -187,38 +194,46 @@ namespace osu.Game.Rulesets.UI.Scrolling
|
||||
}
|
||||
}
|
||||
|
||||
private double computeOriginAdjustedLifetimeStart(DrawableHitObject hitObject)
|
||||
/// <summary>
|
||||
/// Get a conservative maximum bounding box of a <see cref="DrawableHitObject"/> corresponding to <paramref name="entry"/>.
|
||||
/// It is used to calculate when the hit object appears.
|
||||
/// </summary>
|
||||
protected virtual RectangleF GetConservativeBoundingBox(HitObjectLifetimeEntry entry) => new RectangleF().Inflate(100);
|
||||
|
||||
private double computeDisplayStartTime(HitObjectLifetimeEntry entry)
|
||||
{
|
||||
// Origin position may be relative to the parent size
|
||||
Debug.Assert(hitObject.Parent != null);
|
||||
RectangleF boundingBox = GetConservativeBoundingBox(entry);
|
||||
float startOffset = 0;
|
||||
|
||||
float originAdjustment = 0.0f;
|
||||
|
||||
// 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)
|
||||
{
|
||||
case ScrollingDirection.Up:
|
||||
originAdjustment = hitObject.OriginPosition.Y;
|
||||
case ScrollingDirection.Right:
|
||||
startOffset = boundingBox.Right;
|
||||
break;
|
||||
|
||||
case ScrollingDirection.Down:
|
||||
originAdjustment = hitObject.DrawHeight - hitObject.OriginPosition.Y;
|
||||
startOffset = boundingBox.Bottom;
|
||||
break;
|
||||
|
||||
case ScrollingDirection.Left:
|
||||
originAdjustment = hitObject.OriginPosition.X;
|
||||
startOffset = -boundingBox.Left;
|
||||
break;
|
||||
|
||||
case ScrollingDirection.Right:
|
||||
originAdjustment = hitObject.DrawWidth - hitObject.OriginPosition.X;
|
||||
case ScrollingDirection.Up:
|
||||
startOffset = -boundingBox.Top;
|
||||
break;
|
||||
}
|
||||
|
||||
double computedStartTime = scrollingInfo.Algorithm.GetDisplayStartTime(hitObject.HitObject.StartTime, originAdjustment, timeRange.Value, scrollLength);
|
||||
return scrollingInfo.Algorithm.GetDisplayStartTime(entry.HitObject.StartTime, startOffset, timeRange.Value, scrollLength);
|
||||
}
|
||||
|
||||
private void setComputedLifetimeStart(HitObjectLifetimeEntry entry)
|
||||
{
|
||||
double computedStartTime = computeDisplayStartTime(entry);
|
||||
|
||||
// always load the hitobject before its first judgement offset
|
||||
return Math.Min(hitObject.HitObject.StartTime - hitObject.MaximumJudgementOffset, computedStartTime);
|
||||
double judgementOffset = entry.HitObject.HitWindows?.WindowFor(Scoring.HitResult.Miss) ?? 0;
|
||||
entry.LifetimeStart = Math.Min(entry.HitObject.StartTime - judgementOffset, computedStartTime);
|
||||
}
|
||||
|
||||
private void updateLayoutRecursive(DrawableHitObject hitObject)
|
||||
|
Reference in New Issue
Block a user