mirror of
https://github.com/ppy/osu.git
synced 2024-11-11 15:07:44 +08:00
Remove fetch callback logic completely
This commit is contained in:
parent
13f445ddd5
commit
3d59bab7c6
@ -3,12 +3,11 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using JetBrains.Annotations;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Development;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Colour;
|
||||
@ -178,9 +177,9 @@ namespace osu.Game.Online.Leaderboards
|
||||
/// <summary>
|
||||
/// Performs a fetch/refresh of scores to be displayed.
|
||||
/// </summary>
|
||||
/// <param name="scoresCallback">A callback which should be called when fetching is completed. Scheduling is not required.</param>
|
||||
/// <returns>An <see cref="APIRequest"/> responsible for the fetch operation. This will be queued and performed automatically.</returns>
|
||||
protected abstract APIRequest FetchScores(Action<IEnumerable<TScoreInfo>> scoresCallback);
|
||||
[CanBeNull]
|
||||
protected abstract APIRequest FetchScores();
|
||||
|
||||
protected abstract LeaderboardScore CreateDrawableScore(TScoreInfo model, int index);
|
||||
|
||||
@ -193,11 +192,7 @@ namespace osu.Game.Online.Leaderboards
|
||||
PlaceholderState = PlaceholderState.Retrieving;
|
||||
loading.Show();
|
||||
|
||||
getScoresRequest = FetchScores(scores => getScoresRequestCallback = Schedule(() =>
|
||||
{
|
||||
Scores = scores.ToArray();
|
||||
PlaceholderState = Scores.Any() ? PlaceholderState.Successful : PlaceholderState.NoScores;
|
||||
}));
|
||||
getScoresRequest = FetchScores();
|
||||
|
||||
if (getScoresRequest == null)
|
||||
return;
|
||||
@ -240,11 +235,6 @@ namespace osu.Game.Online.Leaderboards
|
||||
get => placeholderState;
|
||||
set
|
||||
{
|
||||
if (value != PlaceholderState.Successful)
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
|
||||
if (value == placeholderState)
|
||||
return;
|
||||
|
||||
@ -284,10 +274,8 @@ namespace osu.Game.Online.Leaderboards
|
||||
}
|
||||
}
|
||||
|
||||
private void updateScoresDrawables()
|
||||
private void updateScoresDrawables() => Scheduler.Add(() =>
|
||||
{
|
||||
Debug.Assert(ThreadSafety.IsUpdateThread);
|
||||
|
||||
scrollFlow?.FadeOut(fade_duration, Easing.OutQuint).Expire();
|
||||
scrollFlow = null;
|
||||
|
||||
@ -296,6 +284,7 @@ namespace osu.Game.Online.Leaderboards
|
||||
if (scores?.Any() != true)
|
||||
{
|
||||
loading.Hide();
|
||||
PlaceholderState = PlaceholderState.NoScores;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -327,7 +316,7 @@ namespace osu.Game.Online.Leaderboards
|
||||
scrollContainer.ScrollToStart(false);
|
||||
loading.Hide();
|
||||
}, (showScoresCancellationSource = new CancellationTokenSource()).Token);
|
||||
}
|
||||
}, false);
|
||||
|
||||
private void replacePlaceholder(Placeholder placeholder)
|
||||
{
|
||||
|
@ -1,8 +1,6 @@
|
||||
// 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.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Game.Online.API;
|
||||
@ -32,7 +30,7 @@ namespace osu.Game.Screens.OnlinePlay.Match.Components
|
||||
|
||||
protected override bool IsOnlineScope => true;
|
||||
|
||||
protected override APIRequest FetchScores(Action<IEnumerable<APIUserScoreAggregate>> scoresCallback)
|
||||
protected override APIRequest FetchScores()
|
||||
{
|
||||
if (roomId.Value == null)
|
||||
return null;
|
||||
@ -41,7 +39,7 @@ namespace osu.Game.Screens.OnlinePlay.Match.Components
|
||||
|
||||
req.Success += r =>
|
||||
{
|
||||
scoresCallback?.Invoke(r.Leaderboard);
|
||||
Scores = r.Leaderboard;
|
||||
TopScore = r.UserScore;
|
||||
};
|
||||
|
||||
|
@ -25,12 +25,6 @@ namespace osu.Game.Screens.Select.Leaderboards
|
||||
{
|
||||
public Action<ScoreInfo> ScoreSelected;
|
||||
|
||||
[Resolved]
|
||||
private RulesetStore rulesets { get; set; }
|
||||
|
||||
[Resolved]
|
||||
private RealmAccess realm { get; set; }
|
||||
|
||||
private BeatmapInfo beatmapInfo;
|
||||
|
||||
public BeatmapInfo BeatmapInfo
|
||||
@ -52,13 +46,7 @@ namespace osu.Game.Screens.Select.Leaderboards
|
||||
beatmapInfo = value;
|
||||
Scores = null;
|
||||
|
||||
if (IsOnlineScope)
|
||||
RefetchScores();
|
||||
else
|
||||
{
|
||||
if (IsLoaded)
|
||||
refreshRealmSubscription();
|
||||
}
|
||||
RefetchScores();
|
||||
}
|
||||
}
|
||||
|
||||
@ -93,6 +81,14 @@ namespace osu.Game.Screens.Select.Leaderboards
|
||||
[Resolved]
|
||||
private IAPIProvider api { get; set; }
|
||||
|
||||
[Resolved]
|
||||
private RulesetStore rulesets { get; set; }
|
||||
|
||||
[Resolved]
|
||||
private RealmAccess realm { get; set; }
|
||||
|
||||
private IDisposable scoreSubscription;
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
@ -104,33 +100,6 @@ namespace osu.Game.Screens.Select.Leaderboards
|
||||
};
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
refreshRealmSubscription();
|
||||
}
|
||||
|
||||
private IDisposable scoreSubscription;
|
||||
|
||||
private void refreshRealmSubscription()
|
||||
{
|
||||
scoreSubscription?.Dispose();
|
||||
scoreSubscription = null;
|
||||
|
||||
if (beatmapInfo == null)
|
||||
return;
|
||||
|
||||
scoreSubscription = realm.RegisterForNotifications(r =>
|
||||
r.All<ScoreInfo>()
|
||||
.Filter($"{nameof(ScoreInfo.BeatmapInfo)}.{nameof(BeatmapInfo.ID)} = $0", beatmapInfo.ID),
|
||||
(_, changes, ___) =>
|
||||
{
|
||||
if (!IsOnlineScope)
|
||||
RefetchScores();
|
||||
});
|
||||
}
|
||||
|
||||
protected override void Reset()
|
||||
{
|
||||
base.Reset();
|
||||
@ -141,13 +110,11 @@ namespace osu.Game.Screens.Select.Leaderboards
|
||||
|
||||
private CancellationTokenSource loadCancellationSource;
|
||||
|
||||
protected override APIRequest FetchScores(Action<IEnumerable<ScoreInfo>> scoresCallback)
|
||||
protected override APIRequest FetchScores()
|
||||
{
|
||||
loadCancellationSource?.Cancel();
|
||||
loadCancellationSource = new CancellationTokenSource();
|
||||
|
||||
var cancellationToken = loadCancellationSource.Token;
|
||||
|
||||
var fetchBeatmapInfo = BeatmapInfo;
|
||||
|
||||
if (fetchBeatmapInfo == null)
|
||||
@ -158,31 +125,7 @@ namespace osu.Game.Screens.Select.Leaderboards
|
||||
|
||||
if (Scope == BeatmapLeaderboardScope.Local)
|
||||
{
|
||||
realm.Run(r =>
|
||||
{
|
||||
var scores = r.All<ScoreInfo>()
|
||||
.AsEnumerable()
|
||||
// TODO: update to use a realm filter directly (or at least figure out the beatmap part to reduce scope).
|
||||
.Where(s => !s.DeletePending && s.BeatmapInfo.ID == fetchBeatmapInfo.ID && s.Ruleset.ShortName == ruleset.Value.ShortName);
|
||||
|
||||
if (filterMods && !mods.Value.Any())
|
||||
{
|
||||
// we need to filter out all scores that have any mods to get all local nomod scores
|
||||
scores = scores.Where(s => !s.Mods.Any());
|
||||
}
|
||||
else if (filterMods)
|
||||
{
|
||||
// otherwise find all the scores that have *any* of the currently selected mods (similar to how web applies mod filters)
|
||||
// we're creating and using a string list representation of selected mods so that it can be translated into the DB query itself
|
||||
var selectedMods = mods.Value.Select(m => m.Acronym);
|
||||
scores = scores.Where(s => s.Mods.Any(m => selectedMods.Contains(m.Acronym)));
|
||||
}
|
||||
|
||||
scores = scores.Detach();
|
||||
|
||||
scoreManager.OrderByTotalScoreAsync(scores.ToArray(), cancellationToken)
|
||||
.ContinueWith(ordered => scoresCallback?.Invoke(ordered.GetResultSafely()), TaskContinuationOptions.OnlyOnRanToCompletion);
|
||||
});
|
||||
subscribeToLocalScores();
|
||||
|
||||
return null;
|
||||
}
|
||||
@ -217,13 +160,13 @@ namespace osu.Game.Screens.Select.Leaderboards
|
||||
|
||||
req.Success += r =>
|
||||
{
|
||||
scoreManager.OrderByTotalScoreAsync(r.Scores.Select(s => s.CreateScoreInfo(rulesets, fetchBeatmapInfo)).ToArray(), cancellationToken)
|
||||
scoreManager.OrderByTotalScoreAsync(r.Scores.Select(s => s.CreateScoreInfo(rulesets, fetchBeatmapInfo)).ToArray(), loadCancellationSource.Token)
|
||||
.ContinueWith(task => Schedule(() =>
|
||||
{
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
if (loadCancellationSource.IsCancellationRequested)
|
||||
return;
|
||||
|
||||
scoresCallback?.Invoke(task.GetResultSafely());
|
||||
Scores = task.GetResultSafely();
|
||||
TopScore = r.UserScore?.CreateScoreInfo(rulesets, fetchBeatmapInfo);
|
||||
}), TaskContinuationOptions.OnlyOnRanToCompletion);
|
||||
};
|
||||
@ -241,10 +184,53 @@ namespace osu.Game.Screens.Select.Leaderboards
|
||||
Action = () => ScoreSelected?.Invoke(model)
|
||||
};
|
||||
|
||||
private void subscribeToLocalScores()
|
||||
{
|
||||
scoreSubscription?.Dispose();
|
||||
scoreSubscription = null;
|
||||
|
||||
if (beatmapInfo == null)
|
||||
return;
|
||||
|
||||
scoreSubscription = realm.RegisterForNotifications(r =>
|
||||
r.All<ScoreInfo>().Filter($"{nameof(ScoreInfo.BeatmapInfo)}.{nameof(BeatmapInfo.ID)} == $0"
|
||||
+ $" AND {nameof(ScoreInfo.Ruleset)}.{nameof(RulesetInfo.ShortName)} == $1"
|
||||
+ $" AND {nameof(ScoreInfo.DeletePending)} == false"
|
||||
, beatmapInfo.ID, ruleset.Value.ShortName), localScoresChanged);
|
||||
}
|
||||
|
||||
private void localScoresChanged(IRealmCollection<ScoreInfo> sender, ChangeSet changes, Exception exception)
|
||||
{
|
||||
if (IsOnlineScope)
|
||||
return;
|
||||
|
||||
var scores = sender.AsEnumerable();
|
||||
|
||||
if (filterMods && !mods.Value.Any())
|
||||
{
|
||||
// we need to filter out all scores that have any mods to get all local nomod scores
|
||||
scores = scores.Where(s => !s.Mods.Any());
|
||||
}
|
||||
else if (filterMods)
|
||||
{
|
||||
// otherwise find all the scores that have *any* of the currently selected mods (similar to how web applies mod filters)
|
||||
// we're creating and using a string list representation of selected mods so that it can be translated into the DB query itself
|
||||
var selectedMods = mods.Value.Select(m => m.Acronym);
|
||||
scores = scores.Where(s => s.Mods.Any(m => selectedMods.Contains(m.Acronym)));
|
||||
}
|
||||
|
||||
scores = scores.Detach();
|
||||
|
||||
scoreManager.OrderByTotalScoreAsync(scores.ToArray(), loadCancellationSource.Token)
|
||||
.ContinueWith(ordered =>
|
||||
{
|
||||
Scores = ordered.GetResultSafely();
|
||||
}, TaskContinuationOptions.OnlyOnRanToCompletion);
|
||||
}
|
||||
|
||||
protected override void Dispose(bool isDisposing)
|
||||
{
|
||||
base.Dispose(isDisposing);
|
||||
|
||||
scoreSubscription?.Dispose();
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user