From 00b3d97f69abaaed8a29cca1770aca91966e6fc6 Mon Sep 17 00:00:00 2001 From: ekrctb Date: Wed, 5 Oct 2022 21:26:00 +0900 Subject: [PATCH] Improve timeline selection performance But selecting a large number of hit objects is still very slow because all DHOs must be added and also `AddBlueprintFor` has quadratic behaviors --- .../Compose/Components/BlueprintContainer.cs | 10 ++++++++-- .../Timeline/TimelineBlueprintContainer.cs | 18 ++++-------------- 2 files changed, 12 insertions(+), 16 deletions(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs index 787959d214..da7a8e662b 100644 --- a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs @@ -58,13 +58,19 @@ namespace osu.Game.Screens.Edit.Compose.Components { case NotifyCollectionChangedAction.Add: foreach (object o in args.NewItems) - SelectionBlueprints.FirstOrDefault(b => b.Item == o)?.Select(); + { + if (blueprintMap.TryGetValue((T)o, out var blueprint)) + blueprint.Select(); + } break; case NotifyCollectionChangedAction.Remove: foreach (object o in args.OldItems) - SelectionBlueprints.FirstOrDefault(b => b.Item == o)?.Deselect(); + { + if (blueprintMap.TryGetValue((T)o, out var blueprint)) + blueprint.Deselect(); + } break; } diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineBlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineBlueprintContainer.cs index 05897e6d97..2d6dc797ca 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineBlueprintContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineBlueprintContainer.cs @@ -182,21 +182,11 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline var dragBox = (TimelineDragBox)DragBox; double minTime = dragBox.MinTime; double maxTime = dragBox.MaxTime; - Console.WriteLine($"{minTime}, {maxTime}"); - // TODO: performance - foreach (var hitObject in Beatmap.HitObjects) - { - bool shouldBeSelected = minTime <= hitObject.StartTime && hitObject.StartTime <= maxTime; - bool isSelected = SelectedItems.Contains(hitObject); - if (isSelected != shouldBeSelected) - { - if (!isSelected) - SelectedItems.Add(hitObject); - else - SelectedItems.Remove(hitObject); - } - } + SelectedItems.RemoveAll(hitObject => !shouldBeSelected(hitObject)); + SelectedItems.AddRange(Beatmap.HitObjects.Except(SelectedItems).Where(hitObject => shouldBeSelected(hitObject))); + + bool shouldBeSelected(HitObject hitObject) => minTime <= hitObject.StartTime && hitObject.StartTime <= maxTime; } private void handleScrollViaDrag(DragEvent e)