1
0
mirror of https://github.com/ppy/osu.git synced 2025-02-22 02:22:57 +08:00

Merge pull request #12759 from Naxesss/beatmap-verifier-context

Encapsulate check arguments in context object
This commit is contained in:
Dean Herbert 2021-05-15 15:39:12 +09:00 committed by GitHub
commit bdcb1a624e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 152 additions and 93 deletions

View File

@ -5,6 +5,7 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using NUnit.Framework; using NUnit.Framework;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Rulesets.Edit;
using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Objects.Types;
using osu.Game.Rulesets.Osu.Edit.Checks; using osu.Game.Rulesets.Osu.Edit.Checks;
@ -224,12 +225,14 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor.Checks
private void assertOk(IBeatmap beatmap) private void assertOk(IBeatmap beatmap)
{ {
Assert.That(check.Run(beatmap, new TestWorkingBeatmap(beatmap)), Is.Empty); var context = new BeatmapVerifierContext(beatmap, new TestWorkingBeatmap(beatmap));
Assert.That(check.Run(context), Is.Empty);
} }
private void assertOffscreenCircle(IBeatmap beatmap) private void assertOffscreenCircle(IBeatmap beatmap)
{ {
var issues = check.Run(beatmap, new TestWorkingBeatmap(beatmap)).ToList(); var context = new BeatmapVerifierContext(beatmap, new TestWorkingBeatmap(beatmap));
var issues = check.Run(context).ToList();
Assert.That(issues, Has.Count.EqualTo(1)); Assert.That(issues, Has.Count.EqualTo(1));
Assert.That(issues.Single().Template is CheckOffscreenObjects.IssueTemplateOffscreenCircle); Assert.That(issues.Single().Template is CheckOffscreenObjects.IssueTemplateOffscreenCircle);
@ -237,7 +240,8 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor.Checks
private void assertOffscreenSlider(IBeatmap beatmap) private void assertOffscreenSlider(IBeatmap beatmap)
{ {
var issues = check.Run(beatmap, new TestWorkingBeatmap(beatmap)).ToList(); var context = new BeatmapVerifierContext(beatmap, new TestWorkingBeatmap(beatmap));
var issues = check.Run(context).ToList();
Assert.That(issues, Has.Count.EqualTo(1)); Assert.That(issues, Has.Count.EqualTo(1));
Assert.That(issues.Single().Template is CheckOffscreenObjects.IssueTemplateOffscreenSlider); Assert.That(issues.Single().Template is CheckOffscreenObjects.IssueTemplateOffscreenSlider);

View File

@ -2,7 +2,7 @@
// See the LICENCE file in the repository root for full licence text. // See the LICENCE file in the repository root for full licence text.
using System.Collections.Generic; using System.Collections.Generic;
using osu.Game.Beatmaps; using osu.Game.Rulesets.Edit;
using osu.Game.Rulesets.Edit.Checks.Components; using osu.Game.Rulesets.Edit.Checks.Components;
using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Osu.Objects;
using osuTK; using osuTK;
@ -31,9 +31,9 @@ namespace osu.Game.Rulesets.Osu.Edit.Checks
new IssueTemplateOffscreenSlider(this) new IssueTemplateOffscreenSlider(this)
}; };
public IEnumerable<Issue> Run(IBeatmap playableBeatmap, IWorkingBeatmap workingBeatmap) public IEnumerable<Issue> Run(BeatmapVerifierContext context)
{ {
foreach (var hitobject in playableBeatmap.HitObjects) foreach (var hitobject in context.Beatmap.HitObjects)
{ {
switch (hitobject) switch (hitobject)
{ {

View File

@ -3,7 +3,6 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Edit;
using osu.Game.Rulesets.Edit.Checks.Components; using osu.Game.Rulesets.Edit.Checks.Components;
using osu.Game.Rulesets.Osu.Edit.Checks; using osu.Game.Rulesets.Osu.Edit.Checks;
@ -17,9 +16,9 @@ namespace osu.Game.Rulesets.Osu.Edit
new CheckOffscreenObjects() new CheckOffscreenObjects()
}; };
public IEnumerable<Issue> Run(IBeatmap playableBeatmap, WorkingBeatmap workingBeatmap) public IEnumerable<Issue> Run(BeatmapVerifierContext context)
{ {
return checks.SelectMany(check => check.Run(playableBeatmap, workingBeatmap)); return checks.SelectMany(check => check.Run(context));
} }
} }
} }

View File

@ -6,6 +6,7 @@ using Moq;
using NUnit.Framework; using NUnit.Framework;
using osu.Framework.Audio.Track; using osu.Framework.Audio.Track;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Rulesets.Edit;
using osu.Game.Rulesets.Edit.Checks; using osu.Game.Rulesets.Edit.Checks;
using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects;
@ -40,23 +41,23 @@ namespace osu.Game.Tests.Editing.Checks
mock.SetupGet(w => w.Beatmap).Returns(beatmap); mock.SetupGet(w => w.Beatmap).Returns(beatmap);
mock.SetupGet(w => w.Track).Returns((Track)null); mock.SetupGet(w => w.Track).Returns((Track)null);
Assert.That(check.Run(beatmap, mock.Object), Is.Empty); Assert.That(check.Run(new BeatmapVerifierContext(beatmap, mock.Object)), Is.Empty);
} }
[Test] [Test]
public void TestAcceptable() public void TestAcceptable()
{ {
var mock = getMockWorkingBeatmap(192); var context = getContext(192);
Assert.That(check.Run(beatmap, mock.Object), Is.Empty); Assert.That(check.Run(context), Is.Empty);
} }
[Test] [Test]
public void TestNullBitrate() public void TestNullBitrate()
{ {
var mock = getMockWorkingBeatmap(null); var context = getContext(null);
var issues = check.Run(beatmap, mock.Object).ToList(); var issues = check.Run(context).ToList();
Assert.That(issues, Has.Count.EqualTo(1)); Assert.That(issues, Has.Count.EqualTo(1));
Assert.That(issues.Single().Template is CheckAudioQuality.IssueTemplateNoBitrate); Assert.That(issues.Single().Template is CheckAudioQuality.IssueTemplateNoBitrate);
@ -65,9 +66,9 @@ namespace osu.Game.Tests.Editing.Checks
[Test] [Test]
public void TestZeroBitrate() public void TestZeroBitrate()
{ {
var mock = getMockWorkingBeatmap(0); var context = getContext(0);
var issues = check.Run(beatmap, mock.Object).ToList(); var issues = check.Run(context).ToList();
Assert.That(issues, Has.Count.EqualTo(1)); Assert.That(issues, Has.Count.EqualTo(1));
Assert.That(issues.Single().Template is CheckAudioQuality.IssueTemplateNoBitrate); Assert.That(issues.Single().Template is CheckAudioQuality.IssueTemplateNoBitrate);
@ -76,9 +77,9 @@ namespace osu.Game.Tests.Editing.Checks
[Test] [Test]
public void TestTooHighBitrate() public void TestTooHighBitrate()
{ {
var mock = getMockWorkingBeatmap(320); var context = getContext(320);
var issues = check.Run(beatmap, mock.Object).ToList(); var issues = check.Run(context).ToList();
Assert.That(issues, Has.Count.EqualTo(1)); Assert.That(issues, Has.Count.EqualTo(1));
Assert.That(issues.Single().Template is CheckAudioQuality.IssueTemplateTooHighBitrate); Assert.That(issues.Single().Template is CheckAudioQuality.IssueTemplateTooHighBitrate);
@ -87,14 +88,19 @@ namespace osu.Game.Tests.Editing.Checks
[Test] [Test]
public void TestTooLowBitrate() public void TestTooLowBitrate()
{ {
var mock = getMockWorkingBeatmap(64); var context = getContext(64);
var issues = check.Run(beatmap, mock.Object).ToList(); var issues = check.Run(context).ToList();
Assert.That(issues, Has.Count.EqualTo(1)); Assert.That(issues, Has.Count.EqualTo(1));
Assert.That(issues.Single().Template is CheckAudioQuality.IssueTemplateTooLowBitrate); Assert.That(issues.Single().Template is CheckAudioQuality.IssueTemplateTooLowBitrate);
} }
private BeatmapVerifierContext getContext(int? audioBitrate)
{
return new BeatmapVerifierContext(beatmap, getMockWorkingBeatmap(audioBitrate).Object);
}
/// <summary> /// <summary>
/// Returns the mock of the working beatmap with the given audio properties. /// Returns the mock of the working beatmap with the given audio properties.
/// </summary> /// </summary>

View File

@ -9,6 +9,7 @@ using Moq;
using NUnit.Framework; using NUnit.Framework;
using osu.Framework.Graphics.Textures; using osu.Framework.Graphics.Textures;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Rulesets.Edit;
using osu.Game.Rulesets.Edit.Checks; using osu.Game.Rulesets.Edit.Checks;
using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects;
using FileInfo = osu.Game.IO.FileInfo; using FileInfo = osu.Game.IO.FileInfo;
@ -53,25 +54,25 @@ namespace osu.Game.Tests.Editing.Checks
{ {
// While this is a problem, it is out of scope for this check and is caught by a different one. // While this is a problem, it is out of scope for this check and is caught by a different one.
beatmap.Metadata.BackgroundFile = null; beatmap.Metadata.BackgroundFile = null;
var mock = getMockWorkingBeatmap(null, System.Array.Empty<byte>()); var context = getContext(null, System.Array.Empty<byte>());
Assert.That(check.Run(beatmap, mock.Object), Is.Empty); Assert.That(check.Run(context), Is.Empty);
} }
[Test] [Test]
public void TestAcceptable() public void TestAcceptable()
{ {
var mock = getMockWorkingBeatmap(new Texture(1920, 1080)); var context = getContext(new Texture(1920, 1080));
Assert.That(check.Run(beatmap, mock.Object), Is.Empty); Assert.That(check.Run(context), Is.Empty);
} }
[Test] [Test]
public void TestTooHighResolution() public void TestTooHighResolution()
{ {
var mock = getMockWorkingBeatmap(new Texture(3840, 2160)); var context = getContext(new Texture(3840, 2160));
var issues = check.Run(beatmap, mock.Object).ToList(); var issues = check.Run(context).ToList();
Assert.That(issues, Has.Count.EqualTo(1)); Assert.That(issues, Has.Count.EqualTo(1));
Assert.That(issues.Single().Template is CheckBackgroundQuality.IssueTemplateTooHighResolution); Assert.That(issues.Single().Template is CheckBackgroundQuality.IssueTemplateTooHighResolution);
@ -80,9 +81,9 @@ namespace osu.Game.Tests.Editing.Checks
[Test] [Test]
public void TestLowResolution() public void TestLowResolution()
{ {
var mock = getMockWorkingBeatmap(new Texture(640, 480)); var context = getContext(new Texture(640, 480));
var issues = check.Run(beatmap, mock.Object).ToList(); var issues = check.Run(context).ToList();
Assert.That(issues, Has.Count.EqualTo(1)); Assert.That(issues, Has.Count.EqualTo(1));
Assert.That(issues.Single().Template is CheckBackgroundQuality.IssueTemplateLowResolution); Assert.That(issues.Single().Template is CheckBackgroundQuality.IssueTemplateLowResolution);
@ -91,9 +92,9 @@ namespace osu.Game.Tests.Editing.Checks
[Test] [Test]
public void TestTooLowResolution() public void TestTooLowResolution()
{ {
var mock = getMockWorkingBeatmap(new Texture(100, 100)); var context = getContext(new Texture(100, 100));
var issues = check.Run(beatmap, mock.Object).ToList(); var issues = check.Run(context).ToList();
Assert.That(issues, Has.Count.EqualTo(1)); Assert.That(issues, Has.Count.EqualTo(1));
Assert.That(issues.Single().Template is CheckBackgroundQuality.IssueTemplateTooLowResolution); Assert.That(issues.Single().Template is CheckBackgroundQuality.IssueTemplateTooLowResolution);
@ -102,14 +103,19 @@ namespace osu.Game.Tests.Editing.Checks
[Test] [Test]
public void TestTooUncompressed() public void TestTooUncompressed()
{ {
var mock = getMockWorkingBeatmap(new Texture(1920, 1080), new byte[1024 * 1024 * 3]); var context = getContext(new Texture(1920, 1080), new byte[1024 * 1024 * 3]);
var issues = check.Run(beatmap, mock.Object).ToList(); var issues = check.Run(context).ToList();
Assert.That(issues, Has.Count.EqualTo(1)); Assert.That(issues, Has.Count.EqualTo(1));
Assert.That(issues.Single().Template is CheckBackgroundQuality.IssueTemplateTooUncompressed); Assert.That(issues.Single().Template is CheckBackgroundQuality.IssueTemplateTooUncompressed);
} }
private BeatmapVerifierContext getContext(Texture background, [CanBeNull] byte[] fileBytes = null)
{
return new BeatmapVerifierContext(beatmap, getMockWorkingBeatmap(background, fileBytes).Object);
}
/// <summary> /// <summary>
/// Returns the mock of the working beatmap with the given background and filesize. /// Returns the mock of the working beatmap with the given background and filesize.
/// </summary> /// </summary>

View File

@ -6,11 +6,13 @@ using System.Linq;
using Moq; using Moq;
using NUnit.Framework; using NUnit.Framework;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Rulesets.Edit;
using osu.Game.Rulesets.Edit.Checks; using osu.Game.Rulesets.Edit.Checks;
using osu.Game.Rulesets.Mania.Objects; using osu.Game.Rulesets.Mania.Objects;
using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Objects.Types;
using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Osu.Objects;
using osu.Game.Tests.Beatmaps;
namespace osu.Game.Tests.Editing.Checks namespace osu.Game.Tests.Editing.Checks
{ {
@ -105,7 +107,7 @@ namespace osu.Game.Tests.Editing.Checks
new HitCircle { StartTime = 300 } new HitCircle { StartTime = 300 }
}; };
var issues = check.Run(getPlayableBeatmap(hitobjects), null).ToList(); var issues = check.Run(getContext(hitobjects)).ToList();
Assert.That(issues, Has.Count.EqualTo(3)); Assert.That(issues, Has.Count.EqualTo(3));
Assert.That(issues.Where(issue => issue.Template is CheckConcurrentObjects.IssueTemplateConcurrentDifferent).ToList(), Has.Count.EqualTo(2)); Assert.That(issues.Where(issue => issue.Template is CheckConcurrentObjects.IssueTemplateConcurrentDifferent).ToList(), Has.Count.EqualTo(2));
@ -164,12 +166,12 @@ namespace osu.Game.Tests.Editing.Checks
private void assertOk(List<HitObject> hitobjects) private void assertOk(List<HitObject> hitobjects)
{ {
Assert.That(check.Run(getPlayableBeatmap(hitobjects), null), Is.Empty); Assert.That(check.Run(getContext(hitobjects)), Is.Empty);
} }
private void assertConcurrentSame(List<HitObject> hitobjects, int count = 1) private void assertConcurrentSame(List<HitObject> hitobjects, int count = 1)
{ {
var issues = check.Run(getPlayableBeatmap(hitobjects), null).ToList(); var issues = check.Run(getContext(hitobjects)).ToList();
Assert.That(issues, Has.Count.EqualTo(count)); Assert.That(issues, Has.Count.EqualTo(count));
Assert.That(issues.All(issue => issue.Template is CheckConcurrentObjects.IssueTemplateConcurrentSame)); Assert.That(issues.All(issue => issue.Template is CheckConcurrentObjects.IssueTemplateConcurrentSame));
@ -177,18 +179,16 @@ namespace osu.Game.Tests.Editing.Checks
private void assertConcurrentDifferent(List<HitObject> hitobjects, int count = 1) private void assertConcurrentDifferent(List<HitObject> hitobjects, int count = 1)
{ {
var issues = check.Run(getPlayableBeatmap(hitobjects), null).ToList(); var issues = check.Run(getContext(hitobjects)).ToList();
Assert.That(issues, Has.Count.EqualTo(count)); Assert.That(issues, Has.Count.EqualTo(count));
Assert.That(issues.All(issue => issue.Template is CheckConcurrentObjects.IssueTemplateConcurrentDifferent)); Assert.That(issues.All(issue => issue.Template is CheckConcurrentObjects.IssueTemplateConcurrentDifferent));
} }
private IBeatmap getPlayableBeatmap(List<HitObject> hitobjects) private BeatmapVerifierContext getContext(List<HitObject> hitobjects)
{ {
return new Beatmap<HitObject> var beatmap = new Beatmap<HitObject> { HitObjects = hitobjects };
{ return new BeatmapVerifierContext(beatmap, new TestWorkingBeatmap(beatmap));
HitObjects = hitobjects
};
} }
} }
} }

View File

@ -6,6 +6,7 @@ using System.Linq;
using NUnit.Framework; using NUnit.Framework;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.IO; using osu.Game.IO;
using osu.Game.Rulesets.Edit;
using osu.Game.Rulesets.Edit.Checks; using osu.Game.Rulesets.Edit.Checks;
using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects;
using osu.Game.Tests.Beatmaps; using osu.Game.Tests.Beatmaps;
@ -45,7 +46,8 @@ namespace osu.Game.Tests.Editing.Checks
[Test] [Test]
public void TestBackgroundSetAndInFiles() public void TestBackgroundSetAndInFiles()
{ {
Assert.That(check.Run(beatmap, new TestWorkingBeatmap(beatmap)), Is.Empty); var context = new BeatmapVerifierContext(beatmap, new TestWorkingBeatmap(beatmap));
Assert.That(check.Run(context), Is.Empty);
} }
[Test] [Test]
@ -53,7 +55,8 @@ namespace osu.Game.Tests.Editing.Checks
{ {
beatmap.BeatmapInfo.BeatmapSet.Files.Clear(); beatmap.BeatmapInfo.BeatmapSet.Files.Clear();
var issues = check.Run(beatmap, new TestWorkingBeatmap(beatmap)).ToList(); var context = new BeatmapVerifierContext(beatmap, new TestWorkingBeatmap(beatmap));
var issues = check.Run(context).ToList();
Assert.That(issues, Has.Count.EqualTo(1)); Assert.That(issues, Has.Count.EqualTo(1));
Assert.That(issues.Single().Template is CheckFilePresence.IssueTemplateDoesNotExist); Assert.That(issues.Single().Template is CheckFilePresence.IssueTemplateDoesNotExist);
@ -64,7 +67,8 @@ namespace osu.Game.Tests.Editing.Checks
{ {
beatmap.Metadata.BackgroundFile = null; beatmap.Metadata.BackgroundFile = null;
var issues = check.Run(beatmap, new TestWorkingBeatmap(beatmap)).ToList(); var context = new BeatmapVerifierContext(beatmap, new TestWorkingBeatmap(beatmap));
var issues = check.Run(context).ToList();
Assert.That(issues, Has.Count.EqualTo(1)); Assert.That(issues, Has.Count.EqualTo(1));
Assert.That(issues.Single().Template is CheckFilePresence.IssueTemplateNoneSet); Assert.That(issues.Single().Template is CheckFilePresence.IssueTemplateNoneSet);

View File

@ -7,10 +7,12 @@ using Moq;
using NUnit.Framework; using NUnit.Framework;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Beatmaps.ControlPoints; using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Rulesets.Edit;
using osu.Game.Rulesets.Edit.Checks; using osu.Game.Rulesets.Edit.Checks;
using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Objects.Types;
using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Osu.Objects;
using osu.Game.Tests.Beatmaps;
namespace osu.Game.Tests.Editing.Checks namespace osu.Game.Tests.Editing.Checks
{ {
@ -100,12 +102,12 @@ namespace osu.Game.Tests.Editing.Checks
}, count: 2); }, count: 2);
// Start and end are 2 ms and 1.25 ms off respectively, hence two different issues in one object. // Start and end are 2 ms and 1.25 ms off respectively, hence two different issues in one object.
var hitobjects = new List<HitObject> var hitObjects = new List<HitObject>
{ {
getSliderMock(startTime: 98, endTime: 398.75d).Object getSliderMock(startTime: 98, endTime: 398.75d).Object
}; };
var issues = check.Run(getPlayableBeatmap(hitobjects), null).ToList(); var issues = check.Run(getContext(hitObjects)).ToList();
Assert.That(issues, Has.Count.EqualTo(2)); Assert.That(issues, Has.Count.EqualTo(2));
Assert.That(issues.Any(issue => issue.Template is CheckUnsnappedObjects.IssueTemplateSmallUnsnap)); Assert.That(issues.Any(issue => issue.Template is CheckUnsnappedObjects.IssueTemplateSmallUnsnap));
@ -122,34 +124,36 @@ namespace osu.Game.Tests.Editing.Checks
return mockSlider; return mockSlider;
} }
private void assertOk(List<HitObject> hitobjects) private void assertOk(List<HitObject> hitObjects)
{ {
Assert.That(check.Run(getPlayableBeatmap(hitobjects), null), Is.Empty); Assert.That(check.Run(getContext(hitObjects)), Is.Empty);
} }
private void assert1Ms(List<HitObject> hitobjects, int count = 1) private void assert1Ms(List<HitObject> hitObjects, int count = 1)
{ {
var issues = check.Run(getPlayableBeatmap(hitobjects), null).ToList(); var issues = check.Run(getContext(hitObjects)).ToList();
Assert.That(issues, Has.Count.EqualTo(count)); Assert.That(issues, Has.Count.EqualTo(count));
Assert.That(issues.All(issue => issue.Template is CheckUnsnappedObjects.IssueTemplateSmallUnsnap)); Assert.That(issues.All(issue => issue.Template is CheckUnsnappedObjects.IssueTemplateSmallUnsnap));
} }
private void assert2Ms(List<HitObject> hitobjects, int count = 1) private void assert2Ms(List<HitObject> hitObjects, int count = 1)
{ {
var issues = check.Run(getPlayableBeatmap(hitobjects), null).ToList(); var issues = check.Run(getContext(hitObjects)).ToList();
Assert.That(issues, Has.Count.EqualTo(count)); Assert.That(issues, Has.Count.EqualTo(count));
Assert.That(issues.All(issue => issue.Template is CheckUnsnappedObjects.IssueTemplateLargeUnsnap)); Assert.That(issues.All(issue => issue.Template is CheckUnsnappedObjects.IssueTemplateLargeUnsnap));
} }
private IBeatmap getPlayableBeatmap(List<HitObject> hitobjects) private BeatmapVerifierContext getContext(List<HitObject> hitObjects)
{ {
return new Beatmap<HitObject> var beatmap = new Beatmap<HitObject>
{ {
ControlPointInfo = cpi, ControlPointInfo = cpi,
HitObjects = hitobjects HitObjects = hitObjects
}; };
return new BeatmapVerifierContext(beatmap, new TestWorkingBeatmap(beatmap));
} }
} }
} }

View File

@ -3,7 +3,6 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Edit.Checks; using osu.Game.Rulesets.Edit.Checks;
using osu.Game.Rulesets.Edit.Checks.Components; using osu.Game.Rulesets.Edit.Checks.Components;
@ -29,9 +28,9 @@ namespace osu.Game.Rulesets.Edit
new CheckConcurrentObjects() new CheckConcurrentObjects()
}; };
public IEnumerable<Issue> Run(IBeatmap playableBeatmap, WorkingBeatmap workingBeatmap) public IEnumerable<Issue> Run(BeatmapVerifierContext context)
{ {
return checks.SelectMany(check => check.Run(playableBeatmap, workingBeatmap)); return checks.SelectMany(check => check.Run(context));
} }
} }
} }

