Files
MycLib/Src/Myc.Futures.pas
T
Michael Schimmel f033ef2c0f TLatch extended
2025-06-04 01:54:20 +02:00

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.