Improve safety of ongoing operation tracker

Finishing an operation started via
`OngoingOperationTracker.BeginOperation()` was risky in cases where the
operation ended at a callback on another thread (which, in the case of
multiplayer, is *most* cases). In particular, if any consumer registered
a callback that mutates transforms when the operation ends, it would
result in crashes after the framework-side safety checks.

Rework `OngoingOperationTracker` into an always-present component
residing in the drawable hierarchy, and ensure that the
`operationInProgress` bindable is always updated on the update thread.
This way consumers don't have to add local schedules in multiple places.
This commit is contained in:
Bartłomiej Dach
2021-01-09 21:38:20 +01:00
parent c8d83a9fb3
commit 8c3955d341
5 changed files with 19 additions and 11 deletions

View File

@ -3,18 +3,13 @@
using System;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Game.Screens.OnlinePlay;
using osu.Game.Screens.OnlinePlay.Multiplayer;
namespace osu.Game.Tests.Visual.Multiplayer
{
public class TestSceneCreateMultiplayerMatchButton : MultiplayerTestScene
{
[Cached]
private OngoingOperationTracker ongoingOperationTracker = new OngoingOperationTracker();
private CreateMultiplayerMatchButton button;
public override void SetUpSteps()
@ -36,7 +31,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
assertButtonEnableState(true);
AddStep("begin joining room", () => joiningRoomOperation = ongoingOperationTracker.BeginOperation());
AddStep("begin joining room", () => joiningRoomOperation = OngoingOperationTracker.BeginOperation());
assertButtonEnableState(false);
AddStep("end joining room", () => joiningRoomOperation.Dispose());