Add hitobject lifetime support

This commit is contained in:
smoogipoo
2020-11-10 20:16:52 +09:00
parent 45e9f16f6b
commit 6f3f6dc28b
6 changed files with 86 additions and 16 deletions

View File

@ -120,6 +120,12 @@ namespace osu.Game.Rulesets.Objects.Drawables
/// </summary>
private bool hasHitObjectApplied;
/// <summary>
/// The <see cref="HitObjectLifetimeEntry"/> controlling the lifetime of the currently-attached <see cref="HitObject"/>.
/// </summary>
[CanBeNull]
private HitObjectLifetimeEntry lifetimeEntry;
/// <summary>
/// Creates a new <see cref="DrawableHitObject"/>.
/// </summary>
@ -143,7 +149,7 @@ namespace osu.Game.Rulesets.Objects.Drawables
base.LoadAsyncComplete();
if (HitObject != null)
Apply(HitObject);
Apply(HitObject, lifetimeEntry);
}
protected override void LoadComplete()
@ -160,16 +166,33 @@ namespace osu.Game.Rulesets.Objects.Drawables
/// Applies a new <see cref="HitObject"/> to be represented by this <see cref="DrawableHitObject"/>.
/// </summary>
/// <param name="hitObject">The <see cref="HitObject"/> to apply.</param>
public void Apply(HitObject hitObject)
/// <param name="lifetimeEntry">The <see cref="HitObjectLifetimeEntry"/> controlling the lifetime of <paramref name="hitObject"/>.</param>
public void Apply([NotNull] HitObject hitObject, [CanBeNull] HitObjectLifetimeEntry lifetimeEntry)
{
free();
HitObject = hitObject ?? throw new InvalidOperationException($"Cannot apply a null {nameof(HitObject)}.");
this.lifetimeEntry = lifetimeEntry;
if (lifetimeEntry != null)
{
// Transfer lifetime from the entry.
LifetimeStart = lifetimeEntry.LifetimeStart;
LifetimeEnd = lifetimeEntry.LifetimeEnd;
// Copy any existing result from the entry (required for rewind / judgement revert).
Result = lifetimeEntry.Result;
}
// Ensure this DHO has a result.
Result ??= CreateResult(HitObject.CreateJudgement())
?? throw new InvalidOperationException($"{GetType().ReadableName()} must provide a {nameof(JudgementResult)} through {nameof(CreateResult)}.");
// Copy back the result to the entry for potential future retrieval.
if (lifetimeEntry != null)
lifetimeEntry.Result = Result;
foreach (var h in HitObject.NestedHitObjects)
{
var drawableNested = CreateNestedHitObject(h) ?? throw new InvalidOperationException($"{nameof(CreateNestedHitObject)} returned null for {h.GetType().ReadableName()}.");
@ -302,7 +325,7 @@ namespace osu.Game.Rulesets.Objects.Drawables
private void onDefaultsApplied(HitObject hitObject)
{
Apply(hitObject);
Apply(hitObject, lifetimeEntry);
DefaultsApplied?.Invoke(this);
}
@ -549,15 +572,27 @@ namespace osu.Game.Rulesets.Objects.Drawables
/// </remarks>
protected internal new ScheduledDelegate Schedule(Action action) => base.Schedule(action);
private double? lifetimeStart;
public override double LifetimeStart
{
get => lifetimeStart ?? (HitObject.StartTime - InitialLifetimeOffset);
set
get => base.LifetimeStart;
set => setLifetime(value, LifetimeEnd);
}
public override double LifetimeEnd
{
get => base.LifetimeEnd;
set => setLifetime(LifetimeStart, value);
}
private void setLifetime(double lifetimeStart, double lifetimeEnd)
{
base.LifetimeStart = lifetimeStart;
base.LifetimeEnd = lifetimeEnd;
if (lifetimeEntry != null)
{
lifetimeStart = value;
base.LifetimeStart = value;
lifetimeEntry.LifetimeStart = lifetimeStart;
lifetimeEntry.LifetimeEnd = lifetimeEnd;
}
}