unit Myc.Signals.FMX; interface uses System.Classes, System.SysUtils, FMX.Controls, Myc.Signals; type TFMXValidationState = class(TComponent, TSignal.ISubscriber) private [volatile] FInvalidated: Integer; FSignal: TSignal.ISignal; FSubscription: TSignal.TSubscriptionTag; FProc: TProc; procedure CallProc; protected function Notify: Boolean; public constructor Create(AOwner: TControl; const ASignal: TSignal.ISignal; const AProc: TProc); reintroduce; destructor Destroy; override; procedure AfterConstruction; override; procedure BeforeDestruction; override; end; implementation uses System.SyncObjs; { TFMXValidationState } constructor TFMXValidationState.Create(AOwner: TControl; const ASignal: TSignal.ISignal; const AProc: TProc); begin inherited Create(AOwner); FInvalidated := 0; FSignal := ASignal; FProc := AProc; end; destructor TFMXValidationState.Destroy; begin TThread.RemoveQueuedEvents(CallProc); inherited; end; procedure TFMXValidationState.AfterConstruction; begin inherited; FSubscription := FSignal.Subscribe(Self); end; procedure TFMXValidationState.BeforeDestruction; begin FSignal.Unsubscribe(FSubscription); inherited; end; procedure TFMXValidationState.CallProc; begin if TInterlocked.Exchange(FInvalidated, 0) > 0 then FProc; end; function TFMXValidationState.Notify: Boolean; begin if TInterlocked.Exchange(FInvalidated, 1) = 0 then TThread.Queue(nil, CallProc); exit(true); end; end.