* Debugcapture client

This commit is contained in:
Michaël Van Canneyt 2022-10-19 22:39:14 +02:00
parent d196eafe3b
commit fd3127beb0

View File

@ -0,0 +1,192 @@
{
This file is part of the Pas2JS run time library.
Copyright (c) 2017-2020 by the Pas2JS development team.
Unit to send debug info (and console output) to /debugcapture API in simpleserver.
See the file COPYING.FPC, included in this distribution,
for details about the copyright.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
**********************************************************************}
unit debugcapture;
{$mode ObjFPC}
interface
uses
Types, Classes, SysUtils;
Const
DefaultURL = '/debugcapture';
Type
{ TDebugCaptureClient }
TDebugCaptureClient = class(TComponent)
private
FBufferTimeout: Integer;
FHookConsole: Boolean;
FURL: String;
FCurrent : String;
FLines : TStringDynArray;
FOldCallBack : TConsoleHandler;
FTimeOutID : Integer;
procedure SetBufferTimeout(AValue: Integer);
procedure SetHookConsole(AValue: Boolean);
Protected
procedure PushLine(aLine: String); virtual;
procedure DoPush; virtual;
Procedure DoConsoleWrite(S : JSValue; NewLine : Boolean); virtual;
Property Lines : TStringDynArray Read FLines;
Property TimeoutID : Integer Read FTimeOutID;
Public
Constructor Create(aOwner : TComponent); override;
Constructor CustomCreate(aOwner : TComponent; aURL : String; aBufferTimeOut : Integer); overload;
Constructor CustomCreate(aURL : String; aBufferTimeOut : Integer); overload;
Destructor Destroy; override;
Procedure Capture(const aLine : String; NewLine : Boolean = True); virtual;
Procedure SetConsoleHook;
Procedure ClearConsoleHook;
Procedure Flush;
Published
Property URL : String Read FURL Write FURL;
Property BufferTimeout : Integer Read FBufferTimeout Write SetBufferTimeout;
Property HookConsole : Boolean Read FHookConsole Write SetHookConsole;
end;
implementation
uses web, js;
{ TDebugCaptureClient }
procedure TDebugCaptureClient.SetBufferTimeout(AValue: Integer);
begin
if FBufferTimeout=AValue then Exit;
FBufferTimeout:=AValue;
end;
procedure TDebugCaptureClient.SetHookConsole(AValue: Boolean);
begin
if FHookConsole=AValue then Exit;
if aValue then
SetConsoleHook
else
ClearConsoleHook;
end;
procedure TDebugCaptureClient.DoConsoleWrite(S: JSValue; NewLine: Boolean);
begin
Capture(String(S),NewLine);
if Assigned(FOldCallBack) then
FOldCallBack(S,NewLine);
end;
constructor TDebugCaptureClient.Create(aOwner: TComponent);
begin
inherited Create(aOwner);
FURL:=DefaultURL;
FBufferTimeout:=0; // no buffer
end;
constructor TDebugCaptureClient.CustomCreate(aOwner: TComponent; aURL: String;
aBufferTimeOut: Integer);
begin
Create(aOwner);
URL:=aURL;
BufferTimeout:=aBufferTimeOut;
end;
constructor TDebugCaptureClient.CustomCreate(aURL: String; aBufferTimeOut: Integer);
begin
CustomCreate(Nil,aUrl,aBufferTimeout);
end;
destructor TDebugCaptureClient.Destroy;
begin
if HookConsole then
ClearConsoleHook;
Flush;
inherited Destroy;
end;
procedure TDebugCaptureClient.DoPush;
Var
aLines : TStringDynArray;
aBody : String;
begin
FTimeOutID:=0;
if Length(FLines)=0 then
exit;
aLines:=FLines;
FLines:=[];
aBody:=TJSJSON.Stringify(new(['lines',aLines]));
Window.Fetch(Url,new([
'method','POST',
'headers',new(['Content-Type','application.json']),
'body',aBody
]));
end;
procedure TDebugCaptureClient.PushLine(aLine : String);
begin
TJSArray(FLines).Push(aLine);
if (FBufferTimeout>0) and (FTimeOutID=0) then
FTimeOutID:=window.setTimeout(@DoPush,FBufferTimeout)
else
DoPush;
end;
procedure TDebugCaptureClient.Capture(const aLine: String; NewLine: Boolean);
Var
aCurrent : String;
begin
FCurrent:=FCurrent+aLine;
if NewLine then
begin
aCurrent:=FCurrent;
FCurrent:='';
PushLine(aCurrent);
end;
end;
procedure TDebugCaptureClient.SetConsoleHook;
begin
FOldCallBack:=SetWriteCallBack(@DoConsoleWrite);
end;
procedure TDebugCaptureClient.ClearConsoleHook;
begin
SetWriteCallBack(FOldCallBack);
FOldCallBack:=Nil;
end;
procedure TDebugCaptureClient.Flush;
begin
if (Length(Flines)>0) or (FCurrent<>'') then
begin
if FTimeOutID>0 then
Window.ClearInterval(FTimeOutID);
if (FCurrent<>'') then
begin
TJSArray(FLines).Push(FCurrent);
FCurrent:='';
end;
DoPush;
end;
end;
end.