mirror of
https://github.com/osukey/osukey.git
synced 2025-08-07 00:23:59 +09:00
Merge branch 'master' into osu-hitobject-pooling
This commit is contained in:
@ -10,7 +10,7 @@ namespace osu.Game.Tests.Visual.Editing
|
|||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class TestSceneTimelineBlueprintContainer : TimelineTestScene
|
public class TestSceneTimelineBlueprintContainer : TimelineTestScene
|
||||||
{
|
{
|
||||||
public override Drawable CreateTestComponent() => new TimelineBlueprintContainer(null);
|
public override Drawable CreateTestComponent() => new TimelineBlueprintContainer(Composer);
|
||||||
|
|
||||||
protected override void LoadComplete()
|
protected override void LoadComplete()
|
||||||
{
|
{
|
||||||
|
@ -21,21 +21,25 @@ namespace osu.Game.Tests.Visual.Editing
|
|||||||
{
|
{
|
||||||
protected TimelineArea TimelineArea { get; private set; }
|
protected TimelineArea TimelineArea { get; private set; }
|
||||||
|
|
||||||
|
protected HitObjectComposer Composer { get; private set; }
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(AudioManager audio)
|
private void load(AudioManager audio)
|
||||||
{
|
{
|
||||||
Beatmap.Value = new WaveformTestBeatmap(audio);
|
Beatmap.Value = new WaveformTestBeatmap(audio);
|
||||||
|
|
||||||
var playable = Beatmap.Value.GetPlayableBeatmap(Beatmap.Value.BeatmapInfo.Ruleset);
|
var playable = Beatmap.Value.GetPlayableBeatmap(Beatmap.Value.BeatmapInfo.Ruleset);
|
||||||
|
|
||||||
var editorBeatmap = new EditorBeatmap(playable);
|
var editorBeatmap = new EditorBeatmap(playable);
|
||||||
|
|
||||||
Dependencies.Cache(editorBeatmap);
|
Dependencies.Cache(editorBeatmap);
|
||||||
Dependencies.CacheAs<IBeatSnapProvider>(editorBeatmap);
|
Dependencies.CacheAs<IBeatSnapProvider>(editorBeatmap);
|
||||||
|
|
||||||
|
Composer = playable.BeatmapInfo.Ruleset.CreateInstance().CreateHitObjectComposer().With(d => d.Alpha = 0);
|
||||||
|
|
||||||
AddRange(new Drawable[]
|
AddRange(new Drawable[]
|
||||||
{
|
{
|
||||||
editorBeatmap,
|
editorBeatmap,
|
||||||
|
Composer,
|
||||||
new FillFlowContainer
|
new FillFlowContainer
|
||||||
{
|
{
|
||||||
AutoSizeAxes = Axes.Both,
|
AutoSizeAxes = Axes.Both,
|
||||||
|
@ -8,10 +8,9 @@ using osu.Framework.Audio;
|
|||||||
using osu.Framework.Audio.Track;
|
using osu.Framework.Audio.Track;
|
||||||
using osu.Framework.Graphics.Textures;
|
using osu.Framework.Graphics.Textures;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Beatmaps.Formats;
|
|
||||||
using osu.Game.IO;
|
|
||||||
using osu.Game.IO.Archives;
|
using osu.Game.IO.Archives;
|
||||||
using osu.Game.Rulesets.Catch;
|
using osu.Game.Rulesets;
|
||||||
|
using osu.Game.Rulesets.Osu;
|
||||||
using osu.Game.Tests.Beatmaps;
|
using osu.Game.Tests.Beatmaps;
|
||||||
using osu.Game.Tests.Resources;
|
using osu.Game.Tests.Resources;
|
||||||
|
|
||||||
@ -25,8 +24,8 @@ namespace osu.Game.Tests
|
|||||||
private readonly Beatmap beatmap;
|
private readonly Beatmap beatmap;
|
||||||
private readonly ITrackStore trackStore;
|
private readonly ITrackStore trackStore;
|
||||||
|
|
||||||
public WaveformTestBeatmap(AudioManager audioManager)
|
public WaveformTestBeatmap(AudioManager audioManager, RulesetInfo rulesetInfo = null)
|
||||||
: this(audioManager, new WaveformBeatmap())
|
: this(audioManager, new TestBeatmap(rulesetInfo ?? new OsuRuleset().RulesetInfo))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,21 +62,5 @@ namespace osu.Game.Tests
|
|||||||
return reader.Filenames.First(f => f.EndsWith(".mp3", StringComparison.Ordinal));
|
return reader.Filenames.First(f => f.EndsWith(".mp3", StringComparison.Ordinal));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class WaveformBeatmap : TestBeatmap
|
|
||||||
{
|
|
||||||
public WaveformBeatmap()
|
|
||||||
: base(new CatchRuleset().RulesetInfo)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override Beatmap CreateBeatmap()
|
|
||||||
{
|
|
||||||
using (var reader = getZipReader())
|
|
||||||
using (var beatmapStream = reader.GetStream(reader.Filenames.First(f => f.EndsWith(".osu", StringComparison.Ordinal))))
|
|
||||||
using (var beatmapReader = new LineBufferedReader(beatmapStream))
|
|
||||||
return Decoder.GetDecoder<Beatmap>(beatmapReader).Decode(beatmapReader);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,7 @@ namespace osu.Game.Rulesets.UI
|
|||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// If this <see cref="HitObjectContainer"/> uses pooled objects, this represents the time when the <see cref="HitObject"/>s become alive.
|
/// If this <see cref="HitObjectContainer"/> uses pooled objects, this represents the time when the <see cref="HitObject"/>s become alive.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
public event Action<HitObject> HitObjectUsageBegan;
|
internal event Action<HitObject> HitObjectUsageBegan;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Invoked when a <see cref="HitObject"/> becomes unused by a <see cref="DrawableHitObject"/>.
|
/// Invoked when a <see cref="HitObject"/> becomes unused by a <see cref="DrawableHitObject"/>.
|
||||||
@ -56,17 +56,17 @@ namespace osu.Game.Rulesets.UI
|
|||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// If this <see cref="HitObjectContainer"/> uses pooled objects, this represents the time when the <see cref="HitObject"/>s become dead.
|
/// If this <see cref="HitObjectContainer"/> uses pooled objects, this represents the time when the <see cref="HitObject"/>s become dead.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
public event Action<HitObject> HitObjectUsageFinished;
|
internal event Action<HitObject> HitObjectUsageFinished;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The amount of time prior to the current time within which <see cref="HitObject"/>s should be considered alive.
|
/// The amount of time prior to the current time within which <see cref="HitObject"/>s should be considered alive.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public double PastLifetimeExtension { get; set; }
|
internal double PastLifetimeExtension { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The amount of time after the current time within which <see cref="HitObject"/>s should be considered alive.
|
/// The amount of time after the current time within which <see cref="HitObject"/>s should be considered alive.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public double FutureLifetimeExtension { get; set; }
|
internal double FutureLifetimeExtension { get; set; }
|
||||||
|
|
||||||
private readonly Dictionary<DrawableHitObject, IBindable> startTimeMap = new Dictionary<DrawableHitObject, IBindable>();
|
private readonly Dictionary<DrawableHitObject, IBindable> startTimeMap = new Dictionary<DrawableHitObject, IBindable>();
|
||||||
private readonly Dictionary<HitObjectLifetimeEntry, DrawableHitObject> drawableMap = new Dictionary<HitObjectLifetimeEntry, DrawableHitObject>();
|
private readonly Dictionary<HitObjectLifetimeEntry, DrawableHitObject> drawableMap = new Dictionary<HitObjectLifetimeEntry, DrawableHitObject>();
|
||||||
|
@ -29,22 +29,6 @@ namespace osu.Game.Rulesets.UI
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public event Action<DrawableHitObject, JudgementResult> RevertResult;
|
public event Action<DrawableHitObject, JudgementResult> RevertResult;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Invoked when a <see cref="HitObject"/> becomes used by a <see cref="DrawableHitObject"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>
|
|
||||||
/// If this <see cref="HitObjectContainer"/> uses pooled objects, this represents the time when the <see cref="HitObject"/>s become alive.
|
|
||||||
/// </remarks>
|
|
||||||
public event Action<HitObject> HitObjectUsageBegan;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Invoked when a <see cref="HitObject"/> becomes unused by a <see cref="DrawableHitObject"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>
|
|
||||||
/// If this <see cref="HitObjectContainer"/> uses pooled objects, this represents the time when the <see cref="HitObject"/>s become dead.
|
|
||||||
/// </remarks>
|
|
||||||
public event Action<HitObject> HitObjectUsageFinished;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The <see cref="DrawableHitObject"/> contained in this Playfield.
|
/// The <see cref="DrawableHitObject"/> contained in this Playfield.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -154,8 +138,6 @@ namespace osu.Game.Rulesets.UI
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly Dictionary<HitObject, HitObjectLifetimeEntry> lifetimeEntryMap = new Dictionary<HitObject, HitObjectLifetimeEntry>();
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Adds a <see cref="HitObjectLifetimeEntry"/> for a pooled <see cref="HitObject"/> to this <see cref="Playfield"/>.
|
/// Adds a <see cref="HitObjectLifetimeEntry"/> for a pooled <see cref="HitObject"/> to this <see cref="Playfield"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -205,77 +187,6 @@ namespace osu.Game.Rulesets.UI
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Sets whether to keep a given <see cref="HitObject"/> always alive within this or any nested <see cref="Playfield"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="hitObject">The <see cref="HitObject"/> to set.</param>
|
|
||||||
/// <param name="keepAlive">Whether to keep <paramref name="hitObject"/> always alive.</param>
|
|
||||||
public void SetKeepAlive(HitObject hitObject, bool keepAlive)
|
|
||||||
{
|
|
||||||
if (lifetimeEntryMap.TryGetValue(hitObject, out var entry))
|
|
||||||
{
|
|
||||||
entry.KeepAlive = keepAlive;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!nestedPlayfields.IsValueCreated)
|
|
||||||
return;
|
|
||||||
|
|
||||||
foreach (var p in nestedPlayfields.Value)
|
|
||||||
p.SetKeepAlive(hitObject, keepAlive);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Keeps all <see cref="HitObject"/>s alive within this and all nested <see cref="Playfield"/>s.
|
|
||||||
/// </summary>
|
|
||||||
public void KeepAllAlive()
|
|
||||||
{
|
|
||||||
foreach (var (_, entry) in lifetimeEntryMap)
|
|
||||||
entry.KeepAlive = true;
|
|
||||||
|
|
||||||
if (!nestedPlayfields.IsValueCreated)
|
|
||||||
return;
|
|
||||||
|
|
||||||
foreach (var p in nestedPlayfields.Value)
|
|
||||||
p.KeepAllAlive();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The amount of time prior to the current time within which <see cref="HitObject"/>s should be considered alive.
|
|
||||||
/// </summary>
|
|
||||||
public double PastLifetimeExtension
|
|
||||||
{
|
|
||||||
get => HitObjectContainer.PastLifetimeExtension;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
HitObjectContainer.PastLifetimeExtension = value;
|
|
||||||
|
|
||||||
if (!nestedPlayfields.IsValueCreated)
|
|
||||||
return;
|
|
||||||
|
|
||||||
foreach (var nested in nestedPlayfields.Value)
|
|
||||||
nested.PastLifetimeExtension = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The amount of time after the current time within which <see cref="HitObject"/>s should be considered alive.
|
|
||||||
/// </summary>
|
|
||||||
public double FutureLifetimeExtension
|
|
||||||
{
|
|
||||||
get => HitObjectContainer.FutureLifetimeExtension;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
HitObjectContainer.FutureLifetimeExtension = value;
|
|
||||||
|
|
||||||
if (!nestedPlayfields.IsValueCreated)
|
|
||||||
return;
|
|
||||||
|
|
||||||
foreach (var nested in nestedPlayfields.Value)
|
|
||||||
nested.FutureLifetimeExtension = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The cursor currently being used by this <see cref="Playfield"/>. May be null if no cursor is provided.
|
/// The cursor currently being used by this <see cref="Playfield"/>. May be null if no cursor is provided.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -335,6 +246,99 @@ namespace osu.Game.Rulesets.UI
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
protected virtual HitObjectContainer CreateHitObjectContainer() => new HitObjectContainer();
|
protected virtual HitObjectContainer CreateHitObjectContainer() => new HitObjectContainer();
|
||||||
|
|
||||||
|
#region Editor logic
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Invoked when a <see cref="HitObject"/> becomes used by a <see cref="DrawableHitObject"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// If this <see cref="HitObjectContainer"/> uses pooled objects, this represents the time when the <see cref="HitObject"/>s become alive.
|
||||||
|
/// </remarks>
|
||||||
|
internal event Action<HitObject> HitObjectUsageBegan;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Invoked when a <see cref="HitObject"/> becomes unused by a <see cref="DrawableHitObject"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// If this <see cref="HitObjectContainer"/> uses pooled objects, this represents the time when the <see cref="HitObject"/>s become dead.
|
||||||
|
/// </remarks>
|
||||||
|
internal event Action<HitObject> HitObjectUsageFinished;
|
||||||
|
|
||||||
|
private readonly Dictionary<HitObject, HitObjectLifetimeEntry> lifetimeEntryMap = new Dictionary<HitObject, HitObjectLifetimeEntry>();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets whether to keep a given <see cref="HitObject"/> always alive within this or any nested <see cref="Playfield"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="hitObject">The <see cref="HitObject"/> to set.</param>
|
||||||
|
/// <param name="keepAlive">Whether to keep <paramref name="hitObject"/> always alive.</param>
|
||||||
|
internal void SetKeepAlive(HitObject hitObject, bool keepAlive)
|
||||||
|
{
|
||||||
|
if (lifetimeEntryMap.TryGetValue(hitObject, out var entry))
|
||||||
|
{
|
||||||
|
entry.KeepAlive = keepAlive;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!nestedPlayfields.IsValueCreated)
|
||||||
|
return;
|
||||||
|
|
||||||
|
foreach (var p in nestedPlayfields.Value)
|
||||||
|
p.SetKeepAlive(hitObject, keepAlive);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Keeps all <see cref="HitObject"/>s alive within this and all nested <see cref="Playfield"/>s.
|
||||||
|
/// </summary>
|
||||||
|
internal void KeepAllAlive()
|
||||||
|
{
|
||||||
|
foreach (var (_, entry) in lifetimeEntryMap)
|
||||||
|
entry.KeepAlive = true;
|
||||||
|
|
||||||
|
if (!nestedPlayfields.IsValueCreated)
|
||||||
|
return;
|
||||||
|
|
||||||
|
foreach (var p in nestedPlayfields.Value)
|
||||||
|
p.KeepAllAlive();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The amount of time prior to the current time within which <see cref="HitObject"/>s should be considered alive.
|
||||||
|
/// </summary>
|
||||||
|
internal double PastLifetimeExtension
|
||||||
|
{
|
||||||
|
get => HitObjectContainer.PastLifetimeExtension;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
HitObjectContainer.PastLifetimeExtension = value;
|
||||||
|
|
||||||
|
if (!nestedPlayfields.IsValueCreated)
|
||||||
|
return;
|
||||||
|
|
||||||
|
foreach (var nested in nestedPlayfields.Value)
|
||||||
|
nested.PastLifetimeExtension = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The amount of time after the current time within which <see cref="HitObject"/>s should be considered alive.
|
||||||
|
/// </summary>
|
||||||
|
internal double FutureLifetimeExtension
|
||||||
|
{
|
||||||
|
get => HitObjectContainer.FutureLifetimeExtension;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
HitObjectContainer.FutureLifetimeExtension = value;
|
||||||
|
|
||||||
|
if (!nestedPlayfields.IsValueCreated)
|
||||||
|
return;
|
||||||
|
|
||||||
|
foreach (var nested in nestedPlayfields.Value)
|
||||||
|
nested.FutureLifetimeExtension = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
public class InvisibleCursorContainer : GameplayCursorContainer
|
public class InvisibleCursorContainer : GameplayCursorContainer
|
||||||
{
|
{
|
||||||
protected override Drawable CreateCursor() => new InvisibleCursor();
|
protected override Drawable CreateCursor() => new InvisibleCursor();
|
||||||
|
Reference in New Issue
Block a user