mirror of
https://github.com/ppy/osu.git
synced 2026-06-05 19:36:03 +08:00
Merge pull request #34766 from bdach/remove-double-lookup
Pull up online beatmap set lookup to song select level to avoid two components doing the same fetch independently
This commit is contained in:
@@ -7,6 +7,7 @@ using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Audio;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Extensions;
|
||||
using osu.Framework.Extensions.ObjectExtensions;
|
||||
using osu.Framework.Graphics;
|
||||
@@ -42,7 +43,8 @@ namespace osu.Game.Tests.Visual.SongSelectV2
|
||||
private DialogOverlay dialogOverlay = null!;
|
||||
|
||||
private LeaderboardManager leaderboardManager = null!;
|
||||
private RealmPopulatingOnlineLookupSource lookupSource = null!;
|
||||
|
||||
private readonly IBindable<Screens.SelectV2.SongSelect.BeatmapSetLookupResult?> onlineLookupResult = new Bindable<Screens.SelectV2.SongSelect.BeatmapSetLookupResult?>();
|
||||
|
||||
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
|
||||
{
|
||||
@@ -52,7 +54,7 @@ namespace osu.Game.Tests.Visual.SongSelectV2
|
||||
dependencies.Cache(beatmapManager = new BeatmapManager(LocalStorage, Realm, null, dependencies.Get<AudioManager>(), Resources, dependencies.Get<GameHost>(), Beatmap.Default));
|
||||
dependencies.Cache(scoreManager = new ScoreManager(rulesetStore, () => beatmapManager, LocalStorage, Realm, API));
|
||||
dependencies.Cache(leaderboardManager = new LeaderboardManager());
|
||||
dependencies.Cache(lookupSource = new RealmPopulatingOnlineLookupSource());
|
||||
dependencies.CacheAs(onlineLookupResult);
|
||||
|
||||
Dependencies.Cache(Realm);
|
||||
|
||||
@@ -68,7 +70,6 @@ namespace osu.Game.Tests.Visual.SongSelectV2
|
||||
});
|
||||
|
||||
LoadComponent(leaderboardManager);
|
||||
LoadComponent(lookupSource);
|
||||
|
||||
Child = contentContainer = new OsuContextMenuContainer
|
||||
{
|
||||
|
||||
@@ -4,13 +4,12 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Testing;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Extensions;
|
||||
using osu.Game.Models;
|
||||
using osu.Game.Online.API;
|
||||
using osu.Game.Online.API.Requests;
|
||||
using osu.Game.Online.API.Requests.Responses;
|
||||
using osu.Game.Screens.SelectV2;
|
||||
|
||||
@@ -18,64 +17,25 @@ namespace osu.Game.Tests.Visual.SongSelectV2
|
||||
{
|
||||
public partial class TestSceneBeatmapMetadataWedge : SongSelectComponentsTestScene
|
||||
{
|
||||
private APIBeatmapSet? currentOnlineSet;
|
||||
|
||||
private BeatmapMetadataWedge wedge = null!;
|
||||
|
||||
[Cached(typeof(IBindable<Screens.SelectV2.SongSelect.BeatmapSetLookupResult?>))]
|
||||
private Bindable<Screens.SelectV2.SongSelect.BeatmapSetLookupResult?> onlineLookupResult = new Bindable<Screens.SelectV2.SongSelect.BeatmapSetLookupResult?>();
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
var lookupSource = new RealmPopulatingOnlineLookupSource();
|
||||
Child = new DependencyProvidingContainer
|
||||
Child = wedge = new BeatmapMetadataWedge
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
CachedDependencies = [(typeof(RealmPopulatingOnlineLookupSource), lookupSource)],
|
||||
Children =
|
||||
[
|
||||
lookupSource,
|
||||
wedge = new BeatmapMetadataWedge
|
||||
{
|
||||
State = { Value = Visibility.Visible },
|
||||
}
|
||||
]
|
||||
State = { Value = Visibility.Visible },
|
||||
};
|
||||
}
|
||||
|
||||
[SetUpSteps]
|
||||
public override void SetUpSteps()
|
||||
{
|
||||
AddStep("register request handling", () =>
|
||||
{
|
||||
((DummyAPIAccess)API).HandleRequest = request =>
|
||||
{
|
||||
switch (request)
|
||||
{
|
||||
case GetBeatmapSetRequest set:
|
||||
if (set.ID == currentOnlineSet?.OnlineID)
|
||||
{
|
||||
set.TriggerSuccess(currentOnlineSet);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestShowHide()
|
||||
{
|
||||
AddStep("all metrics", () =>
|
||||
{
|
||||
var (working, onlineSet) = createTestBeatmap();
|
||||
currentOnlineSet = onlineSet;
|
||||
Beatmap.Value = working;
|
||||
});
|
||||
AddStep("all metrics", () => (Beatmap.Value, onlineLookupResult.Value) = createTestBeatmap());
|
||||
|
||||
AddStep("hide wedge", () => wedge.Hide());
|
||||
AddStep("show wedge", () => wedge.Show());
|
||||
@@ -84,67 +44,63 @@ namespace osu.Game.Tests.Visual.SongSelectV2
|
||||
[Test]
|
||||
public void TestVariousMetrics()
|
||||
{
|
||||
AddStep("all metrics", () =>
|
||||
{
|
||||
var (working, onlineSet) = createTestBeatmap();
|
||||
currentOnlineSet = onlineSet;
|
||||
Beatmap.Value = working;
|
||||
});
|
||||
AddStep("all metrics", () => (Beatmap.Value, onlineLookupResult.Value) = createTestBeatmap());
|
||||
|
||||
AddStep("null beatmap", () => Beatmap.SetDefault());
|
||||
AddStep("no source", () =>
|
||||
{
|
||||
var (working, onlineSet) = createTestBeatmap();
|
||||
var (working, online) = createTestBeatmap();
|
||||
|
||||
working.Metadata.Source = string.Empty;
|
||||
|
||||
currentOnlineSet = onlineSet;
|
||||
onlineLookupResult.Value = online;
|
||||
Beatmap.Value = working;
|
||||
});
|
||||
AddStep("no success rate", () =>
|
||||
{
|
||||
var (working, onlineSet) = createTestBeatmap();
|
||||
var (working, online) = createTestBeatmap();
|
||||
|
||||
onlineSet.Beatmaps.Single().PlayCount = 0;
|
||||
onlineSet.Beatmaps.Single().PassCount = 0;
|
||||
online.Result!.Beatmaps.Single().PlayCount = 0;
|
||||
online.Result!.Beatmaps.Single().PassCount = 0;
|
||||
|
||||
currentOnlineSet = onlineSet;
|
||||
onlineLookupResult.Value = online;
|
||||
Beatmap.Value = working;
|
||||
});
|
||||
AddStep("no user ratings", () =>
|
||||
{
|
||||
var (working, onlineSet) = createTestBeatmap();
|
||||
var (working, online) = createTestBeatmap();
|
||||
|
||||
onlineSet.Ratings = Array.Empty<int>();
|
||||
online.Result!.Ratings = Array.Empty<int>();
|
||||
|
||||
currentOnlineSet = onlineSet;
|
||||
onlineLookupResult.Value = online;
|
||||
Beatmap.Value = working;
|
||||
});
|
||||
AddStep("no fail times", () =>
|
||||
{
|
||||
var (working, onlineSet) = createTestBeatmap();
|
||||
var (working, online) = createTestBeatmap();
|
||||
|
||||
onlineSet.Beatmaps.Single().FailTimes = null;
|
||||
online.Result!.Beatmaps.Single().FailTimes = null;
|
||||
|
||||
currentOnlineSet = onlineSet;
|
||||
onlineLookupResult.Value = online;
|
||||
Beatmap.Value = working;
|
||||
});
|
||||
AddStep("no metrics", () =>
|
||||
{
|
||||
var (working, onlineSet) = createTestBeatmap();
|
||||
var (working, online) = createTestBeatmap();
|
||||
|
||||
onlineSet.Ratings = Array.Empty<int>();
|
||||
onlineSet.Beatmaps.Single().FailTimes = null;
|
||||
online.Result!.Ratings = Array.Empty<int>();
|
||||
online.Result!.Beatmaps.Single().FailTimes = null;
|
||||
|
||||
currentOnlineSet = onlineSet;
|
||||
onlineLookupResult.Value = online;
|
||||
Beatmap.Value = working;
|
||||
});
|
||||
AddStep("local beatmap", () =>
|
||||
{
|
||||
var (working, onlineSet) = createTestBeatmap();
|
||||
var (working, _) = createTestBeatmap();
|
||||
|
||||
working.BeatmapInfo.OnlineID = 0;
|
||||
|
||||
currentOnlineSet = onlineSet;
|
||||
onlineLookupResult.Value = null;
|
||||
Beatmap.Value = working;
|
||||
});
|
||||
}
|
||||
@@ -154,16 +110,16 @@ namespace osu.Game.Tests.Visual.SongSelectV2
|
||||
{
|
||||
AddStep("long text", () =>
|
||||
{
|
||||
var (working, onlineSet) = createTestBeatmap();
|
||||
var (working, online) = createTestBeatmap();
|
||||
|
||||
working.BeatmapInfo.Metadata.Author = new RealmUser { Username = "Verrrrryyyy llooonngggggg author" };
|
||||
working.BeatmapInfo.Metadata.Source = "Verrrrryyyy llooonngggggg source";
|
||||
working.BeatmapInfo.Metadata.Tags = string.Join(' ', Enumerable.Repeat(working.BeatmapInfo.Metadata.Tags, 3));
|
||||
onlineSet.Genre = new BeatmapSetOnlineGenre { Id = 12, Name = "Verrrrryyyy llooonngggggg genre" };
|
||||
onlineSet.Language = new BeatmapSetOnlineLanguage { Id = 12, Name = "Verrrrryyyy llooonngggggg language" };
|
||||
onlineSet.Beatmaps.Single().TopTags = Enumerable.Repeat(onlineSet.Beatmaps.Single().TopTags, 3).SelectMany(t => t!).ToArray();
|
||||
online.Result!.Genre = new BeatmapSetOnlineGenre { Id = 12, Name = "Verrrrryyyy llooonngggggg genre" };
|
||||
online.Result!.Language = new BeatmapSetOnlineLanguage { Id = 12, Name = "Verrrrryyyy llooonngggggg language" };
|
||||
online.Result!.Beatmaps.Single().TopTags = Enumerable.Repeat(online.Result!.Beatmaps.Single().TopTags, 3).SelectMany(t => t!).ToArray();
|
||||
|
||||
currentOnlineSet = onlineSet;
|
||||
onlineLookupResult.Value = online;
|
||||
Beatmap.Value = working;
|
||||
});
|
||||
}
|
||||
@@ -171,22 +127,17 @@ namespace osu.Game.Tests.Visual.SongSelectV2
|
||||
[Test]
|
||||
public void TestOnlineAvailability()
|
||||
{
|
||||
AddStep("online beatmapset", () =>
|
||||
{
|
||||
var (working, onlineSet) = createTestBeatmap();
|
||||
AddStep("online beatmapset", () => (Beatmap.Value, onlineLookupResult.Value) = createTestBeatmap());
|
||||
|
||||
currentOnlineSet = onlineSet;
|
||||
Beatmap.Value = working;
|
||||
});
|
||||
AddUntilStep("rating wedge visible", () => wedge.RatingsVisible);
|
||||
AddUntilStep("fail time wedge visible", () => wedge.FailRetryVisible);
|
||||
AddStep("online beatmapset with local diff", () =>
|
||||
{
|
||||
var (working, onlineSet) = createTestBeatmap();
|
||||
var (working, lookupResult) = createTestBeatmap();
|
||||
|
||||
working.BeatmapInfo.ResetOnlineInfo();
|
||||
|
||||
currentOnlineSet = onlineSet;
|
||||
onlineLookupResult.Value = lookupResult;
|
||||
Beatmap.Value = working;
|
||||
});
|
||||
AddUntilStep("rating wedge hidden", () => !wedge.RatingsVisible);
|
||||
@@ -195,7 +146,7 @@ namespace osu.Game.Tests.Visual.SongSelectV2
|
||||
{
|
||||
var (working, _) = createTestBeatmap();
|
||||
|
||||
currentOnlineSet = null;
|
||||
onlineLookupResult.Value = null;
|
||||
Beatmap.Value = working;
|
||||
});
|
||||
AddAssert("rating wedge still hidden", () => !wedge.RatingsVisible);
|
||||
@@ -205,21 +156,17 @@ namespace osu.Game.Tests.Visual.SongSelectV2
|
||||
[Test]
|
||||
public void TestUserTags()
|
||||
{
|
||||
AddStep("user tags", () =>
|
||||
{
|
||||
var (working, onlineSet) = createTestBeatmap();
|
||||
AddStep("user tags", () => (Beatmap.Value, onlineLookupResult.Value) = createTestBeatmap());
|
||||
|
||||
currentOnlineSet = onlineSet;
|
||||
Beatmap.Value = working;
|
||||
});
|
||||
AddStep("no user tags", () =>
|
||||
{
|
||||
var (working, onlineSet) = createTestBeatmap();
|
||||
var (working, online) = createTestBeatmap();
|
||||
|
||||
onlineSet.Beatmaps.Single().TopTags = null;
|
||||
onlineSet.RelatedTags = null;
|
||||
online.Result!.Beatmaps.Single().TopTags = null;
|
||||
online.Result!.RelatedTags = null;
|
||||
working.BeatmapSetInfo.Beatmaps.Single().Metadata.UserTags.Clear();
|
||||
|
||||
currentOnlineSet = onlineSet;
|
||||
onlineLookupResult.Value = online;
|
||||
Beatmap.Value = working;
|
||||
});
|
||||
}
|
||||
@@ -227,72 +174,60 @@ namespace osu.Game.Tests.Visual.SongSelectV2
|
||||
[Test]
|
||||
public void TestLoading()
|
||||
{
|
||||
AddStep("override request handling", () =>
|
||||
{
|
||||
currentOnlineSet = null;
|
||||
|
||||
((DummyAPIAccess)API).HandleRequest = request =>
|
||||
{
|
||||
switch (request)
|
||||
{
|
||||
case GetBeatmapSetRequest set:
|
||||
Scheduler.AddDelayed(() => set.TriggerSuccess(currentOnlineSet!), 500);
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
AddStep("set beatmap", () =>
|
||||
{
|
||||
var (working, onlineSet) = createTestBeatmap();
|
||||
var (working, online) = createTestBeatmap();
|
||||
|
||||
currentOnlineSet = onlineSet;
|
||||
onlineLookupResult.Value = Screens.SelectV2.SongSelect.BeatmapSetLookupResult.InProgress();
|
||||
Scheduler.AddDelayed(() => onlineLookupResult.Value = online, 500);
|
||||
Beatmap.Value = working;
|
||||
});
|
||||
AddWaitStep("wait", 5);
|
||||
|
||||
AddStep("set beatmap", () =>
|
||||
{
|
||||
var (working, onlineSet) = createTestBeatmap();
|
||||
var (working, online) = createTestBeatmap();
|
||||
|
||||
onlineSet.RelatedTags![0].Name = "other/tag";
|
||||
onlineSet.RelatedTags[1].Name = "another/tag";
|
||||
onlineSet.RelatedTags[2].Name = "some/tag";
|
||||
online.Result!.RelatedTags![0].Name = "other/tag";
|
||||
online.Result!.RelatedTags[1].Name = "another/tag";
|
||||
online.Result!.RelatedTags[2].Name = "some/tag";
|
||||
|
||||
currentOnlineSet = onlineSet;
|
||||
onlineLookupResult.Value = Screens.SelectV2.SongSelect.BeatmapSetLookupResult.InProgress();
|
||||
Scheduler.AddDelayed(() => onlineLookupResult.Value = online, 500);
|
||||
Beatmap.Value = working;
|
||||
});
|
||||
AddWaitStep("wait", 5);
|
||||
|
||||
AddStep("no user tags", () =>
|
||||
{
|
||||
var (working, onlineSet) = createTestBeatmap();
|
||||
var (working, online) = createTestBeatmap();
|
||||
|
||||
onlineSet.Beatmaps.Single().TopTags = null;
|
||||
onlineSet.RelatedTags = null;
|
||||
online.Result!.Beatmaps.Single().TopTags = null;
|
||||
online.Result!.RelatedTags = null;
|
||||
working.BeatmapSetInfo.Beatmaps.Single().Metadata.UserTags.Clear();
|
||||
|
||||
currentOnlineSet = onlineSet;
|
||||
onlineLookupResult.Value = Screens.SelectV2.SongSelect.BeatmapSetLookupResult.InProgress();
|
||||
Scheduler.AddDelayed(() => onlineLookupResult.Value = online, 500);
|
||||
Beatmap.Value = working;
|
||||
});
|
||||
AddWaitStep("wait", 5);
|
||||
|
||||
AddStep("no user tags", () =>
|
||||
{
|
||||
var (working, onlineSet) = createTestBeatmap();
|
||||
var (working, online) = createTestBeatmap();
|
||||
|
||||
onlineSet.Beatmaps.Single().TopTags = null;
|
||||
onlineSet.RelatedTags = null;
|
||||
online.Result!.Beatmaps.Single().TopTags = null;
|
||||
online.Result!.RelatedTags = null;
|
||||
working.BeatmapSetInfo.Beatmaps.Single().Metadata.UserTags.Clear();
|
||||
|
||||
currentOnlineSet = onlineSet;
|
||||
onlineLookupResult.Value = Screens.SelectV2.SongSelect.BeatmapSetLookupResult.InProgress();
|
||||
Scheduler.AddDelayed(() => onlineLookupResult.Value = online, 500);
|
||||
Beatmap.Value = working;
|
||||
});
|
||||
AddWaitStep("wait", 5);
|
||||
}
|
||||
|
||||
private (WorkingBeatmap, APIBeatmapSet) createTestBeatmap()
|
||||
private (WorkingBeatmap, Screens.SelectV2.SongSelect.BeatmapSetLookupResult) createTestBeatmap()
|
||||
{
|
||||
var working = CreateWorkingBeatmap(Ruleset.Value);
|
||||
var onlineSet = new APIBeatmapSet
|
||||
@@ -346,7 +281,8 @@ namespace osu.Game.Tests.Visual.SongSelectV2
|
||||
|
||||
working.BeatmapSetInfo.DateSubmitted = DateTimeOffset.Now;
|
||||
working.BeatmapSetInfo.DateRanked = DateTimeOffset.Now;
|
||||
return (working, onlineSet);
|
||||
working.Metadata.UserTags.AddRange(onlineSet.RelatedTags.Select(t => t.Name));
|
||||
return (working, Screens.SelectV2.SongSelect.BeatmapSetLookupResult.Completed(onlineSet));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ using NUnit.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Audio;
|
||||
using osu.Framework.Audio.Track;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Textures;
|
||||
@@ -41,10 +42,8 @@ namespace osu.Game.Tests.Visual.SongSelectV2
|
||||
private BeatmapTitleWedge titleWedge = null!;
|
||||
private BeatmapTitleWedge.DifficultyDisplay difficultyDisplay => titleWedge.ChildrenOfType<BeatmapTitleWedge.DifficultyDisplay>().Single();
|
||||
|
||||
private APIBeatmapSet? currentOnlineSet;
|
||||
|
||||
[Cached]
|
||||
private RealmPopulatingOnlineLookupSource lookupSource = new RealmPopulatingOnlineLookupSource();
|
||||
[Cached(typeof(IBindable<Screens.SelectV2.SongSelect.BeatmapSetLookupResult?>))]
|
||||
private Bindable<Screens.SelectV2.SongSelect.BeatmapSetLookupResult?> onlineLookupResult = new Bindable<Screens.SelectV2.SongSelect.BeatmapSetLookupResult?>();
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(RulesetStore rulesets)
|
||||
@@ -58,7 +57,6 @@ namespace osu.Game.Tests.Visual.SongSelectV2
|
||||
|
||||
AddRange(new Drawable[]
|
||||
{
|
||||
lookupSource,
|
||||
new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
@@ -142,44 +140,18 @@ namespace osu.Game.Tests.Visual.SongSelectV2
|
||||
[Test]
|
||||
public void TestOnlineAvailability()
|
||||
{
|
||||
AddStep("set up request handler", () =>
|
||||
{
|
||||
((DummyAPIAccess)API).HandleRequest = request =>
|
||||
{
|
||||
switch (request)
|
||||
{
|
||||
case GetBeatmapSetRequest set:
|
||||
if (set.ID == currentOnlineSet?.OnlineID)
|
||||
{
|
||||
set.TriggerSuccess(currentOnlineSet);
|
||||
return true;
|
||||
}
|
||||
AddStep("online beatmapset", () => (Beatmap.Value, onlineLookupResult.Value) = createTestBeatmap());
|
||||
|
||||
return false;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
AddStep("online beatmapset", () =>
|
||||
{
|
||||
var (working, onlineSet) = createTestBeatmap();
|
||||
|
||||
currentOnlineSet = onlineSet;
|
||||
Beatmap.Value = working;
|
||||
});
|
||||
AddUntilStep("play count is 10000", () => this.ChildrenOfType<BeatmapTitleWedge.Statistic>().ElementAt(0).Text.ToString(), () => Is.EqualTo("10,000"));
|
||||
AddUntilStep("favourites count is 2345", () => this.ChildrenOfType<BeatmapTitleWedge.FavouriteButton>().Single().Text.ToString(), () => Is.EqualTo("2,345"));
|
||||
AddStep("online beatmapset with local diff", () =>
|
||||
{
|
||||
var (working, onlineSet) = createTestBeatmap();
|
||||
var (working, lookupResult) = createTestBeatmap();
|
||||
|
||||
working.BeatmapInfo.ResetOnlineInfo();
|
||||
|
||||
currentOnlineSet = onlineSet;
|
||||
Beatmap.Value = working;
|
||||
onlineLookupResult.Value = lookupResult;
|
||||
});
|
||||
AddUntilStep("play count is -", () => this.ChildrenOfType<BeatmapTitleWedge.Statistic>().ElementAt(0).Text.ToString(), () => Is.EqualTo("-"));
|
||||
AddUntilStep("favourites count is 2345", () => this.ChildrenOfType<BeatmapTitleWedge.FavouriteButton>().Single().Text.ToString(), () => Is.EqualTo("2,345"));
|
||||
@@ -187,8 +159,8 @@ namespace osu.Game.Tests.Visual.SongSelectV2
|
||||
{
|
||||
var (working, _) = createTestBeatmap();
|
||||
|
||||
currentOnlineSet = null;
|
||||
Beatmap.Value = working;
|
||||
onlineLookupResult.Value = Screens.SelectV2.SongSelect.BeatmapSetLookupResult.Completed(null);
|
||||
});
|
||||
AddUntilStep("play count is -", () => this.ChildrenOfType<BeatmapTitleWedge.Statistic>().ElementAt(0).Text.ToString(), () => Is.EqualTo("-"));
|
||||
AddUntilStep("favourites count is -", () => this.ChildrenOfType<BeatmapTitleWedge.FavouriteButton>().Single().Text.ToString(), () => Is.EqualTo("-"));
|
||||
@@ -205,15 +177,6 @@ namespace osu.Game.Tests.Visual.SongSelectV2
|
||||
{
|
||||
switch (request)
|
||||
{
|
||||
case GetBeatmapSetRequest set:
|
||||
if (set.ID == currentOnlineSet?.OnlineID)
|
||||
{
|
||||
set.TriggerSuccess(currentOnlineSet);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
case PostBeatmapFavouriteRequest favourite:
|
||||
Task.Run(() =>
|
||||
{
|
||||
@@ -228,13 +191,8 @@ namespace osu.Game.Tests.Visual.SongSelectV2
|
||||
};
|
||||
});
|
||||
|
||||
AddStep("online beatmapset", () =>
|
||||
{
|
||||
var (working, onlineSet) = createTestBeatmap();
|
||||
AddStep("online beatmapset", () => (Beatmap.Value, onlineLookupResult.Value) = createTestBeatmap());
|
||||
|
||||
currentOnlineSet = onlineSet;
|
||||
Beatmap.Value = working;
|
||||
});
|
||||
AddUntilStep("play count is 10000", () => this.ChildrenOfType<BeatmapTitleWedge.Statistic>().ElementAt(0).Text.ToString(), () => Is.EqualTo("10,000"));
|
||||
AddUntilStep("favourites count is 2345", () => this.ChildrenOfType<BeatmapTitleWedge.FavouriteButton>().Single().Text.ToString(), () => Is.EqualTo("2,345"));
|
||||
|
||||
@@ -251,13 +209,13 @@ namespace osu.Game.Tests.Visual.SongSelectV2
|
||||
AddStep("click favourite button", () => this.ChildrenOfType<BeatmapTitleWedge.FavouriteButton>().Single().TriggerClick());
|
||||
AddStep("change to another beatmap", () =>
|
||||
{
|
||||
var (working, onlineSet) = createTestBeatmap();
|
||||
onlineSet.FavouriteCount = 9999;
|
||||
onlineSet.HasFavourited = true;
|
||||
working.BeatmapSetInfo.OnlineID = onlineSet.OnlineID = 99999;
|
||||
var (working, online) = createTestBeatmap();
|
||||
online.Result!.FavouriteCount = 9999;
|
||||
online.Result!.HasFavourited = true;
|
||||
working.BeatmapSetInfo.OnlineID = online.Result!.OnlineID = 99999;
|
||||
|
||||
currentOnlineSet = onlineSet;
|
||||
Beatmap.Value = working;
|
||||
onlineLookupResult.Value = online;
|
||||
});
|
||||
AddStep("allow request to complete", () => resetEvent.Set());
|
||||
AddUntilStep("favourites count is 9999", () => this.ChildrenOfType<BeatmapTitleWedge.FavouriteButton>().Single().Text.ToString(), () => Is.EqualTo("9,999"));
|
||||
@@ -268,15 +226,6 @@ namespace osu.Game.Tests.Visual.SongSelectV2
|
||||
{
|
||||
switch (request)
|
||||
{
|
||||
case GetBeatmapSetRequest set:
|
||||
if (set.ID == currentOnlineSet?.OnlineID)
|
||||
{
|
||||
set.TriggerSuccess(currentOnlineSet);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
case PostBeatmapFavouriteRequest favourite:
|
||||
Task.Run(() =>
|
||||
{
|
||||
@@ -350,7 +299,7 @@ namespace osu.Game.Tests.Visual.SongSelectV2
|
||||
});
|
||||
}
|
||||
|
||||
private (WorkingBeatmap, APIBeatmapSet) createTestBeatmap()
|
||||
private (WorkingBeatmap, Screens.SelectV2.SongSelect.BeatmapSetLookupResult) createTestBeatmap()
|
||||
{
|
||||
var working = CreateWorkingBeatmap(Ruleset.Value);
|
||||
var onlineSet = new APIBeatmapSet
|
||||
@@ -371,7 +320,7 @@ namespace osu.Game.Tests.Visual.SongSelectV2
|
||||
|
||||
working.BeatmapSetInfo.DateSubmitted = DateTimeOffset.Now;
|
||||
working.BeatmapSetInfo.DateRanked = DateTimeOffset.Now;
|
||||
return (working, onlineSet);
|
||||
return (working, Screens.SelectV2.SongSelect.BeatmapSetLookupResult.Completed(onlineSet));
|
||||
}
|
||||
|
||||
private class TestHitObject : ConvertHitObject;
|
||||
|
||||
@@ -3,16 +3,12 @@
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Audio;
|
||||
using osu.Framework.Audio.Sample;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Logging;
|
||||
using osu.Framework.Utils;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Database;
|
||||
@@ -20,7 +16,6 @@ using osu.Game.Graphics.Containers;
|
||||
using osu.Game.Localisation;
|
||||
using osu.Game.Online;
|
||||
using osu.Game.Online.API;
|
||||
using osu.Game.Online.API.Requests.Responses;
|
||||
using osu.Game.Online.Chat;
|
||||
using osu.Game.Resources.Localisation.Web;
|
||||
using osuTK;
|
||||
@@ -55,10 +50,10 @@ namespace osu.Game.Screens.SelectV2
|
||||
private IBindable<WorkingBeatmap> beatmap { get; set; } = null!;
|
||||
|
||||
[Resolved]
|
||||
private IAPIProvider api { get; set; } = null!;
|
||||
private IBindable<SongSelect.BeatmapSetLookupResult> onlineLookupResult { get; set; } = null!;
|
||||
|
||||
[Resolved]
|
||||
private RealmPopulatingOnlineLookupSource onlineLookupSource { get; set; } = null!;
|
||||
private IAPIProvider api { get; set; } = null!;
|
||||
|
||||
[Resolved]
|
||||
private RealmAccess realm { get; set; } = null!;
|
||||
@@ -254,6 +249,7 @@ namespace osu.Game.Screens.SelectV2
|
||||
{
|
||||
base.LoadComplete();
|
||||
beatmap.BindValueChanged(_ => updateDisplay());
|
||||
onlineLookupResult.BindValueChanged(_ => updateDisplay());
|
||||
|
||||
apiState = api.State.GetBoundCopy();
|
||||
apiState.BindValueChanged(_ => Scheduler.AddOnce(updateDisplay), true);
|
||||
@@ -283,7 +279,7 @@ namespace osu.Game.Screens.SelectV2
|
||||
// Needs some experimentation on what looks good.
|
||||
|
||||
var beatmapInfo = beatmap.Value.BeatmapInfo;
|
||||
var currentOnlineBeatmap = currentOnlineBeatmapSet?.Beatmaps.SingleOrDefault(b => b.OnlineID == beatmapInfo.OnlineID);
|
||||
var currentOnlineBeatmap = onlineLookupResult.Value?.Result?.Beatmaps.SingleOrDefault(b => b.OnlineID == beatmapInfo.OnlineID);
|
||||
|
||||
if (State.Value == Visibility.Visible && currentOnlineBeatmap != null)
|
||||
{
|
||||
@@ -365,41 +361,12 @@ namespace osu.Game.Screens.SelectV2
|
||||
submitted.Date = beatmapSetInfo.DateSubmitted;
|
||||
ranked.Date = beatmapSetInfo.DateRanked;
|
||||
|
||||
if (currentOnlineBeatmapSet == null || currentOnlineBeatmapSet.OnlineID != beatmapSetInfo.OnlineID)
|
||||
refetchBeatmapSet();
|
||||
|
||||
updateOnlineDisplay();
|
||||
}
|
||||
|
||||
private APIBeatmapSet? currentOnlineBeatmapSet;
|
||||
private CancellationTokenSource? cancellationTokenSource;
|
||||
private Task<APIBeatmapSet?>? currentFetchTask;
|
||||
|
||||
private void refetchBeatmapSet()
|
||||
{
|
||||
var beatmapSetInfo = beatmap.Value.BeatmapSetInfo;
|
||||
|
||||
cancellationTokenSource?.Cancel();
|
||||
currentOnlineBeatmapSet = null;
|
||||
|
||||
if (beatmapSetInfo.OnlineID >= 1)
|
||||
{
|
||||
cancellationTokenSource = new CancellationTokenSource();
|
||||
currentFetchTask = onlineLookupSource.GetBeatmapSetAsync(beatmapSetInfo.OnlineID);
|
||||
currentFetchTask.ContinueWith(t =>
|
||||
{
|
||||
if (t.IsCompletedSuccessfully)
|
||||
currentOnlineBeatmapSet = t.GetResultSafely();
|
||||
if (t.Exception != null)
|
||||
Logger.Log($"Error when fetching online beatmap set: {t.Exception}", LoggingTarget.Network);
|
||||
Scheduler.AddOnce(updateOnlineDisplay);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void updateOnlineDisplay()
|
||||
{
|
||||
if (currentFetchTask?.IsCompleted == false)
|
||||
if (onlineLookupResult.Value?.Status != SongSelect.BeatmapSetLookupStatus.Completed)
|
||||
{
|
||||
genre.Data = null;
|
||||
language.Data = null;
|
||||
@@ -407,7 +374,7 @@ namespace osu.Game.Screens.SelectV2
|
||||
return;
|
||||
}
|
||||
|
||||
if (currentOnlineBeatmapSet == null)
|
||||
if (onlineLookupResult.Value.Result == null)
|
||||
{
|
||||
genre.Data = ("-", null);
|
||||
language.Data = ("-", null);
|
||||
@@ -416,7 +383,7 @@ namespace osu.Game.Screens.SelectV2
|
||||
{
|
||||
var beatmapInfo = beatmap.Value.BeatmapInfo;
|
||||
|
||||
var onlineBeatmapSet = currentOnlineBeatmapSet;
|
||||
var onlineBeatmapSet = onlineLookupResult.Value.Result;
|
||||
var onlineBeatmap = onlineBeatmapSet.Beatmaps.SingleOrDefault(b => b.OnlineID == beatmapInfo.OnlineID);
|
||||
|
||||
genre.Data = (onlineBeatmapSet.Genre.Name, () => songSelect?.Search(onlineBeatmapSet.Genre.Name));
|
||||
|
||||
@@ -8,11 +8,9 @@ using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Localisation;
|
||||
using osu.Framework.Logging;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Beatmaps.Drawables;
|
||||
using osu.Game.Configuration;
|
||||
@@ -21,7 +19,6 @@ using osu.Game.Extensions;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Containers;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Online.API.Requests.Responses;
|
||||
using osu.Game.Resources.Localisation.Web;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
@@ -43,6 +40,9 @@ namespace osu.Game.Screens.SelectV2
|
||||
[Resolved]
|
||||
private IBindable<IReadOnlyList<Mod>> mods { get; set; } = null!;
|
||||
|
||||
[Resolved]
|
||||
private IBindable<SongSelect.BeatmapSetLookupResult?> onlineLookupResult { get; set; } = null!;
|
||||
|
||||
protected override bool StartHidden => true;
|
||||
|
||||
private ModSettingChangeTracker? settingChangeTracker;
|
||||
@@ -69,16 +69,9 @@ namespace osu.Game.Screens.SelectV2
|
||||
[Resolved]
|
||||
private LocalisationManager localisation { get; set; } = null!;
|
||||
|
||||
[Resolved]
|
||||
private RealmPopulatingOnlineLookupSource onlineLookupSource { get; set; } = null!;
|
||||
|
||||
[Resolved]
|
||||
private RealmAccess realm { get; set; } = null!;
|
||||
|
||||
private APIBeatmapSet? currentOnlineBeatmapSet;
|
||||
private CancellationTokenSource? cancellationTokenSource;
|
||||
private Task<APIBeatmapSet?>? currentFetchTask;
|
||||
|
||||
private FillFlowContainer statisticsFlow = null!;
|
||||
|
||||
public BeatmapTitleWedge()
|
||||
@@ -190,6 +183,7 @@ namespace osu.Game.Screens.SelectV2
|
||||
|
||||
working.BindValueChanged(_ => updateDisplay());
|
||||
ruleset.BindValueChanged(_ => updateDisplay());
|
||||
onlineLookupResult.BindValueChanged(_ => updateDisplay());
|
||||
|
||||
mods.BindValueChanged(m =>
|
||||
{
|
||||
@@ -230,7 +224,6 @@ namespace osu.Game.Screens.SelectV2
|
||||
{
|
||||
var metadata = working.Value.Metadata;
|
||||
var beatmapInfo = working.Value.BeatmapInfo;
|
||||
var beatmapSetInfo = working.Value.BeatmapSetInfo;
|
||||
|
||||
statusPill.Status = beatmapInfo.Status;
|
||||
|
||||
@@ -243,10 +236,6 @@ namespace osu.Game.Screens.SelectV2
|
||||
artistLink.Action = () => songSelect?.Search(artistText.GetPreferred(localisation.CurrentParameters.Value.PreferOriginalScript));
|
||||
|
||||
updateLengthAndBpmStatistics();
|
||||
|
||||
if (currentOnlineBeatmapSet == null || currentOnlineBeatmapSet.OnlineID != beatmapSetInfo.OnlineID)
|
||||
refetchBeatmapSet();
|
||||
|
||||
updateOnlineDisplay();
|
||||
}
|
||||
|
||||
@@ -289,40 +278,18 @@ namespace osu.Game.Screens.SelectV2
|
||||
}, token);
|
||||
}
|
||||
|
||||
private void refetchBeatmapSet()
|
||||
{
|
||||
var beatmapSetInfo = working.Value.BeatmapSetInfo;
|
||||
|
||||
cancellationTokenSource?.Cancel();
|
||||
currentOnlineBeatmapSet = null;
|
||||
|
||||
if (beatmapSetInfo.OnlineID >= 1)
|
||||
{
|
||||
cancellationTokenSource = new CancellationTokenSource();
|
||||
currentFetchTask = onlineLookupSource.GetBeatmapSetAsync(beatmapSetInfo.OnlineID);
|
||||
currentFetchTask.ContinueWith(t =>
|
||||
{
|
||||
if (t.IsCompletedSuccessfully)
|
||||
currentOnlineBeatmapSet = t.GetResultSafely();
|
||||
if (t.Exception != null)
|
||||
Logger.Log($"Error when fetching online beatmap set: {t.Exception}", LoggingTarget.Network);
|
||||
Scheduler.AddOnce(updateOnlineDisplay);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void updateOnlineDisplay()
|
||||
{
|
||||
if (currentFetchTask?.IsCompleted == false)
|
||||
if (onlineLookupResult.Value?.Status != SongSelect.BeatmapSetLookupStatus.Completed)
|
||||
{
|
||||
playCount.Value = null;
|
||||
favouriteButton.SetLoading();
|
||||
}
|
||||
else
|
||||
{
|
||||
var onlineBeatmap = currentOnlineBeatmapSet?.Beatmaps.SingleOrDefault(b => b.OnlineID == working.Value.BeatmapInfo.OnlineID);
|
||||
var onlineBeatmap = onlineLookupResult.Value.Result?.Beatmaps.SingleOrDefault(b => b.OnlineID == working.Value.BeatmapInfo.OnlineID);
|
||||
playCount.Value = new StatisticPlayCount.Data(onlineBeatmap?.PlayCount ?? -1, onlineBeatmap?.UserPlayCount ?? -1);
|
||||
favouriteButton.SetBeatmapSet(currentOnlineBeatmapSet);
|
||||
favouriteButton.SetBeatmapSet(onlineLookupResult.Value.Result);
|
||||
|
||||
// the online fetch may have also updated the beatmap's status.
|
||||
// this needs to be checked against the *local* beatmap model rather than the online one, because it's not known here whether the status change has occurred or not
|
||||
|
||||
@@ -229,7 +229,10 @@ namespace osu.Game.Screens.SelectV2
|
||||
bool hasFavourited = favouriteRequest.Action == BeatmapFavouriteAction.Favourite;
|
||||
beatmapSet.HasFavourited = hasFavourited;
|
||||
beatmapSet.FavouriteCount += hasFavourited ? 1 : -1;
|
||||
setBeatmapSet(beatmapSet, withHeartAnimation: hasFavourited);
|
||||
|
||||
// if the beatmap set reference changed under the callback, abort visual updates to avoid showing stale data
|
||||
if (onlineBeatmapSet == null || ReferenceEquals(beatmapSet, onlineBeatmapSet))
|
||||
setBeatmapSet(beatmapSet, withHeartAnimation: hasFavourited);
|
||||
};
|
||||
favouriteRequest.Failure += e =>
|
||||
{
|
||||
@@ -238,7 +241,10 @@ namespace osu.Game.Screens.SelectV2
|
||||
Text = e.Message,
|
||||
Icon = FontAwesome.Solid.Times,
|
||||
});
|
||||
setBeatmapSet(beatmapSet, withHeartAnimation: false);
|
||||
|
||||
// if the beatmap set reference changed under the callback, abort visual updates to avoid showing stale data
|
||||
if (onlineBeatmapSet == null || ReferenceEquals(beatmapSet, onlineBeatmapSet))
|
||||
setBeatmapSet(beatmapSet, withHeartAnimation: false);
|
||||
};
|
||||
api.Queue(favouriteRequest);
|
||||
setLoading();
|
||||
|
||||
@@ -5,11 +5,14 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Audio;
|
||||
using osu.Framework.Audio.Sample;
|
||||
using osu.Framework.Audio.Track;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Extensions;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Colour;
|
||||
@@ -34,6 +37,7 @@ using osu.Game.Graphics.UserInterface;
|
||||
using osu.Game.Input.Bindings;
|
||||
using osu.Game.Localisation;
|
||||
using osu.Game.Online.API;
|
||||
using osu.Game.Online.API.Requests.Responses;
|
||||
using osu.Game.Overlays;
|
||||
using osu.Game.Overlays.Mods;
|
||||
using osu.Game.Overlays.Volume;
|
||||
@@ -133,8 +137,7 @@ namespace osu.Game.Screens.SelectV2
|
||||
[Resolved]
|
||||
private IDialogOverlay? dialogOverlay { get; set; }
|
||||
|
||||
[Cached]
|
||||
private RealmPopulatingOnlineLookupSource onlineLookupSource = new RealmPopulatingOnlineLookupSource();
|
||||
private readonly RealmPopulatingOnlineLookupSource onlineLookupSource = new RealmPopulatingOnlineLookupSource();
|
||||
|
||||
private Bindable<bool> configBackgroundBlur = null!;
|
||||
|
||||
@@ -349,6 +352,7 @@ namespace osu.Game.Screens.SelectV2
|
||||
ensurePlayingSelected();
|
||||
updateBackgroundDim();
|
||||
updateWedgeVisibility();
|
||||
fetchOnlineInfo();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -954,6 +958,74 @@ namespace osu.Game.Screens.SelectV2
|
||||
|
||||
#endregion
|
||||
|
||||
#region Online lookups
|
||||
|
||||
public enum BeatmapSetLookupStatus
|
||||
{
|
||||
InProgress,
|
||||
Completed,
|
||||
}
|
||||
|
||||
public class BeatmapSetLookupResult
|
||||
{
|
||||
public BeatmapSetLookupStatus Status { get; }
|
||||
public APIBeatmapSet? Result { get; }
|
||||
|
||||
private BeatmapSetLookupResult(BeatmapSetLookupStatus status, APIBeatmapSet? result)
|
||||
{
|
||||
Status = status;
|
||||
Result = result;
|
||||
}
|
||||
|
||||
public static BeatmapSetLookupResult InProgress() => new BeatmapSetLookupResult(BeatmapSetLookupStatus.InProgress, null);
|
||||
public static BeatmapSetLookupResult Completed(APIBeatmapSet? beatmapSet) => new BeatmapSetLookupResult(BeatmapSetLookupStatus.Completed, beatmapSet);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Result of the latest online beatmap set lookup.
|
||||
/// Note that this being <see langword="null"/> or <see cref="BeatmapSetLookupResult.InProgress"/> is different from
|
||||
/// being a <see cref="BeatmapSetLookupResult.Completed"/> with a <see cref="BeatmapSetLookupResult.Result"/> of null.
|
||||
/// The former indicates a lookup never occurring or being in progress, while the latter indicates a completed lookup with no result.
|
||||
/// </summary>
|
||||
[Cached(typeof(IBindable<BeatmapSetLookupResult?>))]
|
||||
private readonly Bindable<BeatmapSetLookupResult?> lastLookupResult = new Bindable<BeatmapSetLookupResult?>();
|
||||
|
||||
private CancellationTokenSource? onlineLookupCancellation;
|
||||
private Task<APIBeatmapSet?>? currentOnlineLookup;
|
||||
|
||||
private void fetchOnlineInfo()
|
||||
{
|
||||
var beatmapSetInfo = Beatmap.Value.BeatmapSetInfo;
|
||||
|
||||
if (lastLookupResult.Value?.Result?.OnlineID == beatmapSetInfo.OnlineID)
|
||||
return;
|
||||
|
||||
onlineLookupCancellation?.Cancel();
|
||||
|
||||
if (beatmapSetInfo.OnlineID < 0)
|
||||
{
|
||||
lastLookupResult.Value = BeatmapSetLookupResult.Completed(null);
|
||||
return;
|
||||
}
|
||||
|
||||
lastLookupResult.Value = BeatmapSetLookupResult.InProgress();
|
||||
onlineLookupCancellation = new CancellationTokenSource();
|
||||
currentOnlineLookup = onlineLookupSource.GetBeatmapSetAsync(beatmapSetInfo.OnlineID);
|
||||
currentOnlineLookup.ContinueWith(t =>
|
||||
{
|
||||
if (t.IsCompletedSuccessfully)
|
||||
Schedule(() => lastLookupResult.Value = BeatmapSetLookupResult.Completed(t.GetResultSafely()));
|
||||
|
||||
if (t.Exception != null)
|
||||
{
|
||||
Logger.Log($"Error when fetching online beatmap set: {t.Exception}", LoggingTarget.Network);
|
||||
Schedule(() => lastLookupResult.Value = BeatmapSetLookupResult.Completed(null));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Implementation of ISongSelect
|
||||
|
||||
void ISongSelect.Search(string query) => filterControl.Search(query);
|
||||
|
||||
Reference in New Issue
Block a user