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

91 lines
3.1 KiB
C#

using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using Manager;
using MoreChartFormats.Simai.Errors;
using MoreChartFormats.Simai.LexicalAnalysis;
using MoreChartFormats.Simai.Structures;
using MoreChartFormats.Simai.SyntacticAnalysis;
namespace MoreChartFormats.Simai;
public class SimaiReader
{
public static List<Token> Tokenize(string value)
{
return new Tokenizer(value).GetTokens().ToList();
}
public static void Deserialize(IEnumerable<Token> tokens, NotesReferences refs)
{
new Deserializer(tokens).GetChart(refs);
}
public static void ReadBpmChanges(IEnumerable<Token> tokens, NotesReferences refs)
{
var currentTime = new NotesTime();
var subdivision = 4f;
var deltaGrids = 0f;
var nr = refs.Reader;
var header = refs.Header;
var composition = refs.Composition;
foreach (var token in tokens)
{
switch (token.type)
{
case TokenType.Tempo:
{
var deltaBars = deltaGrids / header._resolutionTime;
var bar = (int)deltaBars;
var grid = (int)((deltaBars - bar) * header._resolutionTime);
currentTime += new NotesTime(bar, grid, nr);
deltaGrids -= bar * header._resolutionTime + grid;
var bpmChangeData = new BPMChangeData();
bpmChangeData.time.copy(currentTime);
if (!float.TryParse(token.lexeme, NumberStyles.Any, CultureInfo.InvariantCulture,
out bpmChangeData.bpm))
{
throw new UnexpectedCharacterException(token.line, token.character, "0-9 or \".\"");
}
composition._bpmList.Add(bpmChangeData);
break;
}
case TokenType.Subdivision:
{
if (token.lexeme[0] == '#')
{
throw new UnsupportedSyntaxException(token.line, token.character);
}
if (!float.TryParse(token.lexeme, NumberStyles.Any, CultureInfo.InvariantCulture, out subdivision))
{
throw new UnexpectedCharacterException(token.line, token.character, "0-9 or \".\"");
}
break;
}
case TokenType.TimeStep:
{
deltaGrids += header._resolutionTime / subdivision;
break;
}
default:
continue;
}
}
if (composition._bpmList.Count == 0)
{
var dummyBpmChange = new BPMChangeData { bpm = ReaderConst.DEFAULT_BPM };
dummyBpmChange.time.init(0, 0, nr);
composition._bpmList.Add(dummyBpmChange);
}
}
}