1
0
mirror of https://github.com/ppy/osu.git synced 2024-11-11 08:27:49 +08:00

Merge branch 'master' into slider-snapping

This commit is contained in:
Dean Herbert 2022-01-10 22:42:16 +09:00 committed by GitHub
commit 90558f809f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
91 changed files with 759 additions and 264 deletions

View File

@ -13,3 +13,5 @@ M:System.Enum.HasFlag(System.Enum);Use osu.Framework.Extensions.EnumExtensions.H
M:Realms.IRealmCollection`1.SubscribeForNotifications`1(Realms.NotificationCallbackDelegate{``0});Use osu.Game.Database.RealmObjectExtensions.QueryAsyncWithNotifications(IRealmCollection<T>,NotificationCallbackDelegate<T>) instead.
M:Realms.CollectionExtensions.SubscribeForNotifications`1(System.Linq.IQueryable{``0},Realms.NotificationCallbackDelegate{``0});Use osu.Game.Database.RealmObjectExtensions.QueryAsyncWithNotifications(IQueryable<T>,NotificationCallbackDelegate<T>) instead.
M:Realms.CollectionExtensions.SubscribeForNotifications`1(System.Collections.Generic.IList{``0},Realms.NotificationCallbackDelegate{``0});Use osu.Game.Database.RealmObjectExtensions.QueryAsyncWithNotifications(IList<T>,NotificationCallbackDelegate<T>) instead.
M:System.Threading.Tasks.Task.Wait();Don't use Task.Wait. Use Task.WaitSafely() to ensure we avoid deadlocks.
P:System.Threading.Tasks.Task`1.Result;Don't use Task.Result. Use Task.GetResultSafely() to ensure we avoid deadlocks.

View File

@ -51,8 +51,8 @@
<Reference Include="Java.Interop" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="ppy.osu.Game.Resources" Version="2021.1215.0" />
<PackageReference Include="ppy.osu.Framework.Android" Version="2021.1227.0" />
<PackageReference Include="ppy.osu.Game.Resources" Version="2022.109.0" />
<PackageReference Include="ppy.osu.Framework.Android" Version="2022.107.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

@ -14,7 +14,6 @@ using osu.Game.Tests.Beatmaps;
namespace osu.Game.Rulesets.Catch.Tests
{
[TestFixture]
[Timeout(10000)]
public class CatchBeatmapConversionTest : BeatmapConversionTest<ConvertValue>
{
protected override string ResourceAssembly => "osu.Game.Rulesets.Catch";

View File

@ -14,7 +14,6 @@ using osu.Game.Tests.Beatmaps;
namespace osu.Game.Rulesets.Mania.Tests
{
[TestFixture]
[Timeout(10000)]
public class ManiaBeatmapConversionTest : BeatmapConversionTest<ManiaConvertMapping, ConvertValue>
{
protected override string ResourceAssembly => "osu.Game.Rulesets.Mania";

View File

@ -12,7 +12,6 @@ using osu.Game.Tests.Beatmaps;
namespace osu.Game.Rulesets.Osu.Tests
{
[TestFixture]
[Timeout(10000)]
public class OsuBeatmapConversionTest : BeatmapConversionTest<ConvertValue>
{
protected override string ResourceAssembly => "osu.Game.Rulesets.Osu";

View File

@ -12,7 +12,6 @@ using osu.Game.Tests.Beatmaps;
namespace osu.Game.Rulesets.Taiko.Tests
{
[TestFixture]
[Timeout(10000)]
public class TaikoBeatmapConversionTest : BeatmapConversionTest<ConvertValue>
{
protected override string ResourceAssembly => "osu.Game.Rulesets.Taiko";

View File

@ -95,7 +95,6 @@ namespace osu.Game.Tests.Beatmaps.Formats
Assert.That(decodedAfterEncode, Is.Not.Null);
Assert.That(decodedAfterEncode.ScoreInfo.User.Username, Is.EqualTo(scoreInfo.User.Username));
Assert.That(decodedAfterEncode.ScoreInfo.BeatmapInfoID, Is.EqualTo(scoreInfo.BeatmapInfoID));
Assert.That(decodedAfterEncode.ScoreInfo.Ruleset, Is.EqualTo(scoreInfo.Ruleset));
Assert.That(decodedAfterEncode.ScoreInfo.TotalScore, Is.EqualTo(scoreInfo.TotalScore));
Assert.That(decodedAfterEncode.ScoreInfo.MaxCombo, Is.EqualTo(scoreInfo.MaxCombo));

View File

@ -93,7 +93,7 @@ namespace osu.Game.Tests.Beatmaps.IO
using (var stream = File.OpenRead(tempPath))
{
importedSet = await manager.Import(new ImportTask(stream, Path.GetFileName(tempPath)));
ensureLoaded(osu);
await ensureLoaded(osu);
}
Assert.IsTrue(File.Exists(tempPath), "Stream source file somehow went missing");
@ -171,7 +171,7 @@ namespace osu.Game.Tests.Beatmaps.IO
var importedSecondTime = await osu.Dependencies.Get<BeatmapManager>().Import(new ImportTask(temp));
ensureLoaded(osu);
await ensureLoaded(osu);
// but contents doesn't, so existing should still be used.
Assert.IsTrue(imported.ID == importedSecondTime.Value.ID);
@ -225,7 +225,7 @@ namespace osu.Game.Tests.Beatmaps.IO
var importedSecondTime = await osu.Dependencies.Get<BeatmapManager>().Import(new ImportTask(temp));
ensureLoaded(osu);
await ensureLoaded(osu);
// check the newly "imported" beatmap is not the original.
Assert.IsTrue(imported.ID != importedSecondTime.Value.ID);
@ -277,7 +277,7 @@ namespace osu.Game.Tests.Beatmaps.IO
var importedSecondTime = await osu.Dependencies.Get<BeatmapManager>().Import(new ImportTask(temp));
ensureLoaded(osu);
await ensureLoaded(osu);
// check the newly "imported" beatmap is not the original.
Assert.IsTrue(imported.ID != importedSecondTime.Value.ID);
@ -328,7 +328,7 @@ namespace osu.Game.Tests.Beatmaps.IO
var importedSecondTime = await osu.Dependencies.Get<BeatmapManager>().Import(new ImportTask(temp));
ensureLoaded(osu);
await ensureLoaded(osu);
// check the newly "imported" beatmap is not the original.
Assert.IsTrue(imported.ID != importedSecondTime.Value.ID);
@ -637,7 +637,7 @@ namespace osu.Game.Tests.Beatmaps.IO
if (!importer.ImportAsync(temp).Wait(10000))
Assert.Fail(@"IPC took too long to send");
ensureLoaded(osu);
ensureLoaded(osu).WaitSafely();
waitForOrAssert(() => !File.Exists(temp), "Temporary still exists after IPC import", 5000);
}
@ -659,7 +659,7 @@ namespace osu.Game.Tests.Beatmaps.IO
string temp = TestResources.GetTestBeatmapForImport();
using (File.OpenRead(temp))
await osu.Dependencies.Get<BeatmapManager>().Import(temp);
ensureLoaded(osu);
await ensureLoaded(osu);
File.Delete(temp);
Assert.IsFalse(File.Exists(temp), "We likely held a read lock on the file when we shouldn't");
}
@ -698,7 +698,7 @@ namespace osu.Game.Tests.Beatmaps.IO
await osu.Dependencies.Get<BeatmapManager>().Import(temp);
ensureLoaded(osu);
await ensureLoaded(osu);
}
finally
{
@ -741,7 +741,7 @@ namespace osu.Game.Tests.Beatmaps.IO
var imported = await osu.Dependencies.Get<BeatmapManager>().Import(new ImportTask(temp));
ensureLoaded(osu);
await ensureLoaded(osu);
Assert.IsFalse(imported.Value.Files.Any(f => f.Filename.Contains("subfolder")), "Files contain common subfolder");
}
@ -794,7 +794,7 @@ namespace osu.Game.Tests.Beatmaps.IO
var imported = await osu.Dependencies.Get<BeatmapManager>().Import(new ImportTask(temp));
ensureLoaded(osu);
await ensureLoaded(osu);
Assert.IsFalse(imported.Value.Files.Any(f => f.Filename.Contains("__MACOSX")), "Files contain resource fork folder, which should be ignored");
Assert.IsFalse(imported.Value.Files.Any(f => f.Filename.Contains("actual_data")), "Files contain common subfolder");
@ -812,7 +812,7 @@ namespace osu.Game.Tests.Beatmaps.IO
}
[Test]
public async Task TestUpdateBeatmapInfo()
public void TestUpdateBeatmapInfo()
{
using (HeadlessGameHost host = new CleanRunHeadlessGameHost())
{
@ -822,7 +822,8 @@ namespace osu.Game.Tests.Beatmaps.IO
var manager = osu.Dependencies.Get<BeatmapManager>();
string temp = TestResources.GetTestBeatmapForImport();
await osu.Dependencies.Get<BeatmapManager>().Import(temp);
osu.Dependencies.Get<BeatmapManager>().Import(temp).WaitSafely();
// Update via the beatmap, not the beatmap info, to ensure correct linking
BeatmapSetInfo setToUpdate = manager.GetAllUsableBeatmapSets()[0];
@ -842,7 +843,7 @@ namespace osu.Game.Tests.Beatmaps.IO
}
[Test]
public async Task TestUpdateBeatmapFile()
public void TestUpdateBeatmapFile()
{
using (HeadlessGameHost host = new CleanRunHeadlessGameHost())
{
@ -852,7 +853,8 @@ namespace osu.Game.Tests.Beatmaps.IO
var manager = osu.Dependencies.Get<BeatmapManager>();
string temp = TestResources.GetTestBeatmapForImport();
await osu.Dependencies.Get<BeatmapManager>().Import(temp);
osu.Dependencies.Get<BeatmapManager>().Import(temp).WaitSafely();
BeatmapSetInfo setToUpdate = manager.GetAllUsableBeatmapSets()[0];
@ -976,35 +978,35 @@ namespace osu.Game.Tests.Beatmaps.IO
}
}
public static async Task<BeatmapSetInfo> LoadQuickOszIntoOsu(OsuGameBase osu)
public static Task<BeatmapSetInfo> LoadQuickOszIntoOsu(OsuGameBase osu) => Task.Factory.StartNew(() =>
{
string temp = TestResources.GetQuickTestBeatmapForImport();
var manager = osu.Dependencies.Get<BeatmapManager>();
var importedSet = await manager.Import(new ImportTask(temp)).ConfigureAwait(false);
var importedSet = manager.Import(new ImportTask(temp)).GetResultSafely();
ensureLoaded(osu);
ensureLoaded(osu).WaitSafely();
waitForOrAssert(() => !File.Exists(temp), "Temporary file still exists after standard import", 5000);
return manager.GetAllUsableBeatmapSets().Find(beatmapSet => beatmapSet.ID == importedSet.Value.ID);
}
}, TaskCreationOptions.LongRunning);
public static async Task<BeatmapSetInfo> LoadOszIntoOsu(OsuGameBase osu, string path = null, bool virtualTrack = false)
public static Task<BeatmapSetInfo> LoadOszIntoOsu(OsuGameBase osu, string path = null, bool virtualTrack = false) => Task.Factory.StartNew(() =>
{
string temp = path ?? TestResources.GetTestBeatmapForImport(virtualTrack);
var manager = osu.Dependencies.Get<BeatmapManager>();
var importedSet = await manager.Import(new ImportTask(temp)).ConfigureAwait(false);
var importedSet = manager.Import(new ImportTask(temp)).GetResultSafely();
ensureLoaded(osu);
ensureLoaded(osu).WaitSafely();
waitForOrAssert(() => !File.Exists(temp), "Temporary file still exists after standard import", 5000);
return manager.GetAllUsableBeatmapSets().Find(beatmapSet => beatmapSet.ID == importedSet.Value.ID);
}
}, TaskCreationOptions.LongRunning);
private void deleteBeatmapSet(BeatmapSetInfo imported, OsuGameBase osu)
{
@ -1053,7 +1055,7 @@ namespace osu.Game.Tests.Beatmaps.IO
Assert.AreEqual(expected, osu.Dependencies.Get<DatabaseContextFactory>().Get().FileInfo.Count(f => f.ReferenceCount == 1));
}
private static void ensureLoaded(OsuGameBase osu, int timeout = 60000)
private static Task ensureLoaded(OsuGameBase osu, int timeout = 60000) => Task.Factory.StartNew(() =>
{
IEnumerable<BeatmapSetInfo> resultSets = null;
var store = osu.Dependencies.Get<BeatmapManager>();
@ -1089,14 +1091,14 @@ namespace osu.Game.Tests.Beatmaps.IO
Assert.IsTrue(beatmap?.HitObjects.Any() == true);
beatmap = store.GetWorkingBeatmap(set.Beatmaps.First(b => b.RulesetID == 3))?.Beatmap;
Assert.IsTrue(beatmap?.HitObjects.Any() == true);
}
}, TaskCreationOptions.LongRunning);
private static void waitForOrAssert(Func<bool> result, string failureMessage, int timeout = 60000)
{
Task task = Task.Run(() =>
Task task = Task.Factory.StartNew(() =>
{
while (!result()) Thread.Sleep(200);
});
}, TaskCreationOptions.LongRunning);
Assert.IsTrue(task.Wait(timeout), failureMessage);
}

View File

@ -8,6 +8,7 @@ using System.Threading.Tasks;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Extensions;
using osu.Framework.Testing;
using osu.Game.Beatmaps;
using osu.Game.Rulesets;
@ -32,7 +33,7 @@ namespace osu.Game.Tests.Beatmaps
[BackgroundDependencyLoader]
private void load(OsuGameBase osu)
{
importedSet = ImportBeatmapTest.LoadQuickOszIntoOsu(osu).Result;
importedSet = ImportBeatmapTest.LoadQuickOszIntoOsu(osu).GetResultSafely();
}
[SetUpSteps]

View File

@ -6,6 +6,7 @@ using System.IO;
using System.Text;
using System.Threading.Tasks;
using NUnit.Framework;
using osu.Framework.Extensions;
using osu.Framework.Platform;
using osu.Framework.Testing;
using osu.Game.Tests.Resources;
@ -179,7 +180,7 @@ namespace osu.Game.Tests.Collections.IO
{
// intentionally spin this up on a separate task to avoid disposal deadlocks.
// see https://github.com/EventStore/EventStore/issues/1179
await Task.Run(() => osu.CollectionManager.Import(stream).Wait());
await Task.Factory.StartNew(() => osu.CollectionManager.Import(stream).WaitSafely(), TaskCreationOptions.LongRunning);
}
}
}

View File

@ -6,6 +6,7 @@ using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using NUnit.Framework;
using osu.Framework.Extensions;
using osu.Framework.Testing;
using osu.Game.Database;
using osu.Game.Models;
@ -104,7 +105,7 @@ namespace osu.Game.Tests.Database
liveBeatmap = beatmap.ToLive(realmFactory);
}
}, TaskCreationOptions.LongRunning | TaskCreationOptions.HideScheduler).Wait();
}, TaskCreationOptions.LongRunning | TaskCreationOptions.HideScheduler).WaitSafely();
Debug.Assert(liveBeatmap != null);
@ -115,7 +116,7 @@ namespace osu.Game.Tests.Database
Assert.IsTrue(beatmap.IsValid);
Assert.IsFalse(beatmap.Hidden);
});
}, TaskCreationOptions.LongRunning | TaskCreationOptions.HideScheduler).Wait();
}, TaskCreationOptions.LongRunning | TaskCreationOptions.HideScheduler).WaitSafely();
});
}
@ -133,7 +134,7 @@ namespace osu.Game.Tests.Database
liveBeatmap = beatmap.ToLive(realmFactory);
}
}, TaskCreationOptions.LongRunning | TaskCreationOptions.HideScheduler).Wait();
}, TaskCreationOptions.LongRunning | TaskCreationOptions.HideScheduler).WaitSafely();
Debug.Assert(liveBeatmap != null);
@ -141,7 +142,7 @@ namespace osu.Game.Tests.Database
{
liveBeatmap.PerformWrite(beatmap => { beatmap.Hidden = true; });
liveBeatmap.PerformRead(beatmap => { Assert.IsTrue(beatmap.Hidden); });
}, TaskCreationOptions.LongRunning | TaskCreationOptions.HideScheduler).Wait();
}, TaskCreationOptions.LongRunning | TaskCreationOptions.HideScheduler).WaitSafely();
});
}
@ -175,7 +176,7 @@ namespace osu.Game.Tests.Database
liveBeatmap = beatmap.ToLive(realmFactory);
}
}, TaskCreationOptions.LongRunning | TaskCreationOptions.HideScheduler).Wait();
}, TaskCreationOptions.LongRunning | TaskCreationOptions.HideScheduler).WaitSafely();
Debug.Assert(liveBeatmap != null);
@ -195,7 +196,7 @@ namespace osu.Game.Tests.Database
var __ = liveBeatmap.Value;
});
}
}, TaskCreationOptions.LongRunning | TaskCreationOptions.HideScheduler).Wait();
}, TaskCreationOptions.LongRunning | TaskCreationOptions.HideScheduler).WaitSafely();
});
}
@ -213,7 +214,7 @@ namespace osu.Game.Tests.Database
liveBeatmap = beatmap.ToLive(realmFactory);
}
}, TaskCreationOptions.LongRunning | TaskCreationOptions.HideScheduler).Wait();
}, TaskCreationOptions.LongRunning | TaskCreationOptions.HideScheduler).WaitSafely();
Debug.Assert(liveBeatmap != null);
@ -223,7 +224,7 @@ namespace osu.Game.Tests.Database
{
var unused = liveBeatmap.Value;
});
}, TaskCreationOptions.LongRunning | TaskCreationOptions.HideScheduler).Wait();
}, TaskCreationOptions.LongRunning | TaskCreationOptions.HideScheduler).WaitSafely();
});
}
@ -252,7 +253,7 @@ namespace osu.Game.Tests.Database
liveBeatmap = beatmap.ToLive(realmFactory);
}
}, TaskCreationOptions.LongRunning | TaskCreationOptions.HideScheduler).Wait();
}, TaskCreationOptions.LongRunning | TaskCreationOptions.HideScheduler).WaitSafely();
Debug.Assert(liveBeatmap != null);

View File

@ -6,6 +6,7 @@ using System.Threading;
using System.Threading.Tasks;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Extensions;
using osu.Framework.Platform;
using osu.Game.Collections;
using osu.Game.Tests.Resources;
@ -58,7 +59,7 @@ namespace osu.Game.Tests
{
// Beatmap must be imported before the collection manager is loaded.
if (withBeatmap)
BeatmapManager.Import(TestResources.GetTestBeatmapForImport()).Wait();
BeatmapManager.Import(TestResources.GetTestBeatmapForImport()).WaitSafely();
AddInternal(CollectionManager = new CollectionManager(Storage));
}

View File

@ -16,7 +16,8 @@ namespace osu.Game.Tests.NonVisual.Filtering
{
private BeatmapInfo getExampleBeatmap() => new BeatmapInfo
{
Ruleset = new RulesetInfo { OnlineID = 5 },
Ruleset = new RulesetInfo { OnlineID = 0 },
RulesetID = 0,
StarRating = 4.0d,
BaseDifficulty = new BeatmapDifficulty
{

View File

@ -4,6 +4,7 @@
using System.Threading;
using System.Threading.Tasks;
using NUnit.Framework;
using osu.Framework.Extensions;
using osu.Game.Utils;
namespace osu.Game.Tests.NonVisual
@ -42,9 +43,9 @@ namespace osu.Game.Tests.NonVisual
await Task.WhenAll(task1.task, task2.task, task3.task);
Assert.That(task1.task.Result, Is.EqualTo(1));
Assert.That(task2.task.Result, Is.EqualTo(2));
Assert.That(task3.task.Result, Is.EqualTo(3));
Assert.That(task1.task.GetResultSafely(), Is.EqualTo(1));
Assert.That(task2.task.GetResultSafely(), Is.EqualTo(2));
Assert.That(task3.task.GetResultSafely(), Is.EqualTo(3));
}
[Test]
@ -68,9 +69,9 @@ namespace osu.Game.Tests.NonVisual
// Wait on both tasks.
await Task.WhenAll(task1.task, task3.task);
Assert.That(task1.task.Result, Is.EqualTo(1));
Assert.That(task1.task.GetResultSafely(), Is.EqualTo(1));
Assert.That(task2.task.IsCompleted, Is.False);
Assert.That(task3.task.Result, Is.EqualTo(2));
Assert.That(task3.task.GetResultSafely(), Is.EqualTo(2));
}
[Test]

View File

@ -100,7 +100,7 @@ namespace osu.Game.Tests.Online
public void TestTrackerRespectsSoftDeleting()
{
AddStep("allow importing", () => beatmaps.AllowImport.SetResult(true));
AddStep("import beatmap", () => beatmaps.Import(testBeatmapFile).Wait());
AddStep("import beatmap", () => beatmaps.Import(testBeatmapFile).WaitSafely());
addAvailabilityCheckStep("state locally available", BeatmapAvailability.LocallyAvailable);
AddStep("delete beatmap", () => beatmaps.Delete(beatmaps.QueryBeatmapSet(b => b.OnlineID == testBeatmapSet.OnlineID)));
@ -114,12 +114,12 @@ namespace osu.Game.Tests.Online
public void TestTrackerRespectsChecksum()
{
AddStep("allow importing", () => beatmaps.AllowImport.SetResult(true));
AddStep("import beatmap", () => beatmaps.Import(testBeatmapFile).Wait());
AddStep("import beatmap", () => beatmaps.Import(testBeatmapFile).WaitSafely());
addAvailabilityCheckStep("initially locally available", BeatmapAvailability.LocallyAvailable);
AddStep("import altered beatmap", () =>
{
beatmaps.Import(TestResources.GetTestBeatmapForImport(true)).Wait();
beatmaps.Import(TestResources.GetTestBeatmapForImport(true)).WaitSafely();
});
addAvailabilityCheckStep("state not downloaded", BeatmapAvailability.NotDownloaded);
@ -129,7 +129,7 @@ namespace osu.Game.Tests.Online
});
addAvailabilityCheckStep("state not downloaded as well", BeatmapAvailability.NotDownloaded);
AddStep("reimport original beatmap", () => beatmaps.Import(TestResources.GetQuickTestBeatmapForImport()).Wait());
AddStep("reimport original beatmap", () => beatmaps.Import(TestResources.GetQuickTestBeatmapForImport()).WaitSafely());
addAvailabilityCheckStep("locally available after re-import", BeatmapAvailability.LocallyAvailable);
}

View File

@ -8,6 +8,7 @@ using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Extensions;
using osu.Framework.Platform;
using osu.Game.Database;
using osu.Game.IO;
@ -187,7 +188,7 @@ namespace osu.Game.Tests.Skins.IO
var imported = skinManager.Import(new ImportTask(exportStream, "exported.osk"));
imported.Result.PerformRead(s =>
imported.GetResultSafely().PerformRead(s =>
{
Assert.IsFalse(s.Protected);
Assert.AreNotEqual(originalSkinId, s.ID);
@ -222,7 +223,7 @@ namespace osu.Game.Tests.Skins.IO
var imported = skinManager.Import(new ImportTask(exportStream, "exported.osk"));
imported.Result.PerformRead(s =>
imported.GetResultSafely().PerformRead(s =>
{
Assert.IsFalse(s.Protected);
Assert.AreNotEqual(originalSkinId, s.ID);

View File

@ -4,6 +4,7 @@
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Audio.Track;
using osu.Framework.Extensions;
using osu.Framework.Testing;
using osu.Game.Audio;
using osu.Game.Beatmaps;
@ -24,7 +25,7 @@ namespace osu.Game.Tests.Skins
[BackgroundDependencyLoader]
private void load()
{
var imported = beatmaps.Import(new ZipArchiveReader(TestResources.OpenResource("Archives/ogg-beatmap.osz"))).Result;
var imported = beatmaps.Import(new ZipArchiveReader(TestResources.OpenResource("Archives/ogg-beatmap.osz"))).GetResultSafely();
beatmap = beatmaps.GetWorkingBeatmap(imported.Value.Beatmaps[0]);
beatmap.LoadTrack();
}

View File

@ -3,6 +3,7 @@
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Extensions;
using osu.Framework.Testing;
using osu.Game.Audio;
using osu.Game.IO.Archives;
@ -23,7 +24,7 @@ namespace osu.Game.Tests.Skins
[BackgroundDependencyLoader]
private void load()
{
var imported = skins.Import(new ZipArchiveReader(TestResources.OpenResource("Archives/ogg-skin.osk"))).Result;
var imported = skins.Import(new ZipArchiveReader(TestResources.OpenResource("Archives/ogg-skin.osk"))).GetResultSafely();
skin = imported.PerformRead(skinInfo => skins.GetSkin(skinInfo));
}

View File

@ -7,6 +7,7 @@ using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Bindables;
using osu.Framework.Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Input.Events;
@ -49,7 +50,7 @@ namespace osu.Game.Tests.Visual.Background
Dependencies.Cache(manager = new BeatmapManager(LocalStorage, ContextFactory, rulesets, null, audio, Resources, host, Beatmap.Default));
Dependencies.Cache(new OsuConfigManager(LocalStorage));
manager.Import(TestResources.GetQuickTestBeatmapForImport()).Wait();
manager.Import(TestResources.GetQuickTestBeatmapForImport()).WaitSafely();
Beatmap.SetDefault();
}

View File

@ -4,6 +4,7 @@
using System.Linq;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.UserInterface;
@ -38,7 +39,7 @@ namespace osu.Game.Tests.Visual.Collections
Dependencies.Cache(rulesets = new RulesetStore(ContextFactory));
Dependencies.Cache(beatmapManager = new BeatmapManager(LocalStorage, ContextFactory, rulesets, null, Audio, Resources, host, Beatmap.Default));
beatmapManager.Import(TestResources.GetQuickTestBeatmapForImport()).Wait();
beatmapManager.Import(TestResources.GetQuickTestBeatmapForImport()).WaitSafely();
base.Content.AddRange(new Drawable[]
{

View File

@ -5,6 +5,7 @@ using System;
using System.Linq;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Extensions;
using osu.Framework.Testing;
using osu.Game.Beatmaps;
using osu.Game.Overlays.Dialog;
@ -32,7 +33,7 @@ namespace osu.Game.Tests.Visual.Editing
public override void SetUpSteps()
{
AddStep("import test beatmap", () => importedBeatmapSet = ImportBeatmapTest.LoadOszIntoOsu(game, virtualTrack: true).Result);
AddStep("import test beatmap", () => importedBeatmapSet = ImportBeatmapTest.LoadOszIntoOsu(game, virtualTrack: true).GetResultSafely());
base.SetUpSteps();
}

View File

@ -5,6 +5,7 @@ using System;
using System.Linq;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Extensions;
using osu.Framework.Screens;
using osu.Framework.Testing;
using osu.Game.Beatmaps;
@ -38,7 +39,7 @@ namespace osu.Game.Tests.Visual.Editing
public override void SetUpSteps()
{
AddStep("import test beatmap", () => importedBeatmapSet = ImportBeatmapTest.LoadOszIntoOsu(game).Result);
AddStep("import test beatmap", () => importedBeatmapSet = ImportBeatmapTest.LoadOszIntoOsu(game).GetResultSafely());
base.SetUpSteps();
}

View File

@ -9,6 +9,7 @@ using osu.Game.Online.API.Requests.Responses;
using osu.Game.Scoring;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Extensions;
using osu.Framework.Testing;
using osu.Game.Database;
using osu.Game.Graphics.UserInterface;
@ -135,7 +136,7 @@ namespace osu.Game.Tests.Visual.Gameplay
AddUntilStep("state is not downloaded", () => downloadButton.State.Value == DownloadState.NotDownloaded);
AddStep("import score", () => imported = scoreManager.Import(getScoreInfo(true)).Result);
AddStep("import score", () => imported = scoreManager.Import(getScoreInfo(true)).GetResultSafely());
AddUntilStep("state is available", () => downloadButton.State.Value == DownloadState.LocallyAvailable);

View File

@ -4,6 +4,7 @@
using System.Linq;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Extensions;
using osu.Framework.Graphics;
using osu.Framework.Screens;
using osu.Framework.Testing;
@ -60,7 +61,7 @@ namespace osu.Game.Tests.Visual.Gameplay
AddStep("import beatmap", () =>
{
importedBeatmap = ImportBeatmapTest.LoadOszIntoOsu(game, virtualTrack: true).Result;
importedBeatmap = ImportBeatmapTest.LoadOszIntoOsu(game, virtualTrack: true).GetResultSafely();
importedBeatmapId = importedBeatmap.Beatmaps.First(b => b.RulesetID == 0).OnlineID ?? -1;
});
}

View File

@ -4,6 +4,7 @@
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
using osu.Framework.Extensions;
using osu.Framework.Testing;
using osu.Game.Beatmaps;
using osu.Game.Database;
@ -33,11 +34,11 @@ namespace osu.Game.Tests.Visual.Menus
Queue<(IWorkingBeatmap working, TrackChangeDirection changeDirection)> trackChangeQueue = null;
// ensure we have at least two beatmaps available to identify the direction the music controller navigated to.
AddRepeatStep("import beatmap", () => Game.BeatmapManager.Import(TestResources.CreateTestBeatmapSetInfo()).Wait(), 5);
AddRepeatStep("import beatmap", () => Game.BeatmapManager.Import(TestResources.CreateTestBeatmapSetInfo()).WaitSafely(), 5);
AddStep("import beatmap with track", () =>
{
var setWithTrack = Game.BeatmapManager.Import(new ImportTask(TestResources.GetTestBeatmapForImport())).Result;
var setWithTrack = Game.BeatmapManager.Import(new ImportTask(TestResources.GetTestBeatmapForImport())).GetResultSafely();
Beatmap.Value = Game.BeatmapManager.GetWorkingBeatmap(setWithTrack.Value.Beatmaps.First());
});

View File

@ -5,6 +5,7 @@ using System.Linq;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Extensions;
using osu.Framework.Platform;
using osu.Framework.Screens;
using osu.Framework.Testing;
@ -56,7 +57,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
AddStep("import beatmap", () =>
{
beatmaps.Import(TestResources.GetQuickTestBeatmapForImport()).Wait();
beatmaps.Import(TestResources.GetQuickTestBeatmapForImport()).WaitSafely();
importedSet = beatmaps.GetAllUsableBeatmapSetsEnumerable(IncludedDetails.All).First();
InitialBeatmap = importedSet.Beatmaps.First(b => b.RulesetID == 0);
OtherBeatmap = importedSet.Beatmaps.Last(b => b.RulesetID == 0);

View File

@ -1,13 +1,25 @@
// 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.
#nullable enable
using System;
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
using osu.Framework.Extensions.ObjectExtensions;
using osu.Framework.Screens;
using osu.Framework.Testing;
using osu.Game.Beatmaps;
using osu.Game.Online.Multiplayer;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Catch;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Osu;
using osu.Game.Rulesets.Osu.Mods;
using osu.Game.Screens.OnlinePlay.Multiplayer;
using osu.Game.Screens.OnlinePlay.Multiplayer.Match;
using osu.Game.Screens.Play;
using osuTK.Input;
namespace osu.Game.Tests.Visual.Multiplayer
@ -83,16 +95,60 @@ namespace osu.Game.Tests.Visual.Multiplayer
AddUntilStep("selected beatmap is initial beatmap", () => Beatmap.Value.BeatmapInfo.OnlineID == InitialBeatmap.OnlineID);
}
private void addItem(Func<BeatmapInfo> beatmap)
[Test]
public void TestCorrectRulesetSelectedAfterNewItemAdded()
{
addItem(() => OtherBeatmap, new CatchRuleset().RulesetInfo);
AddUntilStep("selected beatmap is initial beatmap", () => Beatmap.Value.BeatmapInfo.OnlineID == InitialBeatmap.OnlineID);
AddUntilStep("wait for idle", () => Client.LocalUser?.State == MultiplayerUserState.Idle);
ClickButtonWhenEnabled<MultiplayerReadyButton>();
AddUntilStep("wait for ready", () => Client.LocalUser?.State == MultiplayerUserState.Ready);
ClickButtonWhenEnabled<MultiplayerReadyButton>();
AddUntilStep("wait for player", () => CurrentScreen is Player player && player.IsLoaded);
AddAssert("ruleset is correct", () => ((Player)CurrentScreen).Ruleset.Value.Equals(new OsuRuleset().RulesetInfo));
AddStep("exit player", () => CurrentScreen.Exit());
}
[Test]
public void TestCorrectModsSelectedAfterNewItemAdded()
{
addItem(() => OtherBeatmap, mods: new Mod[] { new OsuModDoubleTime() });
AddUntilStep("selected beatmap is initial beatmap", () => Beatmap.Value.BeatmapInfo.OnlineID == InitialBeatmap.OnlineID);
AddUntilStep("wait for idle", () => Client.LocalUser?.State == MultiplayerUserState.Idle);
ClickButtonWhenEnabled<MultiplayerReadyButton>();
AddUntilStep("wait for ready", () => Client.LocalUser?.State == MultiplayerUserState.Ready);
ClickButtonWhenEnabled<MultiplayerReadyButton>();
AddUntilStep("wait for player", () => CurrentScreen is Player player && player.IsLoaded);
AddAssert("mods are correct", () => !((Player)CurrentScreen).Mods.Value.Any());
AddStep("exit player", () => CurrentScreen.Exit());
}
private void addItem(Func<BeatmapInfo> beatmap, RulesetInfo? ruleset = null, IReadOnlyList<Mod>? mods = null)
{
Screens.Select.SongSelect? songSelect = null;
AddStep("click add button", () =>
{
InputManager.MoveMouseTo(this.ChildrenOfType<MultiplayerMatchSubScreen.AddItemButton>().Single());
InputManager.Click(MouseButton.Left);
});
AddUntilStep("wait for song select", () => CurrentSubScreen is Screens.Select.SongSelect select && select.BeatmapSetsLoaded);
AddStep("select other beatmap", () => ((Screens.Select.SongSelect)CurrentSubScreen).FinaliseSelection(beatmap()));
AddUntilStep("wait for song select", () => (songSelect = CurrentSubScreen as Screens.Select.SongSelect) != null);
AddUntilStep("wait for loaded", () => songSelect.AsNonNull().BeatmapSetsLoaded);
if (ruleset != null)
AddStep($"set {ruleset.Name} ruleset", () => songSelect.AsNonNull().Ruleset.Value = ruleset);
if (mods != null)
AddStep($"set mods to {string.Join(",", mods.Select(m => m.Acronym))}", () => songSelect.AsNonNull().Mods.Value = mods);
AddStep("select other beatmap", () => songSelect.AsNonNull().FinaliseSelection(beatmap()));
AddUntilStep("wait for return to match", () => CurrentSubScreen is MultiplayerMatchSubScreen);
}
}

View File

@ -8,6 +8,7 @@ using System.Linq;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Platform;
@ -153,7 +154,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
var beatmap = new TestBeatmap(new OsuRuleset().RulesetInfo).BeatmapInfo;
AddStep("import beatmap", () => manager.Import(beatmap.BeatmapSet).Wait());
AddStep("import beatmap", () => manager.Import(beatmap.BeatmapSet).WaitSafely());
createPlaylistWithBeatmaps(beatmap);

View File

@ -5,6 +5,7 @@ using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Extensions;
using osu.Framework.Extensions.ObjectExtensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
@ -46,7 +47,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
[BackgroundDependencyLoader]
private void load()
{
importedSet = ImportBeatmapTest.LoadOszIntoOsu(game, virtualTrack: true).Result;
importedSet = ImportBeatmapTest.LoadOszIntoOsu(game, virtualTrack: true).GetResultSafely();
importedBeatmap = importedSet.Beatmaps.First(b => b.RulesetID == 0);
importedBeatmapId = importedBeatmap.OnlineID ?? -1;
}

View File

@ -7,6 +7,8 @@ using System.Linq;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Extensions;
using osu.Framework.Extensions.ObjectExtensions;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.UserInterface;
using osu.Framework.Input;
@ -22,6 +24,8 @@ using osu.Game.Online.Multiplayer;
using osu.Game.Online.Rooms;
using osu.Game.Overlays.Mods;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Catch;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Osu;
using osu.Game.Rulesets.Osu.Mods;
using osu.Game.Screens.OnlinePlay.Components;
@ -67,7 +71,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
AddStep("import beatmap", () =>
{
beatmaps.Import(TestResources.GetQuickTestBeatmapForImport()).Wait();
beatmaps.Import(TestResources.GetQuickTestBeatmapForImport()).WaitSafely();
importedSet = beatmaps.GetAllUsableBeatmapSetsEnumerable(IncludedDetails.All).First();
});
@ -438,6 +442,84 @@ namespace osu.Game.Tests.Visual.Multiplayer
AddAssert("Beatmap matches current item", () => Beatmap.Value.BeatmapInfo.OnlineID == client.Room?.Playlist.First().BeatmapID);
}
[Test]
public void TestPlayStartsWithCorrectRulesetWhileAtSongSelect()
{
createRoom(() => new Room
{
Name = { Value = "Test Room" },
Playlist =
{
new PlaylistItem
{
Beatmap = { Value = beatmaps.GetWorkingBeatmap(importedSet.Beatmaps.First(b => b.RulesetID == 0)).BeatmapInfo },
Ruleset = { Value = new OsuRuleset().RulesetInfo },
}
}
});
pressReadyButton();
AddStep("Enter song select", () =>
{
var currentSubScreen = ((Screens.OnlinePlay.Multiplayer.Multiplayer)multiplayerComponents.CurrentScreen).CurrentSubScreen;
((MultiplayerMatchSubScreen)currentSubScreen).OpenSongSelection(client.Room?.Settings.PlaylistItemId);
});
AddUntilStep("wait for song select", () => this.ChildrenOfType<MultiplayerMatchSongSelect>().FirstOrDefault()?.BeatmapSetsLoaded == true);
AddAssert("Ruleset matches current item", () => Ruleset.Value.OnlineID == client.Room?.Playlist.First().RulesetID);
AddStep("Switch ruleset", () => ((MultiplayerMatchSongSelect)multiplayerComponents.MultiplayerScreen.CurrentSubScreen).Ruleset.Value = new CatchRuleset().RulesetInfo);
AddUntilStep("Ruleset doesn't match current item", () => Ruleset.Value.OnlineID != client.Room?.Playlist.First().RulesetID);
AddStep("start match externally", () => client.StartMatch());
AddUntilStep("play started", () => multiplayerComponents.CurrentScreen is Player);
AddAssert("Ruleset matches current item", () => Ruleset.Value.OnlineID == client.Room?.Playlist.First().RulesetID);
}
[Test]
public void TestPlayStartsWithCorrectModsWhileAtSongSelect()
{
createRoom(() => new Room
{
Name = { Value = "Test Room" },
Playlist =
{
new PlaylistItem
{
Beatmap = { Value = beatmaps.GetWorkingBeatmap(importedSet.Beatmaps.First(b => b.RulesetID == 0)).BeatmapInfo },
Ruleset = { Value = new OsuRuleset().RulesetInfo },
}
}
});
pressReadyButton();
AddStep("Enter song select", () =>
{
var currentSubScreen = ((Screens.OnlinePlay.Multiplayer.Multiplayer)multiplayerComponents.CurrentScreen).CurrentSubScreen;
((MultiplayerMatchSubScreen)currentSubScreen).OpenSongSelection(client.Room?.Settings.PlaylistItemId);
});
AddUntilStep("wait for song select", () => this.ChildrenOfType<MultiplayerMatchSongSelect>().FirstOrDefault()?.BeatmapSetsLoaded == true);
AddAssert("Mods match current item", () => SelectedMods.Value.Select(m => m.Acronym).SequenceEqual(client.Room.AsNonNull().Playlist.First().RequiredMods.Select(m => m.Acronym)));
AddStep("Switch required mods", () => ((MultiplayerMatchSongSelect)multiplayerComponents.MultiplayerScreen.CurrentSubScreen).Mods.Value = new Mod[] { new OsuModDoubleTime() });
AddAssert("Mods don't match current item", () => !SelectedMods.Value.Select(m => m.Acronym).SequenceEqual(client.Room.AsNonNull().Playlist.First().RequiredMods.Select(m => m.Acronym)));
AddStep("start match externally", () => client.StartMatch());
AddUntilStep("play started", () => multiplayerComponents.CurrentScreen is Player);
AddAssert("Mods match current item", () => SelectedMods.Value.Select(m => m.Acronym).SequenceEqual(client.Room.AsNonNull().Playlist.First().RequiredMods.Select(m => m.Acronym)));
}
[Test]
public void TestLocalPlayDoesNotStartWhileSpectatingWithNoBeatmap()
{
@ -505,7 +587,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
AddStep("restore beatmap", () =>
{
beatmaps.Import(TestResources.GetQuickTestBeatmapForImport()).Wait();
beatmaps.Import(TestResources.GetQuickTestBeatmapForImport()).WaitSafely();
importedSet = beatmaps.GetAllUsableBeatmapSetsEnumerable(IncludedDetails.All).First();
});

View File

@ -6,6 +6,7 @@ using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Extensions;
using osu.Framework.Extensions.ObjectExtensions;
using osu.Framework.Graphics;
using osu.Framework.Utils;
@ -43,7 +44,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
base.SetUpSteps();
AddStep("set local user", () => ((DummyAPIAccess)API).LocalUser.Value = LookupCache.GetUserAsync(1).Result);
AddStep("set local user", () => ((DummyAPIAccess)API).LocalUser.Value = LookupCache.GetUserAsync(1).GetResultSafely());
AddStep("create leaderboard", () =>
{
@ -90,7 +91,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
public void TestUserQuit()
{
foreach (int user in users)
AddStep($"mark user {user} quit", () => Client.RemoveUser(LookupCache.GetUserAsync(user).Result.AsNonNull()));
AddStep($"mark user {user} quit", () => Client.RemoveUser(LookupCache.GetUserAsync(user).GetResultSafely().AsNonNull()));
}
[Test]

View File

@ -4,6 +4,7 @@
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
using osu.Framework.Extensions;
using osu.Framework.Graphics;
using osu.Framework.Utils;
using osu.Game.Online.API;
@ -47,7 +48,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
base.SetUpSteps();
AddStep("set local user", () => ((DummyAPIAccess)API).LocalUser.Value = LookupCache.GetUserAsync(1).Result);
AddStep("set local user", () => ((DummyAPIAccess)API).LocalUser.Value = LookupCache.GetUserAsync(1).GetResultSafely());
AddStep("create leaderboard", () =>
{

View File

@ -83,7 +83,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
beatmapSetInfo.Beatmaps.Add(beatmap);
}
manager.Import(beatmapSetInfo).Wait();
manager.Import(beatmapSetInfo).WaitSafely();
}
public override void SetUpSteps()

View File

@ -5,6 +5,7 @@ using System.Linq;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Extensions;
using osu.Framework.Platform;
using osu.Framework.Screens;
using osu.Framework.Testing;
@ -39,7 +40,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
Dependencies.Cache(rulesets = new RulesetStore(ContextFactory));
Dependencies.Cache(beatmaps = new BeatmapManager(LocalStorage, ContextFactory, rulesets, null, audio, Resources, host, Beatmap.Default));
beatmaps.Import(TestResources.GetQuickTestBeatmapForImport()).Wait();
beatmaps.Import(TestResources.GetQuickTestBeatmapForImport()).WaitSafely();
importedSet = beatmaps.GetAllUsableBeatmapSetsEnumerable(IncludedDetails.All).First();
}

View File

@ -6,6 +6,7 @@ using System.Linq;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Extensions;
using osu.Framework.Graphics;
using osu.Framework.Platform;
using osu.Framework.Testing;
@ -53,7 +54,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
AddStep("import beatmap", () =>
{
beatmaps.Import(TestResources.GetQuickTestBeatmapForImport()).Wait();
beatmaps.Import(TestResources.GetQuickTestBeatmapForImport()).WaitSafely();
importedSet = beatmaps.GetAllUsableBeatmapSetsEnumerable(IncludedDetails.All).First();
importedBeatmap = importedSet.Beatmaps.First(b => b.RulesetID == 0);
});

View File

@ -6,6 +6,7 @@ using System.Linq;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Platform;
@ -58,7 +59,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
AddStep("import beatmap", () =>
{
beatmaps.Import(TestResources.GetQuickTestBeatmapForImport()).Wait();
beatmaps.Import(TestResources.GetQuickTestBeatmapForImport()).WaitSafely();
importedSet = beatmaps.GetAllUsableBeatmapSetsEnumerable(IncludedDetails.All).First();
importedBeatmap = importedSet.Beatmaps.First(b => b.RulesetID == 0);
});

View File

@ -8,6 +8,7 @@ using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Bindables;
using osu.Framework.Extensions;
using osu.Framework.Graphics;
using osu.Framework.Platform;
using osu.Framework.Testing;
@ -41,7 +42,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
Dependencies.Cache(rulesets = new RulesetStore(ContextFactory));
Dependencies.Cache(beatmaps = new BeatmapManager(LocalStorage, ContextFactory, rulesets, null, audio, Resources, host, Beatmap.Default));
beatmaps.Import(TestResources.GetQuickTestBeatmapForImport()).Wait();
beatmaps.Import(TestResources.GetQuickTestBeatmapForImport()).WaitSafely();
}
[SetUp]

View File

@ -8,6 +8,7 @@ using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Bindables;
using osu.Framework.Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Platform;
@ -42,7 +43,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
Dependencies.Cache(rulesets = new RulesetStore(ContextFactory));
Dependencies.Cache(beatmaps = new BeatmapManager(LocalStorage, ContextFactory, rulesets, null, audio, Resources, host, Beatmap.Default));
beatmaps.Import(TestResources.GetQuickTestBeatmapForImport()).Wait();
beatmaps.Import(TestResources.GetQuickTestBeatmapForImport()).WaitSafely();
}
[SetUp]

View File

@ -6,6 +6,7 @@ using System.Linq;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Extensions;
using osu.Framework.Platform;
using osu.Framework.Screens;
using osu.Framework.Utils;
@ -38,7 +39,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
var beatmapSet = TestResources.CreateTestBeatmapSetInfo();
manager.Import(beatmapSet).Wait();
manager.Import(beatmapSet).WaitSafely();
}
public override void SetUpSteps()

View File

@ -6,6 +6,7 @@ using System.Linq;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Extensions;
using osu.Framework.Platform;
using osu.Framework.Testing;
using osu.Game.Beatmaps;
@ -51,7 +52,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
AddStep("import beatmap", () =>
{
beatmaps.Import(TestResources.GetQuickTestBeatmapForImport()).Wait();
beatmaps.Import(TestResources.GetQuickTestBeatmapForImport()).WaitSafely();
importedSet = beatmaps.GetAllUsableBeatmapSetsEnumerable(IncludedDetails.All).First();
});

View File

@ -2,6 +2,7 @@
// See the LICENCE file in the repository root for full licence text.
using NUnit.Framework;
using osu.Framework.Extensions;
using osu.Game.Configuration;
using osu.Game.Screens.Play;
using osu.Game.Tests.Beatmaps.IO;
@ -82,7 +83,7 @@ namespace osu.Game.Tests.Visual.Navigation
PushAndConfirm(() => songSelect = new TestSceneScreenNavigation.TestPlaySongSelect());
AddUntilStep("wait for song select", () => songSelect.BeatmapSetsLoaded);
AddStep("import beatmap", () => ImportBeatmapTest.LoadOszIntoOsu(Game, virtualTrack: true).Wait());
AddStep("import beatmap", () => ImportBeatmapTest.LoadOszIntoOsu(Game, virtualTrack: true).WaitSafely());
AddUntilStep("wait for selected", () => !Game.Beatmap.IsDefault);
AddStep("press enter", () => InputManager.Key(Key.Enter));

View File

@ -4,6 +4,7 @@
using System.Linq;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Extensions;
using osu.Framework.Graphics.Containers;
using osu.Framework.Screens;
using osu.Framework.Testing;
@ -172,7 +173,7 @@ namespace osu.Game.Tests.Visual.Navigation
private void importAndWaitForSongSelect()
{
AddStep("import beatmap", () => ImportBeatmapTest.LoadQuickOszIntoOsu(Game).Wait());
AddStep("import beatmap", () => ImportBeatmapTest.LoadQuickOszIntoOsu(Game).WaitSafely());
PushAndConfirm(() => new TestPlaySongSelect());
AddUntilStep("beatmap updated", () => Game.Beatmap.Value.BeatmapSetInfo.OnlineID == 241526);
}

View File

@ -4,6 +4,7 @@
using System;
using System.Linq;
using NUnit.Framework;
using osu.Framework.Extensions;
using osu.Framework.Screens;
using osu.Game.Beatmaps;
using osu.Game.Extensions;
@ -126,7 +127,7 @@ namespace osu.Game.Tests.Visual.Navigation
Ruleset = ruleset ?? new OsuRuleset().RulesetInfo
},
}
}).Result.Value;
}).GetResultSafely().Value;
});
AddAssert($"import {i} succeeded", () => imported != null);

View File

@ -4,6 +4,7 @@
using System;
using System.Linq;
using NUnit.Framework;
using osu.Framework.Extensions;
using osu.Framework.Screens;
using osu.Framework.Testing;
using osu.Game.Beatmaps;
@ -57,7 +58,7 @@ namespace osu.Game.Tests.Visual.Navigation
Ruleset = new OsuRuleset().RulesetInfo
},
}
}).Result.Value;
}).GetResultSafely().Value;
});
}
@ -131,7 +132,7 @@ namespace osu.Game.Tests.Visual.Navigation
OnlineID = i,
BeatmapInfo = beatmap.Beatmaps.First(),
Ruleset = ruleset ?? new OsuRuleset().RulesetInfo
}).Result.Value;
}).GetResultSafely().Value;
});
AddAssert($"import {i} succeeded", () => imported != null);

View File

@ -4,6 +4,7 @@
using System.Linq;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Extensions;
using osu.Framework.Graphics.Containers;
using osu.Framework.Screens;
using osu.Framework.Testing;
@ -70,7 +71,7 @@ namespace osu.Game.Tests.Visual.Navigation
PushAndConfirm(() => songSelect = new TestPlaySongSelect());
AddUntilStep("wait for song select", () => songSelect.BeatmapSetsLoaded);
AddStep("import beatmap", () => ImportBeatmapTest.LoadQuickOszIntoOsu(Game).Wait());
AddStep("import beatmap", () => ImportBeatmapTest.LoadQuickOszIntoOsu(Game).WaitSafely());
AddUntilStep("wait for selected", () => !Game.Beatmap.IsDefault);
@ -104,7 +105,7 @@ namespace osu.Game.Tests.Visual.Navigation
PushAndConfirm(() => songSelect = new TestPlaySongSelect());
AddUntilStep("wait for song select", () => songSelect.BeatmapSetsLoaded);
AddStep("import beatmap", () => ImportBeatmapTest.LoadQuickOszIntoOsu(Game).Wait());
AddStep("import beatmap", () => ImportBeatmapTest.LoadQuickOszIntoOsu(Game).WaitSafely());
AddUntilStep("wait for selected", () => !Game.Beatmap.IsDefault);
@ -138,7 +139,7 @@ namespace osu.Game.Tests.Visual.Navigation
PushAndConfirm(() => songSelect = new TestPlaySongSelect());
AddUntilStep("wait for song select", () => songSelect.BeatmapSetsLoaded);
AddStep("import beatmap", () => ImportBeatmapTest.LoadOszIntoOsu(Game, virtualTrack: true).Wait());
AddStep("import beatmap", () => ImportBeatmapTest.LoadOszIntoOsu(Game, virtualTrack: true).WaitSafely());
AddUntilStep("wait for selected", () => !Game.Beatmap.IsDefault);

View File

@ -1,38 +1,27 @@
// 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.Collections.Generic;
using osu.Framework.Graphics.Containers;
using osu.Game.Overlays.Rankings.Tables;
using osu.Framework.Graphics;
using osu.Game.Online.API.Requests;
using osu.Game.Rulesets;
using System.Threading;
using osu.Game.Online.API;
using osu.Game.Rulesets.Osu;
using osu.Game.Rulesets.Mania;
using osu.Game.Rulesets.Taiko;
using osu.Game.Rulesets.Catch;
using osu.Framework.Allocation;
using osu.Game.Graphics.UserInterface;
using osu.Game.Online.API.Requests.Responses;
using osu.Game.Overlays;
using osu.Game.Overlays.Rankings;
using osu.Game.Users;
namespace osu.Game.Tests.Visual.Online
{
public class TestSceneRankingsTables : OsuTestScene
{
protected override bool UseOnlineAPI => true;
[Resolved]
private IAPIProvider api { get; set; }
[Cached]
private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Green);
private readonly BasicScrollContainer scrollFlow;
private readonly LoadingLayer loading;
private CancellationTokenSource cancellationToken;
private APIRequest request;
public TestSceneRankingsTables()
{
@ -53,73 +42,120 @@ namespace osu.Game.Tests.Visual.Online
{
base.LoadComplete();
AddStep("Osu performance", () => createPerformanceTable(new OsuRuleset().RulesetInfo, null));
AddStep("Mania scores", () => createScoreTable(new ManiaRuleset().RulesetInfo));
AddStep("Taiko country scores", () => createCountryTable(new TaikoRuleset().RulesetInfo));
AddStep("Catch US performance page 10", () => createPerformanceTable(new CatchRuleset().RulesetInfo, "US", 10));
AddStep("Osu spotlight table (chart 271)", () => createSpotlightTable(new OsuRuleset().RulesetInfo, 271));
AddStep("User performance", createPerformanceTable);
AddStep("User scores", createScoreTable);
AddStep("Country scores", createCountryTable);
}
private void createCountryTable(RulesetInfo ruleset, int page = 1)
private void createCountryTable()
{
onLoadStarted();
request = new GetCountryRankingsRequest(ruleset, page);
((GetCountryRankingsRequest)request).Success += rankings => Schedule(() =>
var countries = new List<CountryStatistics>
{
var table = new CountriesTable(page, rankings.Countries);
loadTable(table);
});
new CountryStatistics
{
Country = new Country { FlagName = "US", FullName = "United States" },
FlagName = "US",
ActiveUsers = 2_972_623,
PlayCount = 3_086_515_743,
RankedScore = 449_407_643_332_546,
Performance = 371_974_024
},
new CountryStatistics
{
Country = new Country { FlagName = "RU", FullName = "Russian Federation" },
FlagName = "RU",
ActiveUsers = 1_609_989,
PlayCount = 1_637_052_841,
RankedScore = 221_660_827_473_004,
Performance = 163_426_476
}
};
api.Queue(request);
var table = new CountriesTable(1, countries);
loadTable(table);
}
private void createPerformanceTable(RulesetInfo ruleset, string country, int page = 1)
private static List<UserStatistics> createUserStatistics() => new List<UserStatistics>
{
new UserStatistics
{
User = new APIUser
{
Username = "first active user",
Country = new Country { FlagName = "JP" },
Active = true,
},
Accuracy = 0.9972,
PlayCount = 233_215,
TotalScore = 983_231_234_656,
RankedScore = 593_231_345_897,
PP = 23_934,
GradesCount = new UserStatistics.Grades
{
SS = 35_132,
S = 23_345,
A = 12_234
}
},
new UserStatistics
{
User = new APIUser
{
Username = "inactive user",
Country = new Country { FlagName = "AU" },
Active = false,
},
Accuracy = 0.9831,
PlayCount = 195_342,
TotalScore = 683_231_234_656,
RankedScore = 393_231_345_897,
PP = 20_934,
GradesCount = new UserStatistics.Grades
{
SS = 32_132,
S = 20_345,
A = 9_234
}
},
new UserStatistics
{
User = new APIUser
{
Username = "second active user",
Country = new Country { FlagName = "PL" },
Active = true,
},
Accuracy = 0.9584,
PlayCount = 100_903,
TotalScore = 97_242_983_434,
RankedScore = 3_156_345_897,
PP = 9_568,
GradesCount = new UserStatistics.Grades
{
SS = 13_152,
S = 24_375,
A = 9_960
}
},
};
private void createPerformanceTable()
{
onLoadStarted();
request = new GetUserRankingsRequest(ruleset, country: country, page: page);
((GetUserRankingsRequest)request).Success += rankings => Schedule(() =>
{
var table = new PerformanceTable(page, rankings.Users);
loadTable(table);
});
api.Queue(request);
loadTable(new PerformanceTable(1, createUserStatistics()));
}
private void createScoreTable(RulesetInfo ruleset, int page = 1)
private void createScoreTable()
{
onLoadStarted();
request = new GetUserRankingsRequest(ruleset, UserRankingsType.Score, page);
((GetUserRankingsRequest)request).Success += rankings => Schedule(() =>
{
var table = new ScoresTable(page, rankings.Users);
loadTable(table);
});
api.Queue(request);
}
private void createSpotlightTable(RulesetInfo ruleset, int spotlight)
{
onLoadStarted();
request = new GetSpotlightRankingsRequest(ruleset, spotlight, RankingsSortCriteria.All);
((GetSpotlightRankingsRequest)request).Success += rankings => Schedule(() =>
{
var table = new ScoresTable(1, rankings.Users);
loadTable(table);
});
api.Queue(request);
loadTable(new ScoresTable(1, createUserStatistics()));
}
private void onLoadStarted()
{
loading.Show();
request?.Cancel();
cancellationToken?.Cancel();
cancellationToken = new CancellationTokenSource();
}

View File

@ -0,0 +1,57 @@
// 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 System.Linq;
using NUnit.Framework;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Timing;
using osu.Game.Overlays.BeatmapSet.Scores;
namespace osu.Game.Tests.Visual.Online
{
public class TestSceneScoreboardTime : OsuTestScene
{
private StopwatchClock stopwatch;
[Test]
public void TestVariousUnits()
{
AddStep("create various scoreboard times", () => Child = new FillFlowContainer
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Clock = new FramedClock(stopwatch = new StopwatchClock()), // prevent time from naturally elapsing.
Direction = FillDirection.Vertical,
ChildrenEnumerable = testCases.Select(dateTime => new ScoreboardTime(dateTime, 24).With(time => time.Anchor = time.Origin = Anchor.TopCentre))
});
AddStep("start stopwatch", () => stopwatch.Start());
}
private static IEnumerable<DateTimeOffset> testCases => new[]
{
DateTimeOffset.Now,
DateTimeOffset.Now.AddSeconds(-1),
DateTimeOffset.Now.AddSeconds(-25),
DateTimeOffset.Now.AddSeconds(-59),
DateTimeOffset.Now.AddMinutes(-1),
DateTimeOffset.Now.AddMinutes(-25),
DateTimeOffset.Now.AddMinutes(-59),
DateTimeOffset.Now.AddHours(-1),
DateTimeOffset.Now.AddHours(-13),
DateTimeOffset.Now.AddHours(-23),
DateTimeOffset.Now.AddDays(-1),
DateTimeOffset.Now.AddDays(-6),
DateTimeOffset.Now.AddDays(-16),
DateTimeOffset.Now.AddMonths(-1),
DateTimeOffset.Now.AddMonths(-11),
DateTimeOffset.Now.AddYears(-1),
DateTimeOffset.Now.AddYears(-5)
};
}
}

View File

@ -7,6 +7,7 @@ using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Bindables;
using osu.Framework.Extensions;
using osu.Framework.Platform;
using osu.Framework.Screens;
using osu.Framework.Testing;
@ -142,7 +143,7 @@ namespace osu.Game.Tests.Visual.Playlists
modifiedBeatmap.HitObjects.Clear();
modifiedBeatmap.HitObjects.Add(new HitCircle { StartTime = 5000 });
manager.Import(modifiedBeatmap.BeatmapInfo.BeatmapSet).Wait();
manager.Import(modifiedBeatmap.BeatmapInfo.BeatmapSet).WaitSafely();
});
// Create the room using the real beatmap values.
@ -184,7 +185,7 @@ namespace osu.Game.Tests.Visual.Playlists
},
};
manager.Import(originalBeatmap.BeatmapInfo.BeatmapSet).Wait();
manager.Import(originalBeatmap.BeatmapInfo.BeatmapSet).WaitSafely();
});
AddUntilStep("match has correct beatmap", () => realHash == match.Beatmap.Value.BeatmapInfo.MD5Hash);
@ -201,7 +202,7 @@ namespace osu.Game.Tests.Visual.Playlists
});
}
private void importBeatmap() => AddStep("import beatmap", () => importedBeatmap = manager.Import(CreateBeatmap(new OsuRuleset().RulesetInfo).BeatmapInfo.BeatmapSet).Result);
private void importBeatmap() => AddStep("import beatmap", () => importedBeatmap = manager.Import(CreateBeatmap(new OsuRuleset().RulesetInfo).BeatmapInfo.BeatmapSet).GetResultSafely());
private class TestPlaylistsRoomSubScreen : PlaylistsRoomSubScreen
{

View File

@ -6,6 +6,7 @@ using System.Linq;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Extensions;
using osu.Framework.Graphics;
using osu.Framework.Platform;
using osu.Framework.Testing;
@ -74,7 +75,7 @@ namespace osu.Game.Tests.Visual.SongSelect
AddStep(@"Set beatmap", () =>
{
beatmapManager.Import(TestResources.GetQuickTestBeatmapForImport()).Wait();
beatmapManager.Import(TestResources.GetQuickTestBeatmapForImport()).WaitSafely();
beatmapInfo = beatmapManager.GetAllUsableBeatmapSets().First().Beatmaps.First();
leaderboard.BeatmapInfo = beatmapInfo;
@ -175,7 +176,7 @@ namespace osu.Game.Tests.Visual.SongSelect
AddStep(@"Load new scores via manager", () =>
{
foreach (var score in generateSampleScores(beatmapInfo()))
scoreManager.Import(score).Wait();
scoreManager.Import(score).WaitSafely();
});
}

View File

@ -5,6 +5,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
using osu.Framework.Extensions;
using osu.Framework.Testing;
using osu.Game.Beatmaps;
using osu.Game.Extensions;
@ -181,7 +182,7 @@ namespace osu.Game.Tests.Visual.SongSelect
beatmap.DifficultyName = $"SR{i + 1}";
}
return Game.BeatmapManager.Import(beatmapSet).Result.Value;
return Game.BeatmapManager.Import(beatmapSet).GetResultSafely().Value;
}
private bool ensureAllBeatmapSetsImported(IEnumerable<BeatmapSetInfo> beatmapSets) => beatmapSets.All(set => set != null);

View File

@ -5,6 +5,7 @@ using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
@ -38,7 +39,7 @@ namespace osu.Game.Tests.Visual.SongSelect
Dependencies.Cache(rulesets = new RulesetStore(ContextFactory));
Dependencies.Cache(beatmapManager = new BeatmapManager(LocalStorage, ContextFactory, rulesets, null, Audio, Resources, host, Beatmap.Default));
beatmapManager.Import(TestResources.GetQuickTestBeatmapForImport()).Wait();
beatmapManager.Import(TestResources.GetQuickTestBeatmapForImport()).WaitSafely();
base.Content.AddRange(new Drawable[]
{

View File

@ -8,6 +8,7 @@ using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Bindables;
using osu.Framework.Extensions;
using osu.Framework.Platform;
using osu.Framework.Screens;
using osu.Framework.Testing;
@ -256,7 +257,7 @@ namespace osu.Game.Tests.Visual.SongSelect
AddStep("import multi-ruleset map", () =>
{
var usableRulesets = rulesets.AvailableRulesets.Where(r => r.OnlineID != 2).ToArray();
manager.Import(TestResources.CreateTestBeatmapSetInfo(rulesets: usableRulesets)).Wait();
manager.Import(TestResources.CreateTestBeatmapSetInfo(rulesets: usableRulesets)).WaitSafely();
});
}
else
@ -670,7 +671,7 @@ namespace osu.Game.Tests.Visual.SongSelect
AddStep("import multi-ruleset map", () =>
{
var usableRulesets = rulesets.AvailableRulesets.Where(r => r.OnlineID != 2).ToArray();
manager.Import(TestResources.CreateTestBeatmapSetInfo(3, usableRulesets)).Wait();
manager.Import(TestResources.CreateTestBeatmapSetInfo(3, usableRulesets)).WaitSafely();
});
int previousSetID = 0;
@ -710,7 +711,7 @@ namespace osu.Game.Tests.Visual.SongSelect
AddStep("import multi-ruleset map", () =>
{
var usableRulesets = rulesets.AvailableRulesets.Where(r => r.OnlineID != 2).ToArray();
manager.Import(TestResources.CreateTestBeatmapSetInfo(3, usableRulesets)).Wait();
manager.Import(TestResources.CreateTestBeatmapSetInfo(3, usableRulesets)).WaitSafely();
});
DrawableCarouselBeatmapSet set = null;
@ -759,7 +760,7 @@ namespace osu.Game.Tests.Visual.SongSelect
AddStep("import huge difficulty count map", () =>
{
var usableRulesets = rulesets.AvailableRulesets.Where(r => r.OnlineID != 2).ToArray();
imported = manager.Import(TestResources.CreateTestBeatmapSetInfo(50, usableRulesets)).Result.Value;
imported = manager.Import(TestResources.CreateTestBeatmapSetInfo(50, usableRulesets)).GetResultSafely().Value;
});
AddStep("select the first beatmap of import", () => Beatmap.Value = manager.GetWorkingBeatmap(imported.Beatmaps.First()));
@ -868,7 +869,7 @@ namespace osu.Game.Tests.Visual.SongSelect
private void addRulesetImportStep(int id) => AddStep($"import test map for ruleset {id}", () => importForRuleset(id));
private void importForRuleset(int id) => manager.Import(TestResources.CreateTestBeatmapSetInfo(3, rulesets.AvailableRulesets.Where(r => r.OnlineID == id).ToArray())).Wait();
private void importForRuleset(int id) => manager.Import(TestResources.CreateTestBeatmapSetInfo(3, rulesets.AvailableRulesets.Where(r => r.OnlineID == id).ToArray())).WaitSafely();
private void checkMusicPlaying(bool playing) =>
AddUntilStep($"music {(playing ? "" : "not ")}playing", () => music.IsPlaying == playing);
@ -898,7 +899,7 @@ namespace osu.Game.Tests.Visual.SongSelect
var usableRulesets = rulesets.AvailableRulesets.Where(r => r.OnlineID != 2).ToArray();
for (int i = 0; i < 10; i++)
manager.Import(TestResources.CreateTestBeatmapSetInfo(difficultyCountPerSet, usableRulesets)).Wait();
manager.Import(TestResources.CreateTestBeatmapSetInfo(difficultyCountPerSet, usableRulesets)).WaitSafely();
});
}

View File

@ -7,6 +7,7 @@ using NUnit.Framework;
using osu.Framework.Graphics;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Extensions;
using osu.Framework.Graphics.Cursor;
using osu.Framework.Platform;
using osu.Framework.Testing;
@ -85,7 +86,7 @@ namespace osu.Game.Tests.Visual.UserInterface
dependencies.Cache(beatmapManager = new BeatmapManager(LocalStorage, ContextFactory, rulesetStore, null, dependencies.Get<AudioManager>(), Resources, dependencies.Get<GameHost>(), Beatmap.Default));
dependencies.Cache(scoreManager = new ScoreManager(rulesetStore, () => beatmapManager, LocalStorage, ContextFactory, Scheduler));
beatmapInfo = beatmapManager.Import(new ImportTask(TestResources.GetQuickTestBeatmapForImport())).Result.Value.Beatmaps[0];
beatmapInfo = beatmapManager.Import(new ImportTask(TestResources.GetQuickTestBeatmapForImport())).GetResultSafely().Value.Beatmaps[0];
for (int i = 0; i < 50; i++)
{
@ -101,7 +102,7 @@ namespace osu.Game.Tests.Visual.UserInterface
User = new APIUser { Username = "TestUser" },
};
importedScores.Add(scoreManager.Import(score).Result.Value);
importedScores.Add(scoreManager.Import(score).GetResultSafely().Value);
}
return dependencies;

View File

@ -5,6 +5,7 @@ using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Beatmaps;
@ -31,7 +32,7 @@ namespace osu.Game.Tests.Visual.UserInterface
{
this.api = api;
testBeatmap = ImportBeatmapTest.LoadOszIntoOsu(osu).Result;
testBeatmap = ImportBeatmapTest.LoadOszIntoOsu(osu).GetResultSafely();
}
[Test]

View File

@ -10,6 +10,7 @@ using System.Threading.Tasks;
using JetBrains.Annotations;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Extensions;
using osu.Framework.Lists;
using osu.Framework.Logging;
using osu.Framework.Threading;
@ -261,13 +262,18 @@ namespace osu.Game.Beatmaps
// GetDifficultyAsync will fall back to existing data from IBeatmapInfo if not locally available
// (contrary to GetAsync)
GetDifficultyAsync(bindable.BeatmapInfo, rulesetInfo, mods, cancellationToken)
.ContinueWith(t =>
.ContinueWith(task =>
{
// We're on a threadpool thread, but we should exit back to the update thread so consumers can safely handle value-changed events.
Schedule(() =>
{
if (!cancellationToken.IsCancellationRequested && t.Result != null)
bindable.Value = t.Result;
if (cancellationToken.IsCancellationRequested)
return;
var starDifficulty = task.GetResultSafely();
if (starDifficulty != null)
bindable.Value = starDifficulty.Value;
});
}, cancellationToken);
}

View File

@ -11,6 +11,7 @@ using System.Threading.Tasks;
using JetBrains.Annotations;
using osu.Framework.Audio;
using osu.Framework.Audio.Track;
using osu.Framework.Extensions;
using osu.Framework.IO.Stores;
using osu.Framework.Platform;
using osu.Framework.Testing;
@ -91,7 +92,7 @@ namespace osu.Game.Beatmaps
}
};
var imported = beatmapModelManager.Import(set).Result.Value;
var imported = beatmapModelManager.Import(set).GetResultSafely().Value;
return GetWorkingBeatmap(imported.Beatmaps.First());
}

View File

@ -11,6 +11,7 @@ using System.Threading.Tasks;
using JetBrains.Annotations;
using osu.Framework.Audio;
using osu.Framework.Audio.Track;
using osu.Framework.Extensions;
using osu.Framework.Graphics.Textures;
using osu.Framework.Logging;
using osu.Framework.Testing;
@ -185,7 +186,7 @@ namespace osu.Game.Beatmaps
{
try
{
return loadBeatmapAsync().Result;
return loadBeatmapAsync().GetResultSafely();
}
catch (AggregateException ae)
{

View File

@ -8,6 +8,7 @@ using System.Threading;
using System.Threading.Tasks;
using JetBrains.Annotations;
using osu.Framework.Allocation;
using osu.Framework.Extensions;
using osu.Game.Online.API;
namespace osu.Game.Database
@ -58,7 +59,7 @@ namespace osu.Game.Database
if (!task.IsCompletedSuccessfully)
return null;
return task.Result;
return task.GetResultSafely();
}, token));
}

View File

@ -26,6 +26,9 @@ namespace osu.Game.Database
/// <summary>
/// Create a detached copy of the each item in the collection.
/// </summary>
/// <remarks>
/// Items which are already detached (ie. not managed by realm) will not be modified.
/// </remarks>
/// <param name="items">A list of managed <see cref="RealmObject"/>s to detach.</param>
/// <typeparam name="T">The type of object.</typeparam>
/// <returns>A list containing non-managed copies of provided items.</returns>
@ -42,6 +45,9 @@ namespace osu.Game.Database
/// <summary>
/// Create a detached copy of the item.
/// </summary>
/// <remarks>
/// If the item if already detached (ie. not managed by realm) it will not be detached again and the original instance will be returned. This allows this method to be potentially called at multiple levels while only incurring the clone overhead once.
/// </remarks>
/// <param name="item">The managed <see cref="RealmObject"/> to detach.</param>
/// <typeparam name="T">The type of object.</typeparam>
/// <returns>A non-managed copy of provided item. Will return the provided item if already detached.</returns>

View File

@ -7,6 +7,7 @@ using System.Linq;
using System.Threading.Tasks;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Extensions;
using osu.Framework.Logging;
using osu.Game.Database;
using osu.Game.Input;
@ -533,11 +534,12 @@ namespace osu.Game.Online.Chat
else if (lastClosedChannel.Type == ChannelType.PM)
{
// Try to get user in order to open PM chat
users.GetUserAsync((int)lastClosedChannel.Id).ContinueWith(u =>
users.GetUserAsync((int)lastClosedChannel.Id).ContinueWith(task =>
{
if (u.Result == null) return;
var user = task.GetResultSafely();
Schedule(() => CurrentChannel.Value = JoinChannel(new Channel(u.Result)));
if (user != null)
Schedule(() => CurrentChannel.Value = JoinChannel(new Channel(user)));
});
}

View File

@ -128,6 +128,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
if (showPerformancePoints)
columns.Add(new TableColumn(BeatmapsetsStrings.ShowScoreboardHeaderspp, Anchor.CentreLeft, new Dimension(GridSizeMode.Absolute, 30)));
columns.Add(new TableColumn(BeatmapsetsStrings.ShowScoreboardHeadersTime, Anchor.CentreLeft, new Dimension(GridSizeMode.AutoSize)));
columns.Add(new TableColumn(BeatmapsetsStrings.ShowScoreboardHeadersMods, Anchor.CentreLeft, new Dimension(GridSizeMode.AutoSize)));
return columns.ToArray();
@ -202,6 +203,11 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
});
}
content.Add(new ScoreboardTime(score.Date, text_size)
{
Margin = new MarginPadding { Right = 10 }
});
content.Add(new FillFlowContainer
{
Direction = FillDirection.Horizontal,

View File

@ -0,0 +1,56 @@
// 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 Humanizer;
using osu.Game.Graphics;
using osu.Game.Resources.Localisation.Web;
namespace osu.Game.Overlays.BeatmapSet.Scores
{
public class ScoreboardTime : DrawableDate
{
public ScoreboardTime(DateTimeOffset date, float textSize = OsuFont.DEFAULT_FONT_SIZE, bool italic = true)
: base(date, textSize, italic)
{
}
protected override string Format()
{
var now = DateTime.Now;
var difference = now - Date;
// web uses momentjs's custom locales to format the date for the purposes of the scoreboard.
// this is intended to be a best-effort, more legible approximation of that.
// compare:
// * https://github.com/ppy/osu-web/blob/a8f5a68fb435cb19a4faa4c7c4bce08c4f096933/resources/assets/lib/scoreboard-time.tsx
// * https://momentjs.com/docs/#/customization/ (reference for the customisation format)
// TODO: support localisation (probably via `CommonStrings.CountHours()` etc.)
// requires pluralisable string support framework-side
if (difference.TotalHours < 1)
return CommonStrings.TimeNow.ToString();
if (difference.TotalDays < 1)
return "hr".ToQuantity((int)difference.TotalHours);
// this is where this gets more complicated because of how the calendar works.
// since there's no `TotalMonths` / `TotalYears`, we have to iteratively add months/years
// and test against cutoff dates to determine how many months/years to show.
if (Date > now.AddMonths(-1))
return difference.TotalDays < 2 ? "1dy" : $"{(int)difference.TotalDays}dys";
for (int months = 1; months <= 11; ++months)
{
if (Date > now.AddMonths(-(months + 1)))
return months == 1 ? "1mo" : $"{months}mos";
}
int years = 1;
while (Date <= now.AddYears(-(years + 1)))
years += 1;
return years == 1 ? "1yr" : $"{years}yrs";
}
}
}

View File

@ -7,6 +7,7 @@ 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.Graphics.Shapes;
@ -79,14 +80,16 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
};
scoreManager.OrderByTotalScoreAsync(value.Scores.Select(s => s.CreateScoreInfo(rulesets, beatmapInfo)).ToArray(), loadCancellationSource.Token)
.ContinueWith(ordered => Schedule(() =>
.ContinueWith(task => Schedule(() =>
{
if (loadCancellationSource.IsCancellationRequested)
return;
var topScore = ordered.Result.First();
var scores = task.GetResultSafely();
scoreTable.DisplayScores(ordered.Result, apiBeatmap.Status.GrantsPerformancePoints());
var topScore = scores.First();
scoreTable.DisplayScores(scores, apiBeatmap.Status.GrantsPerformancePoints());
scoreTable.Show();
var userScore = value.UserScore;

View File

@ -5,6 +5,7 @@ using System.Collections.Specialized;
using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Screens;
@ -61,17 +62,19 @@ namespace osu.Game.Overlays.Dashboard
case NotifyCollectionChangedAction.Add:
foreach (int id in e.NewItems.OfType<int>().ToArray())
{
users.GetUserAsync(id).ContinueWith(u =>
users.GetUserAsync(id).ContinueWith(task =>
{
if (u.Result == null) return;
var user = task.GetResultSafely();
if (user == null) return;
Schedule(() =>
{
// user may no longer be playing.
if (!playingUsers.Contains(u.Result.Id))
if (!playingUsers.Contains(user.Id))
return;
userFlow.Add(createUserPanel(u.Result));
userFlow.Add(createUserPanel(user));
});
});
}

View File

@ -54,13 +54,15 @@ namespace osu.Game.Overlays.Rankings.Tables
Spacing = new Vector2(0, row_spacing),
});
rankings.ForEach(_ => backgroundFlow.Add(new TableRowBackground { Height = row_height }));
rankings.ForEach(s => backgroundFlow.Add(CreateRowBackground(s)));
Columns = mainHeaders.Concat(CreateAdditionalHeaders()).Cast<TableColumn>().ToArray();
Content = rankings.Select((s, i) => createContent((page - 1) * items_per_page + i, s)).ToArray().ToRectangular();
Content = rankings.Select((s, i) => CreateRowContent((page - 1) * items_per_page + i, s)).ToArray().ToRectangular();
}
private Drawable[] createContent(int index, TModel item) => new Drawable[] { createIndexDrawable(index), createMainContent(item) }.Concat(CreateAdditionalContent(item)).ToArray();
protected virtual Drawable CreateRowBackground(TModel item) => new TableRowBackground { Height = row_height };
protected virtual Drawable[] CreateRowContent(int index, TModel item) => new Drawable[] { createIndexDrawable(index), createMainContent(item) }.Concat(CreateAdditionalContent(item)).ToArray();
private static RankingsTableColumn[] mainHeaders => new[]
{

View File

@ -24,6 +24,31 @@ namespace osu.Game.Overlays.Rankings.Tables
protected virtual IEnumerable<LocalisableString> GradeColumns => new List<LocalisableString> { RankingsStrings.Statss, RankingsStrings.Stats, RankingsStrings.Stata };
protected override Drawable CreateRowBackground(UserStatistics item)
{
var background = base.CreateRowBackground(item);
// see: https://github.com/ppy/osu-web/blob/9de00a0b874c56893d98261d558d78d76259d81b/resources/views/multiplayer/rooms/_rankings_table.blade.php#L23
if (!item.User.Active)
background.Alpha = 0.5f;
return background;
}
protected override Drawable[] CreateRowContent(int index, UserStatistics item)
{
var content = base.CreateRowContent(index, item);
// see: https://github.com/ppy/osu-web/blob/9de00a0b874c56893d98261d558d78d76259d81b/resources/views/multiplayer/rooms/_rankings_table.blade.php#L23
if (!item.User.Active)
{
foreach (var d in content)
d.Alpha = 0.5f;
}
return content;
}
protected override RankingsTableColumn[] CreateAdditionalHeaders() => new[]
{
new RankingsTableColumn(RankingsStrings.StatAccuracy, Anchor.Centre, new Dimension(GridSizeMode.AutoSize)),

View File

@ -4,6 +4,7 @@
using System.Threading.Tasks;
using osu.Framework;
using osu.Framework.Allocation;
using osu.Framework.Extensions;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Localisation;
using osu.Framework.Platform;
@ -45,9 +46,9 @@ namespace osu.Game.Overlays.Settings.Sections.General
Action = () =>
{
checkForUpdatesButton.Enabled.Value = false;
Task.Run(updateManager.CheckForUpdateAsync).ContinueWith(t => Schedule(() =>
Task.Run(updateManager.CheckForUpdateAsync).ContinueWith(task => Schedule(() =>
{
if (!t.Result)
if (!task.GetResultSafely())
{
notifications?.Post(new SimpleNotification
{

View File

@ -9,6 +9,7 @@ using System.Threading;
using System.Threading.Tasks;
using JetBrains.Annotations;
using osu.Framework.Bindables;
using osu.Framework.Extensions;
using osu.Framework.Platform;
using osu.Framework.Threading;
using osu.Game.Beatmaps;
@ -112,7 +113,7 @@ namespace osu.Game.Scoring
public void GetTotalScore([NotNull] ScoreInfo score, [NotNull] Action<long> callback, ScoringMode mode = ScoringMode.Standardised, CancellationToken cancellationToken = default)
{
GetTotalScoreAsync(score, mode, cancellationToken)
.ContinueWith(s => scheduler.Add(() => callback(s.Result)), TaskContinuationOptions.OnlyOnRanToCompletion);
.ContinueWith(task => scheduler.Add(() => callback(task.GetResultSafely())), TaskContinuationOptions.OnlyOnRanToCompletion);
}
/// <summary>

View File

@ -15,6 +15,7 @@ using osuTK.Input;
namespace osu.Game.Screens.Edit.Compose.Components
{
[Cached]
public class SelectionBox : CompositeDrawable
{
public const float BORDER_RADIUS = 3;
@ -306,7 +307,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
var handle = new SelectionBoxScaleHandle
{
Anchor = anchor,
HandleDrag = e => OnScale?.Invoke(e.Delta, anchor)
HandleScale = (delta, a) => OnScale?.Invoke(delta, a)
};
handle.OperationStarted += operationStarted;
@ -319,7 +320,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
var handle = new SelectionBoxRotationHandle
{
Anchor = anchor,
HandleDrag = e => OnRotation?.Invoke(convertDragEventToAngleOfRotation(e))
HandleRotate = angle => OnRotation?.Invoke(angle)
};
handle.OperationStarted += operationStarted;

View File

@ -8,20 +8,12 @@ namespace osu.Game.Screens.Edit.Compose.Components
{
public abstract class SelectionBoxDragHandle : SelectionBoxControl
{
public Action<DragEvent> HandleDrag { get; set; }
protected override bool OnDragStart(DragStartEvent e)
{
TriggerOperationStarted();
return true;
}
protected override void OnDrag(DragEvent e)
{
HandleDrag?.Invoke(e);
base.OnDrag(e);
}
protected override void OnDragEnd(DragEndEvent e)
{
TriggerOperationEnded();

View File

@ -1,19 +1,34 @@
// 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.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Extensions.EnumExtensions;
using osu.Framework.Extensions.LocalisationExtensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Cursor;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Input.Events;
using osu.Framework.Localisation;
using osuTK;
using osuTK.Graphics;
namespace osu.Game.Screens.Edit.Compose.Components
{
public class SelectionBoxRotationHandle : SelectionBoxDragHandle
public class SelectionBoxRotationHandle : SelectionBoxDragHandle, IHasTooltip
{
public Action<float> HandleRotate { get; set; }
public LocalisableString TooltipText { get; private set; }
private SpriteIcon icon;
private readonly Bindable<float?> cumulativeRotation = new Bindable<float?>();
[Resolved]
private SelectionBox selectionBox { get; set; }
[BackgroundDependencyLoader]
private void load()
{
@ -33,10 +48,59 @@ namespace osu.Game.Screens.Edit.Compose.Components
});
}
protected override void LoadComplete()
{
base.LoadComplete();
cumulativeRotation.BindValueChanged(_ => updateTooltipText(), true);
}
protected override void UpdateHoverState()
{
base.UpdateHoverState();
icon.FadeColour(!IsHeld && IsHovered ? Color4.White : Color4.Black, TRANSFORM_DURATION, Easing.OutQuint);
}
protected override bool OnDragStart(DragStartEvent e)
{
bool handle = base.OnDragStart(e);
if (handle)
cumulativeRotation.Value = 0;
return handle;
}
protected override void OnDrag(DragEvent e)
{
base.OnDrag(e);
float instantaneousAngle = convertDragEventToAngleOfRotation(e);
cumulativeRotation.Value += instantaneousAngle;
if (cumulativeRotation.Value < -180)
cumulativeRotation.Value += 360;
else if (cumulativeRotation.Value > 180)
cumulativeRotation.Value -= 360;
HandleRotate?.Invoke(instantaneousAngle);
}
protected override void OnDragEnd(DragEndEvent e)
{
base.OnDragEnd(e);
cumulativeRotation.Value = null;
}
private float convertDragEventToAngleOfRotation(DragEvent e)
{
// Adjust coordinate system to the center of SelectionBox
float startAngle = MathF.Atan2(e.LastMousePosition.Y - selectionBox.DrawHeight / 2, e.LastMousePosition.X - selectionBox.DrawWidth / 2);
float endAngle = MathF.Atan2(e.MousePosition.Y - selectionBox.DrawHeight / 2, e.MousePosition.X - selectionBox.DrawWidth / 2);
return (endAngle - startAngle) * 180 / MathF.PI;
}
private void updateTooltipText()
{
TooltipText = cumulativeRotation.Value?.ToLocalisableString("0.0°") ?? default(LocalisableString);
}
}
}

View File

@ -1,17 +1,28 @@
// 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.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Input.Events;
using osuTK;
namespace osu.Game.Screens.Edit.Compose.Components
{
public class SelectionBoxScaleHandle : SelectionBoxDragHandle
{
public Action<Vector2, Anchor> HandleScale { get; set; }
[BackgroundDependencyLoader]
private void load()
{
Size = new Vector2(10);
}
protected override void OnDrag(DragEvent e)
{
HandleScale?.Invoke(e.Delta, Anchor);
base.OnDrag(e);
}
}
}

View File

@ -2,6 +2,7 @@
// See the LICENCE file in the repository root for full licence text.
using System;
using System.Globalization;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
@ -9,6 +10,7 @@ using osu.Framework.Graphics.UserInterface;
using osu.Framework.Localisation;
using osu.Game.Graphics.UserInterfaceV2;
using osu.Game.Overlays.Settings;
using osu.Game.Utils;
namespace osu.Game.Screens.Edit.Timing
{
@ -66,7 +68,8 @@ namespace osu.Game.Screens.Edit.Timing
Current.BindValueChanged(val =>
{
textBox.Text = val.NewValue.ToString();
decimal decimalValue = slider.Current.Value.ToDecimal(NumberFormatInfo.InvariantInfo);
textBox.Text = decimalValue.ToString($@"N{FormatUtils.FindPrecision(decimalValue)}");
}, true);
}

View File

@ -9,6 +9,7 @@ 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.Graphics;
using osu.Framework.Screens;
using osu.Framework.Utils;
@ -110,7 +111,7 @@ namespace osu.Game.Screens.Menu
{
// if we detect that the theme track or beatmap is unavailable this is either first startup or things are in a bad state.
// this could happen if a user has nuked their files store. for now, reimport to repair this.
var import = beatmaps.Import(new ZipArchiveReader(game.Resources.GetStream($"Tracks/{BeatmapFile}"), BeatmapFile)).Result;
var import = beatmaps.Import(new ZipArchiveReader(game.Resources.GetStream($"Tracks/{BeatmapFile}"), BeatmapFile)).GetResultSafely();
import.PerformWrite(b =>
{

View File

@ -300,6 +300,7 @@ namespace osu.Game.Screens.OnlinePlay.Match
updateWorkingBeatmap();
beginHandlingTrack();
Scheduler.AddOnce(UpdateMods);
Scheduler.AddOnce(updateRuleset);
}
public override bool OnExiting(IScreen next)
@ -353,8 +354,7 @@ namespace osu.Game.Screens.OnlinePlay.Match
.ToList();
UpdateMods();
Ruleset.Value = rulesets.GetRuleset(selected.RulesetID);
updateRuleset();
if (!selected.AllowedMods.Any())
{
@ -387,6 +387,14 @@ namespace osu.Game.Screens.OnlinePlay.Match
Mods.Value = UserMods.Value.Concat(SelectedItem.Value.RequiredMods).ToList();
}
private void updateRuleset()
{
if (SelectedItem.Value == null || !this.IsCurrentScreen())
return;
Ruleset.Value = rulesets.GetRuleset(SelectedItem.Value.RulesetID);
}
private void beginHandlingTrack()
{
Beatmap.BindValueChanged(applyLoopingToTrack, true);

View File

@ -7,6 +7,7 @@ using System.Collections.Specialized;
using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Extensions;
using osu.Framework.Extensions.Color4Extensions;
using osu.Game.Configuration;
using osu.Game.Database;
@ -76,9 +77,11 @@ namespace osu.Game.Screens.Play.HUD
TeamScores.Add(team, new BindableInt());
}
userLookupCache.GetUsersAsync(playingUsers.Select(u => u.UserID).ToArray()).ContinueWith(users => Schedule(() =>
userLookupCache.GetUsersAsync(playingUsers.Select(u => u.UserID).ToArray()).ContinueWith(task => Schedule(() =>
{
foreach (var user in users.Result)
var users = task.GetResultSafely();
foreach (var user in users)
{
if (user == null)
continue;

View File

@ -10,6 +10,7 @@ using System.Threading.Tasks;
using JetBrains.Annotations;
using osu.Framework.Allocation;
using osu.Framework.Audio.Track;
using osu.Framework.Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
@ -73,10 +74,12 @@ namespace osu.Game.Screens.Play.HUD
var gameplayWorkingBeatmap = new GameplayWorkingBeatmap(gameplayState.Beatmap);
difficultyCache.GetTimedDifficultyAttributesAsync(gameplayWorkingBeatmap, gameplayState.Ruleset, clonedMods, loadCancellationSource.Token)
.ContinueWith(r => Schedule(() =>
.ContinueWith(task => Schedule(() =>
{
timedAttributes = r.Result;
timedAttributes = task.GetResultSafely();
IsValid = true;
if (lastJudgement != null)
onJudgementChanged(lastJudgement);
}), TaskContinuationOptions.OnlyOnRanToCompletion);

View File

@ -9,6 +9,7 @@ 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.Input.Events;
@ -770,7 +771,7 @@ namespace osu.Game.Screens.Play
// This player instance may already be in the process of exiting.
return;
this.Push(CreateResults(prepareScoreForDisplayTask.Result));
this.Push(CreateResults(prepareScoreForDisplayTask.GetResultSafely()));
}, Time.Current + delay, 50);
Scheduler.Add(resultsDisplayDelegate);

View File

@ -6,6 +6,7 @@ using System.Linq;
using System.Threading.Tasks;
using JetBrains.Annotations;
using osu.Framework.Allocation;
using osu.Framework.Extensions;
using osu.Framework.Logging;
using osu.Framework.Screens;
using osu.Game.Online.API;
@ -75,7 +76,7 @@ namespace osu.Game.Screens.Play
api.Queue(req);
tcs.Task.Wait();
tcs.Task.WaitSafely();
return true;
void handleTokenFailure(Exception exception)

View File

@ -5,6 +5,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Localisation;
@ -79,7 +80,7 @@ namespace osu.Game.Screens.Ranking.Expanded
statisticDisplays.AddRange(topStatistics);
statisticDisplays.AddRange(bottomStatistics);
var starDifficulty = beatmapDifficultyCache.GetDifficultyAsync(beatmap, score.Ruleset, score.Mods).Result;
var starDifficulty = beatmapDifficultyCache.GetDifficultyAsync(beatmap, score.Ruleset, score.Mods).GetResultSafely();
AddInternal(new FillFlowContainer
{

View File

@ -5,6 +5,7 @@ using System;
using System.Threading;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Extensions;
using osu.Framework.Graphics;
using osu.Game.Graphics.UserInterface;
using osu.Game.Scoring;
@ -37,7 +38,7 @@ namespace osu.Game.Screens.Ranking.Expanded.Statistics
else
{
performanceCache.CalculatePerformanceAsync(score, cancellationTokenSource.Token)
.ContinueWith(t => Schedule(() => setPerformanceValue(t.Result)), cancellationTokenSource.Token);
.ContinueWith(t => Schedule(() => setPerformanceValue(t.GetResultSafely())), cancellationTokenSource.Token);
}
}

View File

@ -10,6 +10,7 @@ using System.Threading.Tasks;
using JetBrains.Annotations;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Input.Events;
@ -151,9 +152,9 @@ namespace osu.Game.Screens.Ranking
// Calculating score can take a while in extreme scenarios, so only display scores after the process completes.
scoreManager.GetTotalScoreAsync(score)
.ContinueWith(totalScore => Schedule(() =>
.ContinueWith(task => Schedule(() =>
{
flow.SetLayoutPosition(trackingContainer, totalScore.Result);
flow.SetLayoutPosition(trackingContainer, task.GetResultSafely());
trackingContainer.Show();

View File

@ -28,8 +28,8 @@ namespace osu.Game.Screens.Select.Carousel
bool match =
criteria.Ruleset == null ||
BeatmapInfo.RulesetID == criteria.Ruleset.ID ||
(BeatmapInfo.RulesetID == 0 && criteria.Ruleset.ID > 0 && criteria.AllowConvertedBeatmaps);
BeatmapInfo.RulesetID == criteria.Ruleset.OnlineID ||
(BeatmapInfo.RulesetID == 0 && criteria.Ruleset.OnlineID > 0 && criteria.AllowConvertedBeatmaps);
if (BeatmapInfo.BeatmapSet?.Equals(criteria.SelectedBeatmapSet) == true)
{

View File

@ -16,6 +16,7 @@ using osu.Game.Rulesets.Mods;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using osu.Framework.Extensions;
using osu.Framework.Localisation;
using osu.Framework.Threading;
using osu.Framework.Utils;
@ -147,15 +148,18 @@ namespace osu.Game.Screens.Select.Details
starDifficultyCancellationSource = new CancellationTokenSource();
var normalStarDifficulty = difficultyCache.GetDifficultyAsync(BeatmapInfo, ruleset.Value, null, starDifficultyCancellationSource.Token);
var moddedStarDifficulty = difficultyCache.GetDifficultyAsync(BeatmapInfo, ruleset.Value, mods.Value, starDifficultyCancellationSource.Token);
var normalStarDifficultyTask = difficultyCache.GetDifficultyAsync(BeatmapInfo, ruleset.Value, null, starDifficultyCancellationSource.Token);
var moddedStarDifficultyTask = difficultyCache.GetDifficultyAsync(BeatmapInfo, ruleset.Value, mods.Value, starDifficultyCancellationSource.Token);
Task.WhenAll(normalStarDifficulty, moddedStarDifficulty).ContinueWith(_ => Schedule(() =>
Task.WhenAll(normalStarDifficultyTask, moddedStarDifficultyTask).ContinueWith(_ => Schedule(() =>
{
if (normalStarDifficulty.Result == null || moddedStarDifficulty.Result == null)
var normalDifficulty = normalStarDifficultyTask.GetResultSafely();
var moddedDifficulty = moddedStarDifficultyTask.GetResultSafely();
if (normalDifficulty == null || moddedDifficulty == null)
return;
starDifficulty.Value = ((float)normalStarDifficulty.Result.Value.Stars, (float)moddedStarDifficulty.Result.Value.Stars);
starDifficulty.Value = ((float)normalDifficulty.Value.Stars, (float)moddedDifficulty.Value.Stars);
}), starDifficultyCancellationSource.Token, TaskContinuationOptions.OnlyOnRanToCompletion, TaskScheduler.Current);
}

View File

@ -8,6 +8,7 @@ using System.Threading;
using System.Threading.Tasks;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Extensions;
using osu.Game.Beatmaps;
using osu.Game.Online.API;
using osu.Game.Online.API.Requests;
@ -142,7 +143,7 @@ namespace osu.Game.Screens.Select.Leaderboards
}
scoreManager.OrderByTotalScoreAsync(scores.ToArray(), cancellationToken)
.ContinueWith(ordered => scoresCallback?.Invoke(ordered.Result), TaskContinuationOptions.OnlyOnRanToCompletion);
.ContinueWith(task => scoresCallback?.Invoke(task.GetResultSafely()), TaskContinuationOptions.OnlyOnRanToCompletion);
return null;
}
@ -178,12 +179,12 @@ namespace osu.Game.Screens.Select.Leaderboards
req.Success += r =>
{
scoreManager.OrderByTotalScoreAsync(r.Scores.Select(s => s.CreateScoreInfo(rulesets, fetchBeatmapInfo)).ToArray(), cancellationToken)
.ContinueWith(ordered => Schedule(() =>
.ContinueWith(task => Schedule(() =>
{
if (cancellationToken.IsCancellationRequested)
return;
scoresCallback?.Invoke(ordered.Result);
scoresCallback?.Invoke(task.GetResultSafely());
TopScore = r.UserScore?.CreateScoreInfo(rulesets, fetchBeatmapInfo);
}), TaskContinuationOptions.OnlyOnRanToCompletion);
};

View File

@ -7,6 +7,7 @@ using System.Linq;
using JetBrains.Annotations;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Extensions;
using osu.Framework.Extensions.ObjectExtensions;
using osu.Game.Beatmaps;
using osu.Game.Database;
@ -57,9 +58,11 @@ namespace osu.Game.Screens.Spectate
{
base.LoadComplete();
userLookupCache.GetUsersAsync(users.ToArray()).ContinueWith(users => Schedule(() =>
userLookupCache.GetUsersAsync(users.ToArray()).ContinueWith(task => Schedule(() =>
{
foreach (var u in users.Result)
var foundUsers = task.GetResultSafely();
foreach (var u in foundUsers)
{
if (u == null)
continue;

View File

@ -11,6 +11,7 @@ using JetBrains.Annotations;
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.OpenGL.Textures;
using osu.Framework.Graphics.Textures;
@ -153,7 +154,7 @@ namespace osu.Game.Skinning
Name = s.Name + @" (modified)",
Creator = s.Creator,
InstantiationInfo = s.InstantiationInfo,
}).Result;
}).GetResultSafely();
if (result != null)
{

View File

@ -6,9 +6,11 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using Newtonsoft.Json;
using NUnit.Framework;
using osu.Framework.Audio.Track;
using osu.Framework.Extensions;
using osu.Framework.Extensions.ObjectExtensions;
using osu.Framework.Graphics.Textures;
using osu.Game.Beatmaps;
@ -108,37 +110,45 @@ namespace osu.Game.Tests.Beatmaps
private ConvertResult convert(string name, Mod[] mods)
{
var beatmap = GetBeatmap(name);
string beforeConversion = beatmap.Serialize();
var converterResult = new Dictionary<HitObject, IEnumerable<HitObject>>();
var working = new ConversionWorkingBeatmap(beatmap)
var conversionTask = Task.Factory.StartNew(() =>
{
ConversionGenerated = (o, r, c) =>
var beatmap = GetBeatmap(name);
string beforeConversion = beatmap.Serialize();
var converterResult = new Dictionary<HitObject, IEnumerable<HitObject>>();
var working = new ConversionWorkingBeatmap(beatmap)
{
converterResult[o] = r;
OnConversionGenerated(o, r, c);
}
};
ConversionGenerated = (o, r, c) =>
{
converterResult[o] = r;
OnConversionGenerated(o, r, c);
}
};
working.GetPlayableBeatmap(CreateRuleset().RulesetInfo, mods);
working.GetPlayableBeatmap(CreateRuleset().RulesetInfo, mods);
string afterConversion = beatmap.Serialize();
string afterConversion = beatmap.Serialize();
Assert.AreEqual(beforeConversion, afterConversion, "Conversion altered original beatmap");
Assert.AreEqual(beforeConversion, afterConversion, "Conversion altered original beatmap");
return new ConvertResult
{
Mappings = converterResult.Select(r =>
return new ConvertResult
{
var mapping = CreateConvertMapping(r.Key);
mapping.StartTime = r.Key.StartTime;
mapping.Objects.AddRange(r.Value.SelectMany(CreateConvertValue));
return mapping;
}).ToList()
};
Mappings = converterResult.Select(r =>
{
var mapping = CreateConvertMapping(r.Key);
mapping.StartTime = r.Key.StartTime;
mapping.Objects.AddRange(r.Value.SelectMany(CreateConvertValue));
return mapping;
}).ToList()
};
}, TaskCreationOptions.LongRunning);
if (!conversionTask.Wait(10000))
Assert.Fail("Conversion timed out");
return conversionTask.GetResultSafely();
}
protected virtual void OnConversionGenerated(HitObject original, IEnumerable<HitObject> result, IBeatmapConverter beatmapConverter)

View File

@ -11,6 +11,7 @@ using System.Threading;
using System.Threading.Tasks;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Extensions;
using osu.Game.Beatmaps;
using osu.Game.Online.API;
using osu.Game.Online.API.Requests.Responses;
@ -77,7 +78,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
private void addUser(MultiplayerRoomUser user)
{
((IMultiplayerClient)this).UserJoined(user).Wait();
((IMultiplayerClient)this).UserJoined(user).WaitSafely();
// We want the user to be immediately available for testing, so force a scheduler update to run the update-bound continuation.
Scheduler.Update();
@ -93,7 +94,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
.Select(team => (teamID: team.ID, userCount: Room.Users.Count(u => (u.MatchState as TeamVersusUserState)?.TeamID == team.ID)))
.OrderBy(pair => pair.userCount)
.First().teamID;
((IMultiplayerClient)this).MatchUserStateChanged(user.UserID, new TeamVersusUserState { TeamID = bestTeam }).Wait();
((IMultiplayerClient)this).MatchUserStateChanged(user.UserID, new TeamVersusUserState { TeamID = bestTeam }).WaitSafely();
break;
}
}
@ -156,7 +157,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
ChangeRoomState(MultiplayerRoomState.Open);
((IMultiplayerClient)this).ResultsReady();
FinishCurrentItem().Wait();
FinishCurrentItem().WaitSafely();
}
break;
@ -216,7 +217,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
Debug.Assert(Room != null);
// emulate the server sending this after the join room. scheduler required to make sure the join room event is fired first (in Join).
changeMatchType(Room.Settings.MatchType).Wait();
changeMatchType(Room.Settings.MatchType).WaitSafely();
RoomJoined = true;
}

View File

@ -36,8 +36,8 @@
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Realm" Version="10.7.1" />
<PackageReference Include="ppy.osu.Framework" Version="2021.1227.0" />
<PackageReference Include="ppy.osu.Game.Resources" Version="2021.1215.0" />
<PackageReference Include="ppy.osu.Framework" Version="2022.107.0" />
<PackageReference Include="ppy.osu.Game.Resources" Version="2022.109.0" />
<PackageReference Include="Sentry" Version="3.12.1" />
<PackageReference Include="SharpCompress" Version="0.30.1" />
<PackageReference Include="NUnit" Version="3.13.2" />

View File

@ -60,8 +60,8 @@
<Reference Include="System.Net.Http" />
</ItemGroup>
<ItemGroup Label="Package References">
<PackageReference Include="ppy.osu.Framework.iOS" Version="2021.1227.0" />
<PackageReference Include="ppy.osu.Game.Resources" Version="2021.1215.0" />
<PackageReference Include="ppy.osu.Framework.iOS" Version="2022.107.0" />
<PackageReference Include="ppy.osu.Game.Resources" Version="2022.109.0" />
</ItemGroup>
<!-- See https://github.com/dotnet/runtime/issues/35988 (can be removed after Xamarin uses net5.0 / net6.0) -->
<PropertyGroup>
@ -83,7 +83,7 @@
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.2.6" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.6" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="ppy.osu.Framework" Version="2021.1227.0" />
<PackageReference Include="ppy.osu.Framework" Version="2022.107.0" />
<PackageReference Include="SharpCompress" Version="0.30.0" />
<PackageReference Include="NUnit" Version="3.13.2" />
<PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />