Merge branch 'spectator-replay-watcher' into spectator-listing

This commit is contained in:
Dean Herbert 2020-10-28 23:17:50 +09:00
commit e1bf751dac
2 changed files with 60 additions and 21 deletions

View File

@ -36,19 +36,29 @@ namespace osu.Game.Tests.Visual.Gameplay
private int nextFrame; private int nextFrame;
private BeatmapSetInfo importedBeatmap;
private int importedBeatmapId;
public override void SetUpSteps() public override void SetUpSteps()
{ {
base.SetUpSteps(); base.SetUpSteps();
AddStep("reset sent frames", () => nextFrame = 0); AddStep("reset sent frames", () => nextFrame = 0);
AddStep("import beatmap", () => ImportBeatmapTest.LoadOszIntoOsu(game, virtualTrack: true).Wait()); AddStep("import beatmap", () =>
{
importedBeatmap = ImportBeatmapTest.LoadOszIntoOsu(game, virtualTrack: true).Result;
importedBeatmapId = importedBeatmap.Beatmaps.First(b => b.RulesetID == 0).OnlineBeatmapID ?? -1;
});
AddStep("add streaming client", () => AddStep("add streaming client", () =>
{ {
Remove(testSpectatorStreamingClient); Remove(testSpectatorStreamingClient);
Add(testSpectatorStreamingClient); Add(testSpectatorStreamingClient);
}); });
finish();
} }
private OsuFramedReplayInputHandler replayHandler => private OsuFramedReplayInputHandler replayHandler =>
@ -86,7 +96,7 @@ namespace osu.Game.Tests.Visual.Gameplay
start(); start();
waitForPlayer(); waitForPlayer();
AddUntilStep("game is paused", () => player.ChildrenOfType<DrawableRuleset>().First().IsPaused.Value); checkPaused(true);
sendFrames(); sendFrames();
@ -115,6 +125,7 @@ namespace osu.Game.Tests.Visual.Gameplay
start(); start();
sendFrames(); sendFrames();
start(); start();
sendFrames(); sendFrames();
} }
@ -125,8 +136,13 @@ namespace osu.Game.Tests.Visual.Gameplay
loadSpectatingScreen(); loadSpectatingScreen();
start(); start();
sendFrames();
waitForPlayer();
checkPaused(true);
finish();
checkPaused(false);
// TODO: should replay until running out of frames then fail // TODO: should replay until running out of frames then fail
} }
@ -149,7 +165,7 @@ namespace osu.Game.Tests.Visual.Gameplay
{ {
loadSpectatingScreen(); loadSpectatingScreen();
start(88); start(-1234);
sendFrames(); sendFrames();
AddAssert("screen didn't change", () => Stack.CurrentScreen is Spectator); AddAssert("screen didn't change", () => Stack.CurrentScreen is Spectator);
@ -157,10 +173,12 @@ namespace osu.Game.Tests.Visual.Gameplay
private void waitForPlayer() => AddUntilStep("wait for player", () => Stack.CurrentScreen is Player); private void waitForPlayer() => AddUntilStep("wait for player", () => Stack.CurrentScreen is Player);
private void start(int? beatmapId = null) => AddStep("start play", () => testSpectatorStreamingClient.StartPlay(beatmapId)); private void start(int? beatmapId = null) => AddStep("start play", () => testSpectatorStreamingClient.StartPlay(beatmapId ?? importedBeatmapId));
private void finish(int? beatmapId = null) => AddStep("end play", () => testSpectatorStreamingClient.EndPlay(beatmapId ?? importedBeatmapId));
private void checkPaused(bool state) => private void checkPaused(bool state) =>
AddAssert($"game is {(state ? "paused" : "playing")}", () => player.ChildrenOfType<DrawableRuleset>().First().IsPaused.Value == state); AddUntilStep($"game is {(state ? "paused" : "playing")}", () => player.ChildrenOfType<DrawableRuleset>().First().IsPaused.Value == state);
private void sendFrames(int count = 10) private void sendFrames(int count = 10)
{ {
@ -179,20 +197,25 @@ namespace osu.Game.Tests.Visual.Gameplay
internal class TestSpectatorStreamingClient : SpectatorStreamingClient internal class TestSpectatorStreamingClient : SpectatorStreamingClient
{ {
[Resolved]
private BeatmapManager beatmaps { get; set; }
public readonly User StreamingUser = new User { Id = 1234, Username = "Test user" }; public readonly User StreamingUser = new User { Id = 1234, Username = "Test user" };
public void StartPlay(int? beatmapId = null) => sendState(beatmapId); private int beatmapId;
public void EndPlay() public void StartPlay(int beatmapId)
{
this.beatmapId = beatmapId;
sendState(beatmapId);
}
public void EndPlay(int beatmapId)
{ {
((ISpectatorClient)this).UserFinishedPlaying((int)StreamingUser.Id, new SpectatorState ((ISpectatorClient)this).UserFinishedPlaying((int)StreamingUser.Id, new SpectatorState
{ {
BeatmapID = beatmaps.GetAllUsableBeatmapSets().First().Beatmaps.First(b => b.RulesetID == 0).OnlineBeatmapID, BeatmapID = beatmapId,
RulesetID = 0, RulesetID = 0,
}); });
sentState = false;
} }
private bool sentState; private bool sentState;
@ -212,7 +235,7 @@ namespace osu.Game.Tests.Visual.Gameplay
((ISpectatorClient)this).UserSentFrames((int)StreamingUser.Id, bundle); ((ISpectatorClient)this).UserSentFrames((int)StreamingUser.Id, bundle);
if (!sentState) if (!sentState)
sendState(); sendState(beatmapId);
} }
public override void WatchUser(int userId) public override void WatchUser(int userId)
@ -220,18 +243,18 @@ namespace osu.Game.Tests.Visual.Gameplay
if (sentState) if (sentState)
{ {
// usually the server would do this. // usually the server would do this.
sendState(); sendState(beatmapId);
} }
base.WatchUser(userId); base.WatchUser(userId);
} }
private void sendState(int? beatmapId = null) private void sendState(int beatmapId)
{ {
sentState = true; sentState = true;
((ISpectatorClient)this).UserBeganPlaying((int)StreamingUser.Id, new SpectatorState ((ISpectatorClient)this).UserBeganPlaying((int)StreamingUser.Id, new SpectatorState
{ {
BeatmapID = beatmapId ?? beatmaps.GetAllUsableBeatmapSets().First().Beatmaps.First(b => b.RulesetID == 0).OnlineBeatmapID, BeatmapID = beatmapId,
RulesetID = 0, RulesetID = 0,
}); });
} }

View File

@ -76,6 +76,11 @@ namespace osu.Game.Screens.Play
private BeatmapSetInfo onlineBeatmap; private BeatmapSetInfo onlineBeatmap;
/// <summary>
/// Becomes true if a new state is waiting to be loaded (while this screen was not active).
/// </summary>
private bool newStatePending;
public Spectator([NotNull] User targetUser) public Spectator([NotNull] User targetUser)
{ {
this.targetUser = targetUser ?? throw new ArgumentNullException(nameof(targetUser)); this.targetUser = targetUser ?? throw new ArgumentNullException(nameof(targetUser));
@ -218,11 +223,23 @@ namespace osu.Game.Screens.Play
if (userId != targetUser.Id) if (userId != targetUser.Id)
return; return;
replay ??= new Replay { HasReceivedAllFrames = false };
this.state = state; this.state = state;
if (this.IsCurrentScreen())
Schedule(attemptStart); Schedule(attemptStart);
else
newStatePending = true;
}
public override void OnResuming(IScreen last)
{
base.OnResuming(last);
if (newStatePending)
{
attemptStart();
newStatePending = false;
}
} }
private void userFinishedPlaying(int userId, SpectatorState state) private void userFinishedPlaying(int userId, SpectatorState state)
@ -266,8 +283,7 @@ namespace osu.Game.Screens.Play
return; return;
} }
if (replay == null) replay ??= new Replay { HasReceivedAllFrames = false };
return;
var scoreInfo = new ScoreInfo var scoreInfo = new ScoreInfo
{ {