Refactor beatmap conversion testing (#5555)

Refactor beatmap conversion testing

Co-authored-by: Dean Herbert <pe@ppy.sh>
This commit is contained in:
Dean Herbert 2019-08-05 09:45:30 +02:00 committed by GitHub
commit 9fab345d79
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 94 additions and 27 deletions

View File

@ -35,11 +35,37 @@ namespace osu.Game.Rulesets.Mania.Tests
}; };
} }
protected override ManiaConvertMapping CreateConvertMapping() => new ManiaConvertMapping(Converter); private readonly Dictionary<HitObject, RngSnapshot> rngSnapshots = new Dictionary<HitObject, RngSnapshot>();
protected override void OnConversionGenerated(HitObject original, IEnumerable<HitObject> result, IBeatmapConverter beatmapConverter)
{
base.OnConversionGenerated(original, result, beatmapConverter);
rngSnapshots[original] = new RngSnapshot(beatmapConverter);
}
protected override ManiaConvertMapping CreateConvertMapping(HitObject source) => new ManiaConvertMapping(rngSnapshots[source]);
protected override Ruleset CreateRuleset() => new ManiaRuleset(); protected override Ruleset CreateRuleset() => new ManiaRuleset();
} }
public class RngSnapshot
{
public readonly uint RandomW;
public readonly uint RandomX;
public readonly uint RandomY;
public readonly uint RandomZ;
public RngSnapshot(IBeatmapConverter converter)
{
var maniaConverter = (ManiaBeatmapConverter)converter;
RandomW = maniaConverter.Random.W;
RandomX = maniaConverter.Random.X;
RandomY = maniaConverter.Random.Y;
RandomZ = maniaConverter.Random.Z;
}
}
public class ManiaConvertMapping : ConvertMapping<ConvertValue>, IEquatable<ManiaConvertMapping> public class ManiaConvertMapping : ConvertMapping<ConvertValue>, IEquatable<ManiaConvertMapping>
{ {
public uint RandomW; public uint RandomW;
@ -51,13 +77,12 @@ namespace osu.Game.Rulesets.Mania.Tests
{ {
} }
public ManiaConvertMapping(IBeatmapConverter converter) public ManiaConvertMapping(RngSnapshot snapshot)
{ {
var maniaConverter = (ManiaBeatmapConverter)converter; RandomW = snapshot.RandomW;
RandomW = maniaConverter.Random.W; RandomX = snapshot.RandomX;
RandomX = maniaConverter.Random.X; RandomY = snapshot.RandomY;
RandomY = maniaConverter.Random.Y; RandomZ = snapshot.RandomZ;
RandomZ = maniaConverter.Random.Z;
} }
public bool Equals(ManiaConvertMapping other) => other != null && RandomW == other.RandomW && RandomX == other.RandomX && RandomY == other.RandomY && RandomZ == other.RandomZ; public bool Equals(ManiaConvertMapping other) => other != null && RandomW == other.RandomW && RandomX == other.RandomX && RandomY == other.RandomY && RandomZ == other.RandomZ;

View File

@ -89,6 +89,14 @@ namespace osu.Game.Beatmaps
return path; return path;
} }
/// <summary>
/// Creates a <see cref="IBeatmapConverter"/> to convert a <see cref="IBeatmap"/> for a specified <see cref="Ruleset"/>.
/// </summary>
/// <param name="beatmap">The <see cref="IBeatmap"/> to be converted.</param>
/// <param name="ruleset">The <see cref="Ruleset"/> for which <paramref name="beatmap"/> should be converted.</param>
/// <returns>The applicable <see cref="IBeatmapConverter"/>.</returns>
protected virtual IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap, Ruleset ruleset) => ruleset.CreateBeatmapConverter(beatmap);
/// <summary> /// <summary>
/// Constructs a playable <see cref="IBeatmap"/> from <see cref="Beatmap"/> using the applicable converters for a specific <see cref="RulesetInfo"/>. /// Constructs a playable <see cref="IBeatmap"/> from <see cref="Beatmap"/> using the applicable converters for a specific <see cref="RulesetInfo"/>.
/// <para> /// <para>
@ -104,7 +112,7 @@ namespace osu.Game.Beatmaps
{ {
var rulesetInstance = ruleset.CreateInstance(); var rulesetInstance = ruleset.CreateInstance();
IBeatmapConverter converter = rulesetInstance.CreateBeatmapConverter(Beatmap); IBeatmapConverter converter = CreateBeatmapConverter(Beatmap, rulesetInstance);
// Check if the beatmap can be converted // Check if the beatmap can be converted
if (!converter.CanConvert) if (!converter.CanConvert)

View File

@ -4,13 +4,16 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq;
using System.Reflection; using System.Reflection;
using Newtonsoft.Json; using Newtonsoft.Json;
using NUnit.Framework; using NUnit.Framework;
using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Audio.Track;
using osu.Framework.Graphics.Textures;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Beatmaps.Formats; using osu.Game.Beatmaps.Formats;
using osu.Game.Rulesets; using osu.Game.Rulesets;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects;
namespace osu.Game.Tests.Beatmaps namespace osu.Game.Tests.Beatmaps
@ -25,8 +28,6 @@ namespace osu.Game.Tests.Beatmaps
protected abstract string ResourceAssembly { get; } protected abstract string ResourceAssembly { get; }
protected IBeatmapConverter Converter { get; private set; }
protected void Test(string name) protected void Test(string name)
{ {
var ourResult = convert(name); var ourResult = convert(name);
@ -98,26 +99,33 @@ namespace osu.Game.Tests.Beatmaps
var rulesetInstance = CreateRuleset(); var rulesetInstance = CreateRuleset();
beatmap.BeatmapInfo.Ruleset = beatmap.BeatmapInfo.RulesetID == rulesetInstance.RulesetInfo.ID ? rulesetInstance.RulesetInfo : new RulesetInfo(); beatmap.BeatmapInfo.Ruleset = beatmap.BeatmapInfo.RulesetID == rulesetInstance.RulesetInfo.ID ? rulesetInstance.RulesetInfo : new RulesetInfo();
Converter = rulesetInstance.CreateBeatmapConverter(beatmap); var converterResult = new Dictionary<HitObject, IEnumerable<HitObject>>();
var result = new ConvertResult(); var working = new ConversionWorkingBeatmap(beatmap)
Converter.ObjectConverted += (orig, converted) =>
{ {
converted.ForEach(h => h.ApplyDefaults(beatmap.ControlPointInfo, beatmap.BeatmapInfo.BaseDifficulty)); ConversionGenerated = (o, r, c) =>
{
var mapping = CreateConvertMapping(); converterResult[o] = r;
mapping.StartTime = orig.StartTime; OnConversionGenerated(o, r, c);
}
foreach (var obj in converted)
mapping.Objects.AddRange(CreateConvertValue(obj));
result.Mappings.Add(mapping);
}; };
IBeatmap convertedBeatmap = Converter.Convert(); working.GetPlayableBeatmap(rulesetInstance.RulesetInfo, Array.Empty<Mod>());
rulesetInstance.CreateBeatmapProcessor(convertedBeatmap)?.PostProcess();
return result; return new ConvertResult
{
Mappings = converterResult.Select(r =>
{
var mapping = CreateConvertMapping(r.Key);
mapping.StartTime = r.Key.StartTime;
mapping.Objects.AddRange(r.Value.SelectMany(CreateConvertValue));
return mapping;
}).ToList()
};
}
protected virtual void OnConversionGenerated(HitObject original, IEnumerable<HitObject> result, IBeatmapConverter beatmapConverter)
{
} }
private ConvertResult read(string name) private ConvertResult read(string name)
@ -154,7 +162,7 @@ namespace osu.Game.Tests.Beatmaps
/// This should be used to validate the integrity of the conversion process after a conversion has occurred. /// This should be used to validate the integrity of the conversion process after a conversion has occurred.
/// </para> /// </para>
/// </summary> /// </summary>
protected virtual TConvertMapping CreateConvertMapping() => new TConvertMapping(); protected virtual TConvertMapping CreateConvertMapping(HitObject source) => new TConvertMapping();
/// <summary> /// <summary>
/// Creates the conversion value for a <see cref="HitObject"/>. A conversion value stores information about the converted <see cref="HitObject"/>. /// Creates the conversion value for a <see cref="HitObject"/>. A conversion value stores information about the converted <see cref="HitObject"/>.
@ -176,6 +184,32 @@ namespace osu.Game.Tests.Beatmaps
[JsonProperty] [JsonProperty]
public List<TConvertMapping> Mappings = new List<TConvertMapping>(); public List<TConvertMapping> Mappings = new List<TConvertMapping>();
} }
private class ConversionWorkingBeatmap : WorkingBeatmap
{
public Action<HitObject, IEnumerable<HitObject>, IBeatmapConverter> ConversionGenerated;
private readonly IBeatmap beatmap;
public ConversionWorkingBeatmap(IBeatmap beatmap)
: base(beatmap.BeatmapInfo, null)
{
this.beatmap = beatmap;
}
protected override IBeatmap GetBeatmap() => beatmap;
protected override Texture GetBackground() => throw new NotImplementedException();
protected override Track GetTrack() => throw new NotImplementedException();
protected override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap, Ruleset ruleset)
{
var converter = base.CreateBeatmapConverter(beatmap, ruleset);
converter.ObjectConverted += (orig, converted) => ConversionGenerated?.Invoke(orig, converted, converter);
return converter;
}
}
} }
public abstract class BeatmapConversionTest<TConvertValue> : BeatmapConversionTest<ConvertMapping<TConvertValue>, TConvertValue> public abstract class BeatmapConversionTest<TConvertValue> : BeatmapConversionTest<ConvertMapping<TConvertValue>, TConvertValue>