Phase 5 (D3): lift connect/disconnect orchestration into the controller

ConnectAndRun (ConnectDevice + RestoreBand + XVTR restore + active-VFO retune +
StartRunning) and StopAndDisconnect (StopRunning + settings persist + Disconnect)
move into TRadioController, making the full connect/disconnect lifecycle callable
headless. MainForm.DoConnectDevice/DoStopAndDisconnect become thin wrappers that
only add UI-extras (status strings, AGCTop mirror, spectrum reset/resize,
offline status, A-VFO highlight). Behavior-preserving: status/highlight now run
after bring-up, consistent with the batch-29 precedent (no packets yet, safe).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Uladzimir Karpenka
2026-06-09 14:50:38 +03:00
co-authored by Claude Opus 4.8
parent f122079b83
commit b9c358789d
2 changed files with 67 additions and 45 deletions
+55
View File
@@ -444,6 +444,8 @@ type
procedure StartRunning(SpectrumWidth: Integer); // Run=1 bring-up: General/DDC/DUC + DSP restore
procedure StopRunning; // Run=0: graceful-стоп RX-потока + сброс TX/телеметрии
function ConnectDevice(const Dev: THPSDRDevice): Boolean; // Connect + load-by-MAC; рендер через rfDevice
function ConnectAndRun(const Dev: THPSDRDevice; SpectrumWidth: Integer): Boolean; // ConnectDevice + band/xvtr/vfo restore + go-live
procedure StopAndDisconnect; // graceful Run=0 + персист настроек + Disconnect (headless)
procedure Discover;
// ---- События наружу ----
@@ -2389,6 +2391,59 @@ begin
Changed(rfDevice); // UI: полная синхронизация device-виджетов из состояния
end;
function TRadioController.ConnectAndRun(const Dev: THPSDRDevice;
SpectrumWidth: Integer): Boolean;
// Headless-оркестрация подключения: Connect+load-by-MAC (ConnectDevice) →
// перестройка диапазона/XVTR/активного VFO → go-live (StartRunning). Рендер всех
// device/band/run-виджетов идёт через события (rfDevice/rfBandRestore/rfXvtr/
// rfActiveVfo/rfRunning). UI-обёртка добавляет лишь статус-строки/AGCTop/resize.
// Возвращает False, если Connect не удался (тогда bring-up не делается).
begin
Result := ConnectDevice(Dev);
if not Result then Exit;
// Перестройка диапазона — команда несёт финальную перестройку по активному VFO.
RestoreBand(FCurrentBand);
// Восстанавливаем XVTR-режим, если он был активен при выходе. FCurrentBand уже
// загружен (HF-диапазон до XVTR) — ActivateXvtr только выставит FVfoA/FCurrentXvtr.
if (FLoadedGlobal.LastXvtr >= 0) and (FLoadedGlobal.LastXvtr < CFG_XVTR_COUNT)
and FXvtrSettings.Entries[FLoadedGlobal.LastXvtr].Enabled then
ActivateXvtr(FLoadedGlobal.LastXvtr);
// Активный VFO загружен из настроек; RestoreBand/ActivateXvtr строят только
// VFO A. Если активен B — перестраиваем приёмник И подсветку на него. Для
// активного A подсветку освежает UI-обёртка (чистый рендер).
if FActiveVfo = 1 then
SetActiveVfo(1);
// Go-live Run=1 (General/DDC/DUC + DSP restore); рендер — через rfRunning.
StartRunning(SpectrumWidth);
end;
procedure TRadioController.StopAndDisconnect;
// Headless STOP+teardown: graceful Run=0 (StopRunning) + персист настроек
// устройства/диапазона/глобала + разрыв сети. Персист идёт ДО Disconnect (saves
// читают живое состояние). Рендер run-кнопки/MOX/sleep — через StopRunning→
// rfRunning; UI-обёртка добавляет очистку спектра и offline-статус.
begin
StopRunning;
// Сохраняем текущую частоту/настройки чтобы следующий START восстановил их.
if FDevConnected then
begin
SaveCurrentBand;
SaveGlobalSettings;
FSettings.SaveAlex(FDevMAC, FAlexSettings);
// XVTR LastFreq → актуальная видимая частота в момент остановки.
if (FCurrentXvtr >= 0) and (FCurrentXvtr < CFG_XVTR_COUNT) then
FXvtrSettings.Entries[FCurrentXvtr].LastFreq := FVfoA;
FSettings.SaveXvtr(FDevMAC, FXvtrSettings);
end;
FSettings.SaveStartupPreview(FVfoA, FVfoB, FSampleRate);
FSettings.Save;
FNetwork.Disconnect;
end;
// ---------------------------------------------------------------------------
// Discovery — поиск устройств в фоновом потоке. Найденные приходят через
// FNetwork.OnDeviceFound (=OnDeviceFound) и копятся в FDeviceStore.Discovered;