diff --git a/osu.Game.Tests/Online/TestSceneOnlinePlayBeatmapAvailabilityTracker.cs b/osu.Game.Tests/Online/TestSceneOnlinePlayBeatmapAvailabilityTracker.cs index ae3451c3e0..5326b36e5e 100644 --- a/osu.Game.Tests/Online/TestSceneOnlinePlayBeatmapAvailabilityTracker.cs +++ b/osu.Game.Tests/Online/TestSceneOnlinePlayBeatmapAvailabilityTracker.cs @@ -28,6 +28,7 @@ using osu.Game.Online.API.Requests; using osu.Game.Online.API.Requests.Responses; using osu.Game.Online.Rooms; using osu.Game.Rulesets; +using osu.Game.Screens.OnlinePlay; using osu.Game.Tests.Resources; using osu.Game.Tests.Visual; @@ -110,7 +111,7 @@ namespace osu.Game.Tests.Online beatmapLookupCache, availabilityTracker = new OnlinePlayBeatmapAvailabilityTracker { - SelectedItem = { BindTarget = selectedItem, } + PlaylistItem = { BindTarget = selectedItem, } } } }; diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerSpectateButton.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerSpectateButton.cs index ff5436a87d..90b633c8f3 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerSpectateButton.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerSpectateButton.cs @@ -52,7 +52,7 @@ namespace osu.Game.Tests.Visual.Multiplayer AddStep("create button", () => { - AvailabilityTracker.SelectedItem.Value = room.Playlist.First(); + AvailabilityTracker.PlaylistItem.Value = room.Playlist.First(); importedSet = beatmaps.GetAllUsableBeatmapSets().First(); Beatmap.Value = beatmaps.GetWorkingBeatmap(importedSet.Beatmaps.First()); diff --git a/osu.Game/Screens/OnlinePlay/DailyChallenge/DailyChallenge.cs b/osu.Game/Screens/OnlinePlay/DailyChallenge/DailyChallenge.cs index 5c8b500c93..2e78a69e4a 100644 --- a/osu.Game/Screens/OnlinePlay/DailyChallenge/DailyChallenge.cs +++ b/osu.Game/Screens/OnlinePlay/DailyChallenge/DailyChallenge.cs @@ -378,7 +378,7 @@ namespace osu.Game.Screens.OnlinePlay.DailyChallenge { base.LoadComplete(); - beatmapAvailabilityTracker.SelectedItem.Value = playlistItem; + beatmapAvailabilityTracker.PlaylistItem.Value = playlistItem; beatmapAvailabilityTracker.Availability.BindValueChanged(_ => TrySetDailyChallengeBeatmap(this, beatmapManager, rulesets, musicController, playlistItem), true); userModsSelectOverlayRegistration = overlayManager?.RegisterBlockingOverlay(userModsSelectOverlay); diff --git a/osu.Game/Screens/OnlinePlay/DailyChallenge/DailyChallengeIntro.cs b/osu.Game/Screens/OnlinePlay/DailyChallenge/DailyChallengeIntro.cs index 7fddb8d1c4..d414e3c54f 100644 --- a/osu.Game/Screens/OnlinePlay/DailyChallenge/DailyChallengeIntro.cs +++ b/osu.Game/Screens/OnlinePlay/DailyChallenge/DailyChallengeIntro.cs @@ -352,7 +352,7 @@ namespace osu.Game.Screens.OnlinePlay.DailyChallenge { base.OnEntering(e); - beatmapAvailabilityTracker.SelectedItem.Value = item; + beatmapAvailabilityTracker.PlaylistItem.Value = item; beatmapAvailabilityTracker.Availability.BindValueChanged(availability => { if (shouldBePlayingMusic && availability.NewValue.State == DownloadState.LocallyAvailable) diff --git a/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs b/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs index f924ff6980..07011c1626 100644 --- a/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs @@ -268,7 +268,7 @@ namespace osu.Game.Screens.OnlinePlay.Match SelectedItem.BindValueChanged(_ => updateSpecifics()); UserMods.BindValueChanged(_ => updateSpecifics()); - beatmapAvailabilityTracker.SelectedItem.BindTo(SelectedItem); + beatmapAvailabilityTracker.PlaylistItem.BindTo(SelectedItem); beatmapAvailabilityTracker.Availability.BindValueChanged(_ => updateSpecifics()); userModsSelectOverlayRegistration = overlayManager?.RegisterBlockingOverlay(UserModsSelectOverlay); diff --git a/osu.Game/Online/Rooms/OnlinePlayBeatmapAvailabilityTracker.cs b/osu.Game/Screens/OnlinePlay/OnlinePlayBeatmapAvailabilityTracker.cs similarity index 58% rename from osu.Game/Online/Rooms/OnlinePlayBeatmapAvailabilityTracker.cs rename to osu.Game/Screens/OnlinePlay/OnlinePlayBeatmapAvailabilityTracker.cs index 45f52f3cd8..bda618d1fa 100644 --- a/osu.Game/Online/Rooms/OnlinePlayBeatmapAvailabilityTracker.cs +++ b/osu.Game/Screens/OnlinePlay/OnlinePlayBeatmapAvailabilityTracker.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Diagnostics; using System.Linq; @@ -16,10 +14,12 @@ using osu.Framework.Logging; using osu.Framework.Threading; using osu.Game.Beatmaps; using osu.Game.Database; +using osu.Game.Online; using osu.Game.Online.API.Requests.Responses; +using osu.Game.Online.Rooms; using Realms; -namespace osu.Game.Online.Rooms +namespace osu.Game.Screens.OnlinePlay { /// /// Represent a checksum-verifying beatmap availability tracker usable for online play screens. @@ -29,7 +29,15 @@ namespace osu.Game.Online.Rooms /// public partial class OnlinePlayBeatmapAvailabilityTracker : CompositeComponent { - public readonly Bindable SelectedItem = new Bindable(); + /// + /// The current availability of 's beatmap. + /// + public IBindable Availability => availability; + + /// + /// The playlist item to track the availability of. + /// + public readonly Bindable PlaylistItem = new Bindable(); [Resolved] private RealmAccess realm { get; set; } = null!; @@ -37,23 +45,17 @@ namespace osu.Game.Online.Rooms [Resolved] private BeatmapLookupCache beatmapLookupCache { get; set; } = null!; - /// - /// The availability state of the currently selected playlist item. - /// - public virtual IBindable Availability => availability; - private readonly Bindable availability = new Bindable(BeatmapAvailability.NotDownloaded()); - private ScheduledDelegate progressUpdate; - private BeatmapDownloadTracker downloadTracker; - private IDisposable realmSubscription; - private APIBeatmap selectedBeatmap; + private ScheduledDelegate? progressUpdate; + private BeatmapDownloadTracker? downloadTracker; + private IDisposable? realmSubscription; protected override void LoadComplete() { base.LoadComplete(); - SelectedItem.BindValueChanged(item => + PlaylistItem.BindValueChanged(item => { // the underlying playlist is regularly cleared for maintenance purposes (things which probably need to be fixed eventually). // to avoid exposing a state change when there may actually be none, ignore all nulls for now. @@ -69,30 +71,29 @@ namespace osu.Game.Online.Rooms // This is just for safety. availability.Value = BeatmapAvailability.Unknown(); - downloadTracker?.RemoveAndDisposeImmediately(); - selectedBeatmap = null; + cancelTracking(); beatmapLookupCache.GetBeatmapAsync(item.NewValue.Beatmap.OnlineID).ContinueWith(task => Schedule(() => { var beatmap = task.GetResultSafely(); - if (beatmap != null && SelectedItem.Value?.Beatmap.OnlineID == beatmap.OnlineID) - { - selectedBeatmap = beatmap; - beginTracking(); - } + if (beatmap != null && PlaylistItem.Value?.Beatmap.OnlineID == beatmap.OnlineID) + startTracking(beatmap); }), TaskContinuationOptions.OnlyOnRanToCompletion); }, true); } - private void beginTracking() + private void cancelTracking() { - Debug.Assert(selectedBeatmap.BeatmapSet != null); + downloadTracker?.RemoveAndDisposeImmediately(); + realmSubscription?.Dispose(); + } - downloadTracker = new BeatmapDownloadTracker(selectedBeatmap.BeatmapSet); - - AddInternal(downloadTracker); + private void startTracking(APIBeatmap beatmap) + { + Debug.Assert(beatmap.BeatmapSet != null); + downloadTracker = new BeatmapDownloadTracker(beatmap.BeatmapSet); downloadTracker.State.BindValueChanged(_ => Scheduler.AddOnce(updateAvailability), true); downloadTracker.Progress.BindValueChanged(_ => { @@ -105,64 +106,55 @@ namespace osu.Game.Online.Rooms progressUpdate = Scheduler.AddDelayed(updateAvailability, progressUpdate == null ? 0 : 500); }, true); + AddInternal(downloadTracker); + // handles changes to hash that didn't occur from the import process (ie. a user editing the beatmap in the editor, somehow). - realmSubscription?.Dispose(); - realmSubscription = realm.RegisterForNotifications(_ => filteredBeatmaps(), (_, changes) => + realmSubscription = realm.RegisterForNotifications(_ => queryBeatmap(), (_, changes) => { if (changes == null) return; Scheduler.AddOnce(updateAvailability); }); - } - private void updateAvailability() - { - if (downloadTracker == null || selectedBeatmap == null) - return; - - switch (downloadTracker.State.Value) + void updateAvailability() { - case DownloadState.Unknown: - availability.Value = BeatmapAvailability.Unknown(); - break; + switch (downloadTracker.State.Value) + { + case DownloadState.Unknown: + availability.Value = BeatmapAvailability.Unknown(); + break; - case DownloadState.NotDownloaded: - availability.Value = BeatmapAvailability.NotDownloaded(); - break; + case DownloadState.NotDownloaded: + availability.Value = BeatmapAvailability.NotDownloaded(); + break; - case DownloadState.Downloading: - availability.Value = BeatmapAvailability.Downloading((float)downloadTracker.Progress.Value); - break; + case DownloadState.Downloading: + availability.Value = BeatmapAvailability.Downloading((float)downloadTracker.Progress.Value); + break; - case DownloadState.Importing: - availability.Value = BeatmapAvailability.Importing(); - break; + case DownloadState.Importing: + availability.Value = BeatmapAvailability.Importing(); + break; - case DownloadState.LocallyAvailable: - bool available = filteredBeatmaps().Any(); + case DownloadState.LocallyAvailable: + bool available = queryBeatmap().Any(); - availability.Value = available ? BeatmapAvailability.LocallyAvailable() : BeatmapAvailability.NotDownloaded(); + availability.Value = available ? BeatmapAvailability.LocallyAvailable() : BeatmapAvailability.NotDownloaded(); - // only display a message to the user if a download seems to have just completed. - if (!available && downloadTracker.Progress.Value == 1) - Logger.Log("The imported beatmap set does not match the online version.", LoggingTarget.Runtime, LogLevel.Important); + // only display a message to the user if a download seems to have just completed. + if (!available && downloadTracker.Progress.Value == 1) + Logger.Log("The imported beatmap set does not match the online version.", LoggingTarget.Runtime, LogLevel.Important); - break; + break; - default: - throw new ArgumentOutOfRangeException(); + default: + throw new ArgumentOutOfRangeException(); + } } - } - private IQueryable filteredBeatmaps() - { - int onlineId = selectedBeatmap.OnlineID; - string checksum = selectedBeatmap.MD5Hash; - - return realm.Realm - .All() - .Filter("OnlineID == $0 && MD5Hash == $1 && BeatmapSet.DeletePending == false", onlineId, checksum); + IQueryable queryBeatmap() => + realm.Realm.All().Filter("OnlineID == $0 && MD5Hash == $1 && BeatmapSet.DeletePending == false", beatmap.OnlineID, beatmap.MD5Hash); } protected override void Dispose(bool isDisposing) diff --git a/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomSubScreen.cs b/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomSubScreen.cs index ae31e55da5..4ada9a99fd 100644 --- a/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomSubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomSubScreen.cs @@ -454,7 +454,7 @@ namespace osu.Game.Screens.OnlinePlay.Playlists SelectedItem.BindValueChanged(onSelectedItemChanged); - beatmapAvailabilityTracker.SelectedItem.BindTo(SelectedItem); + beatmapAvailabilityTracker.PlaylistItem.BindTo(SelectedItem); beatmapAvailabilityTracker.Availability.BindValueChanged(_ => updateGameplayState()); UserBeatmap.BindValueChanged(_ => updateGameplayState()); diff --git a/osu.Game/Tests/Visual/OnlinePlay/IOnlinePlayTestSceneDependencies.cs b/osu.Game/Tests/Visual/OnlinePlay/IOnlinePlayTestSceneDependencies.cs index 60730ee9a4..861aa079f4 100644 --- a/osu.Game/Tests/Visual/OnlinePlay/IOnlinePlayTestSceneDependencies.cs +++ b/osu.Game/Tests/Visual/OnlinePlay/IOnlinePlayTestSceneDependencies.cs @@ -2,7 +2,6 @@ // See the LICENCE file in the repository root for full licence text. using osu.Game.Database; -using osu.Game.Online.Rooms; using osu.Game.Screens.OnlinePlay; namespace osu.Game.Tests.Visual.OnlinePlay diff --git a/osu.Game/Tests/Visual/OnlinePlay/OnlinePlayTestSceneDependencies.cs b/osu.Game/Tests/Visual/OnlinePlay/OnlinePlayTestSceneDependencies.cs index 9537c7958c..ca680fc5ba 100644 --- a/osu.Game/Tests/Visual/OnlinePlay/OnlinePlayTestSceneDependencies.cs +++ b/osu.Game/Tests/Visual/OnlinePlay/OnlinePlayTestSceneDependencies.cs @@ -6,7 +6,6 @@ using System.Collections.Generic; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Game.Database; -using osu.Game.Online.Rooms; using osu.Game.Overlays; using osu.Game.Screens.OnlinePlay;