parsers.py
: Refactor current_branch == 'all'
logic
Fumens require that all branches have the same length, even when branching isn't relevant (i.e. at the start of the song before the first BRANCHSTART, or after a BRANCHEND). So, in the past, I simply duplicated the note data across all branches. However, this causes a bug when balloon notes are duplicated; we get extra reads of the BALLOON: field, and the values get mis-attributed. So, we need to be able to modify this "dummy" note data before it gets duplicated. To do that, we need to rework the 'current_branch == 'all'` logic to separate out the note data writes for the other branches, so that we can modify them in-place.
This commit is contained in:
parent
8e8332cd2b
commit
34428bbbe7
@ -207,7 +207,8 @@ def parse_tja_course_data(data: List[str]) -> Dict[str, List[TJAMeasure]]:
|
|||||||
"""
|
"""
|
||||||
parsed_branches = {k: [TJAMeasure()] for k in BRANCH_NAMES}
|
parsed_branches = {k: [TJAMeasure()] for k in BRANCH_NAMES}
|
||||||
has_branches = bool([d for d in data if d.startswith('#BRANCH')])
|
has_branches = bool([d for d in data if d.startswith('#BRANCH')])
|
||||||
current_branch = 'all' if has_branches else 'normal'
|
current_branch = 'normal'
|
||||||
|
add_dummy_notes_to_other_branches = has_branches
|
||||||
branch_condition = ''
|
branch_condition = ''
|
||||||
|
|
||||||
# Process course lines
|
# Process course lines
|
||||||
@ -229,18 +230,28 @@ def parse_tja_course_data(data: List[str]) -> Dict[str, List[TJAMeasure]]:
|
|||||||
# If measure has ended, then add notes to the current measure,
|
# If measure has ended, then add notes to the current measure,
|
||||||
# then start a new measure by incrementing idx_m
|
# then start a new measure by incrementing idx_m
|
||||||
if note_data.endswith(','):
|
if note_data.endswith(','):
|
||||||
for branch_name in (BRANCH_NAMES if current_branch == 'all'
|
check_branch_length(parsed_branches, current_branch, expected_len=idx_m+1)
|
||||||
else [current_branch]):
|
parsed_branches[current_branch][idx_m].notes += note_data[:-1]
|
||||||
|
parsed_branches[current_branch].append(TJAMeasure())
|
||||||
|
# Repeat steps for other branches if we only have info for a single branch
|
||||||
|
if add_dummy_notes_to_other_branches:
|
||||||
|
other_branches = list(set(BRANCH_NAMES) - set([current_branch]))
|
||||||
|
for branch_name in other_branches:
|
||||||
check_branch_length(parsed_branches, branch_name,
|
check_branch_length(parsed_branches, branch_name,
|
||||||
expected_len=idx_m+1)
|
expected_len=idx_m+1)
|
||||||
parsed_branches[branch_name][idx_m].notes += note_data[:-1]
|
dummy_data = note_data[:-1]
|
||||||
|
parsed_branches[branch_name][idx_m].notes += dummy_data
|
||||||
parsed_branches[branch_name].append(TJAMeasure())
|
parsed_branches[branch_name].append(TJAMeasure())
|
||||||
idx_m += 1
|
idx_m += 1
|
||||||
# Otherwise, keep adding notes to the current measure ('idx_m')
|
# Otherwise, keep adding notes to the current measure ('idx_m')
|
||||||
else:
|
else:
|
||||||
for branch_name in (BRANCH_NAMES if current_branch == 'all'
|
parsed_branches[current_branch][idx_m].notes += note_data
|
||||||
else [current_branch]):
|
# Repeat steps for other branches if we only have info for a single branch
|
||||||
parsed_branches[branch_name][idx_m].notes += note_data
|
if add_dummy_notes_to_other_branches:
|
||||||
|
other_branches = list(set(BRANCH_NAMES) - set([current_branch]))
|
||||||
|
for branch_name in other_branches:
|
||||||
|
dummy_data = note_data
|
||||||
|
parsed_branches[branch_name][idx_m].notes += dummy_data
|
||||||
|
|
||||||
# 2. Parse measure commands that produce an "event"
|
# 2. Parse measure commands that produce an "event"
|
||||||
elif command in ['GOGOSTART', 'GOGOEND', 'BARLINEON', 'BARLINEOFF',
|
elif command in ['GOGOSTART', 'GOGOEND', 'BARLINEON', 'BARLINEOFF',
|
||||||
@ -248,7 +259,7 @@ def parse_tja_course_data(data: List[str]) -> Dict[str, List[TJAMeasure]]:
|
|||||||
'LEVELHOLD', 'SECTION', 'BRANCHSTART']:
|
'LEVELHOLD', 'SECTION', 'BRANCHSTART']:
|
||||||
# Get position of the event
|
# Get position of the event
|
||||||
pos = 0
|
pos = 0
|
||||||
for branch_name in (BRANCH_NAMES if current_branch == 'all'
|
for branch_name in (BRANCH_NAMES if add_dummy_notes_to_other_branches
|
||||||
else [current_branch]):
|
else [current_branch]):
|
||||||
check_branch_length(parsed_branches, branch_name,
|
check_branch_length(parsed_branches, branch_name,
|
||||||
expected_len=idx_m+1)
|
expected_len=idx_m+1)
|
||||||
@ -280,17 +291,17 @@ def parse_tja_course_data(data: List[str]) -> Dict[str, List[TJAMeasure]]:
|
|||||||
# values won't be correctly set for the other two branches.
|
# values won't be correctly set for the other two branches.
|
||||||
if data[idx_l+1].startswith('#BRANCHSTART'):
|
if data[idx_l+1].startswith('#BRANCHSTART'):
|
||||||
name = 'section'
|
name = 'section'
|
||||||
current_branch = 'all'
|
add_dummy_notes_to_other_branches = True
|
||||||
elif not branch_condition:
|
elif not branch_condition:
|
||||||
name = 'section'
|
name = 'section'
|
||||||
current_branch = 'all'
|
add_dummy_notes_to_other_branches = True
|
||||||
# Otherwise, #SECTION exists in isolation. In this case, to
|
# Otherwise, #SECTION exists in isolation. In this case, to
|
||||||
# reset the accuracy, we just repeat the previous #BRANCHSTART.
|
# reset the accuracy, we just repeat the previous #BRANCHSTART.
|
||||||
else:
|
else:
|
||||||
name, value = 'branch_start', branch_condition
|
name, value = 'branch_start', branch_condition
|
||||||
elif command == 'BRANCHSTART':
|
elif command == 'BRANCHSTART':
|
||||||
# Ensure that the #BRANCHSTART command is added to all branches
|
# Ensure that the #BRANCHSTART command is added to all branches
|
||||||
current_branch = 'all'
|
add_dummy_notes_to_other_branches = True
|
||||||
name = 'branch_start'
|
name = 'branch_start'
|
||||||
branch_condition = value
|
branch_condition = value
|
||||||
# If a branch was intentionally excluded by the charter,
|
# If a branch was intentionally excluded by the charter,
|
||||||
@ -301,7 +312,7 @@ def parse_tja_course_data(data: List[str]) -> Dict[str, List[TJAMeasure]]:
|
|||||||
idx_m_branchstart = idx_m
|
idx_m_branchstart = idx_m
|
||||||
|
|
||||||
# Append event to the current measure's events
|
# Append event to the current measure's events
|
||||||
for branch_name in (BRANCH_NAMES if current_branch == 'all'
|
for branch_name in (BRANCH_NAMES if add_dummy_notes_to_other_branches
|
||||||
else [current_branch]):
|
else [current_branch]):
|
||||||
check_branch_length(parsed_branches, branch_name,
|
check_branch_length(parsed_branches, branch_name,
|
||||||
expected_len=idx_m+1)
|
expected_len=idx_m+1)
|
||||||
@ -313,18 +324,23 @@ def parse_tja_course_data(data: List[str]) -> Dict[str, List[TJAMeasure]]:
|
|||||||
# (e.g. simply changing the current branch)
|
# (e.g. simply changing the current branch)
|
||||||
else:
|
else:
|
||||||
if command in ('START', 'END'):
|
if command in ('START', 'END'):
|
||||||
current_branch = 'all' if has_branches else 'normal'
|
current_branch = 'normal'
|
||||||
|
add_dummy_notes_to_other_branches = has_branches
|
||||||
elif command == 'N':
|
elif command == 'N':
|
||||||
current_branch = 'normal'
|
current_branch = 'normal'
|
||||||
|
add_dummy_notes_to_other_branches = False
|
||||||
idx_m = idx_m_branchstart
|
idx_m = idx_m_branchstart
|
||||||
elif command == 'E':
|
elif command == 'E':
|
||||||
current_branch = 'professional'
|
current_branch = 'professional'
|
||||||
|
add_dummy_notes_to_other_branches = False
|
||||||
idx_m = idx_m_branchstart
|
idx_m = idx_m_branchstart
|
||||||
elif command == 'M':
|
elif command == 'M':
|
||||||
current_branch = 'master'
|
current_branch = 'master'
|
||||||
|
add_dummy_notes_to_other_branches = False
|
||||||
idx_m = idx_m_branchstart
|
idx_m = idx_m_branchstart
|
||||||
elif command == 'BRANCHEND':
|
elif command == 'BRANCHEND':
|
||||||
current_branch = 'all'
|
current_branch = 'normal'
|
||||||
|
add_dummy_notes_to_other_branches = True
|
||||||
|
|
||||||
else:
|
else:
|
||||||
warnings.warn(f"Ignoring unsupported command '{command}'")
|
warnings.warn(f"Ignoring unsupported command '{command}'")
|
||||||
|
Loading…
Reference in New Issue
Block a user