unit uIdleJob;
interface
uses
{System.}Classes,
{TNotifyEvent}
{Vcl.}AppEvnts;
{TApplicationEvents}
type
TJobFinishState = ( jfsCancelled, jfsFinished );
TFinishNotifyEvent =
procedure( Sender: TObject; State: TJobFinishState )
of object;
TIdleJob =
class abstract
private
FAppEvnt: TApplicationEvents;
FOnFinish: TFinishNotifyEvent;
FOnStep: TNotifyEvent;
procedure HandleOnIdle( Sender: TObject;
var Done: Boolean );
function GetIsRunning: Boolean;
procedure DoOnFinish( AState: TJobFinishState );
procedure DoOnStep;
protected
procedure DoStart;
virtual;
procedure DoStep;
virtual;
abstract;
procedure DoStop;
virtual;
procedure JobFinished( NotifyLastStep: Boolean = True );
public
procedure AfterConstruction;
override;
procedure BeforeDestruction;
override;
procedure Start;
procedure Stop;
property IsRunning: Boolean
read GetIsRunning;
property OnFinish: TFinishNotifyEvent
read FOnFinish
write FOnFinish;
property OnStep: TNotifyEvent
read FOnStep
write FOnStep;
end;
implementation
{ TIdleJob }
procedure TIdleJob.AfterConstruction;
begin
inherited;
FAppEvnt := TApplicationEvents.Create(
nil );
end;
procedure TIdleJob.BeforeDestruction;
begin
FAppEvnt.Free;
inherited;
end;
procedure TIdleJob.DoOnFinish( AState: TJobFinishState );
begin
if Assigned( FOnFinish )
then
FOnFinish( Self, AState );
end;
procedure TIdleJob.DoOnStep;
begin
if Assigned( FOnStep )
then
FOnStep( Self );
end;
procedure TIdleJob.JobFinished( NotifyLastStep: Boolean );
begin
FAppEvnt.OnIdle :=
nil;
if NotifyLastStep
then
DoOnStep;
DoOnFinish( jfsFinished );
end;
procedure TIdleJob.DoStart;
begin
end;
procedure TIdleJob.DoStop;
begin
end;
function TIdleJob.GetIsRunning: Boolean;
begin
Result := Assigned( FAppEvnt.OnIdle );
end;
procedure TIdleJob.HandleOnIdle( Sender: TObject;
var Done: Boolean );
begin
DoStep( );
if IsRunning
then
DoOnStep;
end;
procedure TIdleJob.Start;
begin
if IsRunning
then
Exit;
FAppEvnt.OnIdle := HandleOnIdle;
DoStart;
DoOnStep;
end;
procedure TIdleJob.Stop;
begin
if not IsRunning
then
Exit;
FAppEvnt.OnIdle :=
nil;
DoStop;
DoOnFinish( jfsCancelled );
end;
end.