[#mono-column] #circlefree mode accepts non-16ths notes and falls back to normal symbols when needed
This commit is contained in:
parent
9e0c4f5c2b
commit
857dd899a7
@ -1,4 +1,6 @@
|
||||
# Unreleased
|
||||
## Added
|
||||
- [#mono-column] #circlefree mode accepts non-16ths notes and falls back to normal symbols when needed
|
||||
## Fixed
|
||||
- [jubeat-analyser]
|
||||
- Raise exception earlier when a mono-column file is detected by the other #memo parsers (based on "--" separator lines)
|
||||
|
@ -31,6 +31,7 @@ from ..dump_tools import (
|
||||
DEFAULT_EXTRA_SYMBOLS,
|
||||
DIRECTION_TO_ARROW,
|
||||
DIRECTION_TO_LINE,
|
||||
NOTE_TO_CIRCLE_FREE_SYMBOL,
|
||||
JubeatAnalyserDumpedSection,
|
||||
LongNoteEnd,
|
||||
SortedDefaultDict,
|
||||
@ -38,7 +39,6 @@ from ..dump_tools import (
|
||||
fraction_to_decimal,
|
||||
jubeat_analyser_file_dumper,
|
||||
)
|
||||
from ..symbols import CIRCLE_FREE_SYMBOLS, NOTE_SYMBOLS
|
||||
|
||||
|
||||
class MonoColumnDumpedSection(JubeatAnalyserDumpedSection):
|
||||
@ -62,19 +62,18 @@ class MonoColumnDumpedSection(JubeatAnalyserDumpedSection):
|
||||
frames: List[Dict[NotePosition, str]] = []
|
||||
frame: Dict[NotePosition, str] = {}
|
||||
for note in self.notes:
|
||||
time_in_section = note.time - self.current_beat
|
||||
symbol = self.symbols[time_in_section]
|
||||
if isinstance(note, LongNote):
|
||||
needed_positions = set(note.positions_covered())
|
||||
if needed_positions & frame.keys():
|
||||
frames.append(frame)
|
||||
frame = {}
|
||||
|
||||
direction = note.tail_direction()
|
||||
arrow = DIRECTION_TO_ARROW[direction]
|
||||
line = DIRECTION_TO_LINE[direction]
|
||||
for is_first, is_last, pos in mark_ends(note.positions_covered()):
|
||||
if is_first:
|
||||
time_in_section = note.time - self.current_beat
|
||||
symbol = self.symbols[time_in_section]
|
||||
frame[pos] = symbol
|
||||
elif is_last:
|
||||
frame[pos] = arrow
|
||||
@ -84,18 +83,13 @@ class MonoColumnDumpedSection(JubeatAnalyserDumpedSection):
|
||||
if note.position in frame:
|
||||
frames.append(frame)
|
||||
frame = {}
|
||||
time_in_section = note.time - self.current_beat
|
||||
symbol = self.symbols[time_in_section]
|
||||
frame[note.position] = symbol
|
||||
elif isinstance(note, LongNoteEnd):
|
||||
if note.position in frame:
|
||||
frames.append(frame)
|
||||
frame = {}
|
||||
time_in_section = note.time - self.current_beat
|
||||
if circle_free:
|
||||
symbol = CIRCLE_FREE_SYMBOLS[int(time_in_section)]
|
||||
else:
|
||||
symbol = self.symbols[time_in_section]
|
||||
if circle_free and symbol in NOTE_TO_CIRCLE_FREE_SYMBOL:
|
||||
symbol = NOTE_TO_CIRCLE_FREE_SYMBOL[symbol]
|
||||
frame[note.position] = symbol
|
||||
|
||||
frames.append(frame)
|
||||
@ -108,9 +102,7 @@ class MonoColumnDumpedSection(JubeatAnalyserDumpedSection):
|
||||
yield "".join(frame.get(NotePosition(x, y), "□") for x in range(4))
|
||||
|
||||
|
||||
def _raise_if_unfit_for_mono_column(
|
||||
chart: Chart, timing: Timing, circle_free: bool = False
|
||||
) -> None:
|
||||
def _raise_if_unfit_for_mono_column(chart: Chart, timing: Timing) -> None:
|
||||
if len(timing.events) < 1:
|
||||
raise ValueError("No BPM found in file") from None
|
||||
|
||||
@ -128,16 +120,6 @@ def _raise_if_unfit_for_mono_column(
|
||||
" mono_column format is not supported by jubeatools"
|
||||
)
|
||||
|
||||
if circle_free and any(
|
||||
(note.time + note.duration) % BeatsTime(1, 4) != 0
|
||||
for note in chart.notes
|
||||
if isinstance(note, LongNote)
|
||||
):
|
||||
raise ValueError(
|
||||
"Chart contains long notes whose ending timing aren't"
|
||||
" representable in #circlefree mode"
|
||||
)
|
||||
|
||||
|
||||
def _section_factory(b: BeatsTime) -> MonoColumnDumpedSection:
|
||||
return MonoColumnDumpedSection(current_beat=b)
|
||||
@ -151,7 +133,7 @@ def _dump_mono_column_chart(
|
||||
circle_free: bool = False,
|
||||
) -> StringIO:
|
||||
|
||||
_raise_if_unfit_for_mono_column(chart, timing, circle_free)
|
||||
_raise_if_unfit_for_mono_column(chart, timing)
|
||||
|
||||
sections = create_sections_from_chart(
|
||||
_section_factory, chart, difficulty, timing, metadata, circle_free
|
||||
|
@ -188,24 +188,16 @@ class MonoColumnParser(JubeatAnalyserParser):
|
||||
unfinished_longs: Dict[NotePosition, UnfinishedLongNote] = {}
|
||||
for section_starting_beat, section, bloc in self._iter_blocs():
|
||||
should_skip: Set[NotePosition] = set()
|
||||
|
||||
# 1/3 : look for ends to unfinished long notes
|
||||
for pos, unfinished_long in unfinished_longs.items():
|
||||
x, y = astuple(pos)
|
||||
symbol = bloc[y][x]
|
||||
if self.circle_free:
|
||||
if symbol in CIRCLE_FREE_SYMBOLS:
|
||||
if self.circle_free and symbol in CIRCLE_FREE_SYMBOLS:
|
||||
should_skip.add(pos)
|
||||
symbol_time = CIRCLE_FREE_TO_BEATS_TIME[symbol]
|
||||
note_time = section_starting_beat + symbol_time
|
||||
yield unfinished_long.ends_at(note_time)
|
||||
elif symbol in section.symbols:
|
||||
raise SyntaxError(
|
||||
"Can't have a note symbol on the holding square of"
|
||||
" an unfinished long note when #circlefree is on"
|
||||
)
|
||||
else:
|
||||
if symbol in section.symbols:
|
||||
should_skip.add(pos)
|
||||
symbol_time = section.symbols[symbol]
|
||||
note_time = section_starting_beat + symbol_time
|
||||
|
@ -2,9 +2,8 @@ from typing import Iterable, Union
|
||||
|
||||
import pytest
|
||||
|
||||
from jubeatools.song import BeatsTime, LongNote, NotePosition, TapNote
|
||||
|
||||
from jubeatools.formats.jubeat_analyser.mono_column.load import MonoColumnParser
|
||||
from jubeatools.song import BeatsTime, LongNote, NotePosition, TapNote
|
||||
|
||||
|
||||
def compare_chart_notes(
|
||||
|
@ -5,6 +5,9 @@ from typing import List, Set, Union
|
||||
import hypothesis.strategies as st
|
||||
from hypothesis import given
|
||||
|
||||
from jubeatools.formats import Format
|
||||
from jubeatools.formats.jubeat_analyser.mono_column.dump import _dump_mono_column_chart
|
||||
from jubeatools.formats.jubeat_analyser.mono_column.load import MonoColumnParser
|
||||
from jubeatools.song import (
|
||||
BeatsTime,
|
||||
BPMEvent,
|
||||
@ -12,19 +15,14 @@ from jubeatools.song import (
|
||||
LongNote,
|
||||
Metadata,
|
||||
SecondsTime,
|
||||
Song,
|
||||
TapNote,
|
||||
Timing,
|
||||
Song
|
||||
)
|
||||
from jubeatools.testutils.strategies import NoteOption, long_note
|
||||
from jubeatools.testutils.strategies import notes as notes_strat
|
||||
from jubeatools.testutils.strategies import tap_note
|
||||
|
||||
from jubeatools.formats import Format
|
||||
from jubeatools.formats.jubeat_analyser.mono_column.dump import _dump_mono_column_chart
|
||||
from jubeatools.formats.jubeat_analyser.mono_column.load import MonoColumnParser
|
||||
|
||||
|
||||
from ..test_utils import load_and_dump_then_check, memo_compatible_song
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user