Phase 3 (WA2b): move web Drive handler into the web adapter

Now that SetDrive is a complete command, the web/CAT Drive handler moves into
TWebAdapter.OnDrive (the one handler WA1 left behind). CAT context SetDriveLevel
repointed to it too.

Makes the channel-power-clear reactive: ChannelController.OnDriveChanged fires on
the rfDrive event and clears FPreChannelPower for any external drive change
(slider/web/encoder), guarded by FRestoringDrive for the unit's own apply/restore.
This removes the imperative ClearPreChannelPower coupling so SetDrive callers need
no channel knowledge.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Uladzimir Karpenka
2026-06-08 20:26:30 +03:00
co-authored by Claude Opus 4.8
parent 03f7359184
commit e5a13096dc
3 changed files with 38 additions and 26 deletions
+23 -6
View File
@@ -37,10 +37,12 @@ type
FRadio: TRadioController; FRadio: TRadioController;
FActiveIdx: Integer; // -1 = нет активного канала FActiveIdx: Integer; // -1 = нет активного канала
FPreChannelPower: Integer; // drive % до применения канала (-1 = не сохранён) FPreChannelPower: Integer; // drive % до применения канала (-1 = не сохранён)
FRestoringDrive: Boolean; // True пока юнит сам ставит drive (apply/restore)
FOnActiveChanged: TChannelActiveEvent; FOnActiveChanged: TChannelActiveEvent;
FOnActivateXvtr: TChannelXvtrEvent; FOnActivateXvtr: TChannelXvtrEvent;
FOnDeactivateXvtr: TChannelNotifyEvent; FOnDeactivateXvtr: TChannelNotifyEvent;
procedure EmitActive(Active: Boolean; const Name: string); procedure EmitActive(Active: Boolean; const Name: string);
procedure SetDriveGuarded(V: Integer); // SetDrive, не сбрасывающий память канала
public public
constructor Create(ARadio: TRadioController); constructor Create(ARadio: TRadioController);
@@ -48,7 +50,7 @@ type
procedure Apply(const Ch: TChannel); // применить канал к радио procedure Apply(const Ch: TChannel); // применить канал к радио
procedure CheckActive; // деактивировать при уходе с частоты procedure CheckActive; // деактивировать при уходе с частоты
procedure OnVfoTuned; // канальная оркестрация после SetVfoA procedure OnVfoTuned; // канальная оркестрация после SetVfoA
procedure ClearPreChannelPower; // ручное изменение drive снимает память procedure OnDriveChanged; // реакция на rfDrive: внешнее изменение снимает память
property ActiveIdx: Integer read FActiveIdx write FActiveIdx; property ActiveIdx: Integer read FActiveIdx write FActiveIdx;
property OnActiveChanged: TChannelActiveEvent read FOnActiveChanged write FOnActiveChanged; property OnActiveChanged: TChannelActiveEvent read FOnActiveChanged write FOnActiveChanged;
@@ -71,9 +73,24 @@ begin
if Assigned(FOnActiveChanged) then FOnActiveChanged(FActiveIdx, Name, Active); if Assigned(FOnActiveChanged) then FOnActiveChanged(FActiveIdx, Name, Active);
end; end;
procedure TChannelController.ClearPreChannelPower; procedure TChannelController.SetDriveGuarded(V: Integer);
// Drive, выставляемый самим юнитом (применение мощности канала / восстановление):
// rfDrive прилетит, но OnDriveChanged НЕ должен трактовать его как ручной → не
// сбрасывать FPreChannelPower.
begin begin
FPreChannelPower := -1; FRestoringDrive := True;
try
FRadio.SetDrive(V);
finally
FRestoringDrive := False;
end;
end;
procedure TChannelController.OnDriveChanged;
// Вызывается из OnControllerState(rfDrive). Любое ВНЕШНЕЕ изменение drive
// (слайдер/web/энкодер) снимает сохранённую «до канала» мощность.
begin
if not FRestoringDrive then FPreChannelPower := -1;
end; end;
procedure TChannelController.Select(Idx: Integer); procedure TChannelController.Select(Idx: Integer);
@@ -144,7 +161,7 @@ begin
begin begin
if FPreChannelPower < 0 then if FPreChannelPower < 0 then
FPreChannelPower := FRadio.FDrivePercent; FPreChannelPower := FRadio.FDrivePercent;
FRadio.SetDrive(EnsureRange(Ch.Power, 0, 100)); SetDriveGuarded(EnsureRange(Ch.Power, 0, 100));
end; end;
// Частота VFO A (XVTR-клэмп, CTUN, band-detect, сеть — всё в SetVfoA) // Частота VFO A (XVTR-клэмп, CTUN, band-detect, сеть — всё в SetVfoA)
@@ -189,7 +206,7 @@ begin
// Восстанавливаем мощность которая была до применения канала // Восстанавливаем мощность которая была до применения канала
if FPreChannelPower >= 0 then if FPreChannelPower >= 0 then
begin begin
FRadio.SetDrive(FPreChannelPower); SetDriveGuarded(FPreChannelPower);
FPreChannelPower := -1; FPreChannelPower := -1;
end; end;
end; end;
@@ -209,7 +226,7 @@ begin
end; end;
if FPreChannelPower >= 0 then if FPreChannelPower >= 0 then
begin begin
FRadio.SetDrive(FPreChannelPower); // восстановить + push + рендер слайдера SetDriveGuarded(FPreChannelPower); // восстановить + push + рендер слайдера
FPreChannelPower := -1; FPreChannelPower := -1;
end; end;
end; end;
+7 -20
View File
@@ -441,7 +441,6 @@ type
procedure WebOnBand(Idx: Integer); procedure WebOnBand(Idx: Integer);
procedure WebOnSpan(Hz: Integer); procedure WebOnSpan(Hz: Integer);
procedure WebOnRun(On_: Boolean); procedure WebOnRun(On_: Boolean);
procedure WebOnDrive(V: Integer);
procedure WebOnFreqA(Hz: Double); procedure WebOnFreqA(Hz: Double);
procedure WebOnXvtrBand(Idx: Integer); procedure WebOnXvtrBand(Idx: Integer);
// Discovery / connect / saved-CRUD из web (маршалятся в UI) // Discovery / connect / saved-CRUD из web (маршалятся в UI)
@@ -464,7 +463,6 @@ type
procedure SyncWebXvtrBand; procedure SyncWebXvtrBand;
procedure SyncWebSpan; procedure SyncWebSpan;
procedure SyncWebRun; procedure SyncWebRun;
procedure SyncWebDrive;
procedure SyncWebFreqA; procedure SyncWebFreqA;
// --- CAT callbacks ------------------------------------------------------- // --- CAT callbacks -------------------------------------------------------
function CATGetVfoA: Double; function CATGetVfoA: Double;
@@ -982,7 +980,7 @@ begin
FWebServer.OnBand := WebOnBand; FWebServer.OnBand := WebOnBand;
FWebServer.OnSpan := WebOnSpan; FWebServer.OnSpan := WebOnSpan;
FWebServer.OnRun := WebOnRun; FWebServer.OnRun := WebOnRun;
FWebServer.OnDrive := WebOnDrive; FWebServer.OnDrive := FWebAdapter.OnDrive;
FWebServer.OnFreqA := WebOnFreqA; FWebServer.OnFreqA := WebOnFreqA;
FWebServer.OnWebMic := FWebAdapter.OnMic; FWebServer.OnWebMic := FWebAdapter.OnMic;
FWebServer.OnXvtrBand := WebOnXvtrBand; FWebServer.OnXvtrBand := WebOnXvtrBand;
@@ -1351,7 +1349,10 @@ begin
rfVolume: rfVolume:
TrkVolume.Position := FController.FVolume; TrkVolume.Position := FController.FVolume;
rfDrive: rfDrive:
TrkDrive.Position := FController.FDrivePercent; // слайдер ← drive% begin
TrkDrive.Position := FController.FDrivePercent; // слайдер ← drive%
FChannelController.OnDriveChanged; // внешнее изменение снимает память канала
end;
rfAGCTop: rfAGCTop:
begin begin
TrkAGC.Position := FController.FAGCTop; TrkAGC.Position := FController.FAGCTop;
@@ -5063,19 +5064,6 @@ end;
// ── CTUN ────────────────────────────────────────────────────────────────── // ── CTUN ──────────────────────────────────────────────────────────────────
procedure TMainForm.WebOnDrive(V: Integer);
begin
FWebSyncInt := V;
FWebSyncM := SyncWebDrive;
TThread.Synchronize(nil, FWebSyncM);
end;
procedure TMainForm.SyncWebDrive;
begin
// Установка Position вызывает TrkDriveChange через OnChange автоматически
TrkDrive.Position := FWebSyncInt;
end;
procedure TMainForm.WebOnFreqA(Hz: Double); procedure TMainForm.WebOnFreqA(Hz: Double);
begin begin
FWebSyncFreq := Hz; FWebSyncFreq := Hz;
@@ -5091,8 +5079,7 @@ end;
procedure TMainForm.TrkDriveChange(Sender: TObject); procedure TMainForm.TrkDriveChange(Sender: TObject);
begin begin
if FSyncingFromController then Exit; // программная установка из OnControllerState — не команда if FSyncingFromController then Exit; // программная установка из OnControllerState — не команда
FChannelController.ClearPreChannelPower; // ручное изменение снимает сохранённую мощность канала FController.SetDrive(TrkDrive.Position); // rfDrive-рендер снимет память канала (OnDriveChanged)
FController.SetDrive(TrkDrive.Position);
end; end;
function TMainForm.CalcDriveByte: Byte; function TMainForm.CalcDriveByte: Byte;
@@ -5859,7 +5846,7 @@ begin
Ctx.SetActiveVfo := FWebAdapter.OnActiveVfo; Ctx.SetActiveVfo := FWebAdapter.OnActiveVfo;
Ctx.SetAGCMode := FWebAdapter.OnAGC; Ctx.SetAGCMode := FWebAdapter.OnAGC;
Ctx.SetVolume := FWebAdapter.OnVolume; Ctx.SetVolume := FWebAdapter.OnVolume;
Ctx.SetDriveLevel := WebOnDrive; Ctx.SetDriveLevel := FWebAdapter.OnDrive;
Ctx.SetFilterIdx := CATSetFilterIdx; Ctx.SetFilterIdx := CATSetFilterIdx;
Ctx.SetNRMode := FWebAdapter.OnNR; Ctx.SetNRMode := FWebAdapter.OnNR;
Ctx.SetNBMode := FWebAdapter.OnNB; Ctx.SetNBMode := FWebAdapter.OnNB;
+8
View File
@@ -45,6 +45,7 @@ type
procedure SyncAGC; procedure SyncAGC;
procedure SyncAGCTop; procedure SyncAGCTop;
procedure SyncVolume; procedure SyncVolume;
procedure SyncDrive;
procedure SyncWfAGC; procedure SyncWfAGC;
procedure SyncWfNF; procedure SyncWfNF;
procedure SyncMute; procedure SyncMute;
@@ -70,6 +71,7 @@ type
procedure OnAGC(Mode: Integer); procedure OnAGC(Mode: Integer);
procedure OnAGCTop(DB: Integer); procedure OnAGCTop(DB: Integer);
procedure OnVolume(V: Integer); procedure OnVolume(V: Integer);
procedure OnDrive(V: Integer);
procedure OnWfAGC(On_: Boolean); procedure OnWfAGC(On_: Boolean);
procedure OnWfNF(On_: Boolean); procedure OnWfNF(On_: Boolean);
procedure OnMute(On_: Boolean); procedure OnMute(On_: Boolean);
@@ -145,6 +147,12 @@ begin FSyncInt := V; FController.Invoke(@SyncVolume); end;
procedure TWebAdapter.SyncVolume; procedure TWebAdapter.SyncVolume;
begin FController.SetVolume(FSyncInt); end; begin FController.SetVolume(FSyncInt); end;
procedure TWebAdapter.OnDrive(V: Integer);
begin FSyncInt := V; FController.Invoke(@SyncDrive); end;
procedure TWebAdapter.SyncDrive;
begin FController.SetDrive(FSyncInt); end; // rfDrive снимет память канала (ChannelController)
procedure TWebAdapter.OnWfAGC(On_: Boolean); procedure TWebAdapter.OnWfAGC(On_: Boolean);
begin FSyncBool := On_; FController.Invoke(@SyncWfAGC); end; begin FSyncBool := On_; FController.Invoke(@SyncWfAGC); end;