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.
// See the LICENCE file in the repository root for full licence text.
#nullable disable
using JetBrains.Annotations;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Timing;
using osu.Game.Beatmaps;
using osu.Game.Scoring;
using osu.Game.Screens.Play;
@ -26,7 +22,7 @@ public class MultiSpectatorPlayer : SpectatorPlayer
/// </summary>
/// <param name="score">The score containing the player's replay.</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 })
{
this.spectatorPlayerClock = spectatorPlayerClock;
@ -41,6 +37,19 @@ private void load()
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()
{
base.UpdateAfterChildren();
@ -50,28 +59,6 @@ protected override void UpdateAfterChildren()
}
protected override GameplayClockContainer CreateGameplayClockContainer(WorkingBeatmap beatmap, double gameplayStart)
=> new SpectatorGameplayClockContainer(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);
}
=> new GameplayClockContainer(spectatorPlayerClock);
}
}

View File

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