125 lines
3.1 KiB
ObjectPascal
125 lines
3.1 KiB
ObjectPascal
unit Myc.Futures;
|
|
|
|
interface
|
|
|
|
uses
|
|
System.SysUtils,
|
|
Myc.Signals, Myc.TaskManager;
|
|
|
|
type
|
|
// Represents the eventual result of an asynchronous operation.
|
|
IMycFuture<T> = 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<T> = record
|
|
private
|
|
FFuture: IMycFuture<T>;
|
|
function GetDone: IMycState; inline;
|
|
function GetResult: T; inline;
|
|
|
|
class var
|
|
FNull: IMycFuture<T>;
|
|
|
|
class constructor CreateClass;
|
|
class destructor DestroyClass;
|
|
|
|
public
|
|
constructor Create( const AFuture: IMycFuture<T> );
|
|
|
|
class operator Implicit( const A: IMycFuture<T> ): TFuture<T>; overload;
|
|
class operator Implicit( const A: TFuture<T> ): IMycFuture<T>; overload;
|
|
|
|
class function Construct( const Proc: TFunc<T> ): TFuture<T>; overload; static;
|
|
class function Construct( const Gate: IMycState; const Proc: TFunc<T> ): TFuture<T>; overload; static;
|
|
|
|
class property Null: IMycFuture<T> read FNull;
|
|
|
|
function Chain<S>( const Proc: TFunc<T, S> ): TFuture<S>;
|
|
|
|
function WaitFor: T;
|
|
|
|
property Done: IMycState read GetDone;
|
|
property Result: T read GetResult;
|
|
end;
|
|
|
|
implementation
|
|
|
|
uses
|
|
Myc.Core.Futures, Myc.Core.Tasks;
|
|
|
|
constructor TFuture<T>.Create( const AFuture: IMycFuture<T> );
|
|
begin
|
|
FFuture := AFuture;
|
|
if not Assigned( FFuture ) then
|
|
FFuture := FNull;
|
|
end;
|
|
|
|
class constructor TFuture<T>.CreateClass;
|
|
begin
|
|
TMycTaskFactory.AquireTaskManager;
|
|
FNull := TMycNullFuture<T>.Create;
|
|
end;
|
|
|
|
class destructor TFuture<T>.DestroyClass;
|
|
begin
|
|
TMycTaskFactory.ReleaseTaskManager;
|
|
end;
|
|
|
|
function TFuture<T>.Chain<S>( const Proc: TFunc<T, S> ): TFuture<S>;
|
|
begin
|
|
var
|
|
Cap := FFuture;
|
|
|
|
Result := TFuture<S>.Construct( FFuture.Done,
|
|
function: S
|
|
begin
|
|
Result := Proc( Cap.Result );
|
|
end );
|
|
end;
|
|
|
|
class function TFuture<T>.Construct( const Proc: TFunc<T> ): TFuture<T>;
|
|
begin
|
|
Result := TMycGateFuncFuture<T>.Create( TaskManager, nil, Proc );
|
|
end;
|
|
|
|
class function TFuture<T>.Construct( const Gate: IMycState; const Proc: TFunc<T> ): TFuture<T>;
|
|
begin
|
|
Result := TMycGateFuncFuture<T>.Create( TaskManager, Gate, Proc );
|
|
end;
|
|
|
|
function TFuture<T>.GetDone: IMycState;
|
|
begin
|
|
Result := FFuture.Done;
|
|
end;
|
|
|
|
function TFuture<T>.GetResult: T;
|
|
begin
|
|
Result := FFuture.Result;
|
|
end;
|
|
|
|
function TFuture<T>.WaitFor: T;
|
|
begin
|
|
TaskManager.WaitFor( FFuture.Done );
|
|
Result := FFuture.Result;
|
|
end;
|
|
|
|
class operator TFuture<T>.Implicit( const A: IMycFuture<T> ): TFuture<T>;
|
|
begin
|
|
Result.Create( A );
|
|
end;
|
|
|
|
class operator TFuture<T>.Implicit( const A: TFuture<T> ): IMycFuture<T>;
|
|
begin
|
|
Result := A.FFuture;
|
|
end;
|
|
|
|
end.
|