1
0
mirror of https://github.com/ppy/osu.git synced 2024-09-21 22:07:25 +08:00

Merge branch 'master' into realm-fix-async-write-after-disposal

This commit is contained in:
Dean Herbert 2022-06-30 19:07:15 +09:00 committed by GitHub
commit 447b496eff
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 113 additions and 87 deletions

View File

@ -52,7 +52,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="ppy.osu.Game.Resources" Version="2022.628.0" />
<PackageReference Include="ppy.osu.Framework.Android" Version="2022.628.1" />
<PackageReference Include="ppy.osu.Framework.Android" Version="2022.629.0" />
</ItemGroup>
<ItemGroup Label="Transitive Dependencies">
<!-- Realm needs to be directly referenced in all Xamarin projects, as it will not pull in its transitive dependencies otherwise. -->

View File

@ -24,21 +24,24 @@ namespace osu.Game.Rulesets.Catch.Tests
new object[] { LegacyMods.DoubleTime, new[] { typeof(CatchModDoubleTime) } },
new object[] { LegacyMods.Relax, new[] { typeof(CatchModRelax) } },
new object[] { LegacyMods.HalfTime, new[] { typeof(CatchModHalfTime) } },
new object[] { LegacyMods.Nightcore, new[] { typeof(CatchModNightcore) } },
new object[] { LegacyMods.Flashlight, new[] { typeof(CatchModFlashlight) } },
new object[] { LegacyMods.Autoplay, new[] { typeof(CatchModAutoplay) } },
new object[] { LegacyMods.Perfect, new[] { typeof(CatchModPerfect) } },
new object[] { LegacyMods.Cinema, new[] { typeof(CatchModCinema) } },
new object[] { LegacyMods.HardRock | LegacyMods.DoubleTime, new[] { typeof(CatchModHardRock), typeof(CatchModDoubleTime) } }
};
[TestCaseSource(nameof(catch_mod_mapping))]
[TestCase(LegacyMods.Cinema, new[] { typeof(CatchModCinema) })]
[TestCase(LegacyMods.Cinema | LegacyMods.Autoplay, new[] { typeof(CatchModCinema) })]
[TestCase(LegacyMods.Nightcore, new[] { typeof(CatchModNightcore) })]
[TestCase(LegacyMods.Nightcore | LegacyMods.DoubleTime, new[] { typeof(CatchModNightcore) })]
[TestCase(LegacyMods.Perfect, new[] { typeof(CatchModPerfect) })]
[TestCase(LegacyMods.Perfect | LegacyMods.SuddenDeath, new[] { typeof(CatchModPerfect) })]
public new void TestFromLegacy(LegacyMods legacyMods, Type[] expectedMods) => base.TestFromLegacy(legacyMods, expectedMods);
[TestCaseSource(nameof(catch_mod_mapping))]
[TestCase(LegacyMods.Cinema | LegacyMods.Autoplay, new[] { typeof(CatchModCinema) })]
[TestCase(LegacyMods.Nightcore | LegacyMods.DoubleTime, new[] { typeof(CatchModNightcore) })]
[TestCase(LegacyMods.Perfect | LegacyMods.SuddenDeath, new[] { typeof(CatchModPerfect) })]
public new void TestFromLegacy(LegacyMods legacyMods, Type[] expectedMods) => base.TestFromLegacy(legacyMods, expectedMods);
[TestCaseSource(nameof(catch_mod_mapping))]
public new void TestToLegacy(LegacyMods legacyMods, Type[] givenMods) => base.TestToLegacy(legacyMods, givenMods);
protected override Ruleset CreateRuleset() => new CatchRuleset();

View File

