-
Notifications
You must be signed in to change notification settings - Fork 15
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1806 from andy840119/implement-page-auto-generator
Implement page auto generator
- Loading branch information
Showing
19 changed files
with
456 additions
and
12 deletions.
There are no files selected for viewing
70 changes: 70 additions & 0 deletions
70
osu.Game.Rulesets.Karaoke.Tests/Editor/Generator/Beatmaps/BaseBeatmapDetectorTest.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
// Copyright (c) andy840119 <[email protected]>. Licensed under the GPL Licence. | ||
// See the LICENCE file in the repository root for full licence text. | ||
|
||
using System; | ||
using NUnit.Framework; | ||
using osu.Game.Rulesets.Karaoke.Beatmaps; | ||
using osu.Game.Rulesets.Karaoke.Edit.Generator.Beatmaps; | ||
|
||
namespace osu.Game.Rulesets.Karaoke.Tests.Editor.Generator.Beatmaps | ||
{ | ||
public abstract class BaseBeatmapDetectorTest<TDetector, TObject, TConfig> | ||
where TDetector : class, IBeatmapPropertyDetector<TObject> where TConfig : new() | ||
{ | ||
protected static TConfig GeneratorConfig(params string?[] properties) | ||
{ | ||
var config = new TConfig(); | ||
|
||
foreach (string? propertyName in properties) | ||
{ | ||
if (propertyName == null) | ||
continue; | ||
|
||
var theMethod = config.GetType().GetProperty(propertyName); | ||
if (theMethod == null) | ||
throw new MissingMethodException("Config is not exist."); | ||
|
||
theMethod.SetValue(config, true); | ||
} | ||
|
||
return config; | ||
} | ||
|
||
protected static TDetector GenerateDetector(TConfig config) | ||
{ | ||
if (Activator.CreateInstance(typeof(TDetector), config) is not TDetector detector) | ||
throw new ArgumentNullException(nameof(detector)); | ||
|
||
return detector; | ||
} | ||
|
||
protected static void CheckCanDetect(KaraokeBeatmap beatmap, bool canDetect, TConfig config) | ||
{ | ||
var detector = GenerateDetector(config); | ||
|
||
CheckCanDetect(beatmap, canDetect, detector); | ||
} | ||
|
||
protected static void CheckCanDetect(KaraokeBeatmap beatmap, bool canDetect, TDetector detector) | ||
{ | ||
bool actual = detector.CanDetect(beatmap); | ||
Assert.AreEqual(canDetect, actual); | ||
} | ||
|
||
protected void CheckDetectResult(KaraokeBeatmap beatmap, TObject expected, TConfig config) | ||
{ | ||
var detector = GenerateDetector(config); | ||
|
||
CheckDetectResult(beatmap, expected, detector); | ||
} | ||
|
||
protected void CheckDetectResult(KaraokeBeatmap beatmap, TObject expected, TDetector detector) | ||
{ | ||
// create time tag and actually time tag. | ||
var actual = detector.Detect(beatmap); | ||
AssertEqual(expected, actual); | ||
} | ||
|
||
protected abstract void AssertEqual(TObject expected, TObject actual); | ||
} | ||
} |
59 changes: 59 additions & 0 deletions
59
osu.Game.Rulesets.Karaoke.Tests/Editor/Generator/Beatmaps/BaseBeatmapGeneratorTest.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
// Copyright (c) andy840119 <[email protected]>. Licensed under the GPL Licence. | ||
// See the LICENCE file in the repository root for full licence text. | ||
|
||
using System; | ||
using NUnit.Framework; | ||
using osu.Game.Rulesets.Karaoke.Beatmaps; | ||
using osu.Game.Rulesets.Karaoke.Edit.Generator; | ||
using osu.Game.Rulesets.Karaoke.Edit.Generator.Beatmaps; | ||
|
||
namespace osu.Game.Rulesets.Karaoke.Tests.Editor.Generator.Beatmaps | ||
{ | ||
public abstract class BaseBeatmapGeneratorTest<TGenerator, TObject, TConfig> | ||
where TGenerator : class, IBeatmapPropertyGenerator<TObject> where TConfig : IHasConfig<TConfig>, new() | ||
{ | ||
protected static TConfig GeneratorConfig(Action<TConfig>? action = null) | ||
{ | ||
var config = new TConfig().CreateDefaultConfig(); | ||
action?.Invoke(config); | ||
return config; | ||
} | ||
|
||
protected static TGenerator GenerateGenerator(TConfig config) | ||
{ | ||
if (Activator.CreateInstance(typeof(TGenerator), config) is not TGenerator generator) | ||
throw new ArgumentNullException(nameof(generator)); | ||
|
||
return generator; | ||
} | ||
|
||
protected static void CheckCanGenerate(KaraokeBeatmap beatmap, bool canGenerate, TConfig config) | ||
{ | ||
var generator = GenerateGenerator(config); | ||
|
||
CheckCanGenerate(beatmap, canGenerate, generator); | ||
} | ||
|
||
protected static void CheckCanGenerate(KaraokeBeatmap beatmap, bool canGenerate, TGenerator generator) | ||
{ | ||
bool actual = generator.CanGenerate(beatmap); | ||
Assert.AreEqual(canGenerate, actual); | ||
} | ||
|
||
protected void CheckGenerateResult(KaraokeBeatmap beatmap, TObject expected, TConfig config) | ||
{ | ||
var generator = GenerateGenerator(config); | ||
|
||
CheckGenerateResult(beatmap, expected, generator); | ||
} | ||
|
||
protected void CheckGenerateResult(KaraokeBeatmap beatmap, TObject expected, TGenerator generator) | ||
{ | ||
// create time tag and actually time tag. | ||
var actual = generator.Generate(beatmap); | ||
AssertEqual(expected, actual); | ||
} | ||
|
||
protected abstract void AssertEqual(TObject expected, TObject actual); | ||
} | ||
} |
114 changes: 114 additions & 0 deletions
114
osu.Game.Rulesets.Karaoke.Tests/Editor/Generator/Beatmaps/Pages/PageGeneratorTest.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
// Copyright (c) andy840119 <[email protected]>. Licensed under the GPL 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.Game.Rulesets.Karaoke.Beatmaps; | ||
using osu.Game.Rulesets.Karaoke.Beatmaps.Metadatas; | ||
using osu.Game.Rulesets.Karaoke.Edit.Checks; | ||
using osu.Game.Rulesets.Karaoke.Edit.Generator.Beatmaps.Pages; | ||
using osu.Game.Rulesets.Karaoke.Objects; | ||
using osu.Game.Rulesets.Karaoke.Tests.Helper; | ||
|
||
namespace osu.Game.Rulesets.Karaoke.Tests.Editor.Generator.Beatmaps.Pages; | ||
|
||
[TestFixture] | ||
public class PageGeneratorTest : BaseBeatmapGeneratorTest<PageGenerator, Page[], PageGeneratorConfig> | ||
{ | ||
private const double min_interval = CheckBeatmapPageInfo.MIN_INTERVAL; | ||
private const double max_interval = CheckBeatmapPageInfo.MAX_INTERVAL; | ||
|
||
[TestCase(new[] { "[1000,3000]:karaoke" }, true)] | ||
[TestCase(new[] { "[1000,3000]:karaoke", "[4000,6000]:karaoke" }, true)] | ||
[TestCase(new[] { "[1000,3000]:karaoke", "[1000,3000]:karaoke" }, true)] // should still runnable even if lyric is overlapping. | ||
[TestCase(new string[] { }, false)] | ||
public void TestCanGenerate(string[] lyrics, bool canGenerate) | ||
{ | ||
var config = GeneratorConfig(); | ||
var beatmap = new KaraokeBeatmap | ||
{ | ||
HitObjects = TestCaseTagHelper.ParseLyrics(lyrics).OfType<KaraokeHitObject>().ToList(), | ||
}; | ||
|
||
CheckCanGenerate(beatmap, canGenerate, config); | ||
} | ||
|
||
[Test] | ||
public void TestGenerateWithZeroLyric() | ||
{ | ||
var config = GeneratorConfig(); | ||
var beatmap = new KaraokeBeatmap | ||
{ | ||
HitObjects = new List<KaraokeHitObject>() | ||
}; | ||
|
||
var expectedPages = Array.Empty<Page>(); | ||
|
||
CheckGenerateResult(beatmap, expectedPages, config); | ||
} | ||
|
||
[TestCase("[1000,3000]:karaoke", new double[] { 1000, 3000 })] | ||
[TestCase("[1000,23000]:karaoke", new[] { 1000, 1000 + max_interval, 1000 + max_interval * 2, 23000 })] | ||
public void TestGenerateWithSingleLyric(string lyric, double[] expectedTimes) | ||
{ | ||
var config = GeneratorConfig(); | ||
var beatmap = new KaraokeBeatmap | ||
{ | ||
HitObjects = new List<KaraokeHitObject> | ||
{ | ||
TestCaseTagHelper.ParseLyric(lyric) | ||
} | ||
}; | ||
|
||
var expectedPages = expectedTimes.Select(x => new Page | ||
{ | ||
Time = x | ||
}).ToArray(); | ||
|
||
CheckGenerateResult(beatmap, expectedPages, config); | ||
} | ||
|
||
[TestCase("[1000,4000]:karaoke", "[4000,7000]:karaoke", new double[] { 1000, 4000, 7000 })] | ||
[TestCase("[1000,4000]:karaoke", "[5000,8000]:karaoke", new double[] { 1000, 4500, 8000 })] | ||
[TestCase("[1000,3000]:karaoke", "[1000,3000]:karaoke", new double[] { 1000, 3000 })] //should deal with overlapping lyric. | ||
[TestCase("[1000,23000]:karaoke", "[1000,23000]:karaoke", new[] { 1000, 1000 + max_interval, 1000 + max_interval * 2, 23000 })] //should deal with overlapping lyric with long time. | ||
[TestCase("[1000,23000]:karaoke", "[3000,4000]:karaoke", new[] { 1000, 1000 + max_interval, 1000 + max_interval * 2, 23000 })] // should ignore second lyric. | ||
public void TestGenerateWithTwoLyrics(string firstLyric, string secondLyric, double[] expectedTimes) | ||
{ | ||
var config = GeneratorConfig(); | ||
var beatmap = new KaraokeBeatmap | ||
{ | ||
HitObjects = new List<KaraokeHitObject> | ||
{ | ||
TestCaseTagHelper.ParseLyric(firstLyric), | ||
TestCaseTagHelper.ParseLyric(secondLyric) | ||
} | ||
}; | ||
|
||
var expectedPages = expectedTimes.Select(x => new Page | ||
{ | ||
Time = x | ||
}).ToArray(); | ||
|
||
CheckGenerateResult(beatmap, expectedPages, config); | ||
} | ||
|
||
[Ignore("Waiting for implementation.")] | ||
public void TestGenerateWithSingleLyricWithPage() | ||
{ | ||
} | ||
|
||
[Ignore("Waiting for implementation.")] | ||
public void TestGenerateWithTwoLyricsWithPage() | ||
{ | ||
} | ||
|
||
protected override void AssertEqual(Page[] expected, Page[] actual) | ||
{ | ||
string expectedTimes = string.Join(",", expected.Select(x => x.Time)); | ||
string actualTimes = string.Join(",", actual.Select(x => x.Time)); | ||
Assert.AreEqual(expectedTimes, actualTimes); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
36 changes: 36 additions & 0 deletions
36
osu.Game.Rulesets.Karaoke/Edit/Generator/Beatmaps/IBeatmapPropertyDetector.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
// Copyright (c) andy840119 <[email protected]>. Licensed under the GPL Licence. | ||
// See the LICENCE file in the repository root for full licence text. | ||
|
||
using osu.Framework.Localisation; | ||
using osu.Game.Rulesets.Karaoke.Beatmaps; | ||
|
||
namespace osu.Game.Rulesets.Karaoke.Edit.Generator.Beatmaps | ||
{ | ||
/// <summary> | ||
/// Base interface of the detector. | ||
/// </summary> | ||
/// <typeparam name="T"></typeparam> | ||
public interface IBeatmapPropertyDetector<out T> | ||
{ | ||
/// <summary> | ||
/// Determined if detect property from <see cref="KaraokeBeatmap"/> is supported. | ||
/// </summary> | ||
/// <param name="beatmap"></param> | ||
/// <returns></returns> | ||
bool CanDetect(KaraokeBeatmap beatmap) => GetInvalidMessage(beatmap) == null; | ||
|
||
/// <summary> | ||
/// Will get the invalid message if beatmap property is not able to be detected. | ||
/// </summary> | ||
/// <param name="beatmap"></param> | ||
/// <returns></returns> | ||
LocalisableString? GetInvalidMessage(KaraokeBeatmap beatmap); | ||
|
||
/// <summary> | ||
/// Detect the property from the beatmap. | ||
/// </summary> | ||
/// <param name="beatmap"></param> | ||
/// <returns></returns> | ||
T Detect(KaraokeBeatmap beatmap); | ||
} | ||
} |
36 changes: 36 additions & 0 deletions
36
osu.Game.Rulesets.Karaoke/Edit/Generator/Beatmaps/IBeatmapPropertyGenerator.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
// Copyright (c) andy840119 <[email protected]>. Licensed under the GPL Licence. | ||
// See the LICENCE file in the repository root for full licence text. | ||
|
||
using osu.Framework.Localisation; | ||
using osu.Game.Rulesets.Karaoke.Beatmaps; | ||
|
||
namespace osu.Game.Rulesets.Karaoke.Edit.Generator.Beatmaps | ||
{ | ||
/// <summary> | ||
/// Base interface of the auto-generator. | ||
/// </summary> | ||
/// <typeparam name="T"></typeparam> | ||
public interface IBeatmapPropertyGenerator<out T> | ||
{ | ||
/// <summary> | ||
/// Determined if detect property from <see cref="KaraokeBeatmap"/> is supported. | ||
/// </summary> | ||
/// <param name="beatmap"></param> | ||
/// <returns></returns> | ||
bool CanGenerate(KaraokeBeatmap beatmap) => GetInvalidMessage(beatmap) == null; | ||
|
||
/// <summary> | ||
/// Will get the invalid message if beatmap property is not able to be generated. | ||
/// </summary> | ||
/// <param name="beatmap"></param> | ||
/// <returns></returns> | ||
LocalisableString? GetInvalidMessage(KaraokeBeatmap beatmap); | ||
|
||
/// <summary> | ||
/// Generate the property from the beatmap. | ||
/// </summary> | ||
/// <param name="beatmap"></param> | ||
/// <returns></returns> | ||
T Generate(KaraokeBeatmap beatmap); | ||
} | ||
} |
Oops, something went wrong.