mirror of
https://github.com/ppy/osu.git
synced 2025-01-26 19:32:55 +08:00
Merge pull request #13517 from ekrctb/initial-entry
Allow setting `Entry` of `PoolableDrawableWithLifetime` (including `DrawableHitObject`)
This commit is contained in:
commit
89c27dcb10
@ -44,11 +44,9 @@ namespace osu.Game.Tests.Gameplay
|
|||||||
{
|
{
|
||||||
TestDrawableHitObject dho = null;
|
TestDrawableHitObject dho = null;
|
||||||
TestLifetimeEntry entry = null;
|
TestLifetimeEntry entry = null;
|
||||||
AddStep("Create DHO", () =>
|
AddStep("Create DHO", () => Child = dho = new TestDrawableHitObject
|
||||||
{
|
{
|
||||||
dho = new TestDrawableHitObject(null);
|
Entry = entry = new TestLifetimeEntry(new HitObject())
|
||||||
dho.Apply(entry = new TestLifetimeEntry(new HitObject()));
|
|
||||||
Child = dho;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
AddStep("KeepAlive = true", () =>
|
AddStep("KeepAlive = true", () =>
|
||||||
@ -81,12 +79,10 @@ namespace osu.Game.Tests.Gameplay
|
|||||||
AddAssert("Lifetime is updated", () => entry.LifetimeStart == -TestLifetimeEntry.INITIAL_LIFETIME_OFFSET);
|
AddAssert("Lifetime is updated", () => entry.LifetimeStart == -TestLifetimeEntry.INITIAL_LIFETIME_OFFSET);
|
||||||
|
|
||||||
TestDrawableHitObject dho = null;
|
TestDrawableHitObject dho = null;
|
||||||
AddStep("Create DHO", () =>
|
AddStep("Create DHO", () => Child = dho = new TestDrawableHitObject
|
||||||
{
|
{
|
||||||
dho = new TestDrawableHitObject(null);
|
Entry = entry,
|
||||||
dho.Apply(entry);
|
SetLifetimeStartOnApply = true
|
||||||
Child = dho;
|
|
||||||
dho.SetLifetimeStartOnApply = true;
|
|
||||||
});
|
});
|
||||||
AddStep("ApplyDefaults", () => entry.HitObject.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty()));
|
AddStep("ApplyDefaults", () => entry.HitObject.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty()));
|
||||||
AddAssert("Lifetime is correct", () => dho.LifetimeStart == TestDrawableHitObject.LIFETIME_ON_APPLY && entry.LifetimeStart == TestDrawableHitObject.LIFETIME_ON_APPLY);
|
AddAssert("Lifetime is correct", () => dho.LifetimeStart == TestDrawableHitObject.LIFETIME_ON_APPLY && entry.LifetimeStart == TestDrawableHitObject.LIFETIME_ON_APPLY);
|
||||||
@ -97,11 +93,9 @@ namespace osu.Game.Tests.Gameplay
|
|||||||
{
|
{
|
||||||
TestDrawableHitObject dho = null;
|
TestDrawableHitObject dho = null;
|
||||||
TestLifetimeEntry entry = null;
|
TestLifetimeEntry entry = null;
|
||||||
AddStep("Create DHO", () =>
|
AddStep("Create DHO", () => Child = dho = new TestDrawableHitObject
|
||||||
{
|
{
|
||||||
dho = new TestDrawableHitObject(null);
|
Entry = entry = new TestLifetimeEntry(new HitObject())
|
||||||
dho.Apply(entry = new TestLifetimeEntry(new HitObject()));
|
|
||||||
Child = dho;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
AddStep("Set entry lifetime", () =>
|
AddStep("Set entry lifetime", () =>
|
||||||
@ -135,7 +129,7 @@ namespace osu.Game.Tests.Gameplay
|
|||||||
|
|
||||||
public bool SetLifetimeStartOnApply;
|
public bool SetLifetimeStartOnApply;
|
||||||
|
|
||||||
public TestDrawableHitObject(HitObject hitObject)
|
public TestDrawableHitObject(HitObject hitObject = null)
|
||||||
: base(hitObject)
|
: base(hitObject)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -156,9 +156,10 @@ namespace osu.Game.Rulesets.Objects.Drawables
|
|||||||
/// If <c>null</c>, a hitobject is expected to be later applied via <see cref="PoolableDrawableWithLifetime{TEntry}.Apply"/> (or automatically via pooling).
|
/// If <c>null</c>, a hitobject is expected to be later applied via <see cref="PoolableDrawableWithLifetime{TEntry}.Apply"/> (or automatically via pooling).
|
||||||
/// </param>
|
/// </param>
|
||||||
protected DrawableHitObject([CanBeNull] HitObject initialHitObject = null)
|
protected DrawableHitObject([CanBeNull] HitObject initialHitObject = null)
|
||||||
: base(initialHitObject != null ? new SyntheticHitObjectEntry(initialHitObject) : null)
|
|
||||||
{
|
{
|
||||||
if (Entry != null)
|
if (initialHitObject == null) return;
|
||||||
|
|
||||||
|
Entry = new SyntheticHitObjectEntry(initialHitObject);
|
||||||
ensureEntryHasResult();
|
ensureEntryHasResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Performance;
|
using osu.Framework.Graphics.Performance;
|
||||||
using osu.Framework.Graphics.Pooling;
|
using osu.Framework.Graphics.Pooling;
|
||||||
|
|
||||||
@ -16,14 +17,32 @@ namespace osu.Game.Rulesets.Objects.Pooling
|
|||||||
/// <typeparam name="TEntry">The <see cref="LifetimeEntry"/> type storing state and controlling this drawable.</typeparam>
|
/// <typeparam name="TEntry">The <see cref="LifetimeEntry"/> type storing state and controlling this drawable.</typeparam>
|
||||||
public abstract class PoolableDrawableWithLifetime<TEntry> : PoolableDrawable where TEntry : LifetimeEntry
|
public abstract class PoolableDrawableWithLifetime<TEntry> : PoolableDrawable where TEntry : LifetimeEntry
|
||||||
{
|
{
|
||||||
|
private TEntry? entry;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The entry holding essential state of this <see cref="PoolableDrawableWithLifetime{TEntry}"/>.
|
/// The entry holding essential state of this <see cref="PoolableDrawableWithLifetime{TEntry}"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public TEntry? Entry { get; private set; }
|
/// <remarks>
|
||||||
|
/// If a non-null value is set before loading is started, the entry is applied when the loading is completed.
|
||||||
|
/// It is not valid to set an entry while this <see cref="PoolableDrawableWithLifetime{TEntry}"/> is loading.
|
||||||
|
/// </remarks>
|
||||||
|
public TEntry? Entry
|
||||||
|
{
|
||||||
|
get => entry;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (LoadState == LoadState.NotLoaded)
|
||||||
|
entry = value;
|
||||||
|
else if (value != null)
|
||||||
|
Apply(value);
|
||||||
|
else if (HasEntryApplied)
|
||||||
|
free();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Whether <see cref="Entry"/> is applied to this <see cref="PoolableDrawableWithLifetime{TEntry}"/>.
|
/// Whether <see cref="Entry"/> is applied to this <see cref="PoolableDrawableWithLifetime{TEntry}"/>.
|
||||||
/// When an initial entry is specified in the constructor, <see cref="Entry"/> is set but not applied until loading is completed.
|
/// When an <see cref="Entry"/> is set during initialization, it is not applied until loading is completed.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected bool HasEntryApplied { get; private set; }
|
protected bool HasEntryApplied { get; private set; }
|
||||||
|
|
||||||
@ -65,9 +84,9 @@ namespace osu.Game.Rulesets.Objects.Pooling
|
|||||||
{
|
{
|
||||||
base.LoadAsyncComplete();
|
base.LoadAsyncComplete();
|
||||||
|
|
||||||
// Apply the initial entry given in the constructor.
|
// Apply the initial entry.
|
||||||
if (Entry != null && !HasEntryApplied)
|
if (Entry != null && !HasEntryApplied)
|
||||||
Apply(Entry);
|
apply(Entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -76,16 +95,10 @@ namespace osu.Game.Rulesets.Objects.Pooling
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public void Apply(TEntry entry)
|
public void Apply(TEntry entry)
|
||||||
{
|
{
|
||||||
if (HasEntryApplied)
|
if (LoadState == LoadState.Loading)
|
||||||
free();
|
throw new InvalidOperationException($"Cannot apply a new {nameof(TEntry)} while currently loading.");
|
||||||
|
|
||||||
Entry = entry;
|
apply(entry);
|
||||||
entry.LifetimeChanged += setLifetimeFromEntry;
|
|
||||||
setLifetimeFromEntry(entry);
|
|
||||||
|
|
||||||
OnApply(entry);
|
|
||||||
|
|
||||||
HasEntryApplied = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected sealed override void FreeAfterUse()
|
protected sealed override void FreeAfterUse()
|
||||||
@ -111,6 +124,20 @@ namespace osu.Game.Rulesets.Objects.Pooling
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void apply(TEntry entry)
|
||||||
|
{
|
||||||
|
if (HasEntryApplied)
|
||||||
|
free();
|
||||||
|
|
||||||
|
this.entry = entry;
|
||||||
|
entry.LifetimeChanged += setLifetimeFromEntry;
|
||||||
|
setLifetimeFromEntry(entry);
|
||||||
|
|
||||||
|
OnApply(entry);
|
||||||
|
|
||||||
|
HasEntryApplied = true;
|
||||||
|
}
|
||||||
|
|
||||||
private void free()
|
private void free()
|
||||||
{
|
{
|
||||||
Debug.Assert(Entry != null && HasEntryApplied);
|
Debug.Assert(Entry != null && HasEntryApplied);
|
||||||
@ -118,7 +145,7 @@ namespace osu.Game.Rulesets.Objects.Pooling
|
|||||||
OnFree(Entry);
|
OnFree(Entry);
|
||||||
|
|
||||||
Entry.LifetimeChanged -= setLifetimeFromEntry;
|
Entry.LifetimeChanged -= setLifetimeFromEntry;
|
||||||
Entry = null;
|
entry = null;
|
||||||
base.LifetimeStart = double.MinValue;
|
base.LifetimeStart = double.MinValue;
|
||||||
base.LifetimeEnd = double.MaxValue;
|
base.LifetimeEnd = double.MaxValue;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user