@ -23,10 +23,8 @@ namespace osu.Game.Rulesets.Mania.Tests
new object[] { LegacyMods.SuddenDeath, new[] { typeof(ManiaModSuddenDeath) } },
new object[] { LegacyMods.DoubleTime, new[] { typeof(ManiaModDoubleTime) } },
new object[] { LegacyMods.HalfTime, new[] { typeof(ManiaModHalfTime) } },
new object[] { LegacyMods.Nightcore, new[] { typeof(ManiaModNightcore) } },
new object[] { LegacyMods.Flashlight, new[] { typeof(ManiaModFlashlight) } },
new object[] { LegacyMods.Autoplay, new[] { typeof(ManiaModAutoplay) } },
new object[] { LegacyMods.Perfect, new[] { typeof(ManiaModPerfect) } },
new object[] { LegacyMods.Key4, new[] { typeof(ManiaModKey4) } },
new object[] { LegacyMods.Key5, new[] { typeof(ManiaModKey5) } },
new object[] { LegacyMods.Key6, new[] { typeof(ManiaModKey6) } },
@ -34,7 +32,6 @@ namespace osu.Game.Rulesets.Mania.Tests
new object[] { LegacyMods.Key8, new[] { typeof(ManiaModKey8) } },
new object[] { LegacyMods.FadeIn, new[] { typeof(ManiaModFadeIn) } },
new object[] { LegacyMods.Random, new[] { typeof(ManiaModRandom) } },
new object[] { LegacyMods.Cinema, new[] { typeof(ManiaModCinema) } },
new object[] { LegacyMods.Key9, new[] { typeof(ManiaModKey9) } },
new object[] { LegacyMods.KeyCoop, new[] { typeof(ManiaModDualStages) } },
new object[] { LegacyMods.Key1, new[] { typeof(ManiaModKey1) } },
@ -45,12 +42,18 @@ namespace osu.Game.Rulesets.Mania.Tests
};
[TestCaseSource(nameof(mania_mod_mapping))]
[TestCase(LegacyMods.Cinema, new[] { typeof(ManiaModCinema) })]
[TestCase(LegacyMods.Cinema | LegacyMods.Autoplay, new[] { typeof(ManiaModCinema) })]
[TestCase(LegacyMods.Nightcore, new[] { typeof(ManiaModNightcore) })]
[TestCase(LegacyMods.Nightcore | LegacyMods.DoubleTime, new[] { typeof(ManiaModNightcore) })]
[TestCase(LegacyMods.Perfect, new[] { typeof(ManiaModPerfect) })]
[TestCase(LegacyMods.Perfect | LegacyMods.SuddenDeath, new[] { typeof(ManiaModPerfect) })]
public new void TestFromLegacy(LegacyMods legacyMods, Type[] expectedMods) => base.TestFromLegacy(legacyMods, expectedMods);
[TestCaseSource(nameof(mania_mod_mapping))]
[TestCase(LegacyMods.Cinema | LegacyMods.Autoplay, new[] { typeof(ManiaModCinema) })]
[TestCase(LegacyMods.Nightcore | LegacyMods.DoubleTime, new[] { typeof(ManiaModNightcore) })]
[TestCase(LegacyMods.Perfect | LegacyMods.SuddenDeath, new[] { typeof(ManiaModPerfect) })]
public new void TestToLegacy(LegacyMods legacyMods, Type[] givenMods) => base.TestToLegacy(legacyMods, givenMods);
protected override Ruleset CreateRuleset() => new ManiaRuleset();

View File

