mirror of
https://github.com/osukey/osukey.git
synced 2025-07-02 08:49:59 +09:00
Fix frames potentially getting lost due to non-matching Schedule
usage
This commit is contained in:
@ -12,6 +12,7 @@ using osu.Framework.Allocation;
|
|||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Development;
|
using osu.Framework.Development;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Logging;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Online.API;
|
using osu.Game.Online.API;
|
||||||
using osu.Game.Replays.Legacy;
|
using osu.Game.Replays.Legacy;
|
||||||
@ -156,6 +157,8 @@ namespace osu.Game.Online.Spectator
|
|||||||
|
|
||||||
IsPlaying = true;
|
IsPlaying = true;
|
||||||
|
|
||||||
|
totalBundledFrames = 0;
|
||||||
|
|
||||||
// transfer state at point of beginning play
|
// transfer state at point of beginning play
|
||||||
currentState.BeatmapID = score.ScoreInfo.BeatmapInfo.OnlineID;
|
currentState.BeatmapID = score.ScoreInfo.BeatmapInfo.OnlineID;
|
||||||
currentState.RulesetID = score.ScoreInfo.RulesetID;
|
currentState.RulesetID = score.ScoreInfo.RulesetID;
|
||||||
@ -169,6 +172,21 @@ namespace osu.Game.Online.Spectator
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void HandleFrame(ReplayFrame frame) => Schedule(() =>
|
||||||
|
{
|
||||||
|
if (!IsPlaying)
|
||||||
|
{
|
||||||
|
Logger.Log($"Frames arrived at {nameof(SpectatorClient)} outside of gameplay scope and will be ignored.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (frame is IConvertibleReplayFrame convertible)
|
||||||
|
pendingFrames.Enqueue(convertible.ToLegacy(currentBeatmap));
|
||||||
|
|
||||||
|
if (pendingFrames.Count > max_pending_frames)
|
||||||
|
purgePendingFrames();
|
||||||
|
});
|
||||||
|
|
||||||
public void EndPlaying(GameplayState state)
|
public void EndPlaying(GameplayState state)
|
||||||
{
|
{
|
||||||
// This method is most commonly called via Dispose(), which is can be asynchronous (via the AsyncDisposalQueue).
|
// This method is most commonly called via Dispose(), which is can be asynchronous (via the AsyncDisposalQueue).
|
||||||
@ -236,6 +254,8 @@ namespace osu.Game.Online.Spectator
|
|||||||
|
|
||||||
private Task? lastSend;
|
private Task? lastSend;
|
||||||
|
|
||||||
|
private int totalBundledFrames;
|
||||||
|
|
||||||
private const int max_pending_frames = 30;
|
private const int max_pending_frames = 30;
|
||||||
|
|
||||||
protected override void Update()
|
protected override void Update()
|
||||||
@ -246,20 +266,6 @@ namespace osu.Game.Online.Spectator
|
|||||||
purgePendingFrames();
|
purgePendingFrames();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void HandleFrame(ReplayFrame frame)
|
|
||||||
{
|
|
||||||
Debug.Assert(ThreadSafety.IsUpdateThread);
|
|
||||||
|
|
||||||
if (!IsPlaying)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (frame is IConvertibleReplayFrame convertible)
|
|
||||||
pendingFrames.Enqueue(convertible.ToLegacy(currentBeatmap));
|
|
||||||
|
|
||||||
if (pendingFrames.Count > max_pending_frames)
|
|
||||||
purgePendingFrames();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void purgePendingFrames()
|
private void purgePendingFrames()
|
||||||
{
|
{
|
||||||
if (pendingFrames.Count == 0)
|
if (pendingFrames.Count == 0)
|
||||||
@ -270,6 +276,10 @@ namespace osu.Game.Online.Spectator
|
|||||||
var frames = pendingFrames.ToArray();
|
var frames = pendingFrames.ToArray();
|
||||||
var bundle = new FrameDataBundle(currentScore.ScoreInfo, frames);
|
var bundle = new FrameDataBundle(currentScore.ScoreInfo, frames);
|
||||||
|
|
||||||
|
totalBundledFrames += frames.Length;
|
||||||
|
|
||||||
|
Console.WriteLine($"Purging {pendingFrames.Count} frames (total {totalBundledFrames})");
|
||||||
|
|
||||||
pendingFrames.Clear();
|
pendingFrames.Clear();
|
||||||
lastPurgeTime = Time.Current;
|
lastPurgeTime = Time.Current;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user