From b9ec860cf2c7a5a3eae50cc06c6301e7ed5e5802 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 18 Jan 2022 12:20:52 +0900 Subject: [PATCH] Ensure global beatmap/ruleset are always mutated from the update thread This came up while testing the new realm thread, where `MusicController` would fall over when `OsuTestScene` changes the global beatmap from an async load thread (causing a cross-thread realm access). We don't want to have to schedule every usage of these bindables, so this seems like a good constraint to put in place. --- osu.Game/OsuGameBase.cs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index 9256514a0a..8126b74418 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -327,6 +327,7 @@ namespace osu.Game dependencies.CacheAs(MusicController); Ruleset.BindValueChanged(onRulesetChanged); + Beatmap.BindValueChanged(onBeatmapChanged); } protected virtual void InitialiseFonts() @@ -448,8 +449,17 @@ namespace osu.Game protected override Storage CreateStorage(GameHost host, Storage defaultStorage) => new OsuStorage(host, defaultStorage); + private void onBeatmapChanged(ValueChangedEvent valueChangedEvent) + { + if (!ThreadSafety.IsUpdateThread) + throw new InvalidOperationException("Global beatmap bindable must be changed from update thread."); + } + private void onRulesetChanged(ValueChangedEvent r) { + if (!ThreadSafety.IsUpdateThread) + throw new InvalidOperationException("Global ruleset bindable must be changed from update thread."); + if (r.NewValue?.Available != true) { // reject the change if the ruleset is not available.