unit Myc.Futures; interface uses System.SysUtils, Myc.Signals, Myc.TaskManager; type // Represents the eventual Value of an asynchronous operation. TFuture = record type IFuture = interface {$REGION 'property access'} function GetValue: T; function GetDone: TState; {$ENDREGION} // Provides access to the computed Value. property Value: T read GetValue; // Provides access to the completion state. property Done: TState read GetDone; end; TFuncConst = reference to function(const Arg1: S): TResult; {$REGION 'private'} strict private class var FNull: IFuture; class constructor CreateClass; class destructor DestroyClass; private FFuture: IFuture; function GetDone: TState; inline; function GetValue: T; inline; {$ENDREGION} public constructor Create(const AFuture: IFuture); class operator Initialize(out Dest: TFuture); class operator Implicit(const A: IFuture): TFuture; overload; class operator Implicit(const A: TFuture): IFuture; overload; class function Construct(const Proc: TFunc): TFuture; overload; static; class function Construct(const Gate: TState.IState; const Proc: TFunc): TFuture; overload; static; class property Null: IFuture read FNull; function Chain(const Proc: TFunc): TFuture; overload; function Chain(const Proc: TFuncConst): TFuture; overload; function WaitFor: T; property Done: TState read GetDone; property Value: T read GetValue; end; implementation uses Myc.Core.Futures, Myc.Core.Tasks; constructor TFuture.Create(const AFuture: IFuture); begin FFuture := AFuture; if not Assigned(FFuture) then FFuture := FNull; end; class constructor TFuture.CreateClass; begin TMycTaskFactory.AquireTaskManager; FNull := TMycNullFuture.Create; end; class destructor TFuture.DestroyClass; begin TMycTaskFactory.ReleaseTaskManager; end; function TFuture.Chain(const Proc: TFunc): TFuture; begin var Cap := FFuture; Result := TFuture.Construct(FFuture.Done, function: S begin Result := Proc(Cap.Value); end); end; function TFuture.Chain(const Proc: TFuncConst): TFuture; begin var Cap := FFuture; Result := TFuture.Construct(FFuture.Done, function: S begin Result := Proc(Cap.Value); end); end; class function TFuture.Construct(const Proc: TFunc): TFuture; begin Result := TMycGateFuncFuture.Create(TaskManager, nil, Proc); end; class function TFuture.Construct(const Gate: TState.IState; const Proc: TFunc): TFuture; begin Result := TMycGateFuncFuture.Create(TaskManager, Gate, Proc); end; function TFuture.GetDone: TState; begin Result := FFuture.Done; end; function TFuture.GetValue: T; begin Result := FFuture.Value; end; function TFuture.WaitFor: T; begin TaskManager.WaitFor(FFuture.Done); Result := FFuture.Value; end; class operator TFuture.Implicit(const A: IFuture): TFuture; begin Result.Create(A); end; class operator TFuture.Implicit(const A: TFuture): IFuture; begin Result := A.FFuture; end; class operator TFuture.Initialize(out Dest: TFuture); begin Dest.FFuture := FNull; end; end.