1
0
mirror of https://github.com/ppy/osu.git synced 2026-05-13 20:33:35 +08:00

Merge pull request #32563 from smoogipoo/refactor-mp-background

Refactor multiplayer background to remove selected item bindable
This commit is contained in:
Bartłomiej Dach
2025-03-27 12:43:59 +01:00
committed by GitHub
Unverified
4 changed files with 121 additions and 83 deletions
@@ -1,12 +1,19 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System;
using System.Threading;
using osu.Framework.Allocation;
using osu.Framework.Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Colour;
using osu.Framework.Graphics.Textures;
using osu.Framework.Logging;
using osu.Framework.Screens;
using osu.Game.Beatmaps;
using osu.Game.Database;
using osu.Game.Graphics.Backgrounds;
using osu.Game.Online.API.Requests.Responses;
using osu.Game.Online.Rooms;
using osuTK;
using osuTK.Graphics;
@@ -16,65 +23,57 @@ namespace osu.Game.Screens.OnlinePlay.Components
public abstract partial class OnlinePlayBackgroundScreen : BackgroundScreen
{
private CancellationTokenSource? cancellationSource;
private PlaylistItemBackground? background;
private Background? lastBackground;
private int? beatmapId;
[BackgroundDependencyLoader]
private void load()
{
switchBackground(new PlaylistItemBackground(playlistItem));
loadNewBackground();
}
private PlaylistItem? playlistItem;
protected PlaylistItem? PlaylistItem
{
get => playlistItem;
set
{
if (playlistItem == value)
if (beatmapId == value?.Beatmap.OnlineID)
return;
playlistItem = value;
beatmapId = value?.Beatmap.OnlineID;
if (LoadState > LoadState.Ready)
updateBackground();
if (LoadState >= LoadState.Ready)
loadNewBackground();
}
}
private void updateBackground()
private void loadNewBackground()
{
Schedule(() =>
{
var beatmap = playlistItem?.Beatmap;
string? lastCover = (background?.Beatmap?.BeatmapSet as IBeatmapSetOnlineInfo)?.Covers.Cover;
string? newCover = (beatmap?.BeatmapSet as IBeatmapSetOnlineInfo)?.Covers.Cover;
if (lastCover == newCover)
return;
cancellationSource?.Cancel();
LoadComponentAsync(new PlaylistItemBackground(playlistItem), switchBackground, (cancellationSource = new CancellationTokenSource()).Token);
});
}
cancellationSource = new CancellationTokenSource();
private void switchBackground(PlaylistItemBackground newBackground)
if (beatmapId == null)
switchBackground(new DefaultBackground());
else
LoadComponentAsync(new OnlineBeatmapBackground(beatmapId.Value), switchBackground, cancellationSource.Token);
void switchBackground(Background newBackground)
{
float newDepth = 0;
if (background != null)
if (lastBackground != null)
{
newDepth = background.Depth + 1;
background.FinishTransforms();
background.FadeOut(250);
background.Expire();
newDepth = lastBackground.Depth + 1;
lastBackground.FinishTransforms();
lastBackground.FadeOut(250);
lastBackground.Expire();
}
newBackground.Depth = newDepth;
newBackground.Colour = ColourInfo.GradientVertical(new Color4(0.1f, 0.1f, 0.1f, 1f), new Color4(0.4f, 0.4f, 0.4f, 1f));
newBackground.BlurTo(new Vector2(10));
AddInternal(background = newBackground);
AddInternal(lastBackground = newBackground);
}
}
public override void OnSuspending(ScreenTransitionEvent e)
@@ -89,5 +88,48 @@ namespace osu.Game.Screens.OnlinePlay.Components
this.MoveToX(0);
return result;
}
[LongRunningLoad]
private partial class OnlineBeatmapBackground : Background
{
private readonly int beatmapId;
public OnlineBeatmapBackground(int beatmapId)
{
this.beatmapId = beatmapId;
}
[BackgroundDependencyLoader]
private void load(BeatmapLookupCache lookupCache, LargeTextureStore textures, CancellationToken cancellationToken)
{
try
{
APIBeatmap? beatmap = lookupCache.GetBeatmapAsync(beatmapId, cancellationToken).GetResultSafely();
string? coverImage = beatmap?.BeatmapSet?.Covers.Cover;
if (coverImage != null)
Sprite.Texture = textures.Get(coverImage);
}
catch (OperationCanceledException)
{
}
catch (Exception ex)
{
Logger.Error(ex, $"Failed to retrieve cover image for beatmap {beatmapId}.");
}
}
}
private partial class DefaultBackground : Background
{
[Resolved]
private BeatmapManager beatmapManager { get; set; } = null!;
[BackgroundDependencyLoader]
private void load()
{
Sprite.Texture = beatmapManager.DefaultBeatmap.GetBackground();
}
}
}
}
@@ -1,42 +0,0 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Allocation;
using osu.Framework.Graphics.Textures;
using osu.Game.Beatmaps;
using osu.Game.Graphics.Backgrounds;
using osu.Game.Online.Rooms;
namespace osu.Game.Screens.OnlinePlay.Components
{
public partial class PlaylistItemBackground : Background
{
public readonly IBeatmapInfo? Beatmap;
public PlaylistItemBackground(PlaylistItem? playlistItem)
{
Beatmap = playlistItem?.Beatmap;
}
[BackgroundDependencyLoader]
private void load(BeatmapManager beatmaps, LargeTextureStore textures)
{
Texture? texture = null;
// prefer online cover where available.
if (Beatmap?.BeatmapSet is IBeatmapSetOnlineInfo online)
texture = textures.Get(online.Covers.Cover);
Sprite.Texture = texture ?? beatmaps.DefaultBeatmap.GetBackground();
}
public override bool Equals(Background? other)
{
if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;
return other.GetType() == GetType()
&& ((PlaylistItemBackground)other).Beatmap == Beatmap;
}
}
}
@@ -39,10 +39,7 @@ namespace osu.Game.Screens.OnlinePlay.Match
public override bool? ApplyModTrackAdjustments => true;
protected override BackgroundScreen CreateBackground() => new RoomBackgroundScreen(Room.Playlist.FirstOrDefault())
{
SelectedItem = { BindTarget = SelectedItem }
};
protected override BackgroundScreen CreateBackground() => new MultiplayerRoomBackgroundScreen();
public override bool DisallowExternalBeatmapRulesetChanges => true;
@@ -0,0 +1,41 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Allocation;
using osu.Framework.Extensions.ObjectExtensions;
using osu.Game.Online.Multiplayer;
using osu.Game.Online.Rooms;
using osu.Game.Screens.OnlinePlay.Components;
namespace osu.Game.Screens.OnlinePlay.Multiplayer
{
public partial class MultiplayerRoomBackgroundScreen : OnlinePlayBackgroundScreen
{
[Resolved]
private MultiplayerClient client { get; set; } = null!;
protected override void LoadComplete()
{
base.LoadComplete();
client.RoomUpdated += onRoomUpdated;
onRoomUpdated();
}
private void onRoomUpdated() => Scheduler.AddOnce(() =>
{
if (client.Room == null)
return;
PlaylistItem = new PlaylistItem(client.Room.CurrentPlaylistItem);
});
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
if (client.IsNotNull())
client.RoomUpdated -= onRoomUpdated;
}
}
}