refactor: flatten nested ifs in workout engine

pull/4/head
lambda 6 days ago
parent b3f42d1f33
commit 688de29269
No known key found for this signature in database
GPG Key ID: CF45A8EE158BBCB6

@ -261,34 +261,44 @@ fn get_ftp(app: AppHandle) -> u16 {
*app.state::<State>().ftp.lock().unwrap() *app.state::<State>().ftp.lock().unwrap()
} }
/// Вычисляет и отправляет целевые мощность/каденс сегмента, если изменились. /// Вычисляет и отправляет целевую мощность сегмента, если она изменилась.
async fn apply_target( async fn apply_power(
source: &Arc<dyn SensorSource>, source: &Arc<dyn SensorSource>,
device: &Device, device: &Device,
seg: &workout::Segment, seg: &workout::Segment,
elapsed_secs: f64, elapsed_secs: f64,
ftp: u16, ftp: u16,
last_watts: Option<i16>, last_watts: Option<i16>,
last_cadence: Option<u16>, ) -> Option<i16> {
) -> (Option<i16>, Option<u16>) {
let watts = seg.power.as_ref().map(|p| { let watts = seg.power.as_ref().map(|p| {
workout::percent_to_watts(workout::target_percent(p, elapsed_secs, seg.duration_secs), ftp) workout::percent_to_watts(workout::target_percent(p, elapsed_secs, seg.duration_secs), ftp)
}); });
let cadence = seg.cadence_rpm; if let Some(w) = watts.filter(|w| Some(*w) != last_watts) {
if watts != last_watts {
if let Some(w) = watts {
let _ = source.command(device, Command::FtmsSetTargetPower(w)).await; let _ = source.command(device, Command::FtmsSetTargetPower(w)).await;
} }
} watts
if cadence != last_cadence { }
if let Some(rpm) = cadence {
if let Some(half) = rpm.checked_mul(2) { /// Шлёт событие прогресса воркаута на фронт.
let _ = source.command(device, Command::FtmsSetTargetCadence(half)).await; fn emit_progress(
} app: &AppHandle,
} idx: usize,
} seg: &workout::Segment,
(watts, cadence) watts: Option<i16>,
elapsed_total: u64,
total: u64,
) {
let _ = app.emit(
"workout-progress",
WorkoutProgressEvent {
step_index: idx,
step_name: seg.text.clone().unwrap_or_default(),
target_watts: watts,
target_cadence: seg.cadence_rpm,
elapsed_secs: elapsed_total,
total_secs: total,
},
);
} }
/// Исполняет воркаут: request_control + start, тик-луп по сегментам, stop в конце. /// Исполняет воркаут: request_control + start, тик-луп по сегментам, stop в конце.
@ -311,26 +321,20 @@ async fn run_workout(
for (idx, seg) in segments.iter().enumerate() { for (idx, seg) in segments.iter().enumerate() {
let dur = seg.duration_secs as u64; let dur = seg.duration_secs as u64;
// каденс — константа сегмента, шлём один раз (в 0.5-rpm единицах FTMS).
if let Some(half) = seg.cadence_rpm.and_then(|rpm| rpm.checked_mul(2)) {
let _ = source.command(&device, Command::FtmsSetTargetCadence(half)).await;
}
let mut last_watts: Option<i16> = None; let mut last_watts: Option<i16> = None;
let mut last_cadence: Option<u16> = None;
let mut tick = time::interval(Duration::from_secs(1)); let mut tick = time::interval(Duration::from_secs(1));
tick.set_missed_tick_behavior(time::MissedTickBehavior::Delay); tick.set_missed_tick_behavior(time::MissedTickBehavior::Delay);
// t = 0 // t = 0
let (w, c) = apply_target(&source, &device, seg, 0.0, ftp, last_watts, last_cadence).await; let w = apply_power(&source, &device, seg, 0.0, ftp, last_watts).await;
last_watts = w; last_watts = w;
last_cadence = c; emit_progress(&app, idx, seg, w, elapsed_total, total);
let _ = app.emit(
"workout-progress",
WorkoutProgressEvent {
step_index: idx,
step_name: seg.text.clone().unwrap_or_default(),
target_watts: w,
target_cadence: c,
elapsed_secs: elapsed_total,
total_secs: total,
},
);
let mut elapsed_in_seg: u64 = 0; let mut elapsed_in_seg: u64 = 0;
while elapsed_in_seg < dur { while elapsed_in_seg < dur {
@ -339,23 +343,10 @@ async fn run_workout(
continue; continue;
} }
elapsed_in_seg += 1; elapsed_in_seg += 1;
let (w, c) = let w = apply_power(&source, &device, seg, elapsed_in_seg as f64, ftp, last_watts).await;
apply_target(&source, &device, seg, elapsed_in_seg as f64, ftp, last_watts, last_cadence)
.await;
last_watts = w; last_watts = w;
last_cadence = c;
elapsed_total += 1; elapsed_total += 1;
let _ = app.emit( emit_progress(&app, idx, seg, w, elapsed_total, total);
"workout-progress",
WorkoutProgressEvent {
step_index: idx,
step_name: seg.text.clone().unwrap_or_default(),
target_watts: w,
target_cadence: c,
elapsed_secs: elapsed_total,
total_secs: total,
},
);
} }
} }

Loading…
Cancel
Save