1
0
mirror of https://github.com/ppy/osu.git synced 2025-02-21 20:12:57 +08:00

Fix initial playback states not being correct

This commit is contained in:
smoogipoo 2021-04-21 23:21:03 +09:00
parent f32d00c0d9
commit 2bea625613
4 changed files with 34 additions and 24 deletions

View File

@ -256,17 +256,10 @@ namespace osu.Game.Tests.Visual.Multiplayer
} }
private void checkPaused(int userId, bool state) => private void checkPaused(int userId, bool state) =>
AddUntilStep($"{userId} is {(state ? "paused" : "playing")}", () => getPlayer(userId).ChildrenOfType<GameplayClockContainer>().First().IsPaused.Value == state); AddUntilStep($"{userId} is {(state ? "paused" : "playing")}", () => getPlayer(userId).ChildrenOfType<GameplayClockContainer>().First().GameplayClock.IsRunning != state);
private void checkPausedInstant(int userId, bool state) => private void checkPausedInstant(int userId, bool state) =>
AddAssert($"{userId} is {(state ? "paused" : "playing")}", () => getPlayer(userId).ChildrenOfType<GameplayClockContainer>().First().IsPaused.Value == state); AddAssert($"{userId} is {(state ? "paused" : "playing")}", () => getPlayer(userId).ChildrenOfType<GameplayClockContainer>().First().GameplayClock.IsRunning != state);
/// <summary>
/// Returns time(user1) - time(user2).
/// </summary>
private double getGameplayOffset(int user1, int user2) => getGameplayTime(user1) - getGameplayTime(user2);
private double getGameplayTime(int userId) => getPlayer(userId).ChildrenOfType<GameplayClockContainer>().Single().GameplayClock.CurrentTime;
private Player getPlayer(int userId) => getInstance(userId).ChildrenOfType<Player>().Single(); private Player getPlayer(int userId) => getInstance(userId).ChildrenOfType<Player>().Single();

View File

@ -39,10 +39,12 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Spectate
private void load() private void load()
{ {
Container leaderboardContainer; Container leaderboardContainer;
masterClockContainer = new MasterGameplayClockContainer(Beatmap.Value, 0);
masterClockContainer = new MasterGameplayClockContainer(Beatmap.Value, 0) InternalChildren = new[]
{ {
Child = new GridContainer (Drawable)(syncManager = new CatchUpSyncManager(masterClockContainer)),
masterClockContainer.WithChild(new GridContainer
{ {
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
ColumnDimensions = new[] ColumnDimensions = new[]
@ -61,13 +63,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Spectate
grid = new PlayerGrid { RelativeSizeAxes = Axes.Both } grid = new PlayerGrid { RelativeSizeAxes = Axes.Both }
} }
} }
} })
};
InternalChildren = new[]
{
(Drawable)(syncManager = new CatchUpSyncManager(masterClockContainer)),
masterClockContainer
}; };
for (int i = 0; i < UserIds.Length; i++) for (int i = 0; i < UserIds.Length; i++)

View File

@ -2,6 +2,7 @@
// 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 osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Timing; using osu.Framework.Timing;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Scoring; using osu.Game.Scoring;
@ -12,22 +13,31 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Spectate
{ {
public class MultiplayerSpectatorPlayer : SpectatorPlayer public class MultiplayerSpectatorPlayer : SpectatorPlayer
{ {
private readonly ISlaveClock gameplayClock; private readonly Bindable<bool> waitingOnFrames = new Bindable<bool>(true);
private readonly Score score;
private readonly ISlaveClock slaveClock;
public MultiplayerSpectatorPlayer(Score score, ISlaveClock gameplayClock) public MultiplayerSpectatorPlayer(Score score, ISlaveClock slaveClock)
: base(score) : base(score)
{ {
this.gameplayClock = gameplayClock; this.score = score;
this.slaveClock = slaveClock;
} }
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load() private void load()
{ {
gameplayClock.WaitingOnFrames.BindTo(DrawableRuleset.FrameStableClock.WaitingOnFrames); slaveClock.WaitingOnFrames.BindTo(waitingOnFrames);
}
protected override void UpdateAfterChildren()
{
base.UpdateAfterChildren();
waitingOnFrames.Value = DrawableRuleset.FrameStableClock.WaitingOnFrames.Value || score.Replay.Frames.Count == 0;
} }
protected override GameplayClockContainer CreateGameplayClockContainer(WorkingBeatmap beatmap, double gameplayStart) protected override GameplayClockContainer CreateGameplayClockContainer(WorkingBeatmap beatmap, double gameplayStart)
=> new SubGameplayClockContainer(gameplayClock); => new SubGameplayClockContainer(slaveClock);
} }
public class SubGameplayClockContainer : GameplayClockContainer public class SubGameplayClockContainer : GameplayClockContainer
@ -37,6 +47,17 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Spectate
{ {
} }
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.
if (SourceClock.IsRunning)
Start();
else
Stop();
base.Update();
}
protected override GameplayClock CreateGameplayClock(IFrameBasedClock source) => new GameplayClock(source); protected override GameplayClock CreateGameplayClock(IFrameBasedClock source) => new GameplayClock(source);
} }
} }

View File

@ -74,7 +74,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Spectate.Sync
public FrameTimeInfo TimeInfo => new FrameTimeInfo { Elapsed = ElapsedFrameTime, Current = CurrentTime }; public FrameTimeInfo TimeInfo => new FrameTimeInfo { Elapsed = ElapsedFrameTime, Current = CurrentTime };
public IBindable<bool> WaitingOnFrames { get; } = new Bindable<bool>(); public IBindable<bool> WaitingOnFrames { get; } = new Bindable<bool>(true);
public bool IsCatchingUp { get; set; } public bool IsCatchingUp { get; set; }
} }