Now, DHO.lifetimeEntry can be non-null even it is not fully applied

This commit is contained in:
ekrctb 2021-04-20 09:17:13 +09:00
parent c1b4aaaa03
commit 1bc63a4c61
2 changed files with 20 additions and 33 deletions

View File

@ -39,12 +39,7 @@ namespace osu.Game.Rulesets.Objects.Drawables
/// <summary> /// <summary>
/// The <see cref="HitObject"/> currently represented by this <see cref="DrawableHitObject"/>. /// The <see cref="HitObject"/> currently represented by this <see cref="DrawableHitObject"/>.
/// </summary> /// </summary>
public HitObject HitObject => lifetimeEntry?.HitObject ?? initialHitObject; public HitObject HitObject => lifetimeEntry?.HitObject;
/// <summary>
/// The <see cref="HitObject"/> given in the constructor that will be applied when loaded.
/// </summary>
private HitObject initialHitObject;
/// <summary> /// <summary>
/// The parenting <see cref="DrawableHitObject"/>, if any. /// The parenting <see cref="DrawableHitObject"/>, if any.
@ -145,9 +140,15 @@ namespace osu.Game.Rulesets.Objects.Drawables
/// </remarks> /// </remarks>
public IBindable<ArmedState> State => state; public IBindable<ArmedState> State => state;
/// <summary>
/// Whether a <see cref="HitObjectLifetimeEntry"/> is currently applied.
/// </summary>
private bool hasEntryApplied;
/// <summary> /// <summary>
/// The <see cref="HitObjectLifetimeEntry"/> controlling the lifetime of the currently-attached <see cref="HitObject"/>. /// The <see cref="HitObjectLifetimeEntry"/> controlling the lifetime of the currently-attached <see cref="HitObject"/>.
/// </summary> /// </summary>
/// <remarks>Even if it is not null, it may not be fully applied until loaded (<see cref="hasEntryApplied"/> is false).</remarks>
[CanBeNull] [CanBeNull]
private HitObjectLifetimeEntry lifetimeEntry; private HitObjectLifetimeEntry lifetimeEntry;
@ -168,7 +169,8 @@ namespace osu.Game.Rulesets.Objects.Drawables
/// </param> /// </param>
protected DrawableHitObject([CanBeNull] HitObject initialHitObject = null) protected DrawableHitObject([CanBeNull] HitObject initialHitObject = null)
{ {
this.initialHitObject = initialHitObject; if (initialHitObject != null)
lifetimeEntry = new UnmanagedHitObjectEntry(initialHitObject);
} }
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
@ -184,11 +186,8 @@ namespace osu.Game.Rulesets.Objects.Drawables
{ {
base.LoadAsyncComplete(); base.LoadAsyncComplete();
if (initialHitObject != null) if (lifetimeEntry != null && !hasEntryApplied)
{ apply(lifetimeEntry);
Apply(initialHitObject, null);
initialHitObject = null;
}
} }
protected override void LoadComplete() protected override void LoadComplete()
@ -210,21 +209,10 @@ namespace osu.Game.Rulesets.Objects.Drawables
if (hitObject == null) if (hitObject == null)
throw new ArgumentNullException($"Cannot apply a null {nameof(HitObject)}."); throw new ArgumentNullException($"Cannot apply a null {nameof(HitObject)}.");
if (lifetimeEntry != null) if (lifetimeEntry != null && lifetimeEntry.HitObject != hitObject)
{ throw new InvalidOperationException($"{nameof(HitObjectLifetimeEntry)} has different {nameof(HitObject)} from the specified one.");
if (lifetimeEntry.HitObject != hitObject)
throw new InvalidOperationException($"{nameof(HitObjectLifetimeEntry)} has different {nameof(HitObject)} from the specified one.");
apply(lifetimeEntry); apply(lifetimeEntry ?? new UnmanagedHitObjectEntry(hitObject));
}
else
{
var unmanagedEntry = new UnmanagedHitObjectEntry(hitObject, this);
apply(unmanagedEntry);
// Set default lifetime for a non-pooled DHO
LifetimeStart = hitObject.StartTime - InitialLifetimeOffset;
}
} }
/// <summary> /// <summary>
@ -294,6 +282,8 @@ namespace osu.Game.Rulesets.Objects.Drawables
else else
updateState(ArmedState.Idle, true); updateState(ArmedState.Idle, true);
} }
hasEntryApplied = true;
} }
/// <summary> /// <summary>
@ -301,7 +291,7 @@ namespace osu.Game.Rulesets.Objects.Drawables
/// </summary> /// </summary>
private void free() private void free()
{ {
if (lifetimeEntry == null) return; if (!hasEntryApplied) return;
StartTimeBindable.UnbindFrom(HitObject.StartTimeBindable); StartTimeBindable.UnbindFrom(HitObject.StartTimeBindable);
if (HitObject is IHasComboInformation combo) if (HitObject is IHasComboInformation combo)
@ -337,6 +327,8 @@ namespace osu.Game.Rulesets.Objects.Drawables
lifetimeEntry = null; lifetimeEntry = null;
clearExistingStateTransforms(); clearExistingStateTransforms();
hasEntryApplied = false;
} }
protected sealed override void FreeAfterUse() protected sealed override void FreeAfterUse()

View File

@ -11,14 +11,9 @@ namespace osu.Game.Rulesets.Objects
/// </summary> /// </summary>
internal class UnmanagedHitObjectEntry : HitObjectLifetimeEntry internal class UnmanagedHitObjectEntry : HitObjectLifetimeEntry
{ {
public readonly DrawableHitObject DrawableHitObject; public UnmanagedHitObjectEntry(HitObject hitObject)
public UnmanagedHitObjectEntry(HitObject hitObject, DrawableHitObject drawableHitObject)
: base(hitObject) : base(hitObject)
{ {
DrawableHitObject = drawableHitObject;
LifetimeStart = DrawableHitObject.LifetimeStart;
LifetimeEnd = DrawableHitObject.LifetimeEnd;
} }
} }
} }