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. // 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. // See the LICENCE file in the repository root for full licence text.
using System;
using System.Threading; using System.Threading;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Extensions;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Colour; using osu.Framework.Graphics.Colour;
using osu.Framework.Graphics.Textures;
using osu.Framework.Logging;
using osu.Framework.Screens; using osu.Framework.Screens;
using osu.Game.Beatmaps; 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 osu.Game.Online.Rooms;
using osuTK; using osuTK;
using osuTK.Graphics; using osuTK.Graphics;
@@ -16,65 +23,57 @@ namespace osu.Game.Screens.OnlinePlay.Components
public abstract partial class OnlinePlayBackgroundScreen : BackgroundScreen public abstract partial class OnlinePlayBackgroundScreen : BackgroundScreen
{ {
private CancellationTokenSource? cancellationSource; private CancellationTokenSource? cancellationSource;
private PlaylistItemBackground? background; private Background? lastBackground;
private int? beatmapId;
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load() private void load()
{ {
switchBackground(new PlaylistItemBackground(playlistItem)); loadNewBackground();
} }
private PlaylistItem? playlistItem;
protected PlaylistItem? PlaylistItem protected PlaylistItem? PlaylistItem
{ {
get => playlistItem;
set set
{ {
if (playlistItem == value) if (beatmapId == value?.Beatmap.OnlineID)
return; return;
playlistItem = value; beatmapId = value?.Beatmap.OnlineID;
if (LoadState > LoadState.Ready) if (LoadState >= LoadState.Ready)
updateBackground(); loadNewBackground();
} }
} }
private void updateBackground() private void loadNewBackground()
{ {
Schedule(() => cancellationSource?.Cancel();
cancellationSource = new CancellationTokenSource();
if (beatmapId == null)
switchBackground(new DefaultBackground());
else
LoadComponentAsync(new OnlineBeatmapBackground(beatmapId.Value), switchBackground, cancellationSource.Token);
void switchBackground(Background newBackground)
{ {
var beatmap = playlistItem?.Beatmap; float newDepth = 0;
string? lastCover = (background?.Beatmap?.BeatmapSet as IBeatmapSetOnlineInfo)?.Covers.Cover; if (lastBackground != null)
string? newCover = (beatmap?.BeatmapSet as IBeatmapSetOnlineInfo)?.Covers.Cover; {
newDepth = lastBackground.Depth + 1;
lastBackground.FinishTransforms();
lastBackground.FadeOut(250);
lastBackground.Expire();
}
if (lastCover == newCover) newBackground.Depth = newDepth;
return; 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));
cancellationSource?.Cancel(); AddInternal(lastBackground = newBackground);
LoadComponentAsync(new PlaylistItemBackground(playlistItem), switchBackground, (cancellationSource = new CancellationTokenSource()).Token);
});
}
private void switchBackground(PlaylistItemBackground newBackground)
{
float newDepth = 0;
if (background != null)
{
newDepth = background.Depth + 1;
background.FinishTransforms();
background.FadeOut(250);
background.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);
} }
public override void OnSuspending(ScreenTransitionEvent e) public override void OnSuspending(ScreenTransitionEvent e)
@@ -89,5 +88,48 @@ namespace osu.Game.Screens.OnlinePlay.Components
this.MoveToX(0); this.MoveToX(0);
return result; 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; public override bool? ApplyModTrackAdjustments => true;
protected override BackgroundScreen CreateBackground() => new RoomBackgroundScreen(Room.Playlist.FirstOrDefault()) protected override BackgroundScreen CreateBackground() => new MultiplayerRoomBackgroundScreen();
{
SelectedItem = { BindTarget = SelectedItem }
};
public override bool DisallowExternalBeatmapRulesetChanges => true; 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;
}
}
}