mirror of
https://github.com/ppy/osu.git
synced 2024-11-15 10:27:35 +08:00
Merge pull request #30526 from smoogipoo/fix-beatmap-recommender-test
Fix intermittent beatmap recommendations test
This commit is contained in:
commit
aad9f4078e
@ -10,9 +10,12 @@ using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Extensions.IEnumerableExtensions;
|
||||
using osu.Framework.Platform;
|
||||
using osu.Framework.Testing;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Database;
|
||||
using osu.Game.Extensions;
|
||||
using osu.Game.Online.API;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Rulesets.Catch;
|
||||
using osu.Game.Rulesets.Mania;
|
||||
@ -191,8 +194,39 @@ namespace osu.Game.Tests.Visual.SongSelect
|
||||
{
|
||||
AddStep("present beatmap", () => Game.PresentBeatmap(getImport()));
|
||||
|
||||
AddUntilStep("wait for song select", () => Game.ScreenStack.CurrentScreen is Screens.Select.SongSelect);
|
||||
AddUntilStep("wait for song select", () => Game.ScreenStack.CurrentScreen is Screens.Select.SongSelect select && select.BeatmapSetsLoaded);
|
||||
AddUntilStep("recommended beatmap displayed", () => Game.Beatmap.Value.BeatmapInfo.MatchesOnlineID(getImport().Beatmaps[expectedDiff - 1]));
|
||||
}
|
||||
|
||||
protected override TestOsuGame CreateTestGame() => new NoBeatmapUpdateGame(LocalStorage, API);
|
||||
|
||||
private partial class NoBeatmapUpdateGame : TestOsuGame
|
||||
{
|
||||
public NoBeatmapUpdateGame(Storage storage, IAPIProvider api, string[] args = null)
|
||||
: base(storage, api, args)
|
||||
{
|
||||
}
|
||||
|
||||
protected override IBeatmapUpdater CreateBeatmapUpdater() => new TestBeatmapUpdater();
|
||||
|
||||
private class TestBeatmapUpdater : IBeatmapUpdater
|
||||
{
|
||||
public void Queue(Live<BeatmapSetInfo> beatmapSet, MetadataLookupScope lookupScope = MetadataLookupScope.LocalCacheFirst)
|
||||
{
|
||||
}
|
||||
|
||||
public void Process(BeatmapSetInfo beatmapSet, MetadataLookupScope lookupScope = MetadataLookupScope.LocalCacheFirst)
|
||||
{
|
||||
}
|
||||
|
||||
public void ProcessObjectCounts(BeatmapInfo beatmapInfo, MetadataLookupScope lookupScope = MetadataLookupScope.LocalCacheFirst)
|
||||
{
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -13,11 +13,11 @@ namespace osu.Game.Beatmaps
|
||||
/// </summary>
|
||||
public partial class BeatmapOnlineChangeIngest : Component
|
||||
{
|
||||
private readonly BeatmapUpdater beatmapUpdater;
|
||||
private readonly IBeatmapUpdater beatmapUpdater;
|
||||
private readonly RealmAccess realm;
|
||||
private readonly MetadataClient metadataClient;
|
||||
|
||||
public BeatmapOnlineChangeIngest(BeatmapUpdater beatmapUpdater, RealmAccess realm, MetadataClient metadataClient)
|
||||
public BeatmapOnlineChangeIngest(IBeatmapUpdater beatmapUpdater, RealmAccess realm, MetadataClient metadataClient)
|
||||
{
|
||||
this.beatmapUpdater = beatmapUpdater;
|
||||
this.realm = realm;
|
||||
|
@ -1,7 +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.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
@ -15,10 +14,7 @@ using osu.Game.Rulesets.Objects.Types;
|
||||
|
||||
namespace osu.Game.Beatmaps
|
||||
{
|
||||
/// <summary>
|
||||
/// Handles all processing required to ensure a local beatmap is in a consistent state with any changes.
|
||||
/// </summary>
|
||||
public class BeatmapUpdater : IDisposable
|
||||
public class BeatmapUpdater : IBeatmapUpdater
|
||||
{
|
||||
private readonly IWorkingBeatmapCache workingBeatmapCache;
|
||||
|
||||
@ -38,11 +34,6 @@ namespace osu.Game.Beatmaps
|
||||
metadataLookup = new BeatmapUpdaterMetadataLookup(api, storage);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Queue a beatmap for background processing.
|
||||
/// </summary>
|
||||
/// <param name="beatmapSet">The managed beatmap set to update. A transaction will be opened to apply changes.</param>
|
||||
/// <param name="lookupScope">The preferred scope to use for metadata lookup.</param>
|
||||
public void Queue(Live<BeatmapSetInfo> beatmapSet, MetadataLookupScope lookupScope = MetadataLookupScope.LocalCacheFirst)
|
||||
{
|
||||
Logger.Log($"Queueing change for local beatmap {beatmapSet}");
|
||||
@ -50,55 +41,56 @@ namespace osu.Game.Beatmaps
|
||||
updateScheduler);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Run all processing on a beatmap immediately.
|
||||
/// </summary>
|
||||
/// <param name="beatmapSet">The managed beatmap set to update. A transaction will be opened to apply changes.</param>
|
||||
/// <param name="lookupScope">The preferred scope to use for metadata lookup.</param>
|
||||
public void Process(BeatmapSetInfo beatmapSet, MetadataLookupScope lookupScope = MetadataLookupScope.LocalCacheFirst) => beatmapSet.Realm!.Write(_ =>
|
||||
public void Process(BeatmapSetInfo beatmapSet, MetadataLookupScope lookupScope = MetadataLookupScope.LocalCacheFirst)
|
||||
{
|
||||
// Before we use below, we want to invalidate.
|
||||
workingBeatmapCache.Invalidate(beatmapSet);
|
||||
|
||||
if (lookupScope != MetadataLookupScope.None)
|
||||
metadataLookup.Update(beatmapSet, lookupScope == MetadataLookupScope.OnlineFirst);
|
||||
|
||||
foreach (var beatmap in beatmapSet.Beatmaps)
|
||||
beatmapSet.Realm!.Write(_ =>
|
||||
{
|
||||
difficultyCache.Invalidate(beatmap);
|
||||
// Before we use below, we want to invalidate.
|
||||
workingBeatmapCache.Invalidate(beatmapSet);
|
||||
|
||||
var working = workingBeatmapCache.GetWorkingBeatmap(beatmap);
|
||||
var ruleset = working.BeatmapInfo.Ruleset.CreateInstance();
|
||||
if (lookupScope != MetadataLookupScope.None)
|
||||
metadataLookup.Update(beatmapSet, lookupScope == MetadataLookupScope.OnlineFirst);
|
||||
|
||||
Debug.Assert(ruleset != null);
|
||||
foreach (var beatmap in beatmapSet.Beatmaps)
|
||||
{
|
||||
difficultyCache.Invalidate(beatmap);
|
||||
|
||||
var calculator = ruleset.CreateDifficultyCalculator(working);
|
||||
var working = workingBeatmapCache.GetWorkingBeatmap(beatmap);
|
||||
var ruleset = working.BeatmapInfo.Ruleset.CreateInstance();
|
||||
|
||||
beatmap.StarRating = calculator.Calculate().StarRating;
|
||||
beatmap.Length = working.Beatmap.CalculatePlayableLength();
|
||||
beatmap.BPM = 60000 / working.Beatmap.GetMostCommonBeatLength();
|
||||
beatmap.EndTimeObjectCount = working.Beatmap.HitObjects.Count(h => h is IHasDuration);
|
||||
beatmap.TotalObjectCount = working.Beatmap.HitObjects.Count;
|
||||
}
|
||||
Debug.Assert(ruleset != null);
|
||||
|
||||
// And invalidate again afterwards as re-fetching the most up-to-date database metadata will be required.
|
||||
workingBeatmapCache.Invalidate(beatmapSet);
|
||||
});
|
||||
var calculator = ruleset.CreateDifficultyCalculator(working);
|
||||
|
||||
public void ProcessObjectCounts(BeatmapInfo beatmapInfo, MetadataLookupScope lookupScope = MetadataLookupScope.LocalCacheFirst) => beatmapInfo.Realm!.Write(_ =>
|
||||
beatmap.StarRating = calculator.Calculate().StarRating;
|
||||
beatmap.Length = working.Beatmap.CalculatePlayableLength();
|
||||
beatmap.BPM = 60000 / working.Beatmap.GetMostCommonBeatLength();
|
||||
beatmap.EndTimeObjectCount = working.Beatmap.HitObjects.Count(h => h is IHasDuration);
|
||||
beatmap.TotalObjectCount = working.Beatmap.HitObjects.Count;
|
||||
}
|
||||
|
||||
// And invalidate again afterwards as re-fetching the most up-to-date database metadata will be required.
|
||||
workingBeatmapCache.Invalidate(beatmapSet);
|
||||
});
|
||||
}
|
||||
|
||||
public void ProcessObjectCounts(BeatmapInfo beatmapInfo, MetadataLookupScope lookupScope = MetadataLookupScope.LocalCacheFirst)
|
||||
{
|
||||
// Before we use below, we want to invalidate.
|
||||
workingBeatmapCache.Invalidate(beatmapInfo);
|
||||
beatmapInfo.Realm!.Write(_ =>
|
||||
{
|
||||
// Before we use below, we want to invalidate.
|
||||
workingBeatmapCache.Invalidate(beatmapInfo);
|
||||
|
||||
var working = workingBeatmapCache.GetWorkingBeatmap(beatmapInfo);
|
||||
var beatmap = working.Beatmap;
|
||||
var working = workingBeatmapCache.GetWorkingBeatmap(beatmapInfo);
|
||||
var beatmap = working.Beatmap;
|
||||
|
||||
beatmapInfo.EndTimeObjectCount = beatmap.HitObjects.Count(h => h is IHasDuration);
|
||||
beatmapInfo.TotalObjectCount = beatmap.HitObjects.Count;
|
||||
beatmapInfo.EndTimeObjectCount = beatmap.HitObjects.Count(h => h is IHasDuration);
|
||||
beatmapInfo.TotalObjectCount = beatmap.HitObjects.Count;
|
||||
|
||||
// And invalidate again afterwards as re-fetching the most up-to-date database metadata will be required.
|
||||
workingBeatmapCache.Invalidate(beatmapInfo);
|
||||
});
|
||||
// And invalidate again afterwards as re-fetching the most up-to-date database metadata will be required.
|
||||
workingBeatmapCache.Invalidate(beatmapInfo);
|
||||
});
|
||||
}
|
||||
|
||||
#region Implementation of IDisposable
|
||||
|
||||
|
35
osu.Game/Beatmaps/IBeatmapUpdater.cs
Normal file
35
osu.Game/Beatmaps/IBeatmapUpdater.cs
Normal file
@ -0,0 +1,35 @@
|
||||
// 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 osu.Game.Database;
|
||||
|
||||
namespace osu.Game.Beatmaps
|
||||
{
|
||||
/// <summary>
|
||||
/// Handles all processing required to ensure a local beatmap is in a consistent state with any changes.
|
||||
/// </summary>
|
||||
public interface IBeatmapUpdater : IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// Queue a beatmap for background processing.
|
||||
/// </summary>
|
||||
/// <param name="beatmapSet">The managed beatmap set to update. A transaction will be opened to apply changes.</param>
|
||||
/// <param name="lookupScope">The preferred scope to use for metadata lookup.</param>
|
||||
void Queue(Live<BeatmapSetInfo> beatmapSet, MetadataLookupScope lookupScope = MetadataLookupScope.LocalCacheFirst);
|
||||
|
||||
/// <summary>
|
||||
/// Run all processing on a beatmap immediately.
|
||||
/// </summary>
|
||||
/// <param name="beatmapSet">The managed beatmap set to update. A transaction will be opened to apply changes.</param>
|
||||
/// <param name="lookupScope">The preferred scope to use for metadata lookup.</param>
|
||||
void Process(BeatmapSetInfo beatmapSet, MetadataLookupScope lookupScope = MetadataLookupScope.LocalCacheFirst);
|
||||
|
||||
/// <summary>
|
||||
/// Runs a subset of processing focused on updating any cached beatmap object counts.
|
||||
/// </summary>
|
||||
/// <param name="beatmapInfo">The managed beatmap to update. A transaction will be opened to apply changes.</param>
|
||||
/// <param name="lookupScope">The preferred scope to use for metadata lookup.</param>
|
||||
void ProcessObjectCounts(BeatmapInfo beatmapInfo, MetadataLookupScope lookupScope = MetadataLookupScope.LocalCacheFirst);
|
||||
}
|
||||
}
|
@ -46,7 +46,7 @@ namespace osu.Game.Database
|
||||
private RealmAccess realmAccess { get; set; } = null!;
|
||||
|
||||
[Resolved]
|
||||
private BeatmapUpdater beatmapUpdater { get; set; } = null!;
|
||||
private IBeatmapUpdater beatmapUpdater { get; set; } = null!;
|
||||
|
||||
[Resolved]
|
||||
private IBindable<WorkingBeatmap> gameBeatmap { get; set; } = null!;
|
||||
|
@ -198,7 +198,7 @@ namespace osu.Game
|
||||
public readonly Bindable<Dictionary<ModType, IReadOnlyList<Mod>>> AvailableMods = new Bindable<Dictionary<ModType, IReadOnlyList<Mod>>>(new Dictionary<ModType, IReadOnlyList<Mod>>());
|
||||
|
||||
private BeatmapDifficultyCache difficultyCache;
|
||||
private BeatmapUpdater beatmapUpdater;
|
||||
private IBeatmapUpdater beatmapUpdater;
|
||||
|
||||
private UserLookupCache userCache;
|
||||
private BeatmapLookupCache beatmapCache;
|
||||
@ -324,7 +324,7 @@ namespace osu.Game
|
||||
base.Content.Add(difficultyCache);
|
||||
|
||||
// TODO: OsuGame or OsuGameBase?
|
||||
dependencies.CacheAs(beatmapUpdater = new BeatmapUpdater(BeatmapManager, difficultyCache, API, Storage));
|
||||
dependencies.CacheAs(beatmapUpdater = CreateBeatmapUpdater());
|
||||
dependencies.CacheAs(SpectatorClient = new OnlineSpectatorClient(endpoints));
|
||||
dependencies.CacheAs(MultiplayerClient = new OnlineMultiplayerClient(endpoints));
|
||||
dependencies.CacheAs(metadataClient = new OnlineMetadataClient(endpoints));
|
||||
@ -563,6 +563,8 @@ namespace osu.Game
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual IBeatmapUpdater CreateBeatmapUpdater() => new BeatmapUpdater(BeatmapManager, difficultyCache, API, Storage);
|
||||
|
||||
protected override UserInputManager CreateUserInputManager() => new OsuUserInputManager();
|
||||
|
||||
protected virtual BatteryInfo CreateBatteryInfo() => null;
|
||||
|
Loading…
Reference in New Issue
Block a user