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.