Use Option instead of Result where applicable
This commit is contained in:
parent
5d3138ed2d
commit
8c8f954bbe
|
@ -3,7 +3,7 @@ use std::str::FromStr;
|
|||
|
||||
use anyhow::{anyhow, Result};
|
||||
use clap::Clap;
|
||||
use log::{debug, info, trace};
|
||||
use log::{debug, info, trace, warn};
|
||||
|
||||
use crate::ddr::ssq;
|
||||
use crate::osu::beatmap;
|
||||
|
@ -142,25 +142,25 @@ impl ShockStepGenerator {
|
|||
}
|
||||
}
|
||||
|
||||
fn get_time_from_beats(beats: f32, tempo_changes: &[ssq::TempoChange]) -> Result<i32> {
|
||||
fn get_time_from_beats(beats: f32, tempo_changes: &[ssq::TempoChange]) -> Option<i32> {
|
||||
for tempo_change in tempo_changes {
|
||||
// For TempoChanges that are infinitely short but exactly cover that beat, use the start
|
||||
// time of that TempoChange
|
||||
if (beats - tempo_change.start_beats).abs() < 0.001
|
||||
&& (beats - tempo_change.end_beats).abs() < 0.001
|
||||
{
|
||||
return Ok(tempo_change.start_ms);
|
||||
return Some(tempo_change.start_ms);
|
||||
}
|
||||
|
||||
if beats < tempo_change.end_beats {
|
||||
return Ok(tempo_change.start_ms
|
||||
+ ((beats - tempo_change.start_beats) * tempo_change.beat_length) as i32);
|
||||
return Some(
|
||||
tempo_change.start_ms
|
||||
+ ((beats - tempo_change.start_beats) * tempo_change.beat_length) as i32,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Err(anyhow!(
|
||||
"Conversion of Step to HitObject failed: Beat lies outside of TimingPoints range"
|
||||
))
|
||||
None
|
||||
}
|
||||
|
||||
impl From<ssq::TempoChange> for beatmap::TimingPoint {
|
||||
|
@ -191,69 +191,93 @@ impl ssq::Step {
|
|||
num_columns: u8,
|
||||
tempo_changes: &ssq::TempoChanges,
|
||||
shock_step_generator: &mut ShockStepGenerator,
|
||||
) -> Result<Vec<beatmap::HitObject>> {
|
||||
) -> Option<Vec<beatmap::HitObject>> {
|
||||
let mut hit_objects = Vec::new();
|
||||
|
||||
match self {
|
||||
ssq::Step::Step { beats, row } => {
|
||||
let time = get_time_from_beats(*beats, &tempo_changes.0)?;
|
||||
let time = get_time_from_beats(*beats, &tempo_changes.0);
|
||||
|
||||
let columns: Vec<bool> = row.clone().into();
|
||||
match time {
|
||||
Some(time) => {
|
||||
let columns: Vec<bool> = row.clone().into();
|
||||
|
||||
for (column, active) in columns.iter().enumerate() {
|
||||
if *active {
|
||||
hit_objects.push(beatmap::HitObject::HitCircle {
|
||||
x: beatmap::column_to_x(column as u8, num_columns),
|
||||
y: 192,
|
||||
time,
|
||||
hit_sound: beatmap::HitSound {
|
||||
normal: true,
|
||||
whistle: false,
|
||||
finish: false,
|
||||
clap: false,
|
||||
},
|
||||
new_combo: false,
|
||||
skip_combo_colours: 0,
|
||||
hit_sample: beatmap::HitSample {
|
||||
normal_set: 0,
|
||||
addition_set: 0,
|
||||
index: 0,
|
||||
volume: 0,
|
||||
filename: "".to_string(),
|
||||
},
|
||||
})
|
||||
for (column, active) in columns.iter().enumerate() {
|
||||
if *active {
|
||||
hit_objects.push(beatmap::HitObject::HitCircle {
|
||||
x: beatmap::column_to_x(column as u8, num_columns),
|
||||
y: 192,
|
||||
time,
|
||||
hit_sound: beatmap::HitSound {
|
||||
normal: true,
|
||||
whistle: false,
|
||||
finish: false,
|
||||
clap: false,
|
||||
},
|
||||
new_combo: false,
|
||||
skip_combo_colours: 0,
|
||||
hit_sample: beatmap::HitSample {
|
||||
normal_set: 0,
|
||||
addition_set: 0,
|
||||
index: 0,
|
||||
volume: 0,
|
||||
filename: "".to_string(),
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
None => {
|
||||
warn!("Could not get start time of step, skipping");
|
||||
return None;
|
||||
}
|
||||
}
|
||||
}
|
||||
ssq::Step::Freeze { start, end, row } => {
|
||||
let time = get_time_from_beats(*start, &tempo_changes.0)?;
|
||||
let end_time = get_time_from_beats(*end, &tempo_changes.0)?;
|
||||
let time = get_time_from_beats(*start, &tempo_changes.0);
|
||||
let end_time = get_time_from_beats(*end, &tempo_changes.0);
|
||||
|
||||
let columns: Vec<bool> = row.clone().into();
|
||||
match (time, end_time) {
|
||||
(Some(time), Some(end_time)) => {
|
||||
let columns: Vec<bool> = row.clone().into();
|
||||
|
||||
for (column, active) in columns.iter().enumerate() {
|
||||
if *active {
|
||||
hit_objects.push(beatmap::HitObject::Hold {
|
||||
column: column as u8,
|
||||
columns: num_columns,
|
||||
time,
|
||||
end_time,
|
||||
hit_sound: beatmap::HitSound {
|
||||
normal: true,
|
||||
whistle: false,
|
||||
finish: true,
|
||||
clap: false,
|
||||
},
|
||||
new_combo: false,
|
||||
skip_combo_colours: 0,
|
||||
hit_sample: beatmap::HitSample {
|
||||
normal_set: 0,
|
||||
addition_set: 0,
|
||||
index: 0,
|
||||
volume: 0,
|
||||
filename: "".to_string(),
|
||||
},
|
||||
})
|
||||
for (column, active) in columns.iter().enumerate() {
|
||||
if *active {
|
||||
hit_objects.push(beatmap::HitObject::Hold {
|
||||
column: column as u8,
|
||||
columns: num_columns,
|
||||
time,
|
||||
end_time,
|
||||
hit_sound: beatmap::HitSound {
|
||||
normal: true,
|
||||
whistle: false,
|
||||
finish: true,
|
||||
clap: false,
|
||||
},
|
||||
new_combo: false,
|
||||
skip_combo_colours: 0,
|
||||
hit_sample: beatmap::HitSample {
|
||||
normal_set: 0,
|
||||
addition_set: 0,
|
||||
index: 0,
|
||||
volume: 0,
|
||||
filename: "".to_string(),
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
(None, Some(_)) => {
|
||||
warn!("Could not get start time of freeze, skipping");
|
||||
return None;
|
||||
}
|
||||
(Some(_), None) => {
|
||||
warn!("Could not get end time of freeze, skipping");
|
||||
return None;
|
||||
}
|
||||
(None, None) => {
|
||||
warn!("Could not get start and end time of freeze, skipping");
|
||||
return None;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -288,7 +312,7 @@ impl ssq::Step {
|
|||
}
|
||||
}
|
||||
|
||||
Ok(hit_objects)
|
||||
Some(hit_objects)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -363,12 +387,13 @@ impl ssq::SSQ {
|
|||
ShockStepGenerator::new(chart.difficulty.players * 4, config.shock_action.clone());
|
||||
for step in &chart.steps.0 {
|
||||
trace!("Converting {:?} to hit object", step);
|
||||
let mut step_hit_objects = step.to_hit_objects(
|
||||
if let Some(mut step_hit_objects) = step.to_hit_objects(
|
||||
chart.difficulty.players * 4,
|
||||
&self.tempo_changes,
|
||||
&mut shock_step_generator,
|
||||
)?;
|
||||
hit_objects.0.append(&mut step_hit_objects);
|
||||
) {
|
||||
hit_objects.0.append(&mut step_hit_objects);
|
||||
}
|
||||
}
|
||||
|
||||
let converted_chart = ConvertedChart {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use std::convert::From;
|
||||
use std::fmt;
|
||||
|
||||
use anyhow::{anyhow, Result};
|
||||
use anyhow::Result;
|
||||
use log::{debug, info, trace, warn};
|
||||
use nom::bytes::complete::take;
|
||||
use nom::multi::many0;
|
||||
|
@ -126,27 +126,29 @@ impl Steps {
|
|||
continue;
|
||||
}
|
||||
|
||||
let last_step = match Self::find_last(Self(parsed_steps.clone()), &row) {
|
||||
Ok(last_step) => last_step,
|
||||
Err(err) => {
|
||||
warn!("Could not add freeze arrow: {}; adding normal step", err);
|
||||
parsed_steps.push(Step::Step { beats, row });
|
||||
continue;
|
||||
}
|
||||
};
|
||||
|
||||
if FREEZE {
|
||||
parsed_steps.push(Step::Freeze {
|
||||
start: if let Step::Step { beats, .. } = parsed_steps[last_step] {
|
||||
beats
|
||||
} else {
|
||||
unreachable!()
|
||||
},
|
||||
end: beats,
|
||||
row,
|
||||
});
|
||||
match Self::find_last(Self(parsed_steps.clone()), &row) {
|
||||
Some(last_step) => {
|
||||
parsed_steps.push(Step::Freeze {
|
||||
start: if let Step::Step { beats, .. } = parsed_steps[last_step]
|
||||
{
|
||||
beats
|
||||
} else {
|
||||
unreachable!()
|
||||
},
|
||||
end: beats,
|
||||
row,
|
||||
});
|
||||
|
||||
parsed_steps.remove(last_step);
|
||||
parsed_steps.remove(last_step);
|
||||
}
|
||||
None => {
|
||||
warn!(
|
||||
"Could not find previous step for freeze, adding normal step"
|
||||
);
|
||||
parsed_steps.push(Step::Step { beats, row });
|
||||
}
|
||||
}
|
||||
} else {
|
||||
trace!("Freeze disabled, adding normal step");
|
||||
parsed_steps.push(Step::Step { beats, row });
|
||||
|
@ -173,16 +175,16 @@ impl Steps {
|
|||
Ok((input, Self(parsed_steps)))
|
||||
}
|
||||
|
||||
fn find_last(steps: Self, row: &Row) -> Result<usize> {
|
||||
fn find_last(steps: Self, row: &Row) -> Option<usize> {
|
||||
for i in (0..steps.0.len()).rev() {
|
||||
if let Step::Step { row: step_row, .. } = &steps.0[i] {
|
||||
if step_row.clone().intersects(row.clone()) {
|
||||
return Ok(i);
|
||||
return Some(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Err(anyhow!("No previous step found on that column"))
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Reference in a new issue