Make DHO application logic clearer with Entry/HitObject separation

This commit is contained in:
ekrctb 2021-04-19 19:56:17 +09:00
parent 0988af5449
commit 5afdc3ff66

View File

@ -204,23 +204,27 @@ namespace osu.Game.Rulesets.Objects.Drawables
/// <param name="lifetimeEntry">The <see cref="HitObjectLifetimeEntry"/> controlling the lifetime of <paramref name="hitObject"/>.</param> /// <param name="lifetimeEntry">The <see cref="HitObjectLifetimeEntry"/> controlling the lifetime of <paramref name="hitObject"/>.</param>
public void Apply([NotNull] HitObject hitObject, [CanBeNull] HitObjectLifetimeEntry lifetimeEntry) public void Apply([NotNull] HitObject hitObject, [CanBeNull] HitObjectLifetimeEntry lifetimeEntry)
{ {
free(); if (hitObject == null)
throw new ArgumentNullException($"Cannot apply a null {nameof(HitObject)}.");
HitObject = hitObject ?? throw new InvalidOperationException($"Cannot apply a null {nameof(HitObject)}.");
this.lifetimeEntry = lifetimeEntry;
if (lifetimeEntry != null) if (lifetimeEntry != null)
{ {
// Transfer lifetime from the entry. applyEntry(lifetimeEntry);
LifetimeStart = lifetimeEntry.LifetimeStart;
LifetimeEnd = lifetimeEntry.LifetimeEnd;
// Copy any existing result from the entry (required for rewind / judgement revert).
Result = lifetimeEntry.Result;
} }
else else
LifetimeStart = HitObject.StartTime - InitialLifetimeOffset; {
applyHitObject(hitObject);
// Set default lifetime for a non-pooled DHO
LifetimeStart = hitObject.StartTime - InitialLifetimeOffset;
}
}
private void applyHitObject([NotNull] HitObject hitObject)
{
freeHitObject();
HitObject = hitObject;
// Ensure this DHO has a result. // Ensure this DHO has a result.
Result ??= CreateResult(HitObject.CreateJudgement()) Result ??= CreateResult(HitObject.CreateJudgement())
@ -281,10 +285,23 @@ namespace osu.Game.Rulesets.Objects.Drawables
hasHitObjectApplied = true; hasHitObjectApplied = true;
} }
private void applyEntry([NotNull] HitObjectLifetimeEntry entry)
{
freeEntry();
setLifetime(entry.LifetimeStart, entry.LifetimeEnd);
lifetimeEntry = entry;
// Copy any existing result from the entry (required for rewind / judgement revert).
Result = entry.Result;
applyHitObject(entry.HitObject);
}
/// <summary> /// <summary>
/// Removes the currently applied <see cref="HitObject"/> /// Removes the currently applied <see cref="HitObject"/>
/// </summary> /// </summary>
private void free() private void freeHitObject()
{ {
if (!hasHitObjectApplied) if (!hasHitObjectApplied)
return; return;
@ -322,13 +339,23 @@ namespace osu.Game.Rulesets.Objects.Drawables
HitObject = null; HitObject = null;
ParentHitObject = null; ParentHitObject = null;
Result = null; Result = null;
lifetimeEntry = null;
clearExistingStateTransforms(); clearExistingStateTransforms();
hasHitObjectApplied = false; hasHitObjectApplied = false;
} }
private void freeEntry()
{
freeHitObject();
if (lifetimeEntry == null) return;
lifetimeEntry = null;
setLifetime(double.MaxValue, double.MaxValue);
}
protected sealed override void FreeAfterUse() protected sealed override void FreeAfterUse()
{ {
base.FreeAfterUse(); base.FreeAfterUse();
@ -337,7 +364,7 @@ namespace osu.Game.Rulesets.Objects.Drawables
if (!IsInPool) if (!IsInPool)
return; return;
free(); freeEntry();
} }
/// <summary> /// <summary>