mirror of
https://git.vladimir.cc/vladimir/ewsdr.git
synced 2026-08-26 22:57:34 +00:00
Phase 5: move global-settings persistence into the controller
MakeGlobalSettings (the central persist builder, ~50 fields) lived in MainForm and mixed radio state with UI fields, blocking headless persistence. Replace it with TRadioController.BuildGlobalSettings (radio fields from live state) + SaveGlobalSettings (self-gated on FDevConnected). The 7 scattered SaveGlobal(FDevMAC, MakeGlobalSettings) call-sites collapse to FController. SaveGlobalSettings. Non-radio fields (theme/FPS/MHz-digits/CAT) are NOT controller state — they ride through FLoadedGlobal (the loaded persist record the controller already holds for round-trip). The GUI mirrors them into FLoadedGlobal at their change-points (SetLightTheme/ApplyFPS/ApplyFreqMhzDigits/OnCATSettingsChange + connect for the app-global theme). Controller never reads or acts on them. Behavior-preserving (same blob, same save points); makes the daemon able to persist radio settings without the UI. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
e1ecf947b8
commit
2c356beb77
+23
-87
@@ -367,7 +367,6 @@ type
|
||||
procedure SaveAllAndExit;
|
||||
procedure RestoreWindowBounds;
|
||||
procedure SaveWindowBounds;
|
||||
function MakeGlobalSettings: TGlobalSettings;
|
||||
procedure FreqDispBChanged(Sender: TObject; NewFreq: Int64);
|
||||
procedure BtnBandClick(Sender: TObject);
|
||||
procedure BtnModeClick(Sender: TObject);
|
||||
@@ -709,84 +708,6 @@ begin
|
||||
FController.FSettings.SaveWindowBounds(L, T, Wd, Ht, DPI, Maximized);
|
||||
end;
|
||||
|
||||
function TMainForm.MakeGlobalSettings: TGlobalSettings;
|
||||
var i: Integer;
|
||||
begin
|
||||
Result.Volume := FController.FVolume;
|
||||
Result.DriveLevel := FController.FDrivePercent;
|
||||
Result.PAMaxPower := FController.FPAMaxPower;
|
||||
for i := 0 to BAND_COUNT - 1 do
|
||||
Result.PABandCal[i] := FController.FPABandCal[i];
|
||||
for i := 0 to CFG_XVTR_COUNT - 1 do
|
||||
Result.VHFBandCal[i] := FController.FVHFBandCal[i];
|
||||
Result.ActiveVfo := FController.FActiveVfo;
|
||||
Result.NRMode := FController.FNRMode;
|
||||
Result.NBMode := FController.FNBMode;
|
||||
Result.SNBEnabled := FController.FSNB;
|
||||
Result.ANFEnabled := FController.FANF;
|
||||
Result.AGCSlope := 0;
|
||||
Result.AGCHangThreshold := 100;
|
||||
Result.WfAGCEnabled := FController.FWfAGCEnabled;
|
||||
Result.WfNFEnabled := FController.FWfNFEnabled;
|
||||
Result.DitherEnabled := FController.FDitherEnabled;
|
||||
Result.RandomEnabled := FController.FRandomEnabled;
|
||||
Result.LastBand := FController.FCurrentBand;
|
||||
Result.LastXvtr := FController.FCurrentXvtr;
|
||||
Result.SampleRate := FController.FSampleRate;
|
||||
// Display settings
|
||||
if FController.FWDSPReady then
|
||||
begin
|
||||
Result.FFTSize := FController.FDSPEngine.FFTSize;
|
||||
Result.WindowType := FController.FDSPEngine.WindowType;
|
||||
Result.SpecDetector := FController.FDSPEngine.SpecDetector;
|
||||
Result.SpecAvgMode := FController.FDSPEngine.SpecAvgMode;
|
||||
Result.SpecAvgTimeMS := FController.FDSPEngine.SpecAvgTimeMS;
|
||||
Result.WfDetector := FController.FDSPEngine.WfDetector;
|
||||
Result.WfAvgMode := FController.FDSPEngine.WfAvgMode;
|
||||
Result.WfAvgTimeMS := FController.FDSPEngine.WfAvgTimeMS;
|
||||
end
|
||||
else
|
||||
begin
|
||||
Result.FFTSize := 131072;
|
||||
Result.WindowType := 2;
|
||||
Result.SpecDetector := 0;
|
||||
Result.SpecAvgMode := 3;
|
||||
Result.SpecAvgTimeMS := 30.0;
|
||||
Result.WfDetector := 0;
|
||||
Result.WfAvgMode := 3;
|
||||
Result.WfAvgTimeMS := 120.0;
|
||||
end;
|
||||
Result.WfManualHigh := FController.FWfManualHigh;
|
||||
Result.WfManualLow := FController.FWfManualLow;
|
||||
Result.WfAGCOffset := FController.FWfAGCOffset;
|
||||
Result.SpecRefLevel := FController.FSpecRefLevel;
|
||||
Result.SpecRange := FController.FSpecRange;
|
||||
Result.SpecGridStep := FController.FSpecGridStep;
|
||||
Result.AudioSampleRate := FController.FAudioOut.SampleRate;
|
||||
Result.ShowSpectrum := FController.FShowSpectrum;
|
||||
Result.ShowWaterfall := FController.FShowWaterfall;
|
||||
Result.ShowWideband := FController.FShowWideband;
|
||||
Result.WidebandFill := FController.FWidebandFill;
|
||||
Result.SpectrumFill := FController.FSpectrumFill;
|
||||
Result.DisplayDuplex := FController.FDisplayDuplex;
|
||||
Result.DisplayFPS := FDisplayFPS;
|
||||
Result.LightTheme := FLightTheme;
|
||||
Result.FreqMhzDigits := FFreqMhzDigits;
|
||||
// Audio device names
|
||||
Result.AudioOutDevice := FController.FAudioOutDevName;
|
||||
Result.AudioInDevice := FController.FAudioInDevName;
|
||||
Result.SendAudioToRadio := FController.FSendAudioToRadio;
|
||||
// CAT settings — carried from the last loaded/saved device config
|
||||
Result.CATSerialEnabled := FCATLastGlobal.CATSerialEnabled;
|
||||
Result.CATSerialPort := FCATLastGlobal.CATSerialPort;
|
||||
Result.CATSerialBaud := FCATLastGlobal.CATSerialBaud;
|
||||
Result.CATSerialDataBits := FCATLastGlobal.CATSerialDataBits;
|
||||
Result.CATSerialStopBits := FCATLastGlobal.CATSerialStopBits;
|
||||
Result.CATSerialParity := FCATLastGlobal.CATSerialParity;
|
||||
Result.CATTcpEnabled := FCATLastGlobal.CATTcpEnabled;
|
||||
Result.CATTcpPort := FCATLastGlobal.CATTcpPort;
|
||||
end;
|
||||
|
||||
procedure TMainForm.SaveCurrentBand;
|
||||
begin
|
||||
// Логика сохранения (band-cache/XVTR-слот + конфиг) — в контроллере.
|
||||
@@ -816,7 +737,7 @@ begin
|
||||
if FController.FDevConnected then
|
||||
begin
|
||||
SaveCurrentBand;
|
||||
FController.FSettings.SaveGlobal(FController.FDevMAC, MakeGlobalSettings);
|
||||
FController.SaveGlobalSettings;
|
||||
if FController.FDevConnected then
|
||||
FController.FSettings.SaveTX(FController.FDevMAC, FController.FTXSettings);
|
||||
// Запомнить LastFreq A/B XVTR для следующего запуска
|
||||
@@ -1167,7 +1088,7 @@ begin
|
||||
if FController.FDevConnected then
|
||||
begin
|
||||
SaveCurrentBand;
|
||||
FController.FSettings.SaveGlobal(FController.FDevMAC, MakeGlobalSettings);
|
||||
FController.SaveGlobalSettings;
|
||||
if FController.FDevConnected then
|
||||
FController.FSettings.SaveTX(FController.FDevMAC, FController.FTXSettings);
|
||||
end;
|
||||
@@ -1436,6 +1357,9 @@ begin
|
||||
// Полная синхронизация device-виджетов после ConnectDevice (load-by-MAC).
|
||||
// Состояние уже в контроллере; здесь только рендер + UI/CAT/web-побочки.
|
||||
FCATLastGlobal := FController.FLoadedGlobal;
|
||||
// Тема — app-global (своё хранилище LoadTheme/SaveTheme), не из device-блоба:
|
||||
// возвращаем живое значение в persist-буфер, чтобы blob нёс актуальную тему.
|
||||
FController.FLoadedGlobal.LightTheme := FLightTheme;
|
||||
CATApplySettings(FController.FLoadedGlobal);
|
||||
RebuildXvtrButtons;
|
||||
PushXvtrToWeb;
|
||||
@@ -2743,6 +2667,7 @@ procedure TMainForm.SetLightTheme(V: Boolean);
|
||||
begin
|
||||
if FLightTheme = V then Exit;
|
||||
FLightTheme := V;
|
||||
FController.FLoadedGlobal.LightTheme := V; // зеркало в persist-буфер контроллера
|
||||
ApplyDarkTheme;
|
||||
FController.FSettings.SaveTheme(V);
|
||||
FController.FSettings.Save;
|
||||
@@ -3492,7 +3417,7 @@ begin
|
||||
if FController.FDevConnected then
|
||||
begin
|
||||
SaveCurrentBand;
|
||||
FController.FSettings.SaveGlobal(FController.FDevMAC, MakeGlobalSettings);
|
||||
FController.SaveGlobalSettings;
|
||||
FController.FSettings.SaveAlex(FController.FDevMAC, FController.FAlexSettings);
|
||||
// XVTR LastFreq → актуальная видимая частота в момент остановки
|
||||
if (FController.FCurrentXvtr >= 0) and (FController.FCurrentXvtr < CFG_XVTR_COUNT) then
|
||||
@@ -4582,7 +4507,7 @@ begin
|
||||
if FController.FNetwork.Connected and FController.FRunning then
|
||||
FController.FNetwork.ConfigureDDCs(1, FController.FSampleRate div 1000, 0, FController.FDitherEnabled, FController.FRandomEnabled);
|
||||
if FController.FDevConnected then
|
||||
FController.FSettings.SaveGlobal(FController.FDevMAC, MakeGlobalSettings);
|
||||
FController.SaveGlobalSettings;
|
||||
end;
|
||||
|
||||
procedure TMainForm.ApplyWebSettings(Enabled: Boolean; Port: Integer;
|
||||
@@ -4737,7 +4662,7 @@ begin
|
||||
FController.SetSampleRate(SampleRate);
|
||||
// SampleRate глобальный — сохраняем в global settings.
|
||||
if FController.FDevConnected then
|
||||
FController.FSettings.SaveGlobal(FController.FDevMAC, MakeGlobalSettings);
|
||||
FController.SaveGlobalSettings;
|
||||
end;
|
||||
|
||||
// ===========================================================================
|
||||
@@ -5577,7 +5502,7 @@ begin
|
||||
// выкл = замьютить динамик (byte 1400 bit1) и не слать поток.
|
||||
FController.FNetwork.SetSpeakerAudio(Enabled);
|
||||
if FController.FDevConnected then
|
||||
FController.FSettings.SaveGlobal(FController.FDevMAC, MakeGlobalSettings);
|
||||
FController.SaveGlobalSettings;
|
||||
end;
|
||||
|
||||
procedure TMainForm.ApplyVisibility(ShowSpectrum, ShowWaterfall,
|
||||
@@ -5601,6 +5526,7 @@ begin
|
||||
if FPS < 1 then FPS := 1;
|
||||
if FPS > 100 then FPS := 100;
|
||||
FDisplayFPS := FPS;
|
||||
FController.FLoadedGlobal.DisplayFPS := FPS; // зеркало в persist-буфер контроллера
|
||||
FSpectrumTimer.Interval := 1000 div FPS;
|
||||
// CPU path keeps the historical every-other-frame waterfall update.
|
||||
// OpenGL uploads only one texture row per frame, so it can match display FPS.
|
||||
@@ -5621,6 +5547,7 @@ const
|
||||
begin
|
||||
Digits := EnsureRange(Digits, 3, 5);
|
||||
FFreqMhzDigits := Digits;
|
||||
FController.FLoadedGlobal.FreqMhzDigits := Digits; // зеркало в persist-буфер контроллера
|
||||
FreqDispA.MinMhzDigits := Digits;
|
||||
FreqDispB.MinMhzDigits := Digits;
|
||||
FreqDispA.MaxFreq := MaxFreqs[Digits];
|
||||
@@ -5828,10 +5755,19 @@ begin
|
||||
end;
|
||||
FCATLastGlobal.CATTcpEnabled := TcpEnabled;
|
||||
FCATLastGlobal.CATTcpPort := TcpPort;
|
||||
// Зеркалим CAT-поля в persist-буфер контроллера (BuildGlobalSettings берёт их
|
||||
// сквозь из FLoadedGlobal; на connect они грузятся в FLoadedGlobal → FCATLastGlobal).
|
||||
FController.FLoadedGlobal.CATSerialEnabled := FCATLastGlobal.CATSerialEnabled;
|
||||
FController.FLoadedGlobal.CATSerialPort := FCATLastGlobal.CATSerialPort;
|
||||
FController.FLoadedGlobal.CATSerialBaud := FCATLastGlobal.CATSerialBaud;
|
||||
FController.FLoadedGlobal.CATSerialDataBits := FCATLastGlobal.CATSerialDataBits;
|
||||
FController.FLoadedGlobal.CATSerialStopBits := FCATLastGlobal.CATSerialStopBits;
|
||||
FController.FLoadedGlobal.CATSerialParity := FCATLastGlobal.CATSerialParity;
|
||||
FController.FLoadedGlobal.CATTcpEnabled := FCATLastGlobal.CATTcpEnabled;
|
||||
FController.FLoadedGlobal.CATTcpPort := FCATLastGlobal.CATTcpPort;
|
||||
CATApplySettings(FCATLastGlobal);
|
||||
FController.FSettings.SaveCATSettings(FCATLastGlobal);
|
||||
if FController.FDevConnected then
|
||||
FController.FSettings.SaveGlobal(FController.FDevMAC, MakeGlobalSettings);
|
||||
FController.SaveGlobalSettings;
|
||||
FController.FSettings.Save;
|
||||
end;
|
||||
|
||||
|
||||
@@ -314,6 +314,13 @@ type
|
||||
function MakeBandSettings: TBandSettings;
|
||||
procedure SaveCurrentBand;
|
||||
procedure RestoreBand(BandIdx: Integer);
|
||||
|
||||
// Глобальные настройки устройства (persist по MAC). BuildGlobalSettings
|
||||
// собирает радио-поля из своего состояния, а НЕ-радио поля (тема/FPS/digits/
|
||||
// CAT) переносит сквозь из FLoadedGlobal — контроллер их не трактует, только
|
||||
// round-trip в файл. SaveGlobalSettings пишет блоб (гейт по FDevConnected).
|
||||
function BuildGlobalSettings: TGlobalSettings;
|
||||
procedure SaveGlobalSettings;
|
||||
// Применяет DSP-настройки диапазона (mode/filter/AGC/CTUN/FM) + шлёт события
|
||||
// рендера. НЕ трогает частоты VFO/центр — это переиспользуется как RestoreBand
|
||||
// (с загрузкой VFO), так и SetActiveVfo (bandstack: смена бэнда без сброса VFO).
|
||||
@@ -994,6 +1001,77 @@ begin
|
||||
FSettings.SaveBand(FDevMAC, FCurrentBand, FBandCache[FCurrentBand]);
|
||||
end;
|
||||
|
||||
function TRadioController.BuildGlobalSettings: TGlobalSettings;
|
||||
// Радио-поля — из живого состояния; тема/FPS/digits/CAT — сквозь из FLoadedGlobal
|
||||
// (контроллер их не трактует). Сидируем загруженным блобом, поверх — радио.
|
||||
var i: Integer;
|
||||
begin
|
||||
Result := FLoadedGlobal; // несёт не-радио поля (тема/FPS/digits/CAT) round-trip
|
||||
|
||||
Result.Volume := FVolume;
|
||||
Result.DriveLevel := FDrivePercent;
|
||||
Result.PAMaxPower := FPAMaxPower;
|
||||
for i := 0 to CFG_BAND_COUNT - 1 do Result.PABandCal[i] := FPABandCal[i];
|
||||
for i := 0 to CFG_XVTR_COUNT - 1 do Result.VHFBandCal[i] := FVHFBandCal[i];
|
||||
Result.ActiveVfo := FActiveVfo;
|
||||
Result.NRMode := FNRMode;
|
||||
Result.NBMode := FNBMode;
|
||||
Result.SNBEnabled := FSNB;
|
||||
Result.ANFEnabled := FANF;
|
||||
Result.AGCSlope := 0;
|
||||
Result.AGCHangThreshold := 100;
|
||||
Result.WfAGCEnabled := FWfAGCEnabled;
|
||||
Result.WfNFEnabled := FWfNFEnabled;
|
||||
Result.DitherEnabled := FDitherEnabled;
|
||||
Result.RandomEnabled := FRandomEnabled;
|
||||
Result.LastBand := FCurrentBand;
|
||||
Result.LastXvtr := FCurrentXvtr;
|
||||
Result.SampleRate := FSampleRate;
|
||||
if FWDSPReady then
|
||||
begin
|
||||
Result.FFTSize := FDSPEngine.FFTSize;
|
||||
Result.WindowType := FDSPEngine.WindowType;
|
||||
Result.SpecDetector := FDSPEngine.SpecDetector;
|
||||
Result.SpecAvgMode := FDSPEngine.SpecAvgMode;
|
||||
Result.SpecAvgTimeMS := FDSPEngine.SpecAvgTimeMS;
|
||||
Result.WfDetector := FDSPEngine.WfDetector;
|
||||
Result.WfAvgMode := FDSPEngine.WfAvgMode;
|
||||
Result.WfAvgTimeMS := FDSPEngine.WfAvgTimeMS;
|
||||
end
|
||||
else
|
||||
begin
|
||||
Result.FFTSize := 131072;
|
||||
Result.WindowType := 2;
|
||||
Result.SpecDetector := 0;
|
||||
Result.SpecAvgMode := 3;
|
||||
Result.SpecAvgTimeMS := 30.0;
|
||||
Result.WfDetector := 0;
|
||||
Result.WfAvgMode := 3;
|
||||
Result.WfAvgTimeMS := 120.0;
|
||||
end;
|
||||
Result.WfManualHigh := FWfManualHigh;
|
||||
Result.WfManualLow := FWfManualLow;
|
||||
Result.WfAGCOffset := FWfAGCOffset;
|
||||
Result.SpecRefLevel := FSpecRefLevel;
|
||||
Result.SpecRange := FSpecRange;
|
||||
Result.SpecGridStep := FSpecGridStep;
|
||||
Result.AudioSampleRate := FAudioOut.SampleRate;
|
||||
Result.ShowSpectrum := FShowSpectrum;
|
||||
Result.ShowWaterfall := FShowWaterfall;
|
||||
Result.ShowWideband := FShowWideband;
|
||||
Result.WidebandFill := FWidebandFill;
|
||||
Result.SpectrumFill := FSpectrumFill;
|
||||
Result.DisplayDuplex := FDisplayDuplex;
|
||||
Result.AudioOutDevice := FAudioOutDevName;
|
||||
Result.AudioInDevice := FAudioInDevName;
|
||||
Result.SendAudioToRadio := FSendAudioToRadio;
|
||||
end;
|
||||
|
||||
procedure TRadioController.SaveGlobalSettings;
|
||||
begin
|
||||
if FDevConnected then FSettings.SaveGlobal(FDevMAC, BuildGlobalSettings);
|
||||
end;
|
||||
|
||||
procedure TRadioController.ApplyBandDSP(const B: TBandSettings);
|
||||
// DSP-настройки диапазона + события рендера. Частоты VFO/центр НЕ трогает.
|
||||
begin
|
||||
|
||||
Reference in New Issue
Block a user