1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-28 09:43:10 +08:00

Make beatmap conversion support cancellation tokens

This commit is contained in:
smoogipoo 2020-09-17 17:40:05 +09:00
parent 0d889f8cc0
commit c7d24203ce
9 changed files with 31 additions and 23 deletions

View File

@ -5,6 +5,7 @@ using osu.Game.Beatmaps;
using osu.Game.Rulesets.Catch.Objects; using osu.Game.Rulesets.Catch.Objects;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading;
using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Objects.Types;
using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects;
using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Extensions.IEnumerableExtensions;
@ -20,7 +21,7 @@ namespace osu.Game.Rulesets.Catch.Beatmaps
public override bool CanConvert() => Beatmap.HitObjects.All(h => h is IHasXPosition); public override bool CanConvert() => Beatmap.HitObjects.All(h => h is IHasXPosition);
protected override IEnumerable<CatchHitObject> ConvertHitObject(HitObject obj, IBeatmap beatmap) protected override IEnumerable<CatchHitObject> ConvertHitObject(HitObject obj, IBeatmap beatmap, CancellationToken cancellationToken)
{ {
var positionData = obj as IHasXPosition; var positionData = obj as IHasXPosition;
var comboData = obj as IHasCombo; var comboData = obj as IHasCombo;

View File

@ -5,6 +5,7 @@ using osu.Game.Rulesets.Mania.Objects;
using System; using System;
using System.Linq; using System.Linq;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading;
using osu.Game.Audio; using osu.Game.Audio;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects;
@ -68,14 +69,14 @@ namespace osu.Game.Rulesets.Mania.Beatmaps
public override bool CanConvert() => Beatmap.HitObjects.All(h => h is IHasXPosition); public override bool CanConvert() => Beatmap.HitObjects.All(h => h is IHasXPosition);
protected override Beatmap<ManiaHitObject> ConvertBeatmap(IBeatmap original) protected override Beatmap<ManiaHitObject> ConvertBeatmap(IBeatmap original, CancellationToken cancellationToken)
{ {
BeatmapDifficulty difficulty = original.BeatmapInfo.BaseDifficulty; BeatmapDifficulty difficulty = original.BeatmapInfo.BaseDifficulty;
int seed = (int)MathF.Round(difficulty.DrainRate + difficulty.CircleSize) * 20 + (int)(difficulty.OverallDifficulty * 41.2) + (int)MathF.Round(difficulty.ApproachRate); int seed = (int)MathF.Round(difficulty.DrainRate + difficulty.CircleSize) * 20 + (int)(difficulty.OverallDifficulty * 41.2) + (int)MathF.Round(difficulty.ApproachRate);
Random = new FastRandom(seed); Random = new FastRandom(seed);
return base.ConvertBeatmap(original); return base.ConvertBeatmap(original, cancellationToken);
} }
protected override Beatmap<ManiaHitObject> CreateBeatmap() protected override Beatmap<ManiaHitObject> CreateBeatmap()
@ -88,7 +89,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps
return beatmap; return beatmap;
} }
protected override IEnumerable<ManiaHitObject> ConvertHitObject(HitObject original, IBeatmap beatmap) protected override IEnumerable<ManiaHitObject> ConvertHitObject(HitObject original, IBeatmap beatmap, CancellationToken cancellationToken)
{ {
if (original is ManiaHitObject maniaOriginal) if (original is ManiaHitObject maniaOriginal)
{ {

View File

@ -8,6 +8,7 @@ using osu.Game.Rulesets.Osu.Objects;
using System.Collections.Generic; using System.Collections.Generic;
using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Objects.Types;
using System.Linq; using System.Linq;
using System.Threading;
using osu.Game.Rulesets.Osu.UI; using osu.Game.Rulesets.Osu.UI;
using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Extensions.IEnumerableExtensions;
@ -22,7 +23,7 @@ namespace osu.Game.Rulesets.Osu.Beatmaps
public override bool CanConvert() => Beatmap.HitObjects.All(h => h is IHasPosition); public override bool CanConvert() => Beatmap.HitObjects.All(h => h is IHasPosition);
protected override IEnumerable<OsuHitObject> ConvertHitObject(HitObject original, IBeatmap beatmap) protected override IEnumerable<OsuHitObject> ConvertHitObject(HitObject original, IBeatmap beatmap, CancellationToken cancellationToken)
{ {
var positionData = original as IHasPosition; var positionData = original as IHasPosition;
var comboData = original as IHasCombo; var comboData = original as IHasCombo;

View File

@ -8,6 +8,7 @@ using osu.Game.Rulesets.Taiko.Objects;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading;
using osu.Game.Audio; using osu.Game.Audio;
using osu.Game.Beatmaps.ControlPoints; using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Beatmaps.Formats; using osu.Game.Beatmaps.Formats;
@ -48,14 +49,14 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps
public override bool CanConvert() => true; public override bool CanConvert() => true;
protected override Beatmap<TaikoHitObject> ConvertBeatmap(IBeatmap original) protected override Beatmap<TaikoHitObject> ConvertBeatmap(IBeatmap original, CancellationToken cancellationToken)
{ {
// Rewrite the beatmap info to add the slider velocity multiplier // Rewrite the beatmap info to add the slider velocity multiplier
original.BeatmapInfo = original.BeatmapInfo.Clone(); original.BeatmapInfo = original.BeatmapInfo.Clone();
original.BeatmapInfo.BaseDifficulty = original.BeatmapInfo.BaseDifficulty.Clone(); original.BeatmapInfo.BaseDifficulty = original.BeatmapInfo.BaseDifficulty.Clone();
original.BeatmapInfo.BaseDifficulty.SliderMultiplier *= LEGACY_VELOCITY_MULTIPLIER; original.BeatmapInfo.BaseDifficulty.SliderMultiplier *= LEGACY_VELOCITY_MULTIPLIER;
Beatmap<TaikoHitObject> converted = base.ConvertBeatmap(original); Beatmap<TaikoHitObject> converted = base.ConvertBeatmap(original, cancellationToken);
if (original.BeatmapInfo.RulesetID == 3) if (original.BeatmapInfo.RulesetID == 3)
{ {
@ -72,7 +73,7 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps
return converted; return converted;
} }
protected override IEnumerable<TaikoHitObject> ConvertHitObject(HitObject obj, IBeatmap beatmap) protected override IEnumerable<TaikoHitObject> ConvertHitObject(HitObject obj, IBeatmap beatmap, CancellationToken cancellationToken)
{ {
// Old osu! used hit sounding to determine various hit type information // Old osu! used hit sounding to determine various hit type information
IList<HitSampleInfo> samples = obj.Samples; IList<HitSampleInfo> samples = obj.Samples;

View File

@ -4,6 +4,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading;
using NUnit.Framework; using NUnit.Framework;
using osu.Framework.Bindables; using osu.Framework.Bindables;
using osu.Framework.Graphics; using osu.Framework.Graphics;
@ -276,7 +277,7 @@ namespace osu.Game.Tests.Visual.Gameplay
public override bool CanConvert() => true; public override bool CanConvert() => true;
protected override IEnumerable<TestHitObject> ConvertHitObject(HitObject original, IBeatmap beatmap) protected override IEnumerable<TestHitObject> ConvertHitObject(HitObject original, IBeatmap beatmap, CancellationToken cancellationToken)
{ {
yield return new TestHitObject yield return new TestHitObject
{ {

View File

@ -4,6 +4,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading;
using osu.Game.Rulesets; using osu.Game.Rulesets;
using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects;
@ -36,34 +37,31 @@ namespace osu.Game.Beatmaps
/// </summary> /// </summary>
public abstract bool CanConvert(); public abstract bool CanConvert();
/// <summary> public IBeatmap Convert(CancellationToken cancellationToken = default)
/// Converts <see cref="Beatmap"/>.
/// </summary>
/// <returns>The converted Beatmap.</returns>
public IBeatmap Convert()
{ {
// We always operate on a clone of the original beatmap, to not modify it game-wide // We always operate on a clone of the original beatmap, to not modify it game-wide
return ConvertBeatmap(Beatmap.Clone()); return ConvertBeatmap(Beatmap.Clone(), cancellationToken);
} }
/// <summary> /// <summary>
/// Performs the conversion of a Beatmap using this Beatmap Converter. /// Performs the conversion of a Beatmap using this Beatmap Converter.
/// </summary> /// </summary>
/// <param name="original">The un-converted Beatmap.</param> /// <param name="original">The un-converted Beatmap.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>The converted Beatmap.</returns> /// <returns>The converted Beatmap.</returns>
protected virtual Beatmap<T> ConvertBeatmap(IBeatmap original) protected virtual Beatmap<T> ConvertBeatmap(IBeatmap original, CancellationToken cancellationToken)
{ {
var beatmap = CreateBeatmap(); var beatmap = CreateBeatmap();
beatmap.BeatmapInfo = original.BeatmapInfo; beatmap.BeatmapInfo = original.BeatmapInfo;
beatmap.ControlPointInfo = original.ControlPointInfo; beatmap.ControlPointInfo = original.ControlPointInfo;
beatmap.HitObjects = convertHitObjects(original.HitObjects, original).OrderBy(s => s.StartTime).ToList(); beatmap.HitObjects = convertHitObjects(original.HitObjects, original, cancellationToken).OrderBy(s => s.StartTime).ToList();
beatmap.Breaks = original.Breaks; beatmap.Breaks = original.Breaks;
return beatmap; return beatmap;
} }
private List<T> convertHitObjects(IReadOnlyList<HitObject> hitObjects, IBeatmap beatmap) private List<T> convertHitObjects(IReadOnlyList<HitObject> hitObjects, IBeatmap beatmap, CancellationToken cancellationToken)
{ {
var result = new List<T>(hitObjects.Count); var result = new List<T>(hitObjects.Count);
@ -75,7 +73,7 @@ namespace osu.Game.Beatmaps
continue; continue;
} }
var converted = ConvertHitObject(obj, beatmap); var converted = ConvertHitObject(obj, beatmap, cancellationToken);
if (ObjectConverted != null) if (ObjectConverted != null)
{ {
@ -104,7 +102,8 @@ namespace osu.Game.Beatmaps
/// </summary> /// </summary>
/// <param name="original">The hit object to convert.</param> /// <param name="original">The hit object to convert.</param>
/// <param name="beatmap">The un-converted Beatmap.</param> /// <param name="beatmap">The un-converted Beatmap.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>The converted hit object.</returns> /// <returns>The converted hit object.</returns>
protected abstract IEnumerable<T> ConvertHitObject(HitObject original, IBeatmap beatmap); protected abstract IEnumerable<T> ConvertHitObject(HitObject original, IBeatmap beatmap, CancellationToken cancellationToken);
} }
} }

View File

@ -3,6 +3,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading;
using JetBrains.Annotations; using JetBrains.Annotations;
using osu.Framework.Audio; using osu.Framework.Audio;
using osu.Framework.Audio.Track; using osu.Framework.Audio.Track;
@ -76,7 +77,7 @@ namespace osu.Game.Beatmaps
public bool CanConvert() => true; public bool CanConvert() => true;
public IBeatmap Convert() public IBeatmap Convert(CancellationToken cancellationToken)
{ {
foreach (var obj in Beatmap.HitObjects) foreach (var obj in Beatmap.HitObjects)
ObjectConverted?.Invoke(obj, obj.Yield()); ObjectConverted?.Invoke(obj, obj.Yield());

View File

@ -3,6 +3,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading;
using osu.Game.Rulesets; using osu.Game.Rulesets;
using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects;
@ -30,6 +31,8 @@ namespace osu.Game.Beatmaps
/// <summary> /// <summary>
/// Converts <see cref="Beatmap"/>. /// Converts <see cref="Beatmap"/>.
/// </summary> /// </summary>
IBeatmap Convert(); /// <param name="cancellationToken">The cancellation token.</param>
/// <returns>The converted Beatmap.</returns>
IBeatmap Convert(CancellationToken cancellationToken);
} }
} }

View File

@ -109,7 +109,7 @@ namespace osu.Game.Beatmaps
} }
// Convert // Convert
IBeatmap converted = converter.Convert(); IBeatmap converted = converter.Convert(cancellationSource.Token);
// Apply conversion mods to the result // Apply conversion mods to the result
foreach (var mod in mods.OfType<IApplicableAfterBeatmapConversion>()) foreach (var mod in mods.OfType<IApplicableAfterBeatmapConversion>())