mirror of
https://github.com/ppy/osu.git
synced 2025-02-22 05:23:05 +08:00
Fix various data races causing crashes or incorrect leaderboard states
This commit is contained in:
parent
f59eef072d
commit
1b9d54a6ad
@ -39,8 +39,9 @@ namespace osu.Game.Screens.Select.Leaderboards
|
|||||||
|
|
||||||
private readonly LoadingAnimation loading;
|
private readonly LoadingAnimation loading;
|
||||||
|
|
||||||
private IEnumerable<Score> scores;
|
private ScheduledDelegate showScoresDelegate;
|
||||||
|
|
||||||
|
private IEnumerable<Score> scores;
|
||||||
public IEnumerable<Score> Scores
|
public IEnumerable<Score> Scores
|
||||||
{
|
{
|
||||||
get { return scores; }
|
get { return scores; }
|
||||||
@ -59,22 +60,28 @@ namespace osu.Game.Screens.Select.Leaderboards
|
|||||||
// ensure placeholder is hidden when displaying scores
|
// ensure placeholder is hidden when displaying scores
|
||||||
PlaceholderState = PlaceholderState.Successful;
|
PlaceholderState = PlaceholderState.Successful;
|
||||||
|
|
||||||
// schedule because we may not be loaded yet (LoadComponentAsync complains).
|
var flow = scrollFlow = new FillFlowContainer<LeaderboardScore>
|
||||||
Schedule(() =>
|
|
||||||
{
|
|
||||||
LoadComponentAsync(new FillFlowContainer<LeaderboardScore>
|
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.X,
|
RelativeSizeAxes = Axes.X,
|
||||||
AutoSizeAxes = Axes.Y,
|
AutoSizeAxes = Axes.Y,
|
||||||
Spacing = new Vector2(0f, 5f),
|
Spacing = new Vector2(0f, 5f),
|
||||||
Padding = new MarginPadding { Top = 10, Bottom = 5 },
|
Padding = new MarginPadding { Top = 10, Bottom = 5 },
|
||||||
ChildrenEnumerable = scores.Select((s, index) => new LeaderboardScore(s, index + 1) { Action = () => ScoreSelected?.Invoke(s) })
|
ChildrenEnumerable = scores.Select((s, index) => new LeaderboardScore(s, index + 1) { Action = () => ScoreSelected?.Invoke(s) })
|
||||||
}, f =>
|
};
|
||||||
|
|
||||||
|
// schedule because we may not be loaded yet (LoadComponentAsync complains).
|
||||||
|
showScoresDelegate?.Cancel();
|
||||||
|
if (!IsLoaded)
|
||||||
|
showScoresDelegate = Schedule(showScores);
|
||||||
|
else
|
||||||
|
showScores();
|
||||||
|
|
||||||
|
void showScores() => LoadComponentAsync(flow, _ =>
|
||||||
{
|
{
|
||||||
scrollContainer.Add(scrollFlow = f);
|
scrollContainer.Add(flow);
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
foreach (var s in f.Children)
|
foreach (var s in flow.Children)
|
||||||
{
|
{
|
||||||
using (s.BeginDelayedSequence(i++ * 50, true))
|
using (s.BeginDelayedSequence(i++ * 50, true))
|
||||||
s.Show();
|
s.Show();
|
||||||
@ -82,7 +89,6 @@ namespace osu.Game.Screens.Select.Leaderboards
|
|||||||
|
|
||||||
scrollContainer.ScrollTo(0f, false);
|
scrollContainer.ScrollTo(0f, false);
|
||||||
});
|
});
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -249,24 +255,31 @@ namespace osu.Game.Screens.Select.Leaderboards
|
|||||||
PlaceholderState = PlaceholderState.Retrieving;
|
PlaceholderState = PlaceholderState.Retrieving;
|
||||||
loading.Show();
|
loading.Show();
|
||||||
|
|
||||||
|
var localBeatmap = Beatmap;
|
||||||
|
|
||||||
getScoresRequest = new GetScoresRequest(Beatmap, osuGame?.Ruleset.Value ?? Beatmap.Ruleset, Scope);
|
getScoresRequest = new GetScoresRequest(Beatmap, osuGame?.Ruleset.Value ?? Beatmap.Ruleset, Scope);
|
||||||
getScoresRequest.Success += r =>
|
getScoresRequest.Success += r => Schedule(() =>
|
||||||
{
|
{
|
||||||
|
if (localBeatmap != Beatmap)
|
||||||
|
return;
|
||||||
|
|
||||||
Scores = r.Scores;
|
Scores = r.Scores;
|
||||||
PlaceholderState = Scores.Any() ? PlaceholderState.Successful : PlaceholderState.NoScores;
|
PlaceholderState = Scores.Any() ? PlaceholderState.Successful : PlaceholderState.NoScores;
|
||||||
};
|
});
|
||||||
getScoresRequest.Failure += onUpdateFailed;
|
|
||||||
|
|
||||||
api.Queue(getScoresRequest);
|
getScoresRequest.Failure += e => Schedule(() =>
|
||||||
}
|
|
||||||
|
|
||||||
private void onUpdateFailed(Exception e)
|
|
||||||
{
|
{
|
||||||
|
if (localBeatmap != Beatmap)
|
||||||
|
return;
|
||||||
|
|
||||||
if (e is OperationCanceledException)
|
if (e is OperationCanceledException)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
PlaceholderState = PlaceholderState.NetworkFailure;
|
PlaceholderState = PlaceholderState.NetworkFailure;
|
||||||
Logger.Error(e, @"Couldn't fetch beatmap scores!");
|
Logger.Error(e, @"Couldn't fetch beatmap scores!");
|
||||||
|
});
|
||||||
|
|
||||||
|
api.Queue(getScoresRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void replacePlaceholder(Placeholder placeholder)
|
private void replacePlaceholder(Placeholder placeholder)
|
||||||
|
Loading…
Reference in New Issue
Block a user