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 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,69 +191,93 @@ 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);
|
||||||
|
|
||||||
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() {
|
for (column, active) in columns.iter().enumerate() {
|
||||||
if *active {
|
if *active {
|
||||||
hit_objects.push(beatmap::HitObject::HitCircle {
|
hit_objects.push(beatmap::HitObject::HitCircle {
|
||||||
x: beatmap::column_to_x(column as u8, num_columns),
|
x: beatmap::column_to_x(column as u8, num_columns),
|
||||||
y: 192,
|
y: 192,
|
||||||
time,
|
time,
|
||||||
hit_sound: beatmap::HitSound {
|
hit_sound: beatmap::HitSound {
|
||||||
normal: true,
|
normal: true,
|
||||||
whistle: false,
|
whistle: false,
|
||||||
finish: false,
|
finish: false,
|
||||||
clap: false,
|
clap: false,
|
||||||
},
|
},
|
||||||
new_combo: false,
|
new_combo: false,
|
||||||
skip_combo_colours: 0,
|
skip_combo_colours: 0,
|
||||||
hit_sample: beatmap::HitSample {
|
hit_sample: beatmap::HitSample {
|
||||||
normal_set: 0,
|
normal_set: 0,
|
||||||
addition_set: 0,
|
addition_set: 0,
|
||||||
index: 0,
|
index: 0,
|
||||||
volume: 0,
|
volume: 0,
|
||||||
filename: "".to_string(),
|
filename: "".to_string(),
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
|
||||||
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() {
|
for (column, active) in columns.iter().enumerate() {
|
||||||
if *active {
|
if *active {
|
||||||
hit_objects.push(beatmap::HitObject::Hold {
|
hit_objects.push(beatmap::HitObject::Hold {
|
||||||
column: column as u8,
|
column: column as u8,
|
||||||
columns: num_columns,
|
columns: num_columns,
|
||||||
time,
|
time,
|
||||||
end_time,
|
end_time,
|
||||||
hit_sound: beatmap::HitSound {
|
hit_sound: beatmap::HitSound {
|
||||||
normal: true,
|
normal: true,
|
||||||
whistle: false,
|
whistle: false,
|
||||||
finish: true,
|
finish: true,
|
||||||
clap: false,
|
clap: false,
|
||||||
},
|
},
|
||||||
new_combo: false,
|
new_combo: false,
|
||||||
skip_combo_colours: 0,
|
skip_combo_colours: 0,
|
||||||
hit_sample: beatmap::HitSample {
|
hit_sample: beatmap::HitSample {
|
||||||
normal_set: 0,
|
normal_set: 0,
|
||||||
addition_set: 0,
|
addition_set: 0,
|
||||||
index: 0,
|
index: 0,
|
||||||
volume: 0,
|
volume: 0,
|
||||||
filename: "".to_string(),
|
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());
|
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 {
|
||||||
|
|
|
@ -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,27 +126,29 @@ 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 {
|
||||||
parsed_steps.push(Step::Freeze {
|
match Self::find_last(Self(parsed_steps.clone()), &row) {
|
||||||
start: if let Step::Step { beats, .. } = parsed_steps[last_step] {
|
Some(last_step) => {
|
||||||
beats
|
parsed_steps.push(Step::Freeze {
|
||||||
} else {
|
start: if let Step::Step { beats, .. } = parsed_steps[last_step]
|
||||||
unreachable!()
|
{
|
||||||
},
|
beats
|
||||||
end: beats,
|
} else {
|
||||||
row,
|
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 {
|
} 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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Reference in a new issue