130 lines
3.2 KiB
ObjectPascal
130 lines
3.2 KiB
ObjectPascal
unit Myc.TaskManager;
|
|
|
|
interface
|
|
|
|
uses
|
|
System.SysUtils,
|
|
Myc.Signals;
|
|
|
|
type
|
|
TTaskManager = record
|
|
type
|
|
IMycTaskManager = interface
|
|
procedure RunTask(const Gate: TState; const Proc: TProc);
|
|
procedure WaitFor(const State: TState);
|
|
end;
|
|
private
|
|
FTaskManager: IMycTaskManager;
|
|
|
|
public
|
|
constructor Create(const ATaskManager: IMycTaskManager);
|
|
class operator Implicit(const A: IMycTaskManager): TTaskManager; overload;
|
|
class operator Implicit(const A: TTaskManager): IMycTaskManager; overload;
|
|
|
|
// Run a task when the gate is opened.
|
|
procedure RunTask(const Gate: TState; const Proc: TProc); inline;
|
|
|
|
// Waits for the operation associated with State to complete.
|
|
// Must not be called from a worker thread of this factory.
|
|
// After waiting, or if the state is already set, any first stored exception
|
|
// from any worker thread of this factory will be re-raised in the calling (main) thread.
|
|
// Raises ETaskException if called from within a worker thread.
|
|
procedure WaitFor(const State: TState); inline;
|
|
end;
|
|
|
|
var
|
|
TaskManager: TTaskManager;
|
|
|
|
procedure SetupTaskManagerMock;
|
|
|
|
implementation
|
|
|
|
uses
|
|
System.Generics.Collections,
|
|
Myc.Core.Tasks;
|
|
|
|
type
|
|
TMycExecMock = class(TInterfacedObject, TSignal.ISubscriber)
|
|
private
|
|
FProc: TProc;
|
|
public
|
|
constructor Create(const AProc: TProc);
|
|
function Notify: Boolean;
|
|
end;
|
|
|
|
TMycTaskManagerMock = class(TInterfacedObject, TTaskManager.IMycTaskManager)
|
|
public
|
|
// IMycTaskManager
|
|
procedure RunTask(const Gate: TState; const Proc: TProc);
|
|
procedure WaitFor(const State: TState);
|
|
|
|
constructor Create;
|
|
end;
|
|
|
|
{ TMycExecMock }
|
|
|
|
constructor TMycExecMock.Create(const AProc: TProc);
|
|
begin
|
|
inherited Create;
|
|
FProc := AProc;
|
|
end;
|
|
|
|
function TMycExecMock.Notify: Boolean;
|
|
begin
|
|
Result := Assigned(FProc);
|
|
if Result then
|
|
begin
|
|
FProc();
|
|
FProc := nil;
|
|
end;
|
|
end;
|
|
|
|
{ TMycTaskManagerMock }
|
|
|
|
constructor TMycTaskManagerMock.Create;
|
|
begin
|
|
inherited Create;
|
|
end;
|
|
|
|
procedure TMycTaskManagerMock.RunTask(const Gate: TState; const Proc: TProc);
|
|
begin
|
|
Gate.Signal.Subscribe(TMycExecMock.Create(Proc));
|
|
end;
|
|
|
|
procedure TMycTaskManagerMock.WaitFor(const State: TState);
|
|
begin
|
|
Assert(State.IsSet);
|
|
end;
|
|
|
|
procedure SetupTaskManagerMock;
|
|
begin
|
|
TaskManager.Create(TMycTaskManagerMock.Create);
|
|
end;
|
|
|
|
constructor TTaskManager.Create(const ATaskManager: IMycTaskManager);
|
|
begin
|
|
FTaskManager := ATaskManager;
|
|
end;
|
|
|
|
procedure TTaskManager.RunTask(const Gate: TState; const Proc: TProc);
|
|
begin
|
|
FTaskManager.RunTask(Gate, Proc);
|
|
end;
|
|
|
|
procedure TTaskManager.WaitFor(const State: TState);
|
|
begin
|
|
FTaskManager.WaitFor(State);
|
|
end;
|
|
|
|
class operator TTaskManager.Implicit(const A: IMycTaskManager): TTaskManager;
|
|
begin
|
|
Result.Create(A);
|
|
end;
|
|
|
|
class operator TTaskManager.Implicit(const A: TTaskManager): IMycTaskManager;
|
|
begin
|
|
Result := A.FTaskManager;
|
|
end;
|
|
|
|
end.
|