Code Style
This commit is contained in:
parent
990b06056a
commit
7732ed1ac1
@ -8,7 +8,16 @@ from path import Path
|
||||
|
||||
from jubeatools.song import Song
|
||||
|
||||
from .jubeat_analyser.mono_column import dump_mono_column, load_mono_column
|
||||
from .jubeat_analyser import (
|
||||
dump_memo,
|
||||
dump_memo1,
|
||||
dump_memo2,
|
||||
dump_mono_column,
|
||||
load_memo,
|
||||
load_memo1,
|
||||
load_memo2,
|
||||
load_mono_column,
|
||||
)
|
||||
from .memon import (
|
||||
dump_memon_0_1_0,
|
||||
dump_memon_0_2_0,
|
||||
@ -24,6 +33,9 @@ class Format(str, Enum):
|
||||
MEMON_0_1_0 = "memon:v0.1.0"
|
||||
MEMON_0_2_0 = "memon:v0.2.0"
|
||||
MONO_COLUMN = "mono-column"
|
||||
MEMO = "memo"
|
||||
MEMO_1 = "memo1"
|
||||
MEMO_2 = "memo2"
|
||||
|
||||
|
||||
# Loaders deserialize a Path to a Song object
|
||||
@ -33,6 +45,9 @@ LOADERS: Dict[Format, Callable[[Path], Song]] = {
|
||||
Format.MEMON_0_1_0: load_memon_0_1_0,
|
||||
Format.MEMON_0_2_0: load_memon_0_2_0,
|
||||
Format.MONO_COLUMN: load_mono_column,
|
||||
Format.MEMO: load_memo,
|
||||
Format.MEMO_1: load_memo1,
|
||||
Format.MEMO_2: load_memo2,
|
||||
}
|
||||
|
||||
DUMPERS: Dict[str, Callable[[Song], Dict[str, IO]]] = {
|
||||
@ -40,4 +55,7 @@ DUMPERS: Dict[str, Callable[[Song], Dict[str, IO]]] = {
|
||||
Format.MEMON_0_1_0: dump_memon_0_1_0,
|
||||
Format.MEMON_0_2_0: dump_memon_0_2_0,
|
||||
Format.MONO_COLUMN: dump_mono_column,
|
||||
Format.MEMO: dump_memo,
|
||||
Format.MEMO_1: dump_memo1,
|
||||
Format.MEMO_2: dump_memo2,
|
||||
}
|
||||
|
@ -11,6 +11,10 @@ on these pages :
|
||||
- http://yosh52.web.fc2.com/jubeat/holdmarker.html
|
||||
"""
|
||||
|
||||
from .memo1.dump import dump_memo1
|
||||
from .memo1.load import load_memo1
|
||||
from .memo2.dump import dump_memo2
|
||||
from .memo2.load import load_memo2
|
||||
from .memo.dump import dump_memo
|
||||
from .memo.load import load_memo
|
||||
from .mono_column.dump import dump_mono_column
|
||||
|
@ -273,16 +273,16 @@ class JubeatAnalyserParser:
|
||||
method(value)
|
||||
else:
|
||||
method()
|
||||
|
||||
|
||||
def do_b(self, value):
|
||||
self.beats_per_section = Decimal(value)
|
||||
|
||||
def do_m(self, value):
|
||||
self.music = value
|
||||
|
||||
|
||||
def do_o(self, value):
|
||||
self.offset = int(value)
|
||||
|
||||
|
||||
def do_r(self, value):
|
||||
self.offset += int(value)
|
||||
|
||||
|
@ -9,4 +9,4 @@ A chart in this format needs to have a `#memo2` line somewhere to indicate its f
|
||||
"""
|
||||
|
||||
from .dump import dump_memo2
|
||||
from .load import load_memo2
|
||||
from .load import load_memo2
|
||||
|
@ -16,13 +16,13 @@ from sortedcontainers import SortedKeyList
|
||||
from jubeatools import __version__
|
||||
from jubeatools.formats.filetypes import ChartFile, JubeatFile
|
||||
from jubeatools.song import (
|
||||
BPMEvent,
|
||||
SecondsTime,
|
||||
BeatsTime,
|
||||
BPMEvent,
|
||||
Chart,
|
||||
LongNote,
|
||||
Metadata,
|
||||
NotePosition,
|
||||
SecondsTime,
|
||||
Song,
|
||||
TapNote,
|
||||
Timing,
|
||||
@ -93,6 +93,7 @@ class StopEvent:
|
||||
@dataclass
|
||||
class Memo2Section:
|
||||
"""A 4-beat-long group of notes"""
|
||||
|
||||
notes: List[AnyNote] = field(default_factory=list)
|
||||
events: List[Union[BPMEvent, StopEvent]] = field(default_factory=list)
|
||||
|
||||
@ -121,11 +122,13 @@ class Memo2Section:
|
||||
events = events_by_bar.get(bar_index, [])
|
||||
bar_length = lcm(
|
||||
*(note.time.denominator for note in notes),
|
||||
*(event.time.denominator for event in events)
|
||||
*(event.time.denominator for event in events),
|
||||
)
|
||||
if bar_length < 3:
|
||||
bar_length = 4
|
||||
bar_dict: Dict[int, List[Union[str, BPMEvent, StopEvent]]] = defaultdict(list)
|
||||
bar_dict: Dict[int, List[Union[str, BPMEvent, StopEvent]]] = defaultdict(
|
||||
list
|
||||
)
|
||||
for note in notes:
|
||||
time_in_section = note.time % BeatsTime(4)
|
||||
time_in_bar = note.time % Fraction(1)
|
||||
@ -145,7 +148,9 @@ class Memo2Section:
|
||||
bar = []
|
||||
for i in range(bar_length):
|
||||
events_and_note = bar_dict.get(i, [])
|
||||
stops = list(filter(lambda e: isinstance(e, StopEvent), events_and_note))
|
||||
stops = list(
|
||||
filter(lambda e: isinstance(e, StopEvent), events_and_note)
|
||||
)
|
||||
bpms = list(filter(lambda e: isinstance(e, BPMEvent), events_and_note))
|
||||
notes = list(filter(lambda e: isinstance(e, str), events_and_note))
|
||||
assert len(notes) <= 1
|
||||
@ -154,12 +159,12 @@ class Memo2Section:
|
||||
|
||||
for bpm in bpms:
|
||||
bar.append(f"({bpm.BPM})")
|
||||
|
||||
|
||||
if notes:
|
||||
note = notes[0]
|
||||
else:
|
||||
note = EMPTY_BEAT_SYMBOL
|
||||
|
||||
|
||||
bar.append(note)
|
||||
|
||||
bars[bar_index] = bar
|
||||
@ -230,6 +235,7 @@ class Memo2Section:
|
||||
dumped_frames = map(lambda f: f.dump(), final_frames)
|
||||
yield from collapse(intersperse("", dumped_frames))
|
||||
|
||||
|
||||
def _raise_if_unfit_for_memo2(chart: Chart, timing: Timing, circle_free: bool = False):
|
||||
if len(timing.events) < 1:
|
||||
raise ValueError("No BPM found in file") from None
|
||||
@ -311,7 +317,7 @@ def _dump_memo2_chart(
|
||||
|
||||
if circle_free:
|
||||
file.write(dump_command("circlefree", 1) + "\n")
|
||||
|
||||
|
||||
file.write(dump_command("memo2") + "\n")
|
||||
|
||||
# Notes
|
||||
|
@ -75,6 +75,7 @@ class BPM:
|
||||
|
||||
Event = Union[Notes, Stop, BPM]
|
||||
|
||||
|
||||
@dataclass
|
||||
class RawMemo2ChartLine:
|
||||
position: str
|
||||
@ -86,12 +87,15 @@ class RawMemo2ChartLine:
|
||||
else:
|
||||
return self.position
|
||||
|
||||
|
||||
@dataclass
|
||||
class Memo2ChartLine:
|
||||
"""timing part only contains notes"""
|
||||
|
||||
position: str
|
||||
timing: Optional[List[str]]
|
||||
|
||||
|
||||
memo2_chart_line_grammar = Grammar(
|
||||
r"""
|
||||
line = ws position_part ws (timing_part ws)? comment?
|
||||
@ -148,9 +152,8 @@ def is_memo2_chart_line(line: str) -> bool:
|
||||
|
||||
|
||||
def parse_memo2_chart_line(line: str) -> RawMemo2ChartLine:
|
||||
return Memo2ChartLineVisitor().visit(
|
||||
memo2_chart_line_grammar.parse(line)
|
||||
)
|
||||
return Memo2ChartLineVisitor().visit(memo2_chart_line_grammar.parse(line))
|
||||
|
||||
|
||||
@dataclass
|
||||
class Memo2Frame:
|
||||
@ -177,12 +180,12 @@ class Memo2Parser(JubeatAnalyserParser):
|
||||
self.offset = None
|
||||
self.current_beat = BeatsTime(0)
|
||||
self.frames: List[Memo2Frame] = []
|
||||
|
||||
|
||||
def do_b(self, value):
|
||||
raise ValueError(
|
||||
"beat command (b=...) found, this commands cannot be used in #memo2 files"
|
||||
)
|
||||
|
||||
|
||||
def do_t(self, value):
|
||||
if self.frames:
|
||||
raise ValueError(
|
||||
@ -190,9 +193,7 @@ class Memo2Parser(JubeatAnalyserParser):
|
||||
"this should not happen in #memo2 files"
|
||||
)
|
||||
else:
|
||||
self.timing_events.append(
|
||||
BPMEvent(self.current_beat, BPM=Decimal(value))
|
||||
)
|
||||
self.timing_events.append(BPMEvent(self.current_beat, BPM=Decimal(value)))
|
||||
|
||||
def do_r(self, value):
|
||||
if self.frames:
|
||||
@ -207,7 +208,7 @@ class Memo2Parser(JubeatAnalyserParser):
|
||||
|
||||
def do_memo(self):
|
||||
raise ValueError("#memo command found : This is not a memo2 file")
|
||||
|
||||
|
||||
def do_memo1(self):
|
||||
raise ValueError("#memo1 command found : This is not a memo2 file")
|
||||
|
||||
@ -255,13 +256,10 @@ class Memo2Parser(JubeatAnalyserParser):
|
||||
in_bar_beat += symbol_duration
|
||||
elif isinstance(event, BPM):
|
||||
self.timing_events.append(
|
||||
BPMEvent(
|
||||
time=self.current_beat+in_bar_beat,
|
||||
BPM=event.value
|
||||
)
|
||||
BPMEvent(time=self.current_beat + in_bar_beat, BPM=event.value)
|
||||
)
|
||||
elif isinstance(event, Stop):
|
||||
time = self.current_beat+in_bar_beat
|
||||
time = self.current_beat + in_bar_beat
|
||||
if time != 0:
|
||||
raise ValueError(
|
||||
"Chart contains a pause that's not happening at the "
|
||||
@ -274,7 +272,7 @@ class Memo2Parser(JubeatAnalyserParser):
|
||||
# beat of the chart or if both an in-bar pause and an
|
||||
# o=... command exist
|
||||
self.offset += event.duration
|
||||
|
||||
|
||||
bar_notes = [e for e in bar if isinstance(e, str)]
|
||||
line = Memo2ChartLine(raw_line.position, bar_notes)
|
||||
|
||||
@ -338,9 +336,7 @@ class Memo2Parser(JubeatAnalyserParser):
|
||||
|
||||
def _iter_frames(
|
||||
self,
|
||||
) -> Iterator[
|
||||
Tuple[Mapping[str, BeatsTime], Memo2Frame, BeatsTime]
|
||||
]:
|
||||
) -> Iterator[Tuple[Mapping[str, BeatsTime], Memo2Frame, BeatsTime]]:
|
||||
"""iterate over tuples of (currently_defined_symbols, frame)"""
|
||||
local_symbols: Dict[str, Decimal] = {}
|
||||
frame_starting_beat = BeatsTime(0)
|
||||
@ -348,7 +344,9 @@ class Memo2Parser(JubeatAnalyserParser):
|
||||
if frame.timing_part:
|
||||
frame_starting_beat = sum(f.duration for f in self.frames[:i])
|
||||
local_symbols = {
|
||||
symbol: frame_starting_beat + bar_index + BeatsTime(symbol_index, len(bar))
|
||||
symbol: frame_starting_beat
|
||||
+ bar_index
|
||||
+ BeatsTime(symbol_index, len(bar))
|
||||
for bar_index, bar in enumerate(frame.timing_part)
|
||||
for symbol_index, symbol in enumerate(bar)
|
||||
if symbol not in EMPTY_BEAT_SYMBOLS
|
||||
|
@ -15,4 +15,4 @@ def lcm(*args):
|
||||
|
||||
def charinfo(c: str) -> str:
|
||||
"""Return some info on the character"""
|
||||
return f"{c!r} # U+{ord(c):05X} : {unicodedata.name(c)}"
|
||||
return f"{c!r} # U+{ord(c):05X} : {unicodedata.name(c)}"
|
||||
|
Loading…
Reference in New Issue
Block a user