unit Myc.Futures; interface uses System.SysUtils, Myc.Signals, Myc.TaskManager; type // Represents the eventual result of an asynchronous operation. IMycFuture = interface {$REGION 'property access'} function GetResult: T; function GetDone: TState; {$ENDREGION} // Provides access to the computed result. property Result: T read GetResult; // Provides access to the completion state. property Done: TState read GetDone; end; TFuture = record private FFuture: IMycFuture; function GetDone: IMycState; inline; function GetResult: T; inline; class var FNull: IMycFuture; class constructor CreateClass; class destructor DestroyClass; public constructor Create( const AFuture: IMycFuture ); class operator Implicit( const A: IMycFuture ): TFuture; overload; class operator Implicit( const A: TFuture ): IMycFuture; overload; class function Construct( const Proc: TFunc ): TFuture; overload; static; class function Construct( const Gate: IMycState; const Proc: TFunc ): TFuture; overload; static; class property Null: IMycFuture read FNull; function Chain( const Proc: TFunc ): TFuture; function WaitFor: T; property Done: IMycState read GetDone; property Result: T read GetResult; end; implementation uses Myc.Core.Futures, Myc.Core.Tasks; constructor TFuture.Create( const AFuture: IMycFuture ); 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.Result ); end ); end; class function TFuture.Construct( const Proc: TFunc ): TFuture; begin Result := TMycGateFuncFuture.Create( TaskManager, nil, Proc ); end; class function TFuture.Construct( const Gate: IMycState; const Proc: TFunc ): TFuture; begin Result := TMycGateFuncFuture.Create( TaskManager, Gate, Proc ); end; function TFuture.GetDone: IMycState; begin Result := FFuture.Done; end; function TFuture.GetResult: T; begin Result := FFuture.Result; end; function TFuture.WaitFor: T; begin TaskManager.WaitFor( FFuture.Done ); Result := FFuture.Result; end; class operator TFuture.Implicit( const A: IMycFuture ): TFuture; begin Result.Create( A ); end; class operator TFuture.Implicit( const A: TFuture ): IMycFuture; begin Result := A.FFuture; end; end.