diff --git a/ChartTools/IO/Chart/Parsing/TrackParser.cs b/ChartTools/IO/Chart/Parsing/TrackParser.cs index 14513383..9fd07661 100644 --- a/ChartTools/IO/Chart/Parsing/TrackParser.cs +++ b/ChartTools/IO/Chart/Parsing/TrackParser.cs @@ -14,9 +14,7 @@ internal abstract class TrackParser(Difficulty difficulty, ChartReadingS public override Track Result => GetResult(result); private readonly Track result = new() { Difficulty = difficulty }; - private TChord? chord; - private bool newChord = true; - private readonly List orderedChords = []; + private TChord? currentChord; protected override void HandleItem(string line) { @@ -30,31 +28,36 @@ protected override void HandleItem(string line) break; // Note or chord modifier case "N": - var newIndex = 0; - // Find the parent chord or create it - if (chord is null) + if (currentChord is null) // First chord { - chord = new() { Position = entry.Position }; - newIndex = orderedChords.Count; + currentChord = new() { Position = entry.Position }; + result.Chords.Add(currentChord!); } - else if (entry.Position == chord.Position) - newChord = false; - else + // Start of a new chord or the note belonging to an existing chord is misplaced + else if (entry.Position != currentChord.Position) { - newIndex = orderedChords.BinarySearchIndex(entry.Position, c => c.Position, out bool exactMatch); - - if (newChord = !exactMatch) - chord = new() { Position = entry.Position }; + // Notes are typically in order of position, not requiring a search for an existing chord + if (entry.Position > result.Chords[^1].Position) // New chord + { + currentChord = new() { Position = entry.Position }; + result.Chords.Add(currentChord!); + } + else // Misplaced note - Requires search for the parent chord + { + var index = result.Chords.BinarySearchIndex(entry.Position, c => c.Position, out bool exactMatch); + + if (exactMatch) + currentChord = result.Chords[index]; + else + { + currentChord = new() { Position = entry.Position }; + result.Chords.Insert(index, currentChord!); + } + } } - HandleNoteEntry(chord!, new(entry.Data)); - - if (newChord) - { - result.Chords.Add(chord!); - orderedChords.Insert(newIndex, chord!); - } + HandleNoteEntry(currentChord!, new(entry.Data)); break; // Star power @@ -75,12 +78,12 @@ protected override void HandleItem(string line) protected abstract void HandleNoteEntry(TChord chord, NoteData data); protected void HandleAddNote(INote note, Action add) { - if (session.HandleDuplicate(chord!.Position, "note", () => chord!.Notes.Any(n => n.Index == note.Index))) + if (session.HandleDuplicate(currentChord!.Position, "note", () => currentChord!.Notes.Any(n => n.Index == note.Index))) add(); } protected void HandleAddModifier(Enum existingModifier, Enum modifier, Action add) { - if (session.HandleDuplicate(chord!.Position, "chord modifier", () => existingModifier.HasFlag(modifier))) + if (session.HandleDuplicate(currentChord!.Position, "chord modifier", () => existingModifier.HasFlag(modifier))) add(); } diff --git a/ChartTools/IO/TextFileReader.cs b/ChartTools/IO/TextFileReader.cs index 6040621b..3e5e2c85 100644 --- a/ChartTools/IO/TextFileReader.cs +++ b/ChartTools/IO/TextFileReader.cs @@ -12,7 +12,7 @@ protected override void ReadBase(bool async, CancellationToken cancellationToken ParserContentGroup? currentGroup = null; using var enumerator = File.ReadLines(Path).Where(s => !string.IsNullOrEmpty(s)).Select(s => s.Trim()).GetEnumerator(); - while (enumerator.MoveNext()) + while (enumerator.MoveNext()) // Runs once for every section { currentGroup = null;