Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix slow performance of polygon generation tool #30214

Merged
merged 13 commits into from
Nov 14, 2024

Conversation

minetoblend
Copy link
Contributor

@minetoblend minetoblend commented Oct 11, 2024

Reusing the hitobjects now instead of removing them and regenerating everything from scratch each time.
Also fixes the flashing whenever the polygon updates.

I put tryCreatePolygon() behind Scheduler.AddOnce for good measure, not sure if this is actually required as it's plenty fast either way now.

Before:

2024-10-11.11-29-04.mp4

After:

2024-10-11.11-44-56.mp4

@bdach
Copy link
Collaborator

bdach commented Oct 11, 2024

How much of the "performance gain" here is the "reuse of objects"? I'd wager the .AddOnce() is doing the heavy lifting here if anything.

@minetoblend
Copy link
Contributor Author

minetoblend commented Oct 11, 2024

The majority of it comes from reusing the objects.

For comparison: (All the videos are recorded on release builds btw)

Index: osu.Game.Rulesets.Osu/Edit/PolygonGenerationPopover.cs
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/osu.Game.Rulesets.Osu/Edit/PolygonGenerationPopover.cs b/osu.Game.Rulesets.Osu/Edit/PolygonGenerationPopover.cs
--- a/osu.Game.Rulesets.Osu/Edit/PolygonGenerationPopover.cs	(revision 7e439be9eca9e626a080defc0cd24da933072710)
+++ b/osu.Game.Rulesets.Osu/Edit/PolygonGenerationPopover.cs	(date 1728640773096)
@@ -125,7 +125,7 @@
             tryCreatePolygon();
         }
 
-        private void scheduleRefresh() => Scheduler.AddOnce(tryCreatePolygon);
+        private void scheduleRefresh() => tryCreatePolygon();
 
         private void tryCreatePolygon()
         {
2024-10-11.12-00-23.mp4

@minetoblend
Copy link
Contributor Author

minetoblend commented Oct 11, 2024

Ran it one more time with just Scheduler.AddOnce to double check, and it looks like it actually does have a noticeable effect, albeit much less than with just reusing the objects.

2024-10-11.12-07-36.mp4

osu.Game.Rulesets.Osu/Edit/PolygonGenerationPopover.cs Outdated Show resolved Hide resolved
osu.Game.Rulesets.Osu/Edit/PolygonGenerationPopover.cs Outdated Show resolved Hide resolved
Comment on lines 165 to 167
circle.Position = position;
circle.StartTime = startTime;
circle.NewCombo = first && selectionHandler.SelectionNewComboState.Value == TernaryState.True;
Copy link
Collaborator

@bdach bdach Oct 11, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can't be changing stuff on hitobjects that already exist in EditorBeatmap without calling EditorBeatmap.Update() at the end. While yes, stuff like changing start time will automatically call it for you, stuff like changing new combo flags does not. And in fact this behaviour with the combo toggle state is completely broken with this change if the first object is reused.

(Note though that it is half-broken already on master if you open the polygon tool without an object selected, because EditorSelectionHandler will reset new combo state to off on deselect. You can do

diff --git a/osu.Game/Screens/Edit/Compose/Components/EditorSelectionHandler.cs b/osu.Game/Screens/Edit/Compose/Components/EditorSelectionHandler.cs
index dbbf767a7d..dfda93cedd 100644
--- a/osu.Game/Screens/Edit/Compose/Components/EditorSelectionHandler.cs
+++ b/osu.Game/Screens/Edit/Compose/Components/EditorSelectionHandler.cs
@@ -176,7 +176,8 @@ private void createStateBindables()
         /// </summary>
         protected virtual void UpdateTernaryStates()
         {
-            SelectionNewComboState.Value = GetStateFromSelection(SelectedItems.OfType<IHasComboInformation>(), h => h.NewCombo);
+            if (SelectedItems.Any())
+                SelectionNewComboState.Value = GetStateFromSelection(SelectedItems.OfType<IHasComboInformation>(), h => h.NewCombo);
 
             var samplesInSelection = SelectedItems.SelectMany(enumerateAllSamples).ToArray();
 

to change that, and we should probably do that at some point.)

Copy link
Contributor Author

@minetoblend minetoblend Oct 11, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I wasn't aware of needing to call EditorBeatmap.Update, I'll keep that in mind for the future.
I restructured the loop body a bit to clearly split the two cases of adding/updating an object.
I also made sure the polygon gets regenerated when the newComboState changes.

The diff above works for preserving the newCombo state in most cases, however when a new object gets added to the beatmap it still resets to false (because of ComposeBlueprintContainer.hitObjectAdded). I added an extra bit at the end to restore the previous newcombo state in that case.

@bdach bdach self-requested a review October 14, 2024 06:20
Comment on lines +179 to +180
if (SelectedItems.Any())
SelectionNewComboState.Value = GetStateFromSelection(SelectedItems.OfType<IHasComboInformation>(), h => h.NewCombo);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know that I proposed this originally but now I see that it's not correct in all instances. This change means that if you select an object that starts a combo, the new combo toggle will enable. Worse yet, if you select a combination of new-combo and non-new-combo objects, the toggle will enter indeterminate state and not even deselection will get rid of that state.

Not sure what the solution here is. Maybe the interaction of this popover with the new combo toggle should be removed completely. @peppy maybe you will have a UX opinion on this

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bdach correct me if i'm wrong, but it seems the only change here is that the check for selected items has been added. so the fail case would be that "new combo" may not be reset when the selection is empty?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct - in the worst case it will stay in indeterminate state after selecting and deselecting a group of objects with mixed new combo state.

Copy link
Member

@peppy peppy Nov 13, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is okay. The next toggle fixes the indeterminate state anyways (and in this state it will seemingly default to placement without new combo, which makes sense to me).

That said, @bdach if you're not happy with this interaction then I'd propose making the generate dialog not set new combo at all, and leave that up to the user to fix as a post operation.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've just made an alternative change to just revert the indeterminate state to full false on deselect (88aea70). Should hopefully be uncontroversial.

My only bother has ever been it visually looking like in the "indeterminate" state after a deselect, nothing more.

peppy
peppy previously approved these changes Nov 13, 2024
Copy link
Member

@peppy peppy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code looks okay to me. Will leave to @bdach's discretion for a final decision.

@bdach bdach merged commit de250d5 into ppy:master Nov 14, 2024
10 checks passed
bdach added a commit to bdach/osu that referenced this pull request Nov 18, 2024
Closes ppy#30713.

Was a point of discussion doing review:

	ppy#30214 (comment)

Given it got pointed out immediately for something so minor, I'm
inclined to believe it's a rather undesirable change.
@minetoblend minetoblend deleted the feat/optimize-polygon-tool branch November 18, 2024 15:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants