unit Myc.Lazy; interface uses System.SysUtils, Myc.Signals; type IMycMutable = interface function GetChanged: TState; function GetValue: T; property Changed: TState read GetChanged; property Value: T read GetValue; end; IMycLazy = interface {$REGION 'property access'} function GetChanged: TState; {$ENDREGION} function Pop(out Res: T): Boolean; property Changed: TState read GetChanged; end; TLazy = record private FLazy: IMycLazy; function GetChanged: TState.IState; inline; class var FNull: IMycLazy; class constructor CreateClass; public constructor Create(const ALazy: IMycLazy); class function Construct(const Changing: TState.IState; const Proc: TFunc): IMycLazy; overload; static; class function Construct(const Value: IMycLazy): IMycLazy; overload; static; class operator Implicit(const A: IMycLazy): TLazy; overload; class operator Implicit(const A: TLazy): IMycLazy; overload; function Pop(out Res: T): Boolean; inline; property Changed: TState.IState read GetChanged; end; implementation uses Myc.Core.Lazy; constructor TLazy.Create(const ALazy: IMycLazy); begin FLazy := ALazy; if not Assigned(FLazy) then FLazy := FNull; end; class function TLazy.Construct(const Changing: TState.IState; const Proc: TFunc): IMycLazy; begin Result := TMycFuncLazy.Create(Changing, Proc); end; class constructor TLazy.CreateClass; begin FNull := TMycNullLazy.Create; end; class function TLazy.Construct(const Value: IMycLazy): IMycLazy; begin Result := TMycChainedLazy.Create(Value); end; function TLazy.GetChanged: TState.IState; begin Result := FLazy.Changed; end; function TLazy.Pop(out Res: T): Boolean; begin Result := FLazy.Pop(Res); end; class operator TLazy.Implicit(const A: IMycLazy): TLazy; begin Result.Create(A); end; class operator TLazy.Implicit(const A: TLazy): IMycLazy; begin Result := A.FLazy; end; end.