1
0
mirror of https://github.com/ppy/osu.git synced 2024-12-15 03:22:55 +08:00

Merge pull request #28801 from bdach/break-generation-caching

Improve performance of automatic break regeneration
This commit is contained in:
Dean Herbert 2024-07-10 19:21:16 +09:00 committed by GitHub
commit 1381b3c0c5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 46 additions and 10 deletions

View File

@ -4,6 +4,7 @@
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Pooling;
using osu.Framework.Graphics.Shapes;
using osu.Game.Beatmaps.Timing;
using osu.Game.Graphics;
@ -17,32 +18,54 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts
{
private readonly BindableList<BreakPeriod> breaks = new BindableList<BreakPeriod>();
private DrawablePool<BreakVisualisation> pool = null!;
[BackgroundDependencyLoader]
private void load()
{
AddInternal(pool = new DrawablePool<BreakVisualisation>(10));
}
protected override void LoadBeatmap(EditorBeatmap beatmap)
{
base.LoadBeatmap(beatmap);
breaks.UnbindAll();
breaks.BindTo(beatmap.Breaks);
}
protected override void LoadComplete()
{
base.LoadComplete();
breaks.BindCollectionChanged((_, _) =>
{
Clear();
foreach (var breakPeriod in beatmap.Breaks)
Add(new BreakVisualisation(breakPeriod));
Clear(disposeChildren: false);
foreach (var breakPeriod in breaks)
Add(pool.Get(v => v.BreakPeriod = breakPeriod));
}, true);
}
private partial class BreakVisualisation : Circle
private partial class BreakVisualisation : PoolableDrawable
{
public BreakVisualisation(BreakPeriod breakPeriod)
public BreakPeriod BreakPeriod
{
RelativePositionAxes = Axes.X;
RelativeSizeAxes = Axes.Both;
X = (float)breakPeriod.StartTime;
Width = (float)breakPeriod.Duration;
set
{
X = (float)value.StartTime;
Width = (float)value.Duration;
}
}
[BackgroundDependencyLoader]
private void load(OsuColour colours) => Colour = colours.Gray7;
private void load(OsuColour colours)
{
RelativePositionAxes = Axes.X;
RelativeSizeAxes = Axes.Both;
InternalChild = new Circle { RelativeSizeAxes = Axes.Both };
Colour = colours.Gray7;
}
}
}
}

View File

@ -2,6 +2,7 @@
// See the LICENCE file in the repository root for full licence text.
using System;
using System.Collections.Generic;
using System.Linq;
using osu.Game.Beatmaps;
using osu.Game.Beatmaps.Timing;
@ -18,6 +19,11 @@ namespace osu.Game.Screens.Edit
private readonly IBeatmapProcessor? rulesetBeatmapProcessor;
/// <summary>
/// Kept for the purposes of reducing redundant regeneration of automatic breaks.
/// </summary>
private HashSet<(double, double)> objectDurationCache = new HashSet<(double, double)>();
public EditorBeatmapProcessor(EditorBeatmap beatmap, Ruleset ruleset)
{
Beatmap = beatmap;
@ -38,6 +44,13 @@ namespace osu.Game.Screens.Edit
private void autoGenerateBreaks()
{
var objectDuration = Beatmap.HitObjects.Select(ho => (ho.StartTime, ho.GetEndTime())).ToHashSet();
if (objectDuration.SetEquals(objectDurationCache))
return;
objectDurationCache = objectDuration;
Beatmap.Breaks.RemoveAll(b => b is not ManualBreakPeriod);
foreach (var manualBreak in Beatmap.Breaks.ToList())