mirror of
https://github.com/ppy/osu.git
synced 2024-12-14 20:22:55 +08:00
Add back playing users list
This commit is contained in:
parent
fcbba3d948
commit
81a22dbd29
@ -35,16 +35,28 @@ namespace osu.Game.Online.Spectator
|
||||
/// </summary>
|
||||
public abstract IBindable<bool> IsConnected { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The states of all users currently being watched.
|
||||
/// </summary>
|
||||
public IBindableDictionary<int, SpectatorState> WatchingUserStates => watchingUserStates;
|
||||
|
||||
/// <summary>
|
||||
/// A global list of all players currently playing.
|
||||
/// </summary>
|
||||
public IBindableList<int> PlayingUsers => playingUsers;
|
||||
|
||||
/// <summary>
|
||||
/// All users currently being watched.
|
||||
/// </summary>
|
||||
private readonly List<int> watchingUsers = new List<int>();
|
||||
|
||||
public IBindableDictionary<int, SpectatorState> WatchingUserStates => watchingUserStates;
|
||||
private readonly BindableDictionary<int, SpectatorState> watchingUserStates = new BindableDictionary<int, SpectatorState>();
|
||||
private readonly BindableList<int> playingUsers = new BindableList<int>();
|
||||
private readonly SpectatorState currentState = new SpectatorState();
|
||||
|
||||
private IBeatmap? currentBeatmap;
|
||||
private Score? currentScore;
|
||||
|
||||
private readonly SpectatorState currentState = new SpectatorState();
|
||||
|
||||
/// <summary>
|
||||
/// Whether the local user is playing.
|
||||
/// </summary>
|
||||
@ -85,7 +97,10 @@ namespace osu.Game.Online.Spectator
|
||||
BeginPlayingInternal(currentState);
|
||||
}
|
||||
else
|
||||
{
|
||||
watchingUserStates.Clear();
|
||||
playingUsers.Clear();
|
||||
}
|
||||
}), true);
|
||||
}
|
||||
|
||||
@ -93,8 +108,12 @@ namespace osu.Game.Online.Spectator
|
||||
{
|
||||
Schedule(() =>
|
||||
{
|
||||
if (!playingUsers.Contains(userId))
|
||||
playingUsers.Add(userId);
|
||||
|
||||
if (watchingUsers.Contains(userId))
|
||||
watchingUserStates[userId] = state;
|
||||
|
||||
OnUserBeganPlaying?.Invoke(userId, state);
|
||||
});
|
||||
|
||||
@ -105,8 +124,11 @@ namespace osu.Game.Online.Spectator
|
||||
{
|
||||
Schedule(() =>
|
||||
{
|
||||
playingUsers.Remove(userId);
|
||||
|
||||
if (watchingUsers.Contains(userId))
|
||||
watchingUserStates[userId] = state;
|
||||
|
||||
OnUserFinishedPlaying?.Invoke(userId, state);
|
||||
});
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
// 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.Collections.Specialized;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using osu.Framework.Allocation;
|
||||
@ -22,7 +23,7 @@ namespace osu.Game.Overlays.Dashboard
|
||||
{
|
||||
internal class CurrentlyPlayingDisplay : CompositeDrawable
|
||||
{
|
||||
private readonly IBindableDictionary<int, SpectatorState> userStates = new BindableDictionary<int, SpectatorState>();
|
||||
private readonly IBindableList<int> playingUsers = new BindableList<int>();
|
||||
|
||||
private FillFlowContainer<PlayingUserPanel> userFlow;
|
||||
|
||||
@ -51,55 +52,46 @@ namespace osu.Game.Overlays.Dashboard
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
userStates.BindTo(spectatorClient.WatchingUserStates);
|
||||
userStates.BindCollectionChanged(onUserStatesChanged, true);
|
||||
playingUsers.BindTo(spectatorClient.PlayingUsers);
|
||||
playingUsers.BindCollectionChanged(onPlayingUsersChanged, true);
|
||||
}
|
||||
|
||||
private void onUserStatesChanged(object sender, NotifyDictionaryChangedEventArgs<int, SpectatorState> e) => Schedule(() =>
|
||||
private void onPlayingUsersChanged(object sender, NotifyCollectionChangedEventArgs e) => Schedule(() =>
|
||||
{
|
||||
switch (e.Action)
|
||||
{
|
||||
case NotifyDictionaryChangedAction.Add:
|
||||
case NotifyDictionaryChangedAction.Replace:
|
||||
case NotifyCollectionChangedAction.Add:
|
||||
Debug.Assert(e.NewItems != null);
|
||||
|
||||
foreach ((int userId, SpectatorState state) in e.NewItems)
|
||||
foreach (int userId in e.NewItems)
|
||||
{
|
||||
if (state.State != SpectatingUserState.Playing)
|
||||
{
|
||||
removePlayingUser(userId);
|
||||
continue;
|
||||
}
|
||||
|
||||
users.GetUserAsync(userId).ContinueWith(task =>
|
||||
{
|
||||
var user = task.GetResultSafely();
|
||||
|
||||
if (user != null)
|
||||
Schedule(() => addPlayingUser(user));
|
||||
{
|
||||
Schedule(() =>
|
||||
{
|
||||
// user may no longer be playing.
|
||||
if (!playingUsers.Contains(user.Id))
|
||||
return;
|
||||
|
||||
userFlow.Add(createUserPanel(user));
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case NotifyDictionaryChangedAction.Remove:
|
||||
case NotifyCollectionChangedAction.Remove:
|
||||
Debug.Assert(e.OldItems != null);
|
||||
|
||||
foreach ((int userId, _) in e.OldItems)
|
||||
removePlayingUser(userId);
|
||||
foreach (int userId in e.OldItems)
|
||||
userFlow.FirstOrDefault(card => card.User.Id == userId)?.Expire();
|
||||
break;
|
||||
}
|
||||
|
||||
void addPlayingUser(APIUser user)
|
||||
{
|
||||
// user may no longer be playing.
|
||||
if (!userStates.TryGetValue(user.Id, out var state2) || state2.State != SpectatingUserState.Playing)
|
||||
return;
|
||||
|
||||
userFlow.Add(createUserPanel(user));
|
||||
}
|
||||
|
||||
void removePlayingUser(int userId) => userFlow.FirstOrDefault(card => card.User.Id == userId)?.Expire();
|
||||
});
|
||||
|
||||
private PlayingUserPanel createUserPanel(APIUser user) =>
|
||||
|
Loading…
Reference in New Issue
Block a user