using System; using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Runtime.CompilerServices; using Manager; using MoreChartFormats.MaiSxt.Structures; using MoreChartFormats.Simai.Structures; namespace MoreChartFormats.MaiSxt; public abstract class SxtReaderBase(NotesReferences refs) { protected readonly NotesReferences Refs = refs; protected int NoteIndex; protected readonly Dictionary SlideHeads = new(); public void Deserialize(string content) { var table = GetSxtTable(content); for (var rowIdx = 0; rowIdx < table.Length; rowIdx++) { var row = ParseRow(rowIdx, table[rowIdx]); LoadRow(rowIdx, in row); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] protected abstract void LoadRow(int rowIdx, in SxtRow row); private static SxtRow ParseRow(int rowIdx, string[] row) { var srtRow = new SxtRow(); if (!float.TryParse(row[0], NumberStyles.Float, CultureInfo.InvariantCulture, out srtRow.Bar)) { throw new Exception($"Invalid whole measure at row {rowIdx}: {row[0]}"); } if (!float.TryParse(row[1], NumberStyles.Float, CultureInfo.InvariantCulture, out srtRow.Grid)) { throw new Exception($"Invalid fractional measure at row {rowIdx}: {row[1]}"); } if (!float.TryParse(row[2], NumberStyles.Float, CultureInfo.InvariantCulture, out srtRow.HoldDuration)) { throw new Exception($"Invalid hold duration at row {rowIdx}: {row[2]}"); } if (!int.TryParse(row[3], NumberStyles.Integer, CultureInfo.InvariantCulture, out srtRow.Position)) { throw new Exception($"Invalid position at row {rowIdx}: {row[3]}"); } if (!int.TryParse(row[4], NumberStyles.Integer, CultureInfo.InvariantCulture, out srtRow.NoteType)) { throw new Exception($"Invalid note type ID at row {rowIdx}: {row[4]}"); } if (!int.TryParse(row[5], NumberStyles.Integer, CultureInfo.InvariantCulture, out srtRow.SlideId)) { throw new Exception($"Invalid slide ID at row {rowIdx}: {row[5]}"); } if (!int.TryParse(row[6], NumberStyles.Integer, CultureInfo.InvariantCulture, out srtRow.SlidePattern)) { throw new Exception($"Invalid slide type at row {rowIdx}: {row[6]}"); } // if (row.Length > 7 && !int.TryParse(row[7], NumberStyles.Integer, CultureInfo.InvariantCulture, // out srtRow.SlideCount)) // { // throw new Exception($"Invalid slide count at row {rowIdx}: {row[7]}"); // } if (row.Length > 8) { if (!float.TryParse(row[8], NumberStyles.Float, CultureInfo.InvariantCulture, out var slideDelay)) throw new Exception($"Invalid slide delay at row {rowIdx}: {row[8]}"); srtRow.SlideDelay = slideDelay; } return srtRow; } private static string[][] GetSxtTable(string content) { return content.Split(["\n", "\r\n"], StringSplitOptions.RemoveEmptyEntries) .Select(r => r.Split([","], StringSplitOptions.RemoveEmptyEntries).Select(s => s.Trim()).Where(s => s.Length > 0).ToArray()) .ToArray(); } }