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 crash on drag selection via timeline while placement is active #28478

Merged
merged 4 commits into from
Jun 20, 2024

Conversation

bdach
Copy link
Collaborator

@bdach bdach commented Jun 14, 2024

This was reported in #28474, albeit the code changes proposed there did not fix the issue at all.

See 8b6385f for demonstration of the crash scenario. Basically what is happening there is:

  • The starting premise is that there is a spinner placement active.
  • At this time, a drag selection is started via the timeline.
  • Once the drag selection finds at least one suitable object to select, it mutates SelectedItems.
    foreach (var hitObject in Beatmap.HitObjects.Except(SelectedItems).Where(shouldBeSelected))
    {
    Composer.Playfield.SetKeepAlive(hitObject, true);
    SelectedItems.Add(hitObject);
    }
  • When selection changes for any reason, the HitObjectComposer decides to switch to the "select" tool, regardless of why
    the selection changed.
    private void selectionChanged(object sender, NotifyCollectionChangedEventArgs changedArgs)
    {
    if (EditorBeatmap.SelectedHitObjects.Any())
    {
    // ensure in selection mode if a selection is made.
    setSelectTool();
    }
    }
  • Changing the active tool causes the current placement - if any - to be committed, which mutates the beatmap.
    /// <summary>
    /// The current placement tool.
    /// </summary>
    public HitObjectCompositionTool CurrentTool
    {
    get => currentTool;
    set
    {
    if (currentTool == value)
    return;
    currentTool = value;
    // As per stable editor, when changing tools, we should forcefully commit any pending placement.
    commitIfPlacementActive();
    }
    }
  • Back at the drag box selection code, this causes a "collection modified when enumerating" exception.

The proposed fix here is to eagerly commit active placement - if any - when drag selection is initiated via the timeline, which avoids this issue. This also appears to vaguely match stable behaviour and is sort of consistent with the logic of committing any outstanding changes upon switching to the selection tool.

cc @Hecatia-Lapislazuli

bdach added 2 commits June 14, 2024 09:24
This was reported in ppy#28474, albeit the
code changes proposed there did not fix the issue at all.

See 8b6385f for demonstration of the
crash scenario. Basically what is happening there is:

- The starting premise is that there is a spinner placement active.
- At this time, a drag selection is started via the timeline.
- Once the drag selection finds at least one suitable object to select,
  it mutates `SelectedItems`.
- When selection changes for any reason, the `HitObjectComposer`
  decides to switch to the "select" tool, regardless of why
  the selection changed.
- Changing the active tool causes the current placement - if any -
  to be committed, which mutates the beatmap.
- Back at the drag box selection code, this causes a "collection
  modified when enumerating" exception.

The proposed fix here is to eagerly commit active placement - if any -
when drag selection is initiated via the timeline, which avoids this
issue. This also appears to vaguely match stable behaviour and is sort
of consistent with the logic of committing any outstanding changes upon
switching to the selection tool.
@ppy-sentryintegration
Copy link

Sentry issue: OSU-1174

@peppy peppy self-requested a review June 20, 2024 09:54
@peppy peppy merged commit cd4dce2 into ppy:master Jun 20, 2024
14 of 17 checks passed
@bdach bdach deleted the timeline-drag-selection-crash branch June 20, 2024 10:58
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.

2 participants