diff --git a/osu.Game/Rulesets/Objects/HitObjectLifetimeEntry.cs b/osu.Game/Rulesets/Objects/HitObjectLifetimeEntry.cs new file mode 100644 index 0000000000..f134c66274 --- /dev/null +++ b/osu.Game/Rulesets/Objects/HitObjectLifetimeEntry.cs @@ -0,0 +1,98 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Graphics.Performance; +using osu.Game.Rulesets.Objects.Drawables; + +namespace osu.Game.Rulesets.Objects +{ + /// + /// A that stores the lifetime for a . + /// + public class HitObjectLifetimeEntry : LifetimeEntry + { + /// + /// The . + /// + public readonly HitObject HitObject; + + /// + /// Creates a new . + /// + /// The to store the lifetime of. + public HitObjectLifetimeEntry(HitObject hitObject) + { + HitObject = hitObject; + ResetLifetimeStart(); + } + + // The lifetime start, as set by the hitobject. + private double realLifetimeStart = double.MinValue; + + /// + /// The time at which the should become alive. + /// + public new double LifetimeStart + { + get => realLifetimeStart; + set => setLifetime(realLifetimeStart = value, LifetimeEnd); + } + + // The lifetime end, as set by the hitobject. + private double realLifetimeEnd = double.MaxValue; + + /// + /// The time at which the should become dead. + /// + public new double LifetimeEnd + { + get => realLifetimeEnd; + set => setLifetime(LifetimeStart, realLifetimeEnd = value); + } + + private void setLifetime(double start, double end) + { + if (keepAlive) + { + start = double.MinValue; + end = double.MaxValue; + } + + base.LifetimeStart = start; + base.LifetimeEnd = end; + } + + private bool keepAlive; + + /// + /// Whether the should be kept always alive. + /// + internal bool KeepAlive + { + set + { + if (keepAlive == value) + return; + + keepAlive = value; + setLifetime(realLifetimeStart, realLifetimeEnd); + } + } + + /// + /// A safe offset prior to the start time of at which it may begin displaying contents. + /// By default, s are assumed to display their contents within 10 seconds prior to their start time. + /// + /// + /// This is only used as an optimisation to delay the initial update of the and may be tuned more aggressively if required. + /// It is indirectly used to decide the automatic transform offset provided to . + /// A more accurate should be set for further optimisation (in , for example). + /// + protected virtual double InitialLifetimeOffset => 10000; + + /// + /// Resets according to the start time of the . + /// + internal void ResetLifetimeStart() => LifetimeStart = HitObject.StartTime - InitialLifetimeOffset; + } +}