unit Myc.Lazy; interface uses System.SysUtils, Myc.Signals; type TMutable = record type IMutable = interface {$REGION 'property access'} function GetChanged: TSignal; function GetValue: T; {$ENDREGION} property Changed: TSignal read GetChanged; property Value: T read GetValue; end; IWriteableMutable = interface(IMutable) procedure SetValue(const Value: T); end; {$REGION 'private'} strict private class var FNull: IMutable; class constructor CreateClass; private FMutable: IMutable; function GetChanged: TSignal; inline; {$ENDREGION} public constructor Create(const AMutable: IMutable); class operator Initialize(out Dest: TMutable); class operator Implicit(const A: IMutable): TMutable; overload; class operator Implicit(const A: TMutable): IMutable; overload; class property Null: IMutable read FNull; class function Construct(const Changing: TSignal; const Proc: TFunc): TMutable; overload; static; class function CreateWriteable(const Init: T): IWriteableMutable; overload; static; property Changed: TSignal read GetChanged; end; TLazy = record type ILazy = interface {$REGION 'property access'} function GetChanged: TState; {$ENDREGION} function Pop(out Res: T): Boolean; property Changed: TState read GetChanged; end; {$REGION 'private'} strict private class var FNull: ILazy; class constructor CreateClass; private FLazy: ILazy; function GetChanged: TState; inline; {$ENDREGION} public constructor Create(const ALazy: ILazy); class operator Initialize(out Dest: TLazy); class operator Implicit(const A: ILazy): TLazy; overload; class operator Implicit(const A: TLazy): ILazy; overload; class function Construct(const Changing: TState; const Proc: TFunc): TLazy; overload; static; class function Construct(const Value: ILazy): TLazy; overload; static; class property Null: ILazy read FNull; function Pop(out Res: T): Boolean; inline; property Changed: TState read GetChanged; end; implementation uses Myc.Core.Lazy; { TMutable } constructor TMutable.Create(const AMutable: IMutable); begin FMutable := AMutable; if not Assigned(FMutable) then FMutable := FNull; end; class constructor TMutable.CreateClass; begin FNull := TMycNullMutable.Create; end; class function TMutable.Construct(const Changing: TSignal; const Proc: TFunc): TMutable; begin Result := TMycFuncMutable.Create(Changing, Proc); end; class function TMutable.CreateWriteable(const Init: T): IWriteableMutable; begin Result := TMycWriteableMutable.Create(Init); end; function TMutable.GetChanged: TSignal; begin Result := FMutable.Changed; end; class operator TMutable.Implicit(const A: TMutable): IMutable; begin Result := A.FMutable; end; class operator TMutable.Implicit(const A: IMutable): TMutable; begin Result.Create(A); end; class operator TMutable.Initialize(out Dest: TMutable); begin Dest.FMutable := FNull; end; { TLazy } constructor TLazy.Create(const ALazy: ILazy); begin FLazy := ALazy; if not Assigned(FLazy) then FLazy := FNull; end; class function TLazy.Construct(const Changing: TState; const Proc: TFunc): TLazy; begin Result := TMycFuncLazy.Create(Changing, Proc); end; class constructor TLazy.CreateClass; begin FNull := TMycNullLazy.Create; end; class function TLazy.Construct(const Value: ILazy): TLazy; begin Result := TMycChainedLazy.Create(Value); end; function TLazy.GetChanged: TState; begin Result := FLazy.Changed; end; function TLazy.Pop(out Res: T): Boolean; begin Result := FLazy.Pop(Res); end; class operator TLazy.Implicit(const A: ILazy): TLazy; begin Result.Create(A); end; class operator TLazy.Implicit(const A: TLazy): ILazy; begin Result := A.FLazy; end; class operator TLazy.Initialize(out Dest: TLazy); begin Dest.FLazy := FNull; end; end.