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

Merge pull request #16446 from peppy/summary-timeline-control-point-optimisation

Reduce number of redundant control points displayed on summary timeline
This commit is contained in:
Dan Balasescu 2022-01-19 15:51:20 +09:00 committed by GitHub
commit 9920ff51a6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 54 additions and 8 deletions

View File

@ -1,6 +1,7 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System;
using System.Collections.Specialized;
using System.Linq;
using osu.Framework.Bindables;
@ -31,7 +32,16 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts
case NotifyCollectionChangedAction.Add:
foreach (var group in args.NewItems.OfType<ControlPointGroup>())
{
// as an optimisation, don't add a visualisation if there are already groups with the same types in close proximity.
// for newly added control points (ie. lazer editor first where group is added empty) we always skip for simplicity.
// that is fine, because cases where this is causing a performance issue are mostly where external tools were used to create an insane number of points.
if (Children.Any(g => Math.Abs(g.Group.Time - group.Time) < 500 && g.IsVisuallyRedundant(group)))
continue;
Add(new GroupVisualisation(group));
}
break;
case NotifyCollectionChangedAction.Remove:
@ -39,7 +49,20 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts
{
var matching = Children.SingleOrDefault(gv => gv.Group == group);
matching?.Expire();
if (matching != null)
matching.Expire();
else
{
// due to the add optimisation above, if a point is deleted which wasn't being displayed we need to recreate all points
// to guarantee an accurate representation.
//
// note that the case where control point (type) is added or removed from a non-displayed group is not handled correctly.
// this is an edge case which shouldn't affect the user too badly. we may flatten control point groups in the future
// which would allow this to be handled better.
Clear();
foreach (var g in controlPointGroups)
Add(new GroupVisualisation(g));
}
}
break;

View File

@ -9,7 +9,7 @@ using osu.Game.Screens.Edit.Components.Timelines.Summary.Visualisations;
namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts
{
public class ControlPointVisualisation : PointVisualisation
public class ControlPointVisualisation : PointVisualisation, IControlPointVisualisation
{
protected readonly ControlPoint Point;
@ -26,5 +26,7 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts
{
Colour = Point.GetRepresentingColour(colours);
}
public bool IsVisuallyRedundant(ControlPoint other) => other.GetType() == Point.GetType();
}
}

View File

@ -13,7 +13,7 @@ using osu.Game.Screens.Edit.Components.Timelines.Summary.Visualisations;
namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts
{
public class EffectPointVisualisation : CompositeDrawable
public class EffectPointVisualisation : CompositeDrawable, IControlPointVisualisation
{
private readonly EffectControlPoint effect;
private Bindable<bool> kiai;
@ -68,5 +68,8 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts
}
}, true);
}
// kiai sections display duration, so are required to be visualised.
public bool IsVisuallyRedundant(ControlPoint other) => other is EffectControlPoint otherEffect && effect.KiaiMode == otherEffect.KiaiMode;
}
}

View File

@ -1,6 +1,7 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System.Linq;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
@ -23,12 +24,8 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts
Group = group;
X = (float)group.Time;
}
protected override void LoadComplete()
{
base.LoadComplete();
// Run in constructor so IsRedundant calls can work correctly.
controlPoints.BindTo(Group.ControlPoints);
controlPoints.BindCollectionChanged((_, __) =>
{
@ -60,5 +57,11 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts
}
}, true);
}
/// <summary>
/// For display purposes, check whether the proposed group is made redundant by this visualisation group.
/// </summary>
public bool IsVisuallyRedundant(ControlPointGroup other) =>
other.ControlPoints.All(c => InternalChildren.OfType<IControlPointVisualisation>().Any(c2 => c2.IsVisuallyRedundant(c)));
}
}

View File

@ -0,0 +1,15 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using osu.Game.Beatmaps.ControlPoints;
namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts
{
public interface IControlPointVisualisation
{
/// <summary>
/// For display purposes, check whether the proposed point is made redundant by this visualisation.
/// </summary>
bool IsVisuallyRedundant(ControlPoint other);
}
}