sinmai-mods/MoreChartFormats/MaiSxt/SxtReaderBase.cs
2024-05-27 10:59:40 +07:00

95 lines
3.5 KiB
C#

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<int, SxtRow> 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();
}
}