1
0
mirror of https://github.com/ppy/osu.git synced 2024-12-14 20:03:22 +08:00

Make GameplayClockContainer non-abstract and use in MultiSpectatorPlayer

This commit is contained in:
Dean Herbert 2022-08-15 16:56:16 +09:00
parent 95c1b488a7
commit 224f3eaa84
2 changed files with 19 additions and 32 deletions

View File

@ -1,12 +1,8 @@
// 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.
#nullable disable
using JetBrains.Annotations;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Bindables; using osu.Framework.Bindables;
using osu.Framework.Timing;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Scoring; using osu.Game.Scoring;
using osu.Game.Screens.Play; using osu.Game.Screens.Play;
@ -26,7 +22,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Spectate
/// </summary> /// </summary>
/// <param name="score">The score containing the player's replay.</param> /// <param name="score">The score containing the player's replay.</param>
/// <param name="spectatorPlayerClock">The clock controlling the gameplay running state.</param> /// <param name="spectatorPlayerClock">The clock controlling the gameplay running state.</param>
public MultiSpectatorPlayer([NotNull] Score score, [NotNull] ISpectatorPlayerClock spectatorPlayerClock) public MultiSpectatorPlayer(Score score, ISpectatorPlayerClock spectatorPlayerClock)
: base(score, new PlayerConfiguration { AllowUserInteraction = false }) : base(score, new PlayerConfiguration { AllowUserInteraction = false })
{ {
this.spectatorPlayerClock = spectatorPlayerClock; this.spectatorPlayerClock = spectatorPlayerClock;
@ -41,6 +37,19 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Spectate
HUDOverlay.HoldToQuit.Expire(); HUDOverlay.HoldToQuit.Expire();
} }
protected override void Update()
{
// The player clock's running state is controlled externally, but the local pausing state needs to be updated to start/stop gameplay.
CatchUpSpectatorPlayerClock catchUpClock = (CatchUpSpectatorPlayerClock)GameplayClockContainer.SourceClock;
if (catchUpClock.IsRunning)
GameplayClockContainer.Start();
else
GameplayClockContainer.Stop();
base.Update();
}
protected override void UpdateAfterChildren() protected override void UpdateAfterChildren()
{ {
base.UpdateAfterChildren(); base.UpdateAfterChildren();
@ -50,28 +59,6 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Spectate
} }
protected override GameplayClockContainer CreateGameplayClockContainer(WorkingBeatmap beatmap, double gameplayStart) protected override GameplayClockContainer CreateGameplayClockContainer(WorkingBeatmap beatmap, double gameplayStart)
=> new SpectatorGameplayClockContainer(spectatorPlayerClock); => new GameplayClockContainer(spectatorPlayerClock);
private class SpectatorGameplayClockContainer : GameplayClockContainer
{
public SpectatorGameplayClockContainer([NotNull] IClock sourceClock)
: base(sourceClock)
{
}
protected override void Update()
{
// The SourceClock here is always a CatchUpSpectatorPlayerClock.
// The player clock's running state is controlled externally, but the local pausing state needs to be updated to stop gameplay.
if (SourceClock.IsRunning)
Start();
else
Stop();
base.Update();
}
protected override GameplayClock CreateGameplayClock(IFrameBasedClock source) => new GameplayClock(source);
}
} }
} }

View File

@ -16,7 +16,7 @@ namespace osu.Game.Screens.Play
/// <summary> /// <summary>
/// Encapsulates gameplay timing logic and provides a <see cref="GameplayClock"/> via DI for gameplay components to use. /// Encapsulates gameplay timing logic and provides a <see cref="GameplayClock"/> via DI for gameplay components to use.
/// </summary> /// </summary>
public abstract class GameplayClockContainer : Container, IAdjustableClock public class GameplayClockContainer : Container, IAdjustableClock
{ {
/// <summary> /// <summary>
/// The final clock which is exposed to gameplay components. /// The final clock which is exposed to gameplay components.
@ -36,7 +36,7 @@ namespace osu.Game.Screens.Play
/// <summary> /// <summary>
/// The source clock. /// The source clock.
/// </summary> /// </summary>
protected IClock SourceClock { get; private set; } public IClock SourceClock { get; private set; }
/// <summary> /// <summary>
/// Invoked when a seek has been performed via <see cref="Seek"/> /// Invoked when a seek has been performed via <see cref="Seek"/>
@ -68,7 +68,7 @@ namespace osu.Game.Screens.Play
/// Creates a new <see cref="GameplayClockContainer"/>. /// Creates a new <see cref="GameplayClockContainer"/>.
/// </summary> /// </summary>
/// <param name="sourceClock">The source <see cref="IClock"/> used for timing.</param> /// <param name="sourceClock">The source <see cref="IClock"/> used for timing.</param>
protected GameplayClockContainer(IClock sourceClock) public GameplayClockContainer(IClock sourceClock)
{ {
SourceClock = sourceClock; SourceClock = sourceClock;
@ -193,7 +193,7 @@ namespace osu.Game.Screens.Play
/// </remarks> /// </remarks>
/// <param name="source">The <see cref="IFrameBasedClock"/> providing the source time.</param> /// <param name="source">The <see cref="IFrameBasedClock"/> providing the source time.</param>
/// <returns>The final <see cref="GameplayClock"/>.</returns> /// <returns>The final <see cref="GameplayClock"/>.</returns>
protected abstract GameplayClock CreateGameplayClock(IFrameBasedClock source); protected virtual GameplayClock CreateGameplayClock(IFrameBasedClock source) => new GameplayClock(source);
#region IAdjustableClock #region IAdjustableClock