diff --git a/osu.Game.Rulesets.Karaoke.Tests/Edit/Generator/TimeTags/BaseTimeTagGeneratorTest.cs b/osu.Game.Rulesets.Karaoke.Tests/Edit/Generator/TimeTags/BaseTimeTagGeneratorTest.cs index 04f1c8266..dcc19f108 100644 --- a/osu.Game.Rulesets.Karaoke.Tests/Edit/Generator/TimeTags/BaseTimeTagGeneratorTest.cs +++ b/osu.Game.Rulesets.Karaoke.Tests/Edit/Generator/TimeTags/BaseTimeTagGeneratorTest.cs @@ -54,8 +54,8 @@ protected TConfig GeneratorConfig(params string[] properties) #region test helper - private TimeTagIndex[] getTimeTagIndex(Tuple[] timeTags) - => timeTags.Select((v, i) => v.Item1).ToArray(); + private TimeTagIndex[] getTimeTagIndex(TimeTag[] timeTags) + => timeTags.Select((v, i) => v.Index).ToArray(); private TimeTagIndex[] getTimeTagIndexByArray(double[] timeTags) => timeTags.Select(timeTag => diff --git a/osu.Game.Rulesets.Karaoke.Tests/Graphics/TestSceneTimeTagTooltip.cs b/osu.Game.Rulesets.Karaoke.Tests/Graphics/TestSceneTimeTagTooltip.cs index e8e270beb..d4164435b 100644 --- a/osu.Game.Rulesets.Karaoke.Tests/Graphics/TestSceneTimeTagTooltip.cs +++ b/osu.Game.Rulesets.Karaoke.Tests/Graphics/TestSceneTimeTagTooltip.cs @@ -6,6 +6,7 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Sprites; using osu.Game.Rulesets.Karaoke.Graphics.Cursor; +using osu.Game.Rulesets.Karaoke.Objects; using osu.Game.Rulesets.Karaoke.Utils; using osu.Game.Tests.Visual; @@ -30,12 +31,12 @@ public void SetUp() => Schedule(() => [Test] public void TestDisplayToolTip() { - setTooltip("Start time tag.", TimeTagsUtils.Create(new TimeTagIndex(0), 1280)); - setTooltip("End time tag.", TimeTagsUtils.Create(new TimeTagIndex(0, TimeTagIndex.IndexState.End), 1280)); - setTooltip("Null time", TimeTagsUtils.Create(new TimeTagIndex(0), null)); + setTooltip("Start time tag.", new TimeTag(new TimeTagIndex(0), 1280)); + setTooltip("End time tag.", new TimeTag(new TimeTagIndex(0, TimeTagIndex.IndexState.End), 1280)); + setTooltip("Null time", new TimeTag(new TimeTagIndex(0), null)); } - private void setTooltip(string testName, Tuple timeTag) + private void setTooltip(string testName, TimeTag timeTag) { AddStep(testName, () => { diff --git a/osu.Game.Rulesets.Karaoke.Tests/IO/Serialization/Converters/TimeTagsConverterTest.cs b/osu.Game.Rulesets.Karaoke.Tests/IO/Serialization/Converters/TimeTagsConverterTest.cs index 5dcb03d0a..b0ad17f0b 100644 --- a/osu.Game.Rulesets.Karaoke.Tests/IO/Serialization/Converters/TimeTagsConverterTest.cs +++ b/osu.Game.Rulesets.Karaoke.Tests/IO/Serialization/Converters/TimeTagsConverterTest.cs @@ -6,6 +6,7 @@ using NUnit.Framework; using osu.Framework.Graphics.Sprites; using osu.Game.Rulesets.Karaoke.IO.Serialization.Converters; +using osu.Game.Rulesets.Karaoke.Objects; using osu.Game.Rulesets.Karaoke.Utils; namespace osu.Game.Rulesets.Karaoke.Tests.IO.Serialization.Converters @@ -18,9 +19,9 @@ public void TestSerialize() { var rowTimeTag = new[] { - TimeTagsUtils.Create(new TimeTagIndex(0), 1000d), - TimeTagsUtils.Create(new TimeTagIndex(0, TimeTagIndex.IndexState.End), 1100d), - TimeTagsUtils.Create(new TimeTagIndex(0, TimeTagIndex.IndexState.End), 1200d), + new TimeTag(new TimeTagIndex(0), 1000d), + new TimeTag(new TimeTagIndex(0, TimeTagIndex.IndexState.End), 1100d), + new TimeTag(new TimeTagIndex(0, TimeTagIndex.IndexState.End), 1200d), }; var result = JsonConvert.SerializeObject(rowTimeTag, CreateSettings()); @@ -32,13 +33,13 @@ public void TestSerialize() public void TestDeserialize() { const string json_string = "[\r\n \"0,0,1000\",\r\n \"0,1,1100\",\r\n \"0,1,1200\"\r\n]"; - var result = JsonConvert.DeserializeObject[]>(json_string, CreateSettings()); + var result = JsonConvert.DeserializeObject(json_string, CreateSettings()); Assert.IsNotNull(result); Assert.AreEqual(result.Length, 3); - Assert.AreEqual(result[0].Item1.Index, 0); - Assert.AreEqual(result[0].Item1.State, TimeTagIndex.IndexState.Start); - Assert.AreEqual(result[0].Item2, 1000); + Assert.AreEqual(result[0].Index.Index, 0); + Assert.AreEqual(result[0].Index.State, TimeTagIndex.IndexState.Start); + Assert.AreEqual(result[0].Time, 1000); } } } diff --git a/osu.Game.Rulesets.Karaoke.Tests/Utils/TimeTagsUtilsTest.cs b/osu.Game.Rulesets.Karaoke.Tests/Utils/TimeTagsUtilsTest.cs index 752809dfd..9dd764eb0 100644 --- a/osu.Game.Rulesets.Karaoke.Tests/Utils/TimeTagsUtilsTest.cs +++ b/osu.Game.Rulesets.Karaoke.Tests/Utils/TimeTagsUtilsTest.cs @@ -7,6 +7,7 @@ using Microsoft.EntityFrameworkCore.Internal; using NUnit.Framework; using osu.Framework.Graphics.Sprites; +using osu.Game.Rulesets.Karaoke.Objects; using osu.Game.Rulesets.Karaoke.Utils; namespace osu.Game.Rulesets.Karaoke.Tests.Utils @@ -90,111 +91,111 @@ public void TestToDictionary(string testCase, double[] results) Assert.AreEqual(getSortedTime(dictionary), results); } - private double[] getSortedTime(Tuple[] timeTags) - => timeTags.Where(x => x.Item2 != null).Select(x => x.Item2 ?? 0) + private double[] getSortedTime(TimeTag[] timeTags) + => timeTags.Where(x => x.Time != null).Select(x => x.Time ?? 0) .OrderBy(x => x).ToArray(); private double[] getSortedTime(IReadOnlyDictionary dictionary) => dictionary.Select(x => x.Value).ToArray(); - private Tuple[] getValueByMethodName(string methodName) + private TimeTag[] getValueByMethodName(string methodName) { Type thisType = GetType(); var theMethod = thisType.GetMethod(methodName); if (theMethod == null) throw new MissingMethodException("Test method is not exist."); - return theMethod.Invoke(this, null) as Tuple[]; + return theMethod.Invoke(this, null) as TimeTag[]; } #region valid source - public static Tuple[] ValidTimeTagWithSorted() + public static TimeTag[] ValidTimeTagWithSorted() => new[] { - TimeTagsUtils.Create(new TimeTagIndex(0), 1100), - TimeTagsUtils.Create(new TimeTagIndex(0, TimeTagIndex.IndexState.End), 2000), - TimeTagsUtils.Create(new TimeTagIndex(1), 2100), - TimeTagsUtils.Create(new TimeTagIndex(1, TimeTagIndex.IndexState.End), 3000), + new TimeTag(new TimeTagIndex(0), 1100), + new TimeTag(new TimeTagIndex(0, TimeTagIndex.IndexState.End), 2000), + new TimeTag(new TimeTagIndex(1), 2100), + new TimeTag(new TimeTagIndex(1, TimeTagIndex.IndexState.End), 3000), }; - public static Tuple[] ValidTimeTagWithUnsorted() + public static TimeTag[] ValidTimeTagWithUnsorted() => ValidTimeTagWithSorted().Reverse().ToArray(); - public static Tuple[] ValidTimeTagWithUnsortedAndDuplicatedWithNoValue() + public static TimeTag[] ValidTimeTagWithUnsortedAndDuplicatedWithNoValue() => new[] { - TimeTagsUtils.Create(new TimeTagIndex(0), null), - TimeTagsUtils.Create(new TimeTagIndex(0), null), - TimeTagsUtils.Create(new TimeTagIndex(0, TimeTagIndex.IndexState.End), 2000), // this time tag is not in order. - TimeTagsUtils.Create(new TimeTagIndex(0), 1100), + new TimeTag(new TimeTagIndex(0), null), + new TimeTag(new TimeTagIndex(0), null), + new TimeTag(new TimeTagIndex(0, TimeTagIndex.IndexState.End), 2000), // this time tag is not in order. + new TimeTag(new TimeTagIndex(0), 1100), }; - public static Tuple[] ValidTimeTagWithUnsortedAndDuplicatedWithValue() + public static TimeTag[] ValidTimeTagWithUnsortedAndDuplicatedWithValue() => new[] { // not sorted + duplicated time tag(with value) - TimeTagsUtils.Create(new TimeTagIndex(0), 1000), - TimeTagsUtils.Create(new TimeTagIndex(0), 1100), - TimeTagsUtils.Create(new TimeTagIndex(0, TimeTagIndex.IndexState.End), 2000), // this time tag is not in order. - TimeTagsUtils.Create(new TimeTagIndex(0), 1100), + new TimeTag(new TimeTagIndex(0), 1000), + new TimeTag(new TimeTagIndex(0), 1100), + new TimeTag(new TimeTagIndex(0, TimeTagIndex.IndexState.End), 2000), // this time tag is not in order. + new TimeTag(new TimeTagIndex(0), 1100), }; - public static Tuple[] ValidTimeTagWithUnsortedAndAllEmpty() + public static TimeTag[] ValidTimeTagWithUnsortedAndAllEmpty() => new[] { - TimeTagsUtils.Create(new TimeTagIndex(0), null), - TimeTagsUtils.Create(new TimeTagIndex(0, TimeTagIndex.IndexState.End), null), - TimeTagsUtils.Create(new TimeTagIndex(0), null), // this time tag is not sorted. - TimeTagsUtils.Create(new TimeTagIndex(1), null), - TimeTagsUtils.Create(new TimeTagIndex(1, TimeTagIndex.IndexState.End), null), + new TimeTag(new TimeTagIndex(0), null), + new TimeTag(new TimeTagIndex(0, TimeTagIndex.IndexState.End), null), + new TimeTag(new TimeTagIndex(0), null), // this time tag is not sorted. + new TimeTag(new TimeTagIndex(1), null), + new TimeTag(new TimeTagIndex(1, TimeTagIndex.IndexState.End), null), }; #endregion #region invalid source - public static Tuple[] InvalidTimeTagWithStartLargerThenEnd() + public static TimeTag[] InvalidTimeTagWithStartLargerThenEnd() => new[] { - TimeTagsUtils.Create(new TimeTagIndex(0), 2000), // Start is larger then end. - TimeTagsUtils.Create(new TimeTagIndex(0, TimeTagIndex.IndexState.End), 1000), + new TimeTag(new TimeTagIndex(0), 2000), // Start is larger then end. + new TimeTag(new TimeTagIndex(0, TimeTagIndex.IndexState.End), 1000), }; - public static Tuple[] InvalidTimeTagWithEndLargerThenNextStart() + public static TimeTag[] InvalidTimeTagWithEndLargerThenNextStart() => new[] { - TimeTagsUtils.Create(new TimeTagIndex(0), 1100), - TimeTagsUtils.Create(new TimeTagIndex(0, TimeTagIndex.IndexState.End), 2100), // End is larger than second start. - TimeTagsUtils.Create(new TimeTagIndex(1), 2000), - TimeTagsUtils.Create(new TimeTagIndex(1, TimeTagIndex.IndexState.End), 3000), + new TimeTag(new TimeTagIndex(0), 1100), + new TimeTag(new TimeTagIndex(0, TimeTagIndex.IndexState.End), 2100), // End is larger than second start. + new TimeTag(new TimeTagIndex(1), 2000), + new TimeTag(new TimeTagIndex(1, TimeTagIndex.IndexState.End), 3000), }; - public static Tuple[] InvalidTimeTagWithEndLargerThenNextEnd() + public static TimeTag[] InvalidTimeTagWithEndLargerThenNextEnd() => new[] { - TimeTagsUtils.Create(new TimeTagIndex(0), 1000), - TimeTagsUtils.Create(new TimeTagIndex(0, TimeTagIndex.IndexState.End), 5000), // End is larger than second end. - TimeTagsUtils.Create(new TimeTagIndex(1), 2000), - TimeTagsUtils.Create(new TimeTagIndex(1, TimeTagIndex.IndexState.End), 3000), + new TimeTag(new TimeTagIndex(0), 1000), + new TimeTag(new TimeTagIndex(0, TimeTagIndex.IndexState.End), 5000), // End is larger than second end. + new TimeTag(new TimeTagIndex(1), 2000), + new TimeTag(new TimeTagIndex(1, TimeTagIndex.IndexState.End), 3000), }; - public static Tuple[] InvalidTimeTagWithStartSmallerThenPreviousStart() + public static TimeTag[] InvalidTimeTagWithStartSmallerThenPreviousStart() => new[] { - TimeTagsUtils.Create(new TimeTagIndex(0), 1000), - TimeTagsUtils.Create(new TimeTagIndex(0, TimeTagIndex.IndexState.End), 2000), - TimeTagsUtils.Create(new TimeTagIndex(1), 0), // Start is smaller than previous start. - TimeTagsUtils.Create(new TimeTagIndex(1, TimeTagIndex.IndexState.End), 3000), + new TimeTag(new TimeTagIndex(0), 1000), + new TimeTag(new TimeTagIndex(0, TimeTagIndex.IndexState.End), 2000), + new TimeTag(new TimeTagIndex(1), 0), // Start is smaller than previous start. + new TimeTag(new TimeTagIndex(1, TimeTagIndex.IndexState.End), 3000), }; - public static Tuple[] InvalidTimeTagWithAllInverse() + public static TimeTag[] InvalidTimeTagWithAllInverse() => new[] { - TimeTagsUtils.Create(new TimeTagIndex(0), 4000), - TimeTagsUtils.Create(new TimeTagIndex(0, TimeTagIndex.IndexState.End), 3000), - TimeTagsUtils.Create(new TimeTagIndex(1), 2000), - TimeTagsUtils.Create(new TimeTagIndex(1, TimeTagIndex.IndexState.End), 1000), + new TimeTag(new TimeTagIndex(0), 4000), + new TimeTag(new TimeTagIndex(0, TimeTagIndex.IndexState.End), 3000), + new TimeTag(new TimeTagIndex(1), 2000), + new TimeTag(new TimeTagIndex(1, TimeTagIndex.IndexState.End), 1000), }; #endregion diff --git a/osu.Game.Rulesets.Karaoke/Edit/Generator/TimeTags/Ja/JaTimeTagGenerator.cs b/osu.Game.Rulesets.Karaoke/Edit/Generator/TimeTags/Ja/JaTimeTagGenerator.cs index 9d2e8dab0..fc284e740 100644 --- a/osu.Game.Rulesets.Karaoke/Edit/Generator/TimeTags/Ja/JaTimeTagGenerator.cs +++ b/osu.Game.Rulesets.Karaoke/Edit/Generator/TimeTags/Ja/JaTimeTagGenerator.cs @@ -21,7 +21,7 @@ public JaTimeTagGenerator(JaTimeTagGeneratorConfig config) /// Thanks for RhythmKaTTE's author writing this logic into C# /// http://juna-idler.blogspot.com/2016/05/rhythmkatte-version-01.html /// - protected override void TimeTagLogic(Lyric lyric, List> timeTags) + protected override void TimeTagLogic(Lyric lyric, List timeTags) { timeTags.AddRange(generateTimeTagByText(lyric.Text)); @@ -31,27 +31,27 @@ protected override void TimeTagLogic(Lyric lyric, List x.Item1.Index > ruby.StartIndex && x.Item1.Index < ruby.EndIndex); + timeTags.RemoveAll(x => x.Index.Index > ruby.StartIndex && x.Index.Index < ruby.EndIndex); // add new time tags created from ruby var rubyTags = generateTimeTagByText(ruby.Text); var shiftingTimeTags = rubyTags.Select((x, v) => { - return TimeTagsUtils.Create(new TimeTagIndex(ruby.StartIndex, x.Item1.State), x.Item2); + return new TimeTag(new TimeTagIndex(ruby.StartIndex, x.Index.State), x.Time); }); timeTags.AddRange(shiftingTimeTags); } } - private List> generateTimeTagByText(string text) + private List generateTimeTagByText(string text) { - var timeTags = new List>(); + var timeTags = new List(); if (text == null || text == "") return timeTags; for (var i = 1; i < text.Length; i++) { - var timeTag = TimeTagsUtils.Create(new TimeTagIndex(i, TimeTagIndex.IndexState.Start), null); + var timeTag = new TimeTag(new TimeTagIndex(i, TimeTagIndex.IndexState.Start), null); var c = text[i]; var pc = text[i - 1]; diff --git a/osu.Game.Rulesets.Karaoke/Edit/Generator/TimeTags/TimeTagGenerator.cs b/osu.Game.Rulesets.Karaoke/Edit/Generator/TimeTags/TimeTagGenerator.cs index 4eb8f4ed6..fc7ba3e16 100644 --- a/osu.Game.Rulesets.Karaoke/Edit/Generator/TimeTags/TimeTagGenerator.cs +++ b/osu.Game.Rulesets.Karaoke/Edit/Generator/TimeTags/TimeTagGenerator.cs @@ -19,25 +19,25 @@ protected TimeTagGenerator(T config) Config = config; } - public virtual Tuple[] CreateTimeTags(Lyric lyric) + public virtual TimeTag[] CreateTimeTags(Lyric lyric) { - var timeTags = new List>(); + var timeTags = new List(); var text = lyric.Text; if (text.Length == 0) return timeTags.ToArray(); // create tag at start of lyric - timeTags.Add(TimeTagsUtils.Create(new TimeTagIndex(0, TimeTagIndex.IndexState.Start), null)); + timeTags.Add(new TimeTag(new TimeTagIndex(0, TimeTagIndex.IndexState.Start), null)); if (Config.CheckLineEndKeyUp) - timeTags.Add(TimeTagsUtils.Create(new TimeTagIndex(text.Length - 1, TimeTagIndex.IndexState.End), null)); + timeTags.Add(new TimeTag(new TimeTagIndex(text.Length - 1, TimeTagIndex.IndexState.End), null)); TimeTagLogic(lyric, timeTags); - return timeTags.OrderBy(x => x.Item1).ToArray(); + return timeTags.OrderBy(x => x.Index).ToArray(); } - protected abstract void TimeTagLogic(Lyric lyric, List> timeTags); + protected abstract void TimeTagLogic(Lyric lyric, List timeTags); } } diff --git a/osu.Game.Rulesets.Karaoke/Edit/Generator/TimeTags/Zh/ZhTimeTagGenerator.cs b/osu.Game.Rulesets.Karaoke/Edit/Generator/TimeTags/Zh/ZhTimeTagGenerator.cs index 806950a86..82472d170 100644 --- a/osu.Game.Rulesets.Karaoke/Edit/Generator/TimeTags/Zh/ZhTimeTagGenerator.cs +++ b/osu.Game.Rulesets.Karaoke/Edit/Generator/TimeTags/Zh/ZhTimeTagGenerator.cs @@ -16,7 +16,7 @@ public ZhTimeTagGenerator(ZhTimeTagGeneratorConfig config) { } - protected override void TimeTagLogic(Lyric lyric, List> timeTags) + protected override void TimeTagLogic(Lyric lyric, List timeTags) { var text = lyric.Text; @@ -24,7 +24,7 @@ protected override void TimeTagLogic(Lyric lyric, List t != timeTag).Count(x => x.Item1 == timeTag.Item1) - 1; - var spacing = duplicatedTagAmount * time_tag_spacing * (timeTag.Item1.State == TimeTagIndex.IndexState.Start ? 1 : -1); + var duplicatedTagAmount = timeTags.SkipWhile(t => t != timeTag).Count(x => x.Index == timeTag.Index) - 1; + var spacing = duplicatedTagAmount * time_tag_spacing * (timeTag.Index.State == TimeTagIndex.IndexState.Start ? 1 : -1); timeTagContainer.Add(new DrawableTimeTag(timeTag) { diff --git a/osu.Game.Rulesets.Karaoke/Edit/Lyrics/Components/TimeTags/DrawableTimeTag.cs b/osu.Game.Rulesets.Karaoke/Edit/Lyrics/Components/TimeTags/DrawableTimeTag.cs index acd79dfb6..c1beaeacf 100644 --- a/osu.Game.Rulesets.Karaoke/Edit/Lyrics/Components/TimeTags/DrawableTimeTag.cs +++ b/osu.Game.Rulesets.Karaoke/Edit/Lyrics/Components/TimeTags/DrawableTimeTag.cs @@ -7,6 +7,7 @@ using osu.Framework.Graphics.Sprites; using osu.Game.Graphics; using osu.Game.Rulesets.Karaoke.Graphics.Shapes; +using osu.Game.Rulesets.Karaoke.Objects; using osuTK; using System; @@ -19,9 +20,9 @@ public class DrawableTimeTag : CompositeDrawable /// private const float triangle_width = 3; - private readonly Tuple timeTag; + private readonly TimeTag timeTag; - public DrawableTimeTag(Tuple timeTag) + public DrawableTimeTag(TimeTag timeTag) { this.timeTag = timeTag; @@ -31,14 +32,14 @@ public DrawableTimeTag(Tuple timeTag) Anchor = Anchor.TopCentre, Origin = Anchor.Centre, Size = new Vector2(triangle_width), - Scale = new Vector2(timeTag.Item1.State == TimeTagIndex.IndexState.Start ? 1 : -1, 1) + Scale = new Vector2(timeTag.Index.State == TimeTagIndex.IndexState.Start ? 1 : -1, 1) }; } [BackgroundDependencyLoader] private void load(OsuColour colours) { - InternalChild.Colour = timeTag.Item2.HasValue ? colours.Yellow : colours.Gray7; + InternalChild.Colour = timeTag.Time.HasValue ? colours.Yellow : colours.Gray7; } } } diff --git a/osu.Game.Rulesets.Karaoke/Edit/Lyrics/TimeTagManager.cs b/osu.Game.Rulesets.Karaoke/Edit/Lyrics/TimeTagManager.cs index 0679c625f..49232687b 100644 --- a/osu.Game.Rulesets.Karaoke/Edit/Lyrics/TimeTagManager.cs +++ b/osu.Game.Rulesets.Karaoke/Edit/Lyrics/TimeTagManager.cs @@ -64,7 +64,7 @@ public TimeTagGeneratorSelector() }); } - public Tuple[] GenerateTimeTags(Lyric lyric) + public TimeTag[] GenerateTimeTags(Lyric lyric) { // lazy to generate language detector and apply it's setting switch (lyric.Language?.LCID) diff --git a/osu.Game.Rulesets.Karaoke/Graphics/Cursor/TimeTagTooltip.cs b/osu.Game.Rulesets.Karaoke/Graphics/Cursor/TimeTagTooltip.cs index 69c1f6422..6cb9c22da 100644 --- a/osu.Game.Rulesets.Karaoke/Graphics/Cursor/TimeTagTooltip.cs +++ b/osu.Game.Rulesets.Karaoke/Graphics/Cursor/TimeTagTooltip.cs @@ -10,6 +10,7 @@ using osu.Game.Extensions; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; +using osu.Game.Rulesets.Karaoke.Objects; using osuTK; namespace osu.Game.Rulesets.Karaoke.Graphics.Cursor @@ -76,12 +77,12 @@ protected override Drawable SetBackground() public override bool SetContent(object content) { - if (!(content is Tuple timeTag)) + if (!(content is TimeTag timeTag)) return false; - trackTimer.Text = timeTag.Item2?.ToEditorFormattedString() ?? "--:--:---"; - index.Text = $"At index {timeTag.Item1.Index}"; - indexState.Text = timeTag.Item1.State == TimeTagIndex.IndexState.Start ? "Start" : "End"; + trackTimer.Text = timeTag.Time?.ToEditorFormattedString() ?? "--:--:---"; + index.Text = $"At index {timeTag.Index.Index}"; + indexState.Text = timeTag.Index.State == TimeTagIndex.IndexState.Start ? "Start" : "End"; return true; } diff --git a/osu.Game.Rulesets.Karaoke/IO/Serialization/Converters/TimeTagsConverter.cs b/osu.Game.Rulesets.Karaoke/IO/Serialization/Converters/TimeTagsConverter.cs index 7c87e4754..133d544a1 100644 --- a/osu.Game.Rulesets.Karaoke/IO/Serialization/Converters/TimeTagsConverter.cs +++ b/osu.Game.Rulesets.Karaoke/IO/Serialization/Converters/TimeTagsConverter.cs @@ -6,12 +6,13 @@ using Newtonsoft.Json; using Newtonsoft.Json.Linq; using osu.Framework.Graphics.Sprites; +using osu.Game.Rulesets.Karaoke.Objects; namespace osu.Game.Rulesets.Karaoke.IO.Serialization.Converters { - public class TimeTagsConverter : JsonConverter[]> + public class TimeTagsConverter : JsonConverter { - public override Tuple[] ReadJson(JsonReader reader, Type objectType, Tuple[] existingValues, bool hasExistingValue, JsonSerializer serializer) + public override TimeTag[] ReadJson(JsonReader reader, Type objectType, TimeTag[] existingValues, bool hasExistingValue, JsonSerializer serializer) { var obj = JArray.Load(reader); @@ -21,18 +22,18 @@ public class TimeTagsConverter : JsonConverter[]> return deserializeTuple(value); }).ToArray(); - Tuple deserializeTuple(string str) + TimeTag deserializeTuple(string str) { var strArray = str.Split(','); var state = strArray[1] == "0" ? TimeTagIndex.IndexState.Start : TimeTagIndex.IndexState.End; var timeTag = new TimeTagIndex(int.Parse(strArray[0]), state); var time = strArray[2] != "" ? int.Parse(strArray[2]) : default(double?); - return new Tuple(timeTag, time); + return new TimeTag(timeTag, time); } } - public override void WriteJson(JsonWriter writer, Tuple[] values, JsonSerializer serializer) + public override void WriteJson(JsonWriter writer, TimeTag[] values, JsonSerializer serializer) { writer.WriteStartArray(); @@ -43,11 +44,11 @@ public override void WriteJson(JsonWriter writer, Tuple[] writer.WriteEndArray(); - string serializeTuple(Tuple timeTagTuple) + string serializeTuple(TimeTag timeTagTuple) { - var tag = timeTagTuple.Item1; + var tag = timeTagTuple.Index; var state = tag.State == TimeTagIndex.IndexState.Start ? "0" : "1"; - var time = timeTagTuple.Item2; + var time = timeTagTuple.Time; return $"{tag.Index},{state},{time}"; } } diff --git a/osu.Game.Rulesets.Karaoke/Objects/Drawables/DrawableLyric.cs b/osu.Game.Rulesets.Karaoke/Objects/Drawables/DrawableLyric.cs index b73e73912..58a5c8054 100644 --- a/osu.Game.Rulesets.Karaoke/Objects/Drawables/DrawableLyric.cs +++ b/osu.Game.Rulesets.Karaoke/Objects/Drawables/DrawableLyric.cs @@ -30,7 +30,7 @@ public class DrawableLyric : DrawableKaraokeHitObject private OsuSpriteText translateText; public readonly IBindable TextBindable = new Bindable(); - public readonly IBindable[]> TimeTagsBindable = new Bindable[]>(); + public readonly IBindable TimeTagsBindable = new Bindable(); public readonly IBindable RubyTagsBindable = new Bindable(); public readonly IBindable RomajiTagsBindable = new Bindable(); public readonly IBindable SingersBindable = new Bindable(); diff --git a/osu.Game.Rulesets.Karaoke/Objects/Lyric.cs b/osu.Game.Rulesets.Karaoke/Objects/Lyric.cs index f9f7f1118..0ccb8f6e9 100644 --- a/osu.Game.Rulesets.Karaoke/Objects/Lyric.cs +++ b/osu.Game.Rulesets.Karaoke/Objects/Lyric.cs @@ -35,12 +35,12 @@ public string Text } [JsonIgnore] - public readonly Bindable[]> TimeTagsBindable = new Bindable[]>(); + public readonly Bindable TimeTagsBindable = new Bindable(); /// /// Time tags /// - public Tuple[] TimeTags + public TimeTag[] TimeTags { get => TimeTagsBindable.Value; set => TimeTagsBindable.Value = value; diff --git a/osu.Game.Rulesets.Karaoke/Objects/TimeTag.cs b/osu.Game.Rulesets.Karaoke/Objects/TimeTag.cs new file mode 100644 index 000000000..d09099eb7 --- /dev/null +++ b/osu.Game.Rulesets.Karaoke/Objects/TimeTag.cs @@ -0,0 +1,19 @@ +// Copyright (c) andy840119 . Licensed under the GPL Licence. +// See the LICENCE file in the repository root for full licence text. +using osu.Framework.Graphics.Sprites; + +namespace osu.Game.Rulesets.Karaoke.Objects +{ + public class TimeTag + { + public TimeTag(TimeTagIndex index, double? time = null) + { + Index = index; + Time = time; + } + + public TimeTagIndex Index { get; } + + public double? Time { get; set; } + } +} diff --git a/osu.Game.Rulesets.Karaoke/Utils/TimeTagsUtils.cs b/osu.Game.Rulesets.Karaoke/Utils/TimeTagsUtils.cs index e045ecc35..39e3dc849 100644 --- a/osu.Game.Rulesets.Karaoke/Utils/TimeTagsUtils.cs +++ b/osu.Game.Rulesets.Karaoke/Utils/TimeTagsUtils.cs @@ -6,6 +6,7 @@ using System.Linq; using Microsoft.EntityFrameworkCore.Internal; using osu.Framework.Graphics.Sprites; +using osu.Game.Rulesets.Karaoke.Objects; namespace osu.Game.Rulesets.Karaoke.Utils { @@ -16,10 +17,10 @@ public static class TimeTagsUtils /// /// Time tags /// Sorted time tags - public static Tuple[] Sort(Tuple[] timeTags) + public static TimeTag[] Sort(TimeTag[] timeTags) { - return timeTags?.OrderBy(x => x.Item1) - .ThenBy(x => x.Item2).ToArray(); + return timeTags?.OrderBy(x => x.Index) + .ThenBy(x => x.Time).ToArray(); } /// @@ -29,17 +30,17 @@ public static class TimeTagsUtils /// Check way /// Check way /// List of invalid time tags - public static Tuple[] FindInvalid(Tuple[] timeTags, GroupCheck other = GroupCheck.Asc, SelfCheck self = SelfCheck.BasedOnStart) + public static TimeTag[] FindInvalid(TimeTag[] timeTags, GroupCheck other = GroupCheck.Asc, SelfCheck self = SelfCheck.BasedOnStart) { var sortedTimeTags = Sort(timeTags); - var groupedTimeTags = sortedTimeTags.GroupBy(x => x.Item1.Index); + var groupedTimeTags = sortedTimeTags.GroupBy(x => x.Index.Index); - var invalidList = new List>(); + var invalidList = new List(); foreach (var groupedTimeTag in groupedTimeTags) { - var startTimeGroup = groupedTimeTag.Where(x => x.Item1.State == TimeTagIndex.IndexState.Start && x.Item2 != null); - var endTimeGroup = groupedTimeTag.Where(x => x.Item1.State == TimeTagIndex.IndexState.End && x.Item2 != null); + var startTimeGroup = groupedTimeTag.Where(x => x.Index.State == TimeTagIndex.IndexState.Start && x.Time != null); + var endTimeGroup = groupedTimeTag.Where(x => x.Index.State == TimeTagIndex.IndexState.End && x.Time != null); // add invalid group into list. var groupInvalid = findGroupInvalid(); @@ -51,48 +52,48 @@ public static class TimeTagsUtils if (selfInvalid != null) invalidList.AddRange(selfInvalid); - List> findGroupInvalid() + List findGroupInvalid() { switch (other) { case GroupCheck.Asc: // mark next is invalid if smaller then self - var groupMaxTime = groupedTimeTag.Max(x => x.Item2); + var groupMaxTime = groupedTimeTag.Max(x => x.Time); if (groupMaxTime == null) return null; - return sortedTimeTags.Where(x => x.Item1.Index > groupedTimeTag.Key && x.Item2 < groupMaxTime).ToList(); + return sortedTimeTags.Where(x => x.Index.Index > groupedTimeTag.Key && x.Time < groupMaxTime).ToList(); case GroupCheck.Desc: // mark previous is invalid if larger then self - var groupMinTime = groupedTimeTag.Min(x => x.Item2); + var groupMinTime = groupedTimeTag.Min(x => x.Time); if (groupMinTime == null) return null; - return sortedTimeTags.Where(x => x.Item1.Index < groupedTimeTag.Key && x.Item2 > groupMinTime).ToList(); + return sortedTimeTags.Where(x => x.Index.Index < groupedTimeTag.Key && x.Time > groupMinTime).ToList(); default: return null; } } - List> findSelfInvalid() + List findSelfInvalid() { switch (self) { case SelfCheck.BasedOnStart: - var maxStartTime = startTimeGroup.Max(x => x.Item2); + var maxStartTime = startTimeGroup.Max(x => x.Time); if (maxStartTime == null) return null; - return endTimeGroup.Where(x => x.Item2.Value < maxStartTime.Value).ToList(); + return endTimeGroup.Where(x => x.Time.Value < maxStartTime.Value).ToList(); case SelfCheck.BasedOnEnd: - var minEndTime = endTimeGroup.Min(x => x.Item2); + var minEndTime = endTimeGroup.Min(x => x.Time); if (minEndTime == null) return null; - return startTimeGroup.Where(x => x.Item2.Value > minEndTime.Value).ToList(); + return startTimeGroup.Where(x => x.Time.Value > minEndTime.Value).ToList(); default: return null; @@ -110,13 +111,13 @@ public static class TimeTagsUtils /// Fix way /// Fix way /// Fixed time tags. - public static Tuple[] FixInvalid(Tuple[] timeTags, GroupCheck other = GroupCheck.Asc, SelfCheck self = SelfCheck.BasedOnStart) + public static TimeTag[] FixInvalid(TimeTag[] timeTags, GroupCheck other = GroupCheck.Asc, SelfCheck self = SelfCheck.BasedOnStart) { if (timeTags == null || timeTags.Length == 0) return timeTags; var sortedTimeTags = Sort(timeTags); - var groupedTimeTags = sortedTimeTags.GroupBy(x => x.Item1.Index); + var groupedTimeTags = sortedTimeTags.GroupBy(x => x.Index.Index); var invalidTimeTags = FindInvalid(timeTags, other, self); var validTimeTags = sortedTimeTags.Except(invalidTimeTags); @@ -124,32 +125,32 @@ public static class TimeTagsUtils foreach (var invalidTimeTag in invalidTimeTags) { var listIndex = sortedTimeTags.IndexOf(invalidTimeTag); - var timeTag = invalidTimeTag.Item1; + var timeTag = invalidTimeTag.Index; // fix self-invalid var groupedTimeTag = groupedTimeTags.FirstOrDefault(x => x.Key == timeTag.Index).ToList(); - var startTimeGroup = groupedTimeTag.Where(x => x.Item1.State == TimeTagIndex.IndexState.Start && x.Item2 != null); - var endTimeGroup = groupedTimeTag.Where(x => x.Item1.State == TimeTagIndex.IndexState.End && x.Item2 != null); + var startTimeGroup = groupedTimeTag.Where(x => x.Index.State == TimeTagIndex.IndexState.Start && x.Time != null); + var endTimeGroup = groupedTimeTag.Where(x => x.Index.State == TimeTagIndex.IndexState.End && x.Time != null); switch (timeTag.State) { case TimeTagIndex.IndexState.Start: - var minEndTime = endTimeGroup.Min(x => x.Item2); + var minEndTime = endTimeGroup.Min(x => x.Time); - if (minEndTime != null && minEndTime < invalidTimeTag.Item2) + if (minEndTime != null && minEndTime < invalidTimeTag.Time) { - sortedTimeTags[listIndex] = new Tuple(timeTag, minEndTime); + sortedTimeTags[listIndex] = new TimeTag(timeTag, minEndTime); continue; } break; case TimeTagIndex.IndexState.End: - var maxStartTime = startTimeGroup.Max(x => x.Item2); + var maxStartTime = startTimeGroup.Max(x => x.Time); - if (maxStartTime != null && maxStartTime > invalidTimeTag.Item2) + if (maxStartTime != null && maxStartTime > invalidTimeTag.Time) { - sortedTimeTags[listIndex] = new Tuple(timeTag, maxStartTime); + sortedTimeTags[listIndex] = new TimeTag(timeTag, maxStartTime); continue; } @@ -161,14 +162,14 @@ public static class TimeTagsUtils { case GroupCheck.Asc: // find previous value to apply. - var previousValidValue = sortedTimeTags.Reverse().FirstOrDefault(x => x.Item1.Index < timeTag.Index && x.Item2 != null)?.Item2; - sortedTimeTags[listIndex] = new Tuple(timeTag, previousValidValue); + var previousValidValue = sortedTimeTags.Reverse().FirstOrDefault(x => x.Index.Index < timeTag.Index && x.Time != null)?.Time; + sortedTimeTags[listIndex] = new TimeTag(timeTag, previousValidValue); break; case GroupCheck.Desc: // find next value to apply. - var nextValidValue = sortedTimeTags.FirstOrDefault(x => x.Item1.Index > timeTag.Index && x.Item2 != null)?.Item2; - sortedTimeTags[listIndex] = new Tuple(timeTag, nextValidValue); + var nextValidValue = sortedTimeTags.FirstOrDefault(x => x.Index.Index > timeTag.Index && x.Time != null)?.Time; + sortedTimeTags[listIndex] = new TimeTag(timeTag, nextValidValue); break; } } @@ -184,7 +185,7 @@ public static class TimeTagsUtils /// Fix way /// Fix way /// Time tags with dictionary format. - public static IReadOnlyDictionary ToDictionary(Tuple[] timeTags, bool applyFix = true, GroupCheck other = GroupCheck.Asc, + public static IReadOnlyDictionary ToDictionary(TimeTag[] timeTags, bool applyFix = true, GroupCheck other = GroupCheck.Asc, SelfCheck self = SelfCheck.BasedOnStart) { if (timeTags == null) @@ -194,13 +195,13 @@ public static IReadOnlyDictionary ToDictionary(Tuple x.Item2 != null).GroupBy(x => x.Item1).Select(x => + return sortedTimeTags.Where(x => x.Time != null).GroupBy(x => x.Index).Select(x => { if (x.Key.State == TimeTagIndex.IndexState.Start) return x.FirstOrDefault(); else return x.LastOrDefault(); - }).ToDictionary(k => k.Item1, v => v.Item2 ?? throw new ArgumentNullException("Dictionaty should not have null value")); + }).ToDictionary(k => k.Index, v => v.Time ?? throw new ArgumentNullException("Dictionaty should not have null value")); } /// @@ -208,9 +209,9 @@ public static IReadOnlyDictionary ToDictionary(Tuple /// Dictionary. /// Time tags - public static Tuple[] ToTimeTagList(IReadOnlyDictionary dictionary) + public static TimeTag[] ToTimeTagList(IReadOnlyDictionary dictionary) { - return dictionary.Select(d => Create(d.Key, d.Value)).ToArray(); + return dictionary.Select(d => new TimeTag(d.Key, d.Value)).ToArray(); } /// @@ -218,7 +219,7 @@ public static IReadOnlyDictionary ToDictionary(Tuple /// Time tags /// Start time - public static double? GetStartTime(Tuple[] timeTags) + public static double? GetStartTime(TimeTag[] timeTags) { return ToDictionary(timeTags).FirstOrDefault().Value; } @@ -228,12 +229,10 @@ public static IReadOnlyDictionary ToDictionary(Tuple /// Time tags /// End time - public static double? GetEndTime(Tuple[] timeTags) + public static double? GetEndTime(TimeTag[] timeTags) { return ToDictionary(timeTags).LastOrDefault().Value; } - - public static Tuple Create(TimeTagIndex index, double? time) => Tuple.Create(index, time); } public enum GroupCheck