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>
public bool AllPlayersLoaded => instances.All(p => p?.PlayerLoaded == true);
private readonly int[] userIds;
[Resolved]
private SpectatorStreamingClient spectatorClient { get; set; }
@ -44,7 +46,8 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Spectate
public MultiSpectatorScreen(int[] userIds)
: base(userIds.Take(PlayerGrid.MAX_PLAYERS).ToArray())
{
instances = new PlayerArea[UserIds.Length];
this.userIds = GetUserIds().ToArray();
instances = new PlayerArea[this.userIds.Length];
}
[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);
}
@ -89,7 +92,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Spectate
var scoreProcessor = Ruleset.Value.CreateInstance().CreateScoreProcessor();
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()
@ -133,10 +136,10 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Spectate
protected override void EndGameplay(int userId)
{
spectatorClient.StopWatchingUser(userId);
RemoveUser(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.Threading.Tasks;
using JetBrains.Annotations;
using NuGet.Packaging;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Game.Beatmaps;
@ -26,7 +27,8 @@ namespace osu.Game.Screens.Spectate
/// </summary>
public abstract class SpectatorScreen : OsuScreen
{
protected readonly int[] UserIds;
protected IEnumerable<int> GetUserIds() => userIds;
private readonly HashSet<int> userIds = new HashSet<int>();
[Resolved]
private BeatmapManager beatmaps { get; set; }
@ -54,7 +56,7 @@ namespace osu.Game.Screens.Spectate
/// <param name="userIds">The users to spectate.</param>
protected SpectatorScreen(params int[] userIds)
{
UserIds = userIds;
this.userIds.AddRange(userIds);
}
protected override void LoadComplete()
@ -80,20 +82,18 @@ namespace osu.Game.Screens.Spectate
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[i] = userLookupCache.GetUserAsync(userId).ContinueWith(task =>
userLookupTasks.Add(userLookupCache.GetUserAsync(u).ContinueWith(task =>
{
if (!task.IsCompletedSuccessfully)
return;
lock (stateLock)
userMap[userId] = task.Result;
});
userMap[u] = task.Result;
}));
}
return Task.WhenAll(userLookupTasks);
@ -239,6 +239,23 @@ namespace osu.Game.Screens.Spectate
/// <param name="userId">The user to end gameplay for.</param>
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)
{
base.Dispose(isDisposing);