Give SpectatorState a user state

This commit is contained in:
Dan Balasescu 2022-02-01 15:51:41 +09:00
parent 38e075c522
commit 41007169f7
6 changed files with 52 additions and 6 deletions

View File

@ -211,7 +211,7 @@ namespace osu.Game.Tests.Visual.Gameplay
AddStep("send frames and finish play", () =>
{
spectatorClient.HandleFrame(new OsuReplayFrame(1000, Vector2.Zero));
spectatorClient.EndPlaying();
spectatorClient.EndPlaying(new GameplayState(new TestBeatmap(new OsuRuleset().RulesetInfo), new OsuRuleset()) { HasPassed = true });
});
// We can't access API because we're an "online" test.

View File

@ -0,0 +1,33 @@
// 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.
namespace osu.Game.Online.Spectator
{
public enum SpectatingUserState
{
/// <summary>
/// The spectated user has not yet played.
/// </summary>
Idle,
/// <summary>
/// The spectated user is currently playing.
/// </summary>
Playing,
/// <summary>
/// The spectated user has successfully completed gameplay.
/// </summary>
Completed,
/// <summary>
/// The spectator user has failed during gameplay.
/// </summary>
Failed,
/// <summary>
/// The spectated user has quit during gameplay.
/// </summary>
Quit
}
}

View File

@ -138,6 +138,7 @@ namespace osu.Game.Online.Spectator
currentState.BeatmapID = score.ScoreInfo.BeatmapInfo.OnlineID;
currentState.RulesetID = score.ScoreInfo.RulesetID;
currentState.Mods = score.ScoreInfo.Mods.Select(m => new APIMod(m)).ToArray();
currentState.State = SpectatingUserState.Playing;
currentBeatmap = state.Beatmap;
currentScore = score;
@ -148,7 +149,7 @@ namespace osu.Game.Online.Spectator
public void SendFrames(FrameDataBundle data) => lastSend = SendFramesInternal(data);
public void EndPlaying()
public void EndPlaying(GameplayState state)
{
// This method is most commonly called via Dispose(), which is can be asynchronous (via the AsyncDisposalQueue).
// We probably need to find a better way to handle this...
@ -163,6 +164,13 @@ namespace osu.Game.Online.Spectator
IsPlaying = false;
currentBeatmap = null;
if (state.HasPassed)
currentState.State = SpectatingUserState.Completed;
else if (state.HasFailed)
currentState.State = SpectatingUserState.Failed;
else
currentState.State = SpectatingUserState.Quit;
EndPlayingInternal(currentState);
});
}

View File

@ -24,14 +24,17 @@ namespace osu.Game.Online.Spectator
[Key(2)]
public IEnumerable<APIMod> Mods { get; set; } = Enumerable.Empty<APIMod>();
[Key(3)]
public SpectatingUserState State { get; set; }
public bool Equals(SpectatorState other)
{
if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;
return BeatmapID == other.BeatmapID && Mods.SequenceEqual(other.Mods) && RulesetID == other.RulesetID;
return BeatmapID == other.BeatmapID && Mods.SequenceEqual(other.Mods) && RulesetID == other.RulesetID && State == other.State;
}
public override string ToString() => $"Beatmap:{BeatmapID} Mods:{string.Join(',', Mods)} Ruleset:{RulesetID}";
public override string ToString() => $"Beatmap:{BeatmapID} Mods:{string.Join(',', Mods)} Ruleset:{RulesetID} State:{State}";
}
}

View File

@ -55,7 +55,9 @@ namespace osu.Game.Rulesets.UI
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
spectatorClient?.EndPlaying();
if (spectatorClient != null && gameplayState != null)
spectatorClient.EndPlaying(gameplayState);
}
protected override void Update()

View File

@ -1000,7 +1000,7 @@ namespace osu.Game.Screens.Play
// EndPlaying() is typically called from ReplayRecorder.Dispose(). Disposal is currently asynchronous.
// To resolve test failures, forcefully end playing synchronously when this screen exits.
// Todo: Replace this with a more permanent solution once osu-framework has a synchronous cleanup method.
spectatorClient.EndPlaying();
spectatorClient.EndPlaying(GameplayState);
// GameplayClockContainer performs seeks / start / stop operations on the beatmap's track.
// as we are no longer the current screen, we cannot guarantee the track is still usable.