1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-12 22:33:05 +08:00

Remove PlayingUsers list from SpectatorClient

This commit is contained in:
Dan Balasescu 2022-01-26 00:21:54 +09:00
parent aa492270dd
commit 502e6af008
5 changed files with 19 additions and 68 deletions

View File

@ -3,12 +3,9 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Specialized;
using System.Diagnostics;
using System.Linq; using System.Linq;
using NUnit.Framework; using NUnit.Framework;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Shapes;
@ -20,7 +17,6 @@ using osu.Framework.Testing;
using osu.Framework.Timing; using osu.Framework.Timing;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Graphics.Sprites; using osu.Game.Graphics.Sprites;
using osu.Game.Online.API;
using osu.Game.Online.Spectator; using osu.Game.Online.Spectator;
using osu.Game.Replays; using osu.Game.Replays;
using osu.Game.Replays.Legacy; using osu.Game.Replays.Legacy;
@ -47,8 +43,6 @@ namespace osu.Game.Tests.Visual.Gameplay
private Replay replay; private Replay replay;
private readonly IBindableList<int> users = new BindableList<int>();
private TestReplayRecorder recorder; private TestReplayRecorder recorder;
private ManualClock manualClock; private ManualClock manualClock;
@ -57,9 +51,6 @@ namespace osu.Game.Tests.Visual.Gameplay
private TestFramedReplayInputHandler replayHandler; private TestFramedReplayInputHandler replayHandler;
[Resolved]
private IAPIProvider api { get; set; }
[Resolved] [Resolved]
private SpectatorClient spectatorClient { get; set; } private SpectatorClient spectatorClient { get; set; }
@ -78,35 +69,6 @@ namespace osu.Game.Tests.Visual.Gameplay
spectatorClient.OnNewFrames += onNewFrames; spectatorClient.OnNewFrames += onNewFrames;
users.BindTo(spectatorClient.PlayingUsers);
users.BindCollectionChanged((obj, args) =>
{
switch (args.Action)
{
case NotifyCollectionChangedAction.Add:
Debug.Assert(args.NewItems != null);
foreach (int user in args.NewItems)
{
if (user == api.LocalUser.Value.Id)
spectatorClient.WatchUser(user);
}
break;
case NotifyCollectionChangedAction.Remove:
Debug.Assert(args.OldItems != null);
foreach (int user in args.OldItems)
{
if (user == api.LocalUser.Value.Id)
spectatorClient.StopWatchingUser(user);
}
break;
}
}, true);
Children = new Drawable[] Children = new Drawable[]
{ {
new GridContainer new GridContainer

View File

@ -115,7 +115,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
public void RandomlyUpdateState() public void RandomlyUpdateState()
{ {
foreach (int userId in PlayingUsers) foreach ((int userId, _) in PlayingUserStates)
{ {
if (RNG.NextBool()) if (RNG.NextBool())
continue; continue;

View File

@ -37,9 +37,6 @@ namespace osu.Game.Online.Spectator
private readonly List<int> watchingUsers = new List<int>(); private readonly List<int> watchingUsers = new List<int>();
public IBindableList<int> PlayingUsers => playingUsers;
private readonly BindableList<int> playingUsers = new BindableList<int>();
public IBindableDictionary<int, SpectatorState> PlayingUserStates => playingUserStates; public IBindableDictionary<int, SpectatorState> PlayingUserStates => playingUserStates;
private readonly BindableDictionary<int, SpectatorState> playingUserStates = new BindableDictionary<int, SpectatorState>(); private readonly BindableDictionary<int, SpectatorState> playingUserStates = new BindableDictionary<int, SpectatorState>();
@ -88,10 +85,7 @@ namespace osu.Game.Online.Spectator
BeginPlayingInternal(currentState); BeginPlayingInternal(currentState);
} }
else else
{
playingUsers.Clear();
playingUserStates.Clear(); playingUserStates.Clear();
}
}), true); }), true);
} }
@ -99,9 +93,6 @@ namespace osu.Game.Online.Spectator
{ {
Schedule(() => Schedule(() =>
{ {
if (!playingUsers.Contains(userId))
playingUsers.Add(userId);
// UserBeganPlaying() is called by the server regardless of whether the local user is watching the remote user, and is called a further time when the remote user is watched. // UserBeganPlaying() is called by the server regardless of whether the local user is watching the remote user, and is called a further time when the remote user is watched.
// This may be a temporary thing (see: https://github.com/ppy/osu-server-spectator/blob/2273778e02cfdb4a9c6a934f2a46a8459cb5d29c/osu.Server.Spectator/Hubs/SpectatorHub.cs#L28-L29). // This may be a temporary thing (see: https://github.com/ppy/osu-server-spectator/blob/2273778e02cfdb4a9c6a934f2a46a8459cb5d29c/osu.Server.Spectator/Hubs/SpectatorHub.cs#L28-L29).
// We don't want the user states to update unless the player is being watched, otherwise calling BindUserBeganPlaying() can lead to double invocations. // We don't want the user states to update unless the player is being watched, otherwise calling BindUserBeganPlaying() can lead to double invocations.
@ -118,7 +109,6 @@ namespace osu.Game.Online.Spectator
{ {
Schedule(() => Schedule(() =>
{ {
playingUsers.Remove(userId);
playingUserStates.Remove(userId); playingUserStates.Remove(userId);
OnUserFinishedPlaying?.Invoke(userId, state); OnUserFinishedPlaying?.Invoke(userId, state);

View File

@ -1,7 +1,7 @@
// 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.Collections.Specialized; using System.Diagnostics;
using System.Linq; using System.Linq;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Bindables; using osu.Framework.Bindables;
@ -22,7 +22,7 @@ namespace osu.Game.Overlays.Dashboard
{ {
internal class CurrentlyPlayingDisplay : CompositeDrawable internal class CurrentlyPlayingDisplay : CompositeDrawable
{ {
private readonly IBindableList<int> playingUsers = new BindableList<int>(); private readonly IBindableDictionary<int, SpectatorState> playingUserStates = new BindableDictionary<int, SpectatorState>();
private FillFlowContainer<PlayingUserPanel> userFlow; private FillFlowContainer<PlayingUserPanel> userFlow;
@ -51,18 +51,20 @@ namespace osu.Game.Overlays.Dashboard
{ {
base.LoadComplete(); base.LoadComplete();
playingUsers.BindTo(spectatorClient.PlayingUsers); playingUserStates.BindTo(spectatorClient.PlayingUserStates);
playingUsers.BindCollectionChanged(onUsersChanged, true); playingUserStates.BindCollectionChanged(onUsersChanged, true);
} }
private void onUsersChanged(object sender, NotifyCollectionChangedEventArgs e) => Schedule(() => private void onUsersChanged(object sender, NotifyDictionaryChangedEventArgs<int, SpectatorState> e) => Schedule(() =>
{ {
switch (e.Action) switch (e.Action)
{ {
case NotifyCollectionChangedAction.Add: case NotifyDictionaryChangedAction.Add:
foreach (int id in e.NewItems.OfType<int>().ToArray()) Debug.Assert(e.NewItems != null);
foreach ((int userId, _) in e.NewItems)
{ {
users.GetUserAsync(id).ContinueWith(task => users.GetUserAsync(userId).ContinueWith(task =>
{ {
var user = task.GetResultSafely(); var user = task.GetResultSafely();
@ -71,7 +73,7 @@ namespace osu.Game.Overlays.Dashboard
Schedule(() => Schedule(() =>
{ {
// user may no longer be playing. // user may no longer be playing.
if (!playingUsers.Contains(user.Id)) if (!playingUserStates.ContainsKey(user.Id))
return; return;
userFlow.Add(createUserPanel(user)); userFlow.Add(createUserPanel(user));
@ -81,13 +83,11 @@ namespace osu.Game.Overlays.Dashboard
break; break;
case NotifyCollectionChangedAction.Remove: case NotifyDictionaryChangedAction.Remove:
foreach (int u in e.OldItems.OfType<int>()) Debug.Assert(e.OldItems != null);
userFlow.FirstOrDefault(card => card.User.Id == u)?.Expire();
break;
case NotifyCollectionChangedAction.Reset: foreach ((int userId, _) in e.OldItems)
userFlow.Clear(); userFlow.FirstOrDefault(card => card.User.Id == userId)?.Expire();
break; break;
} }
}); });

View File

@ -6,7 +6,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Bindables; using osu.Framework.Bindables;
@ -42,7 +41,7 @@ namespace osu.Game.Tests.Visual.Spectator
{ {
OnNewFrames += (i, bundle) => OnNewFrames += (i, bundle) =>
{ {
if (PlayingUsers.Contains(i)) if (PlayingUserStates.ContainsKey(i))
lastReceivedUserFrames[i] = bundle.Frames[^1]; lastReceivedUserFrames[i] = bundle.Frames[^1];
}; };
} }
@ -65,7 +64,7 @@ namespace osu.Game.Tests.Visual.Spectator
/// <param name="userId">The user to end play for.</param> /// <param name="userId">The user to end play for.</param>
public void EndPlay(int userId) public void EndPlay(int userId)
{ {
if (!PlayingUsers.Contains(userId)) if (!PlayingUserStates.ContainsKey(userId))
return; return;
((ISpectatorClient)this).UserFinishedPlaying(userId, new SpectatorState ((ISpectatorClient)this).UserFinishedPlaying(userId, new SpectatorState
@ -131,7 +130,7 @@ namespace osu.Game.Tests.Visual.Spectator
protected override Task WatchUserInternal(int userId) protected override Task WatchUserInternal(int userId)
{ {
// When newly watching a user, the server sends the playing state immediately. // When newly watching a user, the server sends the playing state immediately.
if (PlayingUsers.Contains(userId)) if (PlayingUserStates.ContainsKey(userId))
sendPlayingState(userId); sendPlayingState(userId);
return Task.CompletedTask; return Task.CompletedTask;