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
+12 -45
View File
@@ -3361,29 +3361,14 @@ end;
procedure TMainForm.DoStopAndDisconnect;
// STOP-teardown, общий для десктоп-STOP и web-disconnect. Движок (graceful Run=0,
// сброс TX/телеметрии) + рендер run-кнопки/MOX/sleep — в контроллере (StopRunning
// + OnControllerState). Здесь: persistence + сеть Disconnect + offline-статус.
// сброс TX/телеметрии) + персист настроек + Disconnect — в контроллере
// (StopAndDisconnect); рендер run-кнопки/MOX/sleep — через rfRunning. Здесь —
// только очистка спектра и контекстный offline-статус.
begin
FController.StopRunning;
// Сохраняем текущую частоту/настройки чтобы следующий START восстановил их
if FController.FDevConnected then
begin
SaveCurrentBand;
FController.SaveGlobalSettings;
FController.FSettings.SaveAlex(FController.FDevMAC, FController.FAlexSettings);
// XVTR LastFreq → актуальная видимая частота в момент остановки
if (FController.FCurrentXvtr >= 0) and (FController.FCurrentXvtr < CFG_XVTR_COUNT) then
FController.FXvtrSettings.Entries[FController.FCurrentXvtr].LastFreq := FController.FVfoA;
FController.FSettings.SaveXvtr(FController.FDevMAC, FController.FXvtrSettings);
end;
FController.FSettings.SaveStartupPreview(FController.FVfoA, FController.FVfoB, FController.FSampleRate);
FController.FSettings.Save;
FController.StopAndDisconnect;
FSpecView.ResetSpectrumBuf;
FSpecView.DrawSpectrum;
PbSpectrum.Invalidate;
FController.FNetwork.Disconnect;
// Run-кнопка/MOX уже перерисованы StopRunning (rfRunning); здесь только
// контекстный offline-статус.
SetRadioOfflineStatus('Disconnected', True);
end;
@@ -3454,42 +3439,24 @@ procedure TMainForm.DoConnectDevice(const Dev: THPSDRDevice);
begin
BtnStartStop.Enabled := True;
// Connect + загрузка per-device настроек в контроллер; рендер ВСЕХ device-
// виджетов идёт через OnControllerState(rfDevice) внутри ConnectDevice.
if not FController.ConnectDevice(Dev) then
// Connect + load-by-MAC + перестройка диапазона/XVTR/активного VFO + go-live —
// вся оркестрация в контроллере (ConnectAndRun); рендер device/band/run-
// виджетов идёт через события (rfDevice/rfBandRestore/rfXvtr/rfActiveVfo/
// rfRunning). Здесь — только UI-extras (статус-строки/AGCTop/resize).
if not FController.ConnectAndRun(Dev, FSpectrumWidth) then
begin
ShowMessage('Failed to connect to ' + Dev.IPAddress +
IfThen(FController.FNetwork.LastError <> '', ': ' + FController.FNetwork.LastError, ''));
Exit;
end;
// Перестройка диапазона/VFO — обёртки с UI-extras (финальная перестройка через
// ApplyVfoA; XVTR — wideband-view+web). Состояние уже загружено ConnectDevice.
RestoreBand(FController.FCurrentBand);
// Восстанавливаем XVTR-режим, если он был активен при выходе.
// FController.FCurrentBand уже загружен (HF-диапазон, на который пользователь зашёл
// до XVTR), его FController.FBandCache не пострадает — ActivateXvtrBand только
// выставит FController.FVfoA на XVTR-частоту и FController.FCurrentXvtr.
if (FController.FLoadedGlobal.LastXvtr >= 0) and (FController.FLoadedGlobal.LastXvtr < CFG_XVTR_COUNT)
and FController.FXvtrSettings.Entries[FController.FLoadedGlobal.LastXvtr].Enabled then
ActivateXvtrBand(FController.FLoadedGlobal.LastXvtr);
// Активный VFO загружен из настроек (выше), но подсветку рисовали в FormCreate
// (тогда FActiveVfo ещё = 0 → A), а RestoreBand/ActivateXvtrBand перестраивают
// только VFO A. Приводим приёмник И подсветку к фактически активному VFO,
// иначе движок работает по B, а UI показывает активным A.
if FController.FActiveVfo = 1 then
FController.SetActiveVfo(1) // перестройка RX на VFO B + рендер (rfActiveVfo)
else
// Активный VFO=A: подсветку (рисовалась в FormCreate при FActiveVfo=0) освежаем
// здесь — для B это сделал SetActiveVfo(1) внутри ConnectAndRun.
if FController.FActiveVfo <> 1 then
UpdateVfoDisplay;
SetStatusText(1, 'IP: ' + FController.FNetwork.Device.IPAddress);
SetStatusText(0, 'Board: ' + BoardTypeName(FController.FNetwork.Device.BoardType));
// «Go-live» Run=1 (General/DDC/DUC + DSP restore) — в контроллере; рендер
// run-кнопки/MOX/sleep идёт через OnControllerState(rfRunning).
FController.StartRunning(FSpectrumWidth);
FSpecView.AGCTop := FController.FAGCTop;
SetStatusText(6, 'SEQ OK');
SetStatusText(2, 'Running');