Use Option instead of Result where applicable

This commit is contained in:
Simon Bruder 2020-06-25 13:25:47 +02:00
parent 5d3138ed2d
commit 8c8f954bbe
No known key found for this signature in database
GPG key ID: 6F03E0000CC5B62F
2 changed files with 113 additions and 86 deletions

View file

@ -3,7 +3,7 @@ use std::str::FromStr;
use anyhow::{anyhow, Result}; use anyhow::{anyhow, Result};
use clap::Clap; use clap::Clap;
use log::{debug, info, trace}; use log::{debug, info, trace, warn};
use crate::ddr::ssq; use crate::ddr::ssq;
use crate::osu::beatmap; 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 tempo_change in tempo_changes {
// For TempoChanges that are infinitely short but exactly cover that beat, use the start // For TempoChanges that are infinitely short but exactly cover that beat, use the start
// time of that TempoChange // time of that TempoChange
if (beats - tempo_change.start_beats).abs() < 0.001 if (beats - tempo_change.start_beats).abs() < 0.001
&& (beats - tempo_change.end_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 { if beats < tempo_change.end_beats {
return Ok(tempo_change.start_ms return Some(
+ ((beats - tempo_change.start_beats) * tempo_change.beat_length) as i32); tempo_change.start_ms
+ ((beats - tempo_change.start_beats) * tempo_change.beat_length) as i32,
);
} }
} }
Err(anyhow!( None
"Conversion of Step to HitObject failed: Beat lies outside of TimingPoints range"
))
} }
impl From<ssq::TempoChange> for beatmap::TimingPoint { impl From<ssq::TempoChange> for beatmap::TimingPoint {
@ -191,13 +191,15 @@ impl ssq::Step {
num_columns: u8, num_columns: u8,
tempo_changes: &ssq::TempoChanges, tempo_changes: &ssq::TempoChanges,
shock_step_generator: &mut ShockStepGenerator, shock_step_generator: &mut ShockStepGenerator,
) -> Result<Vec<beatmap::HitObject>> { ) -> Option<Vec<beatmap::HitObject>> {
let mut hit_objects = Vec::new(); let mut hit_objects = Vec::new();
match self { match self {
ssq::Step::Step { beats, row } => { 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);
match time {
Some(time) => {
let columns: Vec<bool> = row.clone().into(); let columns: Vec<bool> = row.clone().into();
for (column, active) in columns.iter().enumerate() { for (column, active) in columns.iter().enumerate() {
@ -225,10 +227,18 @@ impl ssq::Step {
} }
} }
} }
None => {
warn!("Could not get start time of step, skipping");
return None;
}
}
}
ssq::Step::Freeze { start, end, row } => { ssq::Step::Freeze { start, end, row } => {
let time = get_time_from_beats(*start, &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 end_time = get_time_from_beats(*end, &tempo_changes.0);
match (time, end_time) {
(Some(time), Some(end_time)) => {
let columns: Vec<bool> = row.clone().into(); let columns: Vec<bool> = row.clone().into();
for (column, active) in columns.iter().enumerate() { for (column, active) in columns.iter().enumerate() {
@ -257,6 +267,20 @@ impl ssq::Step {
} }
} }
} }
(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;
}
}
}
ssq::Step::Shock { beats } => { ssq::Step::Shock { beats } => {
let columns = match shock_step_generator.next() { let columns = match shock_step_generator.next() {
Some(columns) => columns, Some(columns) => columns,
@ -288,7 +312,7 @@ impl ssq::Step {
} }
} }
Ok(hit_objects) Some(hit_objects)
} }
} }
@ -363,13 +387,14 @@ impl ssq::SSQ {
ShockStepGenerator::new(chart.difficulty.players * 4, config.shock_action.clone()); ShockStepGenerator::new(chart.difficulty.players * 4, config.shock_action.clone());
for step in &chart.steps.0 { for step in &chart.steps.0 {
trace!("Converting {:?} to hit object", step); 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, chart.difficulty.players * 4,
&self.tempo_changes, &self.tempo_changes,
&mut shock_step_generator, &mut shock_step_generator,
)?; ) {
hit_objects.0.append(&mut step_hit_objects); hit_objects.0.append(&mut step_hit_objects);
} }
}
let converted_chart = ConvertedChart { let converted_chart = ConvertedChart {
difficulty: chart.difficulty.clone(), difficulty: chart.difficulty.clone(),

View file

@ -1,7 +1,7 @@
use std::convert::From; use std::convert::From;
use std::fmt; use std::fmt;
use anyhow::{anyhow, Result}; use anyhow::Result;
use log::{debug, info, trace, warn}; use log::{debug, info, trace, warn};
use nom::bytes::complete::take; use nom::bytes::complete::take;
use nom::multi::many0; use nom::multi::many0;
@ -126,18 +126,12 @@ impl Steps {
continue; 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 { if FREEZE {
match Self::find_last(Self(parsed_steps.clone()), &row) {
Some(last_step) => {
parsed_steps.push(Step::Freeze { parsed_steps.push(Step::Freeze {
start: if let Step::Step { beats, .. } = parsed_steps[last_step] { start: if let Step::Step { beats, .. } = parsed_steps[last_step]
{
beats beats
} else { } else {
unreachable!() unreachable!()
@ -147,6 +141,14 @@ impl Steps {
}); });
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 { } else {
trace!("Freeze disabled, adding normal step"); trace!("Freeze disabled, adding normal step");
parsed_steps.push(Step::Step { beats, row }); parsed_steps.push(Step::Step { beats, row });
@ -173,16 +175,16 @@ impl Steps {
Ok((input, Self(parsed_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() { for i in (0..steps.0.len()).rev() {
if let Step::Step { row: step_row, .. } = &steps.0[i] { if let Step::Step { row: step_row, .. } = &steps.0[i] {
if step_row.clone().intersects(row.clone()) { if step_row.clone().intersects(row.clone()) {
return Ok(i); return Some(i);
} }
} }
} }
Err(anyhow!("No previous step found on that column")) None
} }
} }