1
0
mirror of https://github.com/salvadordf/CEF4Delphi.git synced 2025-04-17 06:57:13 +02:00
CEF4Delphi/source/uCEFWorkSchedulerQueueThread.pas
salvadordf ca8bc9dff4 Added cef4delphi.chm help file
Added the PDS file to extract the HTML Help files using PasDoc
Added more XML documentation
Fixed some XML errors.
Removed the license copy from the pas units.
Updated the LICENSE.md file
2023-08-09 19:38:57 +02:00

236 lines
4.9 KiB
ObjectPascal

unit uCEFWorkSchedulerQueueThread;
{$IFDEF FPC}
{$MODE OBJFPC}{$H+}
{$ENDIF}
{$I cef.inc}
{$IFNDEF TARGET_64BITS}{$ALIGN ON}{$ENDIF}
{$MINENUMSIZE 4}
interface
uses
{$IFDEF DELPHI16_UP}
System.Classes, System.SyncObjs, System.SysUtils,
{$ELSE}
Classes, SyncObjs, SysUtils,
{$ENDIF}
uCEFConstants;
type
TOnPulseEvent = procedure(Sender: TObject; aDelay: integer) of object;
TValuesArray = array of integer;
TCEFWorkSchedulerQueueThread = class(TThread)
protected
FQueueCS : TCriticalSection;
FEvent : TEvent;
FWaiting : boolean;
FStop : boolean;
FReady : boolean;
FValues : TValuesArray;
FOnPulse : TOnPulseEvent;
function GetAvailableValue : integer;
function GetHasPendingValue : boolean;
function Lock : boolean;
procedure Unlock;
function CanContinue : boolean;
procedure ReadAllPendingValues;
procedure DoOnPulse;
procedure Execute; override;
property AvailableValue : integer read GetAvailableValue;
property HasPendingValue : boolean read GetHasPendingValue;
public
constructor Create;
destructor Destroy; override;
procedure AfterConstruction; override;
procedure StopThread;
procedure EnqueueValue(aValue : integer);
property Ready : boolean read FReady;
property OnPulse : TOnPulseEvent read FOnPulse write FOnPulse;
end;
implementation
constructor TCEFWorkSchedulerQueueThread.Create;
begin
inherited Create(True);
FReady := False;
FQueueCS := nil;
FWaiting := False;
FStop := False;
FEvent := nil;
FValues := nil;
FOnPulse := nil;
FreeOnTerminate := False;
end;
destructor TCEFWorkSchedulerQueueThread.Destroy;
begin
if (FEvent <> nil) then FreeAndNil(FEvent);
if (FQueueCS <> nil) then FreeAndNil(FQueueCS);
if (FValues <> nil) then
begin
Finalize(FValues);
FValues := nil;
end;
inherited Destroy;
end;
procedure TCEFWorkSchedulerQueueThread.AfterConstruction;
begin
inherited AfterConstruction;
FEvent := TEvent.Create(nil, False, False, '');
FQueueCS := TCriticalSection.Create;
end;
function TCEFWorkSchedulerQueueThread.Lock : boolean;
begin
if (FQueueCS <> nil) then
begin
FQueueCS.Acquire;
Result := True;
end
else
Result := False;
end;
procedure TCEFWorkSchedulerQueueThread.Unlock;
begin
if (FQueueCS <> nil) then FQueueCS.Release;
end;
function TCEFWorkSchedulerQueueThread.GetAvailableValue : integer;
var
TempLen : integer;
TempNewValues : TValuesArray;
begin
Result := 0;
if Lock then
begin
TempLen := length(FValues);
if (TempLen > 0) then
begin
Result := FValues[0];
if (TempLen = 1) then
SetLength(FValues, 0)
else
begin
SetLength(TempNewValues, TempLen - 1);
TempNewValues := copy(FValues, 1, high(integer));
SetLength(FValues, length(TempNewValues));
FValues := Copy(TempNewValues);
Finalize(TempNewValues);
end;
end;
Unlock;
end;
end;
function TCEFWorkSchedulerQueueThread.GetHasPendingValue : boolean;
begin
Result := False;
if Lock then
begin
if not(Terminated) and not(FStop) then
begin
FWaiting := False;
Result := (Length(FValues) > 0);
end;
Unlock;
end;
end;
procedure TCEFWorkSchedulerQueueThread.StopThread;
begin
if Lock then
begin
FStop := True;
if FWaiting then
begin
FWaiting := False;
FEvent.SetEvent;
end;
Unlock;
end;
end;
procedure TCEFWorkSchedulerQueueThread.EnqueueValue(aValue : integer);
begin
if Lock then
try
SetLength(FValues, Length(FValues) + 1);
FValues[Length(FValues) - 1] := aValue;
if FWaiting then
begin
FWaiting := False;
FEvent.SetEvent;
end;
finally
Unlock;
end;
end;
procedure TCEFWorkSchedulerQueueThread.ReadAllPendingValues;
begin
while HasPendingValue do
if not(Terminated) then
Synchronize({$IFDEF FPC}self, @{$ENDIF}DoOnPulse);
end;
procedure TCEFWorkSchedulerQueueThread.DoOnPulse;
begin
if assigned(FOnPulse) then
FOnPulse(self, AvailableValue);
end;
function TCEFWorkSchedulerQueueThread.CanContinue : boolean;
begin
Result := False;
if Lock then
try
if not(Terminated) and not(FStop) then
begin
Result := True;
FWaiting := True;
FEvent.ResetEvent;
end;
finally
Unlock;
end;
end;
procedure TCEFWorkSchedulerQueueThread.Execute;
begin
FReady := True;
while CanContinue do
begin
FEvent.WaitFor(INFINITE);
ReadAllPendingValues;
end;
end;
end.