@ -25,24 +25,27 @@ namespace osu.Game.Rulesets.Osu.Tests
new object[] { LegacyMods.DoubleTime, new[] { typeof(OsuModDoubleTime) } },
new object[] { LegacyMods.Relax, new[] { typeof(OsuModRelax) } },
new object[] { LegacyMods.HalfTime, new[] { typeof(OsuModHalfTime) } },
new object[] { LegacyMods.Nightcore, new[] { typeof(OsuModNightcore) } },
new object[] { LegacyMods.Flashlight, new[] { typeof(OsuModFlashlight) } },
new object[] { LegacyMods.Autoplay, new[] { typeof(OsuModAutoplay) } },
new object[] { LegacyMods.SpunOut, new[] { typeof(OsuModSpunOut) } },
new object[] { LegacyMods.Autopilot, new[] { typeof(OsuModAutopilot) } },
new object[] { LegacyMods.Perfect, new[] { typeof(OsuModPerfect) } },
new object[] { LegacyMods.Cinema, new[] { typeof(OsuModCinema) } },
new object[] { LegacyMods.Target, new[] { typeof(OsuModTarget) } },
new object[] { LegacyMods.HardRock | LegacyMods.DoubleTime, new[] { typeof(OsuModHardRock), typeof(OsuModDoubleTime) } }
};
[TestCaseSource(nameof(osu_mod_mapping))]
[TestCase(LegacyMods.Cinema, new[] { typeof(OsuModCinema) })]
[TestCase(LegacyMods.Cinema | LegacyMods.Autoplay, new[] { typeof(OsuModCinema) })]
[TestCase(LegacyMods.Nightcore, new[] { typeof(OsuModNightcore) })]
[TestCase(LegacyMods.Nightcore | LegacyMods.DoubleTime, new[] { typeof(OsuModNightcore) })]
[TestCase(LegacyMods.Perfect, new[] { typeof(OsuModPerfect) })]
[TestCase(LegacyMods.Perfect | LegacyMods.SuddenDeath, new[] { typeof(OsuModPerfect) })]
public new void TestFromLegacy(LegacyMods legacyMods, Type[] expectedMods) => base.TestFromLegacy(legacyMods, expectedMods);
[TestCaseSource(nameof(osu_mod_mapping))]
[TestCase(LegacyMods.Cinema | LegacyMods.Autoplay, new[] { typeof(OsuModCinema) })]
[TestCase(LegacyMods.Nightcore | LegacyMods.DoubleTime, new[] { typeof(OsuModNightcore) })]
[TestCase(LegacyMods.Perfect | LegacyMods.SuddenDeath, new[] { typeof(OsuModPerfect) })]
public new void TestToLegacy(LegacyMods legacyMods, Type[] givenMods) => base.TestToLegacy(legacyMods, givenMods);
protected override Ruleset CreateRuleset() => new OsuRuleset();

View File

@ -24,22 +24,25 @@ namespace osu.Game.Rulesets.Taiko.Tests
new object[] { LegacyMods.DoubleTime, new[] { typeof(TaikoModDoubleTime) } },
new object[] { LegacyMods.Relax, new[] { typeof(TaikoModRelax) } },
new object[] { LegacyMods.HalfTime, new[] { typeof(TaikoModHalfTime) } },
new object[] { LegacyMods.Nightcore, new[] { typeof(TaikoModNightcore) } },
new object[] { LegacyMods.Flashlight, new[] { typeof(TaikoModFlashlight) } },
new object[] { LegacyMods.Autoplay, new[] { typeof(TaikoModAutoplay) } },
new object[] { LegacyMods.Perfect, new[] { typeof(TaikoModPerfect) } },
new object[] { LegacyMods.Random, new[] { typeof(TaikoModRandom) } },
new object[] { LegacyMods.Cinema, new[] { typeof(TaikoModCinema) } },
new object[] { LegacyMods.HardRock | LegacyMods.DoubleTime, new[] { typeof(TaikoModHardRock), typeof(TaikoModDoubleTime) } }
};
[TestCaseSource(nameof(taiko_mod_mapping))]
[TestCase(LegacyMods.Cinema, new[] { typeof(TaikoModCinema) })]
[TestCase(LegacyMods.Cinema | LegacyMods.Autoplay, new[] { typeof(TaikoModCinema) })]
[TestCase(LegacyMods.Nightcore, new[] { typeof(TaikoModNightcore) })]
[TestCase(LegacyMods.Nightcore | LegacyMods.DoubleTime, new[] { typeof(TaikoModNightcore) })]
[TestCase(LegacyMods.Perfect, new[] { typeof(TaikoModPerfect) })]
[TestCase(LegacyMods.Perfect | LegacyMods.SuddenDeath, new[] { typeof(TaikoModPerfect) })]
public new void TestFromLegacy(LegacyMods legacyMods, Type[] expectedMods) => base.TestFromLegacy(legacyMods, expectedMods);
[TestCaseSource(nameof(taiko_mod_mapping))]
[TestCase(LegacyMods.Cinema | LegacyMods.Autoplay, new[] { typeof(TaikoModCinema) })]
[TestCase(LegacyMods.Nightcore | LegacyMods.DoubleTime, new[] { typeof(TaikoModNightcore) })]
[TestCase(LegacyMods.Perfect | LegacyMods.SuddenDeath, new[] { typeof(TaikoModPerfect) })]
public new void TestFromLegacy(LegacyMods legacyMods, Type[] expectedMods) => base.TestFromLegacy(legacyMods, expectedMods);
[TestCaseSource(nameof(taiko_mod_mapping))]
public new void TestToLegacy(LegacyMods legacyMods, Type[] givenMods) => base.TestToLegacy(legacyMods, givenMods);
protected override Ruleset CreateRuleset() => new TaikoRuleset();

View File

@ -91,6 +91,25 @@ namespace osu.Game.Tests.Database
Assert.IsFalse(liveBeatmap.PerformRead(l => l.Hidden));
}
[Test]
public void TestTransactionRolledBackOnException()
{
RunTestWithRealm((realm, _) =>
{
var beatmap = new BeatmapInfo(CreateRuleset(), new BeatmapDifficulty(), new BeatmapMetadata());
realm.Run(r => r.Write(_ => r.Add(beatmap)));
var liveBeatmap = beatmap.ToLive(realm);
Assert.Throws<InvalidOperationException>(() => liveBeatmap.PerformWrite(l => throw new InvalidOperationException()));
Assert.IsFalse(liveBeatmap.PerformRead(l => l.Hidden));
liveBeatmap.PerformWrite(l => l.Hidden = true);
Assert.IsTrue(liveBeatmap.PerformRead(l => l.Hidden));
});
}
[Test]
public void TestScopedReadWithoutContext()
{

View File

@ -44,8 +44,7 @@ namespace osu.Game.Tests.NonVisual
[Test]
public void TestCustomDirectory()
{
string customPath = prepareCustomPath();
using (prepareCustomPath(out string customPath))
using (var host = new CustomTestHeadlessGameHost())
{
using (var storageConfig = new StorageConfigManager(host.InitialStorage))
@ -63,7 +62,6 @@ namespace osu.Game.Tests.NonVisual
finally
{
host.Exit();
cleanupPath(customPath);
}
}
}
@ -71,8 +69,7 @@ namespace osu.Game.Tests.NonVisual
[Test]
public void TestSubDirectoryLookup()
{
string customPath = prepareCustomPath();
using (prepareCustomPath(out string customPath))
using (var host = new CustomTestHeadlessGameHost())
{
using (var storageConfig = new StorageConfigManager(host.InitialStorage))
@ -97,7 +94,6 @@ namespace osu.Game.Tests.NonVisual
finally
{
host.Exit();
cleanupPath(customPath);
}
}
}
@ -105,8 +101,7 @@ namespace osu.Game.Tests.NonVisual
[Test]
public void TestMigration()
{
string customPath = prepareCustomPath();
using (prepareCustomPath(out string customPath))
using (var host = new CustomTestHeadlessGameHost())
{
try
@ -173,7 +168,6 @@ namespace osu.Game.Tests.NonVisual
finally
{
host.Exit();
cleanupPath(customPath);
}
}
}
@ -181,9 +175,8 @@ namespace osu.Game.Tests.NonVisual
[Test]
public void TestMigrationBetweenTwoTargets()
{
string customPath = prepareCustomPath();
string customPath2 = prepareCustomPath();
using (prepareCustomPath(out string customPath))
using (prepareCustomPath(out string customPath2))
using (var host = new CustomTestHeadlessGameHost())
{
try
@ -205,8 +198,6 @@ namespace osu.Game.Tests.NonVisual
finally
{
host.Exit();
cleanupPath(customPath);
cleanupPath(customPath2);
}
}
}
@ -214,8 +205,7 @@ namespace osu.Game.Tests.NonVisual
[Test]
public void TestMigrationToSameTargetFails()
{
string customPath = prepareCustomPath();
using (prepareCustomPath(out string customPath))
using (var host = new CustomTestHeadlessGameHost())
{
try
@ -228,7 +218,6 @@ namespace osu.Game.Tests.NonVisual
finally
{
host.Exit();
cleanupPath(customPath);
}
}
}
@ -236,9 +225,8 @@ namespace osu.Game.Tests.NonVisual
[Test]
public void TestMigrationFailsOnExistingData()
{
string customPath = prepareCustomPath();
string customPath2 = prepareCustomPath();
using (prepareCustomPath(out string customPath))
using (prepareCustomPath(out string customPath2))
using (var host = new CustomTestHeadlessGameHost())
{
try
@ -267,8 +255,6 @@ namespace osu.Game.Tests.NonVisual
finally
{
host.Exit();
cleanupPath(customPath);
cleanupPath(customPath2);
}
}
}
@ -276,8 +262,7 @@ namespace osu.Game.Tests.NonVisual
[Test]
public void TestMigrationToNestedTargetFails()
{
string customPath = prepareCustomPath();
using (prepareCustomPath(out string customPath))
using (var host = new CustomTestHeadlessGameHost())
{
try
@ -298,7 +283,6 @@ namespace osu.Game.Tests.NonVisual
finally
{
host.Exit();
cleanupPath(customPath);
}
}
}
@ -306,8 +290,7 @@ namespace osu.Game.Tests.NonVisual
[Test]
public void TestMigrationToSeeminglyNestedTarget()
{
string customPath = prepareCustomPath();
using (prepareCustomPath(out string customPath))
using (var host = new CustomTestHeadlessGameHost())
{
try
@ -328,7 +311,6 @@ namespace osu.Game.Tests.NonVisual
finally
{
host.Exit();
cleanupPath(customPath);
}
}
}
@ -343,14 +325,17 @@ namespace osu.Game.Tests.NonVisual
return path;
}
private static string prepareCustomPath() => Path.Combine(TestRunHeadlessGameHost.TemporaryTestDirectory, $"custom-path-{Guid.NewGuid()}");
private static IDisposable prepareCustomPath(out string path)
{
path = Path.Combine(TestRunHeadlessGameHost.TemporaryTestDirectory, $"custom-path-{Guid.NewGuid()}");
return new InvokeOnDisposal<string>(path, cleanupPath);
}
private static void cleanupPath(string path)
{
try
{
if (Directory.Exists(path))
Directory.Delete(path, true);
if (Directory.Exists(path)) Directory.Delete(path, true);
}
catch
{

View File

@ -6,18 +6,14 @@ using NUnit.Framework;
using osu.Framework.Extensions;
using osu.Framework.Extensions.IEnumerableExtensions;
using osu.Framework.Extensions.ObjectExtensions;
using osu.Framework.Testing;
using osu.Game.Beatmaps;
using osu.Game.Database;
using osu.Game.Overlays.Notifications;
using osu.Game.Rulesets.Mania;
using osu.Game.Rulesets.Osu;
using osu.Game.Screens.Edit;
using osu.Game.Screens.Edit.Components.Timelines.Summary;
using osu.Game.Screens.Edit.GameplayTest;
using osu.Game.Screens.Select;
using osu.Game.Tests.Resources;
using osuTK.Input;
namespace osu.Game.Tests.Visual.Editing
{
@ -36,20 +32,21 @@ namespace osu.Game.Tests.Visual.Editing
() => Game.Beatmap.Value.BeatmapSetInfo.Equals(beatmapSet)
&& Game.ScreenStack.CurrentScreen is PlaySongSelect songSelect
&& songSelect.IsLoaded);
AddUntilStep("wait for completion notification", () => Game.Notifications.ChildrenOfType<ProgressCompletionNotification>().Count() == 1);
AddStep("dismiss notifications", () => Game.Notifications.Hide());
AddStep("switch ruleset", () => Game.Ruleset.Value = new ManiaRuleset().RulesetInfo);
AddStep("open editor", () => ((PlaySongSelect)Game.ScreenStack.CurrentScreen).Edit(beatmapSet.Beatmaps.First(beatmap => beatmap.Ruleset.OnlineID == 0)));
AddUntilStep("wait for editor open", () => Game.ScreenStack.CurrentScreen is Editor editor && editor.ReadyForUse);
AddStep("test gameplay", () =>
AddStep("test gameplay", () => ((Editor)Game.ScreenStack.CurrentScreen).TestGameplay());
AddUntilStep("wait for player", () =>
{
var testGameplayButton = this.ChildrenOfType<TestGameplayButton>().Single();
InputManager.MoveMouseTo(testGameplayButton);
InputManager.Click(MouseButton.Left);
// notifications may fire at almost any inopportune time and cause annoying test failures.
// relentlessly attempt to dismiss any and all interfering overlays, which includes notifications.
// this is theoretically not foolproof, but it's the best that can be done here.
Game.CloseAllOverlays();
return Game.ScreenStack.CurrentScreen is EditorPlayer editorPlayer && editorPlayer.IsLoaded;
});
AddUntilStep("wait for player", () => Game.ScreenStack.CurrentScreen is EditorPlayer editorPlayer && editorPlayer.IsLoaded);
AddAssert("current ruleset is osu!", () => Game.Ruleset.Value.Equals(new OsuRuleset().RulesetInfo));
AddStep("exit to song select", () => Game.PerformFromScreen(_ => { }, typeof(PlaySongSelect).Yield()));

View File

@ -6,10 +6,10 @@
using System.ComponentModel;
using System.Linq;
using osu.Framework.Testing;
using osu.Game.Beatmaps.Timing;
using osu.Game.Graphics.Containers;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Osu;
using osu.Game.Rulesets.Scoring;
using osu.Game.Screens.Play;
using osu.Game.Screens.Play.Break;
@ -31,19 +31,20 @@ namespace osu.Game.Tests.Visual.Gameplay
protected override void AddCheckSteps()
{
// It doesn't matter which ruleset is used - this beatmap is only used for reference.
var beatmap = CreateWorkingBeatmap(new OsuRuleset().RulesetInfo);
AddUntilStep("score above zero", () => Player.ScoreProcessor.TotalScore.Value > 0);
AddUntilStep("key counter counted keys", () => Player.HUDOverlay.KeyCounter.Children.Any(kc => kc.CountPresses > 2));
seekToBreak(0);
seekTo(beatmap.Beatmap.Breaks[0].StartTime);
AddAssert("keys not counting", () => !Player.HUDOverlay.KeyCounter.IsCounting);
AddAssert("overlay displays 100% accuracy", () => Player.BreakOverlay.ChildrenOfType<BreakInfo>().Single().AccuracyDisplay.Current.Value == 1);
AddStep("rewind", () => Player.GameplayClockContainer.Seek(-80000));
AddUntilStep("key counter reset", () => Player.HUDOverlay.KeyCounter.Children.All(kc => kc.CountPresses == 0));
seekToBreak(0);
seekToBreak(1);
AddStep("seek to completion", () => Player.GameplayClockContainer.Seek(Player.DrawableRuleset.Objects.Last().GetEndTime()));
seekTo(beatmap.Beatmap.HitObjects[^1].GetEndTime());
AddUntilStep("results displayed", () => getResultsScreen()?.IsLoaded == true);
AddAssert("score has combo", () => getResultsScreen().Score.Combo > 100);
@ -58,12 +59,18 @@ namespace osu.Game.Tests.Visual.Gameplay
ResultsScreen getResultsScreen() => Stack.CurrentScreen as ResultsScreen;
}
private void seekToBreak(int breakIndex)
private void seekTo(double time)
{
AddStep($"seek to break {breakIndex}", () => Player.GameplayClockContainer.Seek(destBreak().StartTime));
AddUntilStep("wait for seek to complete", () => Player.DrawableRuleset.FrameStableClock.CurrentTime >= destBreak().StartTime);
AddStep($"seek to {time}", () => Player.GameplayClockContainer.Seek(time));
BreakPeriod destBreak() => Beatmap.Value.Beatmap.Breaks.ElementAt(breakIndex);
// Prevent test timeouts by seeking in 10 second increments.
for (double t = 0; t < time; t += 10000)
{
double expectedTime = t;
AddUntilStep($"current time >= {t}", () => Player.DrawableRuleset.FrameStableClock.CurrentTime >= expectedTime);
}
AddUntilStep("wait for seek to complete", () => Player.DrawableRuleset.FrameStableClock.CurrentTime >= time);
}
}
}

View File

@ -39,7 +39,8 @@ namespace osu.Game.Tests.Visual.Online
private TestChatOverlay chatOverlay;
private ChannelManager channelManager;
private APIUser testUser;
private readonly APIUser testUser = new APIUser { Username = "test user", Id = 5071479 };
private Channel[] testChannels;
private Channel testChannel1 => testChannels[0];
@ -51,7 +52,6 @@ namespace osu.Game.Tests.Visual.Online
[SetUp]
public void SetUp() => Schedule(() =>
{
testUser = new APIUser { Username = "test user", Id = 5071479 };
testChannels = Enumerable.Range(1, 10).Select(createPublicChannel).ToArray();
Child = new DependencyProvidingContainer

View File

@ -100,12 +100,13 @@ namespace osu.Game.Tests.Visual.SongSelect
[Test]
public void TestPlaceholderConvertSetting()
{
changeRuleset(2);
addRulesetImportStep(0);
AddStep("change convert setting", () => config.SetValue(OsuSetting.ShowConvertedBeatmaps, false));
createSongSelect();
changeRuleset(2);
AddUntilStep("wait for placeholder visible", () => getPlaceholder()?.State.Value == Visibility.Visible);
AddStep("click link in placeholder", () => getPlaceholder().ChildrenOfType<DrawableLinkCompiler>().First().TriggerClick());

View File

@ -104,9 +104,12 @@ namespace osu.Game.Database
PerformRead(t =>
{
var transaction = t.Realm.BeginWrite();
perform(t);
transaction.Commit();
using (var transaction = t.Realm.BeginWrite())
{
perform(t);
transaction.Commit();
}
RealmLiveStatistics.WRITES.Value++;
});
}

View File

@ -1,6 +1,7 @@
// 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 JetBrains.Annotations;
using osu.Framework.Testing;
using osu.Game.Database;
@ -19,8 +20,8 @@ namespace osu.Game.Models
public RealmNamedFileUsage(RealmFile file, string filename)
{
File = file;
Filename = filename;
File = file ?? throw new ArgumentNullException(nameof(file));
Filename = filename ?? throw new ArgumentNullException(nameof(filename));
}
[UsedImplicitly]

View File

@ -72,7 +72,7 @@ namespace osu.Game.Online.Rooms
/// In many cases, this will *not* contain any usable information apart from OnlineID.
/// </summary>
[JsonIgnore]
public IBeatmapInfo Beatmap { get; set; } = null!;
public IBeatmapInfo Beatmap { get; private set; }
[JsonIgnore]
public IBindable<bool> Valid => valid;
@ -81,6 +81,7 @@ namespace osu.Game.Online.Rooms
[JsonConstructor]
private PlaylistItem()
: this(new APIBeatmap())
{
}

View File

@ -143,7 +143,7 @@ namespace osu.Game.Rulesets
break;
case ModPerfect:
value |= LegacyMods.Perfect;
value |= LegacyMods.Perfect | LegacyMods.SuddenDeath;
break;
case ModSuddenDeath:
@ -151,7 +151,7 @@ namespace osu.Game.Rulesets
break;
case ModNightcore:
value |= LegacyMods.Nightcore;
value |= LegacyMods.Nightcore | LegacyMods.DoubleTime;
break;
case ModDoubleTime:
@ -171,7 +171,7 @@ namespace osu.Game.Rulesets
break;
case ModCinema:
value |= LegacyMods.Cinema;
value |= LegacyMods.Cinema | LegacyMods.Autoplay;
break;
case ModAutoplay:

View File

@ -36,7 +36,7 @@
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Realm" Version="10.14.0" />
<PackageReference Include="ppy.osu.Framework" Version="2022.628.1" />
<PackageReference Include="ppy.osu.Framework" Version="2022.629.0" />
<PackageReference Include="ppy.osu.Game.Resources" Version="2022.628.0" />
<PackageReference Include="Sentry" Version="3.17.1" />
<PackageReference Include="SharpCompress" Version="0.31.0" />

View File

@ -61,7 +61,7 @@
<Reference Include="System.Net.Http" />
</ItemGroup>
<ItemGroup Label="Package References">
<PackageReference Include="ppy.osu.Framework.iOS" Version="2022.628.1" />
<PackageReference Include="ppy.osu.Framework.iOS" Version="2022.629.0" />
<PackageReference Include="ppy.osu.Game.Resources" Version="2022.628.0" />
</ItemGroup>
<!-- See https://github.com/dotnet/runtime/issues/35988 (can be removed after Xamarin uses net6.0) -->
@ -84,7 +84,7 @@
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="5.0.14" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="5.0.14" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="ppy.osu.Framework" Version="2022.628.1" />
<PackageReference Include="ppy.osu.Framework" Version="2022.629.0" />
<PackageReference Include="SharpCompress" Version="0.31.0" />
<PackageReference Include="NUnit" Version="3.13.3" />
<PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />