Skip to content

Commit

Permalink
Merge pull request #300 from andy840119/time-tag/change-time-tag-to-o…
Browse files Browse the repository at this point in the history
…bject

Change time tag from tuple to object
  • Loading branch information
andy840119 authored Dec 10, 2020
2 parents 85a53eb + 40cd5e7 commit 553409f
Show file tree
Hide file tree
Showing 16 changed files with 166 additions and 142 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ protected TConfig GeneratorConfig(params string[] properties)

#region test helper

private TimeTagIndex[] getTimeTagIndex(Tuple<TimeTagIndex, double?>[] 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 =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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<TimeTagIndex, double?> timeTag)
private void setTooltip(string testName, TimeTag timeTag)
{
AddStep(testName, () =>
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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());
Expand All @@ -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<Tuple<TimeTagIndex, double?>[]>(json_string, CreateSettings());
var result = JsonConvert.DeserializeObject<TimeTag[]>(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);
}
}
}
99 changes: 50 additions & 49 deletions osu.Game.Rulesets.Karaoke.Tests/Utils/TimeTagsUtilsTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -90,111 +91,111 @@ public void TestToDictionary(string testCase, double[] results)
Assert.AreEqual(getSortedTime(dictionary), results);
}

private double[] getSortedTime(Tuple<TimeTagIndex, double?>[] 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<TimeTagIndex, double> dictionary)
=> dictionary.Select(x => x.Value).ToArray();

private Tuple<TimeTagIndex, double?>[] 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<TimeTagIndex, double?>[];
return theMethod.Invoke(this, null) as TimeTag[];
}

#region valid source

public static Tuple<TimeTagIndex, double?>[] 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<TimeTagIndex, double?>[] ValidTimeTagWithUnsorted()
public static TimeTag[] ValidTimeTagWithUnsorted()
=> ValidTimeTagWithSorted().Reverse().ToArray();

public static Tuple<TimeTagIndex, double?>[] 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<TimeTagIndex, double?>[] 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<TimeTagIndex, double?>[] 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<TimeTagIndex, double?>[] 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<TimeTagIndex, double?>[] 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<TimeTagIndex, double?>[] 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<TimeTagIndex, double?>[] 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<TimeTagIndex, double?>[] 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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
/// </summary>
protected override void TimeTagLogic(Lyric lyric, List<Tuple<TimeTagIndex, double?>> timeTags)
protected override void TimeTagLogic(Lyric lyric, List<TimeTag> timeTags)
{
timeTags.AddRange(generateTimeTagByText(lyric.Text));

Expand All @@ -31,27 +31,27 @@ protected override void TimeTagLogic(Lyric lyric, List<Tuple<TimeTagIndex, doubl
foreach (var ruby in lyric.RubyTags)
{
// remove exist time tag
timeTags.RemoveAll(x => 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<Tuple<TimeTagIndex, double?>> generateTimeTagByText(string text)
private List<TimeTag> generateTimeTagByText(string text)
{
var timeTags = new List<Tuple<TimeTagIndex, double?>>();
var timeTags = new List<TimeTag>();
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];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,25 +19,25 @@ protected TimeTagGenerator(T config)
Config = config;
}

public virtual Tuple<TimeTagIndex, double?>[] CreateTimeTags(Lyric lyric)
public virtual TimeTag[] CreateTimeTags(Lyric lyric)
{
var timeTags = new List<Tuple<TimeTagIndex, double?>>();
var timeTags = new List<TimeTag>();
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<Tuple<TimeTagIndex, double?>> timeTags);
protected abstract void TimeTagLogic(Lyric lyric, List<TimeTag> timeTags);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,15 @@ public ZhTimeTagGenerator(ZhTimeTagGeneratorConfig config)
{
}

protected override void TimeTagLogic(Lyric lyric, List<Tuple<TimeTagIndex, double?>> timeTags)
protected override void TimeTagLogic(Lyric lyric, List<TimeTag> timeTags)
{
var text = lyric.Text;

for (var i = 1; i < text.Length; i++)
{
if (CharUtils.IsChinese(text[i]))
{
timeTags.Add(TimeTagsUtils.Create(new TimeTagIndex(i, TimeTagIndex.IndexState.Start), null));
timeTags.Add(new TimeTag(new TimeTagIndex(i, TimeTagIndex.IndexState.Start), null));
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,12 +110,12 @@ protected void UpdateTimeTags()

foreach (var timeTag in timeTags)
{
var index = Math.Min(timeTag.Item1.Index, HitObject.Text.Length - 1);
var percentage = timeTag.Item1.State == TimeTagIndex.IndexState.Start ? 0 : 1;
var index = Math.Min(timeTag.Index.Index, HitObject.Text.Length - 1);
var percentage = timeTag.Index.State == TimeTagIndex.IndexState.Start ? 0 : 1;
var position = karaokeText.GetPercentageWidth(index, index + 1, percentage);

var duplicatedTagAmount = timeTags.SkipWhile(t => 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)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -19,9 +20,9 @@ public class DrawableTimeTag : CompositeDrawable
/// </summary>
private const float triangle_width = 3;

private readonly Tuple<TimeTagIndex, double?> timeTag;
private readonly TimeTag timeTag;

public DrawableTimeTag(Tuple<TimeTagIndex, double?> timeTag)
public DrawableTimeTag(TimeTag timeTag)
{
this.timeTag = timeTag;

Expand All @@ -31,14 +32,14 @@ public DrawableTimeTag(Tuple<TimeTagIndex, double?> 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;
}
}
}
2 changes: 1 addition & 1 deletion osu.Game.Rulesets.Karaoke/Edit/Lyrics/TimeTagManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ public TimeTagGeneratorSelector()
});
}

public Tuple<TimeTagIndex, double?>[] GenerateTimeTags(Lyric lyric)
public TimeTag[] GenerateTimeTags(Lyric lyric)
{
// lazy to generate language detector and apply it's setting
switch (lyric.Language?.LCID)
Expand Down
Loading

0 comments on commit 553409f

Please sign in to comment.