mirror of
https://github.com/ppy/osu.git
synced 2025-02-13 12:43:16 +08:00
Merge branch 'master' into legacy-score-encoder-no-beatmap-required
This commit is contained in:
commit
f627a8af30
@ -23,7 +23,7 @@ namespace osu.Game.Rulesets.Taiko.Mods
|
||||
{
|
||||
get
|
||||
{
|
||||
string scrollSpeed = ScrollSpeed.IsDefault ? string.Empty : $"Scroll x{ScrollSpeed.Value:N1}";
|
||||
string scrollSpeed = ScrollSpeed.IsDefault ? string.Empty : $"Scroll x{ScrollSpeed.Value:N2}";
|
||||
|
||||
return string.Join(", ", new[]
|
||||
{
|
||||
|
@ -4,8 +4,10 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Extensions;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Tests.Resources;
|
||||
@ -18,6 +20,33 @@ namespace osu.Game.Tests.Database
|
||||
[TestFixture]
|
||||
public class RealmSubscriptionRegistrationTests : RealmTest
|
||||
{
|
||||
[Test]
|
||||
public void TestSubscriptionWithAsyncWrite()
|
||||
{
|
||||
ChangeSet? lastChanges = null;
|
||||
|
||||
RunTestWithRealm((realm, _) =>
|
||||
{
|
||||
var registration = realm.RegisterForNotifications(r => r.All<BeatmapSetInfo>(), onChanged);
|
||||
|
||||
realm.Run(r => r.Refresh());
|
||||
|
||||
// Without forcing the write onto its own thread, realm will internally run the operation synchronously, which can cause a deadlock with `WaitSafely`.
|
||||
Task.Run(async () =>
|
||||
{
|
||||
await realm.WriteAsync(r => r.Add(TestResources.CreateTestBeatmapSetInfo()));
|
||||
}).WaitSafely();
|
||||
|
||||
realm.Run(r => r.Refresh());
|
||||
|
||||
Assert.That(lastChanges?.InsertedIndices, Has.One.Items);
|
||||
|
||||
registration.Dispose();
|
||||
});
|
||||
|
||||
void onChanged(IRealmCollection<BeatmapSetInfo> sender, ChangeSet? changes, Exception error) => lastChanges = changes;
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestSubscriptionWithContextLoss()
|
||||
{
|
||||
|
@ -17,10 +17,13 @@ using osu.Game.Database;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using osu.Game.Online.API;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Rulesets.Difficulty;
|
||||
using osu.Game.Rulesets.Osu;
|
||||
using osu.Game.Scoring;
|
||||
using osu.Game.Screens;
|
||||
using osu.Game.Screens.Play;
|
||||
using osu.Game.Screens.Ranking;
|
||||
using osu.Game.Screens.Ranking.Expanded.Statistics;
|
||||
using osu.Game.Screens.Ranking.Statistics;
|
||||
using osu.Game.Tests.Resources;
|
||||
using osuTK;
|
||||
@ -256,6 +259,23 @@ namespace osu.Game.Tests.Visual.Ranking
|
||||
AddAssert("download button is enabled", () => screen.ChildrenOfType<DownloadButton>().Last().Enabled.Value);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestRulesetWithNoPerformanceCalculator()
|
||||
{
|
||||
var ruleset = new RulesetWithNoPerformanceCalculator();
|
||||
var score = TestResources.CreateTestScoreInfo(ruleset.RulesetInfo);
|
||||
|
||||
AddStep("load results", () => Child = new TestResultsContainer(createResultsScreen(score)));
|
||||
AddUntilStep("wait for load", () => this.ChildrenOfType<ScorePanelList>().Single().AllPanelsVisible);
|
||||
|
||||
AddAssert("PP displayed as 0", () =>
|
||||
{
|
||||
var performance = this.ChildrenOfType<PerformanceStatistic>().Single();
|
||||
var counter = performance.ChildrenOfType<StatisticCounter>().Single();
|
||||
return counter.Current.Value == 0;
|
||||
});
|
||||
}
|
||||
|
||||
private TestResultsScreen createResultsScreen(ScoreInfo score = null) => new TestResultsScreen(score ?? TestResources.CreateTestScoreInfo());
|
||||
|
||||
private UnrankedSoloResultsScreen createUnrankedSoloResultsScreen() => new UnrankedSoloResultsScreen(TestResources.CreateTestScoreInfo());
|
||||
@ -367,5 +387,10 @@ namespace osu.Game.Tests.Visual.Ranking
|
||||
RetryOverlay = InternalChildren.OfType<HotkeyRetryOverlay>().SingleOrDefault();
|
||||
}
|
||||
}
|
||||
|
||||
private class RulesetWithNoPerformanceCalculator : OsuRuleset
|
||||
{
|
||||
public override PerformanceCalculator CreatePerformanceCalculator(DifficultyAttributes attributes, ScoreInfo score) => null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8,20 +8,21 @@ using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Development;
|
||||
using osu.Framework.Input.Bindings;
|
||||
using osu.Framework.Logging;
|
||||
using osu.Framework.Platform;
|
||||
using osu.Framework.Statistics;
|
||||
using osu.Game.Configuration;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Configuration;
|
||||
using osu.Game.Input.Bindings;
|
||||
using osu.Game.Models;
|
||||
using osu.Game.Skinning;
|
||||
using osu.Game.Stores;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Scoring;
|
||||
using osu.Game.Skinning;
|
||||
using osu.Game.Stores;
|
||||
using Realms;
|
||||
using Realms.Exceptions;
|
||||
|
||||
@ -85,6 +86,14 @@ namespace osu.Game.Database
|
||||
|
||||
private static readonly GlobalStatistic<int> total_subscriptions = GlobalStatistics.Get<int>(@"Realm", @"Subscriptions");
|
||||
|
||||
private static readonly GlobalStatistic<int> total_reads_update = GlobalStatistics.Get<int>(@"Realm", @"Reads (Update)");
|
||||
|
||||
private static readonly GlobalStatistic<int> total_reads_async = GlobalStatistics.Get<int>(@"Realm", @"Reads (Async)");
|
||||
|
||||
private static readonly GlobalStatistic<int> total_writes_update = GlobalStatistics.Get<int>(@"Realm", @"Writes (Update)");
|
||||
|
||||
private static readonly GlobalStatistic<int> total_writes_async = GlobalStatistics.Get<int>(@"Realm", @"Writes (Async)");
|
||||
|
||||
private readonly object realmLock = new object();
|
||||
|
||||
private Realm? updateRealm;
|
||||
@ -213,8 +222,12 @@ namespace osu.Game.Database
|
||||
public T Run<T>(Func<Realm, T> action)
|
||||
{
|
||||
if (ThreadSafety.IsUpdateThread)
|
||||
{
|
||||
total_reads_update.Value++;
|
||||
return action(Realm);
|
||||
}
|
||||
|
||||
total_reads_async.Value++;
|
||||
using (var realm = getRealmInstance())
|
||||
return action(realm);
|
||||
}
|
||||
@ -226,9 +239,13 @@ namespace osu.Game.Database
|
||||
public void Run(Action<Realm> action)
|
||||
{
|
||||
if (ThreadSafety.IsUpdateThread)
|
||||
{
|
||||
total_reads_update.Value++;
|
||||
action(Realm);
|
||||
}
|
||||
else
|
||||
{
|
||||
total_reads_async.Value++;
|
||||
using (var realm = getRealmInstance())
|
||||
action(realm);
|
||||
}
|
||||
@ -241,14 +258,30 @@ namespace osu.Game.Database
|
||||
public void Write(Action<Realm> action)
|
||||
{
|
||||
if (ThreadSafety.IsUpdateThread)
|
||||
{
|
||||
total_writes_update.Value++;
|
||||
Realm.Write(action);
|
||||
}
|
||||
else
|
||||
{
|
||||
total_writes_async.Value++;
|
||||
|
||||
using (var realm = getRealmInstance())
|
||||
realm.Write(action);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write changes to realm asynchronously, guaranteeing order of execution.
|
||||
/// </summary>
|
||||
/// <param name="action">The work to run.</param>
|
||||
public async Task WriteAsync(Action<Realm> action)
|
||||
{
|
||||
total_writes_async.Value++;
|
||||
using (var realm = getRealmInstance())
|
||||
await realm.WriteAsync(action);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Subscribe to a realm collection and begin watching for asynchronous changes.
|
||||
/// </summary>
|
||||
|
@ -38,7 +38,7 @@ namespace osu.Game.Screens.Ranking.Expanded.Statistics
|
||||
else
|
||||
{
|
||||
performanceCache.CalculatePerformanceAsync(score, cancellationTokenSource.Token)
|
||||
.ContinueWith(t => Schedule(() => setPerformanceValue(t.GetResultSafely().Total)), cancellationTokenSource.Token);
|
||||
.ContinueWith(t => Schedule(() => setPerformanceValue(t.GetResultSafely()?.Total)), cancellationTokenSource.Token);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user