From d895800f625d3a0aafc67faf420d2b8c7cee7b01 Mon Sep 17 00:00:00 2001 From: Uladzimir Karpenka Date: Thu, 4 Jun 2026 15:28:33 +0300 Subject: [PATCH] Phase 3 (heavy prep): move XvtrTranslate/ActiveTXFreqHz into controller MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Перенос частотных хелперов (общий блокер для Vfo/Mode/Band/CTun/TX/FM-Rpt) в TRadioController как чистых read-only функций над состоянием. Все константы (CFG_XVTR_COUNT, MODE_FM, RPT_MINUS/PLUS) уже доступны через Settings/WDSPEngine/FMRepeater в uses контроллера. MainForm.XvtrTranslate и MainForm.ActiveTXFreqHz стали тонкими обёртками-делегатами — ~40 мест вызова в UI/сетевом слое работают без изменений. Co-Authored-By: Claude Opus 4.8 --- MainForm.pas | 19 ++++--------------- RadioController.pas | 31 +++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 15 deletions(-) diff --git a/MainForm.pas b/MainForm.pas index 60b723f..b8dab68 100644 --- a/MainForm.pas +++ b/MainForm.pas @@ -5767,14 +5767,8 @@ end; function TMainForm.ActiveTXFreqHz: Double; begin - if FController.FSplitTxB then Result := FController.FVfoB - else if FController.FActiveVfo = 0 then Result := FController.FVfoA - else Result := FController.FVfoB; - if FController.FMode = MODE_FM then - case FController.FFMRptDir of - RPT_MINUS: Result := Result - FController.FFMRptOffsetHz; - RPT_PLUS: Result := Result + FController.FFMRptOffsetHz; - end; + // Логика перенесена в контроллер; обёртка для существующих вызовов в UI. + Result := FController.ActiveTXFreqHz; end; procedure TMainForm.ApplyMOX(Active: Boolean); @@ -6912,13 +6906,8 @@ end; // Если активный XVTR не задан — возвращает входную частоту без изменений. function TMainForm.XvtrTranslate(VisibleHz: Double): Double; begin - Result := VisibleHz; - if (FController.FCurrentXvtr < 0) or (FController.FCurrentXvtr >= CFG_XVTR_COUNT) then Exit; - if not FController.FXvtrSettings.Entries[FController.FCurrentXvtr].Enabled then Exit; - // f_IF = f_visible - LOOffset + LOError - Result := VisibleHz - - FController.FXvtrSettings.Entries[FController.FCurrentXvtr].LOOffset - + FController.FXvtrSettings.Entries[FController.FCurrentXvtr].LOError; + // Логика перенесена в контроллер; обёртка для существующих вызовов в UI. + Result := FController.XvtrTranslate(VisibleHz); end; // Передаёт XVTR-режим в сетевой слой. Вызывается при смене XVTR или его diff --git a/RadioController.pas b/RadioController.pas index 1eebbb5..1f959cd 100644 --- a/RadioController.pas +++ b/RadioController.pas @@ -202,6 +202,14 @@ type // Снимок всего состояния (для синхронизации нового фронтенда). function GetSnapshot: TRadioSnapshot; + // Частотные хелперы — чистые вычисления над состоянием, общие для всех + // фронтендов и сетевого слоя (Vfo/Mode/Band/CTun/TX/FM-Rpt). + // XvtrTranslate — переводит видимую частоту в частоту IF-тракта с учётом + // активного трансвертора (LOOffset/LOError). + // ActiveTXFreqHz — текущая TX-частота (split/active VFO + FM-репитер сдвиг). + function XvtrTranslate(VisibleHz: Double): Double; + function ActiveTXFreqHz: Double; + // ==================================================================== // КОМАНДЫ — единый API для GUI / Web / CAT / Arduino. // Фаза 1: обновляют поле + шлют событие; логика движка — TODO-wiring. @@ -341,6 +349,29 @@ begin Result.PLLLock := FLastPLLLock; end; +function TRadioController.XvtrTranslate(VisibleHz: Double): Double; +begin + Result := VisibleHz; + if (FCurrentXvtr < 0) or (FCurrentXvtr >= CFG_XVTR_COUNT) then Exit; + if not FXvtrSettings.Entries[FCurrentXvtr].Enabled then Exit; + // f_IF = f_visible - LOOffset + LOError + Result := VisibleHz + - FXvtrSettings.Entries[FCurrentXvtr].LOOffset + + FXvtrSettings.Entries[FCurrentXvtr].LOError; +end; + +function TRadioController.ActiveTXFreqHz: Double; +begin + if FSplitTxB then Result := FVfoB + else if FActiveVfo = 0 then Result := FVfoA + else Result := FVfoB; + if FMode = MODE_FM then + case FFMRptDir of + RPT_MINUS: Result := Result - FFMRptOffsetHz; + RPT_PLUS: Result := Result + FFMRptOffsetHz; + end; +end; + // ===================================================================== // Команды (Фаза 1 — каркас). Полная логика переносится из TMainForm. // =====================================================================