View File

@ -0,0 +1,38 @@
// 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 osu.Game.Beatmaps;
#nullable enable
namespace osu.Game.Rulesets.Edit
{
/// <summary>
/// Represents the context provided by the beatmap verifier to the checks it runs.
/// Contains information about what is being checked and how it should be checked.
/// </summary>
public class BeatmapVerifierContext
{
/// <summary>
/// The playable beatmap instance of the current beatmap.
/// </summary>
public readonly IBeatmap Beatmap;
/// <summary>
/// The working beatmap instance of the current beatmap.
/// </summary>
public readonly IWorkingBeatmap WorkingBeatmap;
/// <summary>
/// The difficulty level which the current beatmap is considered to be.
/// </summary>
public DifficultyRating InterpretedDifficulty;
public BeatmapVerifierContext(IBeatmap beatmap, IWorkingBeatmap workingBeatmap, DifficultyRating difficultyRating = DifficultyRating.ExpertPlus)
{
Beatmap = beatmap;
WorkingBeatmap = workingBeatmap;
InterpretedDifficulty = difficultyRating;
}
}
}

View File

@ -10,6 +10,6 @@ namespace osu.Game.Rulesets.Edit.Checks
{ {
protected override CheckCategory Category => CheckCategory.Audio; protected override CheckCategory Category => CheckCategory.Audio;
protected override string TypeOfFile => "audio"; protected override string TypeOfFile => "audio";
protected override string GetFilename(IBeatmap playableBeatmap) => playableBeatmap.Metadata?.AudioFile; protected override string GetFilename(IBeatmap beatmap) => beatmap.Metadata?.AudioFile;
} }
} }

View File

@ -2,7 +2,6 @@
// See the LICENCE file in the repository root for full licence text. // See the LICENCE file in the repository root for full licence text.
using System.Collections.Generic; using System.Collections.Generic;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Edit.Checks.Components; using osu.Game.Rulesets.Edit.Checks.Components;
namespace osu.Game.Rulesets.Edit.Checks namespace osu.Game.Rulesets.Edit.Checks
@ -26,13 +25,13 @@ namespace osu.Game.Rulesets.Edit.Checks
new IssueTemplateNoBitrate(this) new IssueTemplateNoBitrate(this)
}; };
public IEnumerable<Issue> Run(IBeatmap playableBeatmap, IWorkingBeatmap workingBeatmap) public IEnumerable<Issue> Run(BeatmapVerifierContext context)
{ {
var audioFile = playableBeatmap.Metadata?.AudioFile; var audioFile = context.Beatmap.Metadata?.AudioFile;
if (audioFile == null) if (audioFile == null)
yield break; yield break;
var track = workingBeatmap.Track; var track = context.WorkingBeatmap.Track;
if (track?.Bitrate == null || track.Bitrate.Value == 0) if (track?.Bitrate == null || track.Bitrate.Value == 0)
yield return new IssueTemplateNoBitrate(this).Create(); yield return new IssueTemplateNoBitrate(this).Create();

View File

@ -10,6 +10,6 @@ namespace osu.Game.Rulesets.Edit.Checks
{ {
protected override CheckCategory Category => CheckCategory.Resources; protected override CheckCategory Category => CheckCategory.Resources;
protected override string TypeOfFile => "background"; protected override string TypeOfFile => "background";
protected override string GetFilename(IBeatmap playableBeatmap) => playableBeatmap.Metadata?.BackgroundFile; protected override string GetFilename(IBeatmap beatmap) => beatmap.Metadata?.BackgroundFile;
} }
} }

View File

@ -2,7 +2,6 @@
// See the LICENCE file in the repository root for full licence text. // See the LICENCE file in the repository root for full licence text.
using System.Collections.Generic; using System.Collections.Generic;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Edit.Checks.Components; using osu.Game.Rulesets.Edit.Checks.Components;
namespace osu.Game.Rulesets.Edit.Checks namespace osu.Game.Rulesets.Edit.Checks
@ -30,13 +29,13 @@ namespace osu.Game.Rulesets.Edit.Checks
new IssueTemplateTooUncompressed(this) new IssueTemplateTooUncompressed(this)
}; };
public IEnumerable<Issue> Run(IBeatmap playableBeatmap, IWorkingBeatmap workingBeatmap) public IEnumerable<Issue> Run(BeatmapVerifierContext context)
{ {
var backgroundFile = playableBeatmap.Metadata?.BackgroundFile; var backgroundFile = context.Beatmap.Metadata?.BackgroundFile;
if (backgroundFile == null) if (backgroundFile == null)
yield break; yield break;
var texture = workingBeatmap.Background; var texture = context.WorkingBeatmap.Background;
if (texture == null) if (texture == null)
yield break; yield break;
@ -48,8 +47,8 @@ namespace osu.Game.Rulesets.Edit.Checks
else if (texture.Width < low_width || texture.Height < low_height) else if (texture.Width < low_width || texture.Height < low_height)
yield return new IssueTemplateLowResolution(this).Create(texture.Width, texture.Height); yield return new IssueTemplateLowResolution(this).Create(texture.Width, texture.Height);
string storagePath = playableBeatmap.BeatmapInfo.BeatmapSet.GetPathForFile(backgroundFile); string storagePath = context.Beatmap.BeatmapInfo.BeatmapSet.GetPathForFile(backgroundFile);
double filesizeMb = workingBeatmap.GetStream(storagePath).Length / (1024d * 1024d); double filesizeMb = context.WorkingBeatmap.GetStream(storagePath).Length / (1024d * 1024d);
if (filesizeMb > max_filesize_mb) if (filesizeMb > max_filesize_mb)
yield return new IssueTemplateTooUncompressed(this).Create(filesizeMb); yield return new IssueTemplateTooUncompressed(this).Create(filesizeMb);

View File

@ -2,7 +2,6 @@
// See the LICENCE file in the repository root for full licence text. // See the LICENCE file in the repository root for full licence text.
using System.Collections.Generic; using System.Collections.Generic;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Edit.Checks.Components; using osu.Game.Rulesets.Edit.Checks.Components;
using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Objects.Types;
@ -22,15 +21,17 @@ namespace osu.Game.Rulesets.Edit.Checks
new IssueTemplateConcurrentDifferent(this) new IssueTemplateConcurrentDifferent(this)
}; };
public IEnumerable<Issue> Run(IBeatmap playableBeatmap, IWorkingBeatmap workingBeatmap) public IEnumerable<Issue> Run(BeatmapVerifierContext context)
{ {
for (int i = 0; i < playableBeatmap.HitObjects.Count - 1; ++i) var hitObjects = context.Beatmap.HitObjects;
{
var hitobject = playableBeatmap.HitObjects[i];
for (int j = i + 1; j < playableBeatmap.HitObjects.Count; ++j) for (int i = 0; i < hitObjects.Count - 1; ++i)
{
var hitobject = hitObjects[i];
for (int j = i + 1; j < hitObjects.Count; ++j)
{ {
var nextHitobject = playableBeatmap.HitObjects[j]; var nextHitobject = hitObjects[j];
// Accounts for rulesets with hitobjects separated by columns, such as Mania. // Accounts for rulesets with hitobjects separated by columns, such as Mania.
// In these cases we only care about concurrent objects within the same column. // In these cases we only care about concurrent objects within the same column.

View File

@ -11,7 +11,7 @@ namespace osu.Game.Rulesets.Edit.Checks
{ {
protected abstract CheckCategory Category { get; } protected abstract CheckCategory Category { get; }
protected abstract string TypeOfFile { get; } protected abstract string TypeOfFile { get; }
protected abstract string GetFilename(IBeatmap playableBeatmap); protected abstract string GetFilename(IBeatmap beatmap);
public CheckMetadata Metadata => new CheckMetadata(Category, $"Missing {TypeOfFile}"); public CheckMetadata Metadata => new CheckMetadata(Category, $"Missing {TypeOfFile}");
@ -21,9 +21,9 @@ namespace osu.Game.Rulesets.Edit.Checks
new IssueTemplateDoesNotExist(this) new IssueTemplateDoesNotExist(this)
}; };
public IEnumerable<Issue> Run(IBeatmap playableBeatmap, IWorkingBeatmap workingBeatmap) public IEnumerable<Issue> Run(BeatmapVerifierContext context)
{ {
var filename = GetFilename(playableBeatmap); var filename = GetFilename(context.Beatmap);
if (filename == null) if (filename == null)
{ {
@ -33,7 +33,7 @@ namespace osu.Game.Rulesets.Edit.Checks
} }
// If the file is set, also make sure it still exists. // If the file is set, also make sure it still exists.
var storagePath = playableBeatmap.BeatmapInfo.BeatmapSet.GetPathForFile(filename); var storagePath = context.Beatmap.BeatmapInfo.BeatmapSet.GetPathForFile(filename);
if (storagePath != null) if (storagePath != null)
yield break; yield break;

View File

@ -3,7 +3,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Edit.Checks.Components; using osu.Game.Rulesets.Edit.Checks.Components;
using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Objects.Types;
@ -22,11 +21,11 @@ namespace osu.Game.Rulesets.Edit.Checks
new IssueTemplateSmallUnsnap(this) new IssueTemplateSmallUnsnap(this)
}; };
public IEnumerable<Issue> Run(IBeatmap playableBeatmap, IWorkingBeatmap workingBeatmap) public IEnumerable<Issue> Run(BeatmapVerifierContext context)
{ {
var controlPointInfo = playableBeatmap.ControlPointInfo; var controlPointInfo = context.Beatmap.ControlPointInfo;
foreach (var hitobject in playableBeatmap.HitObjects) foreach (var hitobject in context.Beatmap.HitObjects)
{ {
double startUnsnap = hitobject.StartTime - controlPointInfo.GetClosestSnappedTime(hitobject.StartTime); double startUnsnap = hitobject.StartTime - controlPointInfo.GetClosestSnappedTime(hitobject.StartTime);
string startPostfix = hitobject is IHasDuration ? "start" : ""; string startPostfix = hitobject is IHasDuration ? "start" : "";

View File

@ -2,7 +2,6 @@
// See the LICENCE file in the repository root for full licence text. // See the LICENCE file in the repository root for full licence text.
using System.Collections.Generic; using System.Collections.Generic;
using osu.Game.Beatmaps;
namespace osu.Game.Rulesets.Edit.Checks.Components namespace osu.Game.Rulesets.Edit.Checks.Components
{ {
@ -24,8 +23,7 @@ namespace osu.Game.Rulesets.Edit.Checks.Components
/// <summary> /// <summary>
/// Runs this check and returns any issues detected for the provided beatmap. /// Runs this check and returns any issues detected for the provided beatmap.
/// </summary> /// </summary>
/// <param name="playableBeatmap">The playable beatmap of the beatmap to run the check on.</param> /// <param name="context">The beatmap verifier context associated with the beatmap.</param>
/// <param name="workingBeatmap">The working beatmap of the beatmap to run the check on.</param> public IEnumerable<Issue> Run(BeatmapVerifierContext context);
public IEnumerable<Issue> Run(IBeatmap playableBeatmap, IWorkingBeatmap workingBeatmap);
} }
} }

View File

@ -2,7 +2,6 @@
// See the LICENCE file in the repository root for full licence text. // See the LICENCE file in the repository root for full licence text.
using System.Collections.Generic; using System.Collections.Generic;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Edit.Checks.Components; using osu.Game.Rulesets.Edit.Checks.Components;
namespace osu.Game.Rulesets.Edit namespace osu.Game.Rulesets.Edit
@ -12,6 +11,6 @@ namespace osu.Game.Rulesets.Edit
/// </summary> /// </summary>
public interface IBeatmapVerifier public interface IBeatmapVerifier
{ {
public IEnumerable<Issue> Run(IBeatmap playableBeatmap, WorkingBeatmap workingBeatmap); public IEnumerable<Issue> Run(BeatmapVerifierContext context);
} }
} }

View File

@ -37,6 +37,7 @@ namespace osu.Game.Screens.Edit.Verify
private IBeatmapVerifier rulesetVerifier; private IBeatmapVerifier rulesetVerifier;
private BeatmapVerifier generalVerifier; private BeatmapVerifier generalVerifier;
private BeatmapVerifierContext context;
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(OverlayColourProvider colours) private void load(OverlayColourProvider colours)
@ -44,6 +45,9 @@ namespace osu.Game.Screens.Edit.Verify
generalVerifier = new BeatmapVerifier(); generalVerifier = new BeatmapVerifier();
rulesetVerifier = beatmap.BeatmapInfo.Ruleset?.CreateInstance()?.CreateBeatmapVerifier(); rulesetVerifier = beatmap.BeatmapInfo.Ruleset?.CreateInstance()?.CreateBeatmapVerifier();
context = new BeatmapVerifierContext(beatmap, workingBeatmap.Value, verify.InterpretedDifficulty.Value);
verify.InterpretedDifficulty.BindValueChanged(difficulty => context.InterpretedDifficulty = difficulty.NewValue);
RelativeSizeAxes = Axes.Both; RelativeSizeAxes = Axes.Both;
InternalChildren = new Drawable[] InternalChildren = new Drawable[]
@ -91,10 +95,10 @@ namespace osu.Game.Screens.Edit.Verify
private void refresh() private void refresh()
{ {
var issues = generalVerifier.Run(beatmap, workingBeatmap.Value); var issues = generalVerifier.Run(context);
if (rulesetVerifier != null) if (rulesetVerifier != null)
issues = issues.Concat(rulesetVerifier.Run(beatmap, workingBeatmap.Value)); issues = issues.Concat(rulesetVerifier.Run(context));
issues = filter(issues); issues = filter(issues);