unit Myc.Core.Lazy; interface uses System.SysUtils, Myc.Signals, Myc.Lazy; type TMycLazy = class abstract( TInterfacedObject, IMycLazy ) protected function GetChanged: IMycState; virtual; abstract; public function Pop( out Res: T ): Boolean; virtual; abstract; end; TMycNullLazy = class( TMycLazy ) protected function GetChanged: IMycState; override; public function Pop( out Res: T ): Boolean; override; end; TMycFuncLazy = class( TMycLazy ) private FChanged: IMycDirty; FChangeState: TState.TSubscription; FProc: TFunc; protected function GetChanged: IMycState; override; public constructor Create(const AChanged: TState; const AProc: TFunc); destructor Destroy; override; function Pop( out Res: T ): Boolean; override; end; implementation { TMycNullLazy } function TMycNullLazy.GetChanged: IMycState; begin Result := TState.Null; end; function TMycNullLazy.Pop( out Res: T ): Boolean; begin Res := Default ( T ); Result := true; end; { TMycFuncLazy } constructor TMycFuncLazy.Create(const AChanged: TState; const AProc: TFunc); begin inherited Create; FChanged := TDirty.Construct; FProc := AProc; FChangeState := AChanged.Subscribe( FChanged ); end; destructor TMycFuncLazy.Destroy; begin FChangeState.Unsubscribe; inherited; end; function TMycFuncLazy.GetChanged: IMycState; begin Result := FChanged.State; end; function TMycFuncLazy.Pop( out Res: T ): Boolean; begin Result := FChanged.State.IsSet; if Result then begin if Assigned( FProc ) then Res := FProc; FChanged.Reset; end; end; end.