diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index 55da7b3..208ce38 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -261,34 +261,44 @@ fn get_ftp(app: AppHandle) -> u16 { *app.state::().ftp.lock().unwrap() } -/// Вычисляет и отправляет целевые мощность/каденс сегмента, если изменились. -async fn apply_target( +/// Вычисляет и отправляет целевую мощность сегмента, если она изменилась. +async fn apply_power( source: &Arc, device: &Device, seg: &workout::Segment, elapsed_secs: f64, ftp: u16, last_watts: Option, - last_cadence: Option, -) -> (Option, Option) { +) -> Option { let watts = seg.power.as_ref().map(|p| { workout::percent_to_watts(workout::target_percent(p, elapsed_secs, seg.duration_secs), ftp) }); - let cadence = seg.cadence_rpm; - - if watts != last_watts { - if let Some(w) = watts { - let _ = source.command(device, Command::FtmsSetTargetPower(w)).await; - } - } - 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; - } - } + if let Some(w) = watts.filter(|w| Some(*w) != last_watts) { + let _ = source.command(device, Command::FtmsSetTargetPower(w)).await; } - (watts, cadence) + watts +} + +/// Шлёт событие прогресса воркаута на фронт. +fn emit_progress( + app: &AppHandle, + idx: usize, + seg: &workout::Segment, + watts: Option, + 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 в конце. @@ -311,26 +321,20 @@ async fn run_workout( for (idx, seg) in segments.iter().enumerate() { 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 = None; - let mut last_cadence: Option = None; let mut tick = time::interval(Duration::from_secs(1)); tick.set_missed_tick_behavior(time::MissedTickBehavior::Delay); // 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_cadence = c; - 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, - }, - ); + emit_progress(&app, idx, seg, w, elapsed_total, total); let mut elapsed_in_seg: u64 = 0; while elapsed_in_seg < dur { @@ -339,23 +343,10 @@ async fn run_workout( continue; } elapsed_in_seg += 1; - let (w, c) = - apply_target(&source, &device, seg, elapsed_in_seg as f64, ftp, last_watts, last_cadence) - .await; + let w = apply_power(&source, &device, seg, elapsed_in_seg as f64, ftp, last_watts).await; last_watts = w; - last_cadence = c; elapsed_total += 1; - 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, - }, - ); + emit_progress(&app, idx, seg, w, elapsed_total, total); } }