1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-28 04:02:57 +08:00

Xmldocs and general refactorings

This commit is contained in:
smoogipoo 2021-04-22 23:52:22 +09:00
parent ee25949751
commit 4f0857f946
6 changed files with 59 additions and 15 deletions

View File

@ -299,7 +299,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
private Player getPlayer(int userId) => getInstance(userId).ChildrenOfType<Player>().Single();
private PlayerInstance getInstance(int userId) => spectatorScreen.ChildrenOfType<PlayerInstance>().Single(p => p.UserId == userId);
private PlayerArea getInstance(int userId) => spectatorScreen.ChildrenOfType<PlayerArea>().Single(p => p.UserId == userId);
public class TestSpectatorStreamingClient : SpectatorStreamingClient
{

View File

@ -11,7 +11,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Spectate
{
public class MultiSpectatorLeaderboard : MultiplayerGameplayLeaderboard
{
public MultiSpectatorLeaderboard(ScoreProcessor scoreProcessor, int[] userIds)
public MultiSpectatorLeaderboard([NotNull] ScoreProcessor scoreProcessor, int[] userIds)
: base(scoreProcessor, userIds)
{
}

View File

@ -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 JetBrains.Annotations;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Timing;
@ -11,13 +12,21 @@ using osu.Game.Screens.Play;
namespace osu.Game.Screens.OnlinePlay.Multiplayer.Spectate
{
/// <summary>
/// A single spectated player within a <see cref="MultiSpectatorScreen"/>.
/// </summary>
public class MultiSpectatorPlayer : SpectatorPlayer
{
private readonly Bindable<bool> waitingOnFrames = new Bindable<bool>(true);
private readonly Score score;
private readonly ISlaveClock slaveClock;
public MultiSpectatorPlayer(Score score, ISlaveClock slaveClock)
/// <summary>
/// Creates a new <see cref="MultiSpectatorPlayer"/>.
/// </summary>
/// <param name="score">The score containing the player's replay.</param>
/// <param name="slaveClock">The clock controlling the gameplay running state.</param>
public MultiSpectatorPlayer([NotNull] Score score, [NotNull] ISlaveClock slaveClock)
: base(score)
{
this.score = score;
@ -33,6 +42,8 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Spectate
protected override void UpdateAfterChildren()
{
base.UpdateAfterChildren();
// This is required because the frame stable clock is set to WaitingOnFrames = false for one frame.
waitingOnFrames.Value = DrawableRuleset.FrameStableClock.WaitingOnFrames.Value || score.Replay.Frames.Count == 0;
}
@ -41,14 +52,14 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Spectate
private class SlaveGameplayClockContainer : GameplayClockContainer
{
public SlaveGameplayClockContainer(IClock sourceClock)
public SlaveGameplayClockContainer([NotNull] IClock sourceClock)
: base(sourceClock)
{
}
protected override void Update()
{
// The slave clock's running state is controlled by the sync manager, but the local pausing state needs to be updated to stop gameplay.
// The slave clock's running state is controlled externally, but the local pausing state needs to be updated to stop gameplay.
if (SourceClock.IsRunning)
Start();
else

View File

@ -2,15 +2,19 @@
// See the LICENCE file in the repository root for full licence text.
using System;
using JetBrains.Annotations;
using osu.Game.Scoring;
using osu.Game.Screens.Menu;
using osu.Game.Screens.Play;
namespace osu.Game.Screens.OnlinePlay.Multiplayer.Spectate
{
/// <summary>
/// Used to load a single <see cref="MultiSpectatorPlayer"/> in a <see cref="MultiSpectatorScreen"/>.
/// </summary>
public class MultiSpectatorPlayerLoader : SpectatorPlayerLoader
{
public MultiSpectatorPlayerLoader(Score score, Func<MultiSpectatorPlayer> createPlayer)
public MultiSpectatorPlayerLoader([NotNull] Score score, [NotNull] Func<MultiSpectatorPlayer> createPlayer)
: base(score, createPlayer)
{
}

View File

@ -14,27 +14,37 @@ using osu.Game.Screens.Spectate;
namespace osu.Game.Screens.OnlinePlay.Multiplayer.Spectate
{
/// <summary>
/// A <see cref="SpectatorScreen"/> that spectates multiple users in a match.
/// </summary>
public class MultiSpectatorScreen : SpectatorScreen
{
// Isolates beatmap/ruleset to this screen.
public override bool DisallowExternalBeatmapRulesetChanges => true;
/// <summary>
/// Whether all spectating players have finished loading.
/// </summary>
public bool AllPlayersLoaded => instances.All(p => p?.PlayerLoaded == true);
[Resolved]
private SpectatorStreamingClient spectatorClient { get; set; }
private readonly PlayerInstance[] instances;
private readonly PlayerArea[] instances;
private MasterGameplayClockContainer masterClockContainer;
private ISyncManager syncManager;
private PlayerGrid grid;
private MultiSpectatorLeaderboard leaderboard;
private PlayerInstance currentAudioSource;
private PlayerArea currentAudioSource;
/// <summary>
/// Creates a new <see cref="MultiSpectatorScreen"/>.
/// </summary>
/// <param name="userIds">The players to spectate.</param>
public MultiSpectatorScreen(int[] userIds)
: base(userIds.AsSpan().Slice(0, Math.Min(16, userIds.Length)).ToArray())
{
instances = new PlayerInstance[UserIds.Length];
instances = new PlayerArea[UserIds.Length];
}
[BackgroundDependencyLoader]
@ -69,7 +79,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Spectate
};
for (int i = 0; i < UserIds.Length; i++)
grid.Add(instances[i] = new PlayerInstance(UserIds[i], new CatchUpSlaveClock(masterClockContainer.GameplayClock)));
grid.Add(instances[i] = new PlayerArea(UserIds[i], new CatchUpSlaveClock(masterClockContainer.GameplayClock)));
// Todo: This is not quite correct - it should be per-user to adjust for other mod combinations.
var playableBeatmap = Beatmap.Value.GetPlayableBeatmap(Ruleset.Value);

View File

@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
using JetBrains.Annotations;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Bindables;
@ -18,13 +19,31 @@ using osu.Game.Screens.Play;
namespace osu.Game.Screens.OnlinePlay.Multiplayer.Spectate
{
public class PlayerInstance : CompositeDrawable, IAdjustableAudioComponent
/// <summary>
/// Provides an area for and manages the hierarchy of a spectated player within a <see cref="MultiSpectatorScreen"/>.
/// </summary>
public class PlayerArea : CompositeDrawable, IAdjustableAudioComponent
{
/// <summary>
/// Whether a <see cref="Player"/> is loaded in the area.
/// </summary>
public bool PlayerLoaded => stack?.CurrentScreen is Player;
/// <summary>
/// The user id this <see cref="PlayerArea"/> corresponds to.
/// </summary>
public readonly int UserId;
public readonly CatchUpSlaveClock GameplayClock;
/// <summary>
/// The <see cref="ISlaveClock"/> used to control the gameplay running state of a loaded <see cref="Player"/>.
/// </summary>
[NotNull]
public readonly ISlaveClock GameplayClock;
/// <summary>
/// The currently-loaded score.
/// </summary>
[CanBeNull]
public Score Score { get; private set; }
[Resolved]
@ -35,7 +54,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Spectate
private readonly AudioContainer audioContainer;
private OsuScreenStack stack;
public PlayerInstance(int userId, CatchUpSlaveClock gameplayClock)
public PlayerArea(int userId, [NotNull] ISlaveClock gameplayClock)
{
UserId = userId;
GameplayClock = gameplayClock;
@ -54,10 +73,10 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Spectate
};
}
public void LoadScore(Score score)
public void LoadScore([NotNull] Score score)
{
if (Score != null)
throw new InvalidOperationException($"Cannot load a new score on a {nameof(PlayerInstance)} with an existing score.");
throw new InvalidOperationException($"Cannot load a new score on a {nameof(PlayerArea)} that has an existing score.");
Score = score;