1
0
mirror of https://github.com/ppy/osu.git synced 2024-12-14 10:52:53 +08:00

Remove finished players from multi spectator screen

This commit is contained in:
smoogipoo 2021-04-26 21:25:34 +09:00
parent 94d0b06493
commit 7e11d520d5
2 changed files with 35 additions and 15 deletions

View File

@ -27,6 +27,8 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Spectate
/// </summary> /// </summary>
public bool AllPlayersLoaded => instances.All(p => p?.PlayerLoaded == true); public bool AllPlayersLoaded => instances.All(p => p?.PlayerLoaded == true);
private readonly int[] userIds;
[Resolved] [Resolved]
private SpectatorStreamingClient spectatorClient { get; set; } private SpectatorStreamingClient spectatorClient { get; set; }
@ -44,7 +46,8 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Spectate
public MultiSpectatorScreen(int[] userIds) public MultiSpectatorScreen(int[] userIds)
: base(userIds.Take(PlayerGrid.MAX_PLAYERS).ToArray()) : base(userIds.Take(PlayerGrid.MAX_PLAYERS).ToArray())
{ {
instances = new PlayerArea[UserIds.Length]; this.userIds = GetUserIds().ToArray();
instances = new PlayerArea[this.userIds.Length];
} }
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
@ -78,9 +81,9 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Spectate
}) })
}; };
for (int i = 0; i < UserIds.Length; i++) for (int i = 0; i < userIds.Length; i++)
{ {
grid.Add(instances[i] = new PlayerArea(UserIds[i], masterClockContainer.GameplayClock)); grid.Add(instances[i] = new PlayerArea(userIds[i], masterClockContainer.GameplayClock));
syncManager.AddPlayerClock(instances[i].GameplayClock); syncManager.AddPlayerClock(instances[i].GameplayClock);
} }
@ -89,7 +92,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Spectate
var scoreProcessor = Ruleset.Value.CreateInstance().CreateScoreProcessor(); var scoreProcessor = Ruleset.Value.CreateInstance().CreateScoreProcessor();
scoreProcessor.ApplyBeatmap(playableBeatmap); scoreProcessor.ApplyBeatmap(playableBeatmap);
LoadComponentAsync(leaderboard = new MultiSpectatorLeaderboard(scoreProcessor, UserIds) { Expanded = { Value = true } }, leaderboardContainer.Add); LoadComponentAsync(leaderboard = new MultiSpectatorLeaderboard(scoreProcessor, userIds) { Expanded = { Value = true } }, leaderboardContainer.Add);
} }
protected override void LoadComplete() protected override void LoadComplete()
@ -133,10 +136,10 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Spectate
protected override void EndGameplay(int userId) protected override void EndGameplay(int userId)
{ {
spectatorClient.StopWatchingUser(userId); RemoveUser(userId);
leaderboard.RemoveClock(userId); leaderboard.RemoveClock(userId);
} }
private int getIndexForUser(int userId) => Array.IndexOf(UserIds, userId); private int getIndexForUser(int userId) => Array.IndexOf(userIds, userId);
} }
} }

View File

@ -7,6 +7,7 @@ using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using JetBrains.Annotations; using JetBrains.Annotations;
using NuGet.Packaging;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Bindables; using osu.Framework.Bindables;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
@ -26,7 +27,8 @@ namespace osu.Game.Screens.Spectate
/// </summary> /// </summary>
public abstract class SpectatorScreen : OsuScreen public abstract class SpectatorScreen : OsuScreen
{ {
protected readonly int[] UserIds; protected IEnumerable<int> GetUserIds() => userIds;
private readonly HashSet<int> userIds = new HashSet<int>();
[Resolved] [Resolved]
private BeatmapManager beatmaps { get; set; } private BeatmapManager beatmaps { get; set; }
@ -54,7 +56,7 @@ namespace osu.Game.Screens.Spectate
/// <param name="userIds">The users to spectate.</param> /// <param name="userIds">The users to spectate.</param>
protected SpectatorScreen(params int[] userIds) protected SpectatorScreen(params int[] userIds)
{ {
UserIds = userIds; this.userIds.AddRange(userIds);
} }
protected override void LoadComplete() protected override void LoadComplete()
@ -80,20 +82,18 @@ namespace osu.Game.Screens.Spectate
private Task populateAllUsers() private Task populateAllUsers()
{ {
var userLookupTasks = new Task[UserIds.Length]; var userLookupTasks = new List<Task>();
for (int i = 0; i < UserIds.Length; i++) foreach (var u in userIds)
{ {
var userId = UserIds[i]; userLookupTasks.Add(userLookupCache.GetUserAsync(u).ContinueWith(task =>
userLookupTasks[i] = userLookupCache.GetUserAsync(userId).ContinueWith(task =>
{ {
if (!task.IsCompletedSuccessfully) if (!task.IsCompletedSuccessfully)
return; return;
lock (stateLock) lock (stateLock)
userMap[userId] = task.Result; userMap[u] = task.Result;
}); }));
} }
return Task.WhenAll(userLookupTasks); return Task.WhenAll(userLookupTasks);
@ -239,6 +239,23 @@ namespace osu.Game.Screens.Spectate
/// <param name="userId">The user to end gameplay for.</param> /// <param name="userId">The user to end gameplay for.</param>
protected abstract void EndGameplay(int userId); protected abstract void EndGameplay(int userId);
/// <summary>
/// Stops spectating a user.
/// </summary>
/// <param name="userId">The user to stop spectating.</param>
protected void RemoveUser(int userId)
{
lock (stateLock)
{
userFinishedPlaying(userId, null);
userIds.Remove(userId);
userMap.Remove(userId);
spectatorClient.StopWatchingUser(userId);
}
}
protected override void Dispose(bool isDisposing) protected override void Dispose(bool isDisposing)
{ {
base.Dispose(isDisposing); base.Dispose(isDisposing);