1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-13 17:13:06 +08:00

Merge pull request #9664 from smoogipoo/fix-catch-banana-performance

Load nested hitobjects during map load
This commit is contained in:
Dean Herbert 2020-07-24 22:11:08 +09:00 committed by GitHub
commit 15df0dc870
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 37 additions and 15 deletions

View File

@ -129,9 +129,9 @@ namespace osu.Game.Rulesets.Objects.Drawables
LoadSamples(); LoadSamples();
} }
protected override void LoadComplete() protected override void LoadAsyncComplete()
{ {
base.LoadComplete(); base.LoadAsyncComplete();
HitObject.DefaultsApplied += onDefaultsApplied; HitObject.DefaultsApplied += onDefaultsApplied;
@ -148,6 +148,11 @@ namespace osu.Game.Rulesets.Objects.Drawables
samplesBindable.CollectionChanged += (_, __) => LoadSamples(); samplesBindable.CollectionChanged += (_, __) => LoadSamples();
apply(HitObject); apply(HitObject);
}
protected override void LoadComplete()
{
base.LoadComplete();
updateState(ArmedState.Idle, true); updateState(ArmedState.Idle, true);
} }

View File

@ -2,11 +2,13 @@
// See the LICENCE file in the repository root for full licence text. // See the LICENCE file in the repository root for full licence text.
using System.Collections.Generic; using System.Collections.Generic;
using JetBrains.Annotations;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Bindables; using osu.Framework.Bindables;
using osu.Framework.Caching; using osu.Framework.Caching;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Layout; using osu.Framework.Layout;
using osu.Framework.Threading;
using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Objects.Types;
using osuTK; using osuTK;
@ -17,7 +19,7 @@ namespace osu.Game.Rulesets.UI.Scrolling
{ {
private readonly IBindable<double> timeRange = new BindableDouble(); private readonly IBindable<double> timeRange = new BindableDouble();
private readonly IBindable<ScrollingDirection> direction = new Bindable<ScrollingDirection>(); private readonly IBindable<ScrollingDirection> direction = new Bindable<ScrollingDirection>();
private readonly Dictionary<DrawableHitObject, Cached> hitObjectInitialStateCache = new Dictionary<DrawableHitObject, Cached>(); private readonly Dictionary<DrawableHitObject, InitialState> hitObjectInitialStateCache = new Dictionary<DrawableHitObject, InitialState>();
[Resolved] [Resolved]
private IScrollingInfo scrollingInfo { get; set; } private IScrollingInfo scrollingInfo { get; set; }
@ -175,10 +177,10 @@ namespace osu.Game.Rulesets.UI.Scrolling
{ {
// The cache may not exist if the hitobject state hasn't been computed yet (e.g. if the hitobject was added + defaults applied in the same frame). // The cache may not exist if the hitobject state hasn't been computed yet (e.g. if the hitobject was added + defaults applied in the same frame).
// In such a case, combinedObjCache will take care of updating the hitobject. // In such a case, combinedObjCache will take care of updating the hitobject.
if (hitObjectInitialStateCache.TryGetValue(drawableObject, out var objCache)) if (hitObjectInitialStateCache.TryGetValue(drawableObject, out var state))
{ {
combinedObjCache.Invalidate(); combinedObjCache.Invalidate();
objCache.Invalidate(); state.Cache.Invalidate();
} }
} }
@ -190,8 +192,8 @@ namespace osu.Game.Rulesets.UI.Scrolling
if (!layoutCache.IsValid) if (!layoutCache.IsValid)
{ {
foreach (var cached in hitObjectInitialStateCache.Values) foreach (var state in hitObjectInitialStateCache.Values)
cached.Invalidate(); state.Cache.Invalidate();
combinedObjCache.Invalidate(); combinedObjCache.Invalidate();
scrollingInfo.Algorithm.Reset(); scrollingInfo.Algorithm.Reset();
@ -215,16 +217,18 @@ namespace osu.Game.Rulesets.UI.Scrolling
foreach (var obj in Objects) foreach (var obj in Objects)
{ {
if (!hitObjectInitialStateCache.TryGetValue(obj, out var objCache)) if (!hitObjectInitialStateCache.TryGetValue(obj, out var state))
objCache = hitObjectInitialStateCache[obj] = new Cached(); state = hitObjectInitialStateCache[obj] = new InitialState(new Cached());
if (objCache.IsValid) if (state.Cache.IsValid)
continue; continue;
computeLifetimeStartRecursive(obj); state.ScheduledComputation?.Cancel();
computeInitialStateRecursive(obj); state.ScheduledComputation = computeInitialStateRecursive(obj);
objCache.Validate(); computeLifetimeStartRecursive(obj);
state.Cache.Validate();
} }
combinedObjCache.Validate(); combinedObjCache.Validate();
@ -267,8 +271,7 @@ namespace osu.Game.Rulesets.UI.Scrolling
return scrollingInfo.Algorithm.GetDisplayStartTime(hitObject.HitObject.StartTime, originAdjustment, timeRange.Value, scrollLength); return scrollingInfo.Algorithm.GetDisplayStartTime(hitObject.HitObject.StartTime, originAdjustment, timeRange.Value, scrollLength);
} }
// Cant use AddOnce() since the delegate is re-constructed every invocation private ScheduledDelegate computeInitialStateRecursive(DrawableHitObject hitObject) => hitObject.Schedule(() =>
private void computeInitialStateRecursive(DrawableHitObject hitObject) => hitObject.Schedule(() =>
{ {
if (hitObject.HitObject is IHasDuration e) if (hitObject.HitObject is IHasDuration e)
{ {
@ -325,5 +328,19 @@ namespace osu.Game.Rulesets.UI.Scrolling
break; break;
} }
} }
private class InitialState
{
[NotNull]
public readonly Cached Cache;
[CanBeNull]
public ScheduledDelegate ScheduledComputation;
public InitialState(Cached cache)
{
Cache = cache;
}
}
} }